home *** CD-ROM | disk | FTP | other *** search
- if1
- %out COMPHEX.ASM
- endif
- if2
- %out **** PASS 2
- endif
- name COMPHEX
- .xall
- page ,132
- title COMPHEX - 28 JUN 1986
-
- ; ****************************************************************
- ; ** **
- ; ** MS-DOS INTEL HEX FILE COMPARATOR **
- ; ** **
- ; **............................................................**
- ; ** **
- ; ** **
- ; ** Written by Michael Kesti. If you like it, use it. **
- ; ** **
- ; ** Requires MS-DOS or PC-DOS version 2.XX or later. **
- ; ** **
- ; ** Assembler: Microsoft MASM **
- ; ** **
- ; ****************************************************************
-
- ; ..... READ DISK FILE MACRO .....
-
- diskrd macro numbyte,bufname ; read numbyte bytes into bufname
- local ok ; ok is a local symbol
- mov ah,read ; load read command
- mov bx,handle ; load file handle
- mov cx,numbyte ; load number of characters to be read
- mov dx,offset bufname ; point to buffer
- int dosfunc ; read from file - error?
- jnc ok ; no - done
-
- jmp doserr ; yes - display error
-
- ok:
- endm
- page
- ; ..... dos commands .....
-
- dosfunc equ 21H ; dos function interrupt
- pr_str equ 09H ; print string command
- create equ 3CH ; create file command
- open equ 3DH ; open file command
- close equ 3EH ; close file command
- read equ 3FH ; read file command
- rdacc equ 0 ; read file access code
- write equ 40H ; write file command
- wratt equ 0 ; write file attribute code
-
-
- ; ..... constants .....
-
- maxlen equ 80 ; maximum filespec length
- tab equ 09H ; ascii tab
- cr equ 0DH ; ascii carriage return
- lf equ 0AH ; ascii line feed
- datind equ 00H ; Intel hex file data record indicator
- eofind equ 01H ; Intel hex file end of file indicator
- std_out equ 01H ; standard output file handle
-
-
- stack segment stack ; stack segment
- dw 1024 dup (?) ; 1024 levels of stack
- stack ends
- page
- data segment ; data segment
-
- ; ****************************************************************
- ; ** **
- ; ** STRINGS **
- ; ** **
- ; ****************************************************************
-
- mbcom db cr,lf,'COMMAND LINE ERROR',cr,lf,lf,'$'
-
- mlong db cr,lf,'INPUT FILE TOO LONG',cr,lf,lf,'$'
-
- mbhex db cr,lf,'INVALID HEX FILE ',cr,lf,lf,'$'
-
- mfileA db 'FILE A = $'
-
- mfileB db cr,lf,'FILE B = $'
-
- mhdr db cr,lf
- db cr,lf,'ADDR',tab,'FILE A',tab,'FILE B'
- db cr,lf,'----',tab,'------',tab,'------',cr,lf,'$'
-
- mbytes db cr,lf,'BYTE COUNT: $'
-
- mmis db cr,lf,'MISMATCH COUNT: $'
-
- mnewlin db cr,lf,'$'
-
- mdos0 db cr,lf,'DISK FULL',cr,lf,lf,'$'
-
- mdos1 db cr,lf,'INVALID FUNCTION',cr,lf,lf,'$'
-
- mdos2 db cr,lf,'FILE NOT FOUND',cr,lf,lf,'$'
-
- mdos3 db cr,lf,'PATH NOT FOUND',cr,lf,lf,'$'
-
- mdos4 db cr,lf,'TOO MANY OPEN FILES',cr,lf,lf,'$'
-
- mdos5 db cr,lf,'ACCESS DENIED',cr,lf,lf,'$'
-
- mdos6 db cr,lf,'INVALID HANDLE',cr,lf,lf,'$'
-
- muknow db cr,lf,'UNKNOWN DISK ERROR',cr,lf,lf,'$'
- page
- ; ****************************************************************
- ; ** **
- ; ** STORAGE ASSIGNMENTS **
- ; ** **
- ; ****************************************************************
-
- file_A db maxlen+1 dup (0) ; first filespec
-
- file_B db maxlen+1 dup (0) ; second filespec
-
- handle dw ? ; file handle
-
- dskbuf db 80 dup (?) ; disk buffer
-
- dskptr dw (?) ; disk buffer pointer
-
- dskcnt dw (?) ; disk buffer counter
-
- chkacc db (?) ; checksum accumulator
-
- memadd dw (?) ; memory address
-
- numrec dw (?) ; number of records in current line
-
- recbyt dw (?) ; number of bytes for numrec records
-
- outbuf db 83 dup (?) ; output buffer
-
- comp_cnt dw (0) ; compare counter
-
- mis_cnt dw (0) ; mismatch counter
-
- filebuf equ this byte ; file buffer start
-
- org 0FFFFH ; segment end
- endbuf equ this byte ; file buffer end
-
- memlen equ (offset endbuf - offset filebuf) / 2 ; file buffer length
-
- org filebuf ;
-
- buf_A db memlen dup (?) ; first first buffer
-
- buf_B db memlen dup (?) ; second file buffer
-
- data ends
- page
- code segment ; code segment
-
- assume cs:code,ds:data,es:data,ss:stack
-
- ; ****************************************************************
- ; ** **
- ; ** MAIN PROGRAM **
- ; ** **
- ; ****************************************************************
-
- comphex proc far ;
-
- push ds ;
- mov ax,0 ;
- push ax ; set up for far return to dos
-
- mov ax,data ;
- mov ds,ax ; set up data segment register
-
- call rcmd ; read command line
- call open_A ; open first file
- mov bp,offset buf_A ; point to first file buffer
- call load_hex ; load hex file
- call closer ; close first file
- call open_B ; open first file
- mov bp,offset buf_B ; point to second file buffer
- call load_hex ; load hex file
- call closer ; close first file
- call comp_hex ; compare the hex files
- ret ; return to dos
-
- comphex endp ;
- page
- ; ****************************************************************
- ; ** **
- ; ** READ COMMAND LINE **
- ; ** **
- ; ****************************************************************
-
- rcmd proc near ;
-
- mov bx,80H ; point to received characters quantity
- mov ch,es:[bx] ; load character counter
- or ch,ch ; zero characters?
- jz rcmd30 ; yes - display error
-
- inc bx ; no - point to characters
- mov di,offset file_A ; point to first filespec
- mov cl,maxlen ; load length counter
- mov al,es:[bx] ; load next character
- inc bx ; advance pointer
- dec ch ; retard character counter - end?
- jz rcmd30 ; yes - display error
-
- cmp al,' ' ; no - space?
- jnz rcmd30 ; no - display error
-
- rcmd05:
- mov al,es:[bx] ; yes - load next character
- mov [di],al ; write to first filespec
- cmp al,' ' ; space?
- jz rcmd10 ; yes - load second filespec
-
- inc bx ; no -
- inc di ; - advance pointers
- dec ch ; retard character counter - end?
- jz rcmd30 ; yes - display error
-
- dec cl ; no - retard length counter - too long?
- jz rcmd30 ; yes - display error
-
- jmp rcmd05 ; no - load next character
-
- rcmd10:
- inc bx ; advance command line pointer
- dec ch ; retard character counter - end?
- jz rcmd30 ; yes - display error
-
- mov di,offset file_B ; no - point to second filespec
- mov cl,maxlen ; load length counter
-
- rcmd15:
- mov al,es:[bx] ; load next character
- cmp al,' ' ; space?
- jz rcmd35 ; yes - done
-
- mov [di],al ; no - write to second filespec
- inc bx ;
- inc di ; advance pointers
- dec ch ; retard counter - last character?
- jz rcmd35 ; yes - exit
-
- dec cl ; no - retard length counter - too long?
- jz rcmd30 ; yes - display error
-
- jmp rcmd15 ; no - load next character
-
- rcmd30:
- mov dx,offset mbcom ; point to bad command line string
- jmp dsperr ; display string and exit to dos
-
- rcmd35:
- ret ;
-
- rcmd endp ;
- page
- ; ****************************************************************
- ; ** **
- ; ** OPEN FIRST FILE **
- ; ** **
- ; ****************************************************************
-
- open_A proc near ;
-
- mov ah,open ; load open file command
- mov al,rdacc ; load read access code
- mov dx,offset file_A ; point to first filespec
- int dosfunc ; open first file - error?
- jnc open_A05 ; no - store file handle
-
- jmp doserr ; yes - display error
-
- open_A05:
- mov handle,ax ; store file handle
- ret ; done
-
- open_A endp ;
- page
- ; ****************************************************************
- ; ** function: load an INTEL hex file into memory space **
- ; ** entry: file handle in handle **
- ; ** uses: all **
- ; ** exit: carry flag is clear if no errors detected **
- ; ** calls: pack **
- ; ****************************************************************
-
- load_hex proc near
-
- diskrd 1,dskbuf ; read one byte from disk file - error?
-
- cmp ax,01 ; no - 1 character?
- jz load_hex_15 ; yes - test for record mark
-
- jmp load_hex_60 ; no - write error
-
- load_hex_15:
- lea bx,dskbuf ; point to disk buffer
- mov al,[bx] ; load received character
- cmp al,':' ; record mark?
- jnz load_hex ; no - try again
-
- diskrd 8,dskbuf ; yes - read eight bytes from disk file - error?
-
- mov chkacc,0 ; no - initialize checksum accumulator
- cmp ax,08 ; receive 8 characters?
- jz load_hex_20 ; yes - convert number of bytes in record
-
- jmp load_hex_60 ; no - write error
-
- load_hex_20:
- lea bx,dskbuf ; point to disk buffer
- call pack ; convert number of bytes in record
- mov ah,0
- mov numrec,ax ; store
- call pack ; convert high start address
- mov dh,al ; store
- call pack ; convert low start address
- mov dl,al ; store
- mov memadd,dx ; store this record's start address
- call pack ; convert record indicator
- cmp al,datind ; data indicator?
- jz load_hex_23 ; yes - load number of records
-
- jmp load_hex_35 ; no - test for end of file indicator
-
- load_hex_23:
- mov ax,numrec ; load number of records
- add ax,ax ; compute number of data characters
- add ax,4 ; add checksum and terminator character count
- mov recbyt,ax ; store
- diskrd recbyt,dskbuf ; yes - read recbyt bytes from disk file - error?
-
- lea bx,dskbuf ; no - point to disk buffer
- mov dskptr,bx ; inititialize disk buffer pointer
- cmp recbyt,cx ; receive correct number of characters?
- jz load_hex_25 ; yes - convert record
-
- jmp load_hex_60 ; no - write error
-
- load_hex_25:
- mov cx,numrec ; load counter
- jcxz load_hex_40 ; zero characters? - yes - read and test
- ; chksum and terminator
-
- load_hex_30:
- mov bx,dskptr ; no - load disk buffer pointer
- call pack ; convert data
- mov dskptr,bx ; store disk buffer pointer
- mov si,memadd ; load memory address
- mov ds:[si + bp],al ; store data in memory space
- inc memadd ; advance memory address
- dec cx ; retard counter - done?
- jnz load_hex_30 ; no - continue
-
- mov ax,memadd ; yes - load memory address
- cmp ax,comp_cnt ; greater than current compare counter?
- jb load_hex_33 ; no - test checksum
-
- mov comp_cnt,ax ; yes - update comapre counter
-
- load_hex_33:
- mov bx,dskptr ; load disk buffer pointer
- call pack ; convert checksum
- mov cl,al ; store checksum
- mov al,chkacc ; load checksum accumulator
- sub al,cl ; adjust checksum
- not al ;
- inc al ; compute 2's complement of checksum
- cmp al,cl ; checksums match?
- jnz load_hex_60 ; no - write error
-
- cmp byte ptr[bx],cr ; yes - terminated with <cr>?
- jnz load_hex_60 ; no - write error
-
- inc bx ; yes - point to line feed
- cmp byte ptr[bx],lf ; line feed?
- jnz load_hex_60 ; no - write error
-
- jmp load_hex ; yes - continue
-
- load_hex_35:
- cmp al,eofind ; end of file indicator?
- jnz load_hex_60 ; no - write error
-
- diskrd 4,dskbuf ; yes - read 4 bytes from disk file - error?
- cmp ax,4 ; no - 4 characters?
- jnz load_hex_60 ; no - write error
-
- load_hex_40:
- lea bx,dskbuf ; yes - point to disk buffer
- call pack ; convert checksum
- mov cl,al ; store checksum
- mov al,chkacc ; load checksum accumulator
- sub al,cl ; adjust checksum
- not al ;
- inc al ; compute 2's complement of checksum
- cmp al,cl ; checksums match?
- jnz load_hex_60 ; no - write error
-
- cmp byte ptr[bx],cr ; yes - terminated with <cr>?
- jnz load_hex_60 ; no - write error
-
- inc bx ; yes - point to line feed
- cmp byte ptr[bx],lf ; line feed?
- jnz load_hex_60 ; no - write error
-
- load_hex_55:
- clc ; yes - indicate no error occurred
- ret ;
-
- load_hex_60:
- lea dx,mbhex ; point to bad hex data string
- jmp dsperr ; display string and exit to dos
-
- load_hex endp
- page
- ; ****************************************************************
- ; ** **
- ; ** OPEN SECOND FILE **
- ; ** **
- ; ****************************************************************
-
- open_B proc near ;
-
- mov ah,open ; load open file command
- mov al,rdacc ; load read access code
- mov dx,offset file_B ; point to second filespec
- int dosfunc ; open second file - error?
- jnc open_B05 ; no - store file handle
-
- jmp doserr ; yes - display error
-
- open_B05:
- mov handle,ax ; store file handle
- ret ; done
-
- open_B endp ;
- page
- ; ****************************************************************
- ; ** **
- ; ** CLOSE FILE **
- ; ** **
- ; ****************************************************************
-
- closer proc near ;
-
- mov ah,close ; load close file command
- mov bx,handle ; load file handle
- int dosfunc ; close file - error?
- jnc closer05 ; no - done
-
- jmp doserr ; yes - display error
-
- closer05:
- ret ;
-
- closer endp
- page
- ; ****************************************************************
- ; ** **
- ; ** COMPARE FILES **
- ; ** **
- ; ****************************************************************
-
- comp_hex proc near ;
- lea si,file_A ; point to first filespec
-
- comp_hex_05:
- cmp byte ptr[si],0 ; next first filename character = 0?
- je comp_hex_10 ; yes - write terminator
-
- inc si ; no - advance pointer
- jmp comp_hex_05 ; test next character
-
- comp_hex_10:
- mov byte ptr[si],'$' ; terminate first filespec
- lea si,file_B ; point to second filespec
-
- comp_hex_15:
- cmp byte ptr[si],0 ; next second filename character = 0?
- je comp_hex_20 ; yes - write terminator
-
- inc si ; no - advance pointer
- jmp comp_hex_15 ; test next character
-
- comp_hex_20:
- mov byte ptr[si],'$' ; terminate second filespec
- mov dx,offset mfileA ; point to file A string
- mov ah,pr_str ; load print string command
- int dosfunc ; write string to standard output
- mov dx,offset file_A ; point to filespecA
- mov ah,pr_str ; load print string command
- int dosfunc ; write string to standard output
- mov dx,offset mfileB ; point to file B string
- mov ah,pr_str ; load print string command
- int dosfunc ; write string to standard output
- mov dx,offset file_B ; point to filespecB
- mov ah,pr_str ; load print string command
- int dosfunc ; write string to standard output
- lea si,buf_A ; point to first file
- lea di,buf_B ; point to second file
- mov cx,comp_cnt ; load compare counter - zero?
- jcxz comp_hex_45 ; yes - done
-
- comp_hex_25:
- mov al,[si] ; no - load next first file character
- cmp al,[di] ; match next second file character?
- jne comp_hex_30 ; no - test for first mismatch
-
- jmp comp_hex_40 ; yes - continue
-
- comp_hex_30:
- push cx ; save compare counter
- cmp mis_cnt,0 ; first mismatch?
- jne comp_hex_35 ; no - output mismatch
-
- mov dx,offset mhdr ; yes - point to header string
- mov ah,pr_str ; load print string command
- int dosfunc ; write header string to standard output
-
- comp_hex_35:
- lea bx,outbuf ; point to output buffer
- mov dx,si ; load buffer pointer
- sub dx,offset buf_A ; compute address
- mov al,dh ; load high address
- call expand ; convert to ascii
- mov al,dl ; load low address
- call expand ; convert to ascii
- mov byte ptr[bx],tab ; write tab to output buffer
- inc bx ; advance output buffer pointer
- mov al,[si] ; load first file byte
- call expand ; convert to ascii
- mov byte ptr[bx],tab ; write tab to output buffer
- inc bx ; advance output buffer pointer
- mov al,[di] ; load second file byte
- call expand ; convert to ascii
- mov byte ptr[bx],cr ; write cr to output buffer
- inc bx ; advance output buffer pointer
- mov byte ptr[bx],lf ; write lf to output buffer
- mov ah,write ; load write command
- mov bx,std_out ; load standard output file handle
- mov cx,12 ; load number of characters
- lea dx,outbuf ; point to output buffer
- int dosfunc ; write to standard output
- inc mis_cnt ; advance mismatch counter
- pop cx ; restore compare counter
-
- comp_hex_40:
- inc si ;
- inc di ; advance pointers
- dec cx ; done?
- jz comp_hex_45 ; yes - display summary
-
- jmp comp_hex_25 ; no - continue
-
- comp_hex_45:
- cmp mis_cnt,0 ; any mismatches?
- jne comp_hex_50 ; yes - output summary
-
- mov dx,offset mnewlin ; no - point to newline string
- mov ah,pr_str ; load print string command
- int dosfunc ; write string to standard output
-
- comp_hex_50:
- mov dx,offset mbytes ; yes - point to last address string
- mov ah,pr_str ; load print string command
- int dosfunc ; write string to standard output
- lea bx,outbuf ; point to output buffer
- mov dx,comp_cnt ; load compare counter
- mov al,dh ; load high compare counter
- call expand ; convert to ascii
- mov al,dl ; load low compare counter
- call expand ; convert to ascii
- mov ah,write ; load write command
- mov bx,std_out ; load standard output file handle
- mov cx,4 ; load number of characters
- lea dx,outbuf ; point to output buffer
- int dosfunc ; write to standard output
- mov dx,offset mmis ; point to mismatch string
- mov ah,pr_str ; load print string command
- int dosfunc ; write string to standard output
- lea bx,outbuf ; point to output buffer
- mov dx,mis_cnt ; load mismatch counter
- mov al,dh ; load high address
- call expand ; convert to ascii
- mov al,dl ; load low address
- call expand ; convert to ascii
- mov ah,write ; load write command
- mov bx,std_out ; load standard output file handle
- mov cx,4 ; load number of characters
- lea dx,outbuf ; point to output buffer
- int dosfunc ; write to standard output
- mov dx,offset mnewlin ; point to newline string
- mov ah,pr_str ; load print string command
- int dosfunc ; write string to standard output
- ret ;
-
- comp_hex endp
- page
- subs proc near
-
- ; ****************************************************************
- ; ** function: convert two ascii characters to 8 bit number **
- ; ** entry: bx=start address of valid ascii hex characters **
- ; ** uses: al, bx **
- ; ** exit: a=8 bit number, bx=bx+2 **
- ; ** calls: aschex **
- ; ****************************************************************
-
- pack: push cx ; save cx
- mov al,[bx] ; load character
- call aschex ; convert ascii character to hex
- mov cl,4
- rol al,cl ; exchange nibbles
- mov ch,al ; store
- inc bx ; point to next character
- mov al,[bx] ; load next character
- call aschex ; convert ascii character to hex
- or al,ch ; combine nibbles
- inc bx ; point to next character
- add chkacc,al ; update checksum accumulator
- pop cx ; restore cx
- ret
-
- ; ****************************************************************
- ; ** function: convert ascii to hexadecimal **
- ; ** entry: ascii representation of valid hex number in al **
- ; ** uses: al **
- ; ** exit: hex number in al **
- ; ** calls: none **
- ; ****************************************************************
-
- aschex:
- cmp al,'9' ; less than or equal to 9?
- jle aschex_05 ; yes - jump past hex conversion
-
- add al,9 ; no - add hex offset
-
- aschex_05:
- and al,0FH ; strip ascii bias
- ret
- page
- ; ****************************************************************
- ; ** function: convert 8 bit number to two ascii characters **
- ; ** and write them to memory **
- ; ** entry: al = 8 bit number to be converted **
- ; ** bx = address of memory to be written to **
- ; ** uses: al, bx **
- ; ** calls: hexasc **
- ; ** exit: bx = address of next location in memory **
- ; ****************************************************************
-
- expand:
- push cx ; save cx
- push ax ; save byte to be expanded
- mov cl,4
- rol al,cl ; exchange nibbles
- call hexasc ; convert hex to ascii
- mov [bx],al ; write to memory
- inc bx ; advance buffer pointer
- pop ax ; restore original byte
- call hexasc ; convert hex to ascii
- mov [bx],al ; write to screen buffer
- inc bx ; advance buffer pointer
- pop cx ; restore cx
- ret
-
-
- ; ****************************************************************
- ; ** function: convert 4 bit number to ascii **
- ; ** entry: lower nibble of a=number to be converted **
- ; ** uses: al **
- ; ** calls: none **
- ; ** exit: al = ascii character **
- ; ****************************************************************
-
- hexasc:
- and al,0FH ; isolate lower nibble
- cmp al,9 ; is it less than or equal to 9?
- jle hexasc_05 ; yes - jump past hex conversion
-
- sub al,9 ; no - subtract hex offset
- or al,40H ; combine with hex ascii bias
- ret
-
- hexasc_05:
- or al,30H ; combine with decimal ascii bias
- ret
-
- subs endp
- page
- errhan proc far
-
- ; ****************************************************************
- ; ** **
- ; ** DOS ERROR HANDLER **
- ; ** **
- ; ****************************************************************
-
- doserr:
- mov dx,offset mdos0 ; point to error string 0
- or ax,ax ; error 0?
- jz dsperr ; yes - display string and exit to dos
-
- mov dx,offset mdos1 ; no - point to error string 1
- dec ax ; error 1?
- jz dsperr ; yes - display string and exit to dos
-
- mov dx,offset mdos2 ; no - point to error string 2
- dec ax ; error 2?
- jz dsperr ; yes - display string and exit to dos
-
- mov dx,offset mdos3 ; no - point to error string 3
- dec ax ; error 3?
- jz dsperr ; yes - display string and exit to dos
-
- mov dx,offset mdos4 ; no - point to error string 4
- dec ax ; error 4?
- jz dsperr ; yes - display string and exit to dos
-
- mov dx,offset mdos5 ; no - point to error string 5
- dec ax ; error 5?
- jz dsperr ; yes - display string and exit to dos
-
- mov dx,offset mdos6 ; no - point to error string 6
- dec ax ; error 6?
- jz dsperr ; yes - display string and exit to dos
-
- mov dx,offset muknow ; no - point to unknown error string
- jmp dsperr ; display string and exit to dos
-
-
-
- ; ****************************************************************
- ; ** **
- ; ** DISPLAY ERROR MESSAGE **
- ; ** **
- ; ****************************************************************
-
- dsperr:
- mov ah,pr_str ; load print string command
- int dosfunc ; write string to standard output
- pop ax ; restore stack
- ret ; return to dos
-
- errhan endp ;
-
- code ends ;
-
- end comphex ;