; * * * * * * * * * * * * * * * version 2.7 * * * * * * * * * * * * * * * ; [31] Fix display of file renaming. ; RonB, 05/05/84 ; [30c] Isolate ANSI escape sequences for machine independence. ; [29g] Add 8th bit quoting ; RonB, 04/15/84 ; * * * * * * * * * * * * * * * version 2.6 * * * * * * * * * * * * * * * ; [28d] Improve input filename processing, allow valid special chars ; RonB, 03/27/84 ; [23] Modification to GTCEOF to fix ASCII mode transfer ; * * * * * * * * * * * * * * * version 2.4 * * * * * * * * * * * * * * * ; [Rg] ^X/^Z file interruption. Slight mod to GTNFIL. Rg, 2/84 ; * * * * * * * * * * * * * * * version 2.1 * * * * * * * * * * * * * * * ; [par] Added calls to set parity, strip parity on input if ; other than none parity is called for. ; JD, 2/84 ; [16] Add file-mode ASCII or BINARY processing. ; RonB,01/02/84 ; [11] Capitalize and parse filename being received. ; RonB,12/27/83 ; [9] Fix filename parsing, and add wildcard ability. ; RonB,12/26/83 ; * * * * * * * * * * * * * * * version 2.0 * * * * * * * * * * * * * * * CSEG $ ; Get the file name (including host to micro translation) gofil: lea bx, data ;Get the address of the file name. mov datptr, bx ;Store the address. lea bx, fcb+1 ;Address of the FCB. mov fcbptr, bx ;Save it. mov ax, 0 mov temp1, ax ;Initialize the char count. mov temp2, ax lea si, fcb mov [si], ah ;Set the drive to default to current. mov ch, ' ' gofil1: mov [bx], ch ;Blank the FCB. inc bx inc ah cmp ah, 0BH ;Twelve? jl gofil1 gofil2: mov bx, datptr ;Get the NAME field. mov ah, [bx] inc bx mov datptr, bx cmp ah, '.' ;Seperator? jne gofil3 ;No. lea bx, fcb+9H mov fcbptr, bx mov ax, temp1 mov temp2, ax mov temp1, 9H jmp gofil6 gofil3: cmp ah, 0 ;Trailing null? jz gofil7 ;Then we're done. call gofl20 ;Capitalize, and replace strange chars ;[11] mov bx, fcbptr mov [bx], ah inc bx mov fcbptr, bx mov ax, temp1 ;Get the char count. inc ax mov temp1, ax cmp ax, 8H ;Are we finished with this field? jl gofil2 gofil4: mov temp2, ax mov bx, datptr mov ah, [bx] inc bx mov datptr, bx cmp ah, 0 jz gofil7 cmp ah, '.' ;Is this the terminator? jne gofil4 ;Go until we find it. gofil6: mov bx, datptr ;Get the TYPE field. mov ah, [bx] inc bx mov datptr, bx cmp ah, 0 ;Trailing null? jz gofil7 ;Then we're done. call gofl20 ;Capitalize, and replace strange chars ;[11] mov bx, fcbptr mov [bx], ah inc bx mov fcbptr, bx inc temp1 ;Increment char count. cmp temp1, 0CH ;Are we finished with this field? jl gofil6 gofil7: lea si, fcb+1 ;Move parsed filename into data ;[11] begin lea di, data ; for printing. mov cx, 8 gofl71: mov al, [si] ;First the eight (or less) chars in the name inc si cmp al, ' ' je gofl72 mov [di], al inc di loop gofl71 gofl72: mov al, '.' ;Then a period mov [di], al inc di lea si, fcb+9 mov cx, 3 gofl73: mov al, [si] ;Then the three (or less) chars in the ext. inc si cmp al, ' ' je gofl74 mov [di], al inc di loop gofl73 gofl74: mov al, '$' ;Follow all with a $ to terminate. mov [di], al call clrfln lea dx, data ;Print the file name. call tmsg cmp flwflg, 0 ;Is file warning on? jnz gf7x jmp gofil9 ;If not, just proceed. gf7x: lea dx, fcb call openf ;See if the file exists. cmp al, 0FFH ;Does it exist? jnz gf8x jmp gofil9 ;If not create it. gf8x: lea dx, scrfr ;Move cursor. call poscur ;[30c] lea dx, infms5 ;Inform the user we are renaming the file. call tmsg mov ax, temp2 ;Get the number of chars in the file name. cmp ax, 0 jne gofil8 mov ax, temp1 mov temp2, ax gofil8: mov ch, 0 mov cl, al mov al, 0 ;Says if first field is full. cmp cl, 9H ;Is the first field full? jne gofl81 mov al, 0FFH ;Set a flag saying so. dec cl gofl81: lea bx, fcb ;Get the FCB. add bx, cx ;Add in the character number. mov ah, '&' mov [bx], ah ;Replace the char with an ampersand. push ax push bx lea dx, fcb ;See if the file exists. call openf pop bx cmp al, 0FFH ;Does it exist? pop ax jz gofl89 ;If not create it. cmp al, 0 ;Get the flag. jz gofl83 dec cl ;Decrement the number of chars. cmp cl, 0 jz gofl88 ;If no more, die. jmp gofl81 gofl83: inc cl ;Increment the number of chars. cmp cl, 9H ;Are we to the end? jl gofl81 ;If not try again ;else fail. gofl88: lea dx, screrr call poscur ;[30c] lea dx, ermes4 ;Tell the user that we can't rename it. call tmsg ret gofl89: push dx lea dx, fcb ;Print the file name. ;[31] call tfile ;[31] pop dx gofil9: lea dx, fcb ;Delete the file if it exists. call delete mov ax, 0 lea si, fcb+0CH mov [si], ax ;Zero current block. lea si, fcb+0EH mov [si], ax ;Same for Lrecl. lea si, fcb+20H mov [si], ah ;Zero the current record (within block). inc si mov [si], ax ;Zero record (within file). lea si, fcb+23H mov [si], ax lea dx, fcb ;Now create it. call create cmp al, 0FFH ;Is the disk full? je gf9x jmp rskp gf9x: lea dx, screrr ;Position cursor. call poscur ;[30c] lea dx, erms11 call tmsg ret ; Make sure character in ah is a legal filename character: ;[11] begin ; Mask 8th bit, capitalize, and replace all illegal ; special characters with '#' gofl20: and ah, 7Fh ;mask eighth bit ;[28d] cmp ah, '0' ;Check for digit jb gofl21 cmp ah, '9' jbe gofl23 cmp ah, 'A' ;Check for uppercase letter jb gofl21 cmp ah, 'Z' jbe gofl23 cmp ah, 'a' ;Check for lowercase letter jb gofl21 cmp ah, 'z' ja gofl21 and ah, 137O ;Capitalize lowercase jmps gofl23 gofl21: push es ;Check list of special characters ;[28d] begin push cx ; which are legal in filenames pushf cld mov cx, ds mov es, cx ;Scan uses ES register. lea di, spchar ;Special chars. mov cx, 20 ;Twenty of them. mov al, ah ;Char is in al. repnz scasb ;Search string for input char. cmp cx, 0 ;Was it there? jnz gofl22 mov ah, '#' ;Replace illegal characters with '#' gofl22: popf pop cx pop es ;[28d] end gofl23: ret ;[11] end ; Save & restore wildcard FCB's ;[9] begin fcbcpy: cmp cl,0 je fcbcp2 mov ah, [bx] mov [di], ah dec cl inc bx inc di jmp fcbcpy fcbcp2: ret ;[9] end ; Open up the file and set up the FCB. getfil: mov filflg, 0FFH ;Nothing in the DMA. mov eoflag, 0 ;Not the end of file. mov fcb+0CH, 0 ;Zero the current block number. mov fcb+0EH, 0 ;Must be zero for MAKEF or OPENF. mov fcb+20H, 0 ;Zero the current record. lea dx, fcb call openf ;Open the file. jmp rskp gtnfil: cmp cxzflg, 'Z' ;[Rg] file interrupt flag set to 'Z'? je gtn5 ;[Rg] if yes we're done. cmp wldflg, 0 ;Was there a "*"? je gtn5 ;Nope. lea bx, cpfcb ;Get FCB from last check for file. ;[9] begin lea di, fcb ;Copy to FCB. mov cl,37 ;Size of FCB. call fcbcpy gtn2: call gtjfn ;Get the first file again mov cl, wldflg ;And the count of how many to skip mov ch,0 gtn3: push cx mov dx,offset fcb ;More files? call gnjfn pop cx cmp al,0FFH je gtn5 loop gtn3 add wldflg, 1 ;Indicate one more file found push ax ;save directory offset mov bx,offset fcb mov di,offset cpfcb mov cl,37 call fcbcpy ;Copy from FCB. mov di,offset fcb+1 ;Get name of next file to send. mov bx,offset dma+1 pop ax ;get directory offset mov cl, 5 ;multiply by 32 shl al, cl mov ah, 0 add bx, ax ;add to the buffer pointer mov cl,11 call fcbcpy call getfil ;Initialize jmp r jmp rskp ;[9] end gtn5: mov wldflg, 0 ;Reset wild card flag. ret ; Output the chars in a packet. ptchr: mov temp1, ax ;Save the size. lea bx, data ;Beginning of received packet data. mov outpnt, bx ;Remember where we are. mov ch, rquote ;Quote char. ptchr1: dec temp1 ;Decrement # of chars in packet. jnl pt1 jmp rskp ;Return successfully if done. pt1: dec chrcnt ;Decrement number of chars in dta. jns ptchr2 ;Continue if space left. call outbuf ;Output it if full. jmp r ; Error return if disk is full. ptchr2: mov bx, outpnt ;Get position in packet data buffer. mov ah, [bx] ;Grab a char inc bx mov outpnt, bx ;and bump pointer. mov al, 00h ;First assume no 8th bit ;[29g] begin cmp ebquot, 'N' ;No 8th bit if we can't quote je ptch21 cmp ebquot, 'Y' ; or if we can but aren't. je ptch21 cmp ah, ebquot ;Is this the 8th bit quote character? jne ptch21 mov ah, [bx] ;Get the quoted character inc bx mov outpnt, bx dec temp1 ;Decrement # of chars in packet. mov al, 80h ;Set the 8th bit. ;[29g] end ptch21: cmp ah, ch ;Is it the quote char? jne ptchr4 ;If not proceed. mov ah, [bx] ;Get the quoted character inc bx mov outpnt, bx ;and bump pointer. dec temp1 ;Decrement # of chars in packet. mov dl, ah ;Save the parity bit in dl. ;[29g] begin and dl, 80H and ah, 7FH ;Turn off the parity bit. cmp ah, ch ;Is it the quote char? je ptchr3 ;If so just go write it out. cmp ebquot, 'N' ;No 8th bit if we can't quote je ptch22 cmp ebquot, 'Y' ; or if we can but aren't. je ptch22 cmp ah, ebquot ;Is this the 8th bit quote character? je ptchr3 ;If so, just go write it out. ptch22: add ah, 40H ;Make it a control char again. ;[29g] end and ah, 7FH ;Modulo 128. ptchr3: or ah, dl ;Or in the parity bit. ptchr4: or ah, al ;Or in the quoted 8th bit. ;[29g] mov bx, bufpnt ;Destination buffer. mov [bx], ah ;Store it. inc bx mov bufpnt, bx ;Update the pointer jmp ptchr1 ;and loop to next char. ; output the buffer, reset bufpnt and chrcnt outbuf: push bx push cx lea dx, fcb call soutr ;Write the record. pop cx pop bx cmp al, 0 ;Successful. jz outbf1 cmp al, 1 jz outbf0 lea dx, screrr call poscur ;[30c] lea dx, erms17 ;Record length exceeds DTA. call tmsg ret outbf0: lea dx, screrr call poscur ;[30c] lea dx, erms11 ;Disk full error. call tmsg ret outbf1: lea bx, dma ;Addr for beginning. mov bufpnt, bx ;Store addr for beginning. mov ax, bufsiz-1 ;Buffer size. mov chrcnt, ax ;Number of chars left. jmp rskp ; Get the chars from the file. gtchr: mov ch, squote ;Keep quote char in c. cmp filflg, 0 ;Is there anything in the DMA? jz gtchr0 ;Yup, proceed. mov cl, 0 ;No chars yet. call inbuf jmp gtceof ;No more chars, go return EOF. gtchr0: mov al, spsiz ;Get the maximum packet size. sub al, 5 ;Subtract the overhead. mov ah, 0 mov temp1, ax ;Number of chars we're to get. lea bx, filbuf ;Where to put the data. mov cbfptr, bx ;Remember where we are. mov cl, 0 ;No chars. gtchr1: dec temp1 ;Decrement the number of chars left. jns gtchr2 ;Go on if there is more than one left. mov al, cl ;Return the count in A. mov ah, 0 jmp rskp gtchr2: mov ax, chrcnt dec ax jl gtchr3 mov chrcnt, ax jmp gtchr4 gtchr3: call inbuf ;Get another buffer full. jmp gtceof cmp chrcnt, 0 jne gtchr4 sub cl, 2 ;Don't count controllified Z. mov al, cl mov ah, 0 jmp rskp gtchr4: mov bx, bufpnt ;Position in DMA. mov ah, [bx] ;Get a char from the file. inc bx mov bufpnt, bx cmp ebquot, 'N' ;Can we not do 8th bit quoting? ;[29g] begin je gtch41 cmp ebquot, 'Y' ;Or are we not? je gtch41 mov dh, ah and ah, 7Fh and dh, 80h ;Is the 8th bit set? je gtch41 ;If not, no need for quoting dec temp1 ;Decrement the number of characters left mov dh, ebquot ;Insert 8th bit quote char. in packet buffer mov bx, cbfptr mov [bx], dh inc cbfptr inc cl ;Count the character gtch41: mov dl, ah ;Save the char. ;[29g] end and dl, 80H ;Turn off all but parity. and ah, 7FH ;Turn off the parity. cmp ah, ' ' ;Compare to a space. jl gtchr5 ;If less then its a control char, handle it. cmp ah, del ;Is the char a delete? jz gtchr5 ;Go quote it. cmp ah, ch ;Is it the quote char? je gtch42 ;If so, insert it in the buffer ;[29g] begin cmp ebquot, 'N' ;Can we not do 8th bit quoting? je gtchr8 cmp ebquot, 'Y' ;Or are we not? je gtchr8 cmp ah, ebquot ;Is this the 8th bit quote character? jne gtchr8 ;If not, proceed gtch42: dec temp1 ;Decrement the chars remaining. ;[29g] end mov bx, cbfptr ;Position in character buffer. mov [bx], ch ;Precede char with send quote. inc cbfptr inc cl ;Increment the char count. jmp gtchr8 gtchr5: or ah, dl ;Turn on the parity bit. cmp ah, ('Z'-100O) ;Is it a ^Z? jne gtchr7 ;If not just proceed. cmp binflg, 0 ;ASCII file? ;[16] begin je gtceof ;If so, terminate cmp eoflag, 0 ;EOF flag set? ;[16] end jz gtchr6 ;If not just go on. mov bx, bufpnt mov ax, chrcnt mov dh, al ;Get number of chars left in DMA. gtch51: dec dh jns gtch52 ;Any chars left? mov chrcnt, 0 ;If not, say so. mov al, cl ;Return the count in A. mov ah, 0 jmp rskp gtch52: mov ah, [bx] ;Get the next char. inc bx ;Move the pointer. cmp ah, ('Z'-100O) ;Is it a ^Z? jz gtch51 ;If so see if they rest are. gtchr6: mov ah, ('Z'-100O) ;Restore the ^Z. gtchr7: xchg ah, al mov ah, 0 mov temp2, ax ;Save the char. dec temp1 ;Decrement char counter. mov bx, cbfptr ;Position in character buffer. mov [bx], ch ;Put the quote in the buffer. inc cbfptr inc cl ;Increment the char count. mov ax, temp2 ;Get the control char back. xchg al, ah add ah, 40H ;Make the non-control. and ah, 7FH ;Modulo 200 octal. gtchr8: or dl, dl ;Do we have parity? ;[29g] jz gtch81 ;If not, just send it. ;[29g] or ah, dl ;Or in the parity bit. cmp parflg,parnon ;[par] no parity? je gtch81 ;[par] yes, keep going and ah,7fh ;[par] else turn off parity from file ;[par]*** should probably mention that we're losing eighth bit here push ax ;[29g] begin push cx lea dx, scrhi ;mention that high bit is being lost call poscur ;[30c] lea dx, hibit call tmsg pop cx pop ax ;[29g] end gtch81: mov bx, cbfptr ;Position in character buffer. mov [bx], ah ;Put the char in the buffer. inc cbfptr inc cl ;Increment the char count. jmp gtchr1 ;Go around again. gtceof: cmp cl, 0 ;Had we gotten any data? je gteof0 ;Nope. mov filflg,0FFh ;[23] fix ASCII extra buffers at eof mov eoflag,0FFh ;[23] mov al, cl mov ah, 0 jmp rskp gteof0: mov ah, 0FFH ;Get a minus one. ret ;Input the next DMA buffer. inbuf: mov ah, eoflag ;Have we reached the end? cmp ah, 0 jz inbuf0 ret ;Return if set. inbuf0: push bx push cx lea bx, dma ;Set the r/w buffer pointer. mov bufpnt, bx lea dx, fcb call sinr cmp al, 0 ;End of file? je inbuf1 ;Still have data left. mov eoflag, 0FFH ;Set End-of-file. mov filflg, 0 ;Buffer not empty. mov chrcnt, 0 ;Say no characters. pop cx pop bx ret inbuf1: mov al, 80H ;Use as counter for number of chars read. pop cx pop bx cmp filflg, 0 ;Ever used DMS? jnz inbf21 ;Nope, then don't change count. dec al ;Fix boundary error. inbf21: mov ah, 0 ;Zero the flag (buffer not empty). mov chrcnt, ax ;Number of chars read from file. mov filflg, 0 ;Buffer not empty. jmp rskp DSEG $ temp1 dw 0 temp2 dw 0 dmaflg db 0 dma rb 80H filbuf rb 60H ;Character buffer. cpfcb rb 25H ;Save FCB in case of "*". rdbuf rb 80H cnt dw 0 fcb rb 33 chrcnt dw 0 ;Number of chars in the file buffer. filcnt dw 0 ;Number of chars left to fill. outpnt dw 0 ;Position in packet. bufpnt dw 0 ;Position in file buffer. fcbptr dw 0 ;Position in FCB. datptr dw 0 ;Position in packet data buffer. cbfptr dw 0 ;Position in character buffer. siz dw 0 ;Size of data from gtchr. filflg db 0 ;Non-zero when nothing in DMA buffer. filsiz rw 02H ;Double word for filesize (in bytes.) eoflag db 0 ;EOF flag;non-zero on EOF. binflg db 0 ;ASCII/Binary flag - 0 if ASCII file ;[16] wldflg db 0 ;Assume no "*" in fn.