;+ ; ; Break up a big file into little files. ; ; 09/08/98 JMBW Created. ; ;- .radix 8 locals ; lf= 12 cr= 15 ; bufl= 177000 ;buffer length (64 KB minus one block) ; error macro string local a,b call err1 ;;print error msg, punt a db b,&string b= $-a-1 endm ; code segment 'code' assume cs:code ; start: cld ;DF=0 mov ax,seg data ;point at data segment mov ds,ax ; open input file mov dx,offset inprm ;input prompt call getstr ;get filename mov ax,3D00h ;func=open /RONLY int 21h jnc @@1 ;success error '?Open error' @@1: mov ds:inhnd,ax ;save ; get size for each output file mov dx,offset kbprm ;prompt for # KB call getstr ;get it mov si,dx ;point at it xor bx,bx ;init @@2: lodsb ;get next char test al,al ;end of string? jz @@3 ;yes sub al,'0' ;convert digit to binary cmp al,9d ;it was a digit right? ja @@2 ;no, ignore cbw ;AH=0 xchg ax,bx ;save, get old number mov dx,10d ;multiplier mul dx ;make space for new digit add bx,ax ;add it in jmp short @@2 ;handle next @@3: test bx,bx ;get anything? jnz @@4 ;yes error '?Invalid file size' @@4: mov ax,1024d ;bytes per KB mul bx ;find bytes per file mov ds:outsiz,ax ;save mov ds:outsiz+2,dx @@5: ; read next bufferload from input file xor dx,dx ;offset=0 mov cx,bufl ;max # bytes mov ax,ds:outsiz ;# bytes per output file mov bx,ds:outsiz+2 sub ax,ds:cursiz ;find # to go in current file sbb bx,ds:cursiz+2 jnz @@6 ;> 64 KB, just fill the buf cmp ax,cx ;more than a bufferful? ja @@6 ;yes, just fill the buf mov cx,ax ;stop short test cx,cx ;anything? jnz @@6 ;yes ; output file full, close it mov ds:cursiz,cx ;start next file at 0 mov ds:cursiz+2,cx mov bx,-1 ;load -1 xchg bx,ds:outhnd ;get handle, set to -1 mov ah,3Eh ;func=close int 21h jmp short @@5 ;now write to fresh file @@6: mov bx,ds:inhnd ;input file handle push ds ;save mov ax,seg buf ;point at buf mov ds,ax mov ah,3Fh ;func=read int 21h pop ds ;[restore] jnc @@7 error '?File read error' @@7: test ax,ax ;EOF? jz @@12 ;yes push ax ;save cmp word ptr ds:outhnd,-1 ;is there an output file? jne @@9 ;yes mov dx,offset outprm ;prompt for next output file call getstr xor cx,cx ;mode=default mov ah,3Ch ;func=create int 21h jnc @@8 error '?File creation error' @@8: mov ds:outhnd,ax ;save @@9: pop cx ;restore length ; write next bufferload to current output file xor dx,dx ;offset=0 mov bx,ds:outhnd ;get handle push ds ;save mov ax,seg buf ;point at buf mov ds,ax mov ah,40h ;func=write int 21h pop ds ;[restore] jc @@10 ;error cmp ax,cx ;wrote all? je @@11 ;yes, success @@10: error '?File write error' @@11: add ds:cursiz,ax ;update # bytes written adc word ptr ds:cursiz+2,0 jmp @@5 ;go read new buffer @@12: ; EOF on input file mov ah,3Eh ;func=close int 21h ;(INHND is still in BX) mov bx,ds:outhnd ;get output handle cmp bx,-1 ;open? je @@13 ;no mov ah,3Eh ;func=close int 21h @@13: mov ax,4C00h ;func=exit, errorlevel=0 int 21h ;+ ; ; Print an error message and exit. ; ; ss:sp return address points to counted string in code segment ; ;- err1: pop si ;restore push cs ;copy CS to DS pop ds lodsb ;get length cbw ;AH=0 mov dx,si ;point at it mov cx,ax ;length mov bx,0001h ;handle=STDOUT mov ah,40h ;func=write int 21h mov dl,cr ;CR mov ah,02h ;func=CONOUT int 21h mov dl,lf ;LF mov ah,02h ;func=CONOUT int 21h mov ax,4C01h ;func=punt, errorlevel=1 int 21h ;+ ; ; Get a string ; ; On entry: ; ds:dx prompt (ending in '$') ; ; On exit: ; ds:dx .ASCIZ string ; ;- getstr: mov ah,09h ;func=print int 21h mov dx,offset kbbuf ;keyboard mov si,dx ;(copy) mov ah,0Ah ;func=string input int 21h mov dl,lf ;echo LF mov ah,02h ;func=CONOUT int 21h inc si ;skip buf length lodsb ;get actual length cbw ;AH=0 mov dx,si ;point at actual string add si,ax ;skip to end mov [si],ah ;mark end ret ; code ends ; data segment 'data' inprm db 'BREAKUP V1.0 by John Wilson ',cr,lf db cr,lf db 'Input file: $' kbprm db 'Number of KB per output file: $' outprm db 'Output file: $' ; outhnd dw -1 ;output file handle (or -1 if none) inhnd dw 1 dup(?) ;input file handle outsiz dw 2 dup(?) ;# bytes per output file cursiz dw 0,0 ;# bytes so far in current output file ; kbbuf db 80d,?,(80d+1) dup(?) ;keyboard input buffer ; data ends ; stk segment stack 'stack' dw 800h dup(?) stk ends ; buf segment 'buffer' db bufl dup(?) ;I/O buffer buf ends ; end start