.TITLE FDCOPY - Floppy Diskette Copy .IDENT /V1.00/ .ENABL LC .SBTTL Program description ; ; ; This program provides a means of rapidly reading or writing of floppies to or from disk ; files followed by optional verification of the copied data. It is installed under a Task ; Name of ...FDC. The actual number of blocks copied may range from a minimum established ; by the symbol BLKCNT defined in the next section through a maximum equal to the floppy ; diskette size if copying to a disk file, or equal to either the file size or the floppy ; diskette size, whichever is smaller, if copying from a disk file. ; ; Command line syntax is: ; ; >FDC filspec=dev:[/SZ:nnnn][/VE] ! To copy from a floppy to a disk file ; -- OR -- ; >FDC dev:[/SZ:nnnn][/VE]=filspec ! To copy from a disk file to a floppy ; ; where: ; filspec = Any valid file specification for a disk file - may include device and/or ; UIC specifications; may also include a version specification, however, if ; any pre-existing file with an identical specification will be superseded. ; dev: = Any valid device specification for a floppy diskette drive. ; nnnn = The number of blocks to be copied to or from the floppy - this number will ; be assumed to be a decimal (base 10) number, even if it is not followed by ; an decimal point (optional), and must be less than or equal to the volume ; size as specified in Control Words 2 and 3 of the device's Unit Control ; Block (UCB). ; ; Note that both the verification selection switch (/VE) and the size specification switch ; (/SZ:nnnn) are optional. If the verification selection switch is absent, no verification ; is performed; if the size selection switch is absent, the entire volume is copied as spe- ; cified in CW2 and CW3 of the UCB. ; ; While both switches are shown appended to the floppy diskette drive specification, each ; switch may actually appear either there or appended to the disk file specification. ; ;------------------------------------------------------------------------------------------- ; ; In addition to reporting various error conditions it detects to the User via TI:, this ; program also uses the Exit Status word to inform any parent task of its success or lack ; thereof. The following table shows how the Exit Status word is used: ; ; High Low ; Word Byte Byte Indication ; ------ ---- ---- -------------------------------------------- ; ; 000001 000 001 EX$SUC - Unqualified success! ; 000000 000 000 EX$WAR - Warning, caused by some internally ; detected discrepancy which does not ; preclude executing the command is- ; sued to it, such as specifying a ; switch more than once. ; 000002 000 002 EX$ERR - Fatal error, caused by some inter- ; nally detected error which prevents ; executing the command issued to it ; without totally aborting the Task, ; such as specifying more blocks than ; the floppy diskette can hold. ; 000004 000 004 EX$SEV - Severe error, caused by either a ; TRAP instruction (executed when an ; internal inconsistency is detected) ; or by some other unforseen event ; which prevents the Task from reach- ; ing completion. ; 000nnn 000 nnn I/O error - nnn is in the range 377 through ; 200 (-1 through -128.) and is the ; I/O error code. ; 177xnn 377 ynn Executive Directive error - xnn (9 bits, 777 ; through 600) and ynn (8 bits, 377 ; through 200) are the Directive error ; code (-1 through -128). .PAGE .SBTTL Symbol Definitions ; ; TAB = 011 ; ASCII Code for Character LF = 012 ; ASCII Code for Character ; BIT00 = 000001 ; Bit masks BIT01 = 000002 BIT05 = 000040 BIT06 = 000100 BIT07 = 000200 BIT08 = 000400 BIT09 = 001000 BIT10 = 002000 BIT11 = 004000 BIT12 = 010000 BIT15 = 100000 ; SIZESW = BIT00 ; Status flag - /SZ specified VFYSW = BIT01 ; Status flag - /VE specified HLPSWI = BIT05 ; Status flag - /HELP specified RDFLOP = BIT06 ; Status flag - Copy floppy diskette to disk file WRFLOP = BIT07 ; Status flag - Copy disk file to floppy diskette SIZE2X = BIT08 ; Status flag - /SZ specified > once MATCH = BIT09 ; Status flag - Multiple /SZ switches specify dif- ; ferent block counts TOOSML = BIT10 ; Status flag - Block count specified in /SZ below ; minimum size VFY2X = BIT11 ; Status flag - /VE specified > once BDUNIT = BIT12 ; Status flag - Illegal character in Unit Number ERROR = BIT15 ; Status flag - Comprehensive error indication ; FTLFLG = BDUNIT!TOOSML!MATCH ; Fatal errors (status flags) ; BLKCNT = 41. ; Number of blocks to be read from / written to the ; floppy for all QIO requests except possibly ; the last one (if the number of blocks to be ; copied is an exact multiple of this value, ; this value is used for all QIO requests) BLKSIZ = 512. ; Size of a Logical Block ; ;------------------------------------------------------------------------------------------- ; .MCALL UCBDF$ ; UCBDF$ ; Define offsets & bits used in Unit Control Blocks .PAGE .SBTTL State Tables for Table-Driven Parser ; ; .MCALL ISTAT$,STATE$,TRAN$ ; $RONLY = 0 ; ISTAT$ STATBL,KEYTBL ; ;=========================================================================================== ; STATE$ ; MCR Command Line TRAN$ "FDC" ; Task invocation must be by "FDC" ; ;------------------------------------------------------------------------------------------- ; STATE$ TRAN$ !DEVICE,TSTFIL,SETDEV ; See if a device specification is present TRAN$ !DSKFIL,RDFLEQ,REINIT ; If not, a file specification is required TRAN$ <'/>,HELPSW,ABBROK ; Special case if / leads off TRAN$ $EOS,$EXIT ; If nothing more, show ID STATE$ HELPSW TRAN$ "HELP",ENDCML,,HLPSWI,FLAGS ; If "HE", "HEL", or "HELP" follows, print help ; message and exit STATE$ TSTFIL TRAN$ !DSKFIL,RDFLEQ,SETFIL ; See if UIC and/or file specification follows the ; device specification - if yes, continue be- ; low TRAN$ $LAMDA ; If not, no problem STATE$ WRFLEQ TRAN$ !SWTCHS,WRFLEQ ; Check for switches TRAN$ <'=>,,INILUN ; Equals sign separates input from output STATE$ TRAN$ !DEVICE,INPFIL,SETDEV ; Input file may include device specification . . . TRAN$ $LAMDA ; . . . but doesn't have to STATE$ INPFIL TRAN$ !DSKFIL,ENDMCR,SETFIL,WRFLOP,FLAGS ; File specification must follow ; ;------------------------------------------------------------------------------------------- ; STATE$ RDFLEQ TRAN$ !SWTCHS,RDFLEQ ; Check for switches TRAN$ <'=> ; Equals sign separates input from output STATE$ TRAN$ !DEVICE,,INILUN,RDFLOP,FLAGS ; Device specification must follow ; ;------------------------------------------------------------------------------------------- ; STATE$ ENDMCR TRAN$ !SWTCHS,ENDMCR ; Check for switches TRAN$ $LAMDA ; If none present, that's OK STATE$ ENDCML TRAN$ $EOS,$EXIT ; Nothing else may be present ; ;=========================================================================================== ; STATE$ SWTCHS TRAN$ <'/> ; All switches are introduced by a virgule STATE$ TRAN$ "VE",$EXIT,VFYCHK,VFYSW,FLAGS ; "VE" is the abbreviation for "VERIFY" - takes no ; arguments TRAN$ "SZ",,SIZCHK,SIZESW,FLAGS ; "SZ" is the abbreviation for "SIZE" STATE$ TRAN$ <':> ; Switch argument is introduced by a colon STATE$ TRAN$ $DNUMB,,RWSIZE ; Number of blocks to be transferred STATE$ TRAN$ <'.>,$EXIT ; May be followed by a decimal point TRAN$ $LAMDA,$EXIT ; But if it isn't, don't consider it an error ; ;------------------------------------------------------------------------------------------- ; STATE$ DSKFIL TRAN$ !UFDSPC,UFDOK,FSPUFD ; Check for optional User File Directory (UFD) spe- TRAN$ $LAMDA ; cification STATE$ UFDOK TRAN$ !NMTPVR,FINLCK,FSPNTV ; Next are file name, file type, and file version - TRAN$ $LAMDA ; all or part of which is optional STATE$ FINLCK TRAN$ $LAMDA,$EXIT,FSPCHK ; Make sure at least one of the above is present ; ;------------------------------------------------------------------------------------------- ; STATE$ DEVICE TRAN$ !DEVTYP,,DEVNAM ; Device specification begins with 2-character De- ; vice Mnemonic STATE$ TRAN$ $NUMBR,DEVEND,DVUNIT ; Mnemonic is usually followed by a Unit Number TRAN$ $LAMDA ; OK if absent (default to Unit 0) STATE$ DEVEND TRAN$ <':>,$EXIT ; Device specification must be terminated with a ; colon ; ;------------------------------------------------------------------------------------------- ; STATE$ DEVTYP TRAN$ $ALPHA ; Device Mnemonic begins with an alphabetic charac- ; ter STATE$ TRAN$ $ALPHA,$EXIT ; Device specification ends with second alphabetic ; character, with no other intervening charac- ; ters ; ;------------------------------------------------------------------------------------------- ; STATE$ UFDSPC TRAN$ '[ ; UFD specification begins with left bracket STATE$ TRAN$ $NUMBR ; Group Number follows STATE$ TRAN$ <',> ; A comma is the only valid separator STATE$ TRAN$ $NUMBR ; Next is a Member Number STATE$ TRAN$ '],$EXIT ; UFD specification is terminated by a right ; bracket ; ;------------------------------------------------------------------------------------------- ; STATE$ NMTPVR TRAN$ $STRNG,FNMFTP ; File name is an alphanumeric string TRAN$ <'.>,FILTYP ; If absent, <.filtyp> is possible TRAN$ <';>,FILVER ; If also absent, <;filver> needed STATE$ FNMFTP TRAN$ <'.>,FILTYP ; A period separates file name from file ; type TRAN$ $LAMDA,TYPVER ; If absent, no problem, but precludes ; presence of file type STATE$ FILTYP TRAN$ $STRNG,TYPVER ; File type is an alphanumeric string TRAN$ $LAMDA ; If absent, not wrong STATE$ TYPVER TRAN$ <';>,FILVER ; A semicolon separates file name or file ; type from file version TRAN$ $LAMDA,$EXIT ; If missing, OK, but precludes presence of ; version number STATE$ FILVER TRAN$ $NUMBR,$EXIT ; Version number is always last ; ;=========================================================================================== ; STATE$ ; ; .RADIX 10 .PAGE .SBTTL Executive Directives and locally defined MACROs ; ; .PSECT MACROS ; .MCALL ALUN$,EXST$,GLUN$,GMCR$,QIO$,QIOW$,WTSE$ ; ASNLN1: ALUN$ 1,TI ; Assign LUN 1 to User's terminal ASNLN2: ALUN$ 2 ; Assign LUN 2 to floppy diskette drive BYEBYE: EXST$ EX$SUC ; Terminate instruction execution for this Task LN2INF: GLUN$ 2,LUNBUF ; Get LUN information for floppy diskette drive DNTCAR = DV.UMD!DV.EXT ; Bits (User-mode diagnostics supported and extended ; 22-bit UNIBUS controller supported) that can ; be either 0 or 1 (don't care) DEVCW1 = DV.DIR!DV.MSD!DV.F11!DV.MNT ; Bits (directory {file-structured} device, mass ; storage device, device mountable as Files-11 ; device, and device mountable) that must be ; set (and by omission, those that must be ; clear, or at the very least, those we don't ; care what state they're in) GETMCR: GMCR$ ; Get MCR Command Line (if present) RDWRIT: QIO$ ,2,2,,FDSTAT ; Read data from / Write data to floppy diskette PAINTR: QIOW$ IO.WLB,1,1,,,, ; Display text string at User's terminal WTFLOP: WTSE$ 2 ; Wait for diskette read to complete ; .MCALL DIR$,WSIG$S ; ;=========================================================================================== ; .MACRO EXEDIR LABEL ; MACRO to record address of an Executive Directive ; and then to issue the Directive MOV #.,DIRADX ; Save address of next Directive in case it fails DIR$ #LABEL ; Issue Executive Directive .ENDM EXEDIR ; End of MACRO ; ;------------------------------------------------------------------------------------------- ; .MACRO DRERRS ; MACRO to test for Directive Errors - used when ; distance to reporting routine is short ; enough to allow a BRanch instruction BCS FLPDIR ; If Directive Error detected, go report it .ENDM DRERRS ; End of MACRO ; ;------------------------------------------------------------------------------------------- ; .MACRO DRERRL ; MACRO to test for Directive Errors - used when ; distance to reporting routine is long enough ; to require a JuMP instruction BCC .+6 ; If no Directive Error detected, skip next instruc- ; tion JMP FLPDIR ; Go report it .ENDM DRERRL ; End of MACRO ; ;------------------------------------------------------------------------------------------- ; .MACRO IOERRS ; MACRO to test for I/O Errors - used when distance ; to reporting routine is short enough to al- ; low a BRanch instruction CMPB FDSTAT,#IS.SUC ; I/O Error detected? BNE FLPIOE ; If yes, go report it .ENDM IOERRS ; End of MACRO ; ;------------------------------------------------------------------------------------------- ; .MACRO IOERRL ; MACRO to test for I/O Errors - used when distance ; to reporting routine is long enough to re- ; quire a JuMP instruction CMPB FDSTAT,#IS.SUC ; I/O Error detected? BEQ .+6 ; If not, skip next instruction JMP FLPIOE ; Go report I/O error .ENDM IOERRL ; End of MACRO .PAGE .SBTTL Text Strings (ASCII) ; ; .PSECT STRING ; IDMSG: .ASCII /FDC - Flopppy Diskette Copy program, Version 1.00%2NFor more infor/ .ASCIZ \mation, type "FDC /HE".%N\ ERRMSK: .ASCIZ /FDC -- <<< %I >>> -- %I%N/ WARNIN: .ASCIZ /WARNING/ FATAL: .ASCIZ /FATAL/ DGNSTC: .ASCIZ /STATUS/ SZGTDV: .ASCII /Requested number of blocks to be copied (%T) exceeds%N//dev/ .ASCIZ /ice size (%T)./ NOCMDL: .ASCIZ /No MCR Command Line provided./ INVDVU: .ASCIZ /Invalid device or unit (%2A%O:)./ SNTXER: .ASCIZ /Syntax Error:%2N>%VA%N%VS^/ SWTCH2: .ASCIZ /Multiply specified switch: %I./ SIZENN: .ASCIZ \/SZ:nnnn\ VERIFY: .ASCIZ \/VE\ NOMTCH: .ASCIZ /Conflicting block counts/ MINERR: .ASCIZ /Block count specified (%T) below minimum (%D)/ BADUNI: .ASCIZ /Illegal Unit Number detected (%VA)./ UNSAT: .ASCII /Specified device (%2A%O:) does not have proper charac-%N//t/ .ASCII /eristics:%2N//DV.REC (Record-oriented device) ......................./ .ASCII /.. %I%N//DV.CCL (Carriage control device) ........................ %I/ .ASCII /%N//DV.TTY (Terminal device) ................................ %I%N/ .ASCII /DV.DIR (Directory [file-structured] device) ............. %I%N/ .ASCII /DV.SDI (Single directory device) ........................ %I%N//DV.SQ/ .ASCII /D (Sequential device) .............................. %I%N//DV.MSD (Ma/ .ASCII /ss storage device) ............................ %I%N//DV.SWL (Unit so/ .ASCII /ftware write-locked) ..................... %I%N//DV.ISP (Input spoole/ .ASCII /d device) ........................... %I%N//DV.OSP (Output spooled de/ .ASCII /vice) .......................... %I%N//DV.PSE (Pseudo device) ......./ .ASCII /........................... %I%N//DV.COM (Device mountable as a commu/ .ASCII /nications channel) ... %I%N//DV.F11 (Device mountable as a Files-11 d/ .ASCII /evice) .......... %I%N//DV.MNT (Device mountable) .................../ .ASCIZ /............ %I/ YES: .ASCIZ /Yes/ NO: .ASCIZ /No/ DIRIOE: .ASCIZ /%I Error at address %P:%2N%8S%D %I/ DIRCTV: .ASCIZ /Directive/ IO: .ASCIZ \I/O\ NOTDEF: .ASCIZ /<> <> <> This error code has not been defined. <> <> <>/ IOSUPL: .ASCIZ /Terminating character = %B%N//Bytes transferred = %D.%N/ VFYERR: .ASCII /Verification failure - Address %P in LBN %T%2N//Floppy diskette: %P%/ .ASCIZ /2N//%6SDisk File: %P/ SIZERR: .ASCII /Number of blocks to be written to floppy diskette does%N// not / .ASCII /match size of disk file:%2N//Floppy diskette: %T blocks%N//%6SD/ .ASCIZ /isk file: %T blocks%2NThe smaller block count will be used./ READNG: .ASCIZ /Copying from %2A%O: to disk file . . ./ WRITNG: .ASCIZ /Copying from disk file to %2A%O: . . ./ VFYING: .ASCIZ /Beginning verify pass . . ./ FINSHD: .ASCIZ /Completed./ HLPTXT: .ASCII /FDC - Floppy Diskette Copy program%2N%8SThis program will copy dat/ .ASCII /a either from a floppy diskette to a%N%6SFiles-11 (disk) file or from a Fi/ .ASCII /les-11 file to a floppy diskette.%N%6SMinimum diskette size is %D blocks; / .ASCII /maximum size is the number of%N%6Savailable blocks on the destination disk/ .ASCII / when copying to a Files-%N%6S11 file, or the file size when copying from / .ASCII /a Files-11 file.%2N%6SThe basic command line uses standard MCR syntax:%2N/ .ASCII />filspec=ddn://! Copy from diskette to Files-11 file%N/ .ASCII /%4S- or -%N//>ddn:=filspec//! Copy from Files-11 / .ASCII /file to diskette%2N%6Swhere:%N//ddn: designates the floppy diskette t/ .ASCII /o be used - it must be ei-%N// ther not mounted (RSX-11M) or mounted/ .ASCII / FOREIGN (RSX-11M or%N/\ RSX-11M/PLUS)%N\/filspec designates th/ .ASCII \e Files-11 file to/from which data is to be%N\/ transferred - defaul/ .ASCII /ts are as follows (at least one of the%N// components marked with an/ .ASCII / asterisk (*) must be present:%N// Device ................ SY:%/ .ASCII /N//* UIC ................... User's default UIC%N//* F/ .ASCII /ile Name ............. FLOPPYDSK%N//* File Type ............. FD/ .ASCII /C%N//* File Version .......... 0%2N/\In addition to the /HE\ .ASCII /LP switch which causes this text to be%N%6Sdisplayed, FDC supports two oth/ .ASCII /er switches which may be appended%N%6Sto either the file or device specifi/ .ASCII /cation:%N/\/SZ:nnnn = to specify a number of blocks to be copied - ma\ .ASCII /y not%N// be larger than the device size when copying from a diskett/ .ASCII /e%N// or larger than either the device size or the file size when%N/ .ASCII / copying to a diskette%N/\/VE = verify the data transferred aft\ .ASCIZ /er the copying has finished%N/ .PAGE .SBTTL File Descriptor Block and other FCS related MACROs ; ; .PSECT FCSFDB ; .MCALL FSRSZ$,FDBDF$,FDRC$A,FDBK$A,FDOP$A .MCALL NMBLK$,NBOF$L ; FSRSZ$ 0,,FCSFDB ; DSKFDB: FDBDF$ FDRC$A FD.RWM FDBK$A ,,,3,DFSTAT FDOP$A 3,DSPT,DFLTFN ; DFLTFN: NMBLK$ FLOPPYDSK,FDC ; Define defaults for File Name, File Type, Device ; Mnemonic, and Unit Number NBOF$L ; Define offsets within Filename Block ; .MCALL OPEN$W,OPEN$R,OFID$R,FDBK$R,READ$,WRITE$,WAIT$,CLOSE$ ; ;=========================================================================================== ; .MACRO FCSCAL FCSMAC,ARGS ; MACRO to record address of an Executive Directive ; and then to issue the Directive MOV #.,FCSADX ; Save address of next FCS call in case it fails FCSMAC ARGS ; Call FCS routine .ENDM FCSCAL ; End of MACRO ; ;------------------------------------------------------------------------------------------- ; .MACRO FCSERS ; MACRO to test for FCS Errors - used when distance ; to reporting routine is short enough to al- ; low a BRanch instruction BCS DSPFCS ; If FCS Error detected, go report it .ENDM FCSERS ; End of MACRO ; ;------------------------------------------------------------------------------------------- ; .MACRO FCSERL ; MACRO to test for FCS Errors - used when distance ; to shutdown routine is long enough to re- ; quire a JuMP instruction BCC .+6 ; If no FCS Error detected, skip next instruction JMP DSPFCS ; Go report it .ENDM FCSERL ; End of MACRO .PAGE .SBTTL Constants ; ; .PSECT KNSTNT ; DIRTBL: .REPT 128 ; Table of pointers to Directive Error descriptor .WORD NOTDEF ; strings - initialized with pointer to .ENDR ; "Undefined" string, will be changed later by ; "ERRDAT" MACRO IOETBL: .REPT 128 ; Table of pointers to I/O Error descriptor strings .WORD NOTDEF ; - initialized with pointers to "Undefined" .ENDR ; string, will be changed later by "ERRDAT" ; MACRO DSPT: .WORD 0,0,0,0,0,0 ; Dataset pointer MNEMON: .WORD 0,0,0,0,0 ; Device specification storage - first word is ; device's Mnemonic UNITNO = MNEMON+2 ; Second word is device's Unit Number DVSTRT = MNEMON+4 ; Third word is pointer to start of device specifi- ; cation DVLEN = MNEMON+6 ; Fourth word is length of device specification FLAGS: .WORD 0 ; Status Flags .PAGE .SBTTL Working Storage ; ; .PSECT WRKSTG ; ARGBLK: .BLKW 20 ; Argument Block for $EDMSG processing LUNBUF: .BLKW 6 ; Information buffer for GLUN$ Directive LIMIT = LUNBUF+G.LUCW+2 ; Second and third device characteristics words ; will contain number of LBNs to be read ; from floppy diskette FDSTAT: .BLKW 2 ; I/O Status Block for floppy diskette operations DFSTAT: .BLKW 2 ; I/O Status Block for disk file operations IOSTAT: .BLKW 2 ; Common I/O Status Block FLSIZE: .BLKW 2 ; Number of blocks to be copied to / from floppy FNMBLK: .BLKW S.FNBW ; Temporary storage for contents of Filename Block ; in disk file's File Descriptor Block (FDB) DIRADX: .BLKW 1 ; Address of failing Executive Directive FCSADX: .BLKW 1 ; Address of failing FCS call ERRADX: .BLKW 1 ; Address of failing Directive or FCS call DRSTAT: .BLKW 1 ; Common storage for Directive Status Word ; TXTBUF: .BLKB 500 ; Text buffer for messages to User's terminal BUFFR1: .BLKB BLKCNT*BLKSIZ ; I/O buffers for floppy diskette data BUFFR2: .BLKB BLKCNT*BLKSIZ ; : .PAGE .SBTTL Directive and I/O Error Data ; ; .MACRO ERRDAT ERCD,TYP,DSCRPT ; MACRO to build Directive and I/O Error data tables $$$ = 0 ; Zero errors detected at outset .IF B ERCD ; Error Code left blank? If so, describe error: .ERROR Error Code not specified. $$$ = -1 ; Remember that an error was detected .IFF ; On the other hand, if it was not left blank: .IIF GE ERCD $$$ = -2 ; If positive or less than -128 (valid nega- .IIF LT ERCD+128 $$$ = -2 ; tive byte) . . . .IF EQ $$$+2 .ERROR Invalid Error Code: ERCD .ENDC ; EQ $$$+2 .ENDC ; B ERCD .IF B TYP ; Error Type left blank? If so, describe error: .ERROR Error Type (Directive or I/O ) not specified. $$$ = -1 ; Remember that an error was detected .IFF ; On the other hand, if it was not left blank: .IF DIF TYP D ; If Error Type is not "D" and ... .IF DIF TYP I ; ... is not "I", error: .ERROR Error Type improperly defined: TYP .ENDC ; DIF TYP I .ENDC ; DIF TYP D .ENDC ; B TYP .IF B ; Descriptive text missing? If so, describe error: .ERROR Error description not specified. $$$ = -1 ; Remember that an error was detected .ENDC ; B .IIF NE $$$ .MEXIT ; Abort MACRO if any error detected .PSECT STRING $$$ = . ; Remember where we are about to put text string .ASCIZ \DSCRPT\ .PSECT KNSTNT .IIF IDN TYP D . = DIRTBL-<*2> ; Select location in proper .IIF IDN TYP I . = IOETBL-<*2> ; table .WORD $$$ ; Leave pointer to text string .ENDM ERRDAT ; End of MACRO ; ;------------------------------------------------------------------------------------------- ; .MACRO CONTNU DSCRPT ; MACRO to continue descriptive text string for pre- ; ceding error .PSECT STRING . = .-1 ; Overlay terminator previously appended .ASCIZ \DSCRPT\ ; Continue description, append new .ENDM CONTNU ; ;=========================================================================================== ; ERRDAT -1,D,<(IE.UPN) {Insufficient dynamic storage}> ERRDAT -2,D,<(IE.INS) {Specified task not installed}> ERRDAT -3,D,<(IE.PTS) {Partition too small for task}> ERRDAT -4,D,<(IE.UNS) {Insufficient dynamic storage for send}> ERRDAT -5,D,<(IE.ULN) {Unassigned LUN}> ERRDAT -6,D,<(IE.HWR) {Device driver not resident}> ERRDAT -7,D,<(IE.ACT) {Task not active}> ERRDAT -8,D,<(IE.ITS) {Directive inconsistent with task state}> ERRDAT -9,D,<(IE.FIX) {Task already fixed/unfixed}> ERRDAT -10,D,<(IE.CKP) {Issuing task not checkpointable}> ERRDAT -11,D,<(IE.TCH) {Task is checkpointable}> ERRDAT -15,D,<(IE.RBS) {Receive buffer too small}> ERRDAT -16,D,<(IE.PRI) {Privilege violation}> ERRDAT -17,D,<(IE.RSU) {Resource in use}> ERRDAT -18,D,<(IE.NSW) {No swap space available}> ERRDAT -19,D,<(IE.ILV) {Illegal vector supplied}> ERRDAT -20,D,<(IE.ITN) {Invalid table number}> ERRDAT -21,D,<(IE.LNF) {Logical name not found}> ERRDAT -80,D,<(IE.AST) {Directive issued/not issued from AST}> ERRDAT -81,D,<(IE.MAP) {Illegal mapping specified}> ERRDAT -83,D,<(IE.IOP) {Window has I/O in progress}> ERRDAT -84,D,<(IE.ALG) {Alignment error}> ERRDAT -85,D,<(IE.WOV) {Address window allocation overflow}> ERRDAT -86,D,<(IE.NVR) {Invalid region ID}> ERRDAT -87,D,<(IE.NVW) {Invalid address window ID}> ERRDAT -88,D,<(IE.ITP) {Invalid TI parameter}> ERRDAT -89,D,<(IE.IBS) {Invalid send buffer (greater than 255)}> ERRDAT -90,D,<(IE.LNL) {LUN locked in use}> ERRDAT -91,D,<(IE.IUI) {Invalid UIC}> ERRDAT -92,D,<(IE.IDU) {Invalid device or unit}> ERRDAT -93,D,<(IE.ITI) {Invalid time parameters}> ERRDAT -94,D,<(IE.PNS) {Partition/region not in system}> ERRDAT -95,D,<(IE.IPR) {Invalid priority (greater than 250)}> ERRDAT -96,D,<(IE.ILU) {Invalid LUN}> ERRDAT -97,D,<(IE.IEF) {Invalid event flag (greater than 64)}> ERRDAT -98,D,<(IE.ADP) {Part of DPB out of user's space}> ERRDAT -99,D,<(IE.SDP) {DIC or DPB size invalid}> ERRDAT -1,I,<(IE.BAD) {Bad parameters}> ERRDAT -2,I,<(IE.IFC) {Invalid function code}> ERRDAT -3,I,<(IE.DNR) {Device not ready}> ERRDAT -4,I,<(IE.VER) {Parity error on device}> ERRDAT -5,I,<(IE.ONP) {Hardware option not present}> ERRDAT -6,I,<(IE.SPC) {Illegal user buffer}> ERRDAT -7,I,<(IE.DNA) {Device not attached}> ERRDAT -8,I,<(IE.DAA) {Device already attached}> ERRDAT -9,I,<(IE.DUN) {Device not attachable}> ERRDAT -10,I,<(IE.EOF) {End-of-file detected}> ERRDAT -11,I,<(IE.EOV) {End-of-volume detected}> ERRDAT -12,I,<(IE.WLK) {Write attempt to locked unit}> ERRDAT -13,I,<(IE.DAO) {Data overrun}> ERRDAT -14,I,<(IE.SRE) {Send/receive failure}> ERRDAT -15,I,<(IE.ABO) {Request terminated}> ERRDAT -16,I,<(IE.PRI) {Privilege violation}> ERRDAT -17,I,<(IE.RSU) {Shareable resource in use}> ERRDAT -18,I,<(IE.OVR) {Illegal overlay request}> ERRDAT -19,I,<(IE.BYT) {Odd byte count (or virtual address)}> ERRDAT -20,I,<(IE.BLK) {Logical Block Number too large}> ERRDAT -21,I,<(IE.MOD) {Invalid UDC module number}> ERRDAT -22,I,<(IE.CON) {UDC connect error}> ERRDAT -23,I,<(IE.NOD) {Caller's nodes exhausted}> ERRDAT -24,I,<(IE.DFU) {Device full}> ERRDAT -25,I,<(IE.IFU) {Index file full}> ERRDAT -26,I,<(IE.NSF) {No such file}> ERRDAT -27,I,<(IE.LCK) {Locked from read/write access}> ERRDAT -28,I,<(IE.HFU) {File header full}> ERRDAT -29,I,<(IE.WAC) {Accessed for write}> ERRDAT -30,I,<(IE.CKS) {File header checksum error}> ERRDAT -31,I,<(IE.WAT) {Attribute control list format error}> ERRDAT -32,I,<(IE.RER) {File processor device read error}> ERRDAT -33,I,<(IE.WER) {File processor device write error}> ERRDAT -34,I,<(IE.ALN) {File already accessed on LUN}> ERRDAT -35,I,<(IE.SNC) {File ID, file number check}> ERRDAT -36,I,<(IE.SQC) {File ID, sequence number check}> ERRDAT -37,I,<(IE.NLN) {No file accessed on LUN}> ERRDAT -38,I,<(IE.CLO) {File was not properly closed}> ERRDAT -39,I,<(IE.NBF) {No buffer space available for file}> ERRDAT -40,I,<(IE.RBG) {Illegal record size}> ERRDAT -41,I,<(IE.NBK) {File exceeds space allocated, no blocks}> ERRDAT -42,I,<(IE.ILL) {Illegal operation on file descriptor block}> ERRDAT -43,I,<(IE.BTP) {Bad record type}> ERRDAT -44,I,<(IE.RAC) {Illegal record access bits set}> ERRDAT -45,I,<(IE.RAT) {Illegal record attribute bits set}> ERRDAT -46,I,<(IE.RCN) {Illegal record number - too large}> ERRDAT -47,I,<(IE.ICE) {Internal consistency error}> ERRDAT -48,I,<(IE.2DV) {Rename - two different devices}> ERRDAT -49,I,<(IE.FEX) {Rename - a new file name already in use}> ERRDAT -50,I,<(IE.BDR) {Bad directory file}> ERRDAT -51,I,<(IE.RNM) {Cannot rename old file system}> ERRDAT -52,I,<(IE.BDI) {Bad directory syntax}> ERRDAT -53,I,<(IE.FOP) {File already open}> ERRDAT -54,I,<(IE.BNM) {Bad file name}> ERRDAT -55,I,<(IE.BDV) {Bad device name}> ERRDAT -56,I,<(IE.BBE) {Bad block on device}> ERRDAT -57,I,<(IE.DUP) {Enter - duplicate entry in directory}> ERRDAT -58,I,<(IE.STK) {Not enough stack space (FCS or FCP)}> ERRDAT -59,I,<(IE.FHE) {Fatal hardware error on device}> ERRDAT -60,I,<(IE.NFI) {File ID was not specified}> ERRDAT -61,I,<(IE.ISQ) {Illegal sequential operation}> ERRDAT -62,I,<(IE.EOT) {End-of-tape detected}> ERRDAT -63,I,<(IE.BVR) {Bad version number}> ERRDAT -64,I,<(IE.BHD) {Bad file header}> ERRDAT -65,I,<(IE.OFL) {Device off line}> ERRDAT -66,I,<(IE.BCC) {Block check, CRC, or framing error}> ERRDAT -67,I,<(IE.ONL) {Device on line}> ERRDAT -68,I,<(IE.NNN) {No such node}> ERRDAT -69,I,<(IE.NFW or IE.DIS) {Path lost to partner}> ERRDAT -70,I,<(IE.BLB) {Bad logical buffer}> ERRDAT -71,I,<(IE.TMM) {Too many outstanding messages}> ERRDAT -72,I,<(IE.NDR) {No dynamic space available}> ERRDAT -73,I,<(IE.URJ) {Connection rejected by user}> ERRDAT -74,I,<(IE.NRJ) {Connection rejected by network}> ERRDAT -75,I,<(IE.EXP) {File expiration date not reached}> ERRDAT -76,I,<(IE.BTF) {Bad tape format}> ERRDAT -77,I,<(IE.NNC) {Not ANSI "D" format byte count}> ERRDAT -78,I,<(IE.NDA) {No data available}> ERRDAT -79,I,<(IE.NLK) {Task not linked to specified ICS/ICR interrupts}> ERRDAT -80,I,<(IE.NST) {Specified task not installed}%N%26S- or -%N%12S(IE.AST) {N> CONTNU ERRDAT -81,I,<(IE.FLN) {Device off-line when off-line request was issued}> ERRDAT -82,I,<(IE.IES) {Invalid escape sequence}> ERRDAT -83,I,<(IE.PES) {Partial escape sequence}> ERRDAT -84,I,<(IE.ALC) {Allocation failure}> ERRDAT -85,I,<(IE.ULK) {Unlock error}> ERRDAT -86,I,<(IE.WCK) {Write check failure}> ERRDAT -87,I,<(IE.NTR) {Task not triggered}> ERRDAT -88,I,<(IE.REJ) {Transfer rejected by receiving CPU}> ERRDAT -89,I,<(IE.FLG) {Event flag already specified}> ERRDAT -90,I,<(IE.DSQ) {Disk quota exceeded}> ERRDAT -91,I,<(IE.IQU) {Inconsistent qualifier usage}> ERRDAT -92,I,<(IE.RES) {Circuit reset during operation}> ERRDAT -93,I,<(IE.TML) {Too many links to task}> ERRDAT -94,I,<(IE.NNT) {Not a network task}> ERRDAT -95,I,<(IE.TMO) {Timeout on request}> ERRDAT -96,I,<(IE.CNR) {Connection rejected}> ERRDAT -97,I,<(IE.UKN) {Unknown name}> ERRDAT -98,I,<(IE.SZE) {Unable to size device}> ERRDAT -99,I,<(IE.MII) {Media inserted incorrectly}> ERRDAT -100,I,<(IE.SPI) {Spindown ignored}> .PAGE .SBTTL Main Program Code ; ; .PSECT MNPRGM ; ...FDC: DIR$ #ASNLN1 ; Assign LUN 1 to User's terminal BCC 1000$ ; If no Directive Error detected, skip task abort MOV $DSW,R0 ; Get Directive Error Code so TKTN can display it BPT ; Trash program 1000$: EXEDIR GETMCR ; Retrieve Command Line BCC 1020$ ; If successful, go see what the Table Driven Parser ; thinks of it CMP $DSW,#IE.AST ; Is failure due to absence of Command Line to be ; retrieved? BEQ 1010$ ; If yes, go report problem JMP FLPDIR ; Go report unforseen error 1010$: MOV #ARGBLK+2,R2 ; Point to last word to be used in Argument Block MOV #NOCMDL,@R2 ; Put pointer to specific error to be reported into ; Argument Block JMP 1160$ ; Go report error and abort program 1020$: MOV #STATBL,R5 ; Point to starting state in State Table MOV #GETMCR+G.MCRB,R4 ; Point to start of MCR Command Line MOV $DSW,R3 ; Define length of MCR Command Line MOV R3,-(SP) ; Save on stack in case we have a Syntax Error MOV #KEYTBL,R2 ; Point to Keyword Table CLR R1 ; Disallow abbreviations, ignore blanks as syntax ; elements CALL .TPARS ; Let Table Driven Parser chew on it for a while BCC 1030$ ; If no gross errors detected, continue below MOV #ARGBLK+8,R2 ; Point to last word to be used in Argument Block DEC R3 ; Calculate character position of Syntax Error and MOV @SP,@R2 ; put result into Argument Block for posi- SUB R3,@R2 ; tioning caret indicator MOV #GETMCR+G.MCRB,-(R2) ; Put starting address and length of offending Com- MOV (SP)+,-(R2) ; mand Line into Argument Block MOV #SNTXER,-(R2) ; Follow with pointer to descriptor of specific er- ; ror being reported JMP 1160$ ; Go display results and terminate instruction exe- ; cution 1030$: TST (SP)+ ; Pop length of Command Line off stack TST FLAGS ; Any errors detected by action routines? BPL 1080$ ; If not, go see if HELP was requested BIT #SIZE2X,FLAGS ; /SZ:nnnn switch specified more than once? BEQ 1040$ ; If not, go see if minimum block count was met MOV #SIZENN,R0 ; Point to switch identifier CALL SWTWIC ; Display error message BIT #MATCH,FLAGS ; Different block counts specified? BEQ 1040$ ; If not, go see if minimum block count was met MOV #NOMTCH,ARGBLK+2 ; Put address of secondary Edit Mask into Argument ; Block CALL FTLERR ; Go display FATAL error message 1040$: BIT #TOOSML,FLAGS ; Block count specified below minimum? BEQ 1050$ ; If not, go see if /VE was specified > once MOV #ARGBLK+6,R2 ; Point to last word to be used in Argument Block MOV #BLKCNT,@R2 ; Put minimum block count into Argument Block MOV #DFSTAT,-(R2) ; Follow with pointer to number of blocks specified MOV #MINERR,-(R2) ; Next comes the address of the secondary Edit Mask CALL FTLERR ; Go display FATAL error message 1050$: BIT #VFY2X,FLAGS ; /VE switch specified more than once? BEQ 1060$ ; If not, go see if an unusable Unit Number was used MOV #VERIFY,R0 ; Point to switch identifier CALL SWTWIC ; Display error message 1060$: BIT #BDUNIT,FLAGS ; Bad Unit Number detected? BEQ 1070$ ; If not, go join common error code below MOV #ARGBLK+6,R2 ; Point to last word to be used in Argument Block MOV BUFFR1,@R2 ; Put pointer to and length of offending string into MOV BUFFR2,-(R2) ; Argument Block MOV #BADUNI,-(R2) ; Follow with pointer to descriptor of specific er- ; ror being reported CALL FTLERR ; Go display FATAL error message 1070$: BIT #FTLFLG,FLAGS ; Were any FATAL errors detected? BEQ 1080$ ; If not, skip the next instruction JMP SETERR ; Go wind things up early 1080$: BIT #HLPSWI,FLAGS ; /HELP specified? BEQ 1100$ ; If not, go see if anything was requested MOV #BLKCNT,ARGBLK ; Put minimum floppy size into Argument Block MOV #HLPTXT,R1 ; Point to text to be displayed 1090$: CALL MESSAG ; Display it JMP THEEND ; Go shut down the act 1100$: BIT #RDFLOP!WRFLOP,FLAGS ; Was any kind of a copy operation requested? BNE 1110$ ; If yes, go get crackin', lad! MOV #IDMSG,R1 ; Point to identification message BR 1090$ ; Go display it and then ring down the curtain 1110$: EXEDIR ASNLN2 ; Assign LUN 2 to floppy diskette drive BCC 1130$ ; If no Directive Errors, continue below CMP $DSW,#IE.IDU ; Is error = INVALID DEVICE OR UNIT? BEQ 1120$ ; If yes, skip next instruction JMP FLPDIR ; Go abort program 1120$: MOV #ARGBLK+6,R2 ; Point to last word to be used in Argument Block MOV ASNLN2+A.LUNU,@R2 ; Put device's Unit Number into Argument Block, fol- MOV #ASNLN2+A.LUNA,-(R2) ; lowed by pointer to device's Mnemonic MOV #INVDVU,-(R2) ; Follow with pointer to descriptor of specific er- ; ror being reported BR 1160$ ; Go display results and terminate instruction exe- ; cution 1130$: EXEDIR LN2INF ; Get some information about this beastie DRERRL ; Abort program if Directive Error detected BIC #DNTCAR,LUNBUF+G.LUCW ; Force "don't care" bits to zeroes CMP #DEVCW1,LUNBUF+G.LUCW ; Could this device be a floppy diskette? BEQ 1140$ ; If yes, continue below MOV #ARGBLK+34,R2 ; Point to last word in Argument Block to be used MOV #DV.MNT,R3 ; Specify DV.MNT is bit to be checked CALL DVCHCK ; Check Device characteristics bit MOV #DV.F11,R3 ; Specify DV.F11 is bit to be checked CALL DVCHCK ; Check Device characteristics bit MOV #DV.COM,R3 ; Specify DV.COM is bit to be checked CALL DVCHCK ; Check Device characteristics bit MOV #DV.PSE,R3 ; Specify DV.PSE is bit to be checked CALL DVCHCK ; Check Device characteristics bit MOV #DV.OSP,R3 ; Specify DV.OSP is bit to be checked CALL DVCHCK ; Check Device characteristics bit MOV #DV.ISP,R3 ; Specify DV.ISP is bit to be checked CALL DVCHCK ; Check Device characteristics bit MOV #DV.SWL,R3 ; Specify DV.SWL is bit to be checked CALL DVCHCK ; Check Device characteristics bit MOV #DV.MSD,R3 ; Specify DV.MSD is bit to be checked CALL DVCHCK ; Check Device characteristics bit MOV #DV.SQD,R3 ; Specify DV.SQD is bit to be checked CALL DVCHCK ; Check Device characteristics bit MOV #DV.SDI,R3 ; Specify DV.SDI is bit to be checked CALL DVCHCK ; Check Device characteristics bit MOV #DV.DIR,R3 ; Specify DV.DIR is bit to be checked CALL DVCHCK ; Check Device characteristics bit MOV #DV.TTY,R3 ; Specify DV.TTY is bit to be checked CALL DVCHCK ; Check Device characteristics bit MOV #DV.CCL,R3 ; Specify DV.CCL is bit to be checked CALL DVCHCK ; Check Device characteristics bit MOV #DV.REC,R3 ; Specify DV.REC is bit to be checked CALL DVCHCK ; Check Device characteristics bit CLR @R2 ; Put Unit Number of target device into Argument MOVB LUNBUF+G.LUNU,@R2 ; Block MOV #LUNBUF+G.LUNA,-(R2) ; Next is pointer to Mnemonic of target device MOV #UNSAT,-(R2) ; Follow with address of secondary Edit Mask BR 1160$ ; Go print result and abort program 1140$: BIT #SIZESW,FLAGS ; Was /SZ specified on Command Line? BEQ 1180$ ; If not, use CW2 and CW3 as number of LBNs to be ; copied CMP FLSIZE,LIMIT ; Was number of blocks requested less than or equal BLO 1170$ ; to device size? BHI 1150$ ; : CMP FLSIZE+2,LIMIT+2 ; If yes, continue below BLOS 1170$ ; : 1150$: MOV #ARGBLK+6,R2 ; Point to last word to be used in Argument Block MOV #LIMIT,@R2 ; Put pointers to specific values to be displayed MOV #FLSIZE,-(R2) ; (number of blocks requested and device size) ; into Argument Block MOV #SZGTDV,-(R2) ; Follow with pointer to descriptor of specific er- ; ror being reported 1160$: CALL FTLERR ; Go display FATAL error message JMP SETERR ; Go set Exit Status word to "ERROR and abort execu- ; tion 1170$: MOV FLSIZE,LIMIT ; Replace device size with number of blocks request- MOV FLSIZE+2,LIMIT+2 ; ed on Command Line 1180$: TSTB FLAGS ; Are we writing a floppy diskette from a disk file? BPL 1190$ ; If not, skip next instruction JMP 1260$ ; Go to disk file - to - floppy copy routine below ; ; Copy data from floppy diskette to disk file. ; 1190$: MOV #IO.RLB,RDWRIT+Q.IOFN ; Set up QIO$ Directive to read from floppy FCSCAL OPEN$W #DSKFDB ; Try to open output file FCSERL ; Abort program if error(s) detected MOV #ARGBLK+6,R2 ; Point to last word to be used in Argument Block CLR @R2 ; Put input device's Unit Number there MOVB LUNBUF+G.LUNU,@R2 ; : MOV #LUNBUF+G.LUNA,-(R2) ; Follow with pointer to input device's Mnemonic MOV #READNG,-(R2) ; Next comes a pointer to the secondary Edit Mask CALL STARPT ; Issue status report MOV LIMIT+2,R1 ; Put size of file to be written in R1 and upper 8 CLR R2 ; bits of R2, put bits specifying that noncon- BISB LIMIT,R2 ; tiguous extension is desired into lower 8 SWAB R2 ; bits of R2 FCSCAL CALL .EXTND ; Allocate desired number of blocks to disk file FCSERL ; Abort program if error(s) detected SUB #BLKCNT,LIMIT+2 ; Calculate LBN in last full blocks to be SBC LIMIT ; read from floppy MOV #BUFFR1,RDWRIT+Q.IOPL ; Define buffer address for floppy diskette reads MOV #BLKCNT*BLKSIZ,RDWRIT+Q.IOPL+2 ; Define size of first bloc to be read from floppy CLR R2 ; Initialize buffer address for disk file write CLR R4 ; Set LBN where reading from floppy diskette begins CLR R5 ; : 1200$: EXEDIR RDWRIT ; Initiate process of reading floppy blocks DRERRL ; Abort program if Directive Error detected TST R2 ; Currently reading first bloc from floppy? BEQ 1210$ ; If yes, don't bother trying to write anything to ; the disk file FCSCAL WRITE$ <,R2,R3> ; Write from previously loaded buffer to disk file FCSERL ; Abort program if FCS Error detected FCSCAL WAIT$ ; Wait for disk write to complete FCSERL ; Abort program if FCS Error detected 1210$: EXEDIR WTFLOP ; Wait for reading of floppy blocks to com- ; plete DRERRL ; Abort program if Directive Error detected IOERRL ; Abort program if I/O Error detected MOV RDWRIT+Q.IOPL,R2 ; Retrieve address and length of buffer just loaded MOV FDSTAT+2,R3 ; : MOV #BUFFR1+BUFFR2,RDWRIT+Q.IOPL ; Calculate starting address of I/O buffer for next SUB R2,RDWRIT+Q.IOPL ; read from floppy diskette ADD #BLKCNT,R5 ; Calculate LBN where next read from floppy diskette ADC R4 ; will begin MOV R5,RDWRIT+Q.IOPL+8 ; Update QIO$ Directive to reflect LBN where next MOV R4,RDWRIT+Q.IOPL+6 ; read from floppy diskette will begin CMP R4,LIMIT ; Will this be the last set of blocks to be read BLO 1200$ ; from the floppy diskette? BHI 1220$ ; : CMP R5,LIMIT+2 ; If not, continue processing as before BLOS 1200$ ; : 1220$: MOV LIMIT,R0 ; Retrieve limit value MOV LIMIT+2,R1 ; : ADD #BLKCNT,R1 ; Otherwise, calculate number of Logical Blocks to ADC R0 ; be read from floppy diskette so that we SUB R5,R1 ; won't attempt reading beyond the end of the SBC R0 ; device SUB R4,R0 ; : BEQ 1230$ ; : TRAP ; Abort program if unreasonable result 1230$: MOV R1,R0 ; Relocate multiplicand for next operation BEQ 1250$ ; If no more blocks to be read, go write last buffer ; to disk file and see about verification MUL #BLKSIZ,R0 ; Convert number of Logical Blocks to byte count TST R0 ; : BEQ 1240$ ; : TRAP ; Abort program if illogical result 1240$: MOV R1,RDWRIT+Q.IOPL+2 ; Update QIO$ Directive to reflect byte count EXEDIR RDWRIT ; Initiate process of reading floppy blocks DRERRL ; Abort program if Directive Error detected FCSCAL WRITE$ <#DSKFDB,R2,R3> ; Write from previously loaded buffer to disk file FCSERL ; Abort program if FCS Error detected FCSCAL WAIT$ ; Wait for disk write to complete FCSERL ; Abort program if FCS Error detected EXEDIR WTFLOP ; Wait for reading of floppy blocks to com- ; plete DRERRL ; Abort program if Directive Error detected IOERRL ; Abort program if I/O Error detected MOV RDWRIT+Q.IOPL,R2 ; Retrieve address and length of buffer just loaded MOV FDSTAT+2,R3 ; : 1250$: FCSCAL WRITE$ <#DSKFDB,R2,R3> ; Write from previously loaded buffer to disk file FCSERL ; Abort program if FCS Error detected FCSCAL WAIT$ ; Wait for disk write to complete FCSERL ; Abort program if FCS Error detected JMP 1360$ ; Go see about some verification ; ; Copy data from disk file to floppy diskette. ; 1260$: MOV #IO.WLB,RDWRIT+Q.IOFN ; Set up QIO$ Directive to write to floppy diskette FCSCAL OPEN$R #DSKFDB ; Try to open input file FCSERL ; Abort program if error(s) detected CLR R4 ; Initialize flag CMP DSKFDB+F.HIBK,LIMIT ; Does size of disk file exactly match size of flop- BNE 1270$ ; py diskette? CMP DSKFDB+F.HIBK+2,LIMIT+2 ; If yes, go issue status report BEQ 1290$ ; : 1270$: BHIS 1280$ ; If disk file is not smaller, skip next instruction COM R4 ; Set flag 1280$: MOV #ARGBLK+6,R2 ; Point to last word to be used in Argument Block MOV #DSKFDB+F.HIBK,@R2 ; Put pointer to number of blocks in disk file there MOV #LIMIT,-(R2) ; Follow with pointer to number of floppy blocks MOV #SIZERR,-(R2) ; Next comes a pointer to the secondary Edit Mask MOV #WARNIN,-(R2) ; Last is a pointer to the effect descriptor (in ; this case, only "WARNING") CALL ERRMSG ; Display results MOV #EX$WAR,BYEBYE+E.XSTS ; Put "WARNING" Code into Exit Status word TST R4 ; Check flag BEQ 1290$ ; If not set, skip next two instructions MOV DSKFDB+F.HIBK,LIMIT ; Reduce number of blocks to be written to size of MOV DSKFDB+F.HIBK+2,LIMIT+2 ; disk file 1290$: MOV #ARGBLK+6,R2 ; Point to last word to be used in Argument Block CLR @R2 ; Put input device's Unit Number there MOVB LUNBUF+G.LUNU,@R2 ; : MOV #LUNBUF+G.LUNA,-(R2) ; Follow with pointer to input device's Mnemonic MOV #WRITNG,-(R2) ; Next comes a pointer to the secondary Edit Mask CALL STARPT ; Issue status report CLR R4 ; Set LBN where writing to floppy diskette begins CLR R5 ; : SUB #BLKCNT,LIMIT+2 ; Calculate LBN in last full blocks to be SBC LIMIT ; written to floppy MOV #BUFFR1,R2 ; Initialize buffer address for disk file reads MOV #BLKCNT*BLKSIZ,R3 ; Set initial buffer size 1300$: FCSCAL READ$ <,R2,R3> ; Read from disk file to buffer FCSERL ; Abort program if FCS Error detected FCSCAL WAIT$ ; Wait for disk read to complete FCSERL ; Abort program if FCS Error detected MOV R4,R1 ; Currently reading first bloc from disk file? BIS R5,R1 ; : BEQ 1310$ ; If yes, don't bother waiting for write to floppy ; to complete EXEDIR WTFLOP ; Wait for writing of floppy blocks to com- ; plete DRERRL ; Abort program if Directive Error detected IOERRL ; Abort program if I/O Error detected 1310$: MOV R2,RDWRIT+Q.IOPL ; Put buffer address and length into QIO$ Directive MOV DFSTAT+2,RDWRIT+Q.IOPL+2; : MOV R4,RDWRIT+Q.IOPL+6 ; Put LBN where to begin writing to floppy diskette MOV R5,RDWRIT+Q.IOPL+8 ; into QIO$ Directive EXEDIR RDWRIT ; Initiate process of writing floppy blocks DRERRL ; Abort program if Directive Error detected MOV #BUFFR1+BUFFR2,R1 ; Calculate starting address of I/O buffer for next SUB R2,R1 ; read from disk file MOV R1,R2 ; : ADD #BLKCNT,R5 ; Calculate LBN where next write to floppy diskette ADC R4 ; will begin CMP R4,LIMIT ; Will this be the last set of blocks to be read BLO 1300$ ; from the floppy diskette? BHI 1320$ ; : CMP R5,LIMIT+2 ; If not, continue processing as before BLOS 1300$ ; : 1320$: MOV LIMIT,R0 ; Retrieve limit value MOV LIMIT+2,R1 ; : ADD #BLKCNT,R1 ; Otherwise, calculate number of Logical Blocks to ADC R0 ; be read from floppy diskette so that we SUB R5,R1 ; won't attempt reading beyond the end of the SBC R0 ; device SUB R4,R0 ; : BEQ 1330$ ; : TRAP ; Abort program if unreasonable result 1330$: MOV R1,R0 ; Relocate multiplicand for next operation BEQ 1350$ ; If no more blocks to be read, go write last buffer ; to floppy diskette & see about verification MUL #BLKSIZ,R0 ; Convert number of Logical Blocks to byte count TST R0 ; : BEQ 1340$ ; : TRAP ; Abort program if illogical result 1340$: FCSCAL READ$ <#DSKFDB,R2,R1> ; Read from disk file to buffer FCSERL ; Abort program if FCS Error detected FCSCAL WAIT$ ; Wait for disk read to complete FCSERL ; Abort program if FCS Error detected EXEDIR WTFLOP ; Wait for writing of floppy blocks to com- ; plete DRERRL ; Abort program if Directive Error detected IOERRL ; Abort program if I/O Error detected MOV R2,RDWRIT+Q.IOPL ; Put buffer address and length of last buffer MOV DFSTAT+2,RDWRIT+Q.IOPL+2; loaded from the disk file into QIO$ Direc- ; tive MOV R4,RDWRIT+Q.IOPL+6 ; Put LBN where to begin writing to floppy diskette MOV R5,RDWRIT+Q.IOPL+8 ; into QIO$ Directive EXEDIR RDWRIT ; Initiate process of writing floppy blocks DRERRL ; Abort program if Directive Error detected 1350$: EXEDIR WTFLOP ; Wait for writing of floppy blocks to com- ; plete DRERRL ; Abort program if Directive Error detected IOERRL ; Abort program if I/O Error detected MOV #IO.RLB,RDWRIT+Q.IOFN ; Set up QIO$ Directive to read from floppy in case ; we will be doing a verify pass ; ; Close disk file and verify data transfer. ; 1360$: MOV #DSKFDB,R0 ; Point to File Descriptor Block again MOV R0,R1 ; Calculate starting address of Filename Block ADD #F.FNB,R1 ; : MOV #FNMBLK,R2 ; Point to start of storage area MOV #S.FNBW,R3 ; Define number of words in Filename Block 1370$: MOV (R1)+,(R2)+ ; Copy word from FDB to storage area SOB R3,1370$ ; Repeat until entire Filename Block has been copied FCSCAL CLOSE$ ; Close file FCSERL ; Abort program if error(s) detected BIT #VFYSW,FLAGS ; /VE switch specified on Command Line? BNE 1380$ ; If yes, skip next instruction JMP SHUTUP ; Go close up shop 1380$: MOV #S.FNBW,R3 ; Define number of words in Filename Block 1390$: MOV -(R2),-(R1) ; Copy word from storage area back to filename block ; in FDB SOB R3,1390$ ; Repeat until entire Filename Block has been copied MOV #BUFFR1,RDWRIT+Q.IOPL ; Read into buffer 1 from floppy diskette MOV #BLKCNT*BLKSIZ,RDWRIT+Q.IOPL+2 ; Define size of buffer to read from floppy diskette CLR RDWRIT+Q.IOPL+6 ; Go back to start of floppy CLR R4 ; : CLR RDWRIT+Q.IOPL+8 ; : CLR R5 ; : FCSCAL FDBK$R <,#BUFFR2> ; Read into buffer 2 from disk file FCSERL ; Abort program if error(s) detected FCSCAL OFID$R ; Re-open disk file for reading FCSERL ; Abort program if error(s) detected MOV #VFYING,ARGBLK+2 ; Put address of secondary Edit Mask into second ; word of Argument Block CALL STARPT ; Issue status report 1400$: EXEDIR RDWRIT ; Read bloc from floppy diskette into buffer 1 DRERRS ; Abort program if Directive Error detected FCSCAL READ$ <,,RDWRIT+Q.IOPL+2> ; Read from disk file into buffer 2 FCSERL ; Abort program if FCS Error detected FCSCAL WAIT$ ; Wait for disk write to complete FCSERL ; Abort program if FCS Error detected EXEDIR WTFLOP ; Wait for reading of floppy blocks to com- ; plete DRERRS ; Abort program if Directive Error detected IOERRS ; Abort program if I/O Error detected CALL VALIDT ; Validate buffers BCC 1410$ ; If no discrepancy found, skip next instruction JMP SETERR ; Go set Exit Status word to "ERROR and abort execu- ; tion 1410$: ADD #BLKCNT,R5 ; Calculate LBN where next read from floppy diskette ADC R4 ; will begin MOV R5,RDWRIT+Q.IOPL+8 ; Update QIO$ Directive to reflect LBN where next MOV R4,RDWRIT+Q.IOPL+6 ; read from floppy diskette will begin CMP R4,LIMIT ; Will this be the last set of blocks to be read BLO 1400$ ; from the floppy diskette? BHI 1420$ ; : CMP R5,LIMIT+2 ; If not, continue processing as before BLOS 1400$ ; : 1420$: MOV LIMIT,R0 ; Retrieve limit value MOV LIMIT+2,R1 ; : ADD #BLKCNT,R1 ; Otherwise, calculate number of Logical Blocks to ADC R0 ; be read from floppy diskette so that we SUB R5,R1 ; won't attempt reading beyond the end of the SBC R0 ; device SUB R4,R0 ; : BEQ 1430$ ; : TRAP ; Abort program if unreasonable result 1430$: MOV R1,R0 ; Relocate multiplicand for next operation BNE 1440$ ; If number of blocks to be read is nonzero, contin- ; ue below JMP SHUTUP ; Otherwise, go ring down the curtain on this show 1440$: MUL #BLKSIZ,R0 ; Convert number of Logical Blocks to byte count TST R0 ; : BEQ 1450$ ; : TRAP ; Abort program if illogical result 1450$: MOV R1,RDWRIT+Q.IOPL+2 ; Update QIO$ Directive to reflect byte count EXEDIR RDWRIT ; Read bloc from floppy diskette into buffer 1 DRERRS ; Abort program if Directive Error detected FCSCAL READ$ <#DSKFDB,,RDWRIT+Q.IOPL+2> ; Read from disk file into buffer 2 FCSERS ; Abort program if FCS Error detected FCSCAL WAIT$ ; Wait for disk write to complete FCSERS ; Abort program if FCS Error detected EXEDIR WTFLOP ; Wait for reading of floppy blocks to com- ; plete DRERRS ; Abort program if Directive Error detected IOERRS ; Abort program if I/O Error detected CALL VALIDT ; Validate buffers BCS SETERR ; Go set Exit Status word to "ERROR and abort execu- ; tion if discrepancy detected BR SHUTUP ; Otherwise, go gracefully exit stage right ; ; Error processing. ; FLPDIR: MOV $DSW,DRSTAT ; Copy Directive Status Word to common storage MOV DIRADX,ERRADX ; Copy Directive address to common storage DSPDIR: CMP DRSTAT,#IE.UPN ; Failure caused by insufficient Pool? BNE 1000$ ; If not, report failure WSIG$S ; Wait for a "Significant Event" - it might shake ; loose some Pool JMP @ERRADX ; Go retry failing operation 1000$: MOV #ARGBLK+10,R2 ; Point to last word to be used in Argument Block MOV DRSTAT,R5 ; Get Directive Error Code MOV R5,BYEBYE+E.XSTS ; Put it into Exit Status word for this task COM R5 ; Make positive and scale to zero ASL R5 ; Calculate byte offset MOV DIRTBL(R5),@R2 ; Put pointer to descriptive text into Argument ; Block MOV DRSTAT,-(R2) ; Follow with Directive Error Code MOV ERRADX,-(R2) ; After that, put in address where failure occurred MOV #DIRCTV,-(R2) ; Next comes type of error - in this case, Directive MOV #DIRIOE,-(R2) ; Then a pointer to the secondary Edit Mask MOV #FATAL,-(R2) ; Finally a pointer to net effect of error - for all ; Directive anticipated errors, FATAL CALL ERRMSG ; Display results BR SETERR ; Go set Exit Status word to "ERROR" and shut down ; everything FLPIOE: MOV FDSTAT,IOSTAT ; Copy I/O Status Block to common storage MOV FDSTAT+2,IOSTAT+2 ; : MOV DIRADX,ERRADX ; Copy Directive address to common storage DSPIOE: MOV #ARGBLK+10,R2 ; Point to last word to be used in Argument Block MOVB IOSTAT,R5 ; Get sign-extended I/O Error Code MOVB R5,BYEBYE+E.XSTS ; Put byte version into low byte of Exit Status word ; for this task MOV R5,R4 ; Make copy for later use COM R5 ; Make positive and scale to zero ASL R5 ; Calculate byte offset MOV IOETBL(R5),@R2 ; Put pointer to descriptive text into Argument ; Block MOV R4,-(R2) ; Follow with I/O Error Code MOV ERRADX,-(R2) ; After that, put in address where failure occurred MOV #IO,-(R2) ; Next comes type of error - in this case, I/O MOV #DIRIOE,-(R2) ; Then a pointer to the secondary Edit Mask MOV #FATAL,-(R2) ; Finally a pointer to net effect of error - for all ; Directive anticipated errors, FATAL CALL ERRMSG ; Display results MOV #IOSTAT+1,(R2)+ ; Put pointer to terminating character into Argument ; Block MOV IOSTAT+2,@R2 ; Put byte count into Argument Block MOV #IOSUPL,R1 ; Point to Edit Mask CALL MESSAG ; Display result SETERR: MOV #EX$ERR,BYEBYE+E.XSTS ; Put "ERROR" Code into Exit Status word BR SHUTUP ; Go shut down everything DSPFCS: MOV FCSADX,ERRADX ; Copy address of failing FCS call to common storage MOV F.ERR(R0),R5 ; Get FCS Error Code BPL 1000$ ; If I/O Error, continue below MOV R5,DRSTAT ; Put FCS Error Code into Directive Status Word in ; case it isn't already there BR DSPDIR ; Go display Directive Error 1000$: MOVB R5,IOSTAT ; Make like this is an I/O error by putting Error MOVB DFSTAT+1,IOSTAT+1 ; Code, terminating character, and byte count MOV DFSTAT+2,IOSTAT+2 ; into I/O Status Block BR DSPIOE ; Go report I/O Error ; ; Final housekeeping and program shutdown. ; SHUTUP: FCSCAL CLOSE$ #DSKFDB ; Close file if open FCSERS ; Abort program if error(s) detected CMP BYEBYE+E.XSTS,#EX$SUC ; Have any errors (either FATAL or WARNING) been re- ; ported? BEQ 1000$ ; If not, go print final status report .IF EQ EX$WAR TST BYEBYE+E.XSTS ; Was it a FATAL error? .IFF CMP BYEBYE+E.XSTS,#EX$WAR ; Was it a FATAL error? .ENDC ; EQ EX$WAR BNE THEEND ; If yes, skip 'finished' message 1000$: MOV #FINSHD,ARGBLK+2 ; Put address of secondary Edit Mask into second ; word of Argument Block CALL STARPT ; Issue status report THEEND: DIR$ #BYEBYE ; Make like a big bird and get the flock out of ; here! HALT ; Force catastrophic failure in case that didn't ; work properly (in other words, roll over and ; DIE A HORRIBLE AND PAINFUL DEATH!) .PAGE .SBTTL "Action Routines" for Table-Driven Parser ; ; .PSECT ACTION ; ABBROK: MOVB #2,.PFLAG+1 ; Allow abbreviation to 2 characters for special ; case RETURN ; Return control to .TPARS ; DEVNAM: MOV .PSTPT,R0 ; Retrieve address of device's Mnemonic MOVB (R0)+,MNEMON ; Copy to temporary storage until final usage has MOVB @R0,MNEMON+1 ; been determined CLR UNITNO ; Tentatively assume Unit Number is not specified RETURN ; Return control to .TPARS ; DVUNIT: CMPB -1(R4),#'. ; Trailing decimal point? BEQ 2000$ ; If yes, go record error TST .PNUMH ; Unit number > 65535.? BEQ 2010$ ; If not, OK 2000$: BIS #BDUNIT!ERROR,FLAGS ; Remember we found a discrepancy here MOV .PSTPT,BUFFR1 ; Remember location and length of offending charac- MOV .PSTCN,BUFFR2 ; ter string 2010$: MOV .PNUMB,UNITNO ; Put result into temporary storage until final ; usage has been determined RETURN ; Return control to .TPARS ; SETDEV: MOV .PSTPT,DVSTRT ; Copy pointer to start and length of device speci- MOV .PSTCN,DVLEN ; fication to storage area RETURN ; Return control to .TPARS ; FSPUFD: MOV .PSTPT,DSPT+6 ; Put pointer to and length of UFD specification MOV .PSTCN,DSPT+4 ; into Dataset Pointer RETURN ; Return control to .TPARS ; FSPNTV: MOV .PSTPT,DSPT+10 ; Put pointer to and length of file name, type, and/ MOV .PSTCN,DSPT+8 ; or version into Dataset Pointer RETURN ; Return control to .TPARS ; FSPCHK: MOV DSPT+6,R0 ; Has any part of a file specification (other than a BIS DSPT+10,R0 ; device specification) been provided? BEQ REJECT ; If not, go reject transition RETURN ; Return control to .TPARS ; SETFIL: MOV DVSTRT,DSPT+2 ; Copy pointer to and length of device specification MOV DVLEN,DSPT ; to Dataset Pointer BR REINIT ; Go re-initialize device specification storage area INILUN: MOV MNEMON,ASNLN2+A.LUNA ; Copy device specification parameters to DPB of MOV UNITNO,ASNLN2+A.LUNU ; ALUN$ Directive REINIT: MOV #MNEMON,R0 ; Point to top of device specification storage area MOV #4,R1 ; Number of words to be reset 2000$: CLR (R0)+ ; Reset device specification storage area to zeroes SOB R1,2000$ ; Repeat until finished RETURN ; Return control to .TPARS ; REJECT: ADD #2,@SP ; Reject transition RETURN ; Return control to .TPARS ; VFYCHK: BIT #VFYSW,FLAGS ; Has /VE already been specified? BEQ 2000$ ; If not, skip next instruction BIS #VFY2X!ERROR,FLAGS ; Remember switch was specified more than once 2000$: RETURN ; Return control to .TPARS ; SIZCHK: BIT #SIZESW,FLAGS ; Has /SZ:nnnn already been specified? BEQ 2000$ ; If not, skip next instruction BIS #SIZE2X!ERROR,FLAGS ; Remember switch was specified more than once 2000$: RETURN ; Return control to .TPARS ; RWSIZE: BIT #SIZE2X,FLAGS ; Second or more appearance of /SZ? BEQ 2010$ ; If not, go store block count CMP .PNUMH,FLSIZE ; Does new block count match previous entry? BNE 2000$ ; If not, set another error flag CMP .PNUMB,FLSIZE+2 ; : BEQ 2010$ ; : 2000$: BIS #MATCH!ERROR,FLAGS ; Remember discrepancy detected 2010$: MOV .PNUMH,FLSIZE ; Copy specified number of blocks to be copied MOV .PNUMB,FLSIZE+2 ; : TST FLSIZE ; Does specified value meet or exceed minimum block BNE 2020$ ; count? CMP FLSIZE+2,#BLKCNT ; If yes, skip setting yet another error flag BHIS 2020$ ; : BIS #TOOSML!ERROR,FLAGS ; Remember that there was an error MOV FLSIZE,DFSTAT ; Remember the offending value MOV FLSIZE+2,DFSTAT+2 ; : 2020$: RETURN ; Return control to .TPARS .PAGE .SBTTL Subroutines ; ; .PSECT SUBRTN ; ; ; PAINT - Subroutine to output a text string to User's terminal. PAINTR is assumed to be ; the label of a QIOW$ Directive containing the address of the start of the string. ; ; Register usage: ; Input: ; R1 - Length of text string to be displayed ; Output: ; None ; ; Subroutines called: None ; PAINT: MOV R1,PAINTR+Q.IOPL+2 ; Put length of output buffer into QIOW$ Directive DIR$ #PAINTR ; Issue Directive to display string at terminal BCC 3000$ ; If no Directive Error detected, go return to ; caller MOV $DSW,R0 ; Get Directive Error Code so TKTN can display it BPT ; Trash program 3000$: RETURN ; Return control to calling routine ; ; ; MESSAG - Subroutine to prepare a text string for display at User's terminal and to perform ; actual display - assumes ARGBLK is the label of an Argument Block containing any ar- ; guments indicated by the Edit Mask. ; ; Register usage: ; Input: ; R1 - Address of primary Edit Mask in $EDMSG format ; Output: ; None ; ; Subroutines called: $SAVAL, $EDMSG, PAINT ; MESSAG: CALL $SAVAL ; Preserve contents of all General Purpose Registers MOV PAINTR+Q.IOPL,R0 ; Define start of output buffer MOV #ARGBLK,R2 ; Define start of Argument Block CALL $EDMSG ; Generate text string CALL PAINT ; Display message RETURN ; Restore contents of General Purpose Registers and ; return control to calling routine ; ; ; ERRMSG - Subroutine to prepare an error message for display at User's terminal and to per- ; form actual display. The following assumptions are made with respect to the Argu- ; ment Block (ARGBLK:): ; 1) The first word contains a pointer to general effect of error being re- ; ported (FATAL or WARNING). ; 2) The second word contains a pointer to the descriptor of the specific er- ; ror being reported. ; 3) The remaining words contain either the values or pointers to the values ; to be displayed in the descriptor of the specific error being re- ; ported (whether the values themselves or pointers to the values need ; to be present is determined by the editing directives present in the ; descriptor). ; ; Register usage: ; Input: ; None ; Output: ; None ; ; Subroutines called: $SAVAL, MESSAG ; ERRMSG: CALL $SAVAL ; Preserve contents of all General Purpose Registers MOV #ERRMSK,R1 ; Point to primary Edit Mask for displaying error ; messages CALL MESSAG ; Format and display message RETURN ; Restore contents of General Purpose Registers and ; return control to calling routine ; ; ; FTLERR - Subroutine to prepare a "FATAL" error message for display at User's terminal and ; to perform actual display and to condition Task's Exit Status word - assumes second ; word of Argument Block contains pointer to text string describing error being re- ; ported and that succeeding words in the Argument Block have been set up for any ar- ; guments it may require. ; ; Register usage: ; Input: ; R0 - Pointer to descriptor string for specific error detected ; Output: ; None ; ; Subroutines called: $SAVAL, ERRMSG ; FTLERR: CALL $SAVAL ; Preserve contents of all General Purpose Registers MOV #FATAL,ARGBLK ; Insert pointer to general effect of error detected ; (in this case, FATAL) into Argument Block CALL ERRMSG ; Display error message MOV #EX$ERR,BYEBYE+E.XSTS ; Put "ERROR" Code into Exit Status word RETURN ; Restore contents of General Purpose Registers and ; return control to calling routine ; ; ; SWTWIC - Subroutine to prepare an error message regarding multiple specification of a ; switch for display at User's terminal and to perform actual display. ; ; Register usage: ; Input: ; R0 - Pointer to descriptor string for specific switch which has been multiply speci- ; fied ; Output: ; None ; ; Subroutines called: $SAVAL, ERRMSG ; SWTWIC: CALL $SAVAL ; Preserve contents of all General Purpose Registers MOV #ARGBLK+4,R2 ; Point to last word to be used in Argument Block MOV R0,@R2 ; Put pointer to specific switch into Argument Block MOV #SWTCH2,-(R2) ; Follow with pointer to descriptor of specific er- ; ror being reported MOV #WARNIN,-(R2) ; Last, insert pointer to general type of error de- ; tected (in this case, a WARNING) CALL ERRMSG ; Display error message CMP BYEBYE+E.XSTS,#EX$SUC ; Have any other errors been reported yet? BNE 2000$ ; If yes, skip next instruction MOV #EX$WAR,BYEBYE+E.XSTS ; Let Exit Status reflect non-fatal error 2000$: RETURN ; Restore contents of General Purpose Registers and ; return control to calling routine ; ; ; DVCHCK - Subroutine to test a specified bit in the Device Characteristics Word #1 in the ; LUN information buffer for the device connected to LUN 2 and to put a pointer to one ; of two text strings depending on whether the bit is set or clear. ; ; Register usage: ; Input: ; R2 - Pointer to next word in Argument Block to be loaded. (The Argument Block is ; loaded in descending address order.) ; R3 - Bit mask for bit to be tested ; Output: ; R2 - Pointer to next word in Argument Block to be loaded or, in other words, to the ; next word in memory below the word loaded by this subroutine. ; ; Subroutines called: None ; DVCHCK: MOV #NO,@R2 ; Tentatively assume bit is clear BIT R3,LUNBUF+G.LUCW ; Specified bit set? BEQ 3000$ ; If not, skip next instruction MOV #YES,@R2 ; Correct results of erroneous assumption 3000$: TST -(R2) ; Point to next word to be loaded RETURN ; Return control to calling routine ; ; ; STARPT - Subroutine to prepare a status message for display at User's terminal and to per- ; form actual display. The following assumptions are made with respect to the Argu- ; ment Block (ARGBLK:): ; 1) The first word is left to be filled in by this routine ; 2) The second word contains a pointer to the secondary Edit Mask forming the ; actual status report to be issued. ; 3) The remaining words contain either the values or pointers to the values ; to be displayed in the descriptor of the specific error being re- ; ported (whether the values themselves or pointers to the values need ; to be present is determined by the editing directives present in the ; descriptor). ; ; Register usage: ; Input: ; None ; Output: ; None ; ; Subroutines called: $SAVAL, MESSAG ; STARPT: CALL $SAVAL ; Preserve contents of all General Purpose Registers MOV #DGNSTC,ARGBLK ; Put pointer to effect descriptor ("STATUS") into ; first word of Argument Block MOV #ERRMSK,R1 ; Point to primary Edit Mask for displaying error ; messages CALL MESSAG ; Format and display message RETURN ; Restore contents of General Purpose Registers and ; return control to calling routine ; ; ; VALIDT - Subroutine to compare data read from the floppy diskette and from the disk file - ; displays error message and sets PS on return if a discrepancy is detected ; - otherwise returns with PS clear. ; ; Register usage: ; Input: ; None ; Output: ; None ; ; Subroutines called: $SAVAL, MESSAG ; VALIDT: CALL $SAVAL ; Preserve contents of all General Purpose Registers MOV #BUFFR1,R1 ; Point to top of floppy disketts's data buffer MOV #BUFFR2,R2 ; Point to top of disk file's data buffer MOV RDWRIT+Q.IOPL+2,R3 ; Get byte count ASR R3 ; Convert to word count 3000$: CMP (R1)+,(R2)+ ; Compare corresponding words in each buffer BEQ 3010$ ; If identical, continue below SUB #BUFFR1+2,R1 ; Calculate offset into buffer where error occurred CLR R0 ; Form dividend DIV #BLKSIZ,R0 ; Calculate relative block and byte offset MOV #RDWRIT+Q.IOPL+8,R4 ; Point to second word of LBN ADD R0,@R4 ; Calculate LBN where error occurred ADC -(R4) ; : MOV #ARGBLK+10,R3 ; Point to last word to be used in Argument Block MOV -(R2),@R3 ; Put value from disk file into Argument Block MOV BUFFR1-BUFFR2(R2),-(R3) ; Follow with value from floppy diskette MOV R4,-(R3) ; Next comes the pointer to the offending LBN MOV R1,-(R3) ; Put byte offset in next MOV #VFYERR,-(R3) ; Now a pointer to the secondary Edit Mask MOV #FATAL,-(R3) ; Finish with pointer to effect drecriptor ("FATAL") CALL ERRMSG ; Display result SEC ; Set PS RETURN ; Restore contents of General Purpose Registers and ; return control to calling routine 3010$: SOB R3,3000$ ; If not finished, get back to work CLC ; Ensure PS = 0 on return RETURN ; Restore contents of General Purpose Registers and ; return control to calling routine .PAGE .SBTTL End of Program ; ; .PSECT ; .END ...FDC ; T-Th-Th-Tha-That's all folks!