home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Share Gallery 1
/
share_gal_1.zip
/
share_gal_1
/
LA
/
LA001.ZIP
/
CHASM.ARC
/
COM2DATA.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-11-08
|
12KB
|
308 lines
;======================================================
; COM2DATA release 2.1
; (c) 1984 by David Whitman
;
; High speed DOS 2.0 filter version
; of file conversion utility.
;
; Reads a COM file from STDIN and
; writes BASIC data statements to STDOUT
;
; Syntax: COM2DATA [<filename] [>filename] [linenumber]
;
; The starting line number defaults to 1000 unless a number
; is given on the command line.
;
; Requires DOS 2.0, will abort under earlier versions.
;
; This source file is in CHASM assembler syntax.
;======================================================
@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
comma equ 2CH ;comma character
param_count equ [80H] ;number of chars in param_area
param_area equ [81H] ;command line parameter text
stdin equ 0000H ;standard input device
stdout equ 0001H ;standard output device
stderror equ 0002H ;standard error output device
buf_length equ 512 ;input buffer size
com2data proc near
call init ;check dos, print title
call get_linenum ;get starting line number
call doit ;run conversion
call cleanup ;final processing
int 20H ;return to dos
endp
init proc near ;initialization routine
mov ah, @dosver ;what dos are we under?
int 21H
cmp al,2 ;dos 2.0 or over?
jae a1 ;yes, skip
mov ah, @prnstr ;no, bitch
mov dx, offset(baddos)
int 21H
pop ax ;reset stack
int 20 ;and exit
a1 mov ah, @write ;send title message
mov bx, stderror ;to stderror
mov cx, title_msg_end-title_msg
mov dx, offset(title_msg)
int 21H
ret
baddos db beep cr lf
db 'This program requires DOS 2.0!' cr lf
db cr lf '$'
title_msg db cr lf
db 'COM2DATA version 2.1' cr lf
db 'Copyright (c) 1986 by D. Whitman' cr lf
db cr lf
title_msg_end
endp
get_linenum proc near ;parse command line for
;starting line number
xor ch,ch ;cx <== # of param chars
mov cl, param_count ; "
cmp cl, 0 ;any parameters?
je b1 ;no, exit with default
mov di, offset(param_area)
mov al, ' ' ;search for first non-blank
rep
scasb
jcxz b1 ;nothing? exit with default
dec di ;back up to character found
inc cx ; "
xor ax,ax ;will hold building linenum
jmps enter_convert ;convert string to binary
convert mov bx, 10 ;multiply running total by 10
mul ax,bx
jo bad_num ;overflow? error exit
enter_convert xor bx,bx ;clear out top half
mov bl, [di] ;get a digit into al
inc di ;bump pointer
cmp bl, '0' ;must be between 0
jb bad_num
cmp bl, '9' ;and 9
ja bad_num
sub bl, '0' ;convert to binary
add ax, bx ;add to running total
jo bad_num ;overflow? error exit
loop convert
mov linenum, ax ;store converted number
ret ;normal return
bad_num mov ah, @write ;print error message
mov bx, 2 ;on stderror
mov cx, num_msg_end-num_msg
mov dx, offset(num_msg)
int 21H ;and use default
b1 ret ;normal return
linenum dw 1000 ;line number defaults to 1000
num_msg db beep cr lf
db 'Invalid starting line number - Defaulting to 1000' cr lf
db cr lf
num_msg_end
endp
doit proc near ;convert infile to data
call write_linenum ;initialize output buffer
do1 mov ah, @read ;read
mov bx, stdin ;from stdin
mov cx, buf_length ;one buffer's worth
mov dx, offset(in_buf)
int 21H
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
jmps do1 ;then refill buffer
done ret
endp
output proc near ;convert byte in al to hex string
;and send to stdout
cmpw cur_pos, offset(eol) ;is the line full?
jb o1 ;no, skip
call newline ;yes, dump buffer
o1 call send_byte ;print hex value of byte
addw cur_pos, 8 ;bump line positions used
ret ;and exit
cur_pos dw offset(first_hex) ;current position in line
endp
newline proc near ;starts a new data line
push ax ;save state
push dx ; "
mov ah, @prnstr ;print line
mov dx, offset(out_buf)
int 21H
movw cur_pos, offset(first_hex) ;reset pointer
addw linenum, 10 ;bump line number
call write_linenum ;update line number
pop dx ;restore state
pop ax
ret ;and exit
endp
;==========================================================
; WRITE_LINENUM
;
; Updates the line number field of the output line buffer.
;==========================================================
write_linenum proc near
push ax ;save machine state
push bx
push cx
push dx
push di
mov al, ' ' ;blank out old number
mov di, offset(out_buf)
mov cx, 5
rep
stosb
mov ax, linenum ;print line number
;the following code fragment was written
;by Bob Smith and published in PC Age
;Volume 3.1 (Jan. '84) p. 116
mov bx, 10 ;set up divisor
xor cx, cx ;clear counter
nxt_in xor dx, dx ;clear for division
div bx ;dl <== AX mod 10
or dl, '0' ;convert to ascii digit
push dx ;save digit
inc cx ;bump counter
and ax, ax ;are we done?
jnz nxt_in ;nope, keep going
;stack now has digits of number
;end of Bob Smith's code
mov di, offset(out_buf) ;peel digits off stack
nxt_out pop ax ;into number field
stosb
loop nxt_out
pop di ;restore state
pop dx
pop cx
pop bx
pop ax
ret ;and exit
endp ;(write_linenum)
send_byte proc near ;converts byte in AL to hex string
;and stuffs it into output buffer
push bx
push dx
push ax
mov bx, offset(table) ;point to xlat table
and al, 0F0H ;mask off low nybble
shr al
shr al
shr al
shr al
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
table db '0123456789ABCDEF'
endp
cleanup proc near ;send out any partial line
cmpw 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
je c_full_line ;special case: full line
sub cx, offset(out_buf) ;normal case: incomplete line
sub cx, 6 ;don't use ',' or next field
jmps c_length_done
c_full_line mov cx, eol-out_buf
c_length_done
mov dx, offset(out_buf)
int 21H
mov ah, @prnstr ;print cr/lf to end line
mov dx, offset(eol)
int 21H
cexit ret
endp
out_buf ds 5 ;5 digit line number
db ' DATA'
db ' &H' ;8 hex bytes per line
first_hex db '00' comma ;first hex field
db ' &H00' comma
db ' &H00' comma
db ' &H00' comma
db ' &H00' comma
db ' &H00' comma
db ' &H00' comma
db ' &H00'
eol db cr lf '$' ;end of output line
in_buf