TITLE EXAMPL - copy a file with conversion SUBTTL Rob Cook Jan 75 v:1 SEARCH C,IO SALL ; version numbering VERSN$ 1,15,2 ;1(15)-2 JBVER$ ;set .JBVER comment ; EXAMPL is a simple program showing what can be done with IOLIB. The aim is to copy a file, performing some character conversion on the way. The conversion routine is loaded seperately so that it can be rewritten for any particular conversion job. The conversion routine must be called CONVRT and must expect and return the character right justified in ac(T1). EXAMPL prompts for a command string with an '*', and then reads a string of the form: output-file=input-file both names are compulsory and wildcards are illegal. The standard SCAN file switches may be used. /REWIND rewinds the file /INDUSTRY sets industry compatible mode. /BLOCKSIZE:n sets the file blocksize /BYTESIZE:n sets the character bytesize /ASCII forces ASCII mode for both files (default) /BINARY forces BINARY mode for both files /IGNOREERROR ignore parity and checksum errors on transfer EXAMPL initialises the channels as if they are both magtapes and then performs the copy, calling CONVRT to convert each byte. ; ; set code into high segment HISEG$ ; define an extra word in the FDB for user switches $FDUSR==-1 ;a vector of fields, defined below ; fields within $FDUSR FU$REW==1B0 ;rewind this volume before using FU$IND==1B1 ;set industry compatible mode FU$IGE==1B2 ;ignore parity errors FU$BYT==77B35 ;bytesize ; define maxima and defaults for switches DM$ BYT,^D36,^D7,^D7 ;BYTESIZE SUBTTL Main Program Loop EXAMPL: ;start address BEGIN$ ;always first with IOLIB MOVEI T1,'EXA' ;setup name for error codes HRLM T1,$IDECD(I) ; into the IDB EXA10: ;loop here to read a new command STORE T1,IOLO,IOHI,0 ;clear data base PUSHJ P,RCOMND ;read an OUT=IN command string JRST EXA10 ;command error - try again MOVEI D,INPFDB ;initialise input MT PUSHJ P,INITMT ; LUKUP$ ;is file there? JRST EXA40 ;report error and start over MOVEI D,OUTFDB ;initialise output MT PUSHJ P,INITMT ; ENTER$ ;do ENTER in case of errors JRST EXA40 ;report error and start over EXA20: ;loop here to copy each byte MOVEI D,INPFDB ;set input tape READ$ ;read byte JRST EXA30 ;treat error JRST EXA50 ;endfile AOS BYTECT ;increment count of bytes transfered PUSHJ P,CONVRT## ;convert byte to new format MOVEI D,OUTFDB ;set output file WRITE$ ;write byte JRST EXA30 ;treat error JRST EXA20 ;loop back for next byte EXA30: ;here on INPUT or OUTPUT errors ;warn user: if a parity error, and parity errors are to be ignored ;continue, else back for more commands PUSH P,T1 ;remember error code WARN$ POP P,T1 ;error codes HRRZ T1,T1 ;lose UUO code MOVE T2,$FDUSR(D) ;pickup flag vector for this file CAIN T1,ERDTE$ ;parity error? TXNN T2,FU$IGE ;yes - and ignore parity errors? CAIA ;no - start over JRST EXA20 ;yes - read next character MSGFD$ ;write to terminal WLINE$ < Transfer terminated> JRST EXA50 ;ask for more commands EXA40: ;here on LOOKUP and ENTER errors WARN$ EXA50: ;here on input endfile and fatal errors MOVEI D,INPFDB ;set input file RLEAS$ ;close it down MOVEI D,OUTFDB ;set output file RLEAS$ ;close that too SKIPE T2,BYTECT ;give user total if any bytes transfered ADVIS$ ,DECL,BYT JRST EXA10 ;loop back for more commands SUBTTL Command Scanner RCOMND: ;This simple minded command scanner looks for command strings ;of the form: ; output-file=input-file ;Wildcards etc are illegal ; ;Call: PUSHJ P,RCOMND MSGFD$ ;write messages WCHAR$ "*" ;deliver prompt CMDFD$ ;read commands CLLIN$ ;clear junk on end of last line RCHAR$ ;read 1st character JUMPLE T1,RCOMND ;ignore null lines MOVEM T1,$IDNXC(I) ;reeat last character MOVEI T2,OUTFDB ;spec. goes to output FDB PUSHJ P,RFILEN ;read filename JRST SYNERR ;command error CAIE T1,"=" ;correct delimiter? CAIN T1,"_" ; CAIA ;yes JRST ILCERR ;illegal character MOVEI T2,INPFDB ;spec goes to input FDB PUSHJ P,RFILEN ;read filename JRST SYNERR ;command error PJMPLE T1,$POPJ1## ;good return if endline ;fall into Illegal Character routine ILCERR: ;here on finding an illegal character MOVE T2,T1 ;save character for error message PUSHJ P,$$ILCH## ;set up error message ;fall into syntax error routine SYNERR: ;here on any form of command error WARN$ ,SYNTAX POPJ P, ;nonskip return RFILEN: ;read a filename from the current file, rejecting null files ;and wild files ;Call: ; T2 : point to destination FDB ; PUSHJ P,RFILEN ; command error ; ok ;clear sticky defaults from default FDB MOVEI T1,DFTFDB ;default FDB address SETZM $FDUSR(T1) ;clear user switch word CLRFD$ T1 ;(make) and initialise it FATAL$ ;not enough core! MOVEM T1,$IDDFD(I) ;set FDB pointer MOVEI T1,$TBSSW## ;table of standard switches MOVEM T1,$IDSWT(I) ;where the switch scanner can find it MOVEI T1,TBSWIT ;point to user switch tables SETZM $FDUSR(T2) ;clear user switch word RFILE$ T1 ;read filename POPJ P, ;command error TXNN T2,FF$WLD!FF$NUL ;wild or null? PJRST $POPJ1## ;no - ok TXNN T2,FF$WLD ;wild? SKIPA T1,[EC$IND+[+[ASCIZ \Null filename illegal\]]] MOVE T1,[EC$IND+<<$ECTFI>B17>+[+[ASCIZ \Wildcards Illegal\]]] POPJ P, TBSWIT: ;define user switch tables. ; /REWIND sets bit FU$REW in $FDUSR ; /INDUSTRY sets bit FU$IND in $FDUSR DEFINE SWIT$$,< SS$ ,,1 SS$ ,,1 SS$ ,,1 SP$ ,,$SWDEC##,BYT SS$ ,IOMODE,0 SS$ ,IOMODE,14 > SWTAB$ USR SUBTTL Initialise a Channel for Magtape IO INITMT: ;open a channel for an FDB, rewind the magtape and ;set industry compatible mode MOVE T1,IOMODE ;load IO mode DPB T1,[POINT 4,$FDSTS(D),35] ;set IO mode OPEN$ ;OPEN UUO FATAL$ ;some IO error MOVE T1,$FDUSR(D) ;pick up switches TXNN T1,FU$BYT ;bytesize specified? JRST INI10 ;no DPB T1,[POINT 6,$FDOBH+1(D),11] ;yes - set into both buffer headers DPB T1,[POINT 6,$FDIBH+1(D),11] ; INI10: ; TXNE T1,FU$REW ;rewind? MTREW$ ;rewind TXNE T1,FU$IND ;industry compatible? MTIND$ ;set industry compatible mode POPJ P, ; SUBTTL Low Segment Data Area LOSEG$ BLOCK 1 ;$FDUSR INPFDB: BLOCK $LNFDB ;input FDB BLOCK 1 ;$FDUSR OUTFDB: BLOCK $LNFDB ;output FDB BLOCK 1 ;$FDUSR DFTFDB: BLOCK $LNFDB ;default FDB IOLO: ;low core to be zeroed IOMODE: BLOCK 1 ;IO mode for file transfers BYTECT: BLOCK 1 ;count of bytes transfered IOHI==.-1 ;top of low core to be zeroed END EXAMPL