home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / filutl / comphex.arc / COMPHEX.ASM next >
Encoding:
Assembly Source File  |  1986-10-06  |  21.7 KB  |  762 lines

  1.     if1
  2.     %out    COMPHEX.ASM
  3.     endif
  4.     if2
  5.     %out    **** PASS 2
  6.     endif
  7.     name    COMPHEX
  8.     .xall
  9.     page    ,132
  10.     title COMPHEX - 28 JUN 1986
  11.  
  12. ; ****************************************************************
  13. ; **                                **
  14. ; **          MS-DOS INTEL HEX FILE COMPARATOR        **
  15. ; **                                **
  16. ; **............................................................**
  17. ; **                                **
  18. ; **                                **
  19. ; **   Written by Michael Kesti.      If you like it, use it.    **
  20. ; **                                **
  21. ; **     Requires MS-DOS or PC-DOS version 2.XX or later.    **
  22. ; **                                **
  23. ; **           Assembler: Microsoft MASM            **
  24. ; **                                **
  25. ; ****************************************************************
  26.  
  27. ; ..... READ DISK FILE MACRO .....
  28.  
  29. diskrd    macro    numbyte,bufname        ; read numbyte bytes into bufname
  30.     local    ok            ; ok is a local symbol
  31.     mov    ah,read            ; load read command
  32.     mov    bx,handle        ; load file handle
  33.     mov    cx,numbyte        ; load number of characters to be read
  34.     mov    dx,offset bufname    ; point to buffer
  35.     int    dosfunc            ; read from file - error?
  36.     jnc    ok            ; no - done
  37.  
  38.     jmp    doserr            ; yes - display error
  39.  
  40. ok:
  41.     endm
  42.     page
  43. ; ..... dos commands .....
  44.  
  45. dosfunc equ    21H            ; dos function interrupt
  46. pr_str    equ    09H            ;  print string command
  47. create    equ    3CH            ;  create file command
  48. open    equ    3DH            ;  open file command
  49. close    equ    3EH            ;  close file command
  50. read    equ    3FH            ;  read file command
  51. rdacc    equ    0            ;    read file access code
  52. write    equ    40H            ;  write file command
  53. wratt    equ    0            ;    write file attribute code
  54.  
  55.  
  56. ; ..... constants .....
  57.  
  58. maxlen    equ    80            ; maximum filespec length
  59. tab    equ    09H            ; ascii tab
  60. cr    equ    0DH            ; ascii carriage return
  61. lf    equ    0AH            ; ascii line feed
  62. datind    equ    00H            ; Intel hex file data record indicator
  63. eofind    equ    01H            ; Intel hex file end of file indicator
  64. std_out    equ    01H            ; standard output file handle
  65.  
  66.  
  67. stack    segment stack            ; stack segment
  68.     dw    1024 dup (?)        ; 1024 levels of stack
  69. stack    ends
  70.     page
  71. data    segment                ; data segment
  72.  
  73. ; ****************************************************************
  74. ; **                                **
  75. ; **                  STRINGS                **
  76. ; **                                **
  77. ; ****************************************************************
  78.  
  79. mbcom    db    cr,lf,'COMMAND LINE ERROR',cr,lf,lf,'$'
  80.  
  81. mlong    db    cr,lf,'INPUT FILE TOO LONG',cr,lf,lf,'$'
  82.  
  83. mbhex    db    cr,lf,'INVALID HEX FILE ',cr,lf,lf,'$'
  84.  
  85. mfileA    db    'FILE A = $'
  86.  
  87. mfileB    db    cr,lf,'FILE B = $'
  88.  
  89. mhdr    db    cr,lf
  90.     db    cr,lf,'ADDR',tab,'FILE A',tab,'FILE B'
  91.     db    cr,lf,'----',tab,'------',tab,'------',cr,lf,'$'
  92.  
  93. mbytes    db    cr,lf,'BYTE COUNT:     $'
  94.  
  95. mmis    db    cr,lf,'MISMATCH COUNT: $'
  96.  
  97. mnewlin    db    cr,lf,'$'
  98.  
  99. mdos0    db    cr,lf,'DISK FULL',cr,lf,lf,'$'
  100.  
  101. mdos1    db    cr,lf,'INVALID FUNCTION',cr,lf,lf,'$'
  102.  
  103. mdos2    db    cr,lf,'FILE NOT FOUND',cr,lf,lf,'$'
  104.  
  105. mdos3    db    cr,lf,'PATH NOT FOUND',cr,lf,lf,'$'
  106.  
  107. mdos4    db    cr,lf,'TOO MANY OPEN FILES',cr,lf,lf,'$'
  108.  
  109. mdos5    db    cr,lf,'ACCESS DENIED',cr,lf,lf,'$'
  110.  
  111. mdos6    db    cr,lf,'INVALID HANDLE',cr,lf,lf,'$'
  112.  
  113. muknow    db    cr,lf,'UNKNOWN DISK ERROR',cr,lf,lf,'$'
  114.     page
  115. ; ****************************************************************
  116. ; **                                **
  117. ; **            STORAGE ASSIGNMENTS            **
  118. ; **                                **
  119. ; ****************************************************************
  120.  
  121. file_A    db    maxlen+1 dup (0)    ; first filespec
  122.  
  123. file_B    db    maxlen+1 dup (0)    ; second filespec
  124.  
  125. handle    dw    ?            ; file handle
  126.  
  127. dskbuf    db    80 dup (?)        ; disk buffer
  128.  
  129. dskptr    dw    (?)            ; disk buffer pointer
  130.  
  131. dskcnt    dw    (?)            ; disk buffer counter
  132.  
  133. chkacc    db    (?)            ; checksum accumulator
  134.  
  135. memadd    dw    (?)            ; memory address
  136.  
  137. numrec    dw    (?)            ; number of records in current line
  138.  
  139. recbyt    dw    (?)            ; number of bytes for numrec records
  140.  
  141. outbuf    db    83 dup (?)        ; output buffer
  142.  
  143. comp_cnt dw    (0)            ; compare counter
  144.  
  145. mis_cnt    dw    (0)            ; mismatch counter
  146.  
  147. filebuf    equ    this byte        ; file buffer start
  148.  
  149.     org    0FFFFH            ; segment end
  150. endbuf    equ    this byte        ; file buffer end
  151.  
  152. memlen    equ    (offset endbuf - offset filebuf) / 2    ; file buffer length
  153.  
  154.     org    filebuf            ;
  155.  
  156. buf_A    db    memlen dup (?)        ; first first buffer
  157.  
  158. buf_B    db    memlen dup (?)        ; second file buffer
  159.  
  160. data    ends
  161.     page
  162. code    segment                ; code segment
  163.  
  164.     assume    cs:code,ds:data,es:data,ss:stack
  165.  
  166. ; ****************************************************************
  167. ; **                                **
  168. ; **             MAIN PROGRAM                **
  169. ; **                                **
  170. ; ****************************************************************
  171.  
  172. comphex    proc    far            ;
  173.  
  174.     push    ds            ;
  175.     mov    ax,0            ;
  176.     push    ax            ; set up for far return to dos
  177.  
  178.     mov    ax,data            ;
  179.     mov    ds,ax            ; set up data segment register
  180.  
  181.     call    rcmd            ; read command line
  182.     call    open_A            ; open first file
  183.     mov    bp,offset buf_A        ; point to first file buffer
  184.     call    load_hex        ; load hex file
  185.     call    closer            ; close first file
  186.     call    open_B            ; open first file
  187.     mov    bp,offset buf_B        ; point to second file buffer
  188.     call    load_hex        ; load hex file
  189.     call    closer            ; close first file
  190.     call    comp_hex        ; compare the hex files
  191.     ret                ; return to dos
  192.  
  193. comphex    endp                ;
  194.     page
  195. ; ****************************************************************
  196. ; **                                **
  197. ; **            READ COMMAND LINE            **
  198. ; **                                **
  199. ; ****************************************************************
  200.  
  201. rcmd    proc    near            ;
  202.  
  203.     mov    bx,80H            ; point to received characters quantity
  204.     mov    ch,es:[bx]        ; load character counter
  205.     or    ch,ch            ; zero characters?
  206.     jz    rcmd30            ; yes - display error
  207.  
  208.     inc    bx            ; no - point to characters
  209.     mov    di,offset file_A    ; point to first filespec
  210.     mov    cl,maxlen        ; load length counter
  211.     mov    al,es:[bx]        ; load next character
  212.     inc    bx            ; advance pointer
  213.     dec    ch            ; retard character counter - end?
  214.     jz    rcmd30            ; yes - display error
  215.  
  216.     cmp    al,' '            ; no - space?
  217.     jnz    rcmd30            ; no - display error
  218.  
  219. rcmd05:
  220.     mov    al,es:[bx]        ; yes - load next character
  221.     mov    [di],al            ; write to first filespec
  222.     cmp    al,' '            ; space?
  223.     jz    rcmd10            ; yes - load second filespec
  224.  
  225.     inc    bx            ; no -
  226.     inc    di            ;    - advance pointers
  227.     dec    ch            ; retard character counter - end?
  228.     jz    rcmd30            ; yes - display error
  229.  
  230.     dec    cl            ; no - retard length counter - too long?
  231.     jz    rcmd30            ; yes - display error
  232.  
  233.     jmp    rcmd05            ; no - load next character
  234.  
  235. rcmd10:
  236.     inc    bx            ; advance command line pointer
  237.     dec    ch            ; retard character counter - end?
  238.     jz    rcmd30            ; yes - display error
  239.  
  240.     mov    di,offset file_B    ; no - point to second filespec
  241.     mov    cl,maxlen        ; load length counter
  242.  
  243. rcmd15:
  244.     mov    al,es:[bx]        ; load next character
  245.     cmp    al,' '            ; space?
  246.     jz    rcmd35            ; yes - done
  247.  
  248.     mov    [di],al            ; no - write to second filespec
  249.     inc    bx            ;
  250.     inc    di            ; advance pointers
  251.     dec    ch            ; retard counter - last character?
  252.     jz    rcmd35            ; yes - exit
  253.  
  254.     dec    cl            ; no - retard length counter - too long?
  255.     jz    rcmd30            ; yes - display error
  256.  
  257.     jmp    rcmd15            ; no - load next character
  258.  
  259. rcmd30:
  260.     mov    dx,offset mbcom        ; point to bad command line string
  261.     jmp    dsperr            ; display string and exit to dos
  262.  
  263. rcmd35:
  264.     ret                ;
  265.  
  266. rcmd    endp                ;
  267.     page
  268. ; ****************************************************************
  269. ; **                                **
  270. ; **               OPEN FIRST FILE            **
  271. ; **                                **
  272. ; ****************************************************************
  273.  
  274. open_A    proc    near            ;
  275.  
  276.     mov    ah,open            ; load open file command
  277.     mov    al,rdacc         ; load read access code
  278.     mov    dx,offset file_A    ; point to first filespec
  279.     int    dosfunc            ; open first file - error?
  280.     jnc    open_A05        ; no - store file handle
  281.  
  282.     jmp    doserr            ; yes - display error
  283.  
  284. open_A05:
  285.     mov    handle,ax        ; store file handle
  286.     ret                ; done
  287.  
  288. open_A    endp                ;
  289.     page
  290. ; ****************************************************************
  291. ; **    function: load an INTEL hex file into memory space    **
  292. ; **    entry: file handle in handle                **
  293. ; **    uses: all                        **
  294. ; **    exit: carry flag is clear if no errors detected        **
  295. ; **    calls: pack                        **
  296. ; ****************************************************************
  297.  
  298. load_hex     proc    near
  299.  
  300.     diskrd    1,dskbuf        ; read one byte from disk file - error?
  301.  
  302.     cmp    ax,01            ; no - 1 character?
  303.     jz    load_hex_15        ; yes - test for record mark
  304.  
  305.     jmp    load_hex_60        ; no - write error
  306.  
  307. load_hex_15:
  308.     lea    bx,dskbuf        ; point to disk buffer
  309.     mov    al,[bx]            ; load received character
  310.     cmp    al,':'            ; record mark?
  311.     jnz    load_hex        ; no - try again
  312.  
  313.     diskrd    8,dskbuf        ; yes - read eight bytes from disk file - error?
  314.  
  315.     mov    chkacc,0         ; no - initialize checksum accumulator
  316.     cmp    ax,08            ; receive 8 characters?
  317.     jz    load_hex_20        ; yes - convert number of bytes in record
  318.  
  319.     jmp    load_hex_60        ; no - write error
  320.  
  321. load_hex_20:
  322.     lea    bx,dskbuf        ; point to disk buffer
  323.     call    pack            ; convert number of bytes in record
  324.     mov    ah,0        
  325.     mov    numrec,ax        ; store
  326.     call    pack            ; convert high start address
  327.     mov    dh,al            ; store
  328.     call    pack            ; convert low start address
  329.     mov    dl,al            ; store
  330.     mov    memadd,dx        ; store this record's start address
  331.     call    pack            ; convert record indicator
  332.     cmp    al,datind        ; data indicator?
  333.     jz    load_hex_23        ; yes - load number of records
  334.  
  335.     jmp    load_hex_35        ; no - test for end of file indicator
  336.  
  337. load_hex_23:
  338.     mov    ax,numrec        ; load number of records
  339.     add    ax,ax            ; compute number of data characters
  340.     add    ax,4            ; add checksum and terminator character count
  341.     mov    recbyt,ax        ; store
  342.     diskrd    recbyt,dskbuf        ; yes - read recbyt bytes from disk file - error?
  343.  
  344.     lea    bx,dskbuf        ; no - point to disk buffer
  345.     mov    dskptr,bx        ; inititialize disk buffer pointer
  346.     cmp    recbyt,cx        ; receive correct number of characters?
  347.     jz    load_hex_25        ; yes - convert record
  348.  
  349.     jmp    load_hex_60        ; no - write error
  350.  
  351. load_hex_25:
  352.     mov    cx,numrec        ; load counter
  353.     jcxz    load_hex_40        ; zero characters? - yes - read and test
  354.                     ;    chksum and terminator
  355.  
  356. load_hex_30:
  357.     mov    bx,dskptr        ; no - load disk buffer pointer
  358.     call    pack            ; convert data
  359.     mov    dskptr,bx        ; store disk buffer pointer
  360.     mov    si,memadd        ; load memory address
  361.     mov    ds:[si + bp],al        ; store data in memory space
  362.     inc    memadd            ; advance memory address
  363.     dec    cx            ; retard counter - done?
  364.     jnz    load_hex_30        ; no - continue
  365.  
  366.     mov    ax,memadd        ; yes - load memory address
  367.     cmp    ax,comp_cnt        ; greater than current compare counter?
  368.     jb    load_hex_33        ; no - test checksum
  369.  
  370.     mov    comp_cnt,ax        ; yes - update comapre counter
  371.  
  372. load_hex_33:
  373.     mov    bx,dskptr        ; load disk buffer pointer
  374.     call    pack            ; convert checksum
  375.     mov    cl,al            ; store checksum
  376.     mov    al,chkacc        ; load checksum accumulator
  377.     sub    al,cl            ; adjust checksum
  378.     not    al            ;
  379.     inc    al            ; compute 2's complement of checksum
  380.     cmp    al,cl            ; checksums match?
  381.     jnz    load_hex_60        ; no - write error
  382.  
  383.     cmp    byte ptr[bx],cr     ; yes - terminated with <cr>?
  384.     jnz    load_hex_60        ; no - write error
  385.  
  386.     inc    bx            ; yes - point to line feed
  387.     cmp    byte ptr[bx],lf     ; line feed?
  388.     jnz    load_hex_60        ; no - write error
  389.  
  390.     jmp    load_hex        ; yes - continue
  391.  
  392. load_hex_35:
  393.     cmp    al,eofind        ; end of file indicator?
  394.     jnz    load_hex_60        ; no - write error
  395.  
  396.     diskrd    4,dskbuf        ; yes - read 4 bytes from disk file - error?
  397.     cmp    ax,4            ; no - 4 characters?
  398.     jnz    load_hex_60        ; no - write error
  399.  
  400. load_hex_40:
  401.     lea    bx,dskbuf        ; yes - point to disk buffer
  402.     call    pack            ; convert checksum
  403.     mov    cl,al            ; store checksum
  404.     mov    al,chkacc        ; load checksum accumulator
  405.     sub    al,cl            ; adjust checksum
  406.     not    al            ;
  407.     inc    al            ; compute 2's complement of checksum
  408.     cmp    al,cl            ; checksums match?
  409.     jnz    load_hex_60        ; no - write error
  410.  
  411.     cmp    byte ptr[bx],cr     ; yes - terminated with <cr>?
  412.     jnz    load_hex_60        ; no - write error
  413.  
  414.     inc    bx            ; yes - point to line feed
  415.     cmp    byte ptr[bx],lf     ; line feed?
  416.     jnz    load_hex_60        ; no - write error
  417.  
  418. load_hex_55:
  419.     clc                ; yes - indicate no error occurred
  420.     ret                ;
  421.  
  422. load_hex_60:
  423.     lea    dx,mbhex         ; point to bad hex data string
  424.     jmp    dsperr            ; display string and exit to dos
  425.  
  426. load_hex     endp
  427.     page
  428. ; ****************************************************************
  429. ; **                                **
  430. ; **              OPEN SECOND FILE            **
  431. ; **                                **
  432. ; ****************************************************************
  433.  
  434. open_B    proc    near            ;
  435.  
  436.     mov    ah,open            ; load open file command
  437.     mov    al,rdacc         ; load read access code
  438.     mov    dx,offset file_B    ; point to second filespec
  439.     int    dosfunc            ; open second file - error?
  440.     jnc    open_B05        ; no - store file handle
  441.  
  442.     jmp    doserr            ; yes - display error
  443.  
  444. open_B05:
  445.     mov    handle,ax        ; store file handle
  446.     ret                ; done
  447.  
  448. open_B    endp                ;
  449.     page
  450. ; ****************************************************************
  451. ; **                                **
  452. ; **                 CLOSE FILE                **
  453. ; **                                **
  454. ; ****************************************************************
  455.  
  456. closer    proc    near            ;
  457.  
  458.     mov    ah,close         ; load close file command
  459.     mov    bx,handle        ; load file handle
  460.     int    dosfunc            ; close file - error?
  461.     jnc    closer05        ; no - done
  462.  
  463.     jmp    doserr            ; yes - display error
  464.  
  465. closer05:
  466.     ret                ;
  467.  
  468. closer    endp
  469.     page
  470. ; ****************************************************************
  471. ; **                                **
  472. ; **               COMPARE FILES            **
  473. ; **                                **
  474. ; ****************************************************************
  475.  
  476. comp_hex    proc    near        ;
  477.     lea    si,file_A        ; point to first filespec
  478.  
  479. comp_hex_05:
  480.     cmp    byte ptr[si],0        ; next first filename character = 0?
  481.     je    comp_hex_10        ; yes - write terminator
  482.  
  483.     inc    si            ; no - advance pointer
  484.     jmp    comp_hex_05        ; test next character
  485.  
  486. comp_hex_10:
  487.     mov    byte ptr[si],'$'    ; terminate first filespec
  488.     lea    si,file_B        ; point to second filespec
  489.  
  490. comp_hex_15:
  491.     cmp    byte ptr[si],0        ; next second filename character = 0?
  492.     je    comp_hex_20        ; yes - write terminator
  493.  
  494.     inc    si            ; no - advance pointer
  495.     jmp    comp_hex_15        ; test next character
  496.  
  497. comp_hex_20:
  498.     mov    byte ptr[si],'$'    ; terminate second filespec
  499.     mov    dx,offset mfileA    ; point to file A string
  500.     mov    ah,pr_str        ; load print string command
  501.     int    dosfunc            ; write string to standard output
  502.     mov    dx,offset file_A    ; point to filespecA
  503.     mov    ah,pr_str        ; load print string command
  504.     int    dosfunc            ; write string to standard output
  505.     mov    dx,offset mfileB    ; point to file B string
  506.     mov    ah,pr_str        ; load print string command
  507.     int    dosfunc            ; write string to standard output
  508.     mov    dx,offset file_B    ; point to filespecB
  509.     mov    ah,pr_str        ; load print string command
  510.     int    dosfunc            ; write string to standard output
  511.     lea    si,buf_A        ; point to first file
  512.     lea    di,buf_B        ; point to second file
  513.     mov    cx,comp_cnt        ; load compare counter - zero?
  514.     jcxz    comp_hex_45        ; yes - done
  515.  
  516. comp_hex_25:
  517.     mov    al,[si]            ; no - load next first file character
  518.     cmp    al,[di]            ; match next second file character?
  519.     jne    comp_hex_30        ; no - test for first mismatch
  520.  
  521.     jmp    comp_hex_40        ; yes - continue
  522.  
  523. comp_hex_30:
  524.     push    cx            ; save compare counter
  525.     cmp    mis_cnt,0        ; first mismatch?
  526.     jne    comp_hex_35        ; no - output mismatch
  527.  
  528.     mov    dx,offset mhdr        ; yes - point to header string
  529.     mov    ah,pr_str        ; load print string command
  530.     int    dosfunc            ; write header string to standard output
  531.  
  532. comp_hex_35:
  533.     lea    bx,outbuf        ; point to output buffer
  534.     mov    dx,si            ; load buffer pointer
  535.     sub    dx,offset buf_A        ; compute address
  536.     mov    al,dh            ; load high address
  537.     call    expand            ; convert to ascii
  538.     mov    al,dl            ; load low address
  539.     call    expand            ; convert to ascii
  540.     mov    byte ptr[bx],tab    ; write tab to output buffer
  541.     inc    bx            ; advance output buffer pointer
  542.     mov    al,[si]            ; load first file byte
  543.     call    expand            ; convert to ascii
  544.     mov    byte ptr[bx],tab    ; write tab to output buffer
  545.     inc    bx            ; advance output buffer pointer
  546.     mov    al,[di]            ; load second file byte
  547.     call    expand            ; convert to ascii
  548.     mov    byte ptr[bx],cr        ; write cr to output buffer
  549.     inc    bx            ; advance output buffer pointer
  550.     mov    byte ptr[bx],lf        ; write lf to output buffer
  551.     mov    ah,write        ; load write command
  552.     mov    bx,std_out        ; load standard output file handle
  553.     mov    cx,12            ; load number of characters
  554.     lea    dx,outbuf        ; point to output buffer
  555.     int    dosfunc            ; write to standard output
  556.     inc    mis_cnt            ; advance mismatch counter
  557.     pop    cx            ; restore compare counter
  558.  
  559. comp_hex_40:
  560.     inc    si            ;
  561.     inc    di            ; advance pointers
  562.     dec    cx            ; done?
  563.     jz    comp_hex_45        ; yes - display summary
  564.  
  565.     jmp    comp_hex_25        ; no - continue
  566.  
  567. comp_hex_45:
  568.     cmp    mis_cnt,0        ; any mismatches?
  569.     jne    comp_hex_50        ; yes - output summary
  570.  
  571.     mov    dx,offset mnewlin    ; no - point to newline string
  572.     mov    ah,pr_str        ; load print string command
  573.     int    dosfunc            ; write string to standard output
  574.  
  575. comp_hex_50:
  576.     mov    dx,offset mbytes    ; yes - point to last address string
  577.     mov    ah,pr_str        ; load print string command
  578.     int    dosfunc            ; write string to standard output
  579.     lea    bx,outbuf        ; point to output buffer
  580.     mov    dx,comp_cnt        ; load compare counter
  581.     mov    al,dh            ; load high compare counter
  582.     call    expand            ; convert to ascii
  583.     mov    al,dl            ; load low compare counter
  584.     call    expand            ; convert to ascii
  585.     mov    ah,write        ; load write command
  586.     mov    bx,std_out        ; load standard output file handle
  587.     mov    cx,4            ; load number of characters
  588.     lea    dx,outbuf        ; point to output buffer
  589.     int    dosfunc            ; write to standard output
  590.     mov    dx,offset mmis        ; point to mismatch string
  591.     mov    ah,pr_str        ; load print string command
  592.     int    dosfunc            ; write string to standard output
  593.     lea    bx,outbuf        ; point to output buffer
  594.     mov    dx,mis_cnt        ; load mismatch counter
  595.     mov    al,dh            ; load high address
  596.     call    expand            ; convert to ascii
  597.     mov    al,dl            ; load low address
  598.     call    expand            ; convert to ascii
  599.     mov    ah,write        ; load write command
  600.     mov    bx,std_out        ; load standard output file handle
  601.     mov    cx,4            ; load number of characters
  602.     lea    dx,outbuf        ; point to output buffer
  603.     int    dosfunc            ; write to standard output
  604.     mov    dx,offset mnewlin    ; point to newline string
  605.     mov    ah,pr_str        ; load print string command
  606.     int    dosfunc            ; write string to standard output
  607.     ret                ;
  608.  
  609. comp_hex    endp
  610.     page
  611. subs    proc    near
  612.  
  613. ; ****************************************************************
  614. ; **    function: convert two ascii characters to 8 bit number    **
  615. ; **    entry: bx=start address of valid ascii hex characters    **
  616. ; **    uses: al, bx                        **
  617. ; **    exit: a=8 bit number, bx=bx+2                **
  618. ; **    calls: aschex                        **
  619. ; ****************************************************************
  620.  
  621. pack:    push    cx        ; save cx
  622.     mov    al,[bx]        ; load character
  623.     call    aschex        ; convert ascii character to hex
  624.     mov    cl,4        
  625.     rol    al,cl        ; exchange nibbles
  626.     mov    ch,al        ; store
  627.     inc    bx        ; point to next character
  628.     mov    al,[bx]        ; load next character
  629.     call    aschex        ; convert ascii character to hex
  630.     or    al,ch        ; combine nibbles
  631.     inc    bx        ; point to next character
  632.     add    chkacc,al    ; update checksum accumulator
  633.     pop    cx        ; restore cx
  634.     ret
  635.  
  636. ; ****************************************************************
  637. ; **    function: convert ascii to hexadecimal            **
  638. ; **    entry: ascii representation of valid hex number in al    **
  639. ; **    uses: al                         **
  640. ; **    exit: hex number in al                    **
  641. ; **    calls: none                        **
  642. ; ****************************************************************
  643.  
  644. aschex:
  645.     cmp    al,'9'        ; less than or equal to 9?
  646.     jle    aschex_05    ; yes - jump past hex conversion
  647.  
  648.     add    al,9        ; no - add hex offset
  649.  
  650. aschex_05:
  651.     and    al,0FH        ; strip ascii bias
  652.     ret
  653.     page
  654. ; ****************************************************************
  655. ; **    function: convert 8 bit number to two ascii characters    **
  656. ; **         and write them to memory            **
  657. ; **    entry: al = 8 bit number to be converted         **
  658. ; **          bx = address of memory to be written to        **
  659. ; **    uses: al, bx                        **
  660. ; **    calls: hexasc                        **
  661. ; **    exit: bx = address of next location in memory        **
  662. ; ****************************************************************
  663.  
  664. expand:
  665.     push    cx        ; save cx
  666.     push    ax        ; save byte to be expanded
  667.     mov    cl,4        
  668.     rol    al,cl        ; exchange nibbles
  669.     call    hexasc        ; convert hex to ascii
  670.     mov    [bx],al        ; write to memory
  671.     inc    bx        ; advance buffer pointer
  672.     pop    ax        ; restore original byte
  673.     call    hexasc        ; convert hex to ascii
  674.     mov    [bx],al        ; write to screen buffer
  675.     inc    bx        ; advance buffer pointer
  676.     pop    cx        ; restore cx
  677.     ret
  678.  
  679.  
  680. ; ****************************************************************
  681. ; **    function: convert 4 bit number to ascii            **
  682. ; **    entry: lower nibble of a=number to be converted        **
  683. ; **    uses: al                         **
  684. ; **    calls: none                        **
  685. ; **    exit: al = ascii character                **
  686. ; ****************************************************************
  687.  
  688. hexasc:
  689.     and    al,0FH        ; isolate lower nibble
  690.     cmp    al,9        ; is it less than or equal to 9?
  691.     jle    hexasc_05    ; yes - jump past hex conversion
  692.  
  693.     sub    al,9        ; no - subtract hex offset
  694.     or    al,40H        ; combine with hex ascii bias
  695.     ret            
  696.  
  697. hexasc_05:
  698.     or    al,30H        ; combine with decimal ascii bias
  699.     ret
  700.  
  701. subs    endp
  702.     page
  703. errhan    proc    far
  704.  
  705. ; ****************************************************************
  706. ; **                                **
  707. ; **             DOS ERROR HANDLER            **
  708. ; **                                **
  709. ; ****************************************************************
  710.  
  711. doserr:
  712.     mov    dx,offset mdos0        ; point to error string 0
  713.     or    ax,ax            ; error 0?
  714.     jz    dsperr            ; yes - display string and exit to dos
  715.  
  716.     mov    dx,offset mdos1        ; no - point to error string 1
  717.     dec    ax            ; error 1?
  718.     jz    dsperr            ; yes - display string and exit to dos
  719.  
  720.     mov    dx,offset mdos2        ; no - point to error string 2
  721.     dec    ax            ; error 2?
  722.     jz    dsperr            ; yes - display string and exit to dos
  723.  
  724.     mov    dx,offset mdos3        ; no - point to error string 3
  725.     dec    ax            ; error 3?
  726.     jz    dsperr            ; yes - display string and exit to dos
  727.  
  728.     mov    dx,offset mdos4        ; no - point to error string 4
  729.     dec    ax            ; error 4?
  730.     jz    dsperr            ; yes - display string and exit to dos
  731.  
  732.     mov    dx,offset mdos5        ; no - point to error string 5
  733.     dec    ax            ; error 5?
  734.     jz    dsperr            ; yes - display string and exit to dos
  735.  
  736.     mov    dx,offset mdos6        ; no - point to error string 6
  737.     dec    ax            ; error 6?
  738.     jz    dsperr            ; yes - display string and exit to dos
  739.  
  740.     mov    dx,offset muknow    ; no - point to unknown error string
  741.     jmp    dsperr            ; display string and exit to dos
  742.  
  743.  
  744.  
  745. ; ****************************************************************
  746. ; **                                **
  747. ; **              DISPLAY ERROR MESSAGE            **
  748. ; **                                **
  749. ; ****************************************************************
  750.  
  751. dsperr:
  752.     mov    ah,pr_str        ; load print string command
  753.     int    dosfunc            ; write string to standard output
  754.     pop    ax            ; restore stack
  755.     ret                ; return to dos
  756.  
  757. errhan    endp                ;
  758.  
  759. code    ends                ;
  760.  
  761.     end    comphex            ;
  762.