TITLE Hamming Code Reader (hamming.asm) Comment ! This program reads ASCII binary values from a text file and converts them to 16-bit binary integers. It then checks for errors, using the Hamming code algorithm and identifies and corrects up to 1 error in each integer. ! INCLUDE Irvine16.inc Group1 = 1010101010100000b Group2 = 0110011001100000b Group4 = 0001111000010000b Group8 = 0000000111110000b .data codeWord DW ? badBitnum DW ? filename DB "hamming.txt",0 greetingMsg DB "PROJECT 5 DEMO - ERROR CORRECTION",0dh,0ah DB "---------------------------------",0dh,0ah,0 readingMsg DB "Reading code word: ",0 parityErrMsg DB "....parity error found in position ",0 noErrMsg DB "....no error detected",0 errorFixed DB "....error corrected: ",0 filehandle DW ? EOFflag DW 0 buffer DB 25 DUP(0) .code main PROC mov ax,@data mov ds,ax mov dx,offset greetingMsg call WriteString mov dx,offset filename call Open_infile ; library procedure mov filehandle,ax call ReadOneCodeWord ; read file into codeWord .WHILE EOFFlag == 0 call TestCodeWord call FixCodeWord call ReadOneCodeWord ; read file into codeWord .ENDW mov bx,filehandle call Close_file .exit main ENDP ;-------------------------------------------------- FixCodeWord PROC ; Fix the error by toggling the bad bit in the ; code word. ;-------------------------------------------------- .IF badBitnum > 0 mov ax,codeWord mov bx,16 ; actual bit position is sub bx,badBitnum ; (16 - badBitnum) btc ax,bx ; complement the bit mov codeWord,ax ; save in codeWord mov dx,offset errorFixed ; "error fixed" call WriteString call WriteBin ; display AX in binary call Crlf .ENDIF ret FixCodeWord ENDP ;-------------------------------------------------- TestCodeWord PROC ; Test the code word for each of the bit groups ; Uses a trick to determine the bad bit: For each ; group having odd parity, add the group number to ; a sum. The sum will identify the position of ; the bad bit. ; Thanks to Brian Peterson for discovering that you ; can check the parity of a 16-bit register with a ; single instruction: XOR AH,AL ; He calls it "bit pair annihlation". ;-------------------------------------------------- mov badBitnum,0 ; set sum to zero ; Group 1-3-5-7-9-11: G1: mov ax,codeWord and ax,Group1 ; test Group1 parity xor ah,al ; check parity jp G2 mov badBitnum,1 ; no: set sum to 1 ; Group 2-3-6-7-10-11: G2: mov ax,codeWord ; test Group1 parity and ax,Group2 xor ah,al jp G4 add badBitnum,2 ; no: add 2 to sum ; Group 4-5-6-7-12: G4: mov ax,codeWord ; test Group4 parity and ax,Group4 xor ah,al jp G8 add badBitnum,4 ; no: add 4 to sum ; Group 8-9-10-11-12: G8: mov ax,codeWord ; test Group8 parity and ax,Group8 xor ah,al jp Done add badBitnum,8 ; no: add 8 to sum Done: .IF badBitnum > 0 mov dx,offset parityErrMsg ; "parity error found" call WriteString mov ax,badBitnum ; display the bit number mov bx,10 call WriteInt .ELSE mov dx,offset noErrMsg ; "no error found" call WriteString .ENDIF call Crlf ret TestCodeWord ENDP ;------------------------------------------------------- ReadOneCodeWord PROC ; Read a 16-digit ASCII binary string from the input ; file and convert to a binary value. ; Returns: value in AX ;------------------------------------------------------- pusha mov ah,3Fh ; read from file mov bx,filehandle mov cx,18 ; byte count mov dx,offset buffer int 21h .IF ax < cx mov EOFflag,1 jmp quit ; end of file .ENDIF call Crlf mov dx,offset readingMsg call WriteString mov dx,offset buffer call WriteString ; Translate ASCII binary to pure binary. The bits ; will be in big endian order. mov si,0 mov cx,16 mov dx,0 ; binary bit string L1: mov al,buffer[si] cmp al,'1' ; is digit a 1? jne L2 ; no, skip next statement or dx,8000h ; yes: set high bit L2: rol dx,1 ; rotate to left inc si ; point to next digit Loop L1 mov codeWord,dx quit: popa ret ReadOneCodeWord ENDP Open_infile proc mov ah,3Dh ; function: open file mov al,0 ; input mode int 21h ; call DOS ret Open_infile endp Close_file proc push ax mov ah,3Eh ; function: close file int 21h ; call DOS pop ax ret ; AX = error code if CF = 1 Close_file endp END main