.title Mgt Magtape transfer utility .sbttl Data area ; .mcall $tpadef,$stsdef,$dcdef,$iodef,$ssdef,$mtdef,$rmsdef $tpadef $stsdef $dcdef $iodef $ssdef $mtdef $rmsdef ; ; Routine to transfer data from or to a mag tape ; .psect dataw,rd,wrt,noexe Mes_desc: .long 256 ;message descriptor for get foreign Mes_adr: .address Message Message: .blkb 256 Message_len: .word ; Omessage: .blkb 256 ; Prompt_desc: .long 13 ;prompt message for get foreign Prompt_adr: .address Prompt Prompt: .ascii \ Mgt > \ Iprompt: .ascii \_Input : \ Oprompt: .ascii \_Output: \ ; Output: .ascid \SYS$OUTPUT\ ;logical name for output TT_chan: .blkw 1 ;location of channel for output TT_desc: .long 63 ;descriptor for output device TT_adr: .address TT TT: .blkb 63 ;buffer for output device name ; Syn_Amb: .word 0 Syn_len: .blkl 1 ;descripter for syntax error Syn_adr: .blkl 1 ;in command line ; ; MT found flags ; Mtin: .word 0 Mtout: .word 0 Mtmode: .word 0 ; ; MT luns ; Mtin_lun: .word 0 Mtout_lun: .word 0 Mtuse_lun: .word 0 ; Tape_mode: .word 0 .word 2048 Tape_density: .long 0 ; ; io status block ; Io_status: .word 0 Io_count: .word 0 Io_data: .long 0 ; ; Switch numeric storage locations ; Block_num: .long 0 Blank_num: .long 0 Lterm_num: .long 0 Transfer_num: .long 0 Record_num: .long 0 File_num: .long 0 Transfer_count: .long 0 ; Sign_flag: .long 0 ; ; Conversational mode flag ; Convers: .long 0 ; ; ; Input and output file parameters ; Input_flag: .word 0 Output_flag: .word 0 Infile: .long 0 Infile_adr: .long 0 Outfile: .long 0 Outfile_adr: .long 0 ; ; ; TPARSE parameter block ; Tparse_block: .long TPA$K_COUNT0 Tparse_opt: .long TPA$M_ABBREV ;ALLOW ABBREVIATION .blkl TPA$K_LENGTH0-8 ; ; GLOBAL PARSE FLAG ; Parser_flags: .blkl 1 ; ; ; File access fab's and rab's also input and output data areas ; .psect filedata,long Infab: $fab Outfab: $fab Inrab: $rab fab=Infab Outrab: $rab fab=Outfab ; ; Inbuf: .blkb 8192 Inbuf_len=8192 Outbuf: .blkb 8192 Outbuf_len=8192 ; Error_found: .word 0 Get_len: .word 0 Put_len: .word 0 Eof_flag: .word 0 Buf_start: .long 0 Trans_desc: .long 0 Trans_desc_adr: .address Outbuf Fill_char: .byte 32 ;fill character for magtape .psect datar,rd,nowrt,noexe ;************************************************************************** ; Read only area ; ; .macro Error_stop ?X cmpw #ss$_normal,R0 beql X ; movl R0,R5 pushl R0 ;got an error calls #1,G^LIB$STOP ;write message stored in R0 $exit_s R5 X: .endm Error_stop ; ; .macro Error_signal ?W ?X ?Y ?Z cmpw #SS$_NORMAL,R0 beql X ; cmpl #RMS$_FNF,R0 bneq W jmp Y ; W: cmpl #RMS$_FNM,R0 bneq Z jmp Y ; Z: movw #1,Error_found Y: pushl R0 calls #1,G^LIB$SIGNAL jmp Done X: .endm Error_signal ; .macro Tape_check ?X ?Y cmpw #ss$_normal,Io_status beql X cmpw #ss$_endoffile,Io_status bneq Y $output chan=TT_chan, - ;Eof massage length=#Eof_message_len, - buffer=Eof_message ; movw #1,Eof_flag jmp X ; Y: pushl Io_status calls #1,G^LIB$SIGNAL movw #1,Error_found X: .endm Tape_check ; ; ; define parser flag bits ; Block_flag = 1 ;blocking factor Blank_flag = 2 ;blank fill records Lterm_flag = 4 ;search or add a lineterminator Ebc_flag = 8 ;convert from ebcidic to ascii Asc_flag = 16 ;convert from ascii to ebcidic All_flag = 32 ;copy all files from on mt to another Transfer_flag = 64 ;number of records to process Endvolume_flag = 128 ;write an end of volume mark Rewind_flag = 256 ;rewind flag Record_flag = 512 ;skip record flag File_flag = 1024 ;skip file flag Flag_800 = 2048 ;write at 800 bpi Flag_1600 = 4096 ;write at 1600 bpi ; ; Mt: .ascii \M\ Colon: .ascii \:\ ; ; Output messages ; SYN: .ascii \Syntax error \ AMB: .ascii \Ambiguous sym\ Er_800: .ascii \Which do you want 800 or 1600 BPI\ Er_800_len=.-Er_800 Er_ebc: .ascii \I will not convert from ASCII to EBCDIC and back again\ Er_ebc_len=.-Er_ebc Er_nomt: .ascii \This is a magtape transfer utility, not a COPY command\ Er_nomt_len=.-Er_nomt Er_all: .ascii \Copy all flag valid only for tape to tape transfer\ Er_all_len=.-Er_all Er_long_rec: .ascii \Record length exceeds 8196\ Er_long_rec_len=.-Er_long_rec Eof_message: .ascii \{Eof found on tape}\ Eof_message_len=.-Eof_message Er_trans: .ascii \An untranslatable character was found\ Er_trans_len=.-Er_trans Er_trans_block: .ascii \Error blocking and lineterminator flag both set\ Er_trans_block_len=.-Er_trans_block Er_block_large: .ascii \Error blocking factor larger than 8192\ Er_block_large_len=.-Er_block_large ; ; ;*************************************************************************** .sbttl Parse up command line .psect code,rd,nowrt,exe .entry MGT,^M ; ; Mainl routine ; ; ; Get the output device ; $trnlog_s lognam=Output,- rslbuf=TT_desc,- rsllen=TT_desc Error_stop ; ; Check to see if the translation was a system assigned logical ; name. If so it is preceded by a four byte header starting ; with an . If this is true, get rid of the header before ; assigning a channel to it. ; cmpb tt,#^X1b bneq 5$ subl #4,tt_desc addl #4,tt_adr 5$: $assign_s devnam=TT_desc, - ;assign a channel chan=TT_chan Error_stop ; ; get a foreign command line ; Forei: pushal Message_len ;length of message recv pushl #0 pushaq Mes_desc ;message location calls #3,g^lib$get_foreign tstw Message_len ;anything in command line beql 1$ ;no jmp Upper 1$: movl #1,Convers ;He wants to enter more than one comd. ; ; clear out data areas ; Begin_convers: ;clear out data areas for conversatinal mode ; clrl Transfer_num ;clear transfer num clrl Transfer_count ;clear transfer count clrw Syn_Amb ;ambigous flag clrl Mtin ;clear mtin & mtout flags clrq Block_num ;clear block_num & blank_num clrq Lterm_num ;clear Lterm_num & Record_num clrl File_num ;clear number of files to skip clrw Mtmode ;clear transfer mode clrl Input_flag ;clear input and output flags clrl Parser_flags ;clear parser flags clrl Get_len ;clear get and put lengths clrw Eof_flag ;clear eof flag clrw Put_len ;clear put length clrw Error_found ;clear error flag clrw Eof_flag ;clear eof flag clrl Buf_start ;clear buffer address movb #32,Fill_char ;assume fill character is an ascii ; moval Prompt,Prompt_adr ;move mgt prompt to prompt moval Message,Mes_adr Getline: pushal Message_len pushaq Prompt_desc pushaq Mes_desc calls #3,g^lib$get_foreign ;go get a command ; cmpl #ss$_normal,R0 beql 1$ $exit_s ; or something 1$: tstw Message_len beql Getline ;null input ; ; Convert string to all upper case characters and ; move command line into TPARSE control block ; Upper: pushal Mes_desc ;input message pushal Mes_desc calls #2,g^str$upcase ;convert to upper case movzwl Message_len,Tparse_block+Tpa$l_stringcnt movl Mes_adr,Tparse_block+Tpa$l_stringptr ; Now call tparse pushal ufd_key pushal ufd_state pushal TPARSE_BLOCK calls #3,g^lib$tparse blbs R0,10$ ;branch if no error tstw Syn_Amb ;Syntax or Ambiguous symbol beql 3$ jmp Amb_error ;Ambigious symbol 3$: jmp Syntax_error ;Syntax error on line jmp done ;exit ; ; Ok now let's check to see if we have an input and output ; spec. If no output and Parser_flags is greater than or ; equal to 64 it is ok. Otherwise go get some more information ; 10$: tstw Input_flag bneq 11$ ;got an input spec moval Iprompt,Prompt_adr ;go get an input spec. pushal Message_len pushaq Prompt_desc pushaq Mes_desc calls #3,g^lib$get_input ;get input spec cmpl #ss$_normal,R0 beql 111$ $exit_s ; or something quit 111$: tstw Message_len beql 10$ ;null input. try again jmp Upper 11$: tstw Parser_flags ;check parser flag to see if we beql 12$ ;need an output spec for one of the bitl #127,Parser_flags;flags that are set beql 15$ ;less than 128 means you have to have 12$: tstw Output_flag ;an output spec bneq 15$ moval Oprompt,Prompt_adr ;go get an output spec moval Omessage,Mes_adr pushal Message_len pushaq Prompt_desc pushaq Mes_desc calls #3,g^lib$get_input ;get output spec cmpl #ss$_normal,R0 beql 13$ $exit_s ; or something quit 13$: tstw Message_len beql 11$ ;null input go try again jmp Upper ; ; Check the flags for ambiguity ; 15$: bitl #Flag_800,Parser_flags beql 16$ bitl #Flag_1600,Parser_flags ;can't have 1600 and 800 beql 16$ jmp Error_800 ; 16$: bitl #Asc_flag,Parser_flags beql 20$ ;Can't convert to ascii and ebcdic movb #64,Fill_char ;fill char is ebcdic bitl #Ebc_flag,Parser_flags beql 20$ jmp Error_ebc ;ebc and asc flags set 20$: bitl #Lterm_flag,Parser_flags;check for lterm and block flag beql 30$ bitl #Block_flag,Parser_flags beql 30$ jmp Error_tra_blo ; 30$: ;check to see if blocking factor is greater that 8192 cmpl #8192,Block_num bgeq Start ;its ok jmp Error_blo_large ; ; See where the magtape is ; Start: cmpc3 #1,Mt,@Infile_adr tstw R0 bneq 10$ ;not on input ; movl Infile_adr,R1 ;check end of line to be sure addl Infile,R1 ;there is a colon. If not the decl R1 ;filename might just start cmpc3 #1,Colon,(R1) ;with MT tstw R0 bneq 10$ ;no colon at end of line not here movw #1,Mtin ; 10$: tstw Output_flag beql 13$ ;see if we have an output spec cmpc3 #1,Mt,@Outfile_adr tstw R0 bneq 13$ ;not on output ; movl Outfile_adr,R1 addl Outfile,R1 decl R1 cmpc3 #1,Colon,(R1) tstw R0 bneq 13$ ;not on output must be a filename movw #1,Mtout ; ; Check to see if we found a mag tape device ; 13$: tstw Mtin bneq Assign_lun tstw Mtout bneq Assign_lun jmp Error_nomt ;no magtape found tell him about it ; .sbttl Assign luns to devices ; ; Assign_lun: ; ; Set the mtmode flag -1 d>m 0 m>d 1 m>m 2 magtape only ; cmpw Mtin,Mtout ;is it magtape to magtape bneq 1$ ;no movw #1,Mtmode brw 5$ 1$: tstw Mtin ;is it magtape to disk or magtape only beql 3$ ;no tstw Output_flag ;do we have an output spec bneq 2$ ;yes movw #2,Mtmode ;must be just position the tape brw 5$ 2$: movw #0,Mtmode ;must be magtape to disk brw 5$ 3$: movw #-1,Mtmode ;must be disk to magtape 5$: bitl #All_flag,Parser_flags ;check for all flag bneq 10$ ;got one jmp Assign_to_magtapes ;not set 10$: tstw Mtmode ;check to see if the transfer is mag to mag bgtr Assign_to_magtapes jmp Error_all ; ; Assign the magtapes to luns. ; Assign_to_magtapes: tstw Mtin beql 10$ $assign_s Chan=Mtin_lun, - Devnam=Infile Error_signal movw Mtin_lun,Mtuse_lun ;save input tape lun in Mtuse_lun ;we will use this for rewinds, skip ;files etc. 10$: tstw Mtout beql Assign_file $assign_s Chan=Mtout_lun, - Devnam=Outfile Error_signal tstw Mtin ;see if input device is a magtape bneq Assign_file ;yes movw Mtout_lun,Mtuse_lun ;save output tape lun in Mtuse_lun ;for rewinds etc. ; ; ; Now go and assign a lun to the file we are going to use ; Assign_file: tstw Mtmode bleq 10$ ;we have to open up a disk file ; jmp Position_tape ;no files to open 10$: tstw Mtin ;is input from magtape beql 20$ jmp Open_output ;go open up an output file ; ; Open up an existing file to put on tape ; 20$: $fab_store fab=Infab,- fna=@Infile_adr,- fns=Infile,- fac=,- rfm=var $open fab=R0 ;open up input file ; Error_signal ; $rab_store rab=Inrab,- ;connect rab to fab Ubf=Inbuf,- Usz=#Inbuf_len $connect rab=R0 ; Error_signal ; jmp Position_tape ; ; Open_output: ; ; Open up a new file ; $fab_store fab=Outfab,- fna=@Outfile_adr,- fns=Outfile,- fac=,- rfm=var,- rat= $create fab=R0 ;create new file ; Error_signal ; $rab_store rab=Outrab,- ;connect rab to fab ubf=Outbuf,- usz=#Outbuf_len,- rbf=Outbuf $connect rab=R0 ; Error_signal ; .sbttl Position the magtape ; ; Now position the tape who's lun is in Mtuse_lun ; Position_tape: ; ; ; Now let's do the commands that can be given to position the tape or ; write an end of volume mark. Use the following hiearchy ; ; flag_800,flag_1600 on mt only or on output tape ; it doesn't matter on a read because TU77 ; sinse it. ; rewind_flag ; File_flag ; record_flag ; endvolume_flag ; bitl #Flag_800,Parser_flags bneq 10$ jmp Chk_1600 ; set tape to 800 bpi 10$: insv #Mt$k_nrzi_800,#Mt$v_density,#Mt$s_density,Tape_density $qiow_s chan=Mtuse_lun, func=#io$_setmode,p1=Tape_mode,- iosb=Io_status Tape_check jmp Chk_rew Chk_1600: bitl #Flag_1600,Parser_flags bneq 10$ jmp Chk_rew 10$: insv #Mt$k_pe_1600,#Mt$v_density,#Mt$s_density,Tape_density $qiow_s chan=Mtuse_lun, func=#io$_setmode,p1=Tape_mode,- iosb=Io_status Tape_check ; Chk_rew: bitl #Rewind_flag,Parser_flags bneq 10$ jmp Chk_file ; 10$: $qiow_s chan=Mtuse_lun, func=#io$_rewind,- iosb=Io_status Tape_check ; Chk_file: bitl #File_flag,Parser_flags bneq 10$ jmp Chk_record ; 10$: cvtlw File_num,File_num $qiow_s chan=Mtuse_lun, func=#io$_skipfile,- iosb=Io_status, P1=@File_num Tape_check Chk_record: bitl #Record_flag,Parser_flags bneq 10$ jmp Eof_write ; 10$: cvtlw Record_num,Record_num $qiow_s chan=Mtuse_lun, func=#io$_skiprecord,- iosb=Io_status, P1=@Record_num Tape_check ; Eof_write: bitl #Endvolume_flag,Parser_flags bneq 5$ jmp Done_check ; ; Write end of file mark only to Mtout_lun if output is a magtape ; otherwise use mtUse_lun ; 5$: tstw Mtout bneq 10$ ;use mtout_lun jmp 20$ ;write to mtuse_lun 10$: $qiow_s chan=Mtout_lun,func=#io$_writeof,iosb=Io_status Tape_check $qiow_s chan=Mtout_lun,func=#io$_writeof,iosb=Io_status Tape_check jmp Done_check ; 20$: $qiow_s chan=Mtuse_lun,func=#io$_writeof,iosb=Io_status Tape_check $qiow_s chan=Mtuse_lun,func=#io$_writeof,iosb=Io_status Tape_check Done_check: tstw Output_flag ;was it just a position tape command bneq Transfer ;no jmp done ;yes got to done ; .sbttl Buffer and copy data ; ; No more excuses, move the data from here to there ; Transfer: ; clrl Transfer_count ;clear the number of records read moval Inbuf,Buf_start calls #0,Get_data ;force first read from input tstw Error_found ;any error bneq Done ;yes tstw Eof_flag ;eof on first read. either a null bneq Done ;file or end of volume. quit calls #0,Buffer_data ;buffer and write data out ; ; check to see if he has the all_flag set. if so go back to transfer ; and do it again until the first Get_data returns a eof ; bitl #All_flag,Parser_flags beql Done clrw Eof_flag jmp Transfer ; Done: movl R0,R5 ;save error $close fab=infab ;close infab and outfab $close fab=outfab tstl Convers ;are we in conversational mode beql 1$ ;yes tstw Error_found bneq 1$ ;leave on error anyway jmp Begin_convers 1$: $exit_s R5 ; ; .sbttl Error routines ; ; Come here to output error messages ; Amb_error: $output chan=TT_chan, - ;Ambiguous symbol length=#13, - buffer=amb brw Line_out Syntax_error: $output chan=TT_chan, - ;Syntax error length=#13, - buffer=syn Line_out: $output chan=TT_chan, - ;put out the part of the length=Syn_len, - ;string where the parsing buffer= @Syn_adr ;error occured jmp done ;exit ; ; Error_800: $output chan=TT_chan, - length=#Er_800_len, - buffer=Er_800 ; write out multiple density error jmp done ; Error_all: $output chan=TT_chan, - length=#Er_all_len, - buffer=Er_all ; write out copy all flag error jmp done ; Error_ebc: $output chan=TT_chan, - length=#Er_ebc_len, - buffer=Er_ebc ; write out ebc asc error jmp done ; Error_nomt: $output chan=TT_chan, - length=#Er_nomt_len, - buffer=Er_nomt ; write out no magtape error jmp done ; Error_longrec: $output chan=TT_chan, - length=#Er_long_rec_len, - buffer=Er_long_rec ; write out long record error jmp done ; Error_tra_blo: $output chan=TT_chan, - length=#Er_trans_block_len, - buffer=Er_trans_block ; write out block and lterm error jmp done ; Error_blo_large: $output chan=TT_chan,- length=#Er_block_large_len,- buffer=Er_block_large ;write large block error jmp done ; .sbttl Get Put & Buffer subroutines ; ; .entry Get_data,^M ; ; Subroutine to get data from the current input device ; It assumes that the input buffer address is in Buf_start ; bitl #Transfer_flag,Parser_flags beql 5$ ; ; check transfer count, if it exceeds the number of records he ; wants, don't read any more and set the eof flag ; cmpl Transfer_count,Transfer_num bneq 5$ ;go read some more ; movw #1,Eof_flag ret ; 5$: tstw Mtmode bgeq Get_from_tape ; movl Buf_start,Inrab+rab$l_ubf $get rab=Inrab,err=Disk_error movw Inrab+rab$w_rsz,Get_len cmpw #8192,@#Get_len blss 10$ incl Transfer_count ;increment no. of records read jmp Get_done ; 10$: movw #1,Error_found jmp Error_longrec ret ; Get_from_tape: movl Buf_start,R0 $qiow_s chan=Mtin_lun ,func=#io$_readlblk,iosb=Io_status,- p1=(R0),p2=#Inbuf_len Tape_check movw Io_count,Get_len cmpw #8192,@#Get_len blss 10$ incl Transfer_count ;increment no. of records read jmp Get_done ; 10$: movw #1,Error_found jmp Error_longrec ret ; Get_done: bitl #Blank_flag,Parser_flags;Blank fill ? bneq Fill ;yes ret ; Fill: cmpw Blank_num,Get_len bgtr 10$ ;go fill with Fill_char ret ; 10$: movc5 @#Get_len,@Buf_start,@#Fill_char,@#Blank_num,@Buf_start cvtlw Blank_num,Get_len ret ; .entry Put_data,^M ; ; Subroutine to put data to the current output device ; ; Check to see if we need to convert ascii to ebcdic or th otherway ; bitl #Asc_flag,Parser_flags ;convert ascii to ebcdic beql Check_ebc ; ; convert from ascii to ebcdic. build descripter and call conversion ; routine. ; cvtwl Put_len,Trans_desc ;is a or 64 pushal Trans_desc pushal Trans_desc calls #2,g^lib$tra_asc_ebc cmpl #ss$_normal,R0 bneq 10$ jmp Put_it ; 10$: $output chan=TT_chan,- length=#Er_trans_len,- buffer=Er_trans jmp Put_it ; Check_ebc: ; bitl #Ebc_flag,Parser_flags ;convert ebcdic to ascii beql Put_it ;no ; ; convert from ebcdic to ascii. build descripter and call conversion ; routine. ; cvtwl Put_len,Trans_desc ;a #32 pushal Trans_desc pushal Trans_desc calls #2,g^lib$tra_ebc_asc cmpl #ss$_normal,R0 bneq 10$ jmp Put_it ; 10$: $output chan=TT_chan,- length=#Er_trans_len,- buffer=Er_trans ; Put_it: tstw Mtmode bneq Put_to_tape ; movw Put_len,Outrab+rab$w_rsz $put rab=Outrab,err=Disk_error ret ; ; Put_to_tape: cmpw Put_len,#14 ;we have to have at least 14 bytes bgeq 10$ ;for a write to tape. Fill if necessary ; movc5 @#Put_len,Outbuf,@#Fill_char,#14,Outbuf ;fill with blanks movw #14,Put_len 10$: $qiow_s chan=Mtout_lun ,func=#io$_writelblk,iosb=Io_status,- p1=Outbuf,p2=@#Put_len Tape_check ret ; .entry Buffer_data,^M ; ; buffer data up and put it in Outbuf. Buffer it one of three ; ways. 1. just move data to outbuf 2. block or deblock data to a ; given record size. 3. deblock data when a given lineterminator is ; found ; bitl #Block_flag,Parser_flags ;block data beql 10$ ;no jmp Block_move 10$: bitl #Lterm_flag,Parser_flags ;deblock data with lterm beql Just_move ;no jmp Lterm_move ; ; No blocking so just move data to Outbuf ; Just_move: movw Get_len,R0 movc3 R0,@Buf_start,Outbuf movw Get_len,Put_len calls #0,Put_data ; calls #0,Get_data ; tstw Eof_flag ;did we find an end of file mark beql 5$ jmp Finished 5$: tstw Error_found beql 10$ jmp Finished ; 10$: jmp Just_move ; ; ; ; ; ; ; block data to a given record size ; Block_move: clrl R6 cvtlw Block_num,Put_len Block_start: tstw Eof_flag ;are we done yet beql 10$ ;no jmp Finished ;yes ; 10$: addw2 Get_len,R6 ;R6 contains the sum of bytes read in cmpl R6,Block_num ;do we have a block yet blss Block_get_more ;no jmp Block_put ;yes go write it out ; Block_get_more: addw2 Get_len,Buf_start ;offset input buffer address calls #0,Get_data ;get somemore data tstw Eof_flag ;eof found beql 30$ ;no tstl R6 ;yes anything left in input buffer bneq 10$ ;yes jmp Finished ;no go quit ; ; something left in input buffer ; move to output and fill if needed with what is in fill_char ; 10$: movc5 R6,Inbuf,@#Fill_char,@#Block_num,Inbuf jmp Block_put ;put it out ; 30$: tstw Error_found ;any errors beql 40$ ;no jmp Finished ;error go quit 40$: jmp Block_start ;go do it again ; Block_put: movc3 @#Block_num,Inbuf,Outbuf ;move block_num characters calls #0,Put_data ;and write them out ; subl2 @#Block_num,R6 ;how many characters left in inputbuf bleq 10$ ;none ; moval Inbuf,Buf_start addl2 @#Block_num,Buf_start movc3 R6,@Buf_start,Inbuf ;move them to top of input buf moval Inbuf,Buf_start ;offset buf_start by no. of chars. addl2 R6,Buf_start clrw Get_len ;go get some more data jmp Block_start ; 10$: clrl R6 ;empty input buffer so let's clear clrw Get_len ;everything we need to and go get some moval Inbuf,Buf_start ;more data jmp Block_start ; ; ; ; ; Deblock the file to records that end in the character stored in ; Lterm_num ; ; Lterm_move: clrl R6 ;clear character count Lterm_start: tstw Eof_flag ;done yet beql 10$ jmp Lterm_finished ;yes 10$: tstw Error_found beql 20$ jmp Finished ;error go quit ; 20$: addw2 Get_len,R6 cmpw #8192,R6 blss 30$ ;record size ok jmp Lterm_ok ; 30$: movw #1,Error_found $output chan=TT_chan,- length=#Er_block_large_len,- buffer=Er_block_large ;write large block error jmp Finished ; Lterm_ok: locc Lterm_num,R6,Inbuf tstw R0 bneq 10$ jmp Lterm_get_more ; 10$: subw3 R0,R6,Put_len incw Put_len movc3 @#Put_len,Inbuf,Outbuf calls #0,Put_data ;write it out ; cmpw Put_len,R6 bneq 20$ clrl R6 moval Inbuf,Buf_start jmp Lterm_get_more ; 20$: subw Put_len,R6 moval Inbuf,Buf_start addl2 @#Put_len,Buf_start ;move remaining data to top of inbuf movc3 R6,@Buf_start,Inbuf moval Inbuf,Buf_start addl2 R6,Buf_start clrw Get_len jmp Lterm_start ; ; Lterm_get_more: addw2 Get_len,Buf_start calls #0,Get_data tstw Eof_flag beql 10$ jmp Lterm_finished 10$: tstw Error_found beql 20$ jmp Finished ;quit on error ; 20$: jmp Lterm_start ; ; ; Lterm_finished: ; ; Finish buffering remaining data out. If a termination character ; is not found for the last record, just pu it out ; locc Lterm_num,R6,Inbuf tstw R0 bneq 10$ tstw R6 beql 5$ movw R6,Put_len movc3 R6,Inbuf,Outbuf calls #0,Put_data 5$: jmp Finished ; 10$: subw3 R0,R6,Put_len incw Put_len movc3 @#Put_len,Inbuf,Outbuf calls #0,Put_data ; cmpw Put_len,R6 bneq 20$ jmp Finished ; 20$: subw Put_len,R6 moval Inbuf,Buf_start addl2 @#Put_len,Buf_start movc3 R6,@Buf_start,Inbuf moval Inbuf,Buf_start addl2 R6,Buf_start jmp Lterm_finished ; ; ; Finished: tstw Mtout ;was output device a magtape beql 10$ ; ; write and end_of_file mark to mtout_lun ; $qiow_s chan=Mtout_lun,func=#io$_writeof,iosb=Io_status Tape_check ; 10$: ret ; .entry Disk_error,^M ; cmpw #ss$_normal,R0 beql 20$ ; movl 4(ap),R0 cmpl #rms$_eof,rab$l_sts(R0) bneq 10$ movw #1,Eof_flag jmp 20$ ; 10$: pushl rab$l_stv(R0) pushl rab$l_sts(R0) calls #2,lib$signal movw #1,Error_found 20$: ret .sbttl Parser table .psect Tabled,rd,wrt,noexe $INIT_STATE UFD_STATE,UFD_KEY ; ; scan for options ; $STATE OPTIONS $TRAN TPA$_EOS,TPA$_EXIT ;done $TRAN '/',QUALIFIER ;got a switch $TRAN !FILE_NAME,OPTIONS ;must be a file or tape spec $STATE QUALIFIER ;check for known switches $TRAN '1600_BPI',OPTIONS,,FLAG_1600,PARSER_FLAGS $TRAN '800_BPI',OPTIONS,,FLAG_800,PARSER_FLAGS $TRAN 'ALL_FILES',OPTIONS,,ALL_FLAG,PARSER_FLAGS $TRAN 'ASC_EBC',OPTIONS,,ASC_FLAG,PARSER_FLAGS $TRAN 'BLANK_FILL',PARSE_BLANK,,BLANK_FLAG,PARSER_FLAGS $TRAN 'BLOCKING_FACTOR',PARSE_BLOCK,,BLOCK_FLAG,PARSER_FLAGS $TRAN 'EBC_ASC',OPTIONS,,EBC_FLAG,PARSER_FLAGS $TRAN 'END_OF_VOLUME',OPTIONS,,ENDVOLUME_FLAG,PARSER_FLAGS $TRAN 'FILE_SKIP',PARSE_FILE,,FILE_FLAG,PARSER_FLAGS $TRAN 'LINE_TERMINATOR',PARSE_LINE,,LTERM_FLAG,PARSER_FLAGS $TRAN 'RECORD_SKIP',PARSE_RECORD,,RECORD_FLAG,PARSER_FLAGS $TRAN 'REWIND',OPTIONS,,REWIND_FLAG,PARSER_FLAGS $TRAN 'TRANSFER_COUNT',PARSE_TRANSFER,,TRANSFER_FLAG,PARSER_FLAGS $TRAN TPA$_ANY,ERROR,STORE_ERR $STATE ERROR ;error out and return $TRAN TPA$_LAMBDA,TPA$_FAIL ; ; Get record length for blank fill ; $STATE PARSE_BLANK $TRAN '=' $STATE $TRAN TPA$_DECIMAL,OPTIONS,,,BLANK_NUM ; ; Get number of records to read from tape ; $STATE PARSE_TRANSFER $TRAN '=' $STATE $TRAN TPA$_DECIMAL,OPTIONS,,,TRANSFER_NUM ; ; Get blocking record size ; $STATE PARSE_BLOCK $TRAN '=' $STATE $TRAN TPA$_DECIMAL,OPTIONS,,,BLOCK_NUM ; ; Get Line_terminator ; $STATE PARSE_LINE $TRAN '=' $STATE $TRAN TPA$_DECIMAL,OPTIONS,,,LTERM_NUM ; ; Get number of records to skip ; $STATE PARSE_RECORD $TRAN '=' $STATE $TRAN '-',,,-1,SIGN_FLAG $TRAN '+',,,+1,SIGN_FLAG $TRAN TPA$_LAMBDA $STATE $TRAN TPA$_DECIMAL,OPTIONS,NEGATIVE,,RECORD_NUM ; ; Get number of files to skip ; $STATE PARSE_FILE $TRAN '=' $STATE $TRAN '-',,,-1,SIGN_FLAG $TRAN '+',,,+1,SIGN_FLAG $TRAN TPA$_LAMBDA $STATE $TRAN TPA$_DECIMAL,OPTIONS,NEGATIVE,,FILE_NUM ; ; Get a file name string ; $STATE FILE_NAME $TRAN TPA$_ANY,GET_NAME,BLANK_ON ;process untill a blank $TRAN TPA$_ANY,ERROR,STORE_ERR ; $STATE GET_NAME $TRAN TPA$_EOS,TPA$_EXIT,BLANK_OFF $TRAN TPA$_BLANK,OPTIONS,BLANK_OFF $TRAN '/',QUALIFIER,BLANK_OFF $TRAN TPA$_ANY,GET_NAME,NAME_ADD ; $END_STATE ; ; .sbttl Parser Action Routines .psect actcode,rd,nowrt,exe ; ; Add to name string ; NAME_ADD: .WORD 0 ; ; Routine used to increment the character length in the ; input or output file ; tstw Output_flag beql 20$ ;not infile must be outfile incl Outfile ;increment string length ret 20$: incl Infile ;increment string length ret ; ; Check sign of number and change if needed ; Negative: .word 0 tstl Sign_flag beql 50$ ;not negative ; clrl Sign_flag ;set to default of positive mull2 #-1,TPA$L_NUMBER(AP) ; 50$: ret ; ; Turn blank processing off ; BLANK_OFF: .WORD 0 bbcc #TPA$V_BLANKS,TPA$L_OPTIONS(AP),10$ 10$: ret ; ; Turn blank processing on ; BLANK_ON: .word 0 bbss #TPA$V_BLANKS,TPA$L_OPTIONS(AP),10$ 10$: bbss #1,Input_flag,20$ movq TPA$L_TOKENCNT(AP),Infile ;move address to infile ret ; 20$: bbss #1,Output_flag,30$ movq TPA$L_TOKENCNT(AP),Outfile ;move address to outfile ret ; 30$: movl #SS$_IVLOGNAM,R0 ;already have input and movq TPA$L_STRINGCNT(AP),Syn_len ;output spec. error out subl #TPA$L_TOKENCNT,Syn_len+4 addl #TPA$L_TOKENCNT,Syn_len ret ; ; Syntax error return string ; store_err: .word 0 bitl #TPA$M_AMBIG,TPA$L_OPTIONS(AP) ;ambigous error? beql 10$ movw #1,Syn_Amb ;syntax error brw 20$ 10$: movw #0,Syn_Amb 20$: movq TPA$L_TOKENCNT(AP),Syn_len ;move address of current subl #1,Syn_len+4 ;position in string to addl #1,Syn_len ;syn_len for error reporting ret ; .end MGT