TITLE MSBMKB MS-DOS System EXE to BOO Utility Program ; (c) 1988 W.C. Parke, WGCP0086@GWUVM ; ; This program converts an EXE to a BOO file ; ; BOO files are ASCII files constructed from binary files for the purpose ; of transferring 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 from 2 to 78 plus '0' bias. ; 3. Three byte sequences are coded as 4 bytes, taking lower 6 bits from ; each byte and adding a '0' bias. ; 4. Carriage return/linefeeds are inserted to make lines breaks ; at column 76 unless a split of 4 byte code would occur. If so, ; line ends at column 74. ; ; MSBMKB compiled with MASM 5.10. Use LINK and EXE2BIN to make COM file. ; ; May be used with any file on any MS-DOS path. ; BOO file is created in current directory. ; ; MSBMKB 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 DW 0 FNAM1 DB 80 DUP(0) FHAND2 DW 0 DW 0 FNAM2 DB 16 DUP(0) DW 0 FNAMT DB 16 DUP(0) INVOC DB CR,LF,'MSMKB Version 1.1' DB CR,LF,'EXE to BOO file converter.' DB CR,LF,'(c) 1988 W.C. Parke',CR,LF,CR,LF,'$' DHPERR DB 'Syntax:',CR,LF,LF DB ' MSBMKB filename',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$' DCLERR DB 'close$' DRDERR DB 'read$' DWRERR DB 'write$' DERRF DB '.',CR,LF,'$' FBOO DB '.BOO',0,0 DONE DB CR,LF,'Done. ',CR,LF,'$' FEOF DB 0 FEND DW 0 FEND2 DW 0 BOO: MOV AH,9 MOV DX,OFFSET INVOC INT 21H ; give our invocation MOV SI,80H LODSB XOR AH,AH AND AX,AX JNZ BOF ; got command line tail JMP ABORTHP ; give help screen BOF: MOV DI,OFFSET FNAM1 INC AX MOV CX,AX BO0: LODSB ; get byte of command line tail CMP AL,CR ; check for cr termination JZ BO1 CMP AL,20H JZ BOL ; check for spaces CMP AL,'a' JC BOLL AND AL,5FH BOLL: STOSB ; save in file name buffer BOL: LOOP BO0 ; continue BO1: XOR AL,AL STOSB ; make asciiz string DEC DI ; point to 0 MOV AX,OFFSET FNAM1 MOV CX,DI SUB CX,AX MOV FEND,CX ; size of file and path name to 0 INC CX INC CX STD MOV AL,'\' REPNZ SCASB CLD INC DI INC DI ; pointer to fnam1 without path MOV SI,DI MOV DI,OFFSET FNAM2 XOR CX,CX BON: LODSB INC CX AND AL,AL STOSB ; move copy to fnam2 JZ BOM JMP SHORT BON BOM: DEC CX MOV FEND2,CX ; size of fnam2 MOV SI,OFFSET FNAM2 MOV DI,OFFSET FNAMT MOV CX,8 REP MOVSW ; copy file name for header of BOO file MOV DX,OFFSET FNAM1 MOV AH,3DH ; open file 1 INT 21H JNC BO2 JMP ABORTOP ; give error on open message BO2: MOV FHAND1,AX ; save handle MOV DI,OFFSET FNAM2 MOV CX,FEND2 ADD DI,CX PUSH DI ; save ptr to 0 STD INC CX MOV AL,'.' REPNZ SCASB ; look for '.' in string from rear CLD JCXZ BO3 ; not found INC DI ; point to '.' POP AX ; drop old 0 pointer PUSH DI ; use new pointer BO3: POP SI ; pointer to extension in FNAM1 MOV DI,SI MOV SI,OFFSET FBOO MOV CX,3 REP MOVSW ; add BOO extension to fnam2 MOV DX,OFFSET FNAM2 XOR CX,CX MOV AH,4EH INT 21H ; search file JC BOZ MOV SI,OFFSET FNAM2 CALL SHOW MOV AH,9 MOV DX,OFFSET DEXIST ; already exists INT 21H MOV AX,0C01H INT 21H ; look for user response 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 ; got overwrite permission JMP EXIT BOZ: MOV DX,OFFSET FNAM2 MOV AH,3CH XOR CX,CX INT 21H ; create output file JC ABORTCR MOV FHAND2,AX ; save handle MOV AH,9 MOV DX,OFFSET DCONV INT 21H ; say converting MOV SI,OFFSET FNAM1 CALL SHOW MOV AH,9 MOV DX,OFFSET DTO INT 21H MOV SI,OFFSET FNAM2 CALL SHOW MOV AH,9 MOV DX,OFFSET DDOT INT 21H MOV SI,OFFSET FNAMT XOR AX,AX MOV BP,AX ; line column count MOV CNT1,AX MOV CNT2,AX ; zero buffer counts MOV DI,OFFSET FBUF2 MOV CX,16 ; do no more than 16 BO4: LODSB AND AL,AL ; end of asciiz string JZ BO5 SUB AL,'0' ; anticipate bias CALL OUTB ; send to file2 buffer LOOP BO4 BO5: CALL OUTCR ; send lf,cr MOV SI,OFFSET FBUF1 JMP NEXT ; start exe file conversion ABORTOP: MOV DX,OFFSET DOPERR ; file open error MOV AL,2 JMP ABORT ABORTCR: MOV DX,OFFSET DCRERR ; file creation error MOV AL,3 JMP ABORT ABORTCL: MOV DX,OFFSET DCLERR ; file close error MOV AL,7 JMP ABORT PUBLIC NULLS NUL1: MOV BL,AL ; put byte-2 after null XOR BH,BH ; put null for byte-1 JMP SHORT NEX3 ; process next byte for byte-3 NULLS: CALL GETB ; process multiple nulls AND AL,AL JNZ NUL1 ; only one null CMP BP,75 ; columns count - 2 JC NULG CALL OUTCR NULG: MOV AL,'~'-'0' ; ascii null flag CALL OUTB MOV CX,77 ; lowest count is 2 MOV BX,78 ; largest count allowed NULSN: CALL GETB AND AL,AL LOOPZ NULSN NULF: PUSH AX ; save non-null for byte-1 SUB BX,CX ; find null count MOV AX,BX CALL OUTB POP AX JMP SHORT NEX1 PUBLIC NEXT NEXT: CALL GETB ; get byte-1 xxxxxxxx NEX1: AND AL,AL JZ NULLS ; got a null MOV AH,AL CALL GETB ; get byte-2 yyyyyyyy MOV BX,AX NEX3: CALL GETB ; get byte-3 zzzzzzzz MOV CH,AL MOV AX,BX SHR AX,1 SHR AX,1 XCHG AH,AL CMP BP,73 ; columns count - 4 JC NEXG CALL OUTCR NEXG: CALL OUTB ; send 00xxxxxx XCHG AL,AH SHR AL,1 SHR AL,1 CALL OUTB ; send 00xxyyyy MOV AH,BL AND AH,0FH MOV AL,CH SHL AX,1 SHL AX,1 XCHG AH,AL CALL OUTB ; send 00yyyyzz MOV AL,AH SHR AL,1 SHR AL,1 CALL OUTB ; send 00zzzzzz, fourth of quarted JMP NEXT PUBLIC GETB CNT1 DW 0 ; byte count in buffer 1 EXTRA DB 3 ; extra byte count to finish ascii quartet GETB: CMP WORD PTR CNT1,0 JZ GETBF ; get more from file GETBG: LODSB DEC WORD PTR CNT1 ; on less in buffer RET GETBF: CALL GETMF ; file get JNC GETBG ; got more file bytes TEST BYTE PTR FEOF,0FFH JZ GETBEC ; error if not end of file DEC EXTRA CMP EXTRA,0 ; any extra bytes to add? JZ FIN ; no MOV AL,90H ; add extra 'nop' to file RET GETBEC: POP AX ; drop return address JMP ABORTWR PUBLIC FIN FIN: POP AX ; drop return address CALL OUTLST ; save last of converted file JNC EXIT JMP ABORTCL ; close error EXIT: MOV AH,9 MOV DX,OFFSET DONE INT 21H MOV AX,4C00H INT 21H ; good exit GETMFF: STC ; got eof RET GETMF: TEST BYTE PTR FEOF,0FFH JNZ GETMFF PUSH AX PUSH BX PUSH CX PUSH DX MOV BX,FHAND1 MOV DX,OFFSET FBUF1 MOV AH,3FH MOV CX,BUFSIZ ; file buffer size INT 21H ; get bytes MOV SI,OFFSET FBUF1 POP DX POP CX POP BX JC GETBC ; read error MOV CNT1,AX ; new byte count AND AX,AX JZ GETBE ; no more bytes GETBC: POP AX RET GETBE: INC BYTE PTR FEOF ; set eof POP AX STC RET OUTCR: XOR BP,BP ; new column PUSH AX MOV AL,0DDH ; cr-'0' CALL OUTB ; send cr MOV AL,0DAH ; lf-'0' CALL OUTB ; send lf POP AX XOR BP,BP ; reset column position RET PUBLIC OUTB CNT2 DW 0 ; buffer 2 character count OUTBB: CALL OUTBF ; write buffer contents JC OUTBCA ; write error JMP SHORT OUTBS ; start filling new buffer OUTB: CMP CNT2,BUFSIZ ; any space in buffer? JNC OUTBB ; no, write buffer OUTBS: ADD AL,'0' ; add bias to byte STOSB ; save character INC BP ; increment column position INC WORD PTR CNT2 ; and characters in buffer CLC RET OUTBCA: POP AX JMP ABORTWR ; write error OUTBF: 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 ; write file 2 buffer POP DX POP CX POP BX JC OUTBC ; write error CMP AX,BUFSIZ JNZ OUTBC ; carry set if incomplete write MOV WORD PTR CNT2,0 ; reset character count MOV DI,OFFSET FBUF2 ; and buffer pointer OUTBC: POP AX RET OUTLST: CALL OUTCR ; send final cr,lf MOV BX,WORD PTR FHAND2 MOV AH,40H MOV DX,OFFSET FBUF2 MOV CX,CNT2 INT 21H ; write MOV AH,3EH INT 21H ; and close RET ABORTHP: MOV DX,OFFSET DHPERR MOV AH,9 INT 21H ; show help screen MOV AX,4C01H INT 21H ABORTRD: MOV DX,OFFSET DRDERR ; read error MOV AL,4 JMP SHORT ABORT ABORTWR: MOV DX,OFFSET DWRERR ; write error MOV AL,6 ABORT: CALL ABERR ; error in file ... PUSH AX MOV AH,9 INT 21H ; ...(error type) MOV DX,OFFSET DERRF ; period INT 21H POP AX ; errorlevel in AL MOV AH,4CH INT 21H ABERR: PUSH AX PUSH DX MOV DX,OFFSET DERROR MOV AH,9 INT 21H ; show error in file 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