@dosver    equ     30h             ;get dos version #
@prnchr    equ     02h             ;print character
@prnstr    equ     09h             ;print string
@read      equ     3fh             ;read device
@write     equ     40h             ;write device
beep       equ     07h             ;bell character
lf         equ     0ah             ;line feed character
cr         equ     0dh             ;carrage return character
stdin      equ     0000h           ;standard input device
stdout     equ     0001h           ;standard output device
stderror   equ     0002h           ;standard error output device
param_c    equ     0080h
buf_length equ     512             ;input buffer size

;======================================================
cls        macro                            ; proc l”scht den bildschirm
           mov ax,0003h              ; ohne parameter aufrufen
           int 010h
#em
zeigbild   macro
           mov dx,offset #1
           mov ah,09
           int 021h
#em
           jmp com_pas
baddos     db  beep,cr,lf
           db  'Dieses Programm ben”tigt DOS >= 2.00',cr,lf,lf
           db  cr,lf '$'
benutzfehl db  '                   COM-PAS           Version 1.01',cr,lf,lf,lf
           db  '* KEIN *  Copyright (c) 1988       by m.s    '
           db  '**  Public - Domain **',cr,lf,lf
           db  'Dieses Programm erzeugt txt-Files aus COM ( BIN ) Programmen'
           db  cr,lf,lf,lf
           db  'Aufruf : COM-PAS < ein.com > aus.txt ',cr,lf,lf
           db  'Die erzeugten txt-Files k”nnen als inline-code fr '
           db  'Turbo-Pascal benutzt werden',cr,lf,lf,lf
tmse       db 0
table      db  '0123456789ABCDEF'
inli       db 'inline ( $'
klammer    db ' ) ',cr,lf,'$'
cur_pos    dw  offset first_hex       ;current position in line

com_pas:   cls
           cmp b[param_c],00
           jg co1
           mov ah,040
           mov bx,stderror
           mov cx,offset tmse
           sub cx,offset benutzfehl
           mov dx,offset benutzfehl
           int 021h
           mov ah,04ch
           int 021h

co1:       zeigbild inli                ;check dos, print title
           call do1            ;run conversion
           call cleanup         ;final processing
           zeigbild klammer
           mov ah,04ch
           int 021h             ;return to dos

do1:       mov ah,@read       ;read
           mov bx,stdin       ;from stdin
           mov cx,buf_length  ;one buffer's worth
           mov dx,offset in_buf
           int 021h
           test ax,ax          ;test for eof
           jz done            ;no bytes? done
           mov cx,ax          ;cx <== # of bytes read
           mov si,offset in_buf
do2:       lodsb                   ;
           call output          ;convert and send to stdout
           loop do2             ;loop for # of bytes read
           jmp short do1             ;then refill buffer
done:      ret

send_byte: push bx
           push dx
           push ax
           mov bx,offset table  ;point to xlat table
           and al, 0f0h         ;mask off low nybble
           shr al,1
           shr al,1
           shr al,1
           shr al,1
           xlat               ;translate to hex string
           mov bp,cur_pos     ;and stuff it into buffer
           mov [bp], al
           pop ax             ;recover character
           and al, 0fh        ;mask off high nybble
           xlat               ;translate low nybble to hex
           mov 1[bp], al      ;and stuff it into buffer
           pop dx
           pop bx
           ret                ;and return

output:    cmp w[cur_pos],offset eol  ;is the line full?
           jb ou1                      ;no, skip
           call newline               ;yes, dump buffer
ou1:       call send_byte             ;print  value of byte
           add cur_pos,4              ;bump line positions used
           ret                        ;and exit

newline:   push ax                   ;save state
           push dx
           push cx
           push bx
           mov ah,@write
           mov bx,0001            ;print line
           mov cx,offset in_buf
           sub cx,offset pas
           mov dx,offset pas
           int 021h
           mov cur_pos,offset first_hex  ;reset pointer
           pop bx
           pop cx
           pop dx                         ;restore state
           pop ax
           ret                            ;and exit

cleanup:   push ax
           push bx
           push cx
           push dx
           cmp w[cur_pos],offset first_hex       ;any unprinted chars?
           je cexit                           ;no, exit
           mov ah,@write
           mov bx,stdout
           mov cx,[cur_pos]                ;calculate # of chars
           cmp cx,offset eol               ;to output
           jge cvoll                       ;special case: full line
           sub cx,offset pas               ;normal case: incomplete line
           sub cx,2
           jmp short cfertig
cvoll:     mov cx,offset in_buf
           sub cx,offset pas
cfertig:   mov dx,offset pas
           int 021h
           pop dx
           pop cx
           pop bx
           pop ax
           mov cur_pos,offset first_hex
cexit:     ret
pas        db '$'
first_hex  db      '00,$'       ;first hex field
           db      '00,$'
           db      '00,$'
           db      '00,$'
           db      '00,$'
           db      '00,$'
           db      '00,$'
           db      '00,'
eol:       db cr, lf,        ;end of output line
in_buf     db 0
