title snip ;++ ; ; Program to snip data off of the beginning and/or end of a file. ; ; It seems it's not so easy to make unlabeled tapes these days... ; ; By John Wilson. ; ; 11/26/95 JMBW Created. ; ;-- .radix 8 ; lf= 12 cr= 15 ; bufl= 32768d ;length of file I/O buffer ; code segment assume cs:code org 100h ; start: cld mov dx,offset banner ;say hellow mov ah,09h ;func=print int 21h mov dx,offset nomem ;assume no memory cmp sp,offset pdl ;make sure we have enough memory jb error1 getfn: ; get filename mov dx,offset prmpt1 ;point at prompt call getln ;get a line jcxz getfn ;loop if none mov dx,si ;copy ptr add si,cx ;pt at end mov byte ptr [si],0 ;mark it mov ax,3D02h ;func=open for R/W int 21h mov dx,offset opnerr ;[assume open error] jc error1 mov ds:handle,ax ;save handle ; get # bytes to chop off at begn mov dx,offset prmpt2 ;point at prompt call getno ;get a number mov ds:stacnt,ax ;save mov ds:stacnt+2,dx ; get # bytes to chop off at end mov dx,offset prmpt3 ;point at prompt call getno ;get a number mov ds:endcnt,ax ;save mov ds:endcnt+2,dx ; find length of file xor dx,dx ;offset=0000:0000 xor cx,cx mov bx,ds:handle ;get handle mov ax,4202h ;func=seek to EOF+0000:0000 int 21h jnc savlen serr1: mov dx,offset sekerr ;seek failed error1: ; bomb, dx=error msg mov ah,09h ;func=print int 21h mov ax,4C01h ;func=bomb int 21h savlen: ; dx:ax=length of file sub ax,ds:stacnt ;subtract off starting count sbb dx,ds:stacnt+2 jc bdcnt sub ax,ds:endcnt ;subtract off ending count sbb dx,ds:endcnt+2 jc bdcnt mov ds:flen,ax ;save mov ds:flen+2,dx mov bx,ds:stacnt ;see if there was any starting count or bx,ds:stacnt+2 jz trunc1 ;no mov ds:fcnt,ax ;init counter mov ds:fcnt+2,dx jmp short copy1 ;into loop bdcnt: mov dx,offset badcnt ;pt at msg jmp short error1 trunc1: jmp trunc2 copy1: ; seek to position for next read mov dx,ds:stacnt ;get starting posn mov cx,ds:stacnt+2 mov bx,ds:handle ;handle mov ax,4200h ;func=seek from BOF int 21h jc serr1 ;seek error ; read next bufferload mov dx,offset buf ;pt at buf mov cx,bufl ;length of buf cmp ds:fcnt+2,0 ;do we have at least 64KB left? jnz copy2 cmp ds:fcnt,cx ;got at least that much? ja copy2 mov cx,ds:fcnt ;no, take what there is copy2: mov ah,3Fh ;func=read int 21h mov dx,offset rderr ;[assume error] jc error1 cmp ax,cx ;get what we wanted? jne error1 ;we should have ; seek to position for next write push cx ;save mov dx,ds:wpos ;get posn mov cx,ds:wpos+2 mov ax,4200h ;func=seek from BOF int 21h jc serr2 ;error pop cx ;restore ; write next bufferload mov dx,offset buf ;pt at buf mov ah,40h ;func=write int 21h mov dx,offset wrerr ;[assume error] jc error2 cmp ax,cx ;wrote it all? jne error2 ;we should have ; update positions add ds:wpos,ax ;write posn adc ds:wpos+2,0 add ds:stacnt,ax ;read posn adc ds:stacnt+2,0 sub ds:fcnt,ax ;count it off sbb ds:fcnt+2,0 mov ax,ds:fcnt ;anything left? or ax,ds:fcnt+2 jnz copy1 ;loop if so trunc2: ; truncate file to size mov dx,ds:flen ;get final length mov cx,ds:flen+2 mov bx,ds:handle ;file handle mov ax,4200h ;func=seek from BOF int 21h jc serr2 ;seek error mov dx,offset buf ;not like it matters xor cx,cx ;count=0 mov ah,40h ;func=write int 21h mov dx,offset wrerr ;[assume error] jc error2 mov ah,3Eh ;func=close int 21h int 20h ;later serr2: jmp serr1 ;couldn't reach error2: jmp error1 ;+ ; ; Get a decimal number from the keyboard. ; ; bx prompt ; dx:ax return number ; ;- getno: call getln ;get a line xor bx,bx ;init xor dx,dx jcxz getno2 ;nothing, keep the 0 getno1: lodsb ;get a char sub al,'0' ;convert cmp al,9d ;digit? ja getno3 ;no cbw ;ah=0 mov di,ax ;save mov ax,10d ;high word *10. mul dx xchg ax,bx ;save result, get low word mov dx,10d ;low word *10. mul dx add ax,di ;add in new digit adc dx,bx ;handle carry from both mov bx,ax ;move out of the way loop getno1 ;loop getno2: mov ax,bx ;copy ret getno3: mov dx,offset badnum ;bad number jmp error1 ;handle it ;+ ; ; Get a line from the keyboard, squish out blanks. ; ; bx pointer to prompt ; si,cx return addr,length of the line ; ;- getln: mov ah,09h ;func=print int 21h mov dx,offset lbuf ;get a line mov ah,0Ah ;func=line input int 21h mov dl,lf ;echo LF mov ah,02h ;func=conout int 21h mov si,offset lbuf+1 ;point at length lodsb ;fetch it cbw ;ah=0 mov cx,ax ;copy jcxz getln3 ;nothing mov di,si ;copy ptr mov dx,si ;twice getln1: lodsb ;get a byte cmp al,' ' ;blank or ctrl char? jbe getln2 ;yes stosb ;save getln2: loop getln1 ;loop mov si,dx ;pt at begn of buf mov cx,di ;pt at end sub cx,si ;find length getln3: ret ; subttl pure data banner db 'This program removes bytes from the beginning and/or end of a' db 'file.',cr,lf,lf,'$' prmpt1 db 'File name: $' prmpt2 db 'Number of bytes to remove from beginning <0>: $' prmpt3 db 'Number of bytes to remove from end <0>: $' ; nomem db '?Insufficient memory',cr,lf,'$' opnerr db '?Error opening file',cr,lf,'$' badnum db '?Bad digit',cr,lf,'$' sekerr db '?File seek error',cr,lf,'$' badcnt db '?File is too short to snip off that much',cr,lf,'$' rderr db '?Read error',cr,lf,'$' wrerr db '?Write error',cr,lf,'$' ; subttl impure data ; wpos dw 0,0 ;file position for writing ; lbuf db 80d,?,80d dup(?) ;buffer for input line db 1 dup(?) ;guard byte for NUL at end of long filename ; subttl pure storage ; handle dw 1 dup(?) ;file handle stacnt dw 2 dup(?) ;# bytes to remove at start endcnt dw 2 dup(?) ;# bytes to remove at end flen dw 2 dup(?) ;file length after truncation fcnt dw 2 dup(?) ;amount of file left to copy ; buf db bufl dup(?) ;file buffer, must all fit in <64KB ; dw 100h dup(?) ;minimum stack pdl label word ;SP must be here or higher ; code ends end start