Trailing-Edge
-
PDP-10 Archives
-
decuslib20-03
-
decus/20-0081/change.mac
There are 2 other files named change.mac in the archive. Click here to see a list.
TITLE CHANGE********** CHARACTER SET CONVERTER **********
SUBTTL *** WORDS OF WISDOM ***
;********************************************************************
;* *
;* NO FORCE, HOWEVER GREAT, CAN STRETCH A CORD, HOWEVER *
;* FINE, INTO A HORIZONTAL LINE, WHICH SHALL BE ABSOLUTELY *
;* STRAIGHT...AND SO IS THE WAY OF AN EAGLE IN THE AIR; THE *
;* WAY OF A SERPENT UPON A ROCK; THE WAY OF A SHIP IN THE *
;* MIDST OF THE SEA; AND THE WAY OF A MAN WITH A MAID...FOR *
;* HOWEVER BEAUTIFUL AND FREE, STILL IMPERFECT.... *
;* *
;********************************************************************
SUBTTL *** DEFINITIONS ***
;VERSION NUMBERS.
VEDIT==555
VWHO==1
VMINOR==0
VMAJOR==4
; ASSEMBLER DIRECTIVES.
TWOSEG
SALL
;EXTERNAL JOBFF,JOBREL,JOBREN,JOBINT,JOBUUO,JOBSA
;EXTERNAL JOB41,JOBDDT,JOBTPC,JOBAPR,JOBCNI
SEARCH JOBDAT ;JOBXXX IS NOW .JBXXX
; ACCUMULATORS.
S=0 ;BIT REGISTER.
OF=1 ;USED FOR DEVICE STATUS.
IF=2 ;USED FOR DEVICE STATUS.
T1=3 ;TEMPORARY AC'S.
T2=4
T3=5
P1=6 ;MAYBE YOU CAN DEPEND ON AC'S.
P2=7
P3=10
P4=11
OCNT=<SIDE=12> ;INDEX IN DECODER AND COUNTER.
ICNT=<WD=13> ;OUTPUT WORD AND COUNTER.
CH=14 ;HOLDS A CHARACTER.
OM=15 ;MODE INDEX.
IM=16 ;MODE INDEX.
PDP=17 ;PUSH-DOWN POINTER.
; BITS SET BY COMMAND DECODER IN S.
COL==1 ;SET BY CD IF COLON FOUND.
PER==2 ;SET BY CD IF PERIOD FOUND.
SLH==4 ;SET BY CD IF SLASH FOUND.
BRK==10 ;SET BY CD IF BRACKET FOUND.
IO==20 ;SET IF _ OR = FOUND BY CD.
EOL==40 ;SET WHEN EOL FOUND.
SOM==100 ;SET WITH ALL OF THE ABOVE.
DEV==200 ;SAYS WE HAVE A DEVICE.
NUM==400 ;SAYS WE HAVE PPN.
REL==1000 ;SAYS WE HAVE REEL SERIAL NUMBER.
PAR==2000 ;SET TO INDICATE WE HAVE PARITY.
MODE==4000 ;SET TO INDICATE WE HAVE MODE.
BLK==10000 ;SET TO INDICATE WE HAVE BLOCKING FACTOR.
ADV==20000 ;SET TO INDICATE WE HAVE ADVANCE NUMBER.
ATS==40000 ;SET BY CD WHEN "@" FOUND.
XBUF==100000 ;SET TO INDICATE WE HAVE A BUFFER SWITCH.
ALT==200000 ;AN ALTMODE WAS THE DELIMITER.
SPC==200000 ;SET IT A CRLF IS NEEDED.
IOT==400000 ;SET WHEN LOOKING AT INPUT SPECS.
DATA==1000000 ;SAYS WE MAY HAVE A TABLE FILE NAME COMING.
DEN==2000000 ;SAYS WE HAVE DENSITY.
LAB==4000000 ;SET TO INDICATE WE HAVE LABEL TYPE.
BAD==10000000 ;SET IF A BAD CHARACTER IS TYPED.
REC==20000000 ;SAYS WE HAVE RECORD SIZE.
NODIS==40000000 ;SAYS THERE IS NO DISPATCH TABLE.
FNDONE==100000000 ;SAYS WE HAVE FOUND ONE MATCH.
FNDTWO==200000000 ;SAYS WE FOUND MORE THEN ONE MATCH.
NOCHK==400000000 ;DON'T CHECK INPUT CHARACTER.
STAR==1000000000 ;WE HAVE SEEN A STAR ON INPUT.
BAC==2000000000 ;WE HAVE BACKSPACE ARGUMENT.
NOSTAR==4000000000 ;WE HAVE GOTTEN A NONE STAR ON INPUT.
; INDEXES INTO CCL BLOCK.
CCLCHN==-1 ;CCL CHANNEL NUMBER.
CCLSTS==0 ;DEVICE STATUS WORD.
CCLDEV==1 ;CCL DEVICE.
CCLBHD==2 ;CCL BUFFER HEADER.
CCLNAM==3 ;NAME OF CCL FILE.
CCLEXT==4 ;EXT OF CCL FILE.
CCLDAT==5 ;DATE TIME PROT WORD.
CCLPPN==6 ;PPN OF ONWER.
CCLOPN==7 ;OPEN MME.
CCLLOK==10 ;LOOKUP MME.
CCLGET==11 ;INPUT MME.
CCLREL==12 ;RELEASE MME.
CCLBUF==13 ;INBUF MME.
CCLHED==14 ;BUFFER HEADER.
; INDEXES INTO IMPURE DATA BLOCK.
CHAN==-1 ;CHANNEL FILE IS OPEN ON.
STATUS==0 ;STATUS BITS FOR OPEN.
DEVICE==1 ;DEVICE FOR OPEN.
BUFFER==2 ;POINTER TO POINTER TO BUFFERS.
NAME==3 ;FILE NAME POSITION FOR LOOKUP.
EXT==4 ;FILE EXTENSION POSITION.
DATTIM==5 ;DATE TIME WORD.
PPN==6 ;PPN WORD.
MOD==7 ;MOD WORD FOR DATA BLOCK.
BLKFCT==10 ;BLOCKING FACTOR.
RECSIZ==11 ;RECORD SIZE.
ADVAN==12 ;ADVANCE COUNT.
LABEL==13 ;LABEL TYPE.
DENSITY==14 ;MAG-TAPE DENSITY.
VOL==15 ;CURRENT VOLUME FOR MAG-TAPE.
PERGE==16 ;PERGE NUMBER FOR MAG-TAPE.
CHRMOD==17 ;FILE MODE (CHARACTER SET).
SEC==20 ;SECTORS FOR BLOCKING FACTOR.
BUFNUM==21 ;NUMBER OF BUFFERS TO USE.
BACSPC==22 ;BACKSPACE ARGUMENT.
NAMMSK==23 ;MASK FOR FILE NAME.
EXTMSK==24 ;MASK FOR EXTENSION.
THREE==<TWO==<ONE==<ZERO==0>+1>+1>+1 ;INDEXES FOR RETURNS.
; BITS SET IN IF OR OF.
NOWIND==1 ;DO NOT REWIND DEVICE.
AWIND==10000 ;DON'T REWIND AFTER OPERATION.
BWIND==20000 ;DON'T REWIND BEFORE OPERATION.
UNLOAD==2 ;UNLOAD DEVICE.
NOHEAD==4 ;NO LINE PRINTER HEADINGS.
IND==10 ;INITIALIZE IN INDUSTRY MODE.
NOERROR==20 ;SET IF IGNORING ERRORS.
SPAN==40 ;RECORDS CROSS BLOCKS.
WDEV==1000 ;DEVICE IS WILD DISK (ALL STR).
WNAME==100 ;WE HAVE A WILD NAME.
WEXT==200 ;WE HAVE A WILD EXTENSION.
WP==2000 ;PROJECT NUMBER IS WILD.
WPN==4000 ;PROGRAM NUMBER IS WILD.
WILD==WDEV!WNAME!WEXT!WP!WPN ;SOMETHING IS WILD.
SCAN==400 ;SAYS TO SCAN MTA FOR FILE.
NOCRLF==40000 ;ASCII FILE HAS NO CRLF'S.
MTA==20000000 ;DEVICE IS A MAG-TAPE.
DIR==4000000 ;DEVICE HAS A DIRECTORY (DTA OR DSK).
DTA==100000000 ;DEVICE IS A DECTAPE.
DSK==200000000000 ;DEVICE IS A DISK.
CDR==100000000000 ;DEVICE IS A CARD READER.
CDP==100000000000 ;DEVICE IS A CARD PUNCH.
LPT==40000000000 ;DEVICE IS A LINE PRINTER.
PTP==400000000 ;DEVICE IS A TAPE PUNCH.
PTR==200000000 ;DEVICE IS A TAPE READER.
TTY==10000000 ;DEVICE IS A TTY.
IPT==2000000 ;DEVICE CAN DO INPUT.
OTP==1000000 ;DEVICE CAN DO OUTPUT.
GDEV==DTA!DSK!CDR!CDP!LPT!PTP!PTR!TTY!MTA;DEVICE CAN BE USED.
; BITS SET IN S.
FF==1 ;LAST CHARACTER WAS A FORM FEED.
EOR==2 ;END OF RECORD HAS BEEN SEEN.
FREAD==4 ;FIRST READ BIT.
LHEAD==10 ;SAYS WE ARE DOING HEADINGS FOR LPT.
TERM==20 ;END LABELS ARE NEXT.
FIN==40 ;SET IF END OF REEL.
NO.ERR==100 ;SET TO IGNORE OUTPUT ERRORS.
NI.ERR==200 ;SET TO IGNORE INPUT ERRORS.
HDR==400 ;SET TO DENOTE WORKING ON HEADERS.
HUNG==1000 ;SET TO DENOTE DEVICE IS HUNG.
NO.PRI==2000 ;DON'T TYPE HUNG MESSAGE.
PRG==4000 ;SET TO INDICATE WE HAVE PERGED LABEL.
NI.LST==10000 ;SET TO IGNORE IOBLK ERRORS.
FFLG==20000 ;FIRST TIME FLAG.
BAC==40000 ;SET TO SAY WE WANT THE SAME CHARACTER.
L.HDR==100000 ;LABEL READ IS A HEADER.
L.EOF==200000 ;LABEL READ IS A TRAILER.
L.EOV==400000 ;LABEL READ IS END OF REEL.
; BITS SET IN SOME KIND OF A STATUS WORD.
EVEN==1000 ;PARITY BIT FOR EVEN.
ODD==0 ;JUST FOR CLEARNESS.
SYNC==40 ;STAY EVEN WITH DEVICE.
BIN==14 ;DEVICE DATA MODE.
DMP==17 ;DEVICE DATA MODE FOR DATA FILE.
ASC==0 ;ASCII DATA MODE.
TRK7==4 ;MTA IS A SEVEN TRACK DRIVE.
ER.IDV==1 ;HUNG DEVICE TRAP.
ER.ICC==2 ;CONTROL-C TRAP.
ER.OFL==4 ;DISK OFF LINE TRAP.
ER.FUL==10 ;DISK FULL TRAP.
ER.QEX==20 ;QUOTA BEING EXCEEDED TRAP.
ER.TLX==40 ;RUN TIME LIMIT EXCEEDED.
ER.ALL==ER.IDV!ER.ICC!ER.OFL!ER.FUL!ER.QEX!ER.TLX ;PROBLEM TRAPS.
E.LOK==400000 ;DEVICE IS WRITE LOCKED.
E.HAD==200000 ;HARDWARE FAILURE.
E.PAR==100000 ;PARITY ERROR.
E.IOB==40000 ;I/O BLOCK TOO LARGE.
E.EOF==20000 ;END OF FILE.
E.BOT==4000 ;WE ARE AT LOAD POINT.
E.EOT==2000 ;END OF TAPE.
E.ERR==E.LOK!E.HAD!E.PAR!E.IOB ;ERROR BITS.
NOR==1000000 ;MODE NEEDS INPUT RECORD SIZE.
NIR==2000000 ;MODE NEEDS OUTPUT RECORD SIZE.
EXW==4000000 ;MODE NEEDS EXTRA WORDS FOR BUFFER.
TAB==10000000 ;SAYS CHARACTER SET HAS TABS.
GDSK==7000000 ;DISK DEVICE IS GENERIC.
; INDEXS INTO MODE TABLE.
INI==0 ;INPUT DISPATCH.
OUTI==1 ;OUTPUT INITIALIZATION.
OUTC==2 ;PUT ONE CHARACTER.
OUTR==3 ;FINISH OUTPUT RECORD.
OUTB==4 ;FINISH OUTPUT BLOCK.
OUTF==5 ;FINISH OUTPUT FILE.
MSIZ==6 ;BYTE SIZE AND BYTES PER WORD.
MPTR==7 ;BYTE POINTER FOR MODE.
FPTR==10 ;POINTER TO DATA FILE ENTRY.
STS==11 ;STATUS BITS FOR MODE.
CNAM==12 ;CHARACTER SET NAME IN SIXBIT.
; CPU FLAGS.
PDL==200000 ;PDL OVERFLOW TRAP.
MPV==20000 ;MEMORY PROTECTION VIOLATION.
NXM==10000 ;NON-EXISTENT MEMORY.
REP==400000 ;REPETITIVE ENABLE.
; MASTER MODE SYMBOLS.
.CH==1 ;OUTPUT A CHARACTER.
.DEV==4 ;GET DEVICE CHARACTERISTICS.
.STR==3 ;OUTPUT A STRING.
.LN==4 ;INPUT A LINE AND WAIT.
.TERM==12 ;TERMINATE EXECUTION.
.CORE==11 ;AJUST CORE ALLOCATION.
.TIME==23 ;GET TIME OF DAY.
.DATE==14 ;GET THE DATE.
.RESET==0 ;RESET I/O.
.CLR==11 ;CLEAR INPUT BUFFER.
.TIM==27 ;GET RUN TIME.
.NAM==64 ;GET PHYSICAL NAME FOR DEVICE.
.SKP==14 ;SKIP IF LINE CAN BE INPUTTED.
.SLP==31 ;SLEEP FOR A WHILE.
.WAIT==72 ;HIBERNATE FOR A WHILE.
.WAT==0 ;WAIT FOR MAG-TAPE OPERATION.
.REW==1 ;REWIND TO LOAD POINT.
.EOF==3 ;WRITE EOF MARK.
.SKR==6 ;SKIP A RECORD.
.BSR==7 ;BACKSPACE RECORD.
.EOT==10 ;SKIP TO LOGICAL END OF TAPE.
.UNL==11 ;REWIND AND UNLOAD.
.BLK==13 ;WRITE SOME BLANK TAPE.
.SKF==16 ;SKIP A FILE.
.BSF==17 ;BACKSPACE FILE.
.DEC==100 ;INITIALIZE FOR DIGITAL TAPE.
.IND==101 ;INITIALIZE FOR INDUSTRY TAPE.
.RUN==35 ;RUN A PROGRAM.
.ENB==16 ;ENABLE APR TRAPS.
.STS==54 ;GET DEVICE CONI BITS.
.TAPE==112 ;GET MAG-TAPE DENSITY.
.NODEL==40 ;RETAIN OLD FILE.
.PPN==24 ;GET MY PPN.
.PJOB==30 ;GET MY JOB NUMBER.
.TAB==41 ;GET A TABLE ENTRY.
.DCHR==45 ;GET DEVICE CHARACTERISTICS.
.JLST==47 ;READ MY SEARCH LIST.
.SLST==46 ;READ SYSTEM STRUCTURES.
.GLST==66 ;READ SOME LIST.
.ALST==46 ;READ SYSTEM STRUCTURE LIST.
.ASC==1 ;STRING IS ASCIZ IN UME CALL.
.SIX==2 ;STRING IS ONE SIXBIT WORD.
.LTP==6 ;GET TTY LINE STUFF.
.SIZ==101 ;GET BUFFER SZE FOR DEVICE.
.IOSTP==10 ;WAIT FOR I/O TO STOP.
.PATH==110 ;READ SEARCH PATH.
; USEFUL OPDEFS.
OPDEF UME [OCT 001000000000] ;USER MODE ENTRY.
OPDEF MME [OCT 047000000000] ;MASTER MODE ENTRY.
OPDEF EME [OCT 051000000000] ;EXECUTIVE MODE ENTRY.
OPDEF GOTO [OCT 254000000000] ;LOAD PC WITH E.
OPDEF NOP [OCT 255000000000] ;NO OPERATION.
OPDEF DRIVE [OCT 072000000000] ;MAG-TAPE OPERATOR.
OPDEF GOSUB [OCT 260740000000] ;SUBROUTINE CALL.
OPDEF SAVE [OCT 261740000000] ;SAVE A LOCATION.
OPDEF UNSAVE [OCT 262740000000] ;UNSAVE A LOCATION.
OPDEF RET [OCT 263740000000] ;RETURN TO STACK.
; SOME MACROS.
DEFINE RETURN (LOC)
<IFN LOC, <GOTO RET0-LOC>
IFE LOC, <POPJ PDP,RET0>>
DEFINE USE (CORE,CONTENTS)
<IFNB <CORE>, <IFB <CONTENTS>, <ZZ==0
IFE "CODE"-"CORE", <ZZ==1
IFGE .-400000, <RELOC .>
IFL .-400000, <LOW==.
RELOC HGH>>
IFE "DATA"-"CORE", <ZZ==1
IFL .-400000, <RELOC .>
IFGE .-400000, <HGH==.
RELOC LOW>>
IFE ZZ, <PRINTX ? BAD CALL TO USE MACRO>>>
IFNB <CORE>, <IFNB <CONTENTS>, <ZZ==.
LOC CORE
EXP CONTENTS
RELOC ZZ>>
IFB <CORE>, <IFB <CONTENTS>, <PRINTX % NO ARGUMENT FOR USE MACRO>>
PURGE ZZ>
DEFINE FTABLE (NUM)
<RADIX 10
IFE NUM, <EXP .YY.>
IFG NUM, <.YY.==NUM/128
IFN <NUM-<<NUM/128>*128>>, <.YY.==.YY.+1>
.XX.==.YY.*128
XWD -.XX.,.ZZ.+1
.YY.==XWD -.XX.,.ZZ.+1
.ZZ.=.ZZ.+<.XX./128>>
IFL NUM, <RELOC .
PURGE .XX.,.YY.
.ZZ.==0>
RADIX 8>
DEFINE OP (AC,FLG,MM) ;CREATE THE RIGHT TEST.
<IFE FLG, <PRINTX % NO BIT ARGUMENT FOR OP MACRO>
IFN FLG, <IFN FLG&777777, <IFN FLG&777777000000, <TD'MM AC,[FLG]>>
IFE FLG&777777, <TL'MM AC,(FLG)>
IFE FLG&777777000000, <TR'MM AC,FLG>>>
DEFINE TEST (AC,FLG,M1,M2,LOC) ;GENERATE A SKIP IF LOC IS NULL
<IFB <LOC>, <OP AC,FLG,M1> ;ELSE GENERATE A JUMP TO LOC.
IFNB <LOC>, <OP AC,FLG,M2
XLIST
GOTO LOC
LIST>>
DEFINE ON (AC,FLG) ;TURN SOME BITS ON.
<OP AC,FLG,O>
DEFINE OFF (AC,FLG) ;TURN SOME BITS OFF.
<OP AC,FLG,Z>
DEFINE IF.ON (AC,FLG,LOC) ;SKIP OR JUMP IF BITS ARE ON.
<TEST AC,FLG,NN,NE,LOC>
DEFINE IF.OFF (AC,FLG,LOC) ;SKIP OR JUMP IF BITS ARE OFF.
<TEST AC,FLG,NE,NN,LOC>
DEFINE TNO (AC,FLG,LOC) ;SKIP OR JUMP IF ON AND TURN ON.
<TEST AC,FLG,ON,OE,LOC>
DEFINE TEO (AC,FLG,LOC) ;SKIP OR JUMP IF OFF AND TURN ON.
<TEST AC,FLG,OE,ON,LOC>
DEFINE TNZ (AC,FLG,LOC) ;SKIP OR JUMP IF ON AND TURN OFF.
<TEST AC,FLG,ZN,ZE,LOC>
DEFINE TEZ (AC,FLG,LOC) ;SKIP OR JUMP IF OFF AND TURN OFF.
<TEST AC,FLG,ZE,ZN,LOC>
DEFINE PRINT (STRING)
<EME .STR,[ASCIZ #STRING
#]>
DEFINE BRANCH (WHERE,LOC)
<GOSUB WHERE
XLIST
IRP (LOC), <GOTO LOC>
LIST>
DEFINE MTABLE (TYP)
<MODTAB: IRP (TYP), <EXP TYP'MOD
XLIST>
LIST>
DEFINE TABLE (NAM,TYP,SIZ,LEN,STS)
<TYP'MOD: EXP INI'TYP
XLIST
EXP OTI'TYP
EXP OTC'TYP
EXP OTR'TYP
EXP OTB'TYP
EXP OTF'TYP
XWD ^D'SIZ,^D36/^D'SIZ
POINT SIZ,ZERO
FTABLE LEN
EXP STS
<SIXBIT "NAM">
LIST>
DEFINE BSS (LOC,SIZE)
<IFB <SIZE>, <BLOCK LOC>
IFNB <SIZE>, <LOC: BLOCK SIZE>>
DEFINE ENABLE (ARG)
<EME .SKP,ZERO
XLIST
NOP ZERO
LIST>
DEFINE DIARET
<MOVEI T1,.
XLIST
MOVEM T1,DIAFLG
LIST>
DEFINE EQUATE (VAL,SYM)
<IRP (SYM), <SYM==VAL>>
DEFINE CBLK (CHAN,DEP)
<XLIST
ZZ==CHAN
REPEAT DEP,
<YY==.
EXP ZZ
BSS TWO
EXP .+12
BSS 4
OPEN ZZ,.-7
LOOKUP ZZ,.-5
IN ZZ,ZERO
RELEASE ZZ,ZERO
INBUF ZZ,ZERO
BSS THREE
CCLCNT==.-YY
ZZ==ZZ+1>
PURGE YY,ZZ
LIST>
DEFINE DEVOP (OP,CHAN,LOC)
<OFF S,HUNG
XLIST
AOS %IO
OP CHAN,LOC
LIST>
; THINGS WITH NO OTHER PLACE TO LIVE.
VERSION==0B2!5B11!1B17!'DRK'
HGH==400000 ;FOR USE MACRO.
LOW==000000 ;FOR USE MACRO.
NEC==400000 ;SAYS CHARACTER CAN'T BE CONVERTED.
DTNAM==122 ;NAME IN DTA DIRECTORY.
DTEXT==150 ;EXTENSION IN DTA DIRECTORY.
CF==<HF==<DF==<MF==<UF==IF+1>+1>+1>+1>+1;CHANNEL DEFINITIONS.
IFNDEF CCLLEN, <CCLLEN==5> ;NUMBER OF NESTING IN CCL FILES.
IFNDEF TMPLEN, <TMPLEN==10> ;LENGTH OF TEMPORARY STACK.
IFNDEF PDPSIZ, <PDPSIZ==150> ;PUSH-DOWN LIST SIZE.
IFNDEF PATSIZ, <PATSIZ==100> ;SIZE OF PATCH AREA.
SUBTTL *** IMPURE DATA AREA ***
USE DATA
; DATA AREA FOR MOD WORDS AND FILE SPECIFICATIONS.
FSTMEM: BSS ONE ;WORD FOR CHANNEL NUMBER.
OFILE: BSS ONE ;STATUS BITS FOR OPEN.
BSS ONE ;DEVICE FOR OPEN.
BSS ONE ;POINTER IN OUTPUT BUFFER HEADERS.
BSS ONE ;FILE NAME.
BSS ONE ;FILE EXTENSION.
BSS ONE ;DATE TIME PROTECTION WORD.
BSS ONE ;PROJECT-PROGRAM NUMBER.
BSS ONE ;MOD WORD FOR OUTPUT DEVICE AND FILE.
BSS ONE ;BLOCKING FACTOR.
BSS ONE ;RECORD SIZE.
BSS ONE ;NUMBER OF FILES TO ADVANCE.
BSS ONE ;LABEL TYPE.
BSS ONE ;MAG-TAPE DENSITY.
BSS ONE ;VOLUME NUMBER.
BSS ONE ;NOT USED.
OUTMOD: BSS ONE ;OUTPUT CHARACTER SET INDEX.
OBLK: BSS ONE ;BLOCKS TO READ FOR BLKFCT.
BSS ONE ;NUMBER OF BUFFERS TO USE.
BSS ONE ;NUMBER OF FILES TO BACKSPACE.
BSS ONE ;WORD FOR CHANNEL NUMBER.
BSS TWO ;UNUSED.
IFILE: BSS ONE ;STATUS BITS FOR OPEN.
BSS ONE ;DEVICE FOR OPEN.
BSS ONE ;POINTER TO INPUT BUFFER HEADERS.
BSS ONE ;FILE NAME.
BSS ONE ;EXTENSION.
BSS ONE ;DATE TIME PROTECTION WORD.
BSS ONE ;PROJECT-PROGRAM NUMBER.
BSS ONE ;MOD WORD FOR INPUT SPECIFICATIONS.
BSS ONE ;BLOCKING FACTOR.
BSS ONE ;RECORD SIZE OR SIZE OF LARGEST BLOCK.
BSS ONE ;NUMBER OF FILES TO ADVANCE.
BSS ONE ;LABEL TYPE.
BSS ONE ;MAG-TAPE DENSITY.
BSS ONE ;VOLUME NUMBER FOR MAG-TAPE.
BSS ONE ;NEW REEL NUMBER AFTER PERGE.
INPMOD: BSS ONE ;INPUT CHARACTER SET INDEX.
IBLK: BSS ONE ;BLOCKS TO READ FOR BLKFCT.
BSS ONE ;NUMBER OF BUFFERS TO USE.
BSS ONE ;NUMBER OF FILES TO BACKSPACE.
BSS TWO ;MASK WORDS FOR WILD CARDS.
TELWRD: BSS ONE ;ZERO IT TALKING.
LSTWRD: BSS ONE ;NON-ZERO IF LISTING.
FSTWRD: BSS ONE ;NON-ZERO IF FAST LIST.
;BUFFERS AND SAVED LOCATIONS FOR THINGS.
BSS INPBUF,^D21 ;SAVE AREA FOR INPUT LABEL.
BSS OUTBUF,^D21 ;SAVE AREA FOR OUTPUT LABEL.
BSS STACK,PDPSIZ ;PUSH-DOWN STACK.
BSS OBUF,3 ;OUTPUT BUFFER HEADER.
BSS IBUF,3 ;INPUT BUFFER HEADER.
BSS OIBUF,3 ;OUTPUT-INPUT BUFFER AREA.
BSS BUFF,^D24 ;OUTPUT-INPUT BUFFER.
BSS ORCNT,ONE ;NUMBER OF RECORDS WRITTEN.
BSS OBCNT,ONE ;NUMBER OF BLOCKS WRITTEN.
BSS IRCNT,ONE ;NUMBER OF RECORDS READ.
BSS IBCNT,ONE ;NUMBER OF BLOCKS READ.
BSS NOCHR,ONE ;NUMBER OF BAD CHARACTERS.
BSS RELNUM,ONE ;NUMBER OF MAG-TAPE REEL SET FROM LABEL.
BSS %IO,ONE ;NUMBER OF DEVICE ACESSES.
BSS %TIME,ONE ;RUN TIME.
BSS IFCNT,ONE ;INPUT FILE COUNT.
BSS OFCNT,ONE ;OUTPUT FILE COUNT.
BSS INPERR,ONE ;INPUT PARITY ERRORS.
BSS OTPERR,ONE ;OUTPUT PARITY ERRORS.
BSS SPCCNT,ONE ;COUNT OF CHARACTERS TYPED DURING COMMAND.
BSS ISEC,ONE ;NUMBER OF BLOCKS READ.
BSS OSEC,ONE ;NUMBER OF BLOCKS WRITTEN.
BSS TCH,ONE ;LAST CHARACTER READ.
BSS TEMP,ONE ;REGISTER FOR TEMPORARY STORAGE.
BSS TEMP1,ONE ;TEMPORARY REGISTER.
BSS LSTDEV,ONE ;LAST DISK DEVICE USED.
BSS SEARCH,ONE ;SAYS WE ARE SEARCHING.
BSS SYSSRH,ONE ;SAYS WE ARE USING DEVICE SYS.
BSS RUNFLG,ONE ;SAYS WE ARE DOING SOMETHING.
BSS RECPTR,ONE ;POINTER TO ALTER BUFFER.
BSS LSTPTR,ONE ;POINTER TO CTRL WORD.
BSS CURPTR,ONE ;CURRENT POINTER TO ALTER BUFFER.
LSTMEM==.-1 ;LAST IMPURE LOCATION TO CLEAR.
;STORAGE FOR THINGS THAT ARE RETAINED ACROSS RUNS.
BSS AC,20 ;SAVE AREA FOR THE AC'S.
BSS DATE,ONE ;DATE OF CRASH.
BSS TIME,ONE ;TIME OF CRASH.
BSS PRGNAM,ONE ;PROGRAM NAME.
XWD ZERO,STACK ;LOCATION OF THE STACK.
BSS PC,ONE ;LOCATION OF CRASH.
BSS SYSNAM,4 ;SYSTEM NAME.
PATCH: BSS PAT,PATSIZ ;PATCH AREA.
BSS LABSTR,ONE ;STRUCTURE FROM TAPE LABEL.
BSS LABNAM,TWO ;LABEL NAME TO TYPE ON ERROR.
BSS LABDTW,ONE ;DATE AND PROTECTION WORD.
BSS LABPPN,ONE ;PPN WORD FROM LABEL.
BSS LABSIZ,ONE ;SIZE OF FILE IN BLOCKS.
BSS LABVOL,ONE ;VOLUME NUMBER READ FROM LABEL.
BSS LABTOT,ONE ;TOTAL BLOCKS FOUND.
BSS LABCNT,ONE ;TOTAL FILES FOUND.
BSS PASS,TWO ;PASSWORD FOR GE LABELS.
BSS RETWRD,ONE ;RETAIN WORD.
BSS I.JBFF,ONE ;SAVE LOCATION FOR .JBFF.
BSS O.JBFF,ONE ;SAVE LOCATION FOR .JBFF.
BSS TRPBLK,TWO ;TRAP BLOCK FOR HUNG DEVICE.
BSS TRPPC,ONE ;PC WORD AT TRAP.
BSS TRPCHN,ONE ;CHANNEL THAT CAUSED TRAP.
BSS LSTSTR,ONE ;LAST STRUCTURE USED IN LIST.
BSS LSTPPN,ONE ;LAST PPN USED IN LIST.
BSS CCLFLG,ONE ;NONE ZERO IF USING CCL FILE.
BSS CCLCOR,ONE ;COPY OF .JBFF WHEN CCL FILE OPEN.
BSS DIAFLG,ONE ;RETURN ADDRESS FOR ERRORS IN DIALOG MODE.
SUBTTL *** PROGRAM START AND INITIALIZATION ***
;PROGRAM TO CONVERT BETWEEN CHARACTER SETS.
USE 137,BYTE (3)VWHO(9)VMAJOR(6)VMINOR(18)VEDIT
USE CODE
START: TDZA PDP,PDP ;NORMAL START.
SETOM PDP ;CCL ENTRY.
MOVEI T2,THREE ;GETTAB TABLE.
MME T1,.PJOB ;MY JOB NUMBER.
HRL T2,T1 ;XWD FOR GETTAB.
MME T2,.TAB ;GET MY NAME.
MOVE T2,[SIXBIT "CHANGE"] ;IF GETTAB FAILS.
MOVEM T2,PRGNAM ;SAVE MY NAME.
MME .RESET ;STOP THE WORLD.
MOVEI T1,NTHERE ;PICK UP REENTER ADDRESS.
MOVEM T1,.JBREN ;STORE IT IN PLACE.
SETZM RETWRD ;CLEAR RETAIN WORD.
SETZM DFFLG ;NO DATA FILE NOW.
MOVE T1,[GOSUB UME0] ;SET UP UME DISPATCH INSTRUCTION.
MOVEM T1,.JB41 ;SAVE IT.
SETZM CCLFLG ;NOT USING CCL FILE NOW.
EME .CLR,ZERO ;CLEAR BUFFERS.
JUMPE PDP,START1 ;JUMP IF NOT CCL ENTRY.
HRLZI T1,'DSK' ;SET DEVICE FOR DATA FILE.
MOVEM T1,DATDEV+1 ;SET DEVICE.
SETZM DATFIL+3 ;CLEAR PPN WORD.
GOTO NTHERE ;YES CONTINUE ON.
START1: MOVE PDP,[IOWD PDPSIZ,STACK] ;SET UP PUSH-DOWN POINTER.
MOVE T1,PRGNAM ;GET OUR NAME.
GOSUB PUTSIX ;PRINT IT.
EME .STR,[ASCIZ " HERE AT "];SAY GOOD THINGS.
MME T1,.TIME ;GET THE TIME OF DAY.
GOSUB TYPTIM ;PRINT THE TIME OF DAY.
EME .CH,[EXP " "] ;SEPARATE THINGS.
MME T1,.DATE ;GET THE DATE.
GOSUB TYPDAT ;PRINT THE DATE.
GOSUB CRLF ;SKIP A LINE.
GOTO NTH0 ;START THINGS ROLLING.
;HERE TO GET ANOTHER COMMAND.
NTHERE: ENABLE TTY ;CLEAR CONTROL O.
PRINT (READY.) ;TELL HIM WE'RE READY.
EME .CH,[EXP 12] ;SKIP A LINE.
NTH1: MOVE PDP,[IOWD PDPSIZ,STACK] ;SET UP PUSH-DOWN POINTER.
SKIPN RETWRD ;SKIP IF RETAINING.
GOTO NTH0 ;ELSE CARRY ON.
SETOM RETWRD ;FLAG NOT TO PERFORM COMMAND.
SKIPA T1,[XWD INPBUF,INPBUF+1];POINTER FOR PARTIAL BLT.
NTH0: MOVE T1,[XWD FSTMEM,FSTMEM+1];POINTER FOR INITIAL BLT.
SETZM -1(T1) ;CLEAR FIRST WORD.
BLT T1,LSTMEM ;DO IT.
SETZM IFILE+BUFFER ;CLEAR BUFFER POINTER.
SETZM OFILE+BUFFER ;CLEAR BUFFER POINTER.
HRRZS IFILE+MOD ;CLEAR DEVICE MOD BITS.
HRRZS OFILE+MOD ;CLEAR DEVICE MOD BITS.
RELEASE IF,ZERO ;RELEASE INPUT CHANNEL.
RELEASE OF,ZERO ;RELEASE OUTPUT CHANNEL.
RELEASE HF,ZERO ;RELEASE HELP FILE CHANNEL.
RELEASE UF,ZERO ;RELEASE UFD CHANNEL.
RELEASE MF,ZERO ;RELEASE MFD CHANNEL.
MOVE T1,CCLCOR ;COPY OF .JBFF FOR CCL COMMAND.
SKIPL CCLFLG ;SKIP IF IN CCL COMMAND.
HLRZ T1,.JBSA ;COPY SAVED .JBFF.
MOVEM T1,.JBFF ;RESTORE IT.
MME T1,.CORE ;BACK TO START SIZE.
NOP ;IGNORE ERRORS.
MOVE T1,[SIXBIT "0001"] ;RESET VOLUME NUMBER.
MOVEM T1,IFILE+VOL ;INTO INPUT SPECS.
MOVEM T1,OFILE+VOL ;INTO OUTPUT SPECS.
MOVEI T1,IF ;GET INPUT CHANNEL NUMBER.
MOVEM T1,IFILE+CHAN ;SAVE IT.
MOVEI T1,OF ;GET THE OUTPUT CHANNEL NUMBER.
MOVEM T1,OFILE+CHAN ;SAVE THE NUMBER.
GOSUB TRPSET ;SET UP TRAP BLOCK.
SUBTTL *** COMMAND DECODER ***
;ENTER HERE TO DECODE A COMMAND STRING OF THE FORM:
;ODEV:FILENAME.EXT[P,PN]/X/Y_IDEV:FILENAME.EXT[P,PN]/X/Y
GETCOM: SETZM DIAFLG ;CLEAR RETURN FLAG.
EME .STR,[ASCIZ "> "] ;FLAG WE WANT A COMMAND.
MOVEI S,TWO ;POSITION ON LINE.
MOVEM S,SPCCNT ;SET THE SPACE COUNTER.
SETZM S ;CLEAR THE FLAGS.
MOVEI SIDE,OFILE ;SET DECODER INDEX.
GOSUB GETSIX ;GET A COMMAND WORD.
IF.OFF S,EOL,CHKDEM ;IF NOT END OF COMMAND JUMP.
JUMPN WD,GTCOM1 ;JUMP IF THERE IS A COMMAND.
IF.OFF S,ALT,GETCOM ;IGNORE NULL COMMANDS.
GOTO DIALOG ;ENTER DIALOG MODE FOR ALTMODE.
GTCOM1: MOVEM WD,TEMP1 ;SAVE THE COMMAND WORD.
MOVE P1,[XWD -COMCNT,COMTAB] ;AOBJ WORD FOR TABLE.
MOVEI P2,COMDIS ;COMMAND DISPATCH TABLE.
GOTO UNICOM ;GO FIND A UNIQUE COMMAND.
NOTCOM: SKIPN RETWRD ;SKIP IF RETAINING.
GOTO COMERR ;ELSE COMMAND ERROR.
SKIPA WD,TEMP1 ;SKIP INTO GOODNESS.
GETWOD: GOSUB GETSIX ;GET A COMMAND WORD.
CHKDEM: IF.OFF S,COL ;IS THE DEVICE BIT SET.
GOSUB GETDEV ;YES SET UP DEVICE.
IF.OFF S,PER ;FILE NAME BIT.
GOSUB GETNAM ;GET THE FILE NAME.
IF.OFF S,BRK ;IS THERE A PPN COMING.
GOSUB GETPPN ;YES READ IT IN.
IF.ON S,ATS,CCLCOM ;OPEN CCL FILE.
SW.RET: IF.ON S,SLH,GETSW ;JUMP IF IT IS A SWITCH.
IF.ON S,IO,RESYNC ;IF _ OR = RECYCLE DECODER.
IF.ON S,EOL,ENDCOM ;IF END OF COMMAND JUMP.
GOTO COMERR ;ELSE ILLEGAL COMMAND.
;HERE ON AN EXIT COMMAND.
STOP: MME .RESET ;RESET THE WORLD.
MME ONE,.TERM ;AND STOP.
GOTO START ;IN CASE OF CONTINUE.
;HERE ON A DDT OR DEBUG COMMAND.
DEBUG: SKIPN T1,.JBDDT ;SKIP IF DDT IS HERE.
GOTO DDTERR ;TELL HIM WHAT IS WRONG.
CALDDT: SAVE [NTHERE] ;RETURN TO THE STACK.
SETZM .JBAPR ;DON'T ALLOW APR TRAPS.
SETZM .JBINT ;DON'T ALLOW DEVICE TRAPS.
DDTCAL: ENABLE TTY ;CLEAR CONTROL O.
GOSUB CRLF ;SKIP A LINE.
EME .STR,[ASCIZ "Debugger here"];TELL HIM WHAT IS GOING ON.
GOTO ZERO(T1) ;CALL THE DEBUGGER.
;HERE ON A BYE COMMAND.
LOGOFF: EME .CLR,ZERO ;CLEAR THE TTY BUFFERS.
GOSUB CRLF ;SKIP A LINE.
MOVEI T1,LOGPRG ;POINTER TO PARAMETERS.
MME T1,.RUN ;RUN LOGOUT.
GOTO STOP ;THE MME FAILED.
;HERE ON A RETAIN COMMAND.
RETAIN: SETOM RETWRD ;FLAG RETAINED COMMAND.
GOTO NTHERE ;CONTINUE ON.
;HERE ON AN ERASE COMMAND.
ERASE: SETZM RETWRD ;CLEAR RETAIN WORD.
GOTO NTHERE ;CONTINUE ON.
;HERE ON A PERFORM COMMAND.
PERFOR: EME .CH,[EXP 12] ;SKIP A LINE.
MOVE T1,PRGNAM ;GET OUT NAME.
GOSUB PUTSIX ;PRINT IT.
EME .CH,[EXP 11] ;TAB A LITTLE.
MME T1,.TIME ;GET THE TIME OF DAY.
GOSUB TYPTIM ;PRINT THE TIME.
EME .CH,[EXP 11] ;TAB TO NEXT ZONE.
MME T1,.DATE ;GET THE DATE.
GOSUB TYPDAT ;TYPE THE DATE.
GOSUB CRLF ;SKIP A LINE.
EME .CH,[EXP 12] ;SKIP A LINE.
SKIPN RETWRD ;SKIP IF THERE IS A COMMAND.
GOTO NOCOM ;TELL HIM NO GO.
HRRZS RETWRD ;FLAG THAT WE DO THIS ONE.
GOTO ENDCM0 ;AND DO IT.
;HERE FOR DIALOG MODE. DIALOG IS ENTERED BY TYPING ONLY
;AN ALTMODE ON THE LINE. IT IS LEFT BY TYPING A CONTROL C
;NOTE: ANY COMMAND UP TO THIS POINT IS ERASED.
DIALOG: XCT CRLF ;SKIP A LINE.
PRINT (Entering dialog mode.)
SETZM FSTMEM ;CLEAR FIRST MEMORY CELL.
MOVE T1,[XWD FSTMEM,FSTMEM+1];BLT POINTER.
BLT T1,LSTMEM ;CLEAR ANY RETAINED COMMAND.
MOVE T1,[SIXBIT "0001"] ;VOLUME NUMBER EXPECTED.
MOVEM T1,IFILE+VOL ;SET IT.
MOVEM T1,OFILE+VOL ;IN BOTH SPECIFICATONS.
SETZM RETWRD ;FLAG NOT TO RETAIN COMMAND.
MOVEI SIDE,IFILE ;SET AN INDEX.
XCT CRLF ;SKIP A LINE.
PRINT (*** Input specifications ***)
GOSUB DIAGET ;GET THE SPECS.
MOVEI SIDE,OFILE ;SET AN INDEX.
SETZM S ;CLEAR A REGISTER.
XCT CRLF ;SKIP A LINE.
PRINT (*** Output specificaions ***)
GOSUB DIAGET ;GET THE SPEC.
HRROS RETWRD ;FLAG COMMAND SHOULD BE RETAINED.
SETZM DIAFLG ;CLEAR RETURN FLAG.
GOTO PERFOR ;PERFORM THE COMMAND.
DIAGET: DIARET ;SET RETURN ADDRESS.
MOVEI T1,6 ;PLACE ON LINE.
MOVEM T1,SPCCNT ;FOR ERROR ROUTINE.
EME .STR,[ASCIZ "File: "] ;ASK FOR DEV:FILE.EXT[P,PN].
DIA0: GOSUB GETSIX ;GET A SIXBIT WORD.
IF.OFF S,COL,DIA1 ;JUMP IF SKIPPED DEVICE.
GOSUB GETDEV ;GET THE DEVICE.
DIA1: GOSUB NAMCHK ;GET THE FILE NAME.
DIA2: IF.OFF S,BRK,DIA3 ;JUMP IF NO PPN.
GOSUB GETPPN ;ELSE GET THE PPN.
DIA3: IF.OFF S,EOL,COMERR ;COMMAND ERROR IF NOT EOL.
MOVE T1,DEVICE(SIDE) ;GET THE DEVICE.
JUMPE T1,WBEDSK ;JUMP IF WILL BE DISK.
MME T1,.DEV ;SEE WHAT IT IS.
IF.OFF T1,DSK!DTA!MTA,DIA3X ;JUMP IF NOT A DIRECTORY DEVICE.
WBEDSK: DIARET ;SET ERROR RETURN.
MOVEI T1,6 ;PLACE ON LINE.
MOVEM T1,SPCCNT ;SAVE IT.
EME .STR,[ASCIZ "Mode: "] ;ASK FOR THE MODE.
ON S,COL ;SO WE THINK A COLON WAS TYPED.
GOSUB SW.M ;GET THE MODE.
IF.OFF S,EOL,COMERR ;JUMP IF NOT EOL.
EME .STR,[ASCIZ "Do records cross logical blocks: "]
GOSUB YESNO ;GET THE ANSWER.
SKIPA ;SKIP INTO GOODNESS.
GOTO DIA3A ;JUMP IF NOT.
MOVEI T1,SPAN ;GET THE SPAN BIT.
IORM T1,MOD(SIDE) ;SET THE BIT.
DIA3A: DIARET ;SET ERROR RETURN.
MOVEI T1,^D13 ;WHERE WE ARE ON LINE.
MOVEM T1,SPCCNT ;SAVE THE COUNT.
EME .STR,[ASCIZ "Record size: "]
ON S,COL ;SO A COL IS SEEN.
GOSUB SW.R ;GET THE RECORD SIZE.
IF.OFF S,EOL,COMERR ;COMMAND ERROR IF NOT EOL.
DIARET ;SET ERROR RETURN.
MOVEI T1,^D17 ;PLACE ON LINE.
MOVEM T1,SPCCNT ;FOR ERROR ROUTINE.
EME .STR,[ASCIZ "Blocking factor: "]
ON S,COL ;SO WE THINK A COLON WAS TYPED.
GOSUB SW.B ;GET THE BLOCKING FACTOR.
IF.OFF S,EOL,COMERR ;IF NOT EOL.
DIA3X: DIARET ;SET ERROR RETURN.
MOVEI T1,^D9 ;PLACE ON LINE.
MOVEM T1,SPCCNT ;SAVE THE LINE POSITION.
EME .STR,[ASCIZ "Buffers: "];ASK HOW MANY BUFFERS.
ON S,COL ;FLAG TO GET ARGUMENT.
GOSUB SW.BUF ;GET THE BUFFER SWITCH.
IF.OFF S,EOL,COMERR ;JUMP IF NOT ENDED RIGHT.
SETZM IM ;CLEAR A REGISTER.
EME .STR,[ASCIZ "Stop on errors: "]
GOSUB YESNO ;GET A REPLY.
GOTO DIA3BX ;JUMP IF YES.
ON IM,NOERROR ;LIGHT A BIT.
DIA3BX: MOVE T1,CHRMOD(SIDE) ;GET THE MODE.
CAILE T1,GEAMOD ;SKIP IF ASCII.
GOTO DIA3B ;ELSE JUMP.
EME .STR,[ASCIZ "CRLF'S IN ASCII FILE: "]
GOSUB YESNO ;GET A REPLY.
SKIPA ;SKIP INTO GOODNESS.
ON IM,NOCRLF ;LIGHT A BIT.
DIA3B: IORM IM,MOD(SIDE) ;SAVE THE BITS.
MOVE T1,DEVICE(SIDE) ;GET THE DEVICE.
MME T1,.DEV ;GET ITS CHARACTERISTICS.
IF.OFF T1,LPT,DIA4 ;JUMP IF NOT LPT.
EME .STR,[ASCIZ "Headers for lpt: "]
GOSUB YESNO ;GET A REPLY.
RETURN ZERO ;RETURN IF HE WANTS IT.
MOVEI T1,NOHEAD ;GET THE NO HEADER BIT.
IORM T1,MOD(SIDE) ;SET IT.
RETURN ZERO ;AND RETURN.
DIA4: IF.OFF T1,MTA,RET0 ;RETURN IF NOT MAG-TAPE.
DIARET ;SET ERROR RETURN.
MOVEI T1,^D9 ;PLACE ON LINE.
MOVEM T1,SPCCNT ;SAVE THE SPACE COUNT.
EME .STR,[ASCIZ "Density: "];ASK FOR THE TAPES DENSITY.
ON S,COL ;TO FLAG ARGUMENT.
GOSUB SW.D ;READ IT IN.
IF.OFF S,EOL,COMERR ;JUMP IF NOT EOL.
DIARET ;SET ERROR RETURN.
MOVEI T1,^D8 ;PLACE ON LINE.
MOVEM T1,SPCCNT ;SAVE THE COUNTER.
EME .STR,[ASCIZ "Parity: "] ;ASK FOR PARITY.
ON S,COL ;TO FLAG ARGUMENT.
GOSUB SW.P ;AND GET IT.
IF.OFF S,EOL,COMERR ;ERROR IF NOT EOL.
DIARET ;SET ERROR RETURN.
MOVEI T1,^D9 ;PLACE ON LINE.
MOVEM T1,SPCCNT ;SAVE FOR ERROR ROUTINE.
EME .STR,[ASCIZ "Advance: "];ASK FOR AN ADVANCE COUNTER.
ON S,COL ;TO FLAG ARGUMENT.
GOSUB SW.A ;READ IT IN.
IF.OFF S,EOL,COMERR ;ERROR IF NOT EOL.
DIARET ;SET ERROR RETURN.
MOVEI T1,^D11 ;PLACE ON LINE.
MOVEM T1,SPCCNT ;SET COUNTER.
EME .STR,[ASCIZ "backspace: "];TELL HIM WE WANT BACKSPACE ARGUMENT.
ON S,COL ;SET COL BIT.
GOSUB SW.BK ;GET AN ARGUMENT.
IF.OFF S,EOL,COMERR ;JUMP IF NOT EOL.
DIARET ;SET ERROR RETURN.
MOVEI T1,^D8 ;PLACE ON LINE.
MOVEM T1,SPCCNT ;SAVE IT.
EME .STR,[ASCIZ "norewind: "];ASK IF DOESN'T WANT TO WIND.
ON S,COL ;FLAG WE HAVE SEEN A COLON.
GOSUB NOREW ;SET THE SWITCH.
IF.OFF S,EOL,COMERR ;JUMP IF NOT EOL.
DIARET ;SET ERROR RETURN.
MOVEI T1,^D7 ;PLACE ON LINE.
MOVEM T1,SPCCNT ;SAVE CHARACTER POSITION.
EME .STR,[ASCIZ "Label: "] ;ASK FOR LABEL TYPE.
ON S,COL ;ARGUMENT IS NEXT.
GOSUB SW.L ;READ THE LABEL TYPE.
IF.OFF S,EOL,COMERR ;JUMP IF NOT END OF LINE.
JUMPE P4,DIA4X ;JUMP IF NO LABEL TYPE.
CAIE SIDE,OFILE ;SKIP IF OUTPUT SPEC.
GOTO DIA4X ;DON'T ASK FOR REEL ON INPUT.
DIARET ;SET ERROR RETURN.
MOVEI T1,^D6 ;PLACE ON LINE.
MOVEM T1,SPCCNT ;SAVE POINTER.
EME .STR,[ASCIZ "Reel: "] ;ASK FOR REEL NUMBER.
ON S,COL ;TO FLAG ARGUMENT.
GOSUB SW.RL ;READ IT.
IF.OFF S,EOL,COMERR ;JUMP IF DIDN'T END RIGHT.
DIA4X: SETZM IM ;CLEAR BIT REGISTER.
EME .STR,[ASCIZ "Industry tape: "]
GOSUB YESNO ;GET A REPLY.
ON IM,IND ;SET A BIT.
EME .STR,[ASCIZ "Unload tape: "]
GOSUB YESNO ;GET A REPLY.
ON IM,UNLOAD ;SET A BIT.
MOVE T1,MOD(SIDE) ;GET THE MOD BITS.
CAIN SIDE,IFILE ;ONLY ASK ON INPUT SIDE.
IF.ON T1,WILD,DIA5 ;JUMP IF WILD.
EME .STR,[ASCIZ "Scan tape for file: "]
GOSUB YESNO ;GET A REPLY.
ON IM,SCAN ;SET SCAN BIT.
DIA5: IORM IM,MOD(SIDE) ;SET THE MODE BITS.
RETURN ZERO ;RETURN.
YESNO: ON S,BAD ;IGNORE BAD CHARACTERS.
MOVE P1,[XWD -YESCNT,YESTAB] ;POINTER FOR TABLE SCAN.
MOVEI P2,YESDIS ;DISPATCH TABLE.
GOTO UNIMAT ;CHECK COMMAND.
YESRET: IF.OFF S,EOL,XYNRET ;BAD ANSWER.
RETURN ZERO ;YES RETURN.
NORET: IF.OFF S,EOL,XYNRET ;BAD ANSWER.
RETURN ONE ;NO RETURN.
XYNRET: IF.ON S,EOL ;SKIP IF END OF LINE.
GOSUB GETONE ;FIND END OF LINE.
IF.ON S,EOL ;SKIP IF EOL.
GOTO .-2 ;TRY AGAIN.
PRINT (? Answer YES or NO.)
UNSAVE T1 ;GET THE RETURN FROM STACK.
GOTO -TWO(T1) ;TRY AGAIN.
;HERE ON A PRINT COMMAND TO DISPLAY THE CURRENT COMMAND.
XPRINT: SKIPN RETWRD ;SKIP IF RETAINING.
GOTO NTHERE ;ELSE IGNORE COMMAND.
GOSUB CRLF ;SKIP A LINE.
EME .STR,[ASCIZ "Out= "] ;SAY OUTPUT IS COMING.
MOVEI SIDE,OFILE ;GET INDEX FOR OUTPUT SIDE.
GOSUB XPRNT0 ;TELL GOOD THINGS.
EME .STR,[ASCIZ "In= "] ;SAY INPUT IS COMING.
MOVEI SIDE,IFILE ;INPUT INDEX.
SAVE [NTHERE] ;RETURN TO THE STACK.
;HERE TO TYPE OUT THE COMMAND FOR ONE SIDE OF THE EQUAL SIGN.
XPRNT0: MOVE P4,MOD(SIDE) ;GET THE MOD BITS.
GOSUB TYPNAM ;TYPE DEV:FILENAME.EXT[P,PN]
SKIPN P1,BLKFCT(SIDE) ;BLOCKING FACTOR YET.
GOTO XPRNT1 ;NO CONTINUE.
EME .STR,[ASCIZ "/BLOCK:"] ;TELL HIM BLOCKING FACTOR IS NEXT.
GOSUB DECOUT ;PRINT IT.
XPRNT1: SKIPN P1,RECSIZ(SIDE) ;IS THERE A RECORD SIZE.
GOTO XPRNT2 ;NO DO THE NEXT THING.
HLRZ T1,P1 ;GET THE LEFT HALF.
JUMPN T1,XPRNT2 ;JUMP IF WE DID IT.
EME .STR,[ASCIZ "/RECORD:"] ;FLAG RECORD SIZE.
GOSUB DECOUT ;OUTPUT IT.
XPRNT2: SKIPN P1,ADVAN(SIDE) ;IS THERE AN ADVANCING COUNT.
GOTO XPRNT8 ;NO JUMP.
EME .STR,[ASCIZ "/ADVANCE:"] ;TELL HIM THE ADVANCE COUNTER.
GOSUB DECOUT ;PRINT IT.
XPRNT8: SKIPN P1,PERGE(SIDE) ;IS THERE A REEL SWITCH.
GOTO XPRNT9 ;NO...
EME .STR,[ASCIZ "/REEL:"] ;TELL WHAT IS COMING.
GOSUB DECOUT ;PRINT IT.
XPRNT9: MOVE T1,STATUS(SIDE) ;GET THE DEVICE STATUS WORD.
IF.OFF T1,EVEN,XPRNT3 ;JUMP IF ODD PARITY.
EME .STR,[ASCIZ "/PARITY:EVEN"] ;SAY EVEN PARITY.
XPRNT3: LDB T1,[POINT 2,DENSITY(SIDE),28] ;GET THE DENSITY BITS.
JUMPLE T1,XPRNT4 ;JUMP IF NONE SPECIFIED.
SOS T1 ;CORRECT IT.
EME .STR,[ASCIZ "/DENSITY:"] ;FLAG DENSITY IS COMING.
MOVE T1,DN.TAB(T1) ;GET THE SIXBIT WORD.
GOSUB PUTSIX ;PRINT IT.
XPRNT4: SKIPN T1,CHRMOD(SIDE) ;GET THE CHARACTER SET INDEX.
GOTO XPRNT5 ;NONE YET.
EME .STR,[ASCIZ "/MODE:"] ;TELL HIM THE MODE.
MOVE T1,CNAM(T1) ;GET THE SIXBIT MODE.
GOSUB PUTSIX ;PRINT THE MODE.
XPRNT5: SKIPN T1,LABEL(SIDE) ;LABEL TYPE YET.
GOTO XPRNTD ;NO JUMP.
EME .STR,[ASCIZ "/LABEL:"] ;FLAG LABEL TYPE COMING.
MOVE T1,LB.TAB(T1) ;GET THE TYPE SPECIFIED.
GOSUB PUTSIX ;PRINT IT.
XPRNTD: SKIPN P1,BUFNUM(SIDE) ;DID HE SPECIFY BUFFERS.
GOTO XPRNTA ;NO CONTINUE ON.
EME .STR,[ASCIZ "/BUFFERS:"];SAY BUFFERS IS NEXT.
GOSUB DECOUT ;PRINT THE NUMBER.
XPRNTA: SKIPN P1,BACSPC(SIDE) ;ANY BACKSPACE COUNTER.
GOTO XPNT99 ;NO FORGET IT.
EME .STR,[ASCIZ "/BACKSPACE:"];TELL WHAT IS COMING.
GOSUB DECOUT ;PRINT IT.
XPNT99: MOVE P3,MOD(SIDE) ;GET THE MOD BITS.
TRC P3,AWIND!BWIND ;COMPLEMENT WIND BITS.
TRCN P3,AWIND!BWIND ;SKIP IF BOTH NOT ON.
ON P3,NOWIND ;FLAG BO]H ON.
IF.OFF P3,AWIND!BWIND!NOWIND,XPNT88;JUMP IF NONE ON.
EME .STR,[ASCIZ "/NOREWIND:"];FLAG A NOWIND.
IF.OFF P3,AWIND ;SKIP IF NOT AFTER.
MOVE T1,REWTAB ;POINTER TO AFTER MESSAGE.
IF.OFF P3,BWIND ;SKIP IF NOT BEFORE.
MOVE T1,REWTAB+1 ;POINTER TO BEFORE MESSAGE.
IF.OFF P3,NOWIND ;SKIP IF NOT NEVER.
MOVE T1,REWTAB+2 ;POINTER TO ALWAYS MESSAGE.
GOSUB PUTSIX ;SEND MESSAGE.
XPNT88: CAIE SIDE,OFILE ;ONLY ON THE OUTPUT SIDE.
GOTO XPRNT6 ;CONTINUE ON.
SKIPE TELWRD ;SKIP IF TALKING.
EME .STR,[ASCIZ "/NOTELL"] ;TELL HIM NO TALK.
SKIPN LSTWRD ;SKIP IF LISTING.
GOTO XPRNTZ ;CARRY ON.
MOVE T1,[EME .STR,[ASCIZ "/LIST"]];IF LIST OPTION.
SKIPE FSTWRD ;SKIP IF NORMAL LIST.
MOVE T1,[EME .STR,[ASCIZ "/FLIST"]];FOR FAST LIST.
XCT T1 ;PRINT IT.
XPRNTZ: SKIPE PASS ;IS THERE A PASSWORD.
GOTO XPRNTB ;YES TYPE IT.
SKIPN PASS+1 ;CHECK THE OTHER HALF.
GOTO XPRNT6 ;NO PASSWORD.
XPRNTB: EME .STR,[ASCIZ "/PASSWORD:"] ;TELL HIM PASSWORD IS NEXT.
MOVE P1,[POINT 6,PASS] ;GET A POINTER.
XPRNTC: ILDB CH,P1 ;GET A CHARACTER.
MOVEI CH," "(CH) ;CONVERT IT TO ASCII.
EME .CH,CH ;PRINT IT.
CAME P1,[XWD 600,PASS+1] ;SKIP IF DONE.
GOTO XPRNTC ;ELSE DO MORE.
XPRNT6: HRLZI P4,-NWUCNT ;COUNT OF OTHER SWITCHES.
MOVE P3,MOD(SIDE) ;GET THE MOD BITS.
TDNE P3,NWUTAB(P4) ;TEST A BIT.
GOSUB XPRNT7 ;THIS ONE IS ON.
AOBJN P4,.-2 ;DO THE NEXT ONE.
GOTO CRLF ;SKIP A LINE AND EXIT.
XPRNT7: EME .CH,[EXP "/"] ;FLAG A SWITCH.
MOVE T1,SW.TAB(P4) ;GET ITS NAME.
GOTO PUTSIX ;PRINT IT.
;HERE WHEN AN "@" IS FOUND IN THE COMMAND STRING. THIS MEANS
;TAKE THE DEV:FILE.EXT[P,PN] POINTED TO BY THE AC SIDE AND
;OPEN IT. IF THE FILE IS FOUND USE IT FOR INPUT TO CHANGE.
CCLCOM: SAVE SPCCNT ;SAVE THE CHARACTER POSITION.
IF.ON S,EOL ;SKIP IF AT END OF COMMAND.
GOSUB GETONE ;GET A CHARACTER.
IF.ON S,EOL ;SKIP IT AT END OF LINE.
GOTO .-2 ;SKIP REST OF COMMAND.
UNSAVE SPCCNT ;RESTORE THE CHARACTER POSITION.
GOSUB NAMCHK ;MAYBE SOMETHING IN WD.
SKIPL P1,CCLFLG ;GET POINTER TO LAST BLOCK.
MOVEI P1,CCLBLK+1-CCLCNT ;NONE USE FIRST.
ADDI P1,CCLCNT ;POINT POINTER TO NEXT BLOCK.
HRRZS P1 ;ZERO THE LEFT HALF.
CAIL P1,CCLEND ;ARE WE TOO DEEP.
GOTO TOODEP ;CCL FILES NESTED TO DEEPLY.
HRRM P1,CCLFLG ;SAVE POINTER.
HRLZI T1,NAME(SIDE) ;SOURCE FOR BLT.
HRRI T1,CCLNAM(P1) ;POINTER TO SPOT IN BLOCK.
BLT T1,CCLPPN(P1) ;SAVE TE NAME.
SKIPN T1,DEVICE(SIDE) ;GET THE DEVICE.
MOVSI T1,'DSK' ;DEFAULT DEVICE.
MOVEM T1,CCLDEV(P1) ;SAVE THE DEVICE.
MME T1,.DEV ;GET THE CHARACTERISTICS.
SKIPN T1 ;DOES IT EXIST.
JSP T1,CCLBAK ;NO CCL DEVICE.
NOP NOEXT ;WHERE TO GO.
IF.OFF T1,DSK!DTA,NOUSE ;CAN'T USE DEVICE.
XCT CCLOPN(P1) ;OPEN THE DEVICE.
GOTO CCLNDV ;DEVICE NOT AVAILABLE.
NOP NODEV ;WHERE TO GO.
XCT CCLLOK(P1) ;OPEN THE FILE.
GOTO NOCCL ;CAN'T FIND FILE.
HRROS CCLFLG ;FLAG WE HAVE A CCL FILE.
XCT CCLBUF(P1) ;GET A BUFFER.
HRRZ T1,.JBFF ;GET THE FIRST FREE.
MOVEM T1,CCLCOR ;SAVE FOR CORE MME.
GOTO NTH1 ;READ FILE AND DO COMMAND.
CCLBAK: HRRZ T2,CCLFLG ;GET THE POINTER WORD.
XCT CCLREL(T2) ;RELEASE DEVICE.
SUBI T2,CCLCNT ;POINT IT RIGHT.
HRRM T2,CCLFLG ;REPLACE FLAG.
GOTO @ZERO(T1) ;CALL ERROR ROUTINE.
CCLNDV: NOP @CCLOPN(P1) ;POINTER TO DEVICE.
JSP T1,CCLBAK ;BACK UP POINTER.
NOP NODEV ;WHERE TO GO ON ERROR.
USE DATA
CCLBLK: CBLK CF,CCLLEN
CCLEND==.-1
USE CODE
;HERE TO GET THE DEVICE SPECIFIED FROM THE USER.
GETDEV: ON S,DEV ;SAY WE HAVE SEEN A DEVICE.
MOVEI T1,WDEV ;GET WILD DEVICE BIT.
ANDCAM T1,MOD(SIDE) ;TURN IT OFF.
GOSUB CHKNAM ;SEE IF IT IS WILD.
ON T1,WDEV ;TO SET THE RIGHT BIT.
IF.OFF T1,WDEV ;SKIP IF NOT WILD.
MOVSI WD,'DSK' ;SET THE RIGHT NAME.
MOVEM WD,DEVICE(SIDE) ;SAVE THE DEVICE IN BLOCK.
GOTO GETSIX ;GET NEXT COMMAND WORD.
;HERE TO GET THE FILE NAME SPECIFIED FROM
;THE USER.
NAMCHK: JUMPE WD,RET0 ;JUMP IF NO NAME.
GETNAM: MOVEI T1,WNAME!WEXT ;GET THE WILD BITS.
ANDCAM T1,MOD(SIDE) ;TURN OFF WILD BITS.
GOSUB CHKNAM ;CHECK OUT THE NAME.
ON T1,WNAME ;FOR WILD CHECK.
MOVEM WD,NAME(SIDE) ;SAVE THE FILE NAME.
MOVEM T2,NAMMSK(SIDE) ;SAVE THE MASK.
SETZM WD ;CLEAR COMMAND WORD.
IF.OFF S,PER ;SKIP IF NO EXTENSION.
GOSUB GETSIX ;GET THE EXTENSION.
GOSUB CHKNAM ;CHECK FOR WILDS.
ON T1,WEXT ;FOR WILD CHECK.
MOVEM WD,EXT(SIDE) ;SAVE THE EXTENSION.
MOVEM T2,EXTMSK(SIDE) ;SAVE THE MASK.
SETZM WD ;CLEAR WD TO DO GOOD THINGS LATER.
RETURN ZERO ;BACK TO CALLER.
CHKNAM: SETZB T1,T2 ;CLEAR SOME REGISTERS.
CAME WD,[SIXBIT "*"] ;IS IT WILD.
RETURN ONE ;NO.
SETOM T2 ;SET THE MASK.
SETBIT: XCT @ZERO(PDP) ;YES SET A BIT.
IORM T1,MOD(SIDE) ;AND LEAVE A TRACE.
OFF S,STAR ;TURN OFF STAR BIT.
RETURN ONE ;BACK TO CALLER.
;HERE TO PICK UP A PPN FROM THE USER.
GETPPN: ON S,NUM ;SAY WE HAVE A PPN.
MOVEI T1,WP!WPN ;GET THE WILD BITS.
ANDCAM T1,MOD(SIDE) ;AND CLEAR THEM.
GOSUB NAMCHK ;SEE IF THERE IS SOMETHING IN WD.
GOSUB GETHAL ;GET THE PROJECT NUMBER.
ON T1,WP ;FOR WILD CHECK.
CAIE CH,"," ;SEE IF RIGHT DELIMITER.
GOTO PPNERR ;IF NOT ERROR.
OFF S,STAR!NOSTAR ;TREAT COMA AS A DELIMTER HERE.
HRLZM P2,PPN(SIDE) ;SAVE THE PROJECT NUMBER.
GOSUB GETHAL ;GET THE OTHER HALF.
ON T1,WPN ;FOR WILD CHECK.
HRRM P2,PPN(SIDE) ;SAVE PROJECT NUMBER.
IF.ON S,EOL,RET0 ;ALLOW NO CLOSING BRACKET AT EOL.
CAIE CH,"]" ;MUST HAVE THE RIGHT DELIMITER.
GOTO PPNERR ;BAD PROGRAM NUMBER.
GOTO GETSIX ;GET NEXT WORD.
GETHAL: GOSUB GETOCT ;GET AN OCTAL NUMBER.
JUMPE P2,GTHAL ;MUST HAVE SOMETHING.
IF.ON P2,-1B17,PPNERR ;MUST BE POSITIVE IN THE RIGHT HALF.
RETURN ONE ;TAKE IT TO CALLER.
GTHAL: CAIE CH,"*" ;IS IT WILD.
GOTO PPNERR ;NO SO BAD PPN.
GOSUB GETONE ;GET ONE PAST STAR.
SETZM T1 ;CLEAR A REGISTER.
GOTO SETBIT ;AND SET A BIT.
;HERE TO GET THE SWITCHES FROM THE USER.
GETSW: GOSUB NAMCHK ;SEE IF ANYTHING IN WD.
MOVE P1,[XWD -SW.CNT,SW.TAB] ;AOBJ WORD FOR TABLE SCAN.
MOVEI P2,SW.DIS ;SWITCH DISPATCH TABLE.
SAVE [SW.RET] ;PUT A RETURN ON THE STACK.
GOTO UNIMAT ;MATCH IT AND DISPATCH.
;HERE TO PICK UP AND SET THE BITS FOR ANY
;SWITCH THAT DOES NOT TAKE AN ARGUMENT.
SW.NWU: MOVE T1,NWUTAB(P4) ;PICK UP THE BIT TO SET.
IORM T1,MOD(SIDE) ;SET THE BIT.
RETURN ZERO ;RETURN FOR NEXT COMMAND.
;HERE TO TURN BITS OFF IN A STATUS WORD.
SW.OFF: MOVE T1,NWUTAB-NWUCNT(P4) ;GET THE BIT TO TURN OFF.
ANDCAM T1,MOD(SIDE) ;TURN IT OFF.
RETURN ZERO ;GET THE NEXT COMMAND.
;HERE TO PICK UP THE VALUE OF THE PARITY
;SWITCH. IF NOT SPECIFIED THIS SWITCH DEFAULTS
;TO ODD PARITY.
SW.P: TNO S,PAR,SWERR ;ONLY HERE ONCE.
IF.OFF S,COL,FOMERR ;NEED THE COLON BIT.
MOVE P1,[XWD -PR.CNT,PR.TAB] ;AOBJ WORD FOR TABLE SCAN.
MOVEI P2,PR.DIS ;DISPATCH TABLE.
GOTO UNIMAT ;MATCH THE COMMAND.
ODDRET: SKIPA T1,[ANDCAM T2,STATUS(SIDE)] ;TO CLEAR THE EVEN PARITY BIT.
EVERET: MOVE T1,[IORM T2,STATUS(SIDE)] ;TO SET THE EVEN PARITY BIT.
MOVEI T2,EVEN ;THE BIT TO DO THINGS WITH.
XCT T1 ;DO IT.
RETURN ZERO ;BACK TO SENDER.
;HERE ON A TELL SWITCH.
XTELL: SETZM TELWRD ;CLEAR TALK WORD.
RETURN ZERO ;BACK TO CALLER.
;HERE ON A NOTELL SWITCH
XNTELL: SETOM TELWRD ;SET TELWRD NON-ZERO.
RETURN ZERO ;AND RETURN.
;HERE TO READ THE PASSWORD FOR GE LABELS.
SW.PW: IF.OFF S,COL,FOMERR ;MUST HAVE A COLON.
MOVE T3,[POINT 6,PASS] ;SET POINTER TO STORAGE.
SETZM PASS ;CLEAR STORAGE.
SETZM PASS+1 ;CLEAR STORAGE.
PASLOP: ON S,NOCHK ;DON'T VALIDATE INPUT.
GOSUB GETONE ;GET A CHARACTER.
IF.ON S,SOM,RET0 ;RETURN IF DELIMITER.
SUBI CH," " ;CONVERT IT TO SIXBIT.
CAME T3,[XWD 600,PASS+1] ;SKIP IF POINTER HAS RUN OUT.
IDPB CH,T3 ;ELSE SAVE THE CHARACTER.
GOTO PASLOP ;LOOP UNTIL A DELIMITER.
;HERE TO SET THE CONVERSION MODE THAT IS TO
;BE DONE.
SW.M: TNO S,MODE,SWERR ;ONLY ONE MODE PER FILE.
IF.OFF S,COL,FOMERR ;FORMAT ERROR IF NO COLON.
MOVE P1,[XWD -M.CNT,M.TAB] ;POINTER TO TABLE.
MOVEI P2,M.DIS ;MODE DISPATCH TABLE.
ON S,NODIS ;SHORT DISPATCH TABLE.
GOTO UNIMAT ;FIND A MATCH.
M.RET: MOVE P4,MODTAB(P4) ;GET TABLE ADDRESS OF DATA.
MOVEM P4,CHRMOD(SIDE) ;SAVE THE MODE.
RETURN ZERO ;BACK FOR THE NEXT ONE.
;HERE TO SET UP THE BLOCKING FACTOR.
SW.B: TNO S,BLK,SWERR ;ONLY ONE BLOCKING FACTOR.
GOSUB NUMVAL ;GET THE VALUE OF THE SWITCH.
MOVEM P2,BLKFCT(SIDE) ;SAVE THE BLOCKING FACTOR.
RETURN ZERO ;BACK TO CALLER.
;HERE TO SET UP THE RECORD SIZE FOR THE FILE.
SW.R: TNO S,REC,SWERR ;ONLY HERE ONCE.
GOSUB NUMVAL ;READ THE VALUE.
MOVEM P2,RECSIZ(SIDE) ;SAVE THE RECORD SIZE.
RETURN ZERO ;BACK TO CALLER.
;HERE TO PICK UP THE VALUE OF THE ADVANCE SWITCH.
SW.A: TNO S,ADV,SWERR ;ONLY ONCE HERE.
GOSUB NUMVAL ;GET THE VALUE.
MOVEM P2,ADVAN(SIDE) ;SAVE IN DATA BLOCK.
RETURN ZERO ;BACK TO CALLER.
;HERE TO GET THE BACKSPACE ARGUMENT.
SW.BK: TNO S,BAC,SWERR ;ONLY HERE ONCE.
GOSUB NUMVAL ;GET THE ARBUMENT.
MOVEM P2,BACSPC(SIDE) ;SAVE THE ARGUMENT.
RETURN ZERO ;BACK FOR MORE.
;HERE FOR A REWIND SWITCH.
REWIND: IF.OFF S,COL,FOMERR ;JUMP IF NO COLON.
MOVE P1,[XWD -REWCNT,REWTAB] ;AOBJN POINTER FOR TABLE SCAN.
MOVEI P2,REWDIS ;DISPATCH TABLE.
ON S,NODIS ;SHORT DISPATCH TABLE.
GOTO UNIMAT ;FIND A MATCH.
REWRET: CAIL P4,THREE ;DID HE TYPE OMITT.
GOTO NOW0 ;YES DON'T REWIND.
REW0: MOVE T1,REWBIT(P4) ;GET THE BIT.
ANDCAM T1,MOD(SIDE) ;SET IT.
RETURN ZERO ;AND RETURN.
;HERE FOR A NOWIND SWITCH.
NOREW: IF.OFF S,COL,FOMERR ;JUMP IF NO COLON.
MOVE P1,[XWD -REWCNT,REWTAB] ;POINTER FOR TABLE SCAN.
MOVEI P2,NORDIS ;DISPATCH TABLE POINTER.
ON S,NODIS ;SHORT DISPATCH TABLE.
GOTO UNIMAT ;FIND A MATCH.
NOWRET: CAIL P4,THREE ;DID HE TYPE OMITT.
GOTO REW0 ;YES REWIND IT.
NOW0: MOVE T1,REWBIT(P4) ;GET THE BIT TO CLEAR.
IORM T1,MOD(SIDE) ;CLEAR THE BITS.
RETURN ZERO ;BACK TO CALLER.
;HERE TO PICK UP THE VALUE OF THE DENSITY SWITCH.
SW.D: TNO S,DEN,SWERR ;ONLY ONE DENSITY PER FILE.
IF.OFF S,COL,FOMERR ;NEED THE COLON BIT HERE.
MOVE P1,[XWD -DN.CNT,DN.TAB] ;SET UP POINTER.
MOVEI P2,DN.DIS ;DISPATCH TABLE.
ON S,NODIS ;SHORT DISPATCH TABLE.
GOTO UNIMAT ;FIND A MATCH.
D.RET: AOS P4 ;BUMP THE COUNTER.
DPB P4,[POINT 2,DENSITY(SIDE),28];SET THE DENSITY.
RETURN ZERO ;BACK TO CALLER.
;HERE TO GET THE LABEL TYPE.
SW.L: TNO S,LAB,SWERR ;CAN ONLY HAVE ONE LABEL TYPE.
IF.OFF S,COL,FOMERR ;FORMAT ERROR IF NO COLON.
MOVE P1,[XWD -LB.CNT,LB.TAB] ;SET POINTER.
MOVEI P2,LB.DIS ;DISPATCH TABLE.
ON S,NODIS ;SHORT DISPATCH TABLE.
GOTO UNIMAT ;GO FIND A MATCH.
L.RET: MOVEM P4,LABEL(SIDE) ;SAVE THE LABEL TYPE.
RETURN ZERO ;BACK TO CALLER.
;HERE TO GET THE VALUE OF THE REEL SERIAL NUMBER THAT
;SHOULD BE WRITTEN IN THE OUTPUT LABEL IF THE LABEL
;TYPE SPECIFIED USES A REEL SERIAL NUMBER.
SW.RL: TNO S,REL,SWERR ;ONLY HERE ONCE.
GOSUB NUMVAL ;READ THE SWITCH'S VALUE.
MOVEM P2,PERGE(SIDE) ;SAVE THE SERIAL NUMBER.
RETURN ZERO ;BACK TO CALLER.
;HERE FOR THE RETAIN SWITCH IN THE COMMAND STRING.
SW.KEP: SETOM RETWRD ;FLAG RETAIN MODE.
RETURN ZERO ;GET THE NEXT ONE.
;HERE ON A PERFORM SWITCH. SET THE FLAG TO SAY WE WILL DO IT.
;AND EXIT.
SW.GO: SETOM RETWRD ;RETAIN COMMAND FIRST.
HRRZS RETWRD ;FLAG THAT WE ARE TO DO IT.
RETURN ZERO ;AND RETURN.
;HERE TO GET THE NUMBER OF BUFFERS TO USE.
SW.BUF: TNO S,XBUF,SWERR ;JUMP IF BEEN HERE BEFORE.
GOSUB NUMVAL ;GET THE VALUE OF THE ARGUMENT.
MOVEM P2,BUFNUM(SIDE) ;SAVE THE NUMBER.
RETURN ZERO ;BACK TO CALLER.
;HERE TO READ THE VALUE OF A NUMERIC SWITCH.
NUMVAL: IF.OFF S,COL,FOMERR ;MUST HAVE THE COLON.
SAVE SPCCNT ;SAVE THE CHARACTER COUNT.
GOSUB GETDEC ;GET THE ARGUMENT.
UNSAVE T1 ;GET BACK CHARACTER COUNT.
AOS T1 ;BUMP FOR CHARACTER READ.
CAMN T1,SPCCNT ;MUST HAVE SOMETHING.
GOTO FOMERR ;FORMAT ERROR.
RETURN ZERO ;BACK TO SENDER.
;HERE ON A LIST SWITCH OR AN FLIST SWITCH.
XFLST: SETOM FSTWRD ;SET FOR A FAST LIST.
SKIPA ;SET THE LIST WORD.
XLST: SETZM FSTWRD ;CLEAR FAST LIST WORD.
SETOM LSTWRD ;SET TO DO A LIST.
RETURN ZERO ;RETURN.
;HERE ON A NOLIST SWITCH.
XNLST: SETZM LSTWRD ;CLEAR LIST WORD.
SETZM FSTWRD ;CLEAR FAST WORD.
RETURN ZERO ;AND RETURN.
;HERE TO RECYCLE THE COMMAND DECODER FOR THE
;INPUT FILE SPECIFICATIONS.
RESYNC: GOSUB NAMCHK ;SEE IF FILE NAME IS PRESENT.
TNO S,IOT,COMERR ;ONLY HERE ONCE.
MOVEI SIDE,IFILE ;CHANGE COMMAND INDEX.
TNZ S,DEV!NUM!DEN!PAR!ADV!LAB!MODE!REL!BLK!REC!XBUF,GETWOD
MOVE WD,OFILE+NAME ;GET THE COMMAND WORD.
MOVE P1,[XWD -E.CNT,E.TAB] ;POINTER TO TABLE.
MOVEI P2,E.DIS ;POINTER TO DISPATCH TABLE.
ON S,NODIS ;SHORT DISPATCH TABLE.
GOTO UNICOM ;FIND THE COMMAND.
E.RET: SKIPN OFILE+EXT ;ONLY IF JUST A NAME.
IOR S,E.BIT(P4) ;SET DELAYED COMMAND BIT.
GOTO GETWOD ;GET THE NEXT COMMAND WORD.
;HERE TO GET A SIXBIT WORD FROM THE COMMAND STRING.
;RETURNS THE WORD IN WD WHEN A DELIMITER IS FOUND.
GETSIX: MOVE T3,[POINT 6,WD] ;SET POINTER TO STORAGE.
SETZM WD ;AND THEN CLEAR STORAGE.
SIXLOP: GOSUB GETONE ;GET A CHARACTER.
IF.ON S,SOM,RET0 ;RETURN IF DELIMITER FOUND.
SUBI CH," " ;CONVERT IT TO SIXBIT.
IF.OFF T3,77B5 ;IF WD IS NOT FULL
IDPB CH,T3 ;STACH THE CHARACTER.
GOTO SIXLOP ;LOOP UNTIL DONE.
;HERE TO FIND A UNIQUE MATCH FOR A SIXBIT WORD. ENTER WITH A
;POINTER TO THE SIXBIT TABLE IN P1, A POINTER TO THE DISPATCH
;TABLE IN P2, AND THE LENGTH OF THE TABLE IN THE UPPER HALF OF P1.
UNIMAT: GOSUB GETSIX ;GET A WORD.
UNICOM: OFF S,FNDONE!FNDTWO ;TURN OFF FOUND BITS.
MOVE T1,WD ;COPY COMMAND WORD.
SETOM T2 ;INITIALIZE MASK.
GETMSK: JUMPE T1,GOTMSK ;JUMP IF MASK IS RIGHT.
LSH T1,6 ;SHIFT A CHARACTER OUT.
LSH T2,-6 ;FIX UP THE MASK.
GOTO GETMSK ;TRY AGAIN.
GOTMSK: MOVE T1,P1 ;COPY AOBJN WORD.
NXTENT: JUMPL T2,TRYNXT ;IF NO COMMAND DON'T CHECK.
MOVE T3,ZERO(T1) ;GET A TABLE ENTRY.
ANDCM T3,T2 ;ISOLATE THE CHARACTERS WE WANT.
CAMN WD,ZERO(T1) ;IS IT AN EXACT MATCH.
GOTO GOTMAT ;YES WE HAVE IT.
CAME T3,WD ;IS IT A PARTIAL MATCH.
GOTO TRYNXT ;NO TRY THE NEXT ONE.
TEO S,FNDONE ;WE HAVE FOUND ONE MATCH.
TNO S,FNDONE!FNDTWO ;LOOKS LIKE WE FOUND TWO.
HRRZ P3,T1 ;SAVE THE INDEX.
TRYNXT: AOBJN T1,NXTENT ;CHECK THE WHOLE LIST.
IF.OFF S,FNDONE ;DID WE FIND ANYTING.
IF.OFF S,FNDTWO ;OR TOO MUCH.
HRRZ P3,T1 ;GET ERROR INDEX.
COMGO: SETZM WD ;CLEAR INPUT WORD.
SUBI P3,ZERO(P1) ;P3 IS RELATIVE POINTER TO DISPATCH.
MOVEI P4,ZERO(P3) ;COPY INDEX.
ADDI P3,ZERO(P2) ;P3 IS NOW ABSOLUTE IF LONG DISPATCH.
MOVEI T1,ZERO(P2) ;ASSUME GOODNESS.
IF.OFF S,FNDONE ;DID WE FIND ONE.
IF.OFF S,FNDTWO ;OR TOO MANY.
MOVEI T1,ONE(P2) ;YES SET ERROR RETURN.
TEZ S,NODIS ;IS THERE A LONG DISPATCH TABLE.
GOTO @ZERO(T1) ;NO USE SHORT TABLE.
GOTO @ZERO(P3) ;USE LONG TABLE.
GOTMAT: ON S,FNDONE ;WE HAVE FOUND A MATCH.
HRRZ P3,T1 ;SAVE EXACT MATCH INDEX.
GOTO COMGO ;AND THEN GO TO IT.
;HERE TO GET ONE CHARACTER AND TO SET ALL THE
;FLAGS THAT DESCRIBE THAT CHARACTER.
GETONE: OFF S,COL!PER!SLH!BRK!IO!EOL!SPC!ATS!SOM ;CLEAR SOME FLAGS.
GETCHR: SKIPE RUNFLG ;SKIP IF NOT RUNNING.
GOTO GTONE1 ;JUMP IF SO.
SKIPGE CCLFLG ;SKIP IF NOT IN CCL FILE.
GOSUB REDCCL ;READ CCL FILE.
GTONE1: EME .LN,CH ;GET A CHARACTER.
CAIN CH,12 ;IGNORE LINE-FEEDS.
GOTO GETCHR ;GET ANOTHER CHARACTER.
CAIE CH,15 ;WAS THAT A RETURN.
GOTO GTONE0 ;NO LOOK AT CHCRACTER.
SKIPN RUNFLG ;SKIP IF RUNNING.
SKIPL CCLFLG ;SKIP IF CCL FILE.
EME .LN,T1 ;YES READ LINE-FEED.
GTONE0: CAIN CH,11 ;IS THIS A TAB.
GOTO CNTTAB ;COUNT THE TAB.
AOS SPCCNT ;COUNT THE CHARACTER.
IF.ON S,NOCHK,GETCH0 ;INCLUDE SPACES IF NO CHECK.
CAIN CH," " ;IS IT A SPACE.
GOTO GETCHR ;THEN GET ANOTHER.
GETCH0: HRLZI T1,-CH.CNT ;COUNT OF DELIMITERS.
HLRZ T2,CH.CHR(T1) ;MAKE A SELECTION.
CAME CH,T2 ;AND TEST FOR A MATCH.
AOBJN T1,.-2 ;TEST THE WHOLE LIST.
JUMPGE T1,MAKUP ;BACK TO SENDER NOT SPECIAL.
HRRZ T1,CH.CHR(T1) ;GET THE BITS.
IOR S,T1 ;SET THEM.
OFF S,STAR!NOSTAR ;TURN OFF STAR BITS.
IF.ON S,SPC,CRLF ;SPECIAL CHARACTER.
RETURN ZERO ;BACK TO CALLER.
MAKUP: CAIL CH,140 ;LOWER CASE.
OFF CH," " ;MAKE IT UPPER CASE.
TEZ S,NOCHK ;SHOULD WE VALIDATE INPUT.
GOTO XONE ;NO SO RETURN.
CAIE CH,"," ;LET HIM HAVE A COMA.
CAIN CH,"]" ;IS THIS A BRACKET.
GOTO XONE ;YES IT IS O.K.
IF.ON S,STAR,BADSTR ;JUMP IF STAR IS ON.
CAIN CH,"?" ;IS IT A QUESTION MARK.
GOTO XONE ;THIS IS O.K.
CAIN CH,"*" ;IS IT A STAR.
GOTO GOTSTR ;YES SEE IF O.K.
CAIGE CH,"0" ;IS IT LESS THEN ZERO.
GOTO BADCHR ;ILLEGAL CHARACTER.
CAIG CH,"9" ;BUT LESS THEN NINE.
GOTO XONE ;CHARACTER IS NUMERIC.
CAIL CH,"A" ;IS IT IN THE ALPHABET.
CAILE CH,"Z" ;IS IT PAST THE TOP.
GOTO BADCHR ;YES IT IS ILLEGAL.
XONE: ON S,NOSTAR ;DIDN'T GET A STAR.
RETURN ZERO ;BACK TO CALLER...
GOTSTR: ON S,STAR ;LIGHT STAR BIT.
IF.ON S,NOSTAR,BADCHR ;JUMP IF LAST CHARACTER WASN'T A DELIMTER.
RETURN ZERO ;AND RETURN.
BADSTR: SOS SPCCNT ;POINT POINTER TO STAR.
GOTO BADCHR ;SAY BAD CHARACTER.
CNTTAB: MOVE T1,SPCCNT ;GET THE SPACE COUNT.
IDIVI T1,^D8 ;GET THE POSITIONS TAB MOVED US.
MOVEI T1,^D8 ;SPACES PER TAB.
SUB T1,T2 ;T1 HAS SPACES MOVED.
ADDM T1,SPCCNT ;UPDATE THE SPACE COUNT.
GOTO GETCHR ;GET THE NEXT CHARACTER.
REDCCL: HRRZ CH,CCLFLG ;GET POINTERS TO THINGS.
SOSGE CCLHED+2(CH) ;SKIP IF DATA IN BUFFER.
GOTO CCLUP ;FILL UP THE BUFFER.
ILDB CH,CCLHED+1(CH) ;GET A CHARACTER.
JUMPE CH,REDCCL ;IGNORE NULLS.
CAIN CH,12 ;SKIP IF NOT LINE-FEED.
GOTO REDCCL ;IGNORE LINE-FEEDS.
EME .CH,CH ;PRINT IT.
CAIN CH,15 ;SKIP IF NOT RETURN.
EME .CH,[EXP 12] ;SKIP A LINE.
RETURN ONE ;SKIP RETURN.
CCLUP: OFF S,HUNG ;CLEAR HUNG DEVICE BIT.
AOS %IO ;COUNT DEVICE ACCESS.
XCT CCLGET(CH) ;FILL UP THE BUFFER.
GOTO REDCCL ;CARRY ON.
XCT CCLREL(CH) ;RELEASE CHANNEL.
SUBI CH,CCLCNT ;DECREMENT TO PREVIOUS BLOCK.
HRRM CH,CCLFLG ;SAVE POINTER.
CAIGE CH,CCLBLK ;HAVE WE DONE THEM ALL.
SETZM CCLFLG ;NO LONGER IN CCL FILE.
UNSAVE ZERO(PDP) ;POP RETURN TO STACK.
ON S,EOL!SOM ;MAKE IT AN EOL CHARACTER.
MOVEI CH,15 ;LOAD ONE TO MAKE SURE.
GOTO CRLF ;SKIP A LINE AND EXIT.
;HERE TO GET EITHER A DECIMAL NUMBER OR OCTAL
;NUMBER FROM THE USER.
GETDEC: SKIPA P1,[^D10] ;SET THE RADIX.
GETOCT: MOVEI P1,10 ;SET THE RADIX.
SETZM P2 ;ZERO STORAGE.
NXTDIG: GOSUB GETONE ;GET A CHARACTER.
IF.OFF S,SOM ;DELIMITER.
RETURN ZERO ;YES RETURN.
CAIL CH,"0" ;MUST BE GREATER THEN 0-1.
CAIL CH,"0"(P1) ;BUT LESS THEN BASE.
RETURN ZERO ;BAD NUMBER.
IMUL P2,P1 ;MULTIPLY NUMBER BY BASE.
ADDI P2,-"0"(CH) ;ADD IN NEW DIGIT.
GOTO NXTDIG ;GET ANOTHER ONE.
;HERE TO CALL THE PROGRAM "TABLE" INTO CORE AND GIVE
;IT A CCL ENTRY. WHEN TABLE GETS THIS TYPE OF START
;IT WILL CREATE THE DATA FILE "DSK:CHANGE.DAT" WITH THE
;CONVERSION TABLES IN IT. "TABLE" WILL THEN RERUN CHANGE
;GIVING IT A CCL ENTRY.
CRETAB: MOVSI T1,'SYS' ;TRY DEVICE "SYS" FIRST.
GOSUB RUNIT ;TRY TO RUN IT.
MOVSI T1,'DSK' ;IF ERROR ON "SYS" TRY "DSK".
GOSUB RUNIT ;TRY AND RUN IT.
GOTO NOMAKE ;IF ERROR HERE NO RUN.
RUNIT: MOVEM T1,TABDEV+1 ;SAVE THE DEVICE FOR LOOKUP.
MOVEM T1,TABRUN ;SAVE DEVICE TO RUN FROM.
SETZM TABFIL+3 ;CLEAR PPN WORD.
OPEN IF,TABDEV ;GET THE DEVICE.
RETURN ZERO ;CAN'T HAVE DEVICE.
LOOKUP IF,TABFIL ;FIND THE FILE.
RETURN ZERO ;CAN'T FIND FILE.
MOVE T1,[XWD ONE,TABRUN] ;POINTER TO BLOCK.
MME T1,.RUN ;RUN THE FILE.
RETURN ZERO ;CAN'T RUN IT.
USE DATA
TABDEV: XWD ZERO,DMP ;SO NO BUFFERS.
SIXBIT "SYS"
BSS ONE
TABRUN: SIXBIT "SYS"
TABFIL: SIXBIT "TABLE"
SIXBIT "EXE"
BSS 3
USE CODE
SUBTTL *** END OF COMMAND ***
;HERE ON COMMAND END TO START IT GOING.
ENDCOM: GOSUB NAMCHK ;MAKE SURE IT IS OVER.
MOVE T1,RETWRD ;GET THE PERFORM WORD.
JUMPN T1,ENDCM0 ;JUMP IF RETAINING.
IF.OFF S,IOT,COMERR ;ONE INPUT AND ONE OUTPUT DEVICE.
IF.ON S,DEN!PAR!BLK!ADV!LAB!MODE!REC!REL!XBUF,ENDCM0
TNZ S,DATA,GETTNM ;IF ON GET DATA FILE NAME.
ENDCM0: SETZM S ;CLEAR FLAGS.
SKIPN OF,OFILE+DEVICE ;IS THERE A DEVICE.
HRLZI OF,'DSK' ;SET UP DEFAULT.
MOVEM OF,OFILE+DEVICE ;SAVE DEVICE NAMED.
MME OF,.DEV ;GET ITS CHARACTERISTICS.
SKIPN OF ;DOES IT EXIST.
JSP T1,NOEXT ;NOT FOUND.
HLLZS OF ;ZERO OUT RIGHT HALF.
IORB OF,OFILE+MOD ;SET THE MOD BITS.
SKIPN IF,IFILE+DEVICE ;DEVICE SPECIFIED.
HRLZI IF,'DSK' ;SET DEFAULT.
MOVEM IF,IFILE+DEVICE ;SET UP DEVICE.
MME IF,.DEV ;GET CHARACTERISTICS.
SKIPN IF ;DOES IT EXIST.
JSP T1,NOEXT ;NOPE...NOT THERE.
HLLZS IF ;SET UP BITS.
IORB IF,IFILE+MOD ;SET ALL THE MOD BITS.
HLRZ T1,OFILE+RECSIZ ;GET THE OUTPUT RECORD SIZE.
SKIPE T1 ;DID WE SET IT.
SETZM OFILE+RECSIZ ;YES SO CLEAR IT.
MOVEI T1,BIN ;MODE.
IORM T1,OFILE+STATUS ;SET THEM.
IORM T1,IFILE+STATUS ;SET THEM.
HRLZI T1,OBUF ;GET POINTER TO BUFFER HEADER.
IF.OFF OF,MTA ;IS THIS MAG-TAPE.
HRRI T1,OIBUF ;YES SO GET A INPUT HEADER.
MOVEM T1,OFILE+BUFFER ;SAVE IN PLACE.
MOVEI T1,IBUF ;GET POINTER TO INPUT HEADER.
HRRZM T1,IFILE+BUFFER ;SAVE IN PLACE.
IF.OFF OF,GDEV,NOOUSE ;CAN'T USE THIS DEVICE.
IF.ON OF,MTA!DSK!DTA,OPNO1 ;JUMP IF THIS IS MTA, DSK, OR DTA.
IF.OFF OF,OTP,NOOUT ;JUMP IF CAN'T DO OUTPUT.
MOVEI T1,ASC ;ASCII DATA MODE.
MOVEM T1,OFILE+STATUS ;SAVE AS STATUS FOR DEVICE.
MOVE T1,OFILE+CHRMOD ;GET THE MODE OF OUTPUT.
CAIN T1,OCTMOD ;ALLOW OCTAL OUTPUT.
GOTO OPNO1 ;DON'T CHANGE TO ASCII.
SETZM OFILE+BLKFCT ;SET BLOCKING FACTOR TO ZERO.
SKIPN T1,OFILE+RECSIZ ;SKIP IF RECORD SPECIFIED.
HRLOI T1,377777 ;RECORD SIZE TO INFINITY.
MOVEM T1,OFILE+RECSIZ ;SAVE THE RECORD SIZE.
MOVEI T1,ASCMOD ;SO WE READ THE RIGHT TABLES.
MOVEM T1,OFILE+CHRMOD ;SAVE CHARACTER MODE.
OPNO1: MOVE T1,OFILE+DENSITY ;SET DENSITY UP FOR MAG-TAPE.
IF.OFF OF,MTA ;IS THIS MAG-TAPE.
IORM T1,OFILE+STATUS ;OR INTO PLACE.
OPNOUT: IF.OFF IF,GDEV,NOIUSE ;CAN'T USE THIS DEVICE.
IF.ON IF,MTA!DSK!DTA,OPNI1 ;JUMP IF DSK, MTA, OR DTA.
IF.OFF IF,IPT,NOINP ;JUMP IF CAN'T DO INPUT.
MOVEI T1,ASC ;ASCII DATA MODE.
MOVEM T1,IFILE+STATUS ;SAVE AS DEVICE STATUS.
SETZM IFILE+BLKFCT ;SET BLOCKING FACTOR TO ZERO.
MOVEI T1,ASCMOD ;SET INDEX FOR TABLES.
MOVEM T1,IFILE+CHRMOD ;SAVE DEVICE DATA MODE.
OPNI1: MOVE T1,IFILE+DENSITY ;SET UP DENSITY FOR MTA.
IF.OFF IF,MTA ;IS IT A MAG-TAPE.
IORM T1,IFILE+STATUS ;SET IT.
OPNINP: SKIPN LSTWRD ;ARE WE GOING TO LIST IT.
GOTO OPNIP0 ;NO JUMP.
IF.OFF OF,WILD ;SKIP IF NOT WILD.
SETZM OFILE+NAME ;CLEAR NAME IF WILD.
OFF OF,WILD ;TURN OFF WILD BITS.
MOVEM OF,OFILE+MOD ;SET INTO STORAGE.
SKIPN IFILE+NAME ;SKIP IF FILE NAME.
IORI IF,WNAME!WEXT ;ELSE MAKE NAME WILD.
MOVEM IF,IFILE+MOD ;SAVE THEM.
OPNIP0: SKIPE OFILE+NAME ;NAME SPECIFIED.
GOTO ONDEV ;YES ONTO THE DEVICE.
MOVE T2,[SIXBIT "OUTPUT"] ;NO SET DEFAULT.
MOVEM T2,OFILE+NAME ;SAVE.
HRLZI T2,'DAT' ;DEFAULT EXTENSION.
MOVEM T2,OFILE+EXT ;SAVE EXTENSION.
ONDEV: SKIPE IFILE+NAME ;NAME SPECIFIED.
GOTO OFFDEV ;YES TAKE IT OFF THE DEVICE.
MOVE T2,[SIXBIT "INPUT"] ;NO SET UP DEFAULT.
MOVEM T2,IFILE+NAME ;SAVE.
HRLZI T2,'DAT' ;SET UP DEFAULT EXTENSION.
MOVEM T2,IFILE+EXT ;SAVE THE EXTENSION FOR MME.
OFFDEV: SKIPN IM,INPMOD ;SKIP IF WE HAVE A MODE.
MOVEI IM,ASCMOD ;ELSE MAKE IT ASCII.
MOVEM IM,INPMOD ;SAVE THE MODE.
SKIPN OM,OUTMOD ;SKIP IF HAVE A MODE.
MOVEI OM,ASCMOD ;ELSE MAKE IT ASCII.
MOVEM OM,OUTMOD ;SAVE THE MODE.
SKIPN LSTWRD ;ARE WE GOING TO LIST.
GOTO CHKREC ;NO CHECK ON MODE.
IF.OFF IF,MTA!DSK!DTA,CANLST ;JUMP IF DEVICE CAN'T DO IT.
CAIN OM,OCTMOD ;CAN'T HAVE OCTAL OUTPUT.
GOTO BADMOD ;COMPLAIN.
ON IF,SCAN ;TURN ON THE SCAN BIT FOR MTA.
MOVEM IF,IFILE+MOD ;SAVE THEM.
MOVEI T1,^D80 ;DEFAULT RECORD SIZE.
MOVEM T1,IFILE+RECSIZ ;SET THE RECORD SIZE.
SETZM IFILE+BLKFCT ;CLEAR BLOCKING FACTOR.
CHKREC: MOVE T1,IFILE+RECSIZ ;GET THE INPUT RECORD SIZE.
SKIPN OFILE+RECSIZ ;IF THERE IS NOT AN OUTPUT
MOVEM T1,OFILE+RECSIZ ;SIZE USE THE INPUT SIZE.
CAIN IM,OCTMOD ;IS INPUT OCTAL.
GOTO NOOCT ;CAN ONLY BE OUTPUT MODE.
CAIE IM,IMGMOD ;IS INPUT IMAGE.
GOTO TSTOUT ;NO CHECK ON THE OUTPUT MODE.
CAIE OM,OCTMOD ;IF INPUT IS IMAGE THEN
CAIN OM,IMGMOD ;OUTPUT MUST BE IMAGE OR OCTAL.
SKIPA ;OUTPUT IS RIGHT.
GOTO MOD0ER ;MODE ERROR.
SETIMG: MOVEI T1,ONE ;BLOCKING FACTOR FOR IMAGE.
CAIN OM,OCTMOD ;SKIP IF NOT OCTAL MODE.
SETZM T1 ;CLEAR BLOCKING FACTOR FOR OCTAL.
MOVEM T1,IFILE+BLKFCT ;SET AS BLOCKING FACTOR.
MOVEM T1,OFILE+BLKFCT ;SET AS OUTPUT BLOCKING FACTOR.
MOVEI T1,^D1000 ;DEFAULT RECORD SIZE.
SKIPN IFILE+RECSIZ ;IS THERE A RECORD SIZE.
MOVEM T1,IFILE+RECSIZ ;SET OURS.
SKIPN OFILE+RECSIZ ;IS THERE AN OUTPUT ONE.
MOVEM T1,OFILE+RECSIZ ;SET THE DEFAULT.
OFF IF,SPAN ;CAN'T SPAN BLOCKS IN THIS MODE.
MOVEM IF,IFILE+MOD ;SAVE IN STORAGE.
OFF OF,SPAN ;CAN'T SPAN BLOCKS IN THIS MODE.
MOVEM OF,OFILE+MOD ;SAVE IN STORAGE.
GOTO TSTCOM ;GO SEE IF WE START.
TSTOUT: CAIE OM,OCTMOD ;IS OUTPUT OCTAL
CAIN OM,IMGMOD ;OR IMAGE. IF SO TEST
SKIPA ;THE INPUT FOR IMAGE.
GOTO TSTCOM ;NONE OF THESE SO CONTINUE.
MOVEI IM,IMGMOD ;FORCE TO IMAGE INPUT.
MOVEM IM,IFILE+CHRMOD ;SAVE THE MODE.
GOTO SETIMG ;SET IMAGE MODE.
TSTCOM: HLRZ T1,RETWRD ;GET THE FLAG WORD FOR GO.
SKIPE T1 ;SKIP IF IT IS TIME.
GOTO NTHERE ;ELSE DO THE COMMAND AGAIN.
SETOM RUNFLG ;SAY WE ARE NOW ACTIVE.
MME T1,.TIM ;GET OUR RUN TIME.
MOVEM T1,%TIME ;SAVE THE RUN TIME.
OPEN IF,IFILE+STATUS ;OPEN THE INPUT DEVICE.
JSP T1,NODEV ;CAN'T HAVE DEVICE.
OPEN OF,OFILE+STATUS ;OPEN OUTPUT DEVICE.
JSP T1,NODEV ;CAN'T HAVE DEVICE.
MOVE T1,IM ;SET ARGUMENTS FOR GETTAB.
MOVE T2,OM ;SET OTHER.
GOSUB GETTAB ;LOAD THE TABLES.
HLRZ T1,MSIZ(IM) ;GET THE INPUT BYTE SIZE.
DPB T1,[POINT 6,IBUF+1,11] ;SET THE BYTE SIZE.
HLRZ T1,MSIZ(OM) ;GET THE OUTPUT BYTE SIZE.
DPB T1,[POINT 6,OBUF+1,11] ;SET THE OUTPUT SIZE.
MOVE T1,STS(IM) ;GET THE INPUT STATUS BITS.
IF.OFF T1,NIR,CHKOUT ;JUMP IF DON'T NEED RECORD SIZE.
SKIPN IFILE+RECSIZ ;MAKE SURE WE HAVE IT.
GOTO NOIREC ;GET A RECORD SIZE.
CHKOUT: MOVE T1,STS(OM) ;GET THE OUTPUT BITS.
IF.OFF T1,NOR,CHKDEV ;JUMP IF DON'T NEED A RECORD SIZE.
SKIPN OFILE+RECSIZ ;ELSE MAKE SURE WE HAVE IT.
GOTO NOOREC ;GET A RECORD SIZE.
CHKDEV: MOVE T1,OFILE+DEVICE ;LOAD AC WITH NAME WE HAVE.
MME T1,.NAM ;GET THE REAL NAME.
GOTO SETINP ;FORGET IT IF MME FAILS.
MOVE T2,IFILE+DEVICE ;LOAD AC WITH OTHER'S NAME.
MME T2,.NAM ;GET ITS NAME.
GOTO SETINP ;JUMP IF MME FAILS.
CAME T1,T2 ;SEE IF THEY MATCH.
GOTO SETINP ;NO MATCH SO O.K.
HLRZS T1 ;EXCHANGE HALFS.
CAIN T1,'MTA' ;MTA CAN'T GO BOTH WAYS.
GOTO SAMDEV ;CAN'T DO INPUT AND OUTPUT TO ONE TAPE.
SUBTTL *** DO YOUR THING ***
;HERE AFTER THE COMMAND DECODER TO SET UP BUFFERS
;IF DEVICE IS A MAG-TAPE.
SETINP: MOVE T1,.JBFF ;PICK UP THE CURRENT .JBFF.
MOVEM T1,I.JBFF ;SAVE FOR LATER.
GOSUB MONIBF ;GET SOME BUFFERS.
IF.OFF OF,MTA,SETIP ;IS OUTPUT DEVICE A MAG-TAPE.
IF.ON OF,BWIND ;SHOULD WE MOVE THE TAPE.
DRIVE OF,.REW ;REWIND THE TAPE.
SETIP: IF.OFF IF,MTA,SETOUT ;JUMP IF NOT MAG-TAPE.
IF.ON IF,BWIND ;SHOULD WE REWIND INPUT.
DRIVE IF,.REW ;BACK TO LOAD POINT.
MOVEI T1,IBUF ;GET POINTER TO BUFFER HEADER.
MOVEI SIDE,IFILE ;GET POINTER TO PARAMETERS.
GOSUB MAKE ;BUILD THE BUFFERS.
;HERE TO SET UP THE OUTPUT BUFFERS IF MAG-TAPE
;IS THE OUTPUT DEVICE.
SETOUT: MOVE T1,.JBFF ;COPY JOB FIRST FREE.
MOVEM T1,O.JBFF ;STORE FOR LATER.
GOSUB MONOBF ;GET SOME BUTTERS.
IF.OFF OF,MTA,POSINP ;START NOW IF THIS ISN'T A MAG-TAPE.
MOVEI T1,OBUF ;GET POINTER TO BUFFER HEADER.
MOVEI SIDE,OFILE ;GET POINTER TO PARAMETERS.
GOSUB MAKE ;BUILD THE BUFFERS.
;HERE TO POSITION THE TAPES IF WE HAVE TAPES.
POSINP: IF.OFF IF,MTA,POSOUT ;JUMP IF NO INPUT TAPE.
DRIVE IF,.WAT ;STOP THE TAPE.
MOVE P1,IFILE+ADVAN ;GET THE ADVANCE COUNT.
SUB P1,IFILE+BACSPC ;SUBTRACT BACKSPACE COUNTER.
JUMPE P1,POSOUT ;JUMP IF ALRIGHT.
JUMPG P1,POSI0 ;JUMP IF ADVANCE.
MOVNS P1 ;MAKE COUNT POSITIVE.
SKIPA P2,[DRIVE IF,.BSF] ;TO GO BACKWARDS.
POSI0: MOVE P2,[GOSUB SKPFIL] ;TO GO FORWARDS.
XCT P2 ;MOVE THE TAPE.
DRIVE IF,.WAT ;WAIT FOR IT.
SOJG P1,.-2 ;COUNT DOWN COUNTER.
CAME P2,[DRIVE IF,.BSF] ;DID WE GO BACKWARDS.
GOTO POSOUT ;NO.
STATO IF,E.BOT ;AT BEGINNING OF TAPE.
DRIVE IF,.SKR ;NO SKIP TAPE MARK.
POSOUT: IF.OFF OF,MTA,DYT ;JUMP IF NOT OUTPUT MTA.
DRIVE OF,.WAT ;BE SURE IT IS STOPPED.
MOVE P1,OFILE+ADVAN ;GET THE ADVANCE COUNTER.
SUB P1,OFILE+BACSPC ;SUBTRACT BACKSPACE COUNTER.
JUMPE P1,DYT ;JUMP IF TAPES ARE O.K.
JUMPG P1,POSO0 ;JUMP IF ADVANCE.
MOVNS P1 ;MAKE COUNT POSITIVE.
SKIPA P2,[DRIVE OF,.BSF] ;TO GO BACKWARDS.
POSO0: MOVE P2,[DRIVE OF,.SKF] ;TO GO FORWARDS.
XCT P2 ;MOVE THE TAPE.
DRIVE OF,.WAT ;WAIT FOR IT.
SOJG P1,.-2 ;COUNT DOWN COUNTER.
CAME P2,[DRIVE OF,.BSF] ;DID WE GO BACKWARDS.
GOTO DYT ;NO...
STATO OF,E.BOT ;AT BEGINNING OF TAPE.
DRIVE OF,.SKR ;SKIP TAPE MARK.
;HERE TO START THE BALL OF WAX ROLLING.
DYT: GOSUB LOKWLD ;GET A FILE NAME.
GOTO NOWLD ;NONE TO GET.
GETINP: TEO S,FFLG,CREIT ;JUMP IF FIRST TIME.
IF.OFF OF,WNAME!WEXT,INIMOD ;JUMP IF NOT WILD.
CREIT: IF.ON IF,WNAME!WEXT ;SKIP IF HAVE A NAME.
IF.OFF OF,WNAME!WEXT,CREATE ;JUMP IF NORMAL OUTPUT.
MOVE P1,IFILE+NAME ;GET THE NAME OF THE INPUT.
MOVE P2,IFILE+EXT ;GET ITS EXTENSION.
GOSUB MOVNM0 ;GET THE NAME OF THE OUTPUT.
GOSUB ABORT ;ALWAYS SKIPS.
CREATE: IF.OFF OF,MTA ;SKIP IF NOT MTA.
GOSUB OUTLAB ;ELSE WRITE A LABEL.
IF.OFF OF,LPT ;SKIP IF NOT LPT.
GOSUB HDRLPT ;PUT OUT A HEADING.
IF.OFF OF,DIR,INIMOD ;JUMP IF ENTER DOES NOTHING.
SAVE OFILE+PPN ;SAVE THE PPN WORD.
HLLZS OFILE+EXT ;CLEAR DATE.
SETZM OFILE+DATTIM ;CLEAR OTHER HALF.
ENTER OF,OFILE+NAME ;CREATE A FILE.
GOTO NOOPN ;CAN'T DO IT.
UNSAVE OFILE+PPN ;RESTORE IT.
INIMOD: MOVEI SIDE,OFILE ;INDEX FOR OUTPUT FILE.
GOSUB SECTOR ;COMPUTE SECTORS NEEDED.
MOVEI SIDE,IFILE ;INDEX FOR THE INPUT FILE.
SKIPN LSTWRD ;SKIP IF LISTING.
SKIPE TELWRD ;SKIP IF WANTS TO KNOW.
GOTO PROCED ;ELSE SKIP IT.
IF.OFF IF,WILD,PROCED ;JUMP IF INPUT ISN'T WILD.
IF.OFF OF,TTY ;SKIP IF OUTPUT ISN'T TO TTY.
EME .CH,[EXP 12] ;FORM THE PAGE.
MOVE T1,PRGNAM ;GET OUR NAME.
GOSUB PUTSIX ;PRINT IT.
EME .STR,[ASCIZ ": "] ;DELIMIT THE NAME.
MOVE P4,IFILE+MOD ;GET THE MOD BITS.
OFF P4,WILD ;TURN OFF WILD BITS.
GOSUB TYPNM0 ;PRINT IT.
GOSUB CRLF ;SKIP A LINE.
PROCED: GOSUB SECTOR ;GET THE INPUT SECTORS.
MOVE OCNT,OFILE+BLKFCT ;GET THE OUTPUT BLOCKING FACTOR.
MOVE ICNT,IFILE+BLKFCT ;GET THE INPUT BLOCKING FACTOR.
SKIPE LSTWRD ;SKIP IF LISTING.
GOTO PROD1 ;JUMP WHEN LISTING.
GOSUB FILL ;GET THE FIRST BUFFER.
GOTO ENDCOP ;FILE IS ZERO LENGTH.
AOS IRCNT ;COUNT FIRST RECORD.
AOS IBCNT ;COUNT FIRST BLOCK.
PROD1: GOSUB @OUTI(OM) ;INITIALIZE OUTPUT.
SKIPE LSTWRD ;SKIP IF LISTING.
GOTO INILST ;GOT LIST A DIRECTORY.
GOSUB @INI(IM) ;DISPATCH.
SUBTTL *** END OF CONVERSION ***
;HERE WHEN WE ARE DONE WITH A FILE.
ENDCOP: AOS IFCNT ;COUNT THE FILE.
IF.OFF OF,TTY ;SKIP IF NOT TTY.
CLOSE OF,ZERO ;FORCE TTY BUFFERS OUT.
ENABLE TTY ;CLEAR CONTROL O.
CLOSE IF,ZERO ;CLOSE INPUT FILE.
GETSTS IF,T1 ;GET STATUS ON CLOSE.
IF.OFF T1,E.ERR ;ERROR DURING CLOSE.
PRINT (% Error during close of input file.)
CLOOUT: OFF S,PRG!FREAD ;CLEAR PERGE BIT AND FIRST READ BIT.
IF.OFF IF,WILD,CLO1 ;IF NOT WILD INPUT CLOSE.
IF.OFF OF,WNAME!WEXT,NXTONE ;JUMP IF NOT WILD OUTPUT.
CLO1: AOS OFCNT ;COUNT OUTPUT FILE.
IF.OFF OF,LPT ;SKIP IF NOT LPT.
GOSUB EOFLPT ;PUT OUT A HEADING.
CLOSE OF,ZERO ;WRITE AN EOF MARK.
CLO2: GETSTS OF,T1 ;TEST FOR ERRORS.
IF.OFF T1,E.ERR ;ANY ERRORS.
PRINT (? Error during close of output file.)
IF.OFF OF,MTA ;WRITE EOF LABEL IF MAG-TAPE.
GOSUB EOFLAB ;WRITE A TRAILER.
IF.ON IF,WILD,NXTONE ;JUMP IF WILD INPUT.
CLO3: IF.OFF IF,MTA!DTA,CLO4 ;JUMP IF NOT MAG-TAPE.
IF.OFF IF,UNLOAD ;SHOULD WE UNLOAD IT.
DRIVE IF,.UNL ;YES UNLOAD IT.
IF.ON IF,AWIND ;SKIP IF CAN MOVE IT.
IF.ON IF,DTA,CLO4 ;JUMP IF DECTAPE.
IF.ON IF,UNLOAD ;IF NOT UNLOAD AT LEAST
DRIVE IF,.REW ;REWIND IT.
CLO4: IF.OFF OF,MTA!DTA,CLO5 ;JUMP IF OUTPUT ISN'T MTA OR DTA.
IF.OFF OF,UNLOAD ;SKIP IF CAN'T UNLOAD IT.
DRIVE OF,.UNL ;REWIND AND UNLOAD.
IF.ON OF,AWIND ;SKIP IF CAN'T MOVE IT.
IF.ON OF,DTA,CLO5 ;DON'T REWIND DECTAPES.
IF.ON OF,UNLOAD ;IF NOT UNLOAD AT LEAST
DRIVE OF,.REW ;REWIND.
CLO5: GOSUB STAT ;THEN TELL HIM GOOD THINGS.
GOTO NTHERE ;START AGAIN.
NXTONE: GOSUB GETNXT ;GET THE NEXT FILE.
GOTO NOMORE ;NO MORE TO GET.
IF.OFF OF,WNAME!WEXT,GETINP ;DON'T CLEAR COUNTERS IF NOT WILD.
SETZM ORCNT ;CLEAR RECORD COUNTER FOR OUTPUT.
SETZM OBCNT ;CLEAR BLOCK COUNTER.
GOTO GETINP ;PROCESS THE FILE.
NOMORE: MOVEI T1,CLO1 ;GET A DISPATCH ADDRESS.
IF.OFF OF,WNAME!WEXT ;SKIP IF WILD OUTPUT.
MOVEI T1,CLO3 ;ELSE CHANGE DISPATCH.
OFF IF,WILD ;TURN OFF WILD BITS.
OFF OF,WILD ;IN BOTH SPECS.
GOTO ZERO(T1) ;DISPATCH.
SUBTTL *** READ/WRITE LOOP ***
;HERE TO COUNT THE NEXT RECORD AND READ A BLOCK IF
;IT IS TIME.
RENEW: SOJLE ICNT,REN1 ;JUMP IF TIME FOR A BLOCK.
REN0: AOS IRCNT ;COUNT THE RECORD.
RETURN ONE ;GIVE GOOD RETURN.
REN1: SKIPE ICNT,IFILE+BLKFCT ;SKIP IF THERE IS A BLOCKING FACTOR.
IF.ON IF,SPAN,REN5 ;JUMP IF SPANNING.
IF.OFF IF,DIR!MTA,REN5 ;JUMP IF NOT DSK, DTA, OR MTA.
REN2: MOVE T1,ISEC ;GET THE SECTORS READ.
CAML T1,IBLK ;HAVE WE READ ENOUGH.
GOTO REN3 ;YES READ THE NEXT DATA BLOCK.
GOSUB FILL ;SKIP OVER A BLOCK.
RETURN ZERO ;END OF FILE.
GOTO REN2 ;TEST AGAIN.
REN3: SETZM ISEC ;RESET SECTORS READ.
GOSUB FILL ;GET A BLOCK.
RETURN ZERO ;EOF FOUND.
REN4: AOS IBCNT ;COUNT THE BLOCK.
GOTO REN0 ;GO COUNT THE RECORD.
REN5: TNO S,FREAD,REN4 ;JUMP IF NOT FIRST TIME HERE.
RETURN ONE ;ELSE RETURN WITHOUT COUNTING.
;HERE TO SET THE COUNT RIGHT WHEN WE FINISH IN THE MIDDLE
;OF A RECORD FOR AN UNBLOCKED FILE.
SETCNT: SETOM OCNT ;FLAG WE WRITE BLOCK.
SKIPE IFILE+BLKFCT ;IS IT BLOCKED.
RETURN ZERO ;NO RETURN.
AOS IRCNT ;COUNT THE RECORD.
AOS IBCNT ;COUNT THE BLOCK.
RETURN ZERO ;RETURN TO CALLER.
;HERE TO CONVERT THE CHARACTER AND CALL THE
;OUTPUT ROUTINE.
CHANGE: HRRZ CH,TAB1(CH) ;CONVERT IT.
TEZ CH,NEC ;IS THIS A BAD CHARACTER.
AOS NOCHR ;YES COUNT IT.
GOTO @OUTC(OM) ;STACH THE CHARACTER.
;HERE TO WRITE THE CURRENT BLOCK AND TO SEE IF WE MUST
;WRITE SOME BLANK ONES TO FILL OUT THE BLOCKING FACTOR.
UPDAT: CAME OCNT,OFILE+BLKFCT ;ARE WE AT A BLOCK BOUNDARY.
GOTO UPDA ;NO SO WRITE THIS BLOCK.
RETURN ZERO ;RETURN NOTHING TO WRITE.
UPDATE: AOS ORCNT ;COUNT THE RECORD PROCESSED.
SOSLE OCNT ;TIME FOR A NEW BLOCK.
RETURN ZERO ;NO BACK TO CALLER.
UPDA: AOS OBCNT ;COUNT THE BLOCK.
GOSUB @OUTB(OM) ;FINISH BLOCK OFF.
GOSUB CHKOPR ;CHECK OPERATOR COMMAND.
UPD0: SKIPE OCNT,OFILE+BLKFCT ;IS THERE NO BLOCKING FACTOR.
IF.OFF OF,SPAN ;OR ARE WE SPANNING.
RETURN ZERO ;IF SO RETURN.
IF.ON OF,DIR!MTA ;IF NOT DSK, DTA, OR MTA
RETURN ZERO ;DEVICE THEN RETURN.
GOSUB EMPTY ;TO THE DEVICE.
UPD1: MOVE T1,OSEC ;GET THE SECTORS WRITTEN.
CAML T1,OBLK ;HAVE WE WRITTEN ENOUGH.
GOTO UPD2 ;YES IT IS ALRIGHT.
IBP OBUF+1 ;SO IT WILL WRITE.
SOS OBUF+2 ;DECREMENT COUNT.
GOSUB EMPTY ;WRITE EMPTY ONES.
GOTO UPD1 ;CONTINUE LOOP.
UPD2: SETZM OSEC ;RESET SECTOR COUNTER.
RETURN ZERO ;AND RETURN.
SUBTTL *** LIST I/O ROUTINES ***
INILST: ON S,NI.LST ;TURN NO ERROR BIT ON.
SETZM LABTOT ;CLEAR TOTAL BLOCKS.
SETZM LABCNT ;CLEAR TOTAL FILES.
SETZM LSTSTR ;CLEAR LAST STRUCTURE FOUND.
SETZM LSTPPN ;CLEAR LAST PPN FOUND.
IN0LST: IF.OFF IF,MTA,IN1LST ;JUMP IF INPUT ISN'T MTA.
SETZM LABSIZ ;CLEAR FILE SIZE.
INMLST: GOSUB FILL ;FILL UP THE BUFFER.
GOTO INELST ;FOUND EOF.
AOS LABSIZ ;COUNT THE BLOCK IN THIS FILE.
AOS IBCNT ;ACCUMULATE BLOCKS.
GOSUB CHKOPR ;CHECK FOR A COMMAND.
GOTO INMLST ;DO IT AGAIN.
INELST: GETSTS IF,T1 ;GET THE DEVICE STATUS.
IF.OFF T1,E.EOT,IN1LST ;JUMP IF ERROR WASN'T EOT.
SKIPE IFILE+LABEL ;SKIP IF NOT LABELS.
GOTO INMLST ;ELSE FIND THE LABEL.
IN1LST: MOVEI T1,ASCMOD ;MUST HAVE ASCII INPUT TABLES.
MOVE T2,OM ;GET THE OUTPUT INDEX.
GOSUB GETTAB ;GET THE RIGHT TABLES.
MOVS T1,LABNAM+1 ;GET THE EXTENSION.
CAIE T1,'UFD' ;IS THIS A UFD.
GOTO INFLST ;NO LIST A FILE.
HLRZ T1,LABNAM ;GET THE PROJECT NUMBER.
GOSUB INOLST ;LIST AN OCTAL NUMBER.
MOVEI CH,"," ;TO SEPARATE THINGS.
GOSUB CHANGE ;PUT THE CHARACTER AWAY.
HRRZ T1,LABNAM ;GET THE OTHER HALF.
GOSUB IN3LST ;PRINT IT.
SOJLE P1,INULST ;JUMP IF DONE ENOUGH.
MOVEI CH," " ;LOAD A SPACE.
GOSUB CHANGE ;PUT IT AWAY.
GOTO .-3 ;CONTINUE ON.
INULST: UME .ASC,[ASCIZ " "] ;TAB TO NEXT ZONE.
GOTO INXLST ;DO THE REST.
INFLST: UME .SIX,LABNAM ;TYPE THE NAME.
UME .ASC,[ASCIZ " "] ;TAB A LITTLE.
UME .SIX,LABNAM+1 ;TYPE THE EXTENSION.
INXLST: SKIPN FSTWRD ;SKIP IF FAST LIST.
GOSUB IN4LST ;TYPE OTHER GOOD THINGS.
MOVE T1,LABSTR ;GET THIS STRUCTURE.
CAMN T1,LSTSTR ;SKIP IF DIFFERENT FROM LAST.
GOTO IN2LST ;DON'T TYPE IF THE SAME.
MOVEM T1,LSTSTR ;SAVE AS THE LAST ONE.
MOVE P1,[POINT 6,LABSTR] ;POINTER TO STORAGE.
IN6LST: ILDB CH,P1 ;GET A CHARACTER.
JUMPE CH,IN7LST ;JUMP IF DONE.
MOVEI CH," "(CH) ;CONVERT TO ASCII.
GOSUB CHANGE ;STORE IT AWAY.
IF.ON P1,77B5,IN6LST ;JUMP IF MORE.
IN7LST: UME .ASC,[ASCIZ ": "] ;TAB A LITTLE.
IN2LST: SKIPN P1,LABPPN ;SKIP IF A PPN IS THERE.
GOTO IN8LST ;ELSE SKIP AHEAD.
CAMN P1,LSTPPN ;SKIP IF DIFFERENT.
GOTO IN8LST ;ELSE SKIP AHEAD.
MOVEM P1,LSTPPN ;SAVE AS THE LAST PPN.
MOVEI CH,"[" ;TO SPECIFY PPN COMING.
GOSUB CHANGE ;PUT IT AWAY.
HLRZ T1,P1 ;GET THE PROJECT NUMBER.
GOSUB IN3LST ;PRINT IT.
MOVEI CH,"," ;TO SEPARATE P FROM PN.
GOSUB CHANGE ;PRINT IT.
HRRZ T1,LABPPN ;GET THE OTHER HALF.
GOSUB IN3LST ;PRINT IT.
MOVEI CH,"]" ;TO FINISH IT OFF.
GOSUB CHANGE ;SEND IT.
IN8LST: GOSUB @OUTR(OM) ;CALL OUTPUT ROUTINE TO FINISH RECORD.
IF.OFF OF,TTY ;SKIP IF NOT TTY.
GOSUB EMPTY ;ELSE EMPTY THE BUFFER.
IF.OFF IF,MTA,INNLST ;GET NEXT IF NOT MTA.
GETSTS IF,T1 ;GET THE DEVICE STATUS.
IF.ON T1,E.EOT,INDLST ;IF EOT WE ARE DONE.
INNLST: GOSUB NXTGET ;GET THE NEXT ONE.
GOTO IN0LST ;CARRY ON.
INDLST: GOSUB @OUTR(OM) ;SKIP A LINE.
SKIPE FSTWRD ;SKIP IF NORMAL LIST.
GOTO INZLST ;FINISH UP.
UME .ASC,[ASCIZ " Total of "]
MOVE T1,LABTOT ;TOTAL BLOCKS.
GOSUB IN3ALT ;ENTER IT.
UME .ASC,[ASCIZ " blocks in "]
MOVE T1,LABCNT ;TOTAL FILES.
GOSUB IN3ALT ;ENTER IT.
UME .ASC,[ASCIZ " files."]
GOSUB @OUTR(OM) ;FINISH LINE.
INZLST: GOSUB @OUTF(OM) ;FINISH OFF THE FILE.
OFF IF,WILD ;TURN OFF WILD BITS.
OFF S,NI.LST ;TURN OFF NO ERROR BIT.
GOTO ENDCOP ;ALL DONE HERE.
NXTGET: GOSUB STORE ;SAVE THE AC'S.
GOSUB GETNXT ;GET THE NEXT FILE.
RETURN ONE ;NONE TO GET.
RETURN ZERO ;RETURN WITH NEXT.
IN3LST: SKIPA P2,[10] ;SET BASE TO BASE 8.
IN3ALT: MOVEI P2,^D10 ;SET BASE TO BASE 10.
MOVEI P1,^D7 ;SO WE KNOW HOW MANY WENT.
IDIVI T1,ZERO(P2) ;SLICE OFF A DIGIT.
HRLM T2,ZERO(PDP) ;SAVE A DIGIT.
SOS P1 ;COUNT THE DIGIT.
SKIPE T1 ;SKIP IF DONE.
GOSUB IN3ALT+2 ;DO THE NEXT ONE.
HLRZ CH,ZERO(PDP) ;GET A DIGIT.
MOVEI CH,"0"(CH) ;MAKE IT ASCII.
GOTO CHANGE ;PUT IT AWAY...
IN4LST: AOS LABCNT ;COUNT THE FILE.
MOVE T1,LABSIZ ;GET THE FILE SIZE.
ADDM T1,LABTOT ;UPDATE THE TOTAL.
GOSUB IN9LST ;ENTER IT.
UME .ASC,[ASCIZ " <"] ;FLAG PROTECTION COMING.
LDB T1,[POINT 9,LABDTW,8] ;GET THE PROTECTION.
MOVEI CH,"0" ;IF WE MUST PAD.
CAIG T1,77 ;SKIP IF NOT NEED.
GOSUB CHANGE ;PAD A ZERO.
CAIG T1,7 ;SEE IF NEED ANOTHER.
GOSUB CHANGE ;PUT IT IN.
GOSUB IN3LST ;PLACE IT.
UME .ASC,[ASCIZ "> "] ;FINISH IT OFF.
HRRZ T1,LABDTW ;GET THE DATE.
GOSUB PUTXDT ;PRINT THE DATE.
UME .ASC,[ASCIZ " "] ;TO NEXT ZONE.
RETURN ZERO ;BACK TO CALLER.
INOLST: SKIPA P2,[10] ;SET THE BASE.
IN9LST: MOVEI P2,^D10 ;SET THE BASE.
MOVEI P1,^D7 ;CHARACTERS TO PRINT.
I90LST: IDIVI T1,ZERO(P2) ;SLICE OFF A DIGIT.
HRLM T2,ZERO(PDP) ;SAVE THE DIGIT.
SOS P1 ;COUNT THE DIGIT.
JUMPN T1,I92LST ;JUMP IF MORE.
I91LST: MOVEI CH," " ;LOAD A SPACE.
SOJLE P1,I93LST ;JUMP IF ENOUGH.
GOSUB CHANGE ;FILL WITH A SPACE.
GOTO I91LST ;CHECK AGAIN.
I92LST: GOSUB I90LST ;GET THE NEXT ONE.
I93LST: HLRZ CH,ZERO(PDP) ;GET A DIGIT.
MOVEI CH,"0"(CH) ;CONVERT IT TO ASCII.
GOTO CHANGE ;PUT IT AWAY.
SUBTTL *** ASCII I/O ROUTINES ***
;HERE TO READ ASCII CHARACTERS FROM THE INPUT
;FILE AND SEND THEM TO THE OUTPUT FILES. HANDLES SEVEN
;EIGHT, OR NINE BIT ASCII.
INIASC: SKIPN P2,IFILE+RECSIZ ;LOAD THE RECORD SIZE.
HRLOI P2,377777 ;IF NO RECORD SIZE.
IN5ASC: MOVEI P1,^D8 ;TAB COUNT.
IN0ASC: GOSUB GET ;GET A CHARACTER.
GOTO @OUTF(OM) ;END OF FILE.
ANDI CH,177 ;JUST THE DATA BITS.
JUMPE CH,IN0ASC ;IGNORE NULLS.
CAIN CH,15 ;IS IT END OF RECORD.
GOTO IN1ASC ;YES PROCESS EOR.
CAIN CH,11 ;IS IT A TAB.
GOTO IN2ASC ;TAKE CARE OF IT.
IN3ASC: GOSUB CHANGE ;SEND IT.
IF.OFF IF,NOCRLF ;SKIP IF CRLF'S ARE EXPECTED.
SOJLE P2,IN6ASC ;JUMP IF END OF RECORD.
SOJG P1,IN0ASC ;JUMP IF TAB IS GOOD.
GOTO IN5ASC ;CONTINUE ON.
IN1ASC: IF.OFF IF,NOCRLF,IN9ASC ;JUMP IF CRLF'S ARE EXPECTED.
SKIPE IFILE+RECSIZ ;IS THERE A RECORD SIZE.
GOTO BADFOM ;CAN'T HAVE RECSIZ IF CRLF PRESENT.
IN9ASC: GOSUB GET ;GET THE NEXT CHARACTER.
GOTO @OUTF(OM) ;END OF FILE FOUND.
ANDI CH,177 ;JUST THE DATA BITS.
JUMPE CH,IN1ASC ;IGNORE NULLS.
CAIE CH,12 ;IS IT A LINE FEED.
ON S,BAC ;NO SO REGET IT.
IN6ASC: GOSUB RENEW ;HANDLE END OF RECORD.
GOTO @OUTF(OM) ;END OF FILE FOUND.
GOSUB @OUTR(OM) ;FINISH THE OUTPUT RECORD.
GOTO INIASC ;CONTINUE ON.
IN2ASC: MOVE T1,STS(OM) ;GET THE OUTPUT STATE WORD.
IF.ON T1,TAB,IN3ASC ;JUMP IF OUTPUT HAS TABS
IN4ASC: MOVEI CH," " ;LOAD A SPACE.
GOSUB CHANGE ;INTO OUTPUT BUFFER.
SOJG P1,IN4ASC ;CONTINUE FOR TAB COUNT.
GOTO IN5ASC ;RESET THE TAB COUNTER.
EQUATE INIASC,<INIGEA,INIHPA>
;HERE TO INITIALIZE THE ASCII OUTPUT ROUTINE.
OTIASC: MOVE P3,OFILE+RECSIZ ;SET UP RECORD SIZE.
RETURN ZERO ;BACK TO CALLER.
;HERE TO ENTER ONE ASCII CHARACTER INTO THE OUTPUT BUFFER.
OTCASC: JUMPE CH,RET0 ;DON'T SAVE NULLS.
OFF S,EOR ;NOT AT RECORD END NOW.
SOJL P3,OT0ASC ;JUMP IF RECORD IS FULL.
GOSUB PUT ;WRITE THE CHARACTER.
OT0ASC: CAIG CH,24 ;IS IT A SPECIAL CHARACTER.
GOTO OT2ASC ;YES SEE IF SPECIAL CHARACTER.
OT1ASC: OFF S,FF ;NOT AT TOP OF FORM.
RETURN ZERO ;BACK TO CALLER.
OT2ASC: CAIE CH,12 ;IS IT A LINE FEED.
CAIN CH,13 ;OR VERTICAL TAB.
GOTO OT3ASC ;YES NO LONGER AT THE TOP.
CAIL CH,21 ;DEVICE CONTROL CHARACTER.
GOTO OT3ASC ;YES NOT AT TOP ANY MORE.
CAIE CH,14 ;IS IT A FORM FEED.
GOTO OT1ASC ;NO SO EXIT.
TROA S,FF ;NOW AT TOP OF PAGE.
OT3ASC: OFF S,FF ;NOT AT TOP OF FORM.
GOTO OTIASC ;RESET RECORD COUNTER. FOR THESE.
;HERE TO FINISH OFF THE ASCII RECORD.
OTRAC0: GOSUB SETCNT ;SET UP COUNTERS.
OTRASC: ON S,EOR ;AT END OF RECORD.
IF.OFF OF,NOCRLF,OTRAS1 ;JUMP IF FILE CAN HAVE CRLF'S.
MOVEI CH," " ;SPACE FILL THE RECORD.
GOSUB OTCASC ;UNTIL THE COUNTER RUNS OUT.
JUMPGE P3,.-2 ;UNTIL IT FINISHES CONTINUE.
IF.ON OF,MTA!DTA!DSK,OTIASC ;JUMP UNLESS THIS IS AN ASCII ONLY DEVICE.
OTRAS1: MOVEI CH,15 ;GET A RETURN.
GOSUB PUT ;INTO THE BUFFER.
MOVEI CH,12 ;AND A LINE FEED.
GOSUB PUT ;INTO THE BUFFER.
GOSUB UPDATE ;COUNT RECORD WRITTEN.
GOTO OTIASC ;RE-INITIALIZE.
;HERE ON INPUT END OF FILE TO FINISH OFF THE OUTPUT FILE.
OTFASC: IF.OFF S,EOR,OTRAC0 ;FINISH THIS RECORD IF NEEDED.
GOTO UPDAT ;ELSE CHECK ON THE BLOCK.
EQUATE RET0,<OTBASC>
EQUATE OTIASC,<OTIGEA,OTIHPA>
EQUATE OTCASC,<OTCGEA,OTCHPA>
EQUATE OTRASC,<OTRHPA,OTRGEA>
EQUATE OTBASC,<OTBGEA,OTBHPA>
EQUATE OTFASC,<OTFGEA,OTFHPA>
SUBTTL *** IMAGE I/O ROUTINES ***
;HERE TO READ A FILE IN BUFFER MODE AND EITHER BLT THE
;INPUT BUFFER TO THE OUTPUT BUFFER IF GOING IMAGE TO IMAGE
;OR TO PASS A WORD AT TIME IF GOING FROM IMAGE TO OCTAL.
INIIMG: CAIN OM,IMGMOD ;IS OUTPUT IMAGE.
GOTO IMGBLT ;YES USE BLT'S.
MOVE P1,ISEC ;GET THE SECTORS READ.
IN0IMG: GOSUB GET ;GET A WORD.
GOTO @OUTF(OM) ;END OF FILE.
GOSUB @OUTC(OM) ;GET RID OF A WORD.
CAMN P1,ISEC ;DID WE READ A BLOCK.
GOTO IN0IMG ;NO CONTINUE.
AOS P1,IBCNT ;COUNT THE BLOCK.
AOS IRCNT ;COUNT THE RECORD.
GOTO IN0IMG ;CARRY ON.
IMGBLT: AOS ORCNT ;COUNT THE RECORD CLOSE WRITES.
AOS OBCNT ;COUNT THE BLOCK CLOSE WRITES.
IMGBT1: SKIPG OBUF ;HAS AN OUTPUT BEEN DONE.
OUTPUT OF,ZERO ;DO ONE TO SET THE RING AS USED.
AOS IBUF+1 ;GET A POINTER TO THIS BUFFER.
SETZM OSEC ;CLEAR SECTORS WRITTEN.
IMGBT0: HRLZ T1,IBUF+1 ;C(T1)LH IS SOURCE POINTER.
MOVE T2,OBUF+2 ;C(T2) SIZE OF THE TARGET.
MOVE T3,IBUF+2 ;C(T3) SIZE OF THE SOURCE.
CAML T2,T3 ;WILL SOURCE FIT IN TARGET.
MOVE T2,T3 ;COPY WHAT IS LEFT.
ADDM T2,IBUF+1 ;UPDATE POINTER.
MOVE P1,IBUF+2 ;GET THE COUNT LEFT.
SUB P1,T2 ;ACCOUNT FOR WORDS TO MOVE.
MOVEM P1,IBUF+2 ;UPDATE THE COUNT.
GOSUB BUF2 ;MOVE THE BUFFER.
SKIPN OBUF+2 ;IS OUTPUT BUFFER FULL.
GOSUB EMPTY ;WRITE BUFFER.
SKIPLE IBUF+2 ;SKIP IF BUFFER IS ALL GONE.
GOTO IMGBT0 ;GET THE NEXT SECTION.
MOVE P1,OSEC ;GET BLOCKS WRITTEN.
ADDM P1,OBCNT ;UPDATE BLOCK COUNT.
ADDM P1,ORCNT ;UPDATE RECORD COUNT.
GOSUB FILL ;GET THE NEXT BUFFER.
RETURN ZERO ;NONE TO GET.
AOS IRCNT ;COUNT THE RECORD.
AOS IBCNT ;COUNT THE BLOCK.
GOSUB CHKOPR ;CHECK FOR COMMAND.
GOTO IMGBT1 ;DO THE NEXT ONE.
EQUATE RET0,<OTIIMG>
EQUATE ABORT,<OTCIMG,OTRIMG,OTBIMG,OTFIMG>
SUBTTL *** OCTAL OUTPUT ROUTINE ***
;HERE TO DUMP A FILE IN OCTAL MODE.
OTIOCT: ON S,LHEAD ;CAN'T USE US TO STORE CHARACTERS.
SETZM OT0TMP ;CLEAR WORD COUNTER.
IF.ON OF,TTY ;SKIP IF TTY OUTPUT.
UME .ASC,[BYTE (7)14,0] ;SEND A FORM FEED.
OT0OCT: MOVEI P3,5 ;WORDS PER LINE IF TTY.
IF.ON OF,TTY ;SKIP IF TTY IS OUTPUT DEVICE.
MOVEI P3,11 ;WORDS PER LINE IF OTHER DEVICE.
MOVEM P3,OT1TMP ;SAVE WORDS PER LINE.
RETURN ZERO ;BACK TO CALLER.
;HERE TO DUMP ONE WORD ONTO THE OUTPUT DEVICE.
OTCOCT: CAMN P3,OT1TMP ;ARE WE AT A NEW LINE.
GOTO OT4OCT ;YES HANDLE NEW LINE STUFF.
OT1OCT: MOVE P4,[POINT 3,T3] ;GET A POINTER TO DATA.
MOVE T3,CH ;COPY OUTPUT WORD.
UME .ASC,[ASCIZ " "] ;SEPARATE THINGS.
OT2OCT: ILDB CH,P4 ;GET A CHARACTER.
MOVEI CH,"0"(CH) ;MAKE IT ASCII.
GOSUB PUT ;WRITE IT OUT.
IF.ON P4,77B5,OT2OCT ;JUMP IF HAVE MORE.
SOJG P3,RET0 ;JUMP IF NOT AT LINES END.
OT3OCT: AOS ORCNT ;COUNT THE RECORD.
AOS OBCNT ;COUNT THE BLOCK.
UME .ASC,[BYTE (7)15,12,0] ;SKIP A LINE.
GOSUB CHKOPR ;CHECK FOR COMMAND.
GOTO OT0OCT ;RESET COUNTER.
OT4OCT: SAVE CH ;SAVE THE DATA WORD.
MOVEI CH,"(" ;TO DELIMIT WORD NUMBER.
GOSUB PUT ;PLACE IT.
MOVE T3,OT0TMP ;GET THE WORD NUMBER.
MOVE P4,[POINT 3,T3,17] ;GET A POINTER TO IT.
GOSUB OT2OCT ;WRITE IT OUT.
MOVEI CH,")" ;TO DELIMIT IT.
GOSUB PUT ;PRINT IT.
UNSAVE CH ;GET THE DATA WORD BACK.
ADDM P3,OT0TMP ;UPDATE WORD COUNTER.
GOTO OT1OCT ;PLACE THE DATA WORD.
;HERE ON END OF FILE.
OTFOCT: CAMN P3,OT1TMP ;ARE WE IN THE MIDDLE OF THE LINE.
RETURN ZERO ;NO SO RETURN.
GOTO OT3OCT ;FINISH LINE AND RETURN.
EQUATE ABORT,<INIOCT,OTROCT,OTBOCT>
SUBTTL *** SIXBIT I/O ROUTINES ***
;HERE TO READ A SIXBIT FILE AND PASS A CHARACTER
;AT A TIME TO THE OUTPUT ROUTINES.
IN0SIX: MOVE P1,IBUF+1 ;GET THE BUFFER POINTER.
IF.OFF P1,77B5,INISIX ;IF NOT AT A WORD BOUNDARY
IBP IBUF+1 ;BUMP POINTER ONE POSITION
SOS IBUF+2 ;AND COUNT AND THEN
GOTO IN0SIX ;TEST FOR A WORD BOUNDARY.
INISIX: GOSUB GET ;MAKE SURE NOT EOF.
GOTO @OUTF(OM) ;FINISH OFF FILE.
LDB P1,[POINT 12,@IBUF+1,35];GET THE RECORD SIZE.
MOVSI T1,770000 ;SET BYTE POINTER TO NEXT WORD.
ANDCAM T1,IBUF+1 ;POINTER NOW POINTS RIGHT.
MOVNI T1,5 ;NUMBER OF PLACES POINTER MOVED.
ADDM T1,IBUF+2 ;UPDATE THE COUNTER.
JUMPE P1,IN0SIX ;DON'T DO ZERO CTRL WORDS.
IN1SIX: SOJL P1,IN2SIX ;HAS COUNTER RUN OUT.
GOSUB GET ;NO GET A WORD.
GOTO @OUTF(OM) ;END OF FILE SHOULDN'T HAPPEN??
GOSUB CHANGE ;CONVERT THE CHARACTER.
GOTO IN1SIX ;AND LOOP.
IN2SIX: GOSUB RENEW ;GET THE NEXT RECORD.
GOTO @OUTF(OM) ;END OF THE FILE.
GOSUB @OUTR(OM) ;FINISH THE OUTPUT RECORD.
GOTO IN0SIX ;GET A NEW CONTROL WORD.
;HERE TO INITAILIZE THE OUTPUT ROUTINE.
OTISIX: GOSUB GETBUF ;GET AN ALTER BUFFER.
OT0SIX: SETZM OSIZE ;SET SIZE OF RECORD TO ZERO.
MOVE P3,CURPTR ;GET THE CURRENT BUFFER POINTER.
CAME P3,RECPTR ;ARE WE AT THE TOP.
AOS P3 ;NO SO BUMP POINTER.
HRRZM P3,LSTPTR ;AND MAKE IT THE LAST POINTER.
AOS CURPTR ;POINT POINTER TO START OF RECORD.
MOVE P3,OFILE+RECSIZ ;GET THE RECORD SIZE.
RETURN ZERO ;BACK TO CALLER.
;HERE TO PUT ONE CHARACTER INTO THE ALTER BUFFER.
OTCSIX: SOJL P3,RET0 ;RETURN IF RECORD IS FULL.
AOS OSIZE ;COUNT THE CHARACTER.
IDPB CH,CURPTR ;SAVE THE CHARACTER.
RETURN ZERO ;BACK TO CALLER.
;HERE TO FINISH OFF THE CURRENT RECORD AND WRITE ITS CTRL WORD.
OT2SIX: GOSUB SETCNT ;SET COUNTERS RIGHT.
OTRSIX: HRRZ CH,TAB2+40 ;LOAD A SPACE.
SKIPN OSIZE ;CHECK SIZE OF RECORD.
GOSUB OTCSIX ;SO RECORD IS KNOWN.
MOVE P3,OSIZE ;GET THE RECORD SIZE.
MOVEM P3,@LSTPTR ;STASH IT IN THE BUFFER.
OT1SIX: SETZM CH ;PUT IN SPACES.
MOVE P3,CURPTR ;GET THE CURRENT POINTER.
IF.OFF P3,77B5,OT3SIX ;JUMP IT AT WORD BOUNDARY.
IDPB CH,CURPTR ;ELSE PUSH POINTER TO A WORD
GOTO OT1SIX ;BOUNDARY AND LOOP.
OT3SIX: GOSUB UPDATE ;COUNT THIS RECORD.
GOTO OT0SIX ;RE-INITIALIZE.
;HERE TO FINISH OFF A BLOCK WHEN WE HAVE BEEN CALLED FROM UPDATE.
OTBSIX: GOSUB BUFMOV ;MOVE ALTER BUFFER TO OUTPUT BUFFER.
MOVE T1,RECPTR ;GET POINTER TO TOP.
MOVEM T1,CURPTR ;SAVE IT AS THE CURRENT POINTER.
RETURN ZERO ;AND RETURN.
;HERE TO FINISH OFF THE FILE.
OTFSIX: SKIPE OSIZE ;SKIP IF JUST FINISHED A RECORD.
GOTO OT2SIX ;FINISH RECORD AND WRITE BLOCK.
SOS CURPTR ;POINTER POINTER RIGHT.
GOTO UPDAT ;FINISH IT OFF.
SUBTTL *** BCD BCL GEBCD AND FIXED EBCDIC I/O ROUTINES ***
;HERE TO GET A CHARACTER FROM THE INPUT BUFFER AND WRITE
;IT TO THE OUTPUT BUFFER. NOTE THIS ROUTINE WILL HANDLE
;ANY FORMAT PROVIDED THE FORMAT HAS NO CTRL WORDS AND NO
;CHARACTERS IN THE RECORDS THAT HAVE A SPECIAL MEANING.
;THE BYTE SIZE OF THE CHARACTER SET HAS NO MEANING HERE.
INIBGE: MOVE P1,IFILE+RECSIZ ;GET THE RECORD SIZE.
IN5BGE: MOVEI P2,^D8 ;SPACES PER TAB.
IN0BGE: SOJL P1,IN1BGE ;JUMP IF RECORD HAS EXPIRED.
GOSUB GET ;GET A WORD.
GOTO @OUTF(OM) ;END OF FILE.
CAIN IM,EBCMOD ;IS THIS EBCDIC.
GOTO IN3BGE ;YES CHECK FOR A TAB.
IN2BGE: GOSUB CHANGE ;CONVERT THE CHARACTER.
SOJG P2,IN0BGE ;JUMP IF TAB IS STILL THERE.
GOTO IN5BGE ;CARRY ON...
IN1BGE: GOSUB RENEW ;GET THE NEXT RECORD.
GOTO @OUTF(OM) ;END OF FILE FOUND.
GOSUB @OUTR(OM) ;FINISH THE OUTPUT RECORD.
GOTO INIBGE ;CONTINUE ON..
IN3BGE: CAIE CH,5 ;CHECK FOR EBCDIC TAB.
GOTO IN2BGE ;NOT ONE.
MOVE T1,STS(OM) ;GET THE OUTPUT STATE WORD.
IF.ON T1,TAB,IN2BGE ;JUMP IF IT HAS TABS.
IN4BGE: MOVEI CH,100 ;LOAD A SPACE.
GOSUB CHANGE ;CONVERT IT.
SOJG P2,IN4BGE ;FOR THE COUNT.
GOTO IN5BGE ;CONTINUE ON.
EQUATE INIBGE,<INIFIX,INICDC,INIBCL,INIBCD,INIXBD,INIEBC,INIHBD>
;HERE TO INITIALIZE THE OUTPUT ROUTINE FOR CHARACTER
;SETS THAT HAVE NO CONTROL WORDS.
OTIBGE: MOVE P3,OFILE+RECSIZ ;GET THE RECORD SIZE.
RETURN ZERO ;BACK TO CALLER.
;HERE TO WRITE ONE CHARACTER OUT INTO THE
;OUTPUT BUFFER.
OTCBGE: SOJL P3,RET0 ;RETURN IF RECORD IS FULL.
GOTO PUT ;ELSE ADD TO BUFFER.
;HERE TO FINSIH OFF THE RECORD.
OT0BGE: GOSUB SETCNT ;SET COUNTERS RIGHT AND SET FLAG.
OTRBGE: HRRZ CH,TAB2+40 ;GET A SPACE FOR THIS SET.
GOSUB OTCBGE ;AND WRITE IT OUT.
JUMPGE P3,OTRBGE ;CONTINUE FOR THE RECORD SIZE.
SAVE OBUF+1 ;SAVE BUFFER POINTER.
OT1BGE: HLRZ T2,MSIZ(OM) ;GET BYTE SIZE.
MOVEI T1,^D36 ;BITS PER WORD.
IDIVI T1,ZERO(T2) ;UNUSED BITS IN T2.
LDB T1,[POINT 6,OBUF+1,5] ;GET THE BITS LEFT IN WORD.
CAIN T1,ZERO(T2) ;SKIP IF NOT AT WORD BOUNDARY.
GOTO OT2BGE ;WE ARE AT A BOUNDARY.
HRRZ CH,TAB2+40 ;LOAD A SPACE.
IDPB CH,OBUF+1 ;SAVE THE SPACE.
GOTO OT1BGE ;TRY AGAIN.
OT2BGE: UNSAVE OBUF+1 ;RESTORE POINTER.
GOSUB UPDATE ;COUNT THE RECORD.
GOTO OTIBGE ;RE-INITIALIZE.
;HERE ON INPUT END OF FILE TO FINISH OFF THE
;OUTPUT FILE.
OTFBGE: CAME P3,OFILE+RECSIZ ;SKIP IF JUST FINISHED A RECORD.
GOTO OT0BGE ;FINISH RECORD AND WRITE BLOCK.
GOTO UPDAT ;DON'T WRITE EXTRA RECORDS.
EQUATE RET0,<OTBBGE>
EQUATE OTIBGE,<OTIHBD,OTIEBC,OTIXBD,OTIBCD,OTIBCL,OTIFIX,OTICDC>
EQUATE OTCBGE,<OTCHBD,OTCEBC,OTCXBD,OTCBCD,OTCBCL,OTCFIX,OTCCDC>
EQUATE OTRBGE,<OTRHBD,OTREBC,OTRXBD,OTRBCD,OTRBCL,OTRFIX,OTRCDC>
EQUATE OTBBGE,<OTBHBD,OTBEBC,OTBXBD,OTBBCD,OTBBCL,OTBFIX,OTBCDC>
EQUATE OTFBGE,<OTFHBD,OTFEBC,OTFXBD,OTFBCD,OTFBCL,OTFFIX,OTFCDC>
SUBTTL *** VARABLE EBCDIC I/O ROUTINES ***
;HERE TO READ FROM A VARABLE EBCDIC FILE.
INIVEB: HRLOI ICNT,377777 ;SO WE WON'T READ A BLOCK.
GOSUB IN3VEB ;GET A BLOCK CTRL WORD.
JUMPE P1,INIVEB ;IGNORE ZERO CTRL WORDS.
SUBI P1,4 ;SUBTRACT LENGTH OF CTRL WORD.
MOVEM P1,IVBCNT ;SAVE THE BLOCK LENGTH.
IN0VEB: GOSUB IN3VEB ;GET A RECORD CTRL WORD.
EXCH P1,IVBCNT ;PUT BLOCK CTRL IN AN AC.
SUB P1,IVBCNT ;SUBTRACT RECORD FROM BLOCK.
EXCH P1,IVBCNT ;REPLACE THE BLOCK WORD.
SUBI P1,4 ;SUBTRACT LENGTH OF CTRL WORD.
IN5VEB: MOVEI P2,^D8 ;SPACES PER TAB.
IN1VEB: SOJL P1,IN2VEB ;JUMP IF CTRL RAN OUT.
GOSUB GET ;GET A WORD.
GOTO @OUTF(OM) ;FOUND END OF FILE.
CAIN CH,5 ;SEE IF IT IS A TAB.
GOTO IN6VEB ;HANDLE TABS.
IN8VEB: GOSUB CHANGE ;CONVERT AND WRITE.
SOJG P2,IN1VEB ;DECREMENT TAB COUNT AND TEST.
GOTO IN5VEB ;CONTINUE LOOP.
IN2VEB: SKIPG IVBCNT ;HAS BLOCK EXPIRED.
SETOM ICNT ;FLAG WE NEED A NEW ONE.
GOSUB RENEW ;GET THE NEXT RECORD.
GOTO @OUTF(OM) ;END OF FILE.
GOSUB @OUTR(OM) ;FINISH THE OUTPUT RECORD.
SKIPLE IVBCNT ;DID BLOCK EXPIRE.
GOTO IN0VEB ;NO SO GET A RECORD CTRL WORD.
GOTO INIVEB ;YES SO GET A NEW BLOCK WORD.
IN3VEB: GOSUB IN4VEB ;GET A BYTE.
MOVE P1,CH ;TO A BETTER AC.
LSH P1,^D8 ;SHIFT FIRST INTO PLACE.
GOSUB IN4VEB ;GET THE NEXT BYTE.
IOR P1,CH ;SET UP COUNTER.
GOSUB IN4VEB ;SKIP PASS UNUSED BYTES.
GOSUB IN4VEB ;SKIP PASS UNUSED BYTES.
RETURN ZERO ;RETURN.
IN4VEB: GOSUB GET ;GET A BYTE.
SKIPA ;END OF FILE RETURN.
RETURN ZERO ;RETURN WITH BYTE.
SUB PDP,[XWD TWO,TWO] ;FIX UP THE PUSH-DOWN POINTER.
GOTO @OUTF(OM) ;END OF FILE DISPATCH.
IN6VEB: MOVE T1,STS(OM) ;GET THE OUTPUT STATE WORD.
IF.ON T1,TAB,IN8VEB ;JUMP IF OUTPUT HAS TABS.
IN7VEB: MOVEI CH,100 ;LOAD A SPACE.
GOSUB CHANGE ;CONVERT IT.
SOJG P2,IN7VEB ;CONTIUE FOR COUNT.
GOTO IN5VEB ;CONTINUE ON...
;HERE TO INITIALIZE THE VARABLE EBCDIC OUTPUT ROUTINE.
OTIVEB: GOSUB GETBUF ;GET AN ALTER BUFFER.
SETZM OBSIZE ;INIT BLOCK SIZE.
OT0VEB: SETZM OSIZE ;INIT RECORD SIZE.
MOVE P3,CURPTR ;GET THE CURRENT POINTER.
MOVEM P3,LSTPTR ;MAKE IT LAST POINTER.
CAMN P3,RECPTR ;ARE WE STARTING A BLOCK.
AOS CURPTR ;YES SO MAKE ROOM FOR BLOCK CTRL WORD.
CAMN P3,RECPTR ;WAS THAT THE SAME.
AOS LSTPTR ;PUSH BY BLOCK CTRL WORD.
MOVE P3,OFILE+RECSIZ ;SET UP RECORD SIZE.
AOS CURPTR ;PUSH BY FUTURE CTRL WORD.
RETURN ZERO ;BACK TO CALLER.
;HERE TO PUT ONE CHARACTER INTO THE ALTER BUFFER.
OTCVEB: SOJL P3,RET0 ;RETURN IF BUFFER IS FULL.
AOS OSIZE ;COUNT THE CHARACTER.
IDPB CH,CURPTR ;SAVE THE CHARACTER.
RETURN ZERO ;BACK TO CALLER.
;HERE TO WRITE A CTRL WORD ONTO THIS RECORD.
OT3VEB: GOSUB SETCNT ;FLAG BLOCK TO GO AND SET COUNTER.
OTRVEB: HRRZ CH,TAB2+40 ;LOAD A SPACE.
SKIPN OSIZE ;GET THE SIZE.
GOSUB OTCVEB ;SO RECORD IS SEEN.
MOVE P3,OSIZE ;GET SIZE OF RECORD.
MOVE T1,LSTPTR ;POINTER TO WHERE IT GOES.
GOSUB OT1VEB ;PLACE IT IN THE RECORD.
ADDM P3,OBSIZE ;UPDATE BLOCK WORD.
GOSUB UPDATE ;WRITE THE RECORD.
GOTO OT0VEB ;RE-INITIALIZE.
;HERE TO WRITE A BLOCK CTRL WORD ONTO THE BLOCK THAT IS ABOUT
;TO LEAVE US.
OTBVEB: MOVE P3,OBSIZE ;GET THE BLOCK SIZE.
MOVE T1,RECPTR ;POINTER TO WHERE IT GOES.
GOSUB OT1VEB ;WRITE THE BLOCK CTRL WORD.
SETZM OBSIZE ;CLEAR BLOCK SIZE.
GOTO OTBSIX ;COPY ALTER BUFFER TO OUTPUT BUFFER.
OT1VEB: ADDI P3,4 ;ADD IN THE SIZE OF THE CTRL WORD.
LDB CH,[POINT 8,P3,27] ;GET THE FIRST EIGHT BITS.
IDPB CH,T1 ;SAVE THEM IN BUFFER.
IDPB P3,T1 ;SAVE THE NEXT EIGHT BITS.
MOVEI CH,100 ;PUT SPACES IN THE REMAINING
IDPB CH,T1 ;TWO BYTES OF THE CTRL WORD
IDPB CH,T1 ;FOR THIS RECORD.
RETURN ZERO ;BACK TO CALLER.
;HERE ON INPUT END OF FILE.
OTFVEB: SKIPE OSIZE ;SKIP IF JUST WROTE A RECORD.
GOTO OT3VEB ;FINISH RECORD AND WRITE THE BLOCK.
HRRZ T1,RECPTR ;GET POINTER TO BUFFER.
HRRZ T2,CURPTR ;POINTER INTO BUFFER.
CAIN T1,-2(T2) ;SEE IF AT THE TOP.
SOS CURPTR ;DECREMENT FOR BLOCK WORD.
SOS CURPTR ;DECREMENT FOR RECORD CTRL WORD.
GOTO UPDAT ;FINISH THE FILE.
SUBTTL *** THINK ABOUT LABELS ***
;HERE TO READ THE LABEL AND TO DISPATCH TO THE
;APPROPRIATE ROUTINE TO HANDLE ITS FORMAT.
INPLAB: ENABLE TTY ;CLEAR THE TTY.
MOVE T1,IFILE+LABEL ;GET LABEL INDEX.
HRRZ T1,LB.TYP(T1) ;COPY DISPATCH.
CHKLAB: OFF S,L.HDR!L.EOF!L.EOV ;TURN OFF LABEL BITS.
MOVE T2,[XWD INPBUF,INPBUF+1];XWD FOR BLT.
SETZM INPBUF ;CLEAR THE FIRST.
BLT T2,INPBUF+^D20 ;CLEAR BUFFER.
GOSUB ZERO(T1) ;CHECK LABEL OUT.
RETURN ZERO ;NOT THAT TYPE OF LABEL.
IF.OFF S,L.HDR,RET3 ;JUMP IF NOT HEADER.
GOSUB TSTNAM ;SEE IF NAME MATCHES.
RETURN ONE ;NO MATCH ON NAME.
CAME P3,IFILE+VOL ;IS THE VOLUME RIGHT.
RETURN TWO ;INCORRECT VOLUME.
RETURN THREE ;LABEL PASSED BITS ARE SET.
;HERE TO CHECK AND WRITE OUTPUT LABELS. HERE WE
;ALSO DO INITIAL POSITIONING OF THE DEVICE.
OUTLAB: IF.OFF OF,IND ;WHICH MODE FOR THE TAPE.
DRIVE OF,.IND ;INDUSTRIAL.
ENABLE TTY ;CLEAR THE TTY.
MOVE T1,OFILE+LABEL ;GET THE LABEL INDEX.
HLRZ T1,LB.TYP(T1) ;COPY DISPATCH.
MOVE T2,[XWD OUTBUF,OUTBUF+1];XWD FOR BLT.
SETZM OUTBUF ;CLEAR FIRST WORD.
BLT T2,OUTBUF+^D20 ;CLEAR BUFFER.
GOTO ZERO(T1) ;DISPATCH.
;HERE WHEN WE ARE READY TO WRITE AN EOF LABEL
;TO THE TAPE.
EOFLAB: ON S,TERM ;NOTE THAT THIS IS EOF.
GOSUB OUTLAB ;OTHER WISE HANDLE AS HDR.
OFF S,TERM ;TURN OFF TERMINAL BIT.
GETSTS OF,T1 ;GET DEVICE STATUS.
IF.OFF T1,E.ERR ;ANY ERRORS.
PRINT (? Error during close of output file.)
RETURN ZERO ;BACK TO CALLER.
;HERE IF NO LABEL TYPE WAS SPECIFIED.
LB.NON: DRIVE IF,.BSR ;BACK UP OVER RECORD READ.
DRIVE IF,.WAT ;WAIT FOR IT.
MOVE P1,IFILE+NAME ;GET THE NAME.
HLLZ P2,IFILE+EXT ;GET THE EXTENSION.
MOVE P3,IFILE+VOL ;GET THE VOLUME NUMBER.
IF.ON IF,WNAME!WEXT,LB.0NO ;JUMP IF WILD.
LB.NST: MOVEM P1,LABNAM ;SAVE FIRST HALF OF NAME.
MOVEM P2,LABNAM+1 ;SAVE THE SECOND HALF.
MOVEM P3,LABVOL ;SAVE THE VOLUME NUMBER.
MME T1,.DATE ;GET THE DATE TODAY.
MOVEM T1,LABDTW ;SAVE THE DATE.
ON S,L.HDR ;SAY WE FOUND A HEADER.
GOTO LABFIL ;GO FILL IN DEFAULTS.
LB.0NO: GOSUB DREAM ;GET A FUNNY NAME.
IF.OFF IF,WNAME,LB.1NO ;JUMP IF NAME ISN'T WILD.
MOVE P1,T1 ;COPY FUNNY NAME.
MOVEM P1,IFILE+NAME ;MAKE IT THE NAME.
LB.1NO: IF.OFF IF,WEXT,LB.NST ;JUMP IF TRUE EXTENSION.
MOVE P2,T2 ;COPY FUNNY EXTENSION.
MOVEM P2,IFILE+EXT ;SAVE AS EXTENSION.
GOTO LB.NST ;SAVE THIS INFO.
;HERE TO CHECK ON A SPECIAL LABEL THAT HAS
;INFORMATION ONLY VALID FOR DECSYSTEM-10.
LB.IMI: MOVE T1,IM ;GET THE INPUT MODE.
GOSUB CVTLAB ;CONVERT THE LABEL.
MOVE T1,INPBUF ;GET THE IDENTIFIER.
CAMN T1,[SIXBIT "HEAD"] ;SKIP IF NOT HEADER LABEL.
ON S,L.HDR ;LIGHT HEADER BIT.
CAMN T1,[SIXBIT "TRAIL"] ;SKIP IF NOT TRAILER.
ON S,L.EOF ;LIGHT EOF BIT.
CAMN T1,[SIXBIT "REEL"] ;SKIP IF NOT END OF REEL.
ON S,L.EOV ;LIGHT VOLUME BIT.
IF.ON S,L.HDR!L.EOF!L.EOV ;SKIP IF WE FOUND ONE.
RETURN ZERO ;GIVE NO LABEL RETURN.
MOVE P1,INPBUF+2 ;GET THE FILE NAME.
HLLZ P2,INPBUF+3 ;GET THE EXTENSION.
MOVEM P1,LABNAM ;SAVE THE NAME.
MOVEM P2,LABNAM+1 ;SAVE THE EXTENSION.
MOVE P3,INPBUF+11 ;GET THE VOLUME NUMBER.
MOVEM P3,LABVOL ;SAVE THE VOLUME NUMBER.
MOVE T1,INPBUF+1 ;GET THE STRUCTURE.
MOVEM T1,LABSTR ;SAVE IT.
MOVE T1,INPBUF+7 ;GET THE CREATION DATE.
GOSUB DATCOB ;COMPRESS IT.
MOVEM T1,LABDTW ;SAVE THE DATE.
MOVE T2,INPBUF+6 ;GET THE PROTECTION BITS.
GOSUB TOBIN ;CONVERT IT IT BINARY.
DPB T3,[POINT 9,LABDTW,8] ;SAVE THE PROTECTION BITS.
MOVE T2,INPBUF+4 ;GET THE PROJECT NUMBER.
GOSUB TOBIN ;CONVERT IT.
HRLM T3,LABPPN ;SAVE THE FIRST HALF.
MOVE T2,INPBUF+5 ;GET THE PROGRAM NUMBER.
GOSUB TOBIN ;CONVERT IT.
HRRM T3,LABPPN ;SAVE THE PROGRAM NUMBER.
RETURN ONE ;BACK TO CALLER.
;HERE IF LABELS ARE TO BE CHECKED FOR BCL
;FORMAT.
LB.IBL: MOVE T1,IM ;GET THE MODE OF INPUT FILE.
GOSUB CVTLAB ;CONVERT THE LABEL TO SIXBIT.
MOVE T1,INPBUF ;MUST BE " LABEL".
CAME T1,[SIXBIT " LABEL"] ;MAKE SURE IT IS RIGHT.
RETURN ZERO ;NOT A LEGAL LABEL.
MOVE P2,[POINT 6,INPBUF+2,29];POINT TO LABEL-ID.
MOVE P1,[POINT 6,T1] ;POINT TO STORAGE WORD.
MOVEI P3,^D6 ;COUNT TO COPY.
GOSUB PLACE ;COPY THE CHARACTERS.
MOVE P1,T1 ;COPY TO BETTER AC.
MOVEM P1,LABNAM ;SAVE FIRST HALF OF NAME.
HLLZ P2,IFILE+EXT ;GET THE EXTENSION.
SETZM LABNAM+1 ;ZERO SECOND HALF.
LDB P3,[POINT 18,INPBUF+4,17];PICK UP THE VOLUME NUMBER.
LSH P3,^D12 ;SHIFT INTO PLACE.
ON P3,'0 ' ;ADD A LEADING ZERO.
MOVEM P3,LABVOL ;SAVE THE VOLUME NUMBER.
LDB T1,[POINT 6,INPBUF+6,23];PICK UP FLAG BIT FOR EOF.
CAIE T1,'0' ;SEE IF FLAGED AS EOF.
ON S,L.EOV ;SET END OF VOLUME BIT.
IF.ON S,L.EOV,RET1 ;RETURN IF WE SET IT.
ON S,L.HDR ;SET HEADER BIT.
HRRZ T1,INPBUF+4 ;GET THE FIRST HALF.
LSH T1,^D12 ;SHIFT INTO PLACE.
LDB T2,[POINT 12,INPBUF+5,11];GET THE SECON HALF.
IOR T1,T2 ;COMBINE THEM.
LSH T1,^D6 ;SET IT RIGHT.
GOSUB DATBCL ;COMPRESS THE DATE.
GOTO LABFIL ;FILL IN THE DEFAULTS.
;HERE TO CHECK LABELS WRITTEN IN DEC-COBOL
;FORMAT.
LB.NCL: GOSUB GETLAB ;READ A LABEL BLOCK.
RETURN ZERO ;BAD WE MADE A MISTAKE.
LB.ICL: MOVE T1,IM ;GET THE MODE OF INPUT.
GOSUB CVTLAB ;CONVERT THE LABEL TO SIXBIT.
LDB T1,[POINT 24,INPBUF,23] ;PICK UP HEADER WORD.
CAMN T1,[SIXBIT " VOL1"] ;IS THIS A VOLUME LABEL.
GOTO LB.NCL ;READ THE NEXT BLOCK IN.
CAMN T1,[SIXBIT " HDR1"] ;IS IT A HEADER LABEL.
ON S,L.HDR ;SET HEADER BIT.
CAMN T1,[SIXBIT " EOF1"] ;TEST FOR EOF LABEL.
ON S,L.EOF ;SET EOF BIT.
CAMN T1,[SIXBIT " EOV1"] ;TEST FOR END OF REEL.
ON S,L.EOV ;SET END OF TAPE BIT.
IF.ON S,L.HDR!L.EOF!L.EOV ;SKIP IF WE FOUND A LABEL.
RETURN ZERO ;NOT A LABEL.
MOVE P2,[POINT 6,INPBUF,23] ;POINTER TO LABEL-ID.
MOVE P1,[POINT 6,LABNAM] ;POINTER TO STORAGE WORD.
SETZM LABNAM+1 ;CLEAR TARGET.
MOVEI P3,^D9 ;CHARACTERS TO PLACE.
GOSUB PLACE ;PLACE THEM.
MOVE P1,LABNAM ;LOAD FIRST HALF OF NAME.
MOVE P2,LABNAM+1 ;LOAD SECOND HALF OF NAME.
LDB T1,[POINT 18,INPBUF+4,35];GET FIRST HALF OF NUMBER.
LDB T2,[POINT 6,INPBUF+5,5] ;GET THE OTHER HALF.
LSH T2,^D30 ;LEFT JUSTIFY DIGITS.
LSHC T1,^D18 ;SHIFT INTO PLACE.
MOVE P3,T1 ;COPY TO RETURN AC.
MOVEM P3,LABVOL ;SAVE THE VOLUME NUMBER.
LDB T1,[POINT 6,INPBUF+6,35];GET THE FIRST HALF OF DATE.
LSH T1,^D30 ;SHIFT INTO PLACE.
LDB T2,[POINT 29,INPBUF+7,29];GET THE OTHER BITS.
IOR T1,T2 ;MAKE ONE WORD.
GOSUB DATCOB ;COMPRESS THE DATE.
GOTO LABFIL ;FILL IN DEFAULTS.
;HERE TO CHECK LABELS WRITTEN IN GE635 BCD.
LB.IGE: MOVEI T1,XBDMOD ;GET MODE FOR LABELS.
GOSUB CVTLAB ;CONVERT IT TO SIXBIT.
MOVE T1,INPBUF ;GET FIRST WORD OF LABEL.
MOVE T2,INPBUF+1 ;GET THE SECOND WORD OF LABEL.
CAMN T1,[SIXBIT "GE 60"] ;TEST THE FIRST WORD.
CAME T2,[SIXBIT "0 BTL "] ;TEST THE SECOND WORD.
GOTO LB.0GE ;CHECK FOR EOF AND EOR.
MOVE T2,INPBUF+2 ;GET THE THIRD WORD OF LABEL.
CAMN T2,[SIXBIT "GE PHX"] ;TEST THE THIRD WORD.
ON S,L.HDR ;SET THE HEADER BIT.
LB.0GE: CAMN T1,[SIXBIT " EOF "] ;SEE IF END OF FILE LABEL.
ON S,L.EOF ;SET EOF BIT.
CAMN T1,[SIXBIT " EOR "] ;SEE IF END OF REEL.
ON S,L.EOV ;SET END OF REEL BIT.
IF.ON S,L.HDR!L.EOF!L.EOV ;SKIP IF WE FOUND A LABEL.
RETURN ZERO ;NOT A GE LABEL.
IF.OFF S,L.HDR,RET1 ;RETURN IF NOT HEADER.
MOVE P1,INPBUF+3 ;GET THE NAME IN THE LABEL.
HLLZ P2,IFILE+EXT ;GET THE EXTENSION.
LSH P1,6 ;SHIFT INTO PLACE.
MOVEM P1,LABNAM ;SAVE THE LABEL NAME.
SETZM LABNAM+1 ;CLEAR OTHER HALF.
MOVE T1,IFILE+NAME ;GET THE NAME SPECIFIED.
ANDI T1,77 ;ONLY CHECK FIVE CHARACTERS.
IOR P1,T1 ;SO COMPARE WILL ONLY CHECK FIVE.
MOVE P3,INPBUF+5 ;GET THE VOLUME NUMBER.
LSH P3,^D12 ;SHIFT INTO PLACE.
MOVEM P3,LABVOL ;SAVE THE VOLUME NUMBER.
LDB T1,[POINT 30,INPBUF+6,35] ;GET THE DATE.
LSH T1,6 ;SHIFT INTO PLACE.
GOSUB DATBCL ;COMPRESS THE DATE.
GOTO LABFIL ;FILL IN DEFAULTS.
;HERE TO READ AND VERIFY IBM LABELS.
LB.NBM: GOSUB GETLAB ;READ A LABEL BLOCK.
RETURN ZERO ;BAD WE MADE A MISTAKE.
LB.IBM: MOVEI T1,BCDMOD ;SET BCD MODE.
MOVEI T2,IF ;CHANNEL FOR INPUT FILE.
MME T2,.STS ;GET THE CONI WORD.
SKIPA ;IF IT FAILS USE EBCDIC.
IF.ON T2,TRK7 ;IF SEVEN TRACK WE'RE GOLDEN.
MOVEI T1,EBCMOD ;ELSE GET EBCDIC.
GOSUB CVTLAB ;CONVERT THE LABEL TO SIXBIT.
LB.IBI: LDB T1,[POINT 24,INPBUF,23] ;GET THE LABEL TYPE.
CAMN T1,[SIXBIT " VOL1"] ;CHECK FOR VOLUME LABEL.
GOTO LB.NBM ;GET THE NEXT LABEL BLOCK.
CAMN T1,[SIXBIT " HDR1"] ;SEE IF HEADER LABEL.
ON S,L.HDR ;SET THE HEADER BIT.
CAMN T1,[SIXBIT " EOF1"] ;TEST FOR END OF FILE LABEL.
ON S,L.EOF ;SET EOF BIT.
CAMN T1,[SIXBIT " EOV1"] ;TEST FOR END OF REEL.
ON S,L.EOV ;SET END OF REEL BIT.
IF.ON S,L.HDR!L.EOF!L.EOV ;SKIP IF WE FOUND A LABEL.
RETURN ZERO ;ELSE GIVE ERROR RETURN.
MOVE T1,[POINT 6,INPBUF,23] ;POINTER TO FILE NAME.
MOVE T2,[POINT 6,P1] ;POINTER TO STORAGE.
MOVEI T3,^D6 ;NUMBER TO PLACE.
MOVEI P3,^D17 ;MAX NUMBER TO READ.
GOSUB COPY ;COPY TO STORAGE.
MOVE T2,[POINT 6,P2] ;SET POINTER TO STORAGE.
MOVEI T3,^D3 ;SET MAX COUNT TO PLACE.
GOSUB COPY ;COPY THEM TO STORAGE.
MOVEM P1,LABNAM ;SAVE FIRST HALF OF NAME.
MOVEM P2,LABNAM+1 ;SAVE THE SECOND HALF.
LDB T1,[POINT 18,INPBUF+4,35];GET FIRST PART OF VOLUME NUMBER.
LDB T2,[POINT 6,INPBUF+5,5] ;GET THE SECOND HALF.
LSH T2,^D30 ;RIGHT JUSTIFY SECOND HALF.
LSHC T1,^D18 ;ALL INTO ONE WORD.
MOVE P3,T1 ;COPY TO RETURN AC.
MOVEM P3,LABVOL ;SAVE THE VOLUME NUMBER.
MOVE T1,INPBUF+7 ;GET THE DATE.
GOSUB DATBCL ;COMPRESS THE DATE.
GOTO LABFIL ;GO FILL IN DEFAULTS.
;HERE TO WRITE SPECIAL LABELS THAT HAVE INFORMATION
;FOR DECSYSTEM-10 ONLY.
LB.OMI: MOVE P1,[SIXBIT "HEAD"] ;LOAD HEADER WORD.
IF.OFF S,TERM ;SKIP IF NOT TRAILER.
MOVE P1,[SIXBIT "TRAIL"] ;LOAD TRAILER WORD.
IF.OFF S,FIN ;SKIP IF NOT END OF REEL.
MOVE P1,[SIXBIT "REEL"] ;LOAD END OF REEL WORD.
MOVEM P1,OUTBUF ;SAVE THE IDENTIFIER.
MOVE P1,IFILE+CHAN ;GET THE CHANNEL FOR INPUT.
MME P1,.NAM ;GET THE REAL NAME.
MOVE P1,IFILE+DEVICE ;IF MME FAILS.
MOVEM P1,OUTBUF+1 ;SAVE DEVICE WHERE IT CAME FROM.
MOVE P1,OFILE+NAME ;GET THE NAME.
MOVEM P1,OUTBUF+2 ;SAVE THE NAME.
HLLZ P1,OFILE+EXT ;GET THE EXTENSION.
MOVEM P1,OUTBUF+3 ;SAVE THE EXTENSION.
SKIPE T1,OFILE+PPN ;GET THE PPN TO WRITE IT AS.
GOTO .+3 ;CONTINUE ON WITH PPN IN T1.
SKIPN T1,IFILE+PPN ;GET THE INPUT PPN IF THERE.
MME T1,.PPN ;NO PPN USE CURRENT.
NOP ;IN CASE OF JACCT.
GOSUB MAK2 ;CONVERT TO TWO WORDS.
MOVEM T1,OUTBUF+4 ;SAVE THE PROJECT NUMBER.
MOVEM T2,OUTBUF+5 ;SAVE THE PROGRAM NUMBER.
LDB T1,[POINT 9,IFILE+DATTIM,8] ;LOAD PROTECTION BITS.
GOSUB MAK2 ;CONVERT TO SIXBIT.
MOVEM T2,OUTBUF+6 ;SAVE THE PROTECTION CODE.
LDB T1,[POINT 12,IFILE+DATTIM,35] ;LOAD DATE OF CREATION.
MOVE P1,[POINT 6,OUTBUF+7] ;GET A POINTER TO BUFFER.
GOSUB COBDAT ;PLACE DATE OF CRETATION.
MME T1,.DATE ;GET TODAYS DATE.
GOSUB COBDAT ;PUT IT AWAY.
MOVE P1,OFILE+VOL ;GET THE VOLUME NUMBER OF TAPE.
MOVEM P1,OUTBUF+11 ;SAVE THE VOLUME NUMBER.
MOVE T1,OFILE+PERGE ;GET THE REEL SERIAL NUMBER.
GOSUB MAKTWO ;CONVERT TO TWO WORDS.
MOVEM T2,OUTBUF+12 ;SAVE THE SERIAL NUMBER.
MOVE T1,OBCNT ;GET THE BLOCK.
IF.ON S,TERM!FIN ;SKIP IF TRAILER OR REEL LABEL.
SETZM T1 ;ZERO BLOCK COUNTER.
GOSUB MAKTWO ;CONVERT TO TWO WORDS.
MOVEM T2,OUTBUF+13 ;SAVE BLOCKS WRITTEN.
MOVE T1,ORCNT ;GET THE RECORD COUNTER.
IF.ON S,TERM!FIN ;SKIP IF TRAILER OR REEL LABEL.
SETZM T1 ;CLEAR RECORD COUNTER.
GOSUB MAKTWO ;CONVERT TO TWO WORDS.
MOVE P2,[POINT 6,T1,23] ;POINTER TO WHAT WE WANT.
MOVE P1,[POINT 6,OUTBUF+14] ;POINTER TO STORAGE.
MOVEI P3,^D8 ;NUMBER TO PLACE.
GOSUB PLACE ;PLACE THEM.
MOVE T2,OM ;GET THE OUTPUT INDEX.
GOTO LB.CLO ;WRITE LABEL TO TAPE.
;HERE TO PRODUCE IBM 360/OS LABELS.
LB.OBM: MOVEI T2,BCDMOD ;ASSUME A SEVEN TRACK DRIVE.
MOVEI T1,OF ;GET OUTPUT DEVICE CHANNEL.
MME T1,.STS ;GET LAST CONI WORD.
SKIPA ;USE EBCDIC IF MME FAILS.
IF.ON T1,TRK7 ;SKIP IF SEVEN TRACK DRIVE.
MOVEI T2,EBCMOD ;ELSE USE EBCDIC.
MOVEM T2,TEMP1 ;SAVE WHAT WE DECIDED ON.
IF.ON S,TERM,LB.OBH ;JUMP IF TRAILER.
GETSTS OF,T1 ;GET THE DEVICE STATUS.
IF.OFF T1,E.BOT,LB.OBH ;ONLY WRITE VOL'S AT BOT.
SKIPE OFILE+PERGE ;REEL NUMBER SPECIFIED.
GOTO LB.PBM ;YES PERGE THE LABEL.
MOVE T2,TEMP1 ;GET THE MODE OF THE LABEL.
GOSUB REDOUT ;READ THE OUTPUT LABEL.
GOTO BADTM ;EOF MARK FOUND.
DRIVE OF,.BSR ;BACK UP OVER LABEL.
DRIVE OF,.WAT ;WAIT FOR COMPLETION.
LDB T1,[POINT 24,OUTBUF,23] ;GET THE IDENTIFIER.
CAMN T1,[SIXBIT " HDR1"] ;IS IT A HEADER LABEL.
GOTO LB.OBH ;YES SO DON'T WRITE A VOL LABEL.
CAME T1,[SIXBIT " VOL1"] ;IS IT A VOLUME LABEL.
GOTO NOTLAB ;NO SO ERROR.
MOVE P2,[POINT 6,OUTBUF,23] ;POINTER TO SERIAL NUMBER.
MOVE P1,[POINT 6,RELNUM] ;POINTER TO STORAGE.
MOVEI P3,^D6 ;CHARACTERS TO MOVE.
GOSUB PLACE ;MOVE THEM.
LB.BVL: MOVE P1,[POINT 6,OUTBUF] ;POINTER TO STORAGE.
MOVE P2,[POINT 6,[SIXBIT "VOL1"]];IDENTIFIER.
MOVEI P3,^D4 ;CHARACTERS TO MOVE.
GOSUB PLACE ;MOVE THEM.
MOVE P2,[POINT 6,RELNUM] ;POINTER TO REEL NUMBER.
MOVEI P3,^D6 ;NUMBER TO PLACE.
GOSUB PLACE ;MOVE THEM TO BUFFER.
MOVEI CH,'0' ;A LONELY ZERO.
IDPB CH,P1 ;PLACE INTO BUFFER.
MOVEI P3,^D30 ;COUNT FOR SOME SPACES.
GOSUB SPACE ;PLACE THEM INTO BUFFER.
MOVE P2,[POINT 6,[SIXBIT "DIGITAL"]];PLACE THAT DID THIS.
MOVEI P3,^D7 ;A COUNTER.
GOSUB PLACE ;INTO BUFFER.
MOVEI P3,^D32 ;SOME MORE SPACES.
GOSUB SPACE ;ADD THEM TO BUFFER.
MOVE T2,TEMP1 ;GET MODE OF OUTPUT.
GOSUB WRILAB ;WRITE THE LABEL.
LB.OBH: MOVE P1,[POINT 6,OUTBUF] ;SET A NEW POINTER.
MOVE P2,[POINT 6,[SIXBIT "HDR1"]];HEADER ONE ID.
IF.OFF S,TERM ;IS THIS REALLY EOF.
MOVE P2,[POINT 6,[SIXBIT "EOF1"]];CHANGE MESSAGE.
IF.OFF S,FIN ;IS THIS REALLY JUST END OF REEL.
MOVE P2,[POINT 6,[SIXBIT "EOV1"]];CHANGE MESSAGE.
MOVEI P3,^D4 ;COUNT TO PLACE.
GOSUB PLACE ;INTO BUFFER.
MOVE P2,[POINT 6,OFILE+NAME] ;POINTER TO FILE-ID.
MOVEI P3,^D9 ;CHARACTERS TO MOVE.
GOSUB PLACE ;IN TO BUFFER.
MOVEI P3,^D14 ;CHARACTERS TO SPACE.
GOSUB SPACE ;INTO BUFFER.
MOVE P2,[POINT 6,OFILE+VOL] ;POINTER TO VOLUME NUMBER.
MOVEI P3,^D4 ;NUMBER TO MOVE.
GOSUB PLACE ;INTO BUFFER.
MOVEI P3,^D11 ;SOME MORE SPACES.
GOSUB SPACE ;INTO BUFFER.
MME T1,.DATE ;GET TODAY'S DATE.
GOSUB BCLDAT ;INTO BUFFER.
SETZM CH ;AN UNWANTED SPACE.
IDPB CH,P1 ;SAVE IT.
MME T1,.DATE ;GET THE DATE AGAIN.
ADDI T1,^D984 ;SAVE FACTOR.
GOSUB BCLDAT ;INTO BUFFER.
MOVEI CH,'0' ;A LITTLE ZERO.
IDPB CH,P1 ;INTO BUFFER.
IF.OFF S,TERM,LB.IBH ;JUMP IF HEADER.
MOVE T1,OBCNT ;GET THE BLOCK COUNT.
GOSUB MAKTWO ;INTO TWO WORDS.
SKIPA P2,[POINT 6,T2] ;SET POINTER.
LB.IBH: MOVE P2,[POINT 6,[SIXBIT "000000"]];FILL BLOCK COUNT WITH ZEROS.
MOVEI P3,^D6 ;COUNT TO MOVE.
GOSUB PLACE ;INTO BUFFER.
MOVEI P3,^D20 ;SOME SPACES.
GOSUB SPACE ;INTO BUFFER.
MOVE T2,TEMP1 ;GET THE MODE OF OUTPUT.
GOSUB WRILAB ;WRITE THE LABEL.
MOVE P1,[POINT 6,OUTBUF] ;GET NEW POINTER.
MOVE P2,[POINT 6,[SIXBIT "HDR2"]];ASSUME HEADER LABEL.
IF.OFF S,TERM ;SKIP IF NOT EOF.
MOVE P2,[POINT 6,[SIXBIT "EOF2"]];CHANGE MESSAGE.
IF.OFF S,FIN ;SKIP IF NOT END OF REEL.
MOVE P2,[POINT 6,[SIXBIT "EOV2"]];CHANGE MESSAGE.
MOVEI P3,^D4 ;COUNT TO PUT.
GOSUB PLACE ;INTO BUFFER.
HRRZ T1,OM ;GET THE OUTPUT MODE.
SETZM T2 ;CLEAR INDEX.
CAIN T1,VEBMOD ;IS IT VARIABLE EBCDIC.
MOVEI T2,ONE ;YES SET INDEX TO ONE.
CAIN T1,EBCMOD ;IS IF FIXED EBCDIC.
MOVEI T2,TWO ;YES SET INDEX TO TWO.
MOVE CH,[EXP 'U','V','F'](T2);GET DISCRIPTOR.
IDPB CH,P1 ;INTO BUFFER.
MOVE T1,OFILE+RECSIZ ;GET THE RECORD SIZE.
ADD T1,[EXP 0,4,0](T2) ;ADD IN THE OFFSET.
SKIPE OFILE+BLKFCT ;SKIP IF NO BLOCKING FACTOR.
IMUL T1,OFILE+BLKFCT ;MULTIPLY BY BLOCKING FACTOR.
ADD T1,[EXP 0,4,0](T2) ;ADD IN OFFSET.
SAVE T2 ;SAVE THE INDEX.
GOSUB MAKTWO ;CONVERT IT TO TWO WORDS.
MOVE P2,[POINT 6,T2,5] ;POINTER TO WHAT WE WANT.
MOVEI P3,^D5 ;CHARACTERS TO PLACE.
GOSUB PLACE ;INTO BUFFER.
UNSAVE T2 ;RESTORE THE INDEX.
MOVE T1,OFILE+RECSIZ ;GET THE RECORD SIZE.
ADD T1,[EXP 0,4,0](T2) ;ADD IN THE OFFSET.
IMUL T1,[EXP 0,1,1](T2) ;PRODUCE RECORD SIZE.
GOSUB MAKTWO ;CONVERT TO TWO WORDS.
MOVE P2,[POINT 6,T2,5] ;POINTER TO WHAT WE WANT.
MOVEI P3,^D5 ;CHARACTERS TO PLACE.
GOSUB PLACE ;INTO BUFFER.
MOVEI T1,OF ;GET THE OUTPUT CHANNEL NUMBER.
MME T1,.TAPE ;GET THE DENSITY OF THE TAPE.
MOVEI T1,3 ;MAKE IT 800 IF IT FAILS.
ADDI T1,'0'-1 ;MAKE IT SIXBIT.
IDPB T1,P1 ;INTO BUFFER.
MOVEI CH,'0' ;LOAD A ZERO FOR EOF.
IF.OFF S,FIN ;SKIP IF NOT EOV.
MOVEI CH,'1' ;DENOTE END OF REEL.
IDPB CH,P1 ;SAVE IT IN THE BUFFER.
MOVE P2,[POINT 6,PRGNAM] ;POINT TO OUR NAME.
MOVEI P3,^D6 ;CHARACTERS IN NAME.
GOSUB PLACE ;INTO BUFFER.
MOVE P2,[POINT 6,[SIXBIT " /"]];SOME GOOD THINGS.
MOVEI P3,^D3 ;CHARACTERS TO MOVE.
GOSUB PLACE ;INTO BUFFER.
MOVEI P3,^D12 ;COUNT FOR SOME SPACES.
GOSUB SPACE ;INTO BUFFER.
MOVEI CH,'B' ;LOAD A B FOR BLOCKED RECORDS.
IF.OFF OF,SPAN ;ARE WE SPANNING.
MOVEI CH,'S' ;YES LOAD AN S.
IDPB CH,P1 ;SAVE IT IN THE BUFFER.
MOVEI P3,^D41 ;FINISH THE RECORD WITH
GOSUB SPACE ;SPACES.
MOVE T2,TEMP1 ;GET THE MODE OF THE LABEL.
GOTO LB.CLO ;WRITE THE LABEL.
;HERE TO PEGE AN IBM LABEL.
LB.PBM: TEO S,PRG ;BEEN HERE BEFORE.
AOSA T1,OFILE+PERGE ;YES SO BUMP NUMBER.
MOVE T1,OFILE+PERGE ;NO SO GET THE PERGE NUMBER.
GOSUB MAKTWO ;CONVERT IT TO TWO WORDS.
MOVE P1,[POINT 6,RELNUM] ;POINTER TO STORAGGE.
MOVE P2,[POINT 6,T2] ;POINTER TO NUMBER.
MOVEI P3,^D6 ;COUNT TO MOVE.
GOSUB PLACE ;INTO STORAGE.
GETSTS OF,T1 ;GET THE DEVICE STATUS.
IF.OFF T1,E.BOT,LB.OBH ;VOL1 ONLY AT BOT.
GOTO LB.BVL ;OTHERWISE LABELS ARE STANDARD.
;HERE TO WRITE GE635 LABELS IN GE635 BCD.
LB.OGE: MOVE P1,[POINT 6,OUTBUF] ;SET POINTER TO BUFFER.
IF.ON S,TERM,LB.GED ;JUMP IF REALLY TRAILERS.
MOVE P2,[POINT 6,[SIXBIT "GE 600 BTL GE PHX "]];IDENTIFIER.
MOVEI P3,^D19 ;COUNTER.
GOSUB PLACE ;PUT IT IN THE BUFFER.
MOVE P2,[POINT 6,OFILE+NAME] ;POINTER TO LABEL ID.
MOVEI P3,^D5 ;FIVE CHARACTERS IN NAME.
GOSUB PLACE ;INTO BUFFER.
SETZM CH ;AN UNUSED SPACE.
IDPB CH,P1 ;PLACE IT IN THE BUFFER.
MOVE P2,[POINT 6,OFILE+NAME] ;POINTER TO SERIAL SAME AS NAME.
MOVEI P3,^D5 ;COUNT TO PUT.
GOSUB PLACE ;INTO BUFFER.
MOVEI P3,^D2 ;SOME SPACES.
GOSUB SPACE ;ADD TO BUFFER.
MOVE P2,[POINT 6,OFILE+VOL] ;POINTER TO VOLUME NUMBER.
MOVEI P3,^D4 ;COUNT TO PUT.
GOSUB PLACE ;INTO BUFFER.
SETZM CH ;ANOTHER OUT OF PLACE SPACE.
IDPB CH,P1 ;PLACE IN THE BUFFER.
MME T1,.DATE ;GET THE DATE.
GOSUB BCLDAT ;TO FORMAT WE WANT.
MOVE P2,[POINT 6,[SIXBIT " 000"]];UNUSED THINGS.
MOVEI P3,^D6 ;COUNT TO PLACE.
GOSUB PLACE ;ADD TO THE BUFFER.
MOVE P2,[POINT 6,PASS] ;POINTER TO PASSWORD.
MOVEI P3,^D12 ;CHARACTERS IN PASSWORD.
GOSUB PLACE ;PUT IT IN THE BUFFER.
SKIPE PASS ;IS THERE A PASSWORD.
GOTO LB.PRT ;YES PROTECT THE TAPE.
SKIPN PASS+1 ;TRY OTHER HALF.
SKIPA P2,[POINT 6,[SIXBIT "!!!000"]];NO PROTECTION.
LB.PRT: MOVE P2,[POINT 6,[SIXBIT "!!!^00"]];PROTECTION WORD.
MOVEI P3,^D6 ;COUNT TO PLACE.
GOSUB PLACE ;INTO BUFFER.
MOVEI CH,'0' ;FILL THE REST OF THE LABEL
MOVEI P3,^D14 ;WITH ZEROS.
GOSUB ANYCHR ;INTO BUFFER.
MOVEI T2,XBDMOD ;MODE TO WRITE IT IN.
;HERE TO WRITE THE LABEL TO THE TAPE.
LB.CLO: GOSUB WRILAB ;WRITE THE LABEL TO TAPE.
CLOSE OF,ZERO ;WRITE AN EOF MARK.
GETSTS OF,T1 ;GET THE DEVICE STATUS.
TEZ T1,E.ERR ;SKIP IF NO ERROR.
PRINT (% Error while writing label.")
SETSTS OF,ZERO(T1) ;RESET THE STATUS.
RETURN ZERO ;BACK TO CALLER.
LB.GED: MOVE P2,[POINT 6,[SIXBIT " EOF "]];ASSUME END OF FILE.
IF.OFF S,FIN ;SKIP IF WE ARE RIGHT.
MOVE P2,[POINT 6,[SIXBIT " EOR "]];SET IT AS END OF REEL.
MOVEI P3,^D6 ;COUNT TO PLACE.
GOSUB PLACE ;INTO BUFFER.
MOVE T1,OBCNT ;GET THE BLOCKS WRITTEN.
GOSUB MAKTWO ;CONVERT TO TWO WORDS.
MOVE P2,[POINT 6,T2] ;POINT TO WHAT WE WANT.
MOVEI P3,^D6 ;SIX TO PLACE.
GOSUB PLACE ;PLACE THEM.
MOVEI CH,'0' ;FILL THE REST OF THE LABEL
MOVEI P3,^D68 ;WITH ZEROS.
GOSUB ANYCHR ;FINISH THE LABEL.
GOTO LB.CLO-1 ;WRITE THE LABEL.
;HERE TO READ AND WRITE OUTPUT LABELS
;IN BCL FORMAT.
LB.OBL: IF.ON S,TERM,LB.BGN ;JUMP IF TRAILER.
GETSTS OF,T1 ;GET THE DEVICE STATUS.
IF.OFF T1,E.BOT,LB.BGN ;JUMP IF NOT AT BOT.
SKIPE OFILE+PERGE ;SERIAL NUMBER SPECIFIED.
GOTO LB.PBL ;YES PERGE THE LABEL.
MOVE T2,OM ;GET THE MODE OF THE OUTPUT.
GOSUB REDOUT ;READ THE OUTPUT LABEL.
GOTO BADTM ;EOF MARK FOUND.
DRIVE OF,.BSR ;BACK UP TO START OF LABEL.
DRIVE OF,.WAT ;WAIT FOR COMPLETION.
MOVE T1,OUTBUF ;PICK UP HEADER WORD.
CAME T1,[SIXBIT " LABEL"] ;MAKE SURE IT IS A LABEL.
GOTO NOTLAB ;YOU LOOSE.
MOVE P2,[POINT 6,OUTBUF+10,29];POINT TO REEL NUMBER.
MOVE P1,[POINT 6,RELNUM] ;POINTER TO STORAGE.
MOVEI P3,^D5 ;CHARACTERS TO COPY.
GOSUB PLACE ;COPY THEM.
LB.BGN: MOVE P1,[POINT 6,OUTBUF] ;POINTER TO STORAGE.
MOVE P2,[POINT 6,[SIXBIT " LABEL 0000000 0"]];IDENTIFIER.
MOVEI P3,^D17 ;COUNT TO PLACE.
GOSUB PLACE ;PLACE IT IN PLACE.
MOVE P2,[POINT 6,OFILE+NAME] ;POINTER TO LABEL-ID.
MOVEI P3,^D6 ;SIX CHARACTERS IN ID.
GOSUB PLACE ;INTO BUFFER.
MOVEI P2,' ' ;PUT IN AN UNUSED SPACE.
IDPB P2,P1 ;PUT IT INTO LABEL.
MOVE P2,[POINT 6,OFILE+VOL,5];POINTER TO VOLUME NUMBER.
MOVEI P3,^D3 ;VOLUME GOES FROM 1-999.
GOSUB PLACE ;PUT IT AWAY.
MME T1,.DATE ;GET TODAY'S DATE.
GOSUB BCLDAT ;CONVERT TO FORMAT WE WANT.
MOVEI CH,'0' ;SOME UNUSED POSITIONS.
MOVEI P3,^D2 ;COUNTER.
GOSUB ANYCHR ;PUT THEM AWAY.
MME T1,.DATE ;GET TODAY'S DATE AGAIN.
ADDI T1,^D984 ;ADD IN SAVE FACTOR.
GOSUB BCLDAT ;CONVERT DATE.
MOVEI P2,'0' ;LOAD A ZERO FOR END OF FILE.
IF.OFF S,FIN ;IS THIS END OF FILE.
MOVEI P2,'1' ;NO JUST END OF REEL.
IDPB P2,P1 ;SAVE IT IN BUFFER.
IF.OFF S,TERM,LB.HDR ;JUMP IF THIS IS REALLY HEADER.
MOVE T1,OBCNT ;PICK UP BLOCKS WRITTEN.
GOSUB MAKTWO ;CONVERT IT TO TWO WORDS.
MOVE P2,[POINT 6,T2,5] ;POINT TO WHAT WE WANT.
MOVEI P3,^D5 ;FIVE CHARACTERS TO COPY.
GOSUB PLACE ;COPY TO OUTPUT BUFFER.
MOVE T1,ORCNT ;GET RECORD COUNT.
GOSUB MAKTWO ;MAKE TWO WORDS.
MOVE P2,[POINT 6,T1,29] ;POINT TO WHAT WE WANT.
MOVEI P3,^D7 ;CHARACTERS TO PLACE.
GOSUB PLACE ;PLACE THEM INTO PLACE.
MOVEI CH,'0' ;UNUSED POSITION.
IDPB CH,P1 ;PUT IT AWAY.
LB.FIN: MOVE P2,[POINT 6,RELNUM] ;POINTER TO REEL NUMBER.
MOVEI P3,^D5 ;FIVE CHARACTERS TO PUT.
GOSUB PLACE ;PLACE THEM.
MOVEI P3,^D26 ;POSITIONS LEFT.
MOVEI CH,'0' ;FINISH BUFFER WITH ZEROS.
GOSUB ANYCHR ;FILL THE BUFFER.
MOVE T2,OM ;GET THE MODE OF THE OUTPUT.
GOTO LB.CLO ;WRITE THE LABEL.
LB.HDR: MOVEI P3,^D13 ;IF HEADER WE DON'T WRITE
MOVEI CH,'0' ;BLOCK AND RECORD COUNTS.
GOSUB ANYCHR ;FILL THESE WITH ZEROS.
GOTO LB.FIN ;DO THE REST.
;HERE IF THE LABELS ARE TO BE WRITTEN IN BCL FORMAT
;BUT NOT CHECKED FIRST. IN THIS CASE THE REEL NUMBER
;OF THE TAPE WAS SPECIFIED IN THE REEL SWITCH.
LB.PBL: TEO S,PRG ;HAVE WE ALREADY DONE THIS.
AOSA T1,OFILE+PERGE ;YES SO BUMP REEL NUMBER FOR LABEL.
MOVE T1,OFILE+PERGE ;GET THE NEW NUMBER.
GOSUB MAKTWO ;CONVERT IT TO SIXBIT.
MOVE P1,[POINT 6,RELNUM] ;POINTER TO STORAGE.
MOVE P2,[POINT 6,T2,5] ;POINTER TO WHAT WE WANT.
MOVEI P3,^D5 ;COUNT TO PLACE.
GOSUB PLACE ;PLACE THEM.
GOTO LB.BGN ;OTHERWISE LABELS ARE STANDARD.
;HERE TO WRITE OUT DEC-COBOL HEADER AND TRAILER LABELS.
LB.OCL: MOVE P2,[POINT 6,[SIXBIT "HDR1"]];ASSUME HEADER LABEL.
IF.OFF S,TERM ;IS THIS A TERMINAL LABEL.
MOVE P2,[POINT 6,[SIXBIT "EOF1"]];YES CHANGE MESSAGE.
IF.OFF S,FIN ;IS THIS REALLY JUST END OF REEL.
MOVE P2,[POINT 6,[SIXBIT "EOV1"]];JUST END OF REEL.
MOVE P1,[POINT 6,OUTBUF] ;SET POINTER TO LABEL BUFFER.
MOVEI P3,^D4 ;COUNT TO PLACE.
GOSUB PLACE ;PUT IT INTO BUFFER.
MOVE P2,[POINT 6,OFILE+NAME] ;POINTER TO NAME.
MOVEI P3,^D9 ;NINE CHARACTERS IN NAME.
GOSUB PLACE ;INTO BUFFER.
MOVEI P3,^D14 ;FOURTEEN SPACES.
GOSUB SPACE ;INTO BUFFER.
MOVE P2,[POINT 6,OFILE+VOL] ;GET VOLUME NUMBER.
MOVEI P3,^D4 ;GET THE COUNT OF CHARACTERS.
GOSUB PLACE ;PUT IT INTO BUFFER.
MOVEI P3,^D10 ;SET COUNT.
GOSUB SPACE ;INTO BUFFER.
MME T1,.DATE ;GET THE DATE.
GOSUB COBDAT ;FIX IT INTO PLACE.
MOVEI P3,^D33 ;NUMBER OF PLACES LEFT.
GOSUB SPACE ;SPACES TO BUFFER.
MOVE T2,OM ;GET THE MODE OF THE OUTPUT.
MOVNI P2,^D80 ;CHARACTERS IN LABEL.
GOSUB WRILAB ;WRITE THE LABEL TO TAPE.
IF.OFF S,TERM ;IS THIS AN EOF LABEL.
CLOSE OF,ZERO ;YES WRITE EOF MARK.
RETURN ZERO ;BACK TO SENDER.
;HERE TO PUT OUT A HEADER FOR THE LINE PRINTER.
HDRLPT: IF.ON OF,NOHEAD,RET0 ;RETURN IF NOT WANTED.
ON S,LHEAD ;SAY WE ARE DOING HEADERS.
MOVE T1,[POINT 7,HDRWRD] ;SET POINTER TO STORAGE.
MME T3,.PPN ;GET OUR PPN.
NOP ;IN CASE OF JACCT.
HLLZS T3 ;JUST THE PROJECT NUMBER.
GOSUB HDR1 ;CONVERT TO ASCII.
MOVEI T2,"," ;TO SEPARATE THINGS.
IDPB T2,T1 ;SAVE IT.
MME T3,.PPN ;GET THE PPN BACK.
NOP ;IN CASE OF JACCT.
HRLZ T3,T3 ;TO THE RIGHT HALF.
GOSUB HDR1 ;CONVERT IT.
SETZM T2 ;SET END FLAG.
IDPB T2,T1 ;SAVE IT.
SETZB P1,P2 ;CLEAR COUNTERS.
GOSUB MATRIX ;BLACKOUT SOMETHINGS.
GOTO XNAME ;TYPE THE FILE NAME.
HDR1: MOVNI P1,6 ;COUNT TO PLACE.
SETZM T2 ;CLEAR A REGISTER.
LSHC T2,3 ;GET A DIGIT.
MOVEI T2,"0"(T2) ;MAKE IT ASCII.
IDPB T2,T1 ;SAVE IT.
AOJN P1,HDR1+1 ;CONTINUE FOR THE COUNT.
RETURN ZERO ;AND RETURN.
;HERE TO PUT A TRAILER HEADER ON THE LINE PRINTER.
EOFLPT: IF.ON OF,NOHEAD,RET0 ;RETURN IF NOT WANTED.
ON S,LHEAD ;SAY WE ARE DOING HEADINGS.
MOVEI CH,14 ;GET A FORM FEED FIRST.
TNZ S,FF ;SKIP IF LAST WAS A FORM.
GOSUB UME4 ;ONTO THE DEVICE.
GOSUB MATRIX ;START IT GOING.
EOF1: MME T1,.TIME ;GET THE TIME OF DAY.
ANDI T1,77 ;MASK OUT SOME BITS.
CAIL T1,ENDCNT ;SEE IF OUT OF THE TABLE.
GOTO EOF1 ;TRY AGAIN.
CAMN T1,LSTVAL ;IS IT THE SAME AS THE LAST.
GOTO EOF1 ;TRY AGAIN.
MOVEM T1,LSTVAL ;SAVE THE LAST ONE.
MOVE T1,ENDTAB(T1) ;GET THE LOCATION OF THE MESSAGE.
MOVE T2,ONE(T1) ;GET THE SECOND HALF.
MOVE T1,ZERO(T1) ;GET THE FIRST HALF.
GOSUB CODE ;PUT IT INTO ASCII.
;HERE TO PLACE THE FILE NAME AND THE ASSORTED OTHER
;THINGS ON THE PRINTER.
XNAME: GOSUB PICTURE ;PUT THE PICTURE OUT.
MOVE T1,OFILE+NAME ;GET THE NAME.
HLLZ T2,OFILE+EXT ;GET THE EXTENSION.
GOSUB DECODE ;SET IT UP RIGHT.
GOSUB PICTURE ;ONTO THE LINE PRINTER.
GOSUB MATRIX ;BLACKOUT SOMETINGS.
UME .ASC,[BYTE (7)15,12,0] ;SKIP A LINE.
MME T2,.PJOB ;GET MY JOB NUMBER.
HRLZ T2,T2 ;INTO THE RIGHT HALF.
HRRI T2,31 ;TABLE ENTRY FOR NAME.
MME T2,.TAB ;GET FIRST HALF OF NAME.
SETZM T2 ;CLEAR IF CAN'T GET IT.
UME .SIX,T2 ;INTO BUFFER.
MME T2,.PJOB ;GET MY JOB NUMBER BACK.
HRLZ T2,T2 ;INTO RIGHT HALF.
HRRI T2,32 ;SECOND HALF OF NAME.
MME T2,.TAB ;GET THE ENTRY.
SETZM T2 ;CLEAR IF CAN'T GET IT.
UME .SIX,T2 ;INTO BUFFER.
UME .ASC,[ASCIZ " "] ;TO SEPARATE THINGS.
GOSUB PUTDAT ;PUT THE DATE.
UME .ASC,[ASCIZ " "] ;SEPARATE THINGS.
GOSUB PUTTIM ;PUT A TIME STAMP ON IT.
MOVEI CH,14 ;A FORM FEED.
GOSUB PUT ;INTO BUFFER.
OFF S,LHEAD ;HEADINGS ARE DONE.
GOTO EMPTY ;WRITE THE BUFFERS.
;HERE TO CONVERT TWO SIXBIT WORDS TO ASCII.
DECODE: JUMPE T2,CODE ;DON'T ADD PERIOD IF NO EXTENSION.
LSH T2,-6 ;MAKE ROOM FOR PERIOD.
IOR T2,[SIXBIT "."] ;ADD A PERIOD.
CODE: MOVE T3,[POINT 6,T1] ;GET A POINTER TO DATA.
MOVE P3,[POINT 7,HDRWRD] ;POINTER TO STORAGE.
MOVNI P1,15 ;SET THE MAX TO DO.
MOVNI P2,^D12 ;NUMBER OF CHARACTERS TO DO.
CODE1: ILDB CH,T3 ;GET A CHARACTER.
JUMPE CH,CODE2 ;DON'T DO NULLS.
MOVEI CH," "(CH) ;CONVERT TO ASCII.
IDPB CH,P3 ;SAVE IT.
AOS P1 ;COUNT THE CHARACTER.
CODE2: AOJN P2,CODE1 ;JUMP IF STILL HAVE MORE.
SETZM CH ;FOR END FLAG.
IDPB CH,P3 ;SAVE IT.
CODE3: MOVN P1,P1 ;MAKE P1 POSITIVE.
IMULI P1,6 ;SIX SPACES PER CHARACTER.
SETZM P2 ;CLEAR P1+1.
LSHC P1,-1 ;DIVIDE P1 BY TWO.
ROT P2,1 ;SO IT CAN BE USED AS AN INDEX.
RETURN ZERO ;BACK TO CALLER.
;HERE TO SEND SOME "X"'S TO THE LINE PRINTER.
MATRIX: GOSUB MAT0 ;CALL THE X PRINTER TWICE.
GOSUB MAT0 ;ONE MORE TIME.
UME .ASC,[BYTE (7)15,12,0] ;SKIP A LINE.
RETURN ZERO ;BACK TO CALLER.
MAT0: MOVNI P4,^D131 ;NUMBER OF POSITIONS.
MOVEI CH,"X" ;CHARACTER TO PRINT.
GOSUB UME4 ;PLACE IT.
AOJN P4,.-2 ;CONTINUE ON.
UME .ASC,[BYTE (7)15,12,0] ;SKIP A LINE.
RETURN ZERO ;BACK TO CALLER.
;HERE TO PRINT A CHARACTER POSTION ALL FILLED IN.
BLACKO: GOSUB BLACK ;CALL THE STAR PRINTER
GOSUB BLACK ;THREE TINES.
BLACK: MOVNI P4,5 ;GET A COUNTER.
MOVEI CH,"*" ;CHAARACTER TO PRINT.
GOSUB UME4 ;ON THE DEVICE.
AOJN P4,.-2 ;LOOP ON THAT.
MOVEI CH," " ;A SPACE TO SEPARATE THINGS.
GOTO UME4 ;ONTO THE DEVICE.
;HERE TO PRINT SOME BLANKS TO EVEN THINGS UP.
XSPACE: JUMPE P1,RET0 ;JUMP IF DON'T NEED ANY.
MOVN P4,P1 ;GET THE NEGATIVE COUNT.
MOVEI CH," " ;GET A SPACE.
GOSUB PUT ;INTO THE BUFFER.
AOJN P4,.-2 ;FOR THE COUNT.
RETURN ZERO ;BACK TO CALLER.
;HERE TO PRINT THE BLOCK LETTERS ON THE LINE PRINTER.
PICTUR: MOVNI P3,43 ;SET UP BITS IN MAP.
MOVE T2,[POINT 7,HDRWRD] ;POINTER TO THINGS TO PLACE.
GOSUB BLACKOUT ;BEGIN IT GOING.
UME .ASC,BLANK ;SOME BLANKS.
GOSUB XSPACE ;EVEN THINGS UP.
ILDB T3,T2 ;GET A BYTE.
JUMPE T3,.+3 ;JUMP IF AT END.
GOSUB XPUT ;INTO BUFFER.
GOTO .-3 ;CONTINUE LOOP.
GOSUB XSPACE ;SOME SPACES.
UME .ASC,BLANK(P2) ;SOME ODD SPACES.
GOSUB BLACKOUT ;WIPE THINGS OUT.
UME .ASC,[BYTE (7)15,12,0] ;NEXT LINE.
ADDI P3,5 ;SET NEXT BIT PATTERN.
JUMPL P3,PICTURE+1 ;TEST AND JUMP IF HAVE MORE.
UME .ASC,[BYTE (7)15,12,0] ;NEXT LINE.
RETURN ZERO ;BACK TO CALLER.
;HERE TO ACTUALLY PUT THE STUFF OUT.
XPUT: MOVE T3,CHRTAB-40(T3) ;GET A BIT PATTERN.
ROT T3,43(P3) ;DIAL A FIVE BIT GROUP.
MOVNI P4,5 ;SET UP COUNTER.
XPUT1: MOVEI CH," " ;LOAD A SPACE.
SKIPGE T3 ;SKIP IF O.K.
MOVEI CH,"@" ;ELSE SET IT FOR ON BIT.
GOSUB UME4 ;TO THE DEVICE.
ROT T3,1 ;DIAL NEXT BIT.
AOJL P4,XPUT1 ;CONTINUE ON.
MOVEI CH," " ;A TRAILING SPACE.
GOTO PUT ;TO THE LINE PRINTER.
BLANK: ASCIZ " "
USE DATA
BSS HDRWRD,5
BSS LSTVAL,ONE
USE CODE
SUBTTL *** BASIC I/O ROUTINES ***
;HERE TO BUILD BUFFERS FOR MAG-TAPE.
MAKE: HRRZ T3,CHRMOD(SIDE) ;GET THE MODE OF THE INPUT.
SKIPN T2,RECSIZ(SIDE) ;GET THE RECORD SIZE.
RETURN ZERO ;NONE SPECIFIED USE DEFAULT.
CAIG T3,GEAMOD ;SKIP IF NOT ASCII.
ADDI T2,TWO ;ACCOUNT FOR CRLF.
MOVE P1,STS(T3) ;GET THE STATUS WORD.
ADDI T2,ZERO(P1) ;ADD WHAT IS NEEDED FOR CTRL WORD.
HRRZ P2,MSIZ(T3) ;GET THE BYTES PER WORD.
CAIE T3,SIXMOD ;SKIP IF SIXBIT.
GOTO MAKE1 ;ELSE FORGET NEXT FEW THINGS.
ADDI T2,-1(P2) ;FORCE TO A WORD BOUNDARY.
IDIVI T2,ZERO(P2) ;PRODUCE INTEGER PART.
IMULI T2,ZERO(P2) ;PRODUCE A WORD MULTIPLE.
MAKE1: SKIPE BLKFCT(SIDE) ;BAG THE MULTIPLY IF ZERO.
IMUL T2,BLKFCT(SIDE) ;MULTIPLY BY BLOCKING FACTOR.
IF.OFF P1,EXW ;DO WE NEED EXTRA STUFF.
ADDI T2,ZERO(P1) ;YES SO ADD IT IN.
ADDI T2,-1(P2) ;ADD BYTE SIZE MINUS ONE.
IDIV T2,P2 ;BUFFFER LENGTH IN WORDS.
WRDCNT: ADDI T2,ONE ;A LITTLE OVERHEAD.
CAIGE T2,^D65 ;MUST HAVE ROOM FOR HEADERS.
MOVEI T2,^D65 ;MAKE ROOM FOR THEM.
HRRZ T1,ZERO(T1) ;GET ADDRESS OF FIRST BUFFER.
SKIPN P3,BUFNUM(SIDE) ;GET NUMBER OF BUFFERS.
MOVEI P3,TWO ;DEFAULT IS TWO.
MOVEI P2,TWO(T2) ;GET TOTAL SIZE OF BUFFERS.
IMULI P2,ZERO(P3) ;COMPUTE TOTAL WORDS NEEDED.
ADDI P2,-1(T1) ;GET THE LAST LOCATION NEEDED.
HRRM P2,.JBFF ;SET IT AS FIRST FREE.
CAMG P2,.JBREL ;DO WE NEED MORE CORE.
GOTO .+3 ;NO IT IS ALRIGHT.
MME P2,.CORE ;GET SOME CORE.
GOTO NOCORE ;CAN'T GET IT.
HRLZI P1,-1(T1) ;GET ADDRESS OF THE TOP OF BUFFERS.
HRRI P1,ZERO(T1) ;GET THE ADDRESS PLUS ONE.
HRRZ P2,.JBFF ;GET THE LAST LOCATION.
SETZM -1(P1) ;CLEAR FIRST WORD.
BLT P1,-1(P2) ;CLEAR OUT JUNK.
SKIPA P1,T1 ;GET POINTER TO FIRST INTO P1.
MAKE2: HRRZI P1,ZERO(P2) ;GET POINTER TO NEXT BUFFER.
MOVEI P2,ZERO(P1) ;GET ADDRESS OF THIS BUFFER.
HRLI P2,ZERO(T2) ;SET THE SIZE OF BUFFER.
ADDI P2,TWO(T2) ;POINT P2 TO NEXT BUFFER.
MOVEM P2,ZERO(P1) ;PLACE IN THIS ONE'S HEADER.
SOJG P3,MAKE2 ;JUMP IF NEED TO DO MORE.
HRRM T1,ZERO(P1) ;LINK LAST TO FIRST.
RETURN ZERO ;AND RETURN.
;HERE TO SET ASIDE A BUFFER AREA FOR VARIABLE LENGTH
;OUTPUT BLOCKS.
GETBUF: SKIPN T1,RECPTR ;BEEN HERE BEFORE.
GOTO GTBF0 ;NO CONTINUE ON.
MOVEM T1,CURPTR ;SAVE AS CURRENT POINTER.
RETURN ZERO ;AND RETURN.
GTBF0: HRRZ T3,MSIZ(OM) ;GET THE BYTES/WORD.
MOVE T2,OFILE+RECSIZ ;GET THE OUTPUT RECORD SIZE.
MOVE T1,STS(OM) ;GET THE STATUS WORD.
ADDI T2,ZERO(T1) ;ADD IN SIZE OF CTRL WORD.
SAVE T3 ;SAVE BYTES/RECORD.
IDIVI T2,ZERO(T3) ;COMPUTE WORDS FOR RECORD.
SKIPE T3 ;SKIP IF REMAINDER.
AOS T2 ;COUNT EXTRA WORD.
UNSAVE T3 ;RESTORE WORDS PER RECORD.
IMULI T2,ZERO(T3) ;BACK TO BYTES.
SKIPE OFILE+BLKFCT ;NO SKIP IF BLOCKING FACTOR.
IMUL T2,OFILE+BLKFCT ;MULTIPLY BY BLOCKING FACTOR.
IF.OFF T1,EXW ;DO WE NEED MORE.
ADDI T2,ZERO(T1) ;YES SO ADD IT IN.
ADDI T2,-1(T3) ;ADD BYTE SIZE MINUS ONE.
IDIV T2,T3 ;T2 IS LENGTH NEEDED IN WORDS.
MOVE T3,.JBFF ;FIRST LOCATION FREE.
MOVEI P4,ONE(T3) ;START OF THE BUFFER.
MOVEI T3,ONE(P4) ;COPY TO ANOTHER AC.
ADD T3,T2 ;END OF THE BUFFER.
HRRM T3,.JBFF ;UPDATE TOP OF CORE.
IORI T3,1777 ;ROUND UP TO K.
CAMG T3,.JBREL ;DO WE HAVE ENOUGH.
GOTO .+3 ;DON'T ASK FOR MORE.
MME T3,.CORE ;GET MORE CORE.
GOTO NOCORE ;NO MORE CORE YOU LOOSE.
HRLZ T2,P4 ;START OF BUFFER.
HRRI T2,ONE(P4) ;START OF BUFFER PLUS ONE.
SETZM ZERO(P4) ;CLEAR FIRST WORD.
MOVE T3,.JBFF ;GET POINTER TO END OF CORE.
BLT T2,-1(T3) ;CLEAR THE BUFFERS.
HLL P4,MPTR(OM) ;GET A BYTE POINTER TO BUFFER.
MOVEM P4,RECPTR ;SET AS THE RECORD POINTER.
MOVEM P4,CURPTR ;ALSO AS CURRENT POINTER.
RETURN ZERO ;BACK TO CALLER.
;HERE TO COMPUTE THE NUMBER OF SECTORS TO WRITE
;IN ORDER TO SATISFY THE BLOCKING FACTOR.
SECTOR: MOVE T3,MOD(SIDE) ;GET THE DEVICE BITS.
IF.OFF T3,DIR,SEC0 ;JUMP IF NOT DSK OR DTA.
HRRZ T3,CHRMOD(SIDE) ;GET THE FILE MODE.
MOVE T2,RECSIZ(SIDE) ;GET THE RECORD SIZE.
MOVE P1,STS(T3) ;MODE STATUS BITS.
ADDI T2,ZERO(P1) ;ADD IN SIZE OF CTRL WORD.
SKIPN BLKFCT(SIDE) ;DO WE HAVE A BLOCKING FACTOR.
GOTO SEC0 ;NO WE DON'T.
IMUL T2,BLKFCT(SIDE) ;MULTIPLY BY BLOCKING FACTOR.
IF.OFF P1,EXW ;DO WE NEED EXTRA STUFF.
ADDI T2,ZERO(P1) ;YES SO ADD IT IN.
HRRZ T3,MSIZ(T3) ;GET BYTES/WORD.
ADDI T2,-1(T3) ;ADD BYTE SIZE MINUS ONE.
IDIV T2,T3 ;WORDS FOR A BLOCK.
MOVE T1,MOD(SIDE) ;DEVICE MODE BITS.
MOVEI T3,200 ;WORDS PER BLOCK ON DISK.
IF.ON T1,DSK ;SKIP IF DISK.
MOVEI T3,177 ;WORDS PER BLOCK ON DTA.
ADDI T2,-1(T3) ;ADD BLOCK SIZE MINUS ONE.
IDIVI T2,ZERO(T3) ;T3 HAS SECTORS FOR BLOCK.
MOVEM T2,SEC(SIDE) ;SAVE IN DATA BLOCK.
RETURN ZERO ;BACK TO CALLER.
SEC0: SETOM SEC(SIDE) ;FOR ALL THOSE BAD GUYS.
RETURN ZERO ;BACK TO CALLER.
;HERE TO DO AN "INBUF" OR "OUTBUF" FOR A DEVICE BUT TO
;MAKE SURE WE HAVE ENOUGH CORE BEFORE WE DO IT.
MONIBF: SKIPA SIDE,[IFILE] ;INDEX TO INPUT STUFF.
MONOBF: MOVEI SIDE,OFILE ;INDEX FOR OUTPUT STUFF.
SKIPN T2,BUFNUM(SIDE) ;GET NUMBER OF BUFFERS.
MOVEI T2,TWO ;DEFAULT TO MAKE.
MOVEI T3,STATUS(SIDE) ;POINTER FOR MME.
MME T3,.SIZ ;GET THE BUFFER SIZE FOR MODE.
MOVEI T3,203 ;DEFAULT IF IT FAILS.
HRRZ T3,T3 ;ZERO LEFT HALF.
IMULI T3,ZERO(T2) ;T3 HAS WORDS NEEDED.
ADD T3,.JBFF ;COMPUTE LAST WORD NEEDED.
IORI T3,1777 ;CONVERT TO A K BOUNDARY.
CAMG T3,.JBREL ;SEE IF ENOUGH ROOM.
GOTO .+3 ;WE HAVE ENOUGH.
MME T3,.CORE ;GET SOME MORE.
GOTO NOCORE ;YOU LOOSE.
MOVE T1,[INBUF IF,ZERO(T2)] ;GET BUFFERS FOR INPUT.
CAIE SIDE,IFILE ;SKIP OF THAT'S WHAT WE WANT.
MOVE T1,[OUTBUF OF,ZERO(T2)] ;ELSE CHANGE TO OUTPUT.
XCT T1 ;GET THE BUFFERS.
RETURN ZERO ;BACK TO CALLER.
;HERE TO MOVE THE ALTER BUFFER INTO THE
;OUTPUT BUFFER.
BUFMOV: HRRZ T3,CURPTR ;GET LAST ADDRESS IN ALTER BUF.
HRRZ T2,RECPTR ;GET ADDRESS OF THE TOP.
CAIG T3,ZERO(T2) ;IS THERE ANYTHING THERE.
RETURN ZERO ;CAN'T MOVE NOTHING.
SKIPE OFILE+BLKFCT ;IS THERE A BLOCKING FACTOR.
IF.ON OF,SPAN,BUF3 ;IF NOT DON'T USE A BLT.
SKIPG OBUF ;HAS BUFFER BEEN USED.
OUTPUT OF,ZERO ;NO USE IT.
SUBI T3,-1(T2) ;GET THE SIZE OF THE SOURCE.
LDB T2,[POINT 17,@OBUF,17] ;GET THE SIZE OF THE TARGET.
SOS T2 ;TO THE RIGHT SIZE.
HRL T1,RECPTR ;SOURCE FOR BLT.
BUF0: CAML T2,T3 ;WILL IT FIT IN ONE SHOT.
GOTO BUF1 ;YES SO DO IT.
SAVE T1 ;SAVE THE XWD FOR BLT.
SAVE T2 ;SAVE THE DESTINATION LENGTH.
SAVE T3 ;SAVE THE SOURCE LENGTH.
GOSUB BUF2 ;MOVE A SEGMENT OF THE BUFFER.
GOSUB EMPTY ;WRITE IT TO THE DEVICE.
UNSAVE T3 ;RESTORE THE SOURCE LENGTH.
UNSAVE T2 ;RESTORE THE DESTINATION LENGTH.
UNSAVE T1 ;RESTORE THE XWD FOR BLT.
HLRZ P3,T1 ;GET THE OLD SOURCE.
ADDI P3,ZERO(T2) ;UPDATE ADDRESS TO POINT TO NEXT SEG.
HRL T1,P3 ;CREATE NEW XWD FOR BLT.
SUB T3,T2 ;ACCOUNT FOR THE NEXT MOVE.
GOTO BUF0 ;DO THE NEXT SEGMENT.
BUF1: MOVE T2,T3 ;COPY WHAT IS LEFT.
BUF2: MOVE T3,T2 ;COPY WORDS TO MOVE.
HRRZ CH,MSIZ(OM) ;GET OUTPUT CHARACTERS/WORD.
IMUL T3,CH ;T3_CHARACTERS TO MOVE.
EXCH T3,OBUF+2 ;T3_BUFCNT OBUF+2_CHR TO MOVE.
SUBM T3,OBUF+2 ;ACCOUNT FOR CHARACTERS MOVED.
HRRZ T3,OBUF+1 ;POINTER TO BUFFER MINUS ONE.
HRRI T1,ONE(T3) ;XWD FOR BLT.
ADDI T3,ZERO(T2) ;COMPUTE LAST WORD OF BUFFER.
HRRM T3,OBUF+1 ;SAVE BYTE POINTER.
BLT T1,ZERO(T3) ;MOVE THE BUFFER.
RETURN ZERO ;BACK TO CALLER.
BUF3: MOVE P3,RECPTR ;GET THE POINTER TO TOP.
BUF4: ILDB CH,P3 ;GET A BYTE.
GOSUB PUT ;TO THE OUTPUT BUFFER.
CAME P3,CURPTR ;SKIP IF ALL DONE.
GOTO BUF4 ;ELSE MOVE THE REST.
RETURN ZERO ;BACK TO CALLER.
;HERE TO GET A CHARACTER FROM THE BUFFER.
GET: TNZ S,BAC,GET2 ;JUMP IF WANT SAME CHARACTER.
SOSGE IBUF+2 ;DECREMENT THE COUNT.
GOTO GET1 ;NEED TO FILL THE BUFFER.
ILDB CH,IBUF+1 ;GET A BYTE.
MOVEM CH,TCH ;SAVE IN CASE WE WANT IT LATTER.
RETURN ONE ;BACK TO SENDER.
GET1: GOSUB FILL ;READ THE NEXT BLOCK.
RETURN ZERO ;END OF FILE RETURN.
GOTO GET ;GET THE NEXT WORD.
GET2: MOVE CH,TCH ;GET LAST CHARACTER BACK.
RETURN ONE ;TAKE IT TO HIM.
FILL: AOS ISEC ;COUNT THE BLOCK TO READ.
DEVOP IN,IF,ZERO ;FILE UP THE BUFFERS.
GOTO BCLCHK ;SEE IF EOF -- WHAT THING THIS IS.
GETSTS IF,T1 ;GET DEVICE STATUS.
IF.OFF T1,E.ERR,CHKEOF ;JUMP IF EOF.
IF.ON S,NI.ERR,RET1 ;NO ERRORS FOR LABELS OR SKIPPING.
IF.ON T1,E.PAR,GETPAR ;PARITY ERROR FOUND.
IF.ON S,NI.LST,RET1 ;LIST IGNORES OTHER ERRORS.
GOTO LKIERR ;JUMP REAL ERROR.
GETPAR: IF.OFF IF,NOERROR,IPERR ;JUMP IF WANTS SEE IT.
AOS INPERR ;COUNT THE ERROR.
RETURN ONE ;BACK TO SENDER.
CHKEOF: IF.ON T1,E.EOF,INPEND ;JUMP IF EOF.
IF.OFF S,NI.LST ;RETURN IF NO ERROR.
IF.ON T1,E.EOT ;SKIP IF END OF TAPE.
RETURN ONE ;ELSE GIVE GOOD RETURN.
RETURN ZERO ;OTHERWISE GIVE EOF RETURN.
INPABT: SKIPA T1,[DRIVE IF,.SKF] ;SKIP FOR LEGAL LABEL AT EOF.
INPAB0: SKIPA T1,[DRIVE IF,.BSR] ;BACK UP FOR ERROR ON LABEL.
SKIPE IFILE+LABEL ;DON'T DO ANYTHING FOR NO LABELS.
XCT T1 ;DO THE FUNCTION.
DRIVE IF,.WAT ;WAIT FOR IT.
OFF S,HDR!NI.ERR!TERM ;CLEAR BITS SET FOR HEADER.
RETURN ZERO ;GIVE EOF RETURN.
;HERE TO WRITE ONE CHARACTER INTO THE BUFFER.
PUT: SOSGE OBUF+2 ;DECREMENT THE COUNT.
GOTO WRITE ;EMPTY THE BUFFER.
IDPB CH,OBUF+1 ;SAVE THE WORD.
RETURN ZERO ;BACK TO SENDER.
WRITE: GOSUB EMPTY ;WRITE IT OUT.
GOTO PUT ;CONTINUE LOOP.
EMPTY: AOS OSEC ;COUNT OUTPUT SECTOR.
DEVOP OUT,OF,ZERO ;WRITE THE BUFFER.
RETURN ZERO ;NORMAL RETURN.
;HERE ON AN ERROR FROM THE LAST OUTPUT.
OUTERR: GETSTS OF,T1 ;GET DEVICE STATUS BITS.
IF.OFF OF,MTA,NOTMTA ;JUMP IF NOT MAG-TAPE.
IF.OFF T1,E.IOB ;***BUG IF I/O BLOCK TO LARGE.
GOSUB ABORT ;PROGRAM BUG *****
IF.ON T1,E.EOT,OUTEND ;IF END OF TAPE GET NEW REEL.
IF.OFF T1,E.PAR,LOKERR ;JUMP IF NOT PARITY ERROR.
IF.OFF OF,NOERROR,OPERR ;TYPE MESSAGE IF HE WANTS IT.
AOS OTPERR ;COUNT THE ERROR.
RETURN ZERO ;ELSE GIVE NORMAL RETURN.
;HERE IF OTHER THEN MAG-TAPE.
NOTMTA: IF.OFF T1,E.IOB,NOTMT1 ;JUMP IF STILL HAVE ROOM.
IF.ON IF,DTA,TAPFUL ;JUMP IF DECTAPE IS FULL.
GOTO NOROOM ;ELSE NO QUOTA.
NOTMT1: IF.OFF T1,E.PAR,LOKERR ;JUMP IF NOT PARITY ERROR.
IF.OFF OF,NOERROR,PARERR ;TYPE MESSAGE IF HE WANTS IT.
RETURN ZERO ;YES WE GIVE NORMAL RETURN.
;HERE FROM INPUT ROUTINE TO GET NEXT REEL.
INPEND: ENABLE TTY ;CLEAR CONTROL O.
CLOSE IF,ZERO ;DO THIS TO RESET EOF FLAG.
TNZ S,NI.ERR,RET0 ;RETURN IF NOT LEGAL EOF.
GETSTS IF,T1 ;SEE IF ERROR.
IF.OFF T1,E.ERR ;TEST ERROR BITS.
PRINT (% Error during eof label check.)
IF.OFF IF,MTA,RET0 ;RETURN IF NOT MAG-TAPE.
ON S,HDR ;SET HEADER BIT.
GOSUB STORE ;SAVE THE AC'S.
GOSUB GETLAB ;READ A LABEL BLOCK.
GOTO INPAB0 ;CAN'T BE A LABEL IF EOF.
BRANCH INPLAB,<INPAB0,INPABT,INPABT> ;SEE IF WE HAVE A LABEL.
IF.OFF S,L.EOV,INPABT ;JUMP IF NOT EOV.
OFF S,TERM ;CLEAR HEADER BIT.
GOSUB STAT ;PROGRAM GOODNESS.
SETZM IBCNT ;CLEAR BLOCKS READ.
SETZM IRCNT ;CLEAR RECORDS READ.
MOVE T1,IFILE+VOL ;GET CURRENT VOLUME NUMBER.
GOSUB BMPVOL ;INCREMENT THE NUMBER.
MOVEM T1,IFILE+VOL ;REPLACE IT.
TAINP: ON S,NO.PRI ;SET FORCE HUNG DEVICE BIT.
DRIVE IF,.UNL ;UNLOAD DEVICE.
PRINT (% Mount next input tape on same drive.)
RELEASE IF,ZERO ;RELEASE THE DEVICE.
GOSUB TRPSET ;RESET TRAP BLOCK.
OPEN IF,IFILE ;GET THE DEVICE BACK.
JSP T1,NODEV ;CAN'T HAVE IT....
HLRZ T1,MSIZ(IM) ;GET THE BYTE SIZE.
DPB T1,[POINT 6,IBUF+1,11] ;SET THE BYTE SIZE.
DRIVE IF,.WAT ;MAKE SURE IT IS READY.
DRIVE IF,.REW ;REWIND THE DEVICE.
DRIVE IF,.WAT ;DRIVE DEVICE TO COMPLETION.
OFF S,NO.PRI ;PRINT HUNG MESSAGE NOW.
MOVE T1,I.JBFF ;GET SAVED TOP OF CORE.
EXCH T1,.JBFF ;PUT IN PLACE FOR EXEC.
SAVE T1 ;SAVE CURRENT VALUE.
INBUF IF,TWO ;GET SOME BUFFERS.
MOVEI T1,IBUF ;POINTER TO HEADERS.
MOVEI SIDE,IFILE ;POINTER TO PARAMETERS.
GOSUB MAKE ;MAKE NEW BUFFERS.
UNSAVE .JBFF ;PUT BACK TOP OF CORE.
SAVE [TAINP-1] ;PLACE A RETURN ON THE STACK.
GOSUB GETLAB ;GET A LABEL BLOCK.
GOTO BADEOF ;BAD FILE MARK FOUND.
BRANCH INPLAB,<NOLAB,NOMAT,BADVOL> ;BRANCH ON LABEL FOUND.
IF.OFF S,L.HDR,NOLAB ;JUMP IF NOT THE RIGHT TYPE.
OFF S,NO.PRI!HDR ;CLEAR INDICATOR BITS.
SUB PDP,[XWD ONE,ONE] ;FIX THE STACK.
RETURN ONE ;GO FILL IT UP.
;HERE FROM OUTPUT ROUTINE ON END OF TAPE TO GET A NEW ONE.
OUTEND: TNO S,NO.ERR,RET0 ;RETURN IF IGNORING ERRORS.
OFF T1,E.ERR!E.EOT ;CLEAR ERROR BITS.
SETSTS OF,ZERO(T1) ;RESET STATUS FOR EXEC.
ENABLE TTY ;CLEAR CONTROL O.
CLOSE OF,ZERO ;WRITE END OF FILE MARK.
GETSTS OF,T1 ;GET STATUS ON THAT.
TEZ T1,E.ERR ;SKIP IF NO ERROR.
PRINT (? Error during close of volume.)
SETSTS OF,ZERO(T1) ;RESET STATUS.
ON S,FIN!TERM!HDR ;LIGHT SOME BITS SO OTHERS CAN SEE.
GOSUB STORE ;SAVE THE AC'S.
GOSUB OUTLAB ;WRITE THE TRAILER LABEL.
OFF S,FIN!TERM ;CLEAR BITS SO OTHERS CAN'T SEE.
GOSUB STAT ;GOOD THINGS COME FROM THIS.
SETZM OBCNT ;CLEAR NUMBER OF BLOCKS WRITTEN.
SETZM ORCNT ;CLEAR RECORD COUNT.
MOVE T1,OFILE+VOL ;GET THE VOLUME NUMBER.
GOSUB BMPVOL ;INCREMENT VOLUME NUMBER.
MOVEM T1,OFILE+VOL ;REPLACE IT.
TAOUT: ON S,NO.PRI ;DON'T PRINT HUNG MESSAGE NOW.
DRIVE OF,.UNL ;UNLOAD TAPE.
PRINT (% Mount new output tape on same drive.)
RELEASE OF,ZERO ;RELEASE OUTPUT CHANNEL.
GOSUB TRPSET ;RESET TRAP BLOCK.
OPEN OF,OFILE ;OPEN IT BACK UP.
JSP T1,NODEV ;COULDN'T GET IT.
HLRZ T1,MSIZ(OM) ;GET THE BYTE SIZE.
DPB T1,[POINT 6,OBUF+1,11] ;SET THE SIZE RIGHT.
DRIVE OF,.WAT ;MAKE SURE IT IS READY.
DRIVE OF,.REW ;REWIND IT.
DRIVE OF,.WAT ;WAIT FOR COMPLETION.
OFF S,NO.PRI ;CLEAR HUNG DEVICE BIT.
MOVE T1,O.JBFF ;GET OUTPUT TOP OF CORE.
EXCH T1,.JBFF ;RESET IT.
SAVE T1 ;SAVE IT ON STACK.
OUTBUF OF,TWO ;CREATE HEADERS.
MOVEI T1,OBUF ;GET POINTER TO BUFFER.
MOVEI SIDE,OFILE ;POINTER TO PARAMETERS.
GOSUB MAKE ;MAKE NEW BUFFERS.
UNSAVE .JBFF ;RESTORE TOP OF CORE.
GOSUB OUTLAB ;WRITE NEW LABEL.
SKIPA ;SKIP INTO GOODNESS.
GOTO TAOUT ;GIVE HIM ANOTHER CHANCE.
OFF S,NO.PRI!NO.ERR!HDR ;IF DEVICE HANGS NOW IT REALY IS.
RETURN ZERO ;RETURN.
;HERE TO FILL THE BUFFER RING WITH A BUFFER THAT SHOULD
;CONTAIN A LABEL OF SOME KIND.
GETLAB: GETSTS IF,T1 ;GET THE DEVICE STATUS.
ON T1,SYNC ;SYNC WITH THE DEVICE.
SETSTS IF,ZERO(T1) ;RESET THE STATUS.
IF.OFF IF,IND ;SKIP IF OUR MODE.
DRIVE IF,.IND ;ELSE SET THEIRS.
ON S,NI.ERR ;TURN ON EOF RETURN FLAG.
GOSUB FILL ;FILL THE BUFFER WITH A LABEL.
SOS ZERO(PDP) ;DECREMENT TO GIVE ERROR RETURN.
AOS ZERO(PDP) ;INCREMENT FOR NORMAL RETURN.
OFF S,NI.ERR ;TURN OFF EOF RETURN FLAG.
GETSTS IF,T1 ;GET DEVICE STATUS.
OFF S,SYNC ;TURN OFF SYNC BIT.
SETSTS IF,ZERO(T1) ;RESET STATUS.
SETOM IBUF+2 ;FLAG BUFFER WILL BE USED.
RETURN ZERO ;TO CALLER.
;HERE TO CONVERT THE LABEL JUST READ INTO THE BUFFER
;RING INTO SIXBIT AND TO STORE THAT BUFFER IN "INPBUF" FOR
;FURTHER PROCESSING.
CVTLAB: MOVSI P3,(POINT 7,ZERO) ;POINTER FOR IMAGE MODE.
CAIE T1,IMGMOD ;SKIP IF IMAGE MODE.
MOVE P3,MPTR(T1) ;GET A BYTE POINTER.
MOVE T2,OM ;GET THE OUTPUT INDEX.
GOSUB GETTAB ;GET THE RIGHT TABLES.
MOVE P1,[POINT 6,INPBUF] ;POINTER TO BUFFER.
MOVNI P2,^D80 ;MAX CHARACTERS IN ANY LABEL.
MOVE T1,IBUF ;GET A POINTER TO CURRENT BUFFER.
ADDI P3,TWO(T1) ;POINT P3 TO BUFFER.
RED0: ILDB CH,P3 ;GET A BYTE.
HLRZ CH,TAB1(CH) ;CONVERT IT TO ASCII.
SUBI CH," " ;NOW TO SIXBIT.
IDPB CH,P1 ;SAVE IT IN BUFFER.
AOJN P2,RED0 ;CONTINUE LOOP.
REVIVE: MOVE T1,IM ;GET THE TRUE INPUT MODE.
MOVE T2,OM ;GET THE TRUE OUTPUT MODE.
GOTO GETTAB ;GET THE RIGHT TABLES.
;HERE TO READ THE LABEL FROM THE OUTPUT DEVICE IF THE
;DEVICE IS A MAG-TAPE AND TO CONVERT IT TO SIXBIT
;AND STORE IT IN OUTBUF FOR FURTHER PROCESSING.
REDOUT: MOVE P1,[XWD OIBUF,OIBUF+1] ;BLT POINTER.
SETZM OIBUF ;CLEAR FIRST WORD.
BLT P1,BUFF+^D23 ;CLEAR CORE.
MOVE P1,[XWD 400000,BUFF+1] ;SET UP BUFFER ON OUTPUT DEVICE.
MOVEM P1,OIBUF ;INTO BUFFER HEADER.
MOVSI P1,(POINT 7,ZERO) ;POINTER IF IMAGE MODE.
CAIE T2,IMGMOD ;SKIP IF IMAGE MODE.
HLLZ P1,MPTR(T2) ;GET THE OUTPUT POINTER.
MOVEM P1,OIBUF+1 ;SET THE POINTER UP.
MOVE T1,IM ;GET THE INPUT MODE.
GOSUB GETTAB ;GET THE RIGHT TABLES.
MOVE P1,[XWD ^D21,BUFF+1] ;LINK WORD.
MOVEM P1,BUFF+1 ;SET IT IN BUFFER HEADER.
MOVE P1,[POINT 6,OUTBUF] ;POINTER TO BUFFER.
MOVNI P2,^D80 ;MAX CHARACTERS IN LABEL.
DEVOP IN,OF,ZERO ;READ THE LABEL.
GOTO RED0B ;START THE COPY.
GETSTS OF,T1 ;A LITTLE ERROR.
IF.ON T1,E.EOF,RET0 ;JUMP IF EOF.
IF.ON T1,E.LOK!E.HAD,LOKERR ;JUMP IF HARD ERROR.
IF.OFF T1,E.PAR,RED0B ;JUMP IF NOT PARITY ERROR.
AOS OTPERR ;COUNT AN OUTPUT ERROR.
IF.ON OF,NOERROR,RED0B ;JUMP IF IGNORING.
UNSAVE T1 ;CLEAN UP THE STACK.
GOTO OPERR ;SAY THERE IS AN ERROR.
RED0B: ILDB CH,OIBUF+1 ;GET A CHARACTER.
HLRZ CH,TAB2(CH) ;CONVERT IT TO ASCII.
SUBI CH," " ;CONVERT IT TO SIXBIT.
IDPB CH,P1 ;STORE THE CHARACTER.
AOJN P2,RED0B ;JUMP IF NOT DONE.
AOS ZERO(PDP) ;SKIP RETURN FOR A JOB WELL DONE.
GOTO REVIVE ;GET THE RIGHT TABLES BACK.
;HERE TO WRITE OUT THE LABEL IN OUTBUF TO
;MAG-TAPE. WE DO CONVERSION HERE FROM SIXBIT TO WHAT
;EVER CODE THE TAPE IS TO BE WRITTEN IN.
WRILAB: SKIPG OBUF ;HAS THE BUFFER BEEN USED.
OUTPUT OF,ZERO ;NO SO USE IT.
MOVEI P1,7 ;BYTE SIZE IF IMAGE MODE.
CAIE T2,IMGMOD ;SKIP IF IMAGE MODE.
HLRZ P1,MSIZ(T2) ;GET OUTPUT BYTE POINTER.
DPB P1,[POINT 6,OBUF+1,11] ;SAVE THE SIZE.
MOVE T1,IM ;INPUT INDEX.
GOSUB GETTAB ;READ THE RIGHT TABLES.
SAVE OBUF+2 ;SAVE THE COUNTER.
HRRZ T2,MSIZ(T1) ;GET THE BYTES PER WORD.
LDB T1,[POINT 17,@OBUF,17] ;GET THE BUFFER SIZE.
MOVEI T1,-1(T1) ;JUST THE DATA WORDS.
IMUL T1,T2 ;GET THE COUNTER.
MOVEM T1,OBUF+2 ;SET COUNTER FOR BUFFER.
MOVE P1,[POINT 6,OUTBUF] ;POINTER TO STORAGE.
MOVNI P2,^D80 ;MAX. CHARACTERS IN LABEL.
WRITE0: ILDB CH,P1 ;GET A CHARACTER.
ADDI CH," " ;CONVERT IT TO ASCII.
HRRZ CH,TAB2(CH) ;TO THE OUTPUT SET.
GOSUB PUT ;INTO OUTPUT BUFFER.
AOJN P2,WRITE0 ;CONTINUE FOR ALL.
GOSUB EMPTY ;WRITE THE LABEL.
HLRZ P1,MSIZ(OM) ;GET TRUE OUTPUT POINTER.
DPB P1,[POINT 6,OBUF+1,11] ;RESET IT.
UNSAVE OBUF+2 ;RESTORE THE COUNTER.
GOTO REVIVE ;GET THE RIGHT TABLES BACK.
SUBTTL *** ERROR MESSAGES ***
NOUSE: HRRZ T2,CCLFLG ;POINTER TO DEVICE BLOCK.
GOTO QUES ;TYPE ERROR MESSAGE.
NOOUSE: SKIPA T2,[OFILE] ;GET DATA INDEX.
NOIUSE: MOVEI T2,IFILE ;GET DATA INDEX.
QUES: EME .STR,[ASCIZ "? "] ;FOR BATCH.
GOSUB NAMIT ;TELL HIM THE DEVICE IN ERR.
EME .STR,[ASCIZ " can't be used."]
GOTO CLEAR1 ;ANOTHER CHANCE FOR HIM.
NODEV: XCT QUES ;FOR BATCH.
HRRZI T2,@-2(T1) ;GET POINTER TO DEVICE NAME.
GOSUB NAMIT ;PRINT ITS NAME.
EME .STR,[ASCIZ " is not available."]
GOTO CLEAR1 ;CLEAR THE FLAGS AND EXIT.
NOEXT: XCT QUES ;FOR BATCH.
HRRZI T1,@-4(T1) ;GET POINTER TO DEVICE NAME.
MOVEI T2,-DEVICE(T1) ;GET POINTER TO DATA AREA.
GOSUB NAMIT ;TELL ME WHAT IT IS.
EME .STR,[ASCIZ " doesn't exist."]
GOTO CLEAR1 ;BYE..BYE..
NAMIT: EME .STR,[ASCIZ /Device "/] ;FOR CLEARNESS.
MOVE T1,CHAN(T2) ;GET THE CHANNEL NUMBER.
MME T1,.NAM ;GET THE REAL NAME.
MOVE T1,DEVICE(T2) ;GET THE NAME WE HAVE.
GOSUB PUTSIX ;PRINT IT.
EME .STR,[ASCIZ /"/] ;DELIMIT DEVICE NAME.
RETURN ZERO ;BACK TO SENDER.
NOOUT: XCT QUES ;FOR BATCH.
MOVEI T2,OFILE ;GET THE DATA INDEX.
GOSUB NAMIT ;TELL HIM ITS NAME.
GOTO NOOUT1 ;TELL HIM NO OUTPUT.
NOINP: XCT QUES ;FOR BATCH.
MOVEI T2,IFILE ;GET THE DATA INDEX.
GOSUB NAMIT ;PRINT ITS NAME.
GOTO NOINP1 ;TELL HIM NO INPUT.
OPERR: EME .STR,[ASCIZ "? Output"] ;SAY IT IS OUTPUT ERROR.
GOTO PARERR ;THEN SAY THE REST.
IPERR: EME .STR,[ASCIZ "? Input"] ;SAY INPUT ERROR.
GOTO PARERR ;THEN TELL THE REST.
HADERR: EME .STR,[ASCIZ "? Unrecoverable i/o error status "]
MOVNI T3,^D6 ;NUMBER OF DIGITS TO PLACE.
LSHC T1,-^D18 ;SHIFT STATUS INTO T2.
JSP P4,OCTOUT+1 ;PRINT IT.
CLEAR1: SETZM S ;CLEAR S.
GOTO ERREXT ;AND RESTART.
;HERE TO TELL WHY WE COULDN'T CREATE OR READ A FILE.
NOOPN: MOVEI SIDE,OFILE ;GET THE INDEX.
HRRZ T1,OFILE+EXT ;GET THE ERROR INDEX.
JUMPN T1,NOFILE+1 ;JUMP IF O.K.
MOVEI T1,-TWO ;SET MESSAGE RIGHT.
HRRM T1,OFILE+EXT ;SAVE IT.
SKIPA ;SKIP INTO GOODNESS.
NOFILE: MOVEI SIDE,IFILE ;GET THE INDEX TO DATA.
UNSAVE PPN(SIDE) ;RESTORE PPN WORD.
EME .STR,[ASCIZ "? "] ;GIVE ERROR SIGNAL.
GOSUB TYPE ;TYPE THE MESSAGE.
SETZM S ;CLEAR ERROR BITS.
GOTO ERR2 ;AND EXIT.
;HERE IF A FILE CAN'T BE ACCESSED.
MAYBE: IF.OFF IF,DSK ;SKIP IF NOT DISK.
IF.OFF IF,WILD,NOFILE ;IF NOT WILD JUMP.
UNSAVE IFILE+PPN ;RESTORE THE PPN.
MOVE P4,IFILE+MOD ;GET THE MOD BITS.
OFF P4,WILD ;TURN OFF WILD BITS.
MOVEI SIDE,IFILE ;INDEX TO DATA BASE.
WARN: EME .STR,[ASCIZ "% "] ;FLASH A WARNING.
GOSUB TYPEIT ;TYPE THE ERROR.
IF.ON IF,DSK,NXTDSK ;JUMP IF DSK.
GOTO NXTDTA ;ELSE MUST BE DTA.
;HERE TO TYPE DEV:FILENAME.EXT[P,PN] ERROR MESSAGE.
TYPE: MOVE P4,MOD(SIDE) ;GET THE MOD BITS.
TYPEIT: EME .STR,[ASCIZ /File "/] ;A LITTLE IDENTIFIER.
TYPE0: GOSUB TYPNAM ;TYPE DEV:FILENAME.EXT[P,PN].
TEL0: EME .STR,[ASCIZ /"/] ;FINISH IT OFF.
HRRE P1,EXT(SIDE) ;GET THE ERROR CODE.
CAILE P1,ERRCNT ;SEE IF IN RANGE.
MOVEI P1,ERRCNT ;SET OUR OWN.
MOVE P1,ERRMES(P1) ;GET POINTER TO STRING.
EME .STR,ZERO(P1) ;TELL WHY.
GOTO CRLF ;SKIP A LINE AND EXIT.
;HERE WHEN WE CAN'T OPEN THE CCL FILE.
NOCCL: MOVE P4,MOD(SIDE) ;GET THE MOD BITS.
IF.ON P4,WILD,NOCCL0 ;JUMP IF WILD BITS WERE ON.
SETZM S ;CLEAR STATUS REGISTER.
HRRZ SIDE,CCLFLG ;GET THE POINTER TO FILE NAME.
XCT QUES ;FOR BATCH.
GOSUB TYPEIT ;PRINT MESSAGE.
JSP T1,CCLBAK ;BACK UP POINTER.
NOP ERR2 ;WHERE TO GO.
NOCCL0: MOVEI P1,[ASCIZ "? ILLEGAL CCL FILE NAME."]
GOTO FSTEOL ;TYPE THE MESAGE.
;HERE TO TYPE DEV:NAME.EXT[P,PN]
TYPNAM: SKIPN DEVICE(SIDE) ;IS THERE A DEVICE.
GOTO TYPNM0 ;SKIP DEVICE THEN.
MOVE T1,CHAN(SIDE) ;GET THE CHANNEL NUMBER.
MME T1,.NAM ;GET ITS REAL NAME.
MOVE T1,DEVICE(SIDE) ;MME FAILED.
IF.OFF P4,WDEV ;SKIP IF TRUE DEVICE.
MOVSI T1,'* ' ;FLAG WILD DEVICE.
GOSUB PUTSIX ;PRINT ITS NAME.
EME .CH,[EXP ":"] ;TO SIGNIFY DEVICE.
TYPNM0: MOVE P1,NAME(SIDE) ;GET THE FILE NAME.
MOVE P2,EXT(SIDE) ;GET THE EXTENSION.
SKIPN T1,DEVICE(SIDE) ;GET THE DEVICE.
MOVSI T1,'DSK' ;NONE USE DISK.
MME T1,.DEV ;GET THE CHARACTERISTICS.
IF.ON T1,DSK ;SKIP IF DSK.
SETZM PPN(SIDE) ;CLEAR PPN WORD.
IF.OFF P4,WNAME ;SKIP IF TRUE NAME.
MOVSI P1,'* ' ;ELSE USE A WILD CHARACTER.
IF.OFF P4,WEXT ;SKIP IF TRUE EXTENSION.
MOVSI P2,'* ' ;SET WILD CHARACTER.
GOSUB PUTNAM ;PRINT THE NAME.
HLRZ P1,PPN(SIDE) ;GET THE PROJECT NUMBER.
IF.ON P4,WP!WPN ;SKIP IF WILD PPN.
JUMPE P1,RET0 ;JUMP IF NONE.
EME .CH,[EXP "["] ;START OF PPN WORD.
IF.OFF P4,WP ;SKIP IF NOT WILD.
GOSUB TYPHAL ;TYPE HALF OF IT.
GOSUB PUTOCT ;TYPE THIS HALF.
EME .CH,[EXP ","] ;SEPARATE THEM.
HRRZ P1,PPN(SIDE) ;GET THE PROGRAM NUMBER.
IF.OFF P4,WPN ;SKIP IF NOT WILD.
GOSUB TYPHAL ;TYPE THE OTHER HALF.
GOSUB PUTOCT ;PRINT IT.
EME .CH,[EXP "]"] ;FINISH THE PPN WORD.
RETURN ZERO ;RETURN TO CALLER.
TYPHAL: MOVSI T1,'* ' ;FLAG WILD.
AOS ZERO(PDP) ;FOR SKIP RETURN.
GOTO PUTSIX ;FLADH A STAR.
[ASCIZ " is an illegal file name."] ; (-2)
[ASCIZ " is non-existent."] ; (-1)
ERRMES: [ASCIZ " is not saved."] ; (0)
[ASCIZ " has no ufd."] ; (1)
[ASCIZ " protection failure."] ; (2)
[ASCIZ " is being modified."] ; (3)
[ASCIZ " unknown executive error return."] ; (4)
[ASCIZ " unknown executive error return."] ; (5)
[ASCIZ " has a rib error."] ; (6)
[ASCIZ " unknown executive error return."] ; (7)
[ASCIZ " unknown executive error return."] ; (10)
[ASCIZ " unknown executive error return."] ; (11)
[ASCIZ " unknown executive error return."] ; (12)
[ASCIZ " unknown executive error return."] ; (13)
[ASCIZ " no room on file structure."] ; (14)
[ASCIZ " structure is write-locked."] ; (15)
[ASCIZ " executive table space exceeded."] ; (16)
[ASCIZ " unknown executive error return."] ; (17)
[ASCIZ " unknown executive error return."] ; (20)
[ASCIZ " can't supersede an existing directory."] ; (21)
[ASCIZ " unknown executive error return."] ; (22)
[ASCIZ " is missing an sfd in its path."] ; (23)
[ASCIZ " has no search list."] ; (24)
[ASCIZ " will nest sfd's too deeply."] ; (25)
[ASCIZ " has no writable file structure."] ; (26)
[ASCIZ " unknown executive error return."] ; (27)
ERRCNT==.-ERRMES-1
NOHELP: EME .STR,[ASCIZ /% Can't provide help for "/]
MOVE T1,HFILE ;GET THE NAME WANTED.
GOSUB PUTSIX ;PRINT IT.
GOTO BACK ;EXIT.
BADFOM: SKIPA P1,[[ASCIZ "? Record size non-zero with carriage-returns in file."]]
NOCOM: MOVEI P1,[ASCIZ "? No command to perform."]
GOTO CLEAR
BADCHR: TNO S,BAD,RET0 ;ONLY ONE BAD CHARACTER PER LINE.
SKIPA P1,[[ASCIZ "? Illegal command syntax character."]]
NOMAKE: MOVEI P1,[ASCIZ "? Can't create tables."]
GOTO FSTEOL
NOTAB: RELEASE DF,ZERO
SETZM DFFLG
SKIPA P1,[[ASCIZ "? Can't find conversion tables."]]
NOIREC: MOVEI P1,[ASCIZ "? Need record switch for input specifications."]
GOTO CLEAR
COMERR: SKIPA P1,[[ASCIZ "? Can't understand command."]]
PPNERR: MOVEI P1,[ASCIZ "? Incorrect project-program number."]
GOTO FSTEOL
IMPSW: SKIPA P1,[[ASCIZ "? Illegal switch in command string."]]
SWERR: MOVEI P1,[ASCIZ "? Switch appears twice in same specifications."]
GOTO FSTEOL
FOMERR: MOVEI P1,[ASCIZ "? Bad modifier for switch."]
GOTO FSTEOL
NOOUT1: SKIPA P1,[[ASCIZ " can't do output."]]
NOINP1: MOVEI P1,[ASCIZ " can't do input."]
GOTO CLEAR
DDTERR: SKIPA P1,[[ASCIZ "? Debugger is not loaded."]]
LOCK: MOVEI P1,[ASCIZ "? Output device is write locked."]
GOTO CLEAR
NOTLAB: SKIPA P1,[[ASCIZ "? Format error in label on output device."]]
BLKERR: MOVEI P1,[ASCIZ "? Blocking factor or record size incorrectly specified."]
GOTO ERR1
NOOREC: SKIPA P1,[[ASCIZ "? Need record switch for output specifications."]]
NOCORE: MOVEI P1,[ASCIZ "? Insufficient memory for operation."]
GOTO CLEAR
NOROOM: SKIPA P1,[[ASCIZ "? Quota, rib, or file structure capacity exceeded."]]
TAPFUL: MOVEI P1,[ASCIZ "? Dectape is full."]
GOTO CLEAR
BADMOD: SKIPA P1,[[ASCIZ "? Octal mode can't be used with list."]]
MOD0ER: MOVEI P1,[ASCIZ "? Image or octal output is required with image input."]
GOTO CLEAR
NOOCT: SKIPA P1,[[ASCIZ "? Octal is an output only mode."]]
IOERR: MOVEI P1,[ASCIZ "? Input device i/o error."]
GOTO CLEAR
SAMDEV: SKIPA P1,[[ASCIZ "? Can't use same mag-tape for input and output."]]
PARERR: MOVEI P1,[ASCIZ " Checksum or parity error encountered."]
CLEAR: SETZM S
GOTO ERR1
NOWLD: MOVNI T1,ONE ;INDEX FOR MESSAGE.
HRRM T1,IFILE+EXT ;SAVE THE INDEX.
SAVE IFILE+PPN ;SO ERROR ROUTINE WORKS RIGHT.
GOTO NOFILE ;TELL HIM IT DOESN'T EXIST.
CANLST: XCT QUES ;FOR BATCH.
MOVEI T2,IFILE ;POINTER TO THINGS.
GOSUB NAMIT ;NAME THE DEVICE.
EME .STR,[ASCIZ " has no directory."]
GOTO CLEAR1 ;EXIT.
NOLAB: GOSUB QW ;FLASH A ? OR %.
MOVEI P1,[ASCIZ "Format error in label on input device."]
GOTO ERR1
BADEOF: IF.ON IF,WNAME!WEXT!SCAN,RET0 ;RETURN IF WILD OR SCANNING.
BADTM: MOVEI P1,[ASCIZ "? Unexpected file mark encountered while reading label."]
GOTO ERR1 ;TELL OF THE ERROR.
BADVOL: IF.OFF IF,WNAME!WEXT!SCAN
GOTO ZERO(T1) ;RETURN FOR WILD CARDS.
GOSUB QW ;FLASH A ? OR %.
EME .STR,[ASCIZ /Volume number is "/]
MOVE T1,LABVOL ;GET THE NUMBER IN ERROR.
GOSUB PUTSIX ;PRINT NUMBER WE FOUND.
EME .STR,[ASCIZ /" should be "/]
MOVE T1,IFILE+VOL ;GET CORRECT VOLUME NUMBER.
GOSUB PUTSIX ;PRINT IT.
GOTO BACK ;EXIT...
NOMAT: GOSUB QW ;FLASH A ? OF %.
EME .STR,[ASCIZ /Label-id of "/]
MOVE P1,LABNAM ;GET FIRST HALF OF ID.
MOVE P2,LABNAM+1 ;GET THE SECOND HALF.
GOSUB PUTNAM ;TYPE THE ID.
EME .STR,[ASCIZ /" doesn't match file-id of "/]
MOVE P1,IFILE+NAME ;COPY FILE NAME.
MOVE P2,IFILE+EXT ;COPY EXTENSION.
GOSUB PUTNAM ;PRINT THE NAME.
BACK: MOVEI P1,[ASCIZ /"./] ;FORMAT.
GOTO ERR1 ;START AGAIN.
;HERE TO SKIP A FILE.
SKPFIL: ON IF,NOERROR ;NO ERRORS WHILE SKIPPING.
ON S,NI.ERR ;GET A RETURN ON ANY EOF.
SKP0: GOSUB CHKOPR ;CHECK FOR COMMAND.
GOSUB FILL ;DON'T DO A DRIVE BECAUSE TAPE
SKIPA ;COULD HAVE TAPE MARKS WRITTEN
GOTO SKP0 ;IN THE SAME PARITY AS THE TAPE.
MOVE IF,IFILE+MOD ;RESET THE MODE BITS.
OFF S,NI.ERR ;NORMAL RETURNS ON EOF.
RETURN ZERO ;RETURN TO CALLER.
;HERE TO TYPE A QUESTION MARK OR A PERCENT SIGN.
QW: MOVEI T1,QUES ;IF FATAL.
IF.OFF S,HDR ;SKIP IF HEADER LABEL.
MOVEI T1,WARN ;IF NOT FATAL.
XCT ZERO(T1) ;PRINT SOMETHING.
RETURN ZERO ;RETURN.
TOODEP: MOVEI P1,[ASCIZ "% Command files nested too deeply -- command ignored."]
;HERE ON AN ERROR MESSAGE WHEN PROCESSING A COMMAND.
FSTEOL: ON S,BAD ;SET ERROR BITS.
SAVE SPCCNT ;SAVE THE SPACE COUNT.
IF.ON S,EOL ;ARE WE THERE ALREADY.
GOSUB GETONE ;FIND END OF LINE.
IF.ON S,EOL ;IS IT END OF LINE.
GOTO .-2 ;NO TRY AGAIN.
SETZM S ;CLEAR SO WE DON'T GET CONFUSED.
UNSAVE T1 ;GET THE COUNT BACK.
SOJLE T1,ERR0 ;JUMP IF AT CORRECT POSTION.
EME .CH,[EXP " "] ;TAB TO POSITION.
GOTO .-2 ;CONTINUE TO TAB.
ERR0: EME .STR,[BYTE (7)"^",15,12,0];POINT TO ERROR.
ERR1: ENABLE TTY ;LET HIM SEE ERRORS.
EME .STR,ZERO(P1) ;SEND MESSAGE.
ERREXT: GOSUB CRLF ;SKIP A LINE.
ERR2: SKIPN DIAFLG ;SKIP IF IN DIALOG MODE.
GOTO ERR3 ;NOT IN DIALOG MODE.
MOVE PDP,[IOWD PDPSIZ+1,STACK+1];SAVE TOP ELEMEMT.
XCT CRLF ;SKIP A LINE.
GOTO @DIAFLG ;GIVE ERROR RETUR.
ERR3: IF.OFF S,HDR,NODEL ;ARE WE CHECKING MULTI-REEL LABELS.
RETURN ONE ;YES GIVE SKIP RETURN.
NODEL: IF.OFF OF,DSK!DTA,NTHERE ;JUMP IF A CLOSE DOES NOTHING.
CLOSE OF,ZERO ;PUT THE FILE ON THE DEVICE.
GOTO NTHERE ;START ALL OVER AGAIN.
CRLF: EME .STR,[BYTE (7)15,12,0] ;SEND CRLF.
RETURN ZERO ;VANISH....
;HERE ON A CONTROL C INTERCEPT.
CTLC: SKIPL T1,CCLFLG ;SKIP IF IN CCL FILE.
GOTO CTLC0 ;ELSE CARRY ON.
HRRZS T1 ;SO A GOOD COMPARE CAN BE DONE.
CAIG T1,CCLBLK+1 ;DONE ALL BUT ONE.
HRRZS CCLFLG ;YES.
JSP T1,CCLBAK ;BACK UP POINTER.
NOP CTLC ;POINTER FOR RETURN.
CTLC0: IF.OFF OF,DSK!DTA ;SKIP IF CLOSE DOES NOTHING.
CLOSE OF,.NODEL ;DON'T DELETE OUTPUT.
SKIPE RUNFLG ;SKIP IF RUNNING.
GOSUB CRLF ;SKIP A LINE.
SKIPE RUNFLG ;SKIP IF NOT RUNNING.
PRINT (***Job aborted) ;TELL HIM WHAT HE DID.
SETOM T1 ;FLAG OUR TTY.
EME .LTP,T1 ;GET TTY BITS.
SKIPGE T1 ;SKIP IF NOT PTY.
GOTO STOP ;TO EASE THE MIND OF BATCH.
GOTO NTHERE ;GO FLASH READY.
STOPIT: ENABLE TTY ;LET HIM SEE WHAT HE DID.
PRINT (stop) ;HERE TO STOP BEFORE WE PLANNED.
GOTO NODEL ;GO CLOSE THE OUTPUT FILE.
;HERE WHEN SOMETHING UNIMAGINABLE HAS
;HAPPENED TO US AND WE CAN'T CONTINUE.
;BECASUE OF A PROGRAM BUG....
ABORT: ENABLE TTY ;CLEAR GARBAGE.
XCT CRLF ;DON'T FORGET FORMAT.
MOVEM 17,AC+17 ;SAVE AC 17.
HRRZI 17,AC ;SET UP BLT POINTER.
BLT 17,AC+16 ;SAVE THE ACS.
MOVE 17,AC+17 ;RESTORE AC 17.
ABORT1: EME .STR,[ASCIZ "***System abort at "]
UNSAVE T2 ;GET ERROR ADDRESS BACK.
SOS T2 ;BACK UP TO ERROR LOCATION.
JSP P4,OCTOUT ;PRINT IT.
XCT CRLF ;LITTLE FORMAT...
SETZM T2 ;CLEAR AN INDEX.
GSNAM: HRRZI T1,11 ;GETTAB TABLE.
HRLI T1,ZERO(T2) ;INDEX INTO TABLE.
MME T1,.TAB ;GET A WORD OF THE SYSTEM NAME.
NOP ;IGNORE ERRORS.
MOVEM T1,SYSNAM(T2) ;SAVE IT.
AOS T2 ;BUMP INDEX.
CAIE T2,4 ;DONE THEM ALL???
GOTO GSNAM ;NO KEEP GOING.
MOVE T2,PRGNAM ;GET OUR NAME.
MOVEM T2,DMPFIL ;SET NAME OF FILE.
MOVE T2,ONE(PDP) ;GET ADDRESS OF CALL.
SUBI T2,ONE ;POINT TO CALL.
MOVEM T2,PC ;SAVE THE LOCATION.
MME T1,.DATE ;GET THE DATE.
MOVEM T1,DATE ;SAVE IT.
MME T1,.TIME ;GET THE TIME OF DAY.
MOVEM T1,TIME ;SAVE THE TIME.
HRRZ T1,.JBREL ;GET LAST LOCATION LOADED.
SUBI T1,137 ;JUST OUR STUFF.
MOVN T1,T1 ;MAKE IT NEGATIVE.
HRLM T1,DMPLST+1 ;SAVE IOW WORD.
OPEN DF,DMPDEV ;GET THE DEVICE.
GOTO ABTEND ;FORGET IT IF ERROR.
ENTER DF,DMPFIL ;GET A FILE.
GOTO ABTEND ;FORGET IT ON ERRORS.
DEVOP OUTPUT,DF,DMPLST ;WRITE US OUT.
ABTEND: CLOSE DF,ZERO ;PLACE US ON DISK.
RELEASE DF,ZERO ;GET RID OF THE CHANNEL.
SETZM DFFLG ;FLAG NO CHANNEL.
XCT CRLF ;ONE MORE LINE DOWN PAGE.
EME .CLR,ZERO ;CLEAR BUFFERS.
SKIPE T1,.JBDDT ;SKIP IF NO DDT.
GOTO CALDDT ;ELSE GET IT HERE.
GOTO NTHERE ;TRY AGAIN.
SUBTTL *** UTILITY ROUTINES ***
;HERE FROM LOCATION 40 ON A USER MODE ENTRY (UME).
UME0: GOSUB SAV2 ;SAVE SOME AC'S.
MOVE P1,.JBUUO ;PICK UP THE UME.
LDB T1,[POINT 4,P1,12] ;GET THE AC FIELD.
CAIN T1,.ASC ;IS IT AN ASCII UME.
GOTO UME1 ;YES GO TO IT.
CAIN T1,.SIX ;IS IT A SIXBIT ONE.
GOTO UME2 ;YES GO TO IT.
GOSUB ABORT ;ILLEGAL UME.
;HERE FOR AN ASCIZ STRING.
UME1: HRLI P1,(POINT 7,0) ;SET UP A BYTE POINTER.
ILDB CH,P1 ;GET AN ASCII CHARACTR.
JUMPE CH,RET0 ;A ZERO ENDS IT.
GOSUB UME4 ;CONVERT THE CHARACTER.
GOTO UME1+1 ;CONTINUE LOOP.
;HERE FOR ONE SIXBIT WORD.
UME2: HRLI P1,(POINT 6,0) ;SET UP BYTE POINTER TO THE DATA.
UME3: ILDB CH,P1 ;GET A CHARACTER.
MOVEI CH," "(CH) ;CONVERT IT TO ASCII.
GOSUB UME4 ;CONVERT THE CHARACTER.
IF.ON P1,77B5,UME3 ;JUMP IF HAVE MORE.
RETURN ZERO ;RETURN TO CALLER.
;HERE TO CONVERT THE CHARACTER.
UME4: HRRZ CH,TAB2(CH) ;TO THE OUTPUT SET.
IF.OFF CH,NEC ;SKIP IF GOOD CHARACTER.
AOS NOCHR ;COUNT THE BAD CHARACTER.
TEZ CH,NEC ;WAS IT BAD.
HRRZ CH,TAB2+"\" ;GET THE DEFAULT.
IF.ON S,LHEAD,PUT ;JUMP IF LPT HEADER.
GOTO @OUTC(OM) ;AND WRITE IT.
;HERE TO SEND A DATE STAMP TO THE OUTPUT DEVICE.
PUTDAT: MME T1,.DATE ;GET THE DATE.
PUTXDT: IDIVI T1,^D31 ;GET THE DAYS INTO T2.
AOS T2 ;THE CORRECT DAY.
SAVE T2 ;SAVE IT.
IDIVI T1,^D12 ;GET THE MONTH IN T2.
AOS T2 ;CORRECTED MONTH.
MOVEI T1,^D64(T1) ;GET THE YEAR.
EXCH T1,ZERO(PDP) ;PUT THE YEAR ON THE STACK.
SAVE T1 ;THE DAYS ARE NEXT.
SAVE T2 ;AND THEN THE MONTH.
MOVEI P1,"/" ;CHARACTER TO SEPARATE THINGS.
GOTO PDTBUF ;MOVE TH PDL TO THE BUFFER.
;HERE TO SEND A TIME STAMP TO THE OUTPUT DEVICE.
PUTTIM: MME T1,.TIME ;GET THE TIME OF DAY.
IDIVI T1,^D1000 ;MSEC. IN T2.
IDIVI T1,^D60 ;SECONDS IN T2.
SAVE T2 ;ONTO THE STACK.
IDIVI T1,^D60 ;MIN IN P2 HOURS IN P1.
SAVE T2 ;MINUTES TO STACK.
SAVE T1 ;HOURS TO THE STACK.
MOVEI P1,":" ;CHARACTER TO DELIMIT THINGS.
;HERE TO MOVE THE TOP THREE ELEMENTS OF THE STACK INTO THE BUFFER
;AS NUMBERS.
PDTBUF: MOVNI P2,3 ;TIMES TO DO IT.
PDTBU0: UNSAVE T2 ;GET AN ITEM.
GOSUB ZPUT ;MOVE IT.
AOJE P2,RET0 ;JUMP IF DONE.
MOVEI CH,ZERO(P1) ;GET THE DELIMITER.
GOSUB UME4 ;PLACE.
GOTO PDTBU0 ;DO THE NEXT ONE.
ZPUT: CAIGE T2,^D10 ;IS IT BETTER THEN 10.
UME .ASC,[ASCIZ "0"] ;NO SO ADD A ZERO.
ZPUT1: IDIVI T2,^D10 ;SLICE OFF A DIGIT.
HRLM T3,ZERO(PDP) ;SAVE A DIGIT.
SKIPE T2 ;SKIP IF DONE.
GOSUB .-3 ;CONTINUE ON.
HLRZ CH,ZERO(PDP) ;GET A DIGIT BACK.
MOVEI CH,"0"(CH) ;CONVERT TO ASCII.
GOTO UME4 ;INTO THE BUFFER.
;HERE TO PRINT P1 AS A THREE DIGIT NUMBER.
THEDIG: CAIGE P1,^D100 ;DOES IT PASS.
EME .CH,[EXP "0"] ;PAD.
;HERE TO PRINT AC P1 AS A TWO DIGIT NUMBER.
TWODIG: CAIGE P1,^D10 ;IS IT LESS THEN 10.
EME .CH,[EXP "0"] ;YES ADD A ZERO.
;FALL INTO DECOUT.
;HERE TO PRINT P1 AS A DECIMAL NUMBER.
DECOUT: SKIPA P3,[^D10] ;SET THE RADIX.
PUTOCT: MOVEI P3,10 ;SET THE RADIX.
MOVE T1,P1 ;TO A BETTER AC.
IDIV T1,P3 ;SLICE OFF A DIGIT.
HRLM T2,ZERO(PDP) ;SAVE DIGIT.
SKIPE T1 ;DONE YET.
GOSUB PUTOCT+2 ;NO CONTINU.
HLRZ T1,ZERO(PDP) ;COPY DIGIT.
MOVEI T1,"0"(T1) ;CONVERT TO ASCII.
EME .CH,T1 ;PRINT IT.
RETURN ZERO ;TRY AGAIN.
;HERE TO PRINT T1 AS A SIXBIT WORD.
PUTSIX: JUMPE T1,RET0 ;SUPPRESS TRAILING SPACES.
LDB CH,[POINT 6,T1,5] ;GET A CHARACTER.
MOVEI CH," "(CH) ;CONVERT TO ASCII.
EME .CH,CH ;PRINT IT.
LSH T1,6 ;GET NEXT CHARACTER INTO POSITION.
GOTO PUTSIX ;LOOP UNTIL DONE.
;HERE TO PRINT THE FILE NAME IN P1 AND P2.
PUTNAM: HLLZS P2 ;CLEAR THE RIGHT HALF.
CAMN P2,[SIXBIT "UFD"] ;IS THIS A UFD.
GOTO PUTNM0 ;YES.
MOVE T1,P1 ;COPY TO BETTER AC.
GOSUB PUTSIX ;PRINT IT.
SKIPE T1,P2 ;TEST AND COPY.
EME .CH,[EXP "."] ;FOR EXTENSION.
GOTO PUTSIX ;PRINT IT.
PUTNM0: EME .CH,[EXP "["] ;SIGNAL PPN COMING.
SAVE P1 ;SAVE UFD NAME.
HLRZS P1 ;GET HALF OF IT.
GOSUB PUTOCT ;PRINT IT.
EME .CH,[EXP ","] ;SEPARATE P FROM PN.
UNSAVE P1 ;GET IT BACK.
HRRZS P1 ;ZERO LEFT HALF.
GOSUB PUTOCT ;PRINT IT.
EME .STR,[ASCIZ "].UFD"] ;TELL THE REST.
RETURN ZERO ;RETURN TO CALLER.
;HERE TO BRANCH ON THE DEVICE TYPE.
WLDDEV: IF.ON IF,DSK,RET0 ;DISK RETURN.
IF.ON IF,DTA,RET1 ;DECTAPE RETURN.
IF.ON IF,MTA,RET2 ;MAG-TAPE RETURN.
RETURN THREE ;NON-DIRECTORY DEVICE.
;HERE ON THE INITIAL CALL TO FIND A FILE.
LOKWLD: GOSUB SAV4 ;SAVE SOME AC'S.
BRANCH WLDDEV,<WLDDSK,WLDDTA,WLDMTA> ;BRANCH ON DEVICE.
OFF IF,WILD!SCAN ;DEVICE DOESN'T HAVE WILDS.
OFF OF,WILD!SCAN ;CLEAR WILD BITS.
RETURN ONE ;AND SAY WE HAVE A FILE.
;HERE ON A CALL FOR A FILE WHEN WE HAVE ALREADY FOUND
;ONE ON THE DEVICE.
GETNXT: GOSUB SAV4 ;SAVE SOME AC'S.
BRANCH WLDDEV,<NXTDSK,NXTDTA,WLDMTA> ;BRANCH ON DEVICE.
RETURN ZERO ;OTHER DEVICES DON'T HAVE ANY.
;HERE TO FIND A FILE ON MAG-TAPE.
WLDMTA: GOSUB GETLAB ;GET A LABEL INTO CORE.
GOTO WDMTA0 ;END OF FILE FOUND.
BRANCH INPLAB,<NXTBLK,NXTNAM> ;BRANCH ON WHAT WE READ.
JSP T1,BADVOL ;BAD VOLUME FOUND.
IF.OFF S,L.HDR,NXTBLK ;CHECK NEXT IF NOT HDR.
SKIPN T1,IFILE+LABEL ;GET THE LABEL INDEX.
RETURN ONE ;TAPE IS AT THE RIGHT SPOT.
HRRZ T1,LB.TYP(T1) ;GET THE DISPATCH ADDRESS.
CAIE T1,LB.ICL ;IF NOT DEC LABEL TYPE
GOSUB SKPFIL ;SKIP EOF MARK AFTER LABEL.
RETURN ONE ;FOUND A FILE FOR HIM.
WDMTA0: IF.OFF IF,WNAME!WEXT!SCAN ;SKIP IF NOT SEARCHING.
RETURN ZERO ;ELSE GIVE EOF RETURN.
SKIPE IFILE+LABEL ;SKIP IF NO LABEL TYPE.
GOTO BADTM ;ELSE UNEXPECTED FILE MARK.
RETURN ONE ;IGNORE FILE MARK.
NXTBLK: IF.ON IF,WNAME!WEXT!SCAN ;IF WILD OR SCANNING SKIP.
GOTO NOLAB ;ELSE TELL BAD THINGS.
NXTFIL: MOVE T1,IFILE+LABEL ;GET THE LABEL INDEX.
HRRZ T1,LB.TYP(T1) ;GET THE DISPATCH ADDRESS.
CAIE T1,LB.ICL ;SKIP IF DEC LABELS.
GOTO SKPIT ;SKIP AHEAD.
IF.ON S,L.HDR,WLDMTA ;IF NOT HEADER SKIP.
SKPIT: GOSUB SKPFIL ;SKIP A FILE ON TAPE.
GOTO WLDMTA ;AND CHECK FOR A LABEL.
NXTNAM: IF.OFF IF,WNAME!WEXT!SCAN,NOMAT;JUMP IF NOT WILD OR SCANNING.
GOTO NXTFIL ;ELSE GO TO THE NEXT FILE.
;HERE TO GET A FILE FROM DECTAPE.
WLDDTA: MOVE T1,IFILE+DEVICE ;GET THE DEVICE NAME.
MOVEM T1,LABSTR ;SAVE IT AS THE STRUCTURE.
MME T1,.PPN ;GET OUT PPN.
NOP ;IN CASE OF JACCT.
MOVEM T1,LABPPN ;SAVE THE PPN.
CLOSE IF,ZERO ;CLOSE THE UNIT.
GETSTS IF,T1 ;GET THE DEVICE STATUS.
SAVE T1 ;ONTO THE STACK.
SETSTS IF,DMP+100 ;CHANGE TO DUMP MODE.
USETI IF,144 ;SET TO READ DIRECTORY BLOCK.
DEVOP IN,IF,DTACTL ;READ THE DIRECTORY.
GOTO DTNXT0 ;RIGHT ON.
GETSTS IF,T1 ;GET THE DEVICE STATUS.
IF.OFF T1,E.ERR,DTNXT0 ;JUMP IF NOT A PARITY ERROR.
IF.OFF T1,E.PAR,LKIERR ;JUMP IF A BAD ERROR.
IF.OFF IF,NOERROR,IPERR ;JUMP IF WANTS ERRORS.
AOS INPERR ;COUNT THE ERROR.
PRINT (% Parity error reading DECtape directory.)
DTNXT0: UNSAVE T1 ;GET THE DEVICE STATUS BACK.
SETSTS IF,ZERO(T1) ;SET IT RIGHT.
CLOSE IF,ZERO ;CLEAR ANY ERROR BITS.
HRLZI T1,-^D23 ;FILES IN DIRECTORY.
MOVEM T1,DTPTR ;SAVE THE POINTER WORD.
GOTO DTSET ;LOOK FOR THE FILE.
NXTDTA: IF.OFF IF,WNAME!WEXT,RET0 ;RETURN IF NOT WILD.
DTSET: MOVE T1,DTPTR ;GET THE POINTER WORD.
DTNXT: AOBJP T1,RET0 ;JUMP IF NO MORE.
SKIPN P1,DTBUF+DTNAM(T1) ;GET THE NAME IF THERE.
GOTO DTNXT ;ELSE TRY THE NEXT ONE.
HLLZ P2,DTBUF+DTEXT(T1) ;GET ITS EXTENSION.
MOVEM P1,LABNAM ;SAVE THE NAME.
MOVEM P2,LABNAM+1 ;SAVE THE EXTENSION.
GOSUB TSTNAM ;CHECK ON THE NAME.
GOTO DTNXT ;DO THE NEXT ONE.
MOVEM T1,DTPTR ;SAVE THE NEW POINTER WORD.
MOVE P1,[POINT 5,DTBUF] ;POINTER TO DIRECTORY.
MOVEI P2,^D578 ;USEABLE BLOCKS ON DTA.
SETZM LABSIZ ;CLEAR FILE SIZE.
DTLOP: ILDB P3,P1 ;GET A SAT BLOCK.
CAIN P3,ZERO(T1) ;SKIP IF NOT THIS FILE.
AOS LABSIZ ;COUNT BLOCK IN FILE.
SOJG P2,DTLOP ;JUMP IF MORE TO GO.
LDB T1,[POINT 12,DTBUF+DTEXT(T1),35] ;GET THE DATE.
HRLI T1,(57B8) ;GET THE DEFAULT PROTECTION.
MOVEM T1,LABDTW ;SAVE IT.
SETZM LABVOL ;CLEAR VOLUME NUMBER.
SKIPN LSTWRD ;SKIP IF LISTING.
GOTO OPNIT ;GO OPEN THE FILE.
RETURN ONE ;SKIP BACK.
;HERE FOR A WILD CARD LOOKUP ON DISK.
WLDDSK: MOVE T1,IFILE+DEVICE ;GET THE DEVICE NAMED.
MOVE T2,[XWD ONE,T1] ;POINTER FOR MME.
MME T2,.DCHR ;GET THE CHARACTERISTICS OF IT.
GOTO SYSDEV ;IF MME FAILS MUST BE SYS.
MOVE T1,IFILE+DEVICE ;GET THE DEVICE NAMED.
MOVEM T1,PATH ;SAVE IT.
MOVE T1,[XWD 5,PATH] ;POINTER TO MME.
MME T1,.PATH ;SEE IF REALLY SYS.
GOTO TSTDEV ;ERROR CONTINUE ON.
MOVE T1,[XWD 1,4] ;SYS PPN.
CAMN T1,PATH+2 ;IS THIS SYS.
GOTO SYSDEV ;FLAG SYSTEM SEARCH.
TSTDEV: IF.OFF T2,GDSK,GENDEV ;JUMP IF GENERIC DISK.
MOVE T1,IFILE+DEVICE ;GET THE DEVICE NAMED.
GOTO USEDEV ;AND USE IT.
SYSDEV: SETOM SYSSRH ;FLAG SYSTEM SEARCH.
GENDEV: SETOM SEARCH ;FLAG WE ARE SEARCHING.
NXTSTR: SKIPN SEARCH ;SKIP IF SEARCHING.
RETURN ZERO ;ELSE WE ARE DONE.
SKIPN T1,LSTDEV ;GET THE LAST DEVICE USED.
SETOM T1 ;IF NONE START FROM THE TOP.
SKIPE SYSSRH ;SKIP IF THIS JOBS LIST.
GOTO SYSLOK ;ELSE USE THE SYSTEM LIST.
IF.ON IF,WDEV,USEALL ;USE EVERY DEVICE IF WILD DSK.
MOVE T2,[XWD ONE,T1] ;POINTER FOR MME.
MME T2,.JLST ;GET A STRUCTURE.
RETURN ZERO ;QUIT ON ERRORS.
GOTO GOTDEV ;USE THIS DEVICE.
USEALL: MOVE T1,LSTDEV ;GET THE LAST DEVICE USED.
MME T1,.ALST ;GET THE NEXT ONE.
RETURN ZERO ;RETURN ON ERROR.
GOTO GOTDEV ;USE THE DEVICE.
SYSLOK: MOVEM T1,GOBLST+2 ;SAVE THE LAST DEVICE USED.
SETZM GOBLST ;SPECIFY SYSTEM LIST.
MOVE T1,[XWD 1,4] ;SYSTEM PPN.
MOVEM T1,IFILE+PPN ;SET THE SYS PPN AS OURS.
MOVEM T1,GOBLST+1 ;SAVE IT.
MOVE T1,[XWD THREE,GOBLST] ;POINTER FOR EXEC.
MME T1,.GLST ;GET A STRUCTURE.
RETURN ZERO ;QUIT ON ERRORS.
MOVE T1,GOBLST+2 ;GET THE DEVICE NAME.
GOTDEV: CAMN T1,[-1] ;HAVE WE REACHED THE END.
RETURN ZERO ;YES RETURN.
JUMPE T1,RET0 ;JUMP IF AT THE FENCE.
USEDEV: MOVEM T1,LSTDEV ;SAVE AS THE LAST DEVICE USED.
MOVEM T1,UFDDEV+1 ;SET IN PARAMETER BLOCK.
MOVEM T1,MFDDEV+1 ;SAVE FOR THE MFD.
IF.OFF IF,WP!WPN,ONLUFD ;IF NOT ACCROSS PPNS NO NEED FOR MFD.
OPEN MF,MFDDEV ;OPEN CHANNEL FOR THE MFD.
GOTO NXTSTR ;DO NEXT IF THIS FAILS.
;HERE WHEN READY TO START ON A NEW UFD.
ONLUFD: OPEN UF,UFDDEV ;OPEN THE DEVICE.
GOTO NXTSTR ;IF ERROR GET THE NEXT.
SKIPN T1,IFILE+PPN ;PPN SPECIFIED.
MME T1,.PPN ;NO GET THE CURRENT ONE.
NOP ;IN CASE OF JACCT.
SKIPE SYSSRH ;IS IT REALLY THE SYSTEM PPN.
MOVE T1,[XWD 1,4] ;YES GET ITS PPN.
MOVEM T1,IFILE+PPN ;SAVE THE PPN.
IF.OFF IF,WP!WPN,OPNUFD ;JUMP IF PPN ISN'T WILD.
MOVE T1,[XWD ONE,ONE] ;MFD PPN.
MOVEM T1,MFDNAM ;SAVE ITS NAME.
MOVEM T1,MFDNAM+3 ;SAVE THE PPN OF THE OWNER.
MOVSI T1,'UFD' ;THE MFD IS ITS OWN UFD.
MOVEM T1,MFDNAM+1 ;SAVE THE EXTENSION.
SETZM MFDNAM+2 ;CLEAR DATE TIME PROTECTION WORD.
LOOKUP MF,MFDNAM ;OPEN THE MFD.
GOTO MFDERR ;ERROR ON LOOKUP.
NXTMFD: DEVOP IN,MF,MFDCTL ;READ A BLOCK OF THE MFD.
GOTO FNDPPN ;READ IS O.K. FIND A PPN.
GETSTS MF,T1 ;SLIGHT ERROR.
IF.ON T1,E.EOF,NXTSTR ;IF DONE THEM ALL GET NEXT STR.
IF.OFF T1,E.PAR,FNDPPN ;IF NO ERROR JUMP.
IF.OFF IF,NOERROR,IPERR ;JUMP IF WANTS TO KNOW.
AOS INPERR ;COUNT THE ERROR.
PRINT (% Parity error reading MFD.)
FNDPPN: HRLZI T1,-101 ;COUNTER FOR ENTRIES.
MOVEM T1,MFDPTR ;SAVE THE POINTER.
NXTPPN: IF.OFF IF,WP!WPN,NXTSTR ;JUMP IF NOT WIL PPNS.
MOVE T1,MFDPTR ;GET THE MFD POINTER.
NTPPN: AOBJP T1,NXTMFD ;JUMP IF NEED NEXT BLOCK.
AOS T1 ;BUMP POINTER.
HLRZ P1,MFDBUF-1(T1) ;GET THE EXTENSION.
CAIE P1,'UFD' ;IS IT A UFD.
GOTO NTPPN ;NO TRY NEXT.
IF.ON IF,WP,CHKPN ;JUMP IF WILD PROJECT NUMBER.
HLRZ P1,MFDBUF-2(T1) ;GET THE PROJECT NUMBER.
HLRZ P2,IFILE+PPN ;GET THE DESIRED MATCH.
CAIE P1,ZERO(P2) ;SKIP IF O.K.
GOTO NTPPN ;ELSE TRY NEXT.
CHKPN: IF.ON IF,WPN,USEPPN ;JUMP IF WE HAVE A MATCH.
HRRZ P1,MFDBUF-2(T1) ;GET THE PROGRAM NUMBER.
HRRZ P2,IFILE+PPN ;GET THE DESIRED MATCH.
CAIE P1,ZERO(P2) ;SKIP IF ONE TO USE.
GOTO NTPPN ;ELSE TRY NEXT.
USEPPN: MOVEM T1,MFDPTR ;SAVE POINTER TO BUFFER.
MOVE T1,MFDBUF-2(T1) ;GET THE PPN THAT MATCHES.
;HERE WITH A PPN TO USE IN T1.
OPNUFD: MOVEM T1,UFDNAM ;SAVE THE NAME OF THE UFD.
MOVEM T1,LABPPN ;SAVE THE PPN.
MOVSI T1,'UFD' ;UFD EXTENSION.
MOVEM T1,UFDNAM+1 ;SAVE THE EXTENSION.
SETZM UFDNAM+2 ;CLEAR DATE TIME PROTECTION WORD.
MOVE T1,[XWD ONE,ONE] ;MFD PPN.
MOVEM T1,UFDNAM+3 ;SAVE THE PPN.
LOOKUP UF,UFDNAM ;OPEN THE DIRECTORY.
GOTO UFDERR ;ERROR ON LOOKUP.
NXTSEC: DEVOP IN,UF,UFDCTL ;READ A BLOCK.
GOTO CHKBLK ;THE READ WAS O.K.
GETSTS UF,T1 ;A LITTLE ERROR.
IF.ON T1,E.EOF,NXTPPN ;IF END GET NEXT.
IF.OFF T1,E.PAR,CHKBLK ;JUMP IF WE ARE NOT INTERESTED.
IF.OFF IF,NOERROR,IPERR ;JUMP IF WANTS TO KNOW.
AOS INPERR ;COUNT THE ERROR.
PRINT (% Parity error reading UFD.)
CHKBLK: HRLZI T1,-101 ;COUNT OF NAMES IN BLOCK.
MOVEM T1,DKPTR ;SAVE THE POINTER.
GOTO DKSET ;LOOK FOR THE FILE.
NXTDSK: IF.OFF IF,WILD,RET0 ;JUMP IF NOT WILD.
DKSET: MOVE T1,DKPTR ;GET THE POINTER.
DKNXT: AOBJP T1,NXTSEC ;GET THHE NEXT SECTOR.
HLLZ P2,UFDBUF(T1) ;GET THE EXTENSION.
AOS T1 ;BUMP THE POINTER.
SKIPN P1,UFDBUF-2(T1) ;SKIP IF NAME IS THERE.
GOTO DKNXT ;GET THE NEXT ONE.
MOVEM P1,LABNAM ;SAVE THE NAME.
MOVEM P2,LABNAM+1 ;SAVE THE EXTENSION.
GOSUB TSTNAM ;SEE IF GOOD NAME.
GOTO DKNXT ;TRY TRY AGAIN.
MOVEM T1,DKPTR ;SAVE POINTER.
MOVE T1,UFDDEV+1 ;GET THE STRUCTURE'S NAME.
MOVEM T1,LABSTR ;SAVE THE NAME.
EXCH T1,IFILE+DEVICE ;MAKE IT HIS.
OPEN IF,IFILE+STATUS ;OPEN THIS STRUCTURE.
GOTO DK0NXT ;SHOULD NEVER HAPPEN.
MOVEM T1,IFILE+DEVICE ;GIVE HIM HIS DEVICE BACK.
HLRZ T1,MSIZ(IM) ;GET THE INPUT BYTE SIZE.
DPB T1,[POINT 6,IBUF+1,11] ;SET THE SIZE WE WANT.
MOVE T1,I.JBFF ;GET INPUT JOB FIRST FREE.
EXCH T1,.JBFF ;SET IT AS CURRENT.
SAVE T1 ;SAVE FIRST FREE.
GOSUB MONIBF ;GET SOME BUFFERS.
UNSAVE .JBFF ;RESTORE FIRST FREE.
MOVE T1,UFDNAM ;GET THE PPN WE FOUND THIS IN.
MOVEM T1,IFILE+PPN ;SAVE THE PPN.
GOTO OPNIT ;OPEN THE FILE.
DK0NXT: MOVEM T1,IFILE+DEVICE ;REPLACE THE DEVICE.
GOTO NXTSTR ;TRY THE NEXT STRUCTURE.
;HERE TO OPEN THE FILE THAT HAS BEEN SELECTED.
OPNIT: SETZM LABVOL ;CLEAR VOLUME NUMBER.
SKIPE FSTWRD ;SKIP IT NOT FAST LIST.
RETURN ONE ;DON'T OPEN IT FOR FAST LIST.
SAVE IFILE+PPN ;SAVE THE PPN.
LOOKUP IF,IFILE+NAME ;OPEN THE FILE.
GOTO MAYBE ;MAYBE STOP NOW.
HLRE T1,IFILE+PPN ;IF DSK THIS IS SIZE.
JUMPGE T1,GOTSIZ ;IF POSITIVE IT IS BLOCKS.
MOVNS T1 ;GET THE POSITIVE WORDS.
IDIVI T1,200 ;CONVERT TO BLOCKS.
SKIPE T2 ;SKIP IF EVEN.
AOS T1 ;ROUND UP.
GOTSIZ: UNSAVE IFILE+PPN ;RESTORE THE PPN.
IF.ON IF,DTA,RET1 ;RETURN IF DTA.
MOVEM T1,LABSIZ ;SAVE THE SIZE OF THE FILE.
MOVE T1,IFILE+DATTIM ;GET THE DATE, TIME, PROT WORD.
AND T1,[EXP 777B8] ;JUST THE PROTECTION BITS.
MOVEM T1,LABDTW ;SAVE IT FOR DISK.
LDB T1,[POINT 12,IFILE+DATTIM,35] ;GET THE DATE.
MOVE T2,IFILE+EXT ;LOAD HIGH ORDER DATE.
ANDI T2,70000 ;ISOLATE BITS.
IORI T1,ZERO(T2) ;COMBINE HIGH AND LOW ORDER.
HRRM T1,LABDTW ;SAVE IT.
RETURN ONE ;GIVE GOOD RETURN.
;HERE ON A MFD LOOKUP ERROR.
MFDERR: MOVEI SIDE,MFDDEV ;GET POINTER TO THINGS.
GOSUB DIRERR ;TELL OF ERROR.
GOTO NXTSTR ;AND TRY NEXT STRUCTURE.
;HERE ON A UFD LOOKUP ERROR.
UFDERR: MOVEI SIDE,UFDDEV ;GET POINTER TO THINGS.
GOSUB DIRERR ;TYPE THE ERROR MESAGE.
GOTO NXTPPN ;TRY AGAIN.
;HERE TO TYPE ERROR MESSAGES FOR MFD AND UFD LOOKUP ERRORS.
DIRERR: EME .STR,[ASCIZ /% Directory "/]
SETZM P4 ;CLEAR FLAGS.
GOTO TYPE0 ;SEND THE MESSAGE.
USE DATA
BSS PATH,5
BSS DTBUF,200
BSS DTPTR,ONE
DTACTL: IOWD 200,DTBUF
BSS ONE
EXP MF
MFDDEV: EXP DMP
BSS TWO
BSS MFDNAM,4
BSS GOBLST,THREE
EXP UF
UFDDEV: EXP DMP
BSS TWO
BSS UFDNAM,4
BSS MFDBUF,200
BSS MFDPTR,ONE
MFDCTL: IOWD 200,MFDBUF
BSS ONE
UFDCTL==DTACTL
DKPTR==DTPTR
UFDBUF==DTBUF
USE CODE
;HERE TO PLACE THE DATE INTO THE BUFFER AS
;YYMMDD.
COBDAT: IDIVI T1,^D31 ;DAYS INTO T2.
SAVE T2 ;SAVE THE DAYS.
IDIVI T1,^D12 ;MONTHS IN T2.
SAVE T2 ;SAVE THE MONTH.
MOVEI T1,^D64(T1) ;GET THIS YEAR.
GOSUB DEPTWO ;INTO BUFFER.
UNSAVE T1 ;GET THE MONTHS BACK.
AOS T1 ;FOR THE ONE LOST.
GOSUB DEPTWO ;ADD INTO BUFFER.
UNSAVE T1 ;GET THE DAYS.
AOS T1 ;COUNT EXTRA DAY.
GOTO DEPTWO ;INTO BUFFER.
;HERE TO COPY THE NUMBER OF CHARACTERS SPECIFIED BY
;THE COUNT IN P3 AND POINTER IN P2 TO THE POINTER
;IN P1.
PLACE: ILDB CH,P2 ;GET A CHARACTER.
IDPB CH,P1 ;SAVE IT.
SOJG P3,PLACE ;DO THEM ALL.
RETURN ZERO ;TO SENDER.
;HERE TO PLACE A FEW SPACES INTO THE LABEL
;BUFFER. PUTS SPACES BY THE POINTER IN P1 AND FOR THE COUNT
;IN P3.
SPACE: SETZM CH ;SET CH TO A SPACE.
ANYCHR: IDPB CH,P1 ;WRITE IT INTO THE BUFFER.
SOJG P3,ANYCHR ;CONTINUE ON.
RETURN ZERO ;BACK TO CALLER.
;HERE TO PRINT T2 AS A TWELVE DIGIT OCTAL NUMBER.
OCTOUT: MOVNI T3,^D12 ;DUMP A WORD.
SETZM T1 ;ZERO STORAGE.
LSHC T1,3 ;GET A DIGIT.
MOVEI CH,"0"(T1) ;CONVERT AND MOVE.
EME .CH,CH ;PRINT.
AOJN T3,OCTOUT+1 ;CONTINUE FOR TWELVE.
EME .CH,[EXP " "] ;ADD A SPACE.
GOTO ZERO(P4) ;RETURN TO CALLER.
;HERE TO TYPE OUT THE DATE CONTAINED IN T1.
TYPDAT: IDIVI T1,^D31 ;GET THE DAYS IN T2.
SAVE T2 ;SAVE THEM.
IDIVI T1,^D12 ;GET THE MONTH IN T2
MOVEI T1,^D64(T1) ;GET THE YEAR IN T1.
EXCH T1,ZERO(PDP) ;PUT THE YEAR ON THE STACK.
SAVE T1 ;PLACE THE DAY ON THE STACK.
MOVEI P1,ONE(T2) ;MONTHS TO A BETTER AC.
GOSUB TWODIG ;PRINT THE MONTH.
EME .CH,[EXP "/"] ;DELIMIT THE MONTH.
UNSAVE P1 ;GET THE DAYS BACK.
MOVEI P1,ONE(P1) ;SET THE DAYS RIGHT.
GOSUB TWODIG ;PRINT THE DAY OF THE MONTH.
EME .CH,[EXP "/"] ;DELIMIT THE DAY.
UNSAVE P1 ;GET THE YEAR.
GOTO TWODIG ;PRINT THE YEAR.
;HERE TO TYPE THE TIME OF DAY CONTAINED IN T1.
TYPTIM: IDIVI T1,^D60000 ;SLICE OFF MILLISECONDS.
IDIVI T1,^D60 ;HOURS IN T1 MINUTES IN T2.
SAVE T2 ;SAVE THE MINUTES.
MOVE P1,T1 ;TO A BETTER AC.
GOSUB TWODIG ;PRINT THE HOURS.
EME .CH,[EXP ":"] ;DELIMIT HOURS FROM SECONDS.
UNSAVE P1 ;GET THE MINUTES BACK.
GOTO TWODIG ;PRINT THE MINUTES.
;HERE TO FILL IN DEFAULTS FOR THE LABELS.
LABFIL: MOVEM T1,LABDTW ;SAVE THE LABEL DATE.
MOVSI T1,'DSK' ;GET THE DEVICE.
MOVEM T1,LABSTR ;SAVE THE DEVICE.
MOVEI T1,057 ;PROTECTION BITS.
DPB T1,[POINT 8,LABDTW,8] ;SET THE PROTECTION WORD.
SKIPN T1,OFILE+PPN ;IS TERE A PPN.
MME T1,.PPN ;USE THE CURRENT ONE.
NOP ;IN CASE OF JACCT.
MOVEM T1,LABPPN ;SAVE THE PPN WORD.
RETURN ONE ;GIVE GOOD LABEL RETURN.
;HERE TO TAKE A SIXBIT NUMBER CONTAINED IN T2
;AND CONVERT IT TO AN OCTAL NUMBER.
TOBIN: GOSUB SAV3 ;SAVE SOME AC'S.
MOVEI P3,10 ;SET OCTAL RADIX.
GOTO TOOCT1 ;CONVERT IT.
TOOCT: GOSUB SAV3 ;SAVE SOME AC'S.
MOVEI P3,^D10 ;SET RADIX TO TEN.
TOOCT1: SETZM T3 ;CLEAR RESULT.
IOR T2,[SIXBIT "000000"] ;ADD LEADING ZEROS.
MOVE P1,[POINT 6,T2] ;POINT TO DATA.
TOOCT0: ILDB P2,P1 ;GET A CHARACTER.
IMULI T3,ZERO(P3) ;SHIFT LEFT FOR BASE.
ADDI T3,-'0'(P2) ;ADD IN NEW DIGIT.
IF.ON P1,77B5,TOOCT0 ;JUMP IF MORE TO GO.
RETURN ZERO ;ELSE RETURN TO CALLER.
;HERE TO TAKE THE DATE IN THE FORM YYMMDD IN T1
;AND CONVERT IT TO ((YEAR-1964)*12+(MONTH-1))*31+DAY-1.
DATCOB: LDB T2,[POINT 12,T1,11] ;LOAD THE YEAR.
GOSUB TOOCT ;MAKE IT OCTAL.
SUBI T3,^D64 ;YEAR-1964.
IMULI T3,^D12 ;(YEAR-1964)*12.
SAVE T3 ;SAVE THE DATE SO FAR.
LDB T2,[POINT 12,T1,23] ;GET THE MONTH.
GOSUB TOOCT ;CONVERT IT TO OCTAL.
UNSAVE T2 ;GET THE ACCUMULATED DATE BACK.
ADDI T2,-ONE(T3) ;(YEAR-1964)*12+(MONTH-1).
IMULI T2,^D31 ;((YEAR-1964)*12+(MONTH-1))*31.
SAVE T2 ;SAVE IT.
LDB T2,[POINT 12,T1,35] ;GET THE DAY.
GOSUB TOOCT ;CONVERT IT TO OCTAL.
UNSAVE T1 ;GET THE ACCUMULATED DATE BACK.
ADDI T1,-ONE(T3) ;((YEAR-1964)*12+(MONTH-1))*31+DAY-1.
RETURN ZERO ;COMPRESSED DATE IN T1.
;HERE TO TAKE THE DATE IN THE FORM YYDDD IN T1
;AND CONVERT IT TO ((YEAR-1964)*12+(MONTH-1))*31+DAY-1.
DATBCL: LDB T2,[POINT 12,T1,11] ;GET THE YEAR.
GOSUB TOOCT ;CONVERT TO OCTAL.
SAVE T3 ;SAVE FOR LATER.
SUBI T3,^D64 ;YEAR-1964.
IMULI T3,^D12 ;(YEAR-1964)*12.
SAVE T3 ;SAVE IT ON THE STACK.
LDB T2,[POINT 18,T1,29] ;COPY THE DAYS.
GOSUB TOOCT ;CONVERT IT TO OCTAL.
HRLZI T2,-^D11 ;COUNTER FOR MONTH SCAN.
CAML T3,MONTH+1(T2) ;HAVE WE PASSED THE MONTH.
AOBJN T2,.-1 ;NO CONTINUE.
UNSAVE T1 ;GET THE ACCUMULATED DATE BACK.
ADDI T1,-ONE(T2) ;(YEAR-1964)*12+(MONTH-1).
IMULI T1,^D31 ;((YEAR-1964)*12+(MONTH-1))*31.
SUB T3,MONTH-1(T2) ;DAYS IN THIS MONTH IN T3.
ADDI T1,-ONE(T3) ;((YEAR-1964)*12+(MONTH-1))*31+DAY-1
CAIG T3,^D59 ;SKIP IF PAST FEB.
GOTO DATBL0 ;JUMP IF NOT PAST FEB.
MOVE T2,ZERO(PDP) ;GET THE YEAR BACK.
IDIVI T2,^D4 ;SEE IF IT IS A LEAP YEAR.
SKIPN T3 ;SKIP IF NOT.
SOS T1 ;SUBTRACT OFF EXTRA DAY.
DATBL0: UNSAVE T2 ;CLEAN UP THE STACK.
RETURN ZERO ;COMPRESSED DATE IN T1.
;HERE TO CHECK FOR DEVICE ERRORS.
LOKERR: IF.ON T1,E.LOK,LOCK ;JUMP IF DEVICE IS WRITE LOCKED.
IF.ON T1,E.HAD,HADERR ;JUMP IF HARDWARE ERROR.
IF.ON T1,E.IOB,BLKERR ;JUMP IF USER ERROR.
GOSUB ABORT ;IF NOT ONE OF THESE REAL BUG.
;HERE TO SEE IF WE HAVE READ AN EOF.
BCLCHK: HRRZ T1,IBUF+1 ;PICK UP POINTER TO DATA.
MOVE T1,ONE(T1) ;GET DATA WORD.
CAME T1,[XWD 170000,0] ;IS IT AN EOF MARK.
CAMN T1,[XWD 230000,0] ;NINE TRACK EOF.
SKIPA ;IT PASSED THAT.
RETURN ONE ;FORGET IT.
HRRZ T1,MSIZ(IM) ;GET THE BYTES PER WORD.
CAME T1,IBUF+2 ;DID WE GET JUST THAT MANY.
RETURN ONE ;NO -- MUST BE DATA.
MME IF,.IOSTP ;WAIT FOR I/O TO STOP.
GETSTS IF,T1 ;GET THE DEVICE STATUS.
IF.ON T1,SYNC,INPEND ;IF SYNC'ED JUMP.
SKIPN T1,IFILE+BUFNUM ;GET THE NUMBER OF BUFFERS.
MOVEI T1,TWO ;DEFAULT NUMBER.
BCLCK0: SOJLE T1,INPEND ;JUMP IF DONE ENOUGH.
DRIVE IF,.BSR ;BACK UP PLEASE.
DRIVE IF,.WAT ;WAIT FOR IT.
GOTO BCLCK0 ;DO IT AGAIN.
;HERE TO FUDGE UP THE IBM LABEL NAME.
COPY: SETZM ZERO(T2) ;CLEAR TARGET.
COPY0: SOJL P3,RET0 ;JUMP IF READ ENOUGH.
ILDB CH,T1 ;GET A CHARACTER.
JUMPE CH,COPY1 ;ALLOW SPACES.
CAIGE CH,'0' ;IS IT BETTER THEN ZERO.
GOTO COPY0 ;NO IGNORE IT.
CAIG CH,'9' ;IS IT GREATER THEN NINE.
GOTO COPY1 ;A DIGIT IS LEGAL.
CAIL CH,'A' ;IS IT LESS THEN A.
CAILE CH,'Z' ;OR GREATER THEN Z.
GOTO COPY0 ;YES SO IGNORE.
COPY1: IDPB CH,T2 ;SAVE THE CHARACTER.
SOJG T3,COPY0 ;JUMP IF HAVE ROOM.
RETURN ZERO ;ELSE RETURN.
;HERE TO TELL HOW MANY CPU SECONDS AND HOW MANY TIMES
;WE ACCESSED A DEVICE.
STAT: GOSUB CRLF ;YES SKIP A LINE.
SETZM P1 ;SPECIFY THIS JOB.
MME P1,.TIM ;GET THE RUN TIME.
SUB P1,%TIME ;SUBTRACT START TIME.
IDIVI P1,^D1000 ;CONVERT TO SECONDS.
GOSUB DECOUT ;PRINT THE SECONDS.
EME .CH,[EXP "."] ;DELIMIT THEM FROM FRACTIONS.
MOVE P1,P2 ;MOVE TO BETTER AC.
GOSUB THEDIG ;PRINT AS THREE DIGITS.
EME .STR,[ASCIZ " sec. "] ;TELL HIM WHAT THAT WAS.
MOVE P1,%IO ;GET I/O UNITS.
GOSUB DECOUT ;PRINT THEM.
PRINT ( I/O units.) ;SO HE KNOWS WHAT WE ARE PRINTING.
HRRZ P1,.JBREL ;OCTAL LOCATIONS USED.
GOSUB PUTOCT ;PRINT THEM.
PRINT ( octal locations used.);SO HE KNOWS WHAT WE USED.
;HERE TO TELL HOW NAMY BLOCKS WE HAVE READ AND HOW NAMY RECORDS
;THERE WERE IN THE BLOCKS.
MOVE P1,IBCNT ;GET BLOCKS READ.
GOSUB DECOUT ;PRINT THEM.
EME .STR,[ASCIZ " blk. "] ;TELL HIM WHAT IT IS.
MOVE P1,IRCNT ;GET THE NUMBER OF RECORDS READ.
GOSUB DECOUT ;SHOW IT TO HIM.
PRINT ( rec. read.) ;TELL HIM WHAT IT MEANS.
;HERE TO TELL HOW MANY BLOCKS WE WROTE AND HOW MANY
;RECORDS WERE IN THOSE BLOCKS.
STAT8: MOVE T1,IFILE+MOD ;GET THE INPUT BITS.
IF.OFF T1,WNAME!WEXT,STAT88 ;JUMP IF INPUT ISN'T WILD.
MOVE T1,OFILE+MOD ;GET THE OUTPUT MOD BITS.
IF.ON T1,WNAME!WEXT,STAT9 ;MEANINGLESS IF WILD.
STAT88: MOVE P1,OBCNT ;GET BLOCKS WRITTEN.
GOSUB DECOUT ;PRINT THEM.
EME .STR,[ASCIZ " blk. "] ;TELL HIM WHAT HE JUST SAW.
MOVE P1,ORCNT ;GET THE RECORD COUNT.
GOSUB DECOUT ;PRINT THEM.
PRINT ( rec. written.) ;SO HE KNOWS WHAT HE SEES.
;HERE TO TELL HOW MANY FILES WE HAVE LOOKED AT.
STAT9: MOVE P1,IFCNT ;GET THE INPUT FILE COUNT.
HRREI P2,-1(P1) ;ONLY IF MORE THEN ONE.
JUMPLE P2,STAT6 ;JUMP IF NOT MORE.
GOSUB DECOUT ;TELL HOW MANY.
PRINT ( input files read.) ;SO HE KNOWS.
STAT6: MOVE P1,OFCNT ;GET THE OUTPUT COUNT.
HRREI P2,-1(P1) ;ONLY IF MORE THEN ONE.
JUMPLE P2,STAT7 ;JUMP IF NOT ENOUGH.
GOSUB DECOUT ;TELL HOW MANY.
PRINT ( output files written.);SO HE KNOWS.
;HERE TO TELL THE BAD THINGS THAT HAPPENED WHILE
;WE WERE CONVERTING THE CHARACTER SETS.
STAT7: SKIPN P1,NOCHR ;COUNT OF NON-CONVERTS.
GOTO STAT2 ;TELL NOTHING IF GOOD.
GOSUB DECOUT ;TELL THE BAD NEWS.
PRINT ( bad characters found.);SO HE KNOWS WHAT IT IS.
;HERE TO TELL ABOUT DEVICE ERRORS IF THERE WERE ANY.
STAT2: SKIPN P1,INPERR ;ARE THERE ANY INPUT ERRORS.
GOTO STAT4 ;NO IGNORE IT.
GOSUB DECOUT ;PRINT THEM.
PRINT ( input parity errors.)
STAT4: SKIPN P1,OTPERR ;ANY OUTPUT ERRORS.
GOTO STAT5 ;NO SO SKIP IT ALL.
GOSUB DECOUT ;PRINT THE VALUE.
PRINT ( output parity errors.)
STAT5: EME .CLR,ZERO ;CLEAR BUFFERS.
RETURN ZERO ;BACK TO CALLER.
;HERE TO CHECK ON A FILE OR LABEL NAME.
TSTNAM: IF.ON IF,WNAME,CHKEXT ;IF WILD NAME CHECK EXT.
CAME P1,IFILE+NAME ;DOES NAME MATCH.
RETURN ZERO ;NOT THE RIGHT ONE.
CHKEXT: IF.ON IF,WEXT,MOVNAM ;MOVE NAME INTO PLACE IF WILD.
HLLZS IFILE+EXT ;ZERO THE RIGHT HALF.
CAME P2,IFILE+EXT ;CHECK THE EXTENSION.
RETURN ZERO ;NO MATCH.
MOVNAM: IF.OFF IF,WNAME ;SKIP IF NAME ISN'T WILD.
MOVEM P1,IFILE+NAME ;SAVE THIS NAME.
IF.OFF IF,WEXT ;SKIP IF NOT WILD EXTENSION.
MOVEM P2,IFILE+EXT ;ELSE SAVE THIS ONE.
MOVE P1,LABNAM ;GET FIRST HALF OF THE NAME.
MOVE P2,LABNAM+1 ;GET THE SECOND HALF.
MOVNM0: IF.OFF OF,WNAME ;SKIP IF OUTPUT NAME IS TRUE.
MOVEM P1,OFILE+NAME ;SAVE THIS NAME.
IF.OFF OF,WEXT ;SKIP IF EXTENSION IS TRUE.
MOVEM P2,OFILE+EXT ;SAVE THE EXTENSION.
RETURN ONE ;GIVE FOUND RETURN.
;HERE TO GET A FUNNY NAME.
DREAM: MME T1,.TIME ;GET THE TIME OF DAY.
IDIVI T1,^D1000 ;LEAVE HOURS, MIN, SEC.
IDIVI T1,^D60 ;SLICE OFF SECONDS.
SAVE T2 ;SAVE THEM.
IDIVI T1,^D60 ;SLICE OFF MIN.
SAVE T2 ;SAVE THEM.
MOVE T3,[POINT 6,WD] ;LOAD A BYTE POINTER.
DREAM0: GOSUB DREAM1 ;SAVE HOURS.
UNSAVE T1 ;GET MINS BACK.
GOSUB DREAM1 ;SAVE MINS.
UNSAVE T1 ;GET SECONDS BACK.
GOSUB DREAM1 ;SAVE THEM.
MOVSI T2,'CHG' ;EXTENSION.
MOVE T1,WD ;PUT IN RIGHT AC.
RETURN ZERO ;BACK TO CALLER.
DREAM1: IDIVI T1,^D10 ;SEPARATE DIGITS.
MOVEI T1,'0'(T1) ;MAKE IT SIXBIT.
IDPB T1,T3 ;SAVE DIGIT.
MOVEI T2,'0'(T2) ;MAKE OTHER SIXBIT.
IDPB T2,T3 ;SAVE IT.
RETURN ZERO ;AND RETURN.
;HERE TO CONVERT THE DATE CONTAINED IN T1 TO
;YYDDD AND DEPOSIT THIS BY THE POINTER IN P1.
BCLDAT: IDIVI T1,^D31 ;GET THE DAYS.
SAVE T2 ;STICK ONTO STACK.
IDIVI T1,^D12 ;GET THE MONTHS.
MOVE T2,MONTH(T2) ;GET DAYS SO FAR IN YEAR.
UNSAVE T3 ;GET DAYS BACK.
ADDI T2,ONE(T3) ;T2 HAS DAYS SO FAR IN YEAR.
SAVE T2 ;SAVE THE DAYS.
MOVEI T1,^D64(T1) ;UPDATE THE YEAR.
MOVE T2,T1 ;COPY TO ANOTHER AC.
IDIVI T2,4 ;MUST BE SURE THIS ISN'T A LEAP YEAR.
JUMPN T3,BYEAR ;JUMP IF NOT A LEAP YEAR.
MOVE T3,ZERO(PDP) ;GET DAYS BACK.
CAILE T3,^D59 ;ARE WE PAST FEB.
AOS ZERO(PDP) ;YES SO COUNT EXTRA DAY.
BYEAR: GOSUB DEPTWO ;PUT TWO DIGITS OUT.
UNSAVE T1 ;GET THE DAYS BACK.
MOVEI T2,'0' ;IN CASE WE MUST PAD.
CAIGE T1,^D100 ;SKIP IF BETTER THEN 100.
IDPB T2,P1 ;PAD A ZERO.
DEPTWO: MOVEI T2,'0' ;IN CASE WE MUST PAD.
CAIGE T1,^D10 ;IS IT BETTER THEN 10.
IDPB T2,P1 ;NO PAD IN A ZERO.
IDIVI T1,^D10 ;SLICE OFF A DIGIT.
HRLM T2,ZERO(PDP) ;SAVE A DIGIT.
SKIPE T1 ;SKIP IF LAST DIGIT.
GOSUB .-3 ;CONTINUE FOR ALL DIGITS.
HLRZ T1,ZERO(PDP) ;GET A DIGIT FROM STACK.
MOVEI CH,'0'(T1) ;CONVERT TO SIXBIT.
IDPB CH,P1 ;PUT INTO BUFFER.
RETURN ZERO ;BACK TO SENDER.
MONTH: DEC 0,31,59,90,120,151,181,212,243,273,304,334
;HERE TO SAVE THE AC'S ON THE STACK. AC 0(S) IS GLOBAL ACROSS
;ALL ROUTINES AND IS NOT SAVED. AC 17(PDP) IS THE PUSH-DOWN POINTER
;AND SHOULD NOT BE SAVED. ***CAUTION SHOULD BE USED IN CALLING THIS
;ROUTINE FOR IT USES SPACE RAPIDLY ON THE STACK. NOTE RETURNS TO PC,
;PC+1, PC+2, AND PC+3 ARE HANDLED CORRECTLY. THE RETURN FROM THE
;ROUTINE THAT CALLS THIS ROUTINE WILL RESTORE THE AC'S.
STORE: EXCH 1,0(PDP) ;SAVE AC ONE.
MOVEM 1,TEMP ;SAVE POINTER TO RETURN.
HRRZI 1,1(PDP) ;DESTINATION FOR BLT.
HRLI 1,2 ;SOURCE FOR BLT.
BLT 1,15(PDP) ;SAVE THE AC'S.
ADD PDP,[XWD 15,15] ;UPDATE PDP.
MOVEI 1,3 ;BUMP RETURN FOR SKIP.
ADDM 1,-16(PDP) ;RETURN IS NOW TO PC+3.
MOVE 1,-15(PDP) ;RESTORE AC 1.
GOSUB @TEMP ;RETURN TO SENDER.
SOS -16(PDP) ;DECREMENT FOR NORMAL RETURN.
SOS -16(PDP) ;DECREMENT FOR RETURN TO PC+2.
SOS -16(PDP) ;DECREMENT FOR RETURN TO PC+1.
HRLZI 16,-15(PDP) ;SOURCE FOR BLT.
HRRI 16,1 ;DESTINATION FOR BLT.
BLT 16,16 ;RESTORE THE AC'S.
SUB PDP,[XWD 16,16] ;UPDATE PDP.
RETURN ZERO ;BACK TO SENDER.
;STACK MANIPULATORS.
RET3: AOS ZERO(PDP) ;RETURN TO PC+3.
RET2: AOS ZERO(PDP) ;RETURN TO PC+2.
RET1: AOS ZERO(PDP) ;RETURN TO PC+1.
RET0: RETURN ZERO ;RETURN TO PC+0.
;HERE TO SAVE THE P AC'S ON THE STACK. SKIP RETURNS HANDLED.
SAV4: SAVE [XWD -4,ZERO] ;AC'S TO SAVE.
GOTO SAVEAC ;GO SAVE THEM.
SAV3: SAVE [XWD -3,ZERO] ;AC'S TO SAVE.
GOTO SAVEAC ;SAVE THEM.
SAV2: SAVE [XWD -2,ZERO] ;AC'S TO SAVE.
GOTO SAVEAC ;GO SAVE THEM.
SAV1: SAVE [XWD -1,ZERO] ;AC'S TO SAVE.
SAVEAC: EXCH P1,-1(PDP) ;SAVE AC P1.
MOVEM P1,TEMP ;SAVE RETURN ADDRESS.
MOVEI P1,3 ;TO FIX UP RETURN.
ADDM P1,-2(PDP) ;RETURN IS NOW TO PC+3.
UNSAVE P1 ;GET AOBJ WORD FOR SAVE.
AOBJP P1,.+3 ;JUMP IF SAVED ENOUGH.
SAVE P1(P1) ;SAVE AN AC.
GOTO .-2 ;DO THE NEXT.
SAVE P1 ;SAVE AC P1.
MOVEI P1,ONE(P1) ;POINT P1 TO RETURN.
SUBM PDP,P1 ;MAKE P1 POINT TO ADR OF RETURN.
HRRZS P1 ;CLEAR P1 RIGHT HALF.
SAVE P1 ;PLACE IT ON THE TOP OF THE STACK.
MOVE P1,ONE(P1) ;RESTORE P1.
GOSUB @TEMP ;DISPATCH...
SOS @ZERO(PDP) ;RETURN TO PC.
SOS @ZERO(PDP) ;RETURN TO PC+1.
SOS @ZERO(PDP) ;RETURN TO PC+2.
UNSAVE P1 ;TAKE POINTER OFF STACK.
UNSAVE P1 ;NUMBER OF AC'S SAVED.
SOJLE P1,.+3 ;JUMP IF DONE ENOUGH.
UNSAVE P1(P1) ;RESTORE AN AC.
GOTO .-2 ;CONTINUE ON.
UNSAVE P1 ;RESTORE P1.
RETURN ZERO ;BACK TO CALLER.
;HERE TO RESTORE THE P AC'S. MUST BE CALLED WITH A "GOSUB".
UNS4: UNSAVE P4 ;GET THE RETURN.
MOVEM P4,ZERO(PDP) ;PUT THE RETURN BACK.
MOVE P4,-THREE(PDP) ;RESTORE P4.
UNS3: UNSAVE P3 ;GET THE RETURN.
MOVEM P3,ZERO(PDP) ;PUT THE RETURN BACK.
MOVE P3,-THREE(PDP) ;RESTORE P3.
UNS2: UNSAVE P2 ;GET THE RETURN.
MOVEM P2,ZERO(PDP) ;PUT THE RETURN BACK.
MOVE P2,-THREE(PDP) ;RESTORE P2.
UNS1: UNSAVE P1 ;GET THE RETURN.
MOVEI P1,3 ;TO FIX RETURN POINTER.
EXCH P1,-4(PDP) ;SO A SUBM CAN BE DONE.
SUBM P1,-4(PDP) ;POINT RETURN RIGHT.
MOVE P1,-THREE(PDP) ;RESTORE P1.
SUB PDP,[XWD 4,4] ;POINT PDP RIGHT.
RETURN ZERO ;RETURN.
;HERE TO INCREMENT THE VOLUME NUMBER.
BMPVOL: ADD T1,[OCT 464646470000] ;ADD ONE AND HANDLE CARRIES.
MOVE T2,T1 ;COPY TO BETTER AC.
AND T2,[OCT 606060600000] ;ISOLATE CARRY BITS.
LSH T2,-3 ;PUT THEM IN PLACE.
SUB T1,T2 ;FUDGE UP CARRIES.
AND T1,[OCT 171717170000] ;NOW HAVE BINARY NUMBER.
IOR T1,[OCT 202020200000] ;BACK TO SIXBIT.
RETURN ZERO ;TO SENDER...
;HERE TO TAKE THE NUMBER CONTAINED IN T1 AND CONVERT IT TO
;A TWO WORD QUANTITY STORED IN T1 AND T2.
MAKTWO: SKIPA P2,[^D10] ;SET RADIX TO TEN.
MAK2: MOVEI P2,10 ;SET THE RADIX TO EIGHT.
IDIVI T1,ZERO(P2) ;SLICE OFF A DIGIT.
HRLM T2,ZERO(PDP) ;STORE ON THE STACK.
JUMPN T1,.+3 ;JUMP IF NOT DONE.
MOVE T1,[SIXBIT "000000"] ;STUFF IN LEADING ZEROS.
SKIPA T2,T1 ;IN BOTH WORDS.
GOSUB MAK2+1 ;CONTINUE IF NOT DONE.
HLRZ T3,ZERO(PDP) ;PICK UP A DIGIT.
LSHC T1,6 ;MAKE ROOM FOR IT.
ADDI T2,'0'(T3) ;CONVERT AND ADD.
RETURN ZERO ;BACK TO SENDER.
;HERE WHEN THE GIG IS UP AND THE TRAP HAS SPRUNG.
TRAP: SAVE TRPPC ;STACK THE RETURN ADDRESS.
GOSUB STORE ;SAVE THE AC'S.
SAVE TRPCHN ;SAVE THE CHANNEL AND CLASS BITS.
GOSUB TRPSET ;RESET THE TRAP.
UNSAVE P3 ;GET THE BITS BACK.
HLRZ P2,P3 ;GET THE CLASS BITS.
IF.ON P2,ER.ICC,CTLC ;STOP ON CTRL/C.
IF.ON P2,ER.TLX,NOTIME ;JUMP IF TIME RAN OUT.
IF.ON P2,ER.ALL ;IF NOT OTHERS THEN
RETURN ZERO ;IGNORE THESE PROBLEMS.
TNO S,HUNG ;ONLY TYPE IT ONCE.
IF.ON S,NO.PRI,TRPCHK ;DON'T TYPE IF FORCED.
TRPTYP: HRRZS P3 ;SO WE CAN USE AS AN INDEX.
CAIGE P3,CF ;SKIP IF CCL FILE.
GOTO OTHDEV ;CHECK OTHERS.
SUBI P3,CF ;MAKE CHANNEL OFFSET FROM CF.
IMULI P3,CCLCNT ;PRODUCE OFFSET FROM CCLBLK.
MOVEI T2,CCLBLK(P3) ;PRODUCE PONTER.
SKIPA ;SKIP INTO GOODNESS.
OTHDEV: MOVEI T2,@[EXP OFILE,IFILE,UFDDEV,MFDDEV,DATDEV,HLPDEV]-OF(P3)
ENABLE TTY ;CLEAR THE TELETYPE.
GOSUB CRLF ;SKIP A LINE.
EME .STR,[ASCIZ "% "] ;GIVE WARNING SIGNAL.
GOSUB NAMIT ;NAME THE DEVICE.
IF.OFF P2,ER.OFL ;SKIP IF UNIT IS ON LINE.
PRINT ( has dropped off line.);TELL HIM UNIT ISN'T READY.
IF.OFF P2,ER.FUL ;SKIP IF UNIT IS NOT FULL.
PRINT ( is full.) ;SAY UNIT IS NO LONGER WITH US.
IF.OFF P2,ER.QEX ;ARE WE GOING OVER QUOTA.
PRINT ( quota being exceeded.);TELL HIM WE ARE GOING INTO OVERDRAW.
IF.OFF P2,ER.IDV ;SKIP IF DEVICE NEEDS NO ACTION.
PRINT ( is not ready!) ;TELL HIM WHAT IS WRONG.
TRPCHK: MOVEI T1,5 ;SLEEP TIME.
MOVE T2,[XWD 10,^D5000] ;LOAD HIBERNATE ARGS.
MME T1,.WAIT ;WAIT AWILE.
MME T1,.SLP ;SLEEP IF WAIT FAILS.
OFF OF,TTY ;TURN GOING TO TTY OFF.
GOSUB CHKOPR ;CHECK FOR A COMMAND.
MOVE OF,OFILE+MOD ;FIX THE MOD BITS.
RETURN ZERO ;TRY AGAIN.
;HERE WHEN THIS USER'S RUN TIME LIMIT IS ALMOST EXCEEDED.
NOTIME: XCT CRLF ;SKIP A LINE.
PRINT (***Run time limit almost exceeded)
GOTO STOPIT ;SAVE THE FILE.
;HERE TO ENABLE US FOR DEVICE AND APR TRAPS.
;THE TRAPS THAT WE WILL CATCH ARE AS FOLLOWS
;FOR THE APR:
; PDL OVERFLOW.
; REFERENCE TO NXM.
; MEMORY PROTECTION VIOLATION.
;FOR DEVICES:
; DEVICE NOT READY.
; QUOTA BEING EXCEEDED ON DISK.
; DISK UNIT GOING OFF LINE.
; DISK UNIT BECOMING FULL.
TRPSET: MOVEI T1,APRTRP ;APR TRAP LOCATION.
MOVEM T1,.JBAPR ;PLACE TO TRAP TO.
MOVEI T1,REP!PDL!MPV!NXM ;THINGS TO TRAP ON.
MME T1,.ENB ;ENABLE THE TRAPS.
MOVEI T1,TRPBLK ;GET POINTER TO BLOCK.
MOVEM T1,.JBINT ;SAVE SO EXEC WILL KNOW.
MOVE T1,[XWD 4,TRAP] ;BLOCK LENGTH AND TRAP LOC.
MOVEM T1,TRPBLK ;SAVE IN BLOCK.
MOVE T1,[XWD 400000,ER.ALL] ;DON'T TYPE MESSAGES AND CLASS BITS.
MOVEM T1,TRPBLK+1 ;SAVE IN BLOCK.
SETZM TRPPC ;CLEAR PC WORD TO ALLOW MULTIPLE TRAPS.
SETZM TRPCHN ;CLEAR CHANNEL NUMBER.
RETURN ZERO ;AWAY...
;HERE FOR AN INPUT ERROR FROM THE LAST INPUT MME.
LKIERR: IF.ON T1,E.HAD,HADERR ;JUMP IF HARD DEVICE ERROR.
IF.ON T1,E.IOB,BLKERR ;JUMP IF USER ERROR.
IF.ON T1,E.LOK ;MAKE SURE THERE IS AN ERROR.
GOSUB ABORT ;ELSE NO OTHER REASON TO BE HERE.
BRANCH WLDDEV,<DSKERR,IOERR,IOERR,IOERR> ;BRANCH ON DEVICE TYPE.
DSKERR: MOVEI P1,[ASCIZ "% "] ;IF IN A WILD CARD RUN.
IF.ON IF,WILD ;TEST THE WILD BITS.
MOVEI P1,[ASCIZ "? "] ;FATAL ERROR.
HRRZI T1,2 ;PROTECTION FAILURE CODE.
HRRM T1,IFILE+EXT ;SET THE ERROR CODE.
GOSUB STORE ;SAVE THE AC'S.
MOVE P4,IFILE+MOD ;GET THE MOD BITS.
OFF P4,WILD ;TURN OFF WILD BITS.
MOVEI SIDE,IFILE ;INDEX TO DATA.
GOSUB TYPEIT ;PRINT DEV:NAME.EXT[P,PN].
IF.OFF IF,WILD,ERREXT ;JUMP IF FATAL.
RETURN ZERO ;ELSE RETURN.
;HERE ON AN APR TRAP. THE TRAPS THAT ARE DETECTED ARE
;PDL OVERFLOW, MEMORY PROTECTION VIOLATION, AND REFERENCES TO
;NON-EXISTENT MEMORY. A MESSAGE IS TYPE TO TELL THE CAUSE
;THE PROBLEM IS CLEARED AND DDT IS CALLED IF IT IS HERE, ELSE
;WE GO TO ABORT. NOTE THE AC'S ARE SAVED IN 'AC'.
APRTRP: MOVEM 17,AC+17 ;SAVE AC 17.
HRRZI 17,AC ;XWD FOR BLT.
BLT 17,AC+16 ;SAVE THE AC'S.
ENABLE TTY ;CLEAR THE TELTYPE.
MOVE T1,.JBCNI ;GET THE APR FLAGS.
IF.OFF T1,PDL ;SKIP IF NOT PDL OVERFLOW.
MOVE PDP,[IOWD TMPLEN,TMPLST];GET A NEW POINTER.
SAVE .JBTPC ;SAVE PLACE OF ERROR.
AOS ZERO(PDP) ;SO ABORT WILL DO GOOD THINGS.
XCT CRLF ;SKIP A LINE.
IF.OFF T1,PDL ;WAS IT PDL OVERFLOW.
EME .STR,[ASCIZ "***Push-down list overflow"]
IF.OFF T1,MPV ;MEMORY PROTECTION VIOLATION.
EME .STR,[ASCIZ "***Memory protection violation"]
IF.OFF T1,NXM ;REFERENCE TO NON-EXISTENT MEMORY.
EME .STR,[ASCIZ "***Non-existent memory referenced"]
IF.ON T1,PDL!MPV!NXM ;IF NONE OF THESE REAL BUG.
GOTO ABORT1 ;SO BUMB.
EME .STR,[ASCIZ " at "] ;TELL HIM WHERE.
MOVE T2,.JBTPC ;GET THE LOCATION OF THE TRAP.
JSP P4,OCTOUT ;PRINT IT.
XCT CRLF ;SKIP A LINE.
MOVEI T1,REP!PDL!NXM!MPV ;BITS TO REENABLE.
MME T1,.ENB ;ENABLE IT AGAIN.
SKIPE T1,.JBDDT ;SKIP IF NO DDT.
GOTO CALDDT ;ELSE GET IT HERE.
GOTO NTHERE ;ELSE START OVER.
USE DATA
BSS TMPLST,TMPLEN ;TEMPORARY STACK.
USE CODE
;HERE TO CHECK FOR AN OPERATOR COMMAND WHILE WE ARE RUNNING.
CHKOPR: IF.ON OF,TTY ;SKIP IF GOING TO TTY.
EME .SKP,ZERO ;SKIP ON INPUT REQUEST.
RETURN ZERO ;RETURN IF NOTHING.
GOSUB STORE ;SAVE THE AC'S.
SAVE S ;SAVE THE STATUS REGISTER.
MOVE P1,[XWD -RUNLEN,RUNTAB] ;POINTER TO COMMAND TABLE.
MOVEI P2,RUNDIS ;POINTER TO DISPATCH TABLE.
MOVSI S,(BAD) ;SO BAD CHARACTERS RETURN.
SAVE [OPRRET] ;TO GET BACK HERE.
GOTO UNIMAT ;READ THE COMAMND.
OPRRET: SKIPA T1,[NOP] ;LOAD A NOP FOR ILLEGAL COMMAND.
MOVE T1,[TRZ S,HUNG] ;TO TURN OFF HUNG DEVICE BIT.
UNSAVE S ;RESTORE THE STATUS REGISTER.
XCT T1 ;DO NOTHING OR SOMETHING.
EME .CLR,ZERO ;CLEAR THE BUFFERS.
RETURN ZERO ;BACK TO CALLER.
;HERE ON A RUNTIME DDT OR DEBUG COMMAND.
RUNDDT: SKIPN T1,.JBDDT ;IS DDT LOADED.
GOTO BADRUN ;NO...
GOTO DDTCAL ;CALL DDT.
;HERE ON A RUNTIME WHAT COMMAND.
RUNWHT: GOSUB STAT ;TELL GOOD THINGS.
SKIPA ;SKIP INTO GOODNESS.
RUNFIL: GOSUB CRLF ;SKIP A LINE.
SETZM P4 ;CLEAR A REGISTER.
MOVEI SIDE,OFILE ;POINTER TO THINGS.
EME .STR,[ASCIZ "Out= "] ;TELL OUTPUT COMING.
GOSUB TYPNAM ;TYPE THE NAME.
GOSUB CRLF ;SKIP A LINE.
MOVEI SIDE,IFILE ;POINTER TO INPUT THINGS.
EME .STR,[ASCIZ "In= "] ;TELL INPUT COMING.
GOSUB TYPNAM ;TYPE THE NAME.
AOS ZERO(PDP) ;FOR A SKIP RETURN.
GOTO CRLF ;SKIP A LINE AND EXIT.
;HERE ON A RUNTIME PAUSE COMMAND.
PAUSE: GOSUB CRLF ;SKIP A LINE.
EME .STR,[ASCIZ "***Job halted"] ;TELL WHAT HE DID.
MME ONE,.TERM ;STOP...
RETURN ONE ;SKIP RETURN.
;HERE ON A LEGAL BUT BAD RUNTIME COMMAND.
BADRUN: PRINT (What?) ;COMPLAIN.
EME .CH,[EXP 12] ;SKIP A LINE.
RETURN ZERO ;RETURN.
;HERE TO GET THE RIGHT CONVERSION TABLES INTO
;CORE.
GETTAB: SKIPN DFFLG ;IS DATA FILE OPEN.
GOSUB GETTM0 ;NO OPEN IT UP.
HRL T3,T1 ;GET THE INPUT INDEX.
HRR T3,T2 ;GET THE OUTPUT INDEX.
CAMN T3,DFPTR ;SKIP IF NOT THE ONES WE HAVE.
RETURN ZERO ;RETURN IF THEY ARE.
MOVEM T3,DFPTR ;SAVE FOR NEXT TIME.
MOVE T3,FPTR(T1) ;GET BLOCK NUMBER AND WORD COUNT.
USETI DF,ZERO(T3) ;SELECT A BLOCK.
HRRI T3,TAB1-1 ;SET UP IOWD.
GOSUB REDTAB ;COPY TABLE INTO CORE.
MOVE T3,FPTR(T2) ;GET BLOCK NUMBER AND WORD COUNT.
USETI DF,ZERO(T3) ;DIAL A BLOCK.
HRRI T3,TAB2-1 ;SET UP IOWD.
GOSUB REDTAB ;GET THE SECOND TABLE.
TABGEN: HRLZI T3,-^D256 ;SET LENGTH OF TABLES.
TG0: HLRZ CH,TAB1(T3) ;GET A TABLE ENTRY.
IF.OFF CH,NEC,TG2 ;JUMP IF GOOD CHARACTER.
TG1: MOVEI CH,"\" ;GET A BAD CHARACTER.
HRRZ CH,TAB2(CH) ;CONVERT TO OUTPUT SET.
ON CH,NEC ;NOTE THAT IT IS BAD.
GOTO TG3 ;SAVE IT.
TG2: HRRZ CH,TAB2(CH) ;CONVERT A GOOD CHARACTER.
IF.ON CH,NEC,TG1 ;JUMP IF A BAD CONVERSION.
TG3: HRRM CH,TAB1(T3) ;REPLACE IN FIRST TABLE.
AOBJN T3,TG0 ;CONTINUE LOOP.
RETURN ZERO ;BACK TO CALLER.
;HERE TO READ A CONVERSION TABLE INTO
;CORE.
REDTAB: MOVEM T3,CTRL ;SAVE IOWD WORD.
SETZM CTRL+1 ;SET TERMINATOR.
DEVOP IN,DF,CTRL ;READ THE TABLE INTO PLACE.
RETURN ZERO ;PERFECT.
MOVEI P1,[ASCIZ "? Error reading data file."]
GOTO CLEAR ;BOMB OFF.
;HERE TO SET UP THE NAME OF THE FILE THAT HOLDS
;THE CONVERSION FILES.
GETTNM: SKIPN T1,IFILE+DEVICE ;IS THERE A DEVICE.
MOVSI T1,'DSK' ;NO USE DSK.
MOVEM T1,DATDEV+1 ;SAVE THE DEVICE.
SKIPN T1,IFILE+NAME ;IS THERE A NAME.
GOTO NOTAB ;NO SO ERROR.
MOVEM T1,DATFIL ;SAVE HIS NAME.
MOVE T1,IFILE+EXT ;GET THE EXTENSION.
MOVEM T1,DATFIL+1 ;SAVE THE EXTENSION.
MOVE T1,IFILE+PPN ;GET PPN IF THERE.
MOVEM T1,DATFIL+3 ;SAVE IT.
GOSUB LOOK ;SEE IF FILE IS THERE.
GOTO NOTAB ;CAN'T FIND IT.
GOTO NTHERE ;START ALL OVER.
;HERE TO SEE IF THE DATA FILE IS AROUND. TRY WHAT EVER
;IS IN THE PARAMETER AREA FIRST AND THEN TRY "DSK:CHANGE.DAT".
GETTM0: GOSUB LOOK ;TRY WHAT'S THERE FIRST.
SKIPA ;NO GOOD.
RETURN ZERO ;FOUND IT.
MOVSI T3,'DSK' ;TRY DISK.
MOVEM T3,DATDEV+1 ;SAVE THE DEVICE.
MOVE T3,[SIXBIT "CHANGE"] ;TRY "CHANGE.DAT".
MOVEM T3,DATFIL ;SAVE THE NAME.
MOVSI T3,'DAT' ;GET A DEFAULT EXTENSION.
MOVEM T3,DATFIL+1 ;SAVE THE EXTENSION.
SETZM DATFIL+3 ;SPECIFIY THIS PPN.
GOSUB LOOK ;SEE IF THERE NOW.
GOTO NOTAB ;YOU LOOSE.
RETURN ZERO ;MADE IT.
LOOK: OPEN DF,DATDEV ;INIT THE DEVICE.
RETURN ZERO ;ERROR RETURN.
LOOKUP DF,DATFIL ;GET THE FILE.
RETURN ZERO ;ERROR RETURN.
SETZM DFPTR ;CLEAR POINTER.
SETOM DFFLG ;FLAG WE HAVE FILE.
RETURN ONE ;BACK TO CALLER.
SUBTTL *** HELP SUPPLIED HERE ***
COMMENT #
Commands:
DATA Specifiy the name of the data file to be used as in
a normal command string "DATA=DEV:FILE.EXT[P,PN]".
MAKE Call TABLE.SAV to create the conversion tables.
EXIT Terminate the program.
HELP This little message.
BYE Call LOGOUT into core and execute it.
RETAIN Allows the user to accumulate commands.
RUN Perform the current command string.
ERASE Erase retained commands.
PRINT Print the current command string.
Switches:
Buffers:x Use x buffers.
Advance:x Advance x files before operation.
Backspace:x Backspace the tape x files before operation.
Block:x Set blocking factor to x.
Record:x Set record size or size of largest block to x.
Density:arg Set mag-tape density to arg [arg=200,556,800].
Retain Retain the following commands.
Run Perform the current command and retain it.
Help These few hints.
Label:arg Set label type as described below for mag-tape.
Mode:arg Set file character set as described below.
Parity:arg Set mag-tape parity [odd=odd, even=even, default=odd].
Password:arg Set the password for GE labels.
Reel:x Set serial number in labels that have this feature.
* Industry Initialize for industry compatible 9-channel tape.
* Scan Scan tape for file named.
* Error Don't ignore checksum and parity errors.
* Span Records cross blocks [implied if "/block:0"].
* Rewind:arg Rewind tapes [arg=before, after, always, omitt]
* Unload Unload tape after operation.
* Tell Type file names on a wild card search.
* List List the device directory.
* Flist List the device directory [file names only].
* Header Print headers on the line printer.
* Crlf Ascii file has crlf's.
Note: To turn a switch off concatenate "no" with the switch.
Switches flaged with an (*) have this feature.
/Label - switch modifiers:
None Mag-tape has no labels just data [default].
Mine Special labels for DECsystem-10.
Digital Process labels as standard DIGITAL labels.
Burroughs Process labels as standard BURROUGHS labels.
IBM Process labels as standard IBM labels.
GE635 Process labels as standard GE-635 labels.
Note: Labels are written in the mode specified except for IBM
and GE-635 labels. IBM labels are written in BCD for
7-track drives and EBCDIC for 9-track drives. GE-635
labels are always written in GE-BCD.
/Mode - switch modifiers:
ASCII File character set is 7-bit ASCII.
HPASCII File character set is 8-bit ASCII.
GEASCII File character set is 9-bit ASCII.
IMAGE File is read and written as 36-bit words.
SIXBIT File character set is SIXBIT.
FIXSIX File character set is SIXBIT with no control words.
BCL File character set is BCL.
BCD File character set is BCD.
CDC File character set is cdc bcd.
GEBCD File character set is GE-BCD.
HONBCD File character set is HONEYWELL BCD.
EBCDIC File character set is fixed EBCDIC.
VEBCDIC File character set is variable EBCDIC.
The end of the input record is determined by the mode of the
input file as described below:
ASCII Terminated by a carriage-return character or record count.
SIXBIT Determinted by the header word in front of each record.
FIXSIX Always copies the number of bytes specified by the record size.
BCL Always copies the number of bytes specified by the record size.
BCD Always copies the number of bytes specified by the record size.
EBCDIC [Fixed] Always copies the number of bytes specified by the
record size.
EBCDIC [Variable] Determined by the header word in front of each
record.
In general all commands may be abbreviated to any number
of characters that will allow that command to be unique. However
no more then six characters are checked for validity in any of
the commands.
The character "*" may be used to denote a wild card for files
on mag-tape, disk, or dectape. The character "@" denotes a
command file which change will read for commands. If only
an altmode is typed change will enter dialog mode.#
;HERE ON A HELP SWITCH OR HELP OR EXPLAIN COMMAND.
SW.H: MOVE WD,PRGNAM ;GET THE DEFAULT.
IF.OFF S,COL ;JUMP IF NO ARGUMENT.
GOSUB GETSIX ;GET A HELP FILE NAME.
MOVEM WD,HFILE ;SAVE THE NAME.
HELP1: IF.ON S,EOL ;SKIP IF END OF COMMAND.
GOSUB GETONE ;SCAN TO END OF LINE.
IF.OFF S,EOL,HELP1 ;FIND END OF LINE.
OPEN HF,HLPDEV ;OPEN THE DEVICE.
GOTO NOHELP ;CAN'T PROVIDE HELP.
LOOKUP HF,HFILE ;OPEN THE FILE.
GOTO NOHELP ;CAN'T PROVIDE HELP.
MOVE T1,.JBFF ;GET FIRST FREE.
SUBI T1,ONE ;TO SET UP IOWD.
HRRM T1,HFCTL ;SET CTRL WORD.
ADDI T1,201 ;LAST LOCATION NEEDED.
IORI T1,1777 ;TO A K BOUNDARY.
CAMG T1,.JBREL ;SKIP IF NEED MORE CORE.
GOTO .+3 ;O.K. LIKE IT IS.
MME T1,.CORE ;GET MORE CORE.
GOTO NOCORE ;NO CORE YOU LOOSE.
GOSUB CRLF ;SKIP A LINE.
HELP2: DEVOP IN,HF,HFCTL ;READ A BLOCK.
GOTO HELP3 ;CONTINUE ON.
GETSTS HF,T1 ;GET THE DEVICE STATUS.
IF.OFF T1,E.ERR!E.EOF,HELP3 ;JUMP IF NO ERROR.
GOTO NTHERE ;ON ANY ERROR CALL IT EOF.
HELP3: HRRZ T1,HFCTL ;GET POINTER TO BUFFER.
SETZM 201(T1) ;FOR ASCIZ.
EME .STR,ONE(T1) ;SEND THE BUFFER.
GOTO HELP2 ;CONTINUE ON.
EXP HF
HLPDEV: EXP DMP
SIXBIT "SYS"
BSS ONE
USE DATA
HFILE: SIXBIT "NAME"
SIXBIT "HLP"
BSS 4
HFCTL: IOWD 200,ZERO
BSS ONE
USE CODE
SUBTTL *** TABLES ***
CH.CHR: XWD "@",ATS!SOM ;DELIMITER TABLE.
XWD ":",COL!SOM
XWD ".",PER!SOM
XWD "[",BRK!SOM
XWD "/",SLH!SOM
XWD "_",IO!SOM
XWD "=",IO!SOM
XWD 15,EOL!SOM
XWD 33,EOL!SPC!ALT!SOM
XWD 175,EOL!SPC!ALT!SOM
XWD 176,EOL!SPC!ALT!SOM
CH.CNT==.-CH.CHR
COMTAB: <SIXBIT "MAKE"> ;COMMAND TABLE.
<SIXBIT "DIALOG">
<SIXBIT "TERMINATE">
<SIXBIT "BYE">
<SIXBIT "EXIT">
<SIXBIT "DDT">
<SIXBIT "DEBUGGER">
<SIXBIT "HELP">
<SIXBIT "EXPLAIN">
<SIXBIT "RETAIN">
<SIXBIT "ERASE">
<SIXBIT "RUN">
<SIXBIT "PERFORM">
<SIXBIT "PRINT">
COMCNT==.-COMTAB
COMDIS: XWD ZERO,CRETAB ;COMMAND DISPATCH TABLE.
XWD ZERO,DIALOG
XWD ZERO,STOP
XWD ZERO,LOGOFF
XWD ZERO,STOP
XWD ZERO,DEBUG
XWD ZERO,DEBUG
XWD ZERO,SW.H
XWD ZERO,SW.H
XWD ZERO,RETAIN
XWD ZERO,ERASE
XWD ZERO,PERFOR
XWD ZERO,PERFOR
XWD ZERO,XPRINT
XWD ZERO,NOTCOM
M.TAB: <SIXBIT "ASCII"> ;TABLE TO SET CONVERSION INDEX.
<SIXBIT "HPASCII">
<SIXBIT "GEASCII">
<SIXBIT "IMAGE">
<SIXBIT "OCTAL">
<SIXBIT "SIXBIT">
<SIXBIT "FIXSIX">
<SIXBIT "BCL">
<SIXBIT "BCD">
<SIXBIT "CDC">
<SIXBIT "GEBCD">
<SIXBIT "HONBCD">
<SIXBIT "EBCDIC">
<SIXBIT "VEBCDIC">
M.CNT==.-M.TAB
M.DIS: XWD ZERO,M.RET ;DISPATCH TABLE FOR MODE.
XWD ZERO,FOMERR
NWUTAB: XWD ZERO,NOHEAD ;BITS FOR SWITCHES.
XWD ZERO,NOCRLF
XWD ZERO,UNLOAD
XWD ZERO,IND
XWD ZERO,NOERROR
XWD ZERO,SPAN
XWD ZERO,SCAN
NWUCNT==.-NWUTAB
LB.TAB: <SIXBIT "NONE"> ;LABEL TYPE TABLE.
<SIXBIT "MINE">
<SIXBIT "BURROUGHS">
<SIXBIT "DIGITAL">
<SIXBIT "DEC">
<SIXBIT "IBM">
<SIXBIT "GE635">
LB.CNT==.-LB.TAB
LB.DIS: XWD ZERO,L.RET ;DISPATCH FOR LABELS.
XWD ZERO,FOMERR
LB.TYP: XWD RET0,LB.NON ;LABEL DISPATCH TABLE.
XWD LB.OMI,LB.IMI
XWD LB.OBL,LB.IBL
XWD LB.OCL,LB.ICL
XWD LB.OCL,LB.ICL
XWD LB.OBM,LB.IBM
XWD LB.OGE,LB.IGE
SW.TAB: <SIXBIT "NOHEADER"> ;SWITCH TABLE.
<SIXBIT "NOCRLF">
<SIXBIT "UNLOAD">
<SIXBIT "INDUSTRY">
<SIXBIT "NOERROR">
<SIXBIT "SPAN">
<SIXBIT "SCAN">
<SIXBIT "HEADER">
<SIXBIT "CRLF">
<SIXBIT "NOUNLOAD">
<SIXBIT "NOINDUSTRY">
<SIXBIT "ERROR">
<SIXBIT "NOSPAN">
<SIXBIT "NOSCAN">
<SIXBIT "DENSITY">
<SIXBIT "LABEL">
<SIXBIT "MODE">
<SIXBIT "BLOCK">
<SIXBIT "BLKSIZE">
<SIXBIT "PARITY">
<SIXBIT "ADVANCE">
<SIXBIT "HELP">
<SIXBIT "RECORD">
<SIXBIT "REC">
<SIXBIT "RECSIZE">
<SIXBIT "REEL">
<SIXBIT "PASSWORD">
<SIXBIT "RETAIN">
<SIXBIT "RUN">
<SIXBIT "PERFORM">
<SIXBIT "EXPLAIN">
<SIXBIT "BUFFERS">
<SIXBIT "LIST">
<SIXBIT "NOLIST">
<SIXBIT "FLIST">
<SIXBIT "TELL">
<SIXBIT "NOTELL">
<SIXBIT "REWIND">
<SIXBIT "NOREWIND">
<SIXBIT "BACKSPACE">
SW.CNT==.-SW.TAB
SW.DIS: XWD ZERO,SW.NWU ;DISPATCH TABLE FOR SWITCHES.
XWD ZERO,SW.NWU
XWD ZERO,SW.NWU
XWD ZERO,SW.NWU
XWD ZERO,SW.NWU
XWD ZERO,SW.NWU
XWD ZERO,SW.NWU
XWD ZERO,SW.OFF
XWD ZERO,SW.OFF
XWD ZERO,SW.OFF
XWD ZERO,SW.OFF
XWD ZERO,SW.OFF
XWD ZERO,SW.OFF
XWD ZERO,SW.OFF
XWD ZERO,SW.D
XWD ZERO,SW.L
XWD ZERO,SW.M
XWD ZERO,SW.B
XWD ZERO,SW.B
XWD ZERO,SW.P
XWD ZERO,SW.A
XWD ZERO,SW.H
XWD ZERO,SW.R
XWD ZERO,SW.R
XWD ZERO,SW.R
XWD ZERO,SW.RL
XWD ZERO,SW.PW
XWD ZERO,SW.KEP
XWD ZERO,SW.GO
XWD ZERO,SW.GO
XWD ZERO,SW.H
XWD ZERO,SW.BUF
XWD ZERO,XLST
XWD ZERO,XNLST
XWD ZERO,XFLST
XWD ZERO,XTELL
XWD ZERO,XNTELL
XWD ZERO,REWIND
XWD ZERO,NOREW
XWD ZERO,SW.BK
XWD ZERO,IMPSW
REWTAB: <SIXBIT "AFTER"> ;REWIND SWITCH ARGUMENTS.
<SIXBIT "BEFORE">
<SIXBIT "ALWAYS">
<SIXBIT "OMITT">
REWCNT==.-REWTAB
REWDIS: XWD ZERO,REWRET ;DISPATCH TABLE FOR REWIND.
XWD ZERO,FOMERR
NORDIS: XWD ZERO,NOWRET ;DISPATCH TABLE FOR NOWIND.
XWD ZERO,FOMERR
REWBIT: XWD ZERO,AWIND ;BITS FOR REWIND OR NOWIND.
XWD ZERO,BWIND
XWD ZERO,AWIND!BWIND
XWD ZERO,AWIND!BWIND
PR.TAB: <SIXBIT "ODD"> ;PARITY TABLE.
<SIXBIT "EVEN">
PR.CNT==.-PR.TAB
PR.DIS: XWD ZERO,ODDRET ;DISPATCH FOR PARITY.
XWD ZERO,EVERET
XWD ZERO,FOMERR
DN.TAB: <SIXBIT "200"> ;DENSITY TABLE.
<SIXBIT "556">
<SIXBIT "800">
DN.CNT==.-DN.TAB
DN.DIS: XWD ZERO,D.RET ;DISPATCH TABLE FOR DENSITY.
XWD ZERO,FOMERR
E.TAB: <SIXBIT "DATA"> ;COMMANDS THAT USE = OR _.
E.CNT=.-E.TAB
E.DIS: XWD ZERO,E.RET ;DISPATCH TABLE FOR SPECIALS.
XWD ZERO,GETWOD
E.BIT: EXP DATA ;BITS TO SET FOR SPECIALS.
RUNTAB: <SIXBIT "DDT"> ;RUNTIME COMMANDS.
<SIXBIT "DEBUGGER">
<SIXBIT "WHAT">
<SIXBIT "FILES">
<SIXBIT "STOP">
<SIXBIT "PAUSE">
RUNLEN==.-RUNTAB
RUNDIS: XWD ZERO,RUNDDT ;RUNTIME DISPATCH TABLE.
XWD ZERO,RUNDDT
XWD ZERO,RUNWHT
XWD ZERO,RUNFIL
XWD ZERO,STOPIT
XWD ZERO,PAUSE
XWD ZERO,BADRUN
USE DATA
BSS TAB1,^D256 ;CONVERSION TABLES.
BSS TAB2,^D256
BSS CTRL,TWO ;I/O LIST FOR DATA FILE.
BSS IVBCNT,ONE ;EBCDIC BLOCK COUNT.
BSS OSIZE,ONE ;SIZE OF OUTPUT RCORD.
BSS OBSIZE,ONE ;SIZE OF OUTPUT BLOCK.
BSS OT0TMP,ONE ;WORD FOR OCTAL.
BSS OT1TMP,ONE ;LINE COUNT FOR OCTAL.
BSS DFPTR,ONE ;INDEX POINTERS FOR TABLES.
BSS DFFLG,ONE ;NON-ZERO IF DATA FILE IS OPEN.
EXP DF ;CHANNEL NUMBER.
DATDEV: XWD ZERO,DMP ;DEVICE FOR DATA FILE.
SIXBIT "SYS"
BSS ONE
DATFIL: SIXBIT "CHANGE" ;NAME OF DATA FILE.
SIXBIT "DAT"
BSS TWO
DMPDEV: XWD ZERO,DMP ;DUMP OF US TO DISK.
SIXBIT "DSK" ;ON DEVICE DISK.
BSS ONE
DMPFIL: SIXBIT "NAME" ;NAME TO DUMP TO.
SIXBIT "DMP"
BSS TWO
DMPLST: IOWD SYSNAM+4-AC,AC
XWD ZERO,136
BSS ONE
USE CODE
LOGPRG: SIXBIT "SYS" ;FOR RUN ON LOGOUT.
SIXBIT "LOGOUT"
BSS 4
YESTAB: <SIXBIT "YES"> ;USED FOR YES NO REPLIES.
<SIXBIT "NO">
YESCNT==.-YESTAB
YESDIS: XWD ZERO,YESRET ;RETURNS FOR YES NO REPLIES.
XWD ZERO,NORET
XWD ZERO,XYNRET
;TABLE OF MESSAGES THAT ARE PUT ON THE TRAILING
;HEADER.
ENDTAB: [SIXBIT "END "]
[SIXBIT "FINIS "]
[SIXBIT "TERMINUS "]
[SIXBIT "CEASE "]
[SIXBIT "HALT "]
[SIXBIT "STOP "]
[SIXBIT "CLOSE "]
[SIXBIT "CONCLUDE "]
[SIXBIT "ARREST "]
[SIXBIT "CHECKMATE "]
[SIXBIT "TERMINATE "]
[SIXBIT "DIE "]
[SIXBIT "COOL_IT "]
[SIXBIT "REST "]
[SIXBIT "CRASH "]
[SIXBIT "THE_END "]
[SIXBIT "STOP_THE_CPU"]
[SIXBIT "BREAK "]
[SIXBIT "STOP_CODE "]
[SIXBIT "RIGHT_ON "]
[SIXBIT "TRASH "]
ENDCNT==.-ENDTAB
;CHARACTER TABLE FOR LINE PRINTER HEADINGS.
CHRTAB: BYTE (5) 00,00,00,00,00,00,00 ; SP
BYTE (5) 04,04,04,04,04,00,04 ; !
BYTE (5) 12,12,00,00,00,00,00 ; "
BYTE (5) 12,12,37,12,37,12,12 ; #
BYTE (5) 04,37,24,37,05,37,04 ; $
BYTE (5) 31,31,02,04,10,23,23 ; %
BYTE (5) 10,24,10,24,23,22,15 ; &
BYTE (5) 06,02,00,00,00,00,00 ; '
BYTE (5) 04,10,20,20,20,10,04 ; (
BYTE (5) 04,02,01,01,01,02,04 ; )
BYTE (5) 00,25,16,33,16,25,00 ; *
BYTE (5) 00,04,04,37,04,04,00 ; +
BYTE (5) 00,00,00,00,00,14,04 ; ,
BYTE (5) 00,00,00,37,00,00,00 ; -
BYTE (5) 00,00,00,00,00,14,14 ; .
BYTE (5) 00,00,01,02,04,10,20 ; /
BYTE (5) 16,21,23,25,31,21,16 ; 0
BYTE (5) 04,14,04,04,04,04,16 ; 1
BYTE (5) 16,21,01,02,04,10,37 ; 2
BYTE (5) 16,21,01,02,01,21,16 ; 3
BYTE (5) 22,22,22,37,02,02,02 ; 4
BYTE (5) 37,20,34,01,01,21,16 ; 5
BYTE (5) 16,20,20,36,21,21,16 ; 6
BYTE (5) 37,01,01,02,04,10,20 ; 7
BYTE (5) 16,21,21,16,21,21,16 ; 8
BYTE (5) 16,21,21,17,01,01,16 ; 9
BYTE (5) 00,06,06,00,06,06,00 ; :
BYTE (5) 00,06,06,00,06,06,02 ; ;
BYTE (5) 02,04,10,20,10,04,02 ; <
BYTE (5) 00,00,37,00,37,00,00 ; =
BYTE (5) 10,04,02,01,02,04,10 ; >
BYTE (5) 16,21,01,02,04,00,04 ; ?
BYTE (5) 16,21,21,27,25,25,07 ; @
BYTE (5) 16,21,21,21,37,21,21 ; A
BYTE (5) 36,21,21,36,21,21,36 ; B
BYTE (5) 17,20,20,20,20,20,17 ; C
BYTE (5) 36,21,21,21,21,21,36 ; D
BYTE (5) 37,20,20,36,20,20,37 ; E
BYTE (5) 37,20,20,36,20,20,20 ; F
BYTE (5) 17,20,20,20,27,21,16 ; G
BYTE (5) 21,21,21,37,21,21,21 ; H
BYTE (5) 16,04,04,04,04,04,16 ; I
BYTE (5) 01,01,01,01,21,21,16 ; J
BYTE (5) 21,21,22,34,22,21,21 ; K
BYTE (5) 20,20,20,20,20,20,37 ; L
BYTE (5) 21,33,25,21,21,21,21 ; M
BYTE (5) 21,21,31,25,23,21,21 ; N
BYTE (5) 16,21,21,21,21,21,16 ; O
BYTE (5) 36,21,21,36,20,20,20 ; P
BYTE (5) 16,21,21,21,25,22,15 ; Q
BYTE (5) 36,21,21,36,24,22,21 ; R
BYTE (5) 17,20,20,16,01,01,36 ; S
BYTE (5) 37,04,04,04,04,04,04 ; T
BYTE (5) 21,21,21,21,21,21,37 ; U
BYTE (5) 21,21,21,21,21,12,04 ; V
BYTE (5) 21,21,21,21,25,33,21 ; W
BYTE (5) 21,21,12,04,12,21,21 ; X
BYTE (5) 21,21,12,04,04,04,04 ; Y
BYTE (5) 37,01,02,04,10,20,37 ; Z
BYTE (5) 14,10,10,10,10,10,14 ; [
BYTE (5) 00,00,20,10,04,02,01 ; \
BYTE (5) 06,02,02,02,02,02,06 ; ]
BYTE (5) 00,04,16,25,04,04,00 ; ^
BYTE (5) 00,00,00,00,00,00,00 ; SPACE USED IN MESSAGES.
;THE FOLLOWING TABLES ARE FOR THE CHARACTER SET MODES.
;THE MACRO "MTABLE" WILL SET UP THE POINTERS TO THE MODE
;DATA BLOCKS. WHILE THE MACRO "TABLE" WILL SET UP ALL THE
;DATA ABOUT A CERTIAN CHARACTER SET.
FTABLE -123456 ;MUST BE BEFORE WHAT FOLLOWS.
MTABLE <ASC,HPA,GEA,IMG,OCT,SIX,FIX,BCL,BCD,CDC,XBD,HBD,EBC,VEB>
TABLE ASCII,ASC,7,128,NOR!TAB
TABLE HPASCII,HPA,8,0,NOR!TAB
TABLE GEASCII,GEA,9,0,NOR!TAB
TABLE IMAGE,IMG,36,0,0
TABLE OCTAL,OCT,7,0,0
TABLE SIXBIT,SIX,6,64,NOR!6
TABLE FIXSIX,FIX,6,0,NOR!NIR
TABLE BCL,BCL,6,64,NOR!NIR
TABLE BCD,BCD,6,64,NOR!NIR
TABLE CDC,CDC,6,64,NOR!NIR
TABLE GEBCD,XBD,6,64,NOR!NIR
TABLE HONBCD,HBD,6,64,NOR!NIR
TABLE EBCDIC,EBC,8,256,NOR!NIR!TAB
TABLE VEBCDIC,VEB,8,0,NOR!EXW!TAB!4
END START