home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / progm / chasm2.zip / COM2DATA.ASM < prev    next >
Assembly Source File  |  1986-11-08  |  12KB  |  308 lines

  1. ;======================================================
  2. ; COM2DATA  release 2.1
  3. ; (c) 1984 by David Whitman
  4. ;
  5. ; High speed DOS 2.0 filter version
  6. ; of file conversion utility.
  7. ;
  8. ; Reads a COM file from STDIN and
  9. ; writes BASIC data statements to STDOUT
  10. ;
  11. ; Syntax:  COM2DATA [<filename] [>filename] [linenumber]
  12. ;
  13. ; The starting line number defaults to 1000 unless a number
  14. ; is given on the command line.
  15. ;
  16. ; Requires DOS 2.0, will abort under earlier versions.
  17. ;
  18. ; This source file is in CHASM assembler syntax.
  19. ;======================================================
  20.  
  21.  
  22. @dosver        equ     30H             ;get dos version #
  23. @prnchr        equ     02H             ;print character
  24. @prnstr        equ     09H             ;print string
  25. @read          equ     3FH             ;read device
  26. @write         equ     40H             ;write device
  27.  
  28. beep           equ     07H             ;bell character
  29. lf             equ     0AH             ;line feed character
  30. cr             equ     0DH             ;carrage return character
  31. comma          equ     2CH             ;comma character
  32. param_count    equ     [80H]           ;number of chars in param_area
  33. param_area     equ     [81H]           ;command line parameter text
  34. stdin          equ     0000H           ;standard input device
  35. stdout         equ     0001H           ;standard output device
  36. stderror       equ     0002H           ;standard error output device
  37. buf_length     equ     512             ;input buffer size
  38.  
  39. com2data       proc    near
  40.                call    init            ;check dos, print title
  41.                call    get_linenum     ;get starting line number
  42.                call    doit            ;run conversion
  43.                call    cleanup         ;final processing
  44.                int     20H             ;return to dos
  45.                endp
  46.  
  47. init           proc    near            ;initialization routine
  48.                mov     ah, @dosver     ;what dos are we under?
  49.                int     21H
  50.                cmp     al,2            ;dos 2.0 or over?
  51.                jae     a1              ;yes, skip
  52.  
  53.                mov     ah, @prnstr     ;no, bitch
  54.                mov     dx, offset(baddos)
  55.                int     21H
  56.                pop     ax              ;reset stack
  57.                int     20              ;and exit
  58.  
  59. a1             mov     ah, @write      ;send title message
  60.                mov     bx, stderror    ;to stderror
  61.                mov     cx, title_msg_end-title_msg
  62.                mov     dx, offset(title_msg)
  63.                int     21H
  64.                ret
  65.  
  66. baddos         db      beep cr lf
  67.                db      'This program requires DOS 2.0!' cr lf
  68.                db      cr lf '$'
  69.  
  70.  
  71. title_msg      db      cr lf
  72.                db      'COM2DATA version 2.1' cr lf
  73.                db      'Copyright (c) 1986 by D. Whitman' cr lf
  74.                db      cr lf
  75. title_msg_end
  76.                endp
  77.  
  78. get_linenum    proc     near           ;parse command line for
  79.                                        ;starting line number
  80.                xor     ch,ch           ;cx <== # of param chars
  81.                mov     cl, param_count ;   "
  82.                cmp     cl, 0           ;any parameters?
  83.                je      b1              ;no, exit with default
  84.  
  85.                mov     di, offset(param_area)
  86.                mov     al, ' '         ;search for first non-blank
  87.                rep
  88.                scasb
  89.                jcxz    b1              ;nothing? exit with default
  90.  
  91.                dec     di              ;back up to character found
  92.                inc     cx              ; "
  93.  
  94.                xor     ax,ax           ;will hold building linenum
  95.                jmps    enter_convert   ;convert string to binary
  96.  
  97. convert        mov     bx, 10          ;multiply running total by 10
  98.                mul     ax,bx
  99.                jo      bad_num         ;overflow?  error exit
  100. enter_convert  xor     bx,bx           ;clear out top half
  101.                mov     bl, [di]        ;get a digit into al
  102.                inc     di              ;bump pointer
  103.                cmp     bl, '0'         ;must be between 0
  104.                jb      bad_num
  105.                cmp     bl, '9'         ;and 9
  106.                ja      bad_num
  107.                sub     bl, '0'         ;convert to binary
  108.                add     ax, bx          ;add to running total
  109.                jo      bad_num         ;overflow? error exit
  110.                loop    convert
  111.  
  112.                mov     linenum, ax     ;store converted number
  113.                ret                     ;normal return
  114.  
  115. bad_num        mov     ah, @write      ;print error message
  116.                mov     bx, 2           ;on stderror
  117.                mov     cx, num_msg_end-num_msg
  118.                mov     dx, offset(num_msg)
  119.                int     21H             ;and use default
  120. b1             ret                     ;normal return
  121.  
  122. linenum        dw      1000            ;line number defaults to 1000
  123.  
  124.  
  125. num_msg        db      beep cr lf
  126.                db      'Invalid starting line number - Defaulting to 1000' cr lf
  127.                db      cr lf
  128. num_msg_end
  129.                endp
  130.  
  131. doit           proc    near            ;convert infile to data
  132.  
  133.                call    write_linenum   ;initialize output buffer
  134. do1            mov     ah, @read       ;read
  135.                mov     bx, stdin       ;from stdin
  136.                mov     cx, buf_length  ;one buffer's worth
  137.                mov     dx, offset(in_buf)
  138.                int     21H
  139.                test    ax, ax          ;test for EOF
  140.                jz      done            ;no bytes? done
  141.  
  142.                mov     cx, ax          ;cx <== # of bytes read
  143.                mov     si, offset(in_buf)
  144. do2            lodsb                   ;
  145.                call    output          ;convert and send to stdout
  146.                loop    do2             ;loop for # of bytes read
  147.                jmps    do1             ;then refill buffer
  148.  
  149. done           ret
  150.                endp
  151.  
  152. output         proc    near            ;convert byte in al to hex string
  153.                                        ;and send to stdout
  154.  
  155.                cmpw    cur_pos, offset(eol) ;is the line full?
  156.                jb      o1              ;no, skip
  157.                call    newline         ;yes, dump buffer
  158.  
  159. o1             call    send_byte       ;print hex value of byte
  160.                addw    cur_pos, 8      ;bump line positions used
  161.                ret                     ;and exit
  162.  
  163. cur_pos        dw      offset(first_hex) ;current position in line
  164.                endp
  165.  
  166.  
  167. newline        proc    near            ;starts a new data line
  168.  
  169.                push    ax              ;save state
  170.                push    dx              ; "
  171.  
  172.                mov     ah, @prnstr      ;print line
  173.                mov     dx, offset(out_buf)
  174.                int     21H
  175.  
  176.                movw    cur_pos, offset(first_hex)   ;reset pointer
  177.                addw    linenum, 10                  ;bump line number
  178.  
  179.                call    write_linenum                ;update line number
  180.  
  181.                pop     dx              ;restore state
  182.                pop     ax
  183.                ret                     ;and exit
  184.                endp
  185.  
  186. ;==========================================================
  187. ; WRITE_LINENUM
  188. ;
  189. ; Updates the line number field of the output line buffer.
  190. ;==========================================================
  191. write_linenum  proc    near
  192.                push    ax              ;save machine state
  193.                push    bx
  194.                push    cx
  195.                push    dx
  196.                push    di
  197.  
  198.                mov     al, ' '         ;blank out old number
  199.                mov     di, offset(out_buf)
  200.                mov     cx, 5
  201.                rep
  202.                stosb
  203.  
  204.                mov    ax, linenum      ;print line number
  205.  
  206.                                        ;the following code fragment was written
  207.                                        ;by Bob Smith and published in PC Age
  208.                                        ;Volume 3.1 (Jan. '84) p. 116
  209.  
  210.                mov     bx, 10          ;set up divisor
  211.                xor     cx, cx          ;clear counter
  212. nxt_in         xor     dx, dx          ;clear for division
  213.                div     bx              ;dl <== AX mod 10
  214.                or      dl, '0'         ;convert to ascii digit
  215.                push    dx              ;save digit
  216.                inc     cx              ;bump counter
  217.                and     ax, ax          ;are we done?
  218.                jnz     nxt_in          ;nope, keep going
  219.                                        ;stack now has digits of number
  220.                                        ;end of Bob Smith's code
  221.  
  222.                mov     di, offset(out_buf) ;peel digits off stack
  223. nxt_out        pop     ax                  ;into number field
  224.                stosb
  225.                loop    nxt_out
  226.  
  227.                pop     di              ;restore state
  228.                pop     dx
  229.                pop     cx
  230.                pop     bx
  231.                pop     ax
  232.                ret                     ;and exit
  233.                endp                    ;(write_linenum)
  234.  
  235.  
  236. send_byte      proc    near            ;converts byte in AL to hex string
  237.                                        ;and stuffs it into output buffer
  238.  
  239.                push    bx
  240.                push    dx
  241.                push    ax
  242.  
  243.                mov     bx, offset(table)  ;point to xlat table
  244.  
  245.                and     al, 0F0H        ;mask off low nybble
  246.                shr     al
  247.                shr     al
  248.                shr     al
  249.                shr     al
  250.                xlat                    ;translate to hex string
  251.                mov     bp, cur_pos     ;and stuff it into buffer
  252.                mov     [bp], al
  253.  
  254.                pop     ax              ;recover character
  255.                and     al, 0FH         ;mask off high nybble
  256.                xlat                    ;translate low nybble to hex
  257.                mov     1[bp], al       ;and stuff it into buffer
  258.  
  259.                pop     dx
  260.                pop     bx
  261.                ret                     ;and return
  262.  
  263. table          db '0123456789ABCDEF'
  264.                endp
  265.  
  266. cleanup        proc    near            ;send out any partial line
  267.  
  268.                cmpw    cur_pos, offset(first_hex) ;any unprinted chars?
  269.                je      cexit                      ;no, exit
  270.  
  271.                mov     ah, @write
  272.                mov     bx, stdout
  273.  
  274.                mov     cx, cur_pos                ;calculate # of chars
  275.                cmp     cx, offset(eol)            ;to output
  276.                je      c_full_line                ;special case: full line
  277.                sub     cx, offset(out_buf)        ;normal case: incomplete line
  278.                sub     cx, 6                      ;don't use ',' or next field
  279.                jmps    c_length_done
  280. c_full_line    mov     cx, eol-out_buf
  281.  
  282. c_length_done
  283.                mov     dx, offset(out_buf)
  284.                int     21H
  285.  
  286.                mov     ah, @prnstr                ;print cr/lf to end line
  287.                mov     dx, offset(eol)
  288.                int     21H
  289. cexit          ret
  290.                endp
  291.  
  292.  
  293.  
  294. out_buf        ds      5               ;5 digit line number
  295.                db      '  DATA'
  296.                db      '   &H'        ;8 hex bytes per line
  297. first_hex      db      '00' comma      ;first hex field
  298.                db      '   &H00' comma
  299.                db      '   &H00' comma
  300.                db      '   &H00' comma
  301.                db      '   &H00' comma
  302.                db      '   &H00' comma
  303.                db      '   &H00' comma
  304.                db      '   &H00'
  305. eol            db      cr lf '$'       ;end of output line
  306.  
  307. in_buf
  308.