TITLE MSBPC2 MS-DOS System BOO to EXE Utility Program ; (c) 1988 W.C. Parke, WGCP0086@GWUVM ; This program converts a BOO file to an EXE or binary file ; ; BOO files are ASCII files constructed from binary files and used ; to transfer the files over networks or tape which do not accept binary. ; The translation is by the following algorithm (by Bill Catchings): ; 1. The name of the file is placed on the first line, in plain text, ; followed by CR,LF ; 2. If a series of nulls occurs, a '~' (7EH) is used followed by ; an byte number for the null count, with a '0' bias, up to 7EH. ; 3. Three byte sequences are coded as 4 bytes, taking 6 bits from ; each byte and adding a '0' bias. ; 4. Carriage return/linefeeds are inserted to make lines break ; at approximately column 76. ; ; MSBPC2 compiled with MASM 5.10. Use LINK and EXE2BIN to make COM file. ; ; May be used with any BOO file on any MS-DOS path. ; ; This program translated the MSVIBM.BOO file in 15 seconds ; on an IBM XT clone. MSBPCT V1.0 took 6 min. 32 sec. ; The dramatic speed up comes largely from using large ; local file buffers. ; ; MSBPC2 uses the file name on the first line of the BOO file ; for its output file. LF EQU 0AH CR EQU 0DH BUFSIZ EQU 6000H CODE SEGMENT ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE ORG 100H START: JMP BOO FHAND1 DW 0 FNAM1 DB 80 DUP(0) FHAND2 DW 0 FNAM2 DB 80 DUP(0) INVOC DB CR,LF,'MSBPC2 Version 1.1' DB CR,LF,'BOO file to binary file converter.' DB CR,LF,'(c) 1988 W.C. Parke',CR,LF,CR,LF,'$' DHPERR DB 'Syntax:',CR,LF,LF DB ' MSBPC2 boofile',CR,LF,CR,LF,'$' DCONV DB 'Converting $' DTO DB ' to $' DDOT DB ' ...$' DEXIST DB ' already exists. Overwrite it? $' DERROR DB CR,LF,'Error in file $' DOPERR DB 'open$' DCRERR DB 'creation$' DCHERR DB 'character$' DCLERR DB 'close$' DRDERR DB 'read$' DWRERR DB 'write$' DERRF DB '.',CR,LF,'$' DONE DB CR,LF,'Done.',CR,LF,'$' BOO: MOV AH,9 MOV DX,OFFSET INVOC INT 21H ; invocation MOV SI,80H LODSB XOR AH,AH ; command line tail size AND AX,AX JNZ BOF JMP ABORTHP BOF: MOV DI,OFFSET FNAM1 INC AX MOV CX,AX PUSH DI BO0: LODSB CMP AL,CR JZ BO1 CMP AL,20H JZ BOL CMP AL,'a' JC BOS AND AL,5FH BOS: STOSB ; save possible file name BOL: LOOP BO0 BO1: XOR AL,AL STOSB POP DX MOV AH,3DH ; try to open file INT 21H JNC BO2 JMP ABORTOP BO2: MOV FHAND1,AX MOV DI,OFFSET FNAM2 MOV SI,OFFSET FBUF1 XOR AX,AX MOV CNT1,AX MOV CNT2,AX BOON: CALL GETBN ; get file name from first line of file JZ BOG STOSB JMP SHORT BOON BOG: XOR AL,AL STOSB MOV DX,OFFSET FNAM2 XOR CX,CX MOV AH,4EH INT 21H ; search for file in our directory JC BOZ ; not there PUSH SI MOV SI,OFFSET FNAM2 CALL SHOW POP SI MOV AH,9 MOV DX,OFFSET DEXIST INT 21H MOV AX,0C01H ; say exists, overwrite? INT 21H PUSH AX MOV AH,2 MOV DL,CR INT 21H MOV DL,LF INT 21H POP AX AND AL,5FH CMP AL,'Y' JZ BOZ JMP EXIT BOZ: MOV DX,OFFSET FNAM2 MOV AH,3CH XOR CX,CX INT 21H ; create output file JC ABORTCR MOV FHAND2,AX PUSH SI MOV AH,9 MOV DX,OFFSET DCONV ; say converting INT 21H MOV SI,OFFSET FNAM1 ; this file CALL SHOW MOV AH,9 MOV DX,OFFSET DTO ; to INT 21H MOV SI,OFFSET FNAM2 ; this one CALL SHOW MOV AH,9 MOV DX,OFFSET DDOT ; show dots INT 21H POP SI MOV DI,OFFSET FBUF2 JMP NEXT ; conversion loop PUBLIC FIN FIN: CALL OUTLST JC ABORTCL MOV AH,9 MOV DX,OFFSET DONE ; say done INT 21H EXIT: MOV AX,4C00H INT 21H ABORTOP: MOV DX,OFFSET DOPERR ; file open error MOV AL,2 JMP ABORT ABORTCR: MOV DX,OFFSET DCRERR ; file create error MOV AL,3 JMP ABORT ABORTCL: MOV DX,OFFSET DCLERR ; file close error MOV AL,7 JMP ABORT PUBLIC NULLS ; process nulls NULLS: CALL GETB XOR AH,AH MOV CX,AX XOR AL,AL PUBLIC NULLN NULLN: CALL OUTB LOOP NULLN PUBLIC NEXT NEXT: CALL GETB CMP AL,'~'-'0' JZ NULLS ; got a null code MOV AH,AL CALL GETB MOV BX,AX ; save first code pair in bx CALL GETB MOV AH,AL CALL GETB ; save second code pair in ax SHL AL,1 SHL AL,1 SHL BL,1 SHL BL,1 ; bx ax = 0xxxxxx0 0xxxxxx0 SHL AX,1 SHL AX,1 SHR BX,1 SHR BX,1 ; bx ax = 00xxxxxx xxxxxx00 SHL AX,1 RCL BX,1 RCL AX,1 RCL BX,1 RCL AX,1 RCL BX,1 RCL AX,1 RCL BX,1 ; bx ax = xxxxxxxx xxxx0000 MOV DX,AX MOV AL,BH CALL OUTB MOV AL,BL CALL OUTB MOV AL,DH CALL OUTB JMP NEXT PUBLIC GETB CNT1 DW 0 GETBF: CALL GETMF ; load buffer from file JNC GETBG JMP SHORT GETBEC ; error loading buffer GETB: ; get a byte from input CMP WORD PTR CNT1,0 JZ GETBF ; no more bytes in buffer - read more in GETBG: LODSB DEC WORD PTR CNT1 AND AL,7FH ; drop eigth bit CMP AL,7FH ; our EOF byte JZ GETBFIN CMP AL,LF ; skip lf's JZ GETB CMP AL,CR ; skip cr's JZ GETB CMP AL,1AH ;^Z JZ GETBFIN ; EOF for ascii file AND AL,AL JZ GETBFIN ; null also EOF for ascii file SUB AL,'0' ; remove bias JC GETBEC ; no other control codes allowed RET GETBEC: POP AX JMP ABORTCH ; character error in file GETBFIN: POP AX JMP FIN ; write and close output file GETMF: ; get more from input file PUSH AX PUSH BX PUSH CX PUSH DX MOV BX,FHAND1 MOV DX,OFFSET FBUF1 ; buffer for input file bytes MOV AH,3FH MOV CX,BUFSIZ ; size of buffer INT 21H ; get bytes MOV SI,OFFSET FBUF1 POP DX POP CX POP BX JC GETBC ; error reading input file MOV CNT1,AX CMP AX,BUFSIZ JC GETBE ; got less than full buffer POP AX RET GETBE: PUSH BX MOV BX,WORD PTR CNT1 MOV AX,07F7FH MOV WORD PTR [SI+BX],AX ; terminator bytes are 7fh POP BX CLC GETBC: POP AX ; carry error RET PUBLIC GETBN GETBN: ; get file name from first line of input file CMP WORD PTR CNT1,0 JZ GETBM GETBNG: LODSB DEC WORD PTR CNT1 AND AL,7FH CMP AL,LF ; end of line sets Zero flag JZ GETR CMP AL,CR ; end of line sets Zero flag GETR: RET GETBM: CALL GETMF ; get more characters from file JNC GETBNG ; ok to get a character from buffer POP AX JMP ABORTRD ; file read error PUBLIC OUTB CNT2 DW 0 OUTBB: CALL OUTBF JC OUTBCA OUTB: ; output a byte to output buffer CMP CNT2,BUFSIZ JNC OUTBB STOSB ; store byte INC WORD PTR CNT2 CLC RET OUTBCA: POP AX JMP ABORTWR ; problems with write OUTBF: ; flush output buffer to file PUSH AX PUSH BX PUSH CX PUSH DX MOV BX,WORD PTR FHAND2 MOV AH,40H MOV DX,OFFSET FBUF2 MOV CX,BUFSIZ INT 21H POP DX POP CX POP BX JC OUTBC ; write error CMP AX,BUFSIZ JNZ OUTBC ; incomplete write, disk full MOV WORD PTR CNT2,0 MOV DI,OFFSET FBUF2 OUTBC: POP AX RET OUTLST: ; flush last of buffer, then close file MOV BX,WORD PTR FHAND2 MOV AH,40H MOV DX,OFFSET FBUF2 MOV CX,CNT2 INT 21H MOV AH,3EH INT 21H RET ABORTHP: ; abort with help screen MOV DX,OFFSET DHPERR MOV AH,9 INT 21H MOV AX,4C01H INT 21H ABORTRD: MOV DX,OFFSET DRDERR ; abort, file read error MOV AL,4 JMP SHORT ABORT ABORTCH: ; abort, file character error CALL OUTLST MOV DX,OFFSET DCHERR MOV AL,5 JMP SHORT ABORT ABORTWR: ; abort, file write error MOV DX,OFFSET DWRERR MOV AL,6 ABORT: CALL ABERR ; show start of error message PUSH AX MOV AH,9 ; show text of error message INT 21H MOV DX,OFFSET DERRF ; period ending INT 21H POP AX ; recover error index MOV AH,4CH INT 21H ABERR: PUSH AX PUSH DX MOV DX,OFFSET DERROR MOV AH,9 INT 21H POP DX POP AX RET EVEN SHOW: MOV AH,2 ; show asciiz string SHOM: LODSB AND AL,AL JZ SHOE MOV DL,AL INT 21H JMP SHORT SHOM SHOE: RET FBUF1 EQU $ FBUF2 EQU $+BUFSIZ CODE ENDS END START