The Damm algorithm is a checksum algorithm which detects all single digit errors and adjacent transposition errors.



The algorithm is named after H. Michael Damm.



Task

Verify the checksum, stored as last digit of an input.



	cpu	8086
	bits	16
section	.text
	org	100h
	jmp	demo
	;;;	Given a 0-terminated ASCII string containing digits in
	;;;	[DS:SI], see if the check digit matches. Returns with zero flag
	;;;	set if it matches.
damm:	xor	cl,cl	; Interim digit starts out at 0
	mov	bx,.tab	; Index for table lookup
.dgt:	lodsb		; Get next string byte
	test	al,al	; If it is zero, we're done
	jz	.out
	sub	al,'0'	; Make ASCII digit
	mov	ah,cl	; Table lookup, AH = interim digit
	aad		; AL += AH * 10 (such handy instructions the 8086 has)
	cs 	xlatb	; AL = CS:table[AL]
	mov	cl,al	; CL = new interim digit
	jmp	.dgt	; Get next string
.out:	test	cl,cl	; Interim digit should be zero at the end
	ret
.tab:	db	0,3,1,7,5,9,8,6,4,2	; Table can be stored as part of the
	db	7,0,9,2,1,5,4,8,6,3	; code
	db	4,2,0,6,8,7,1,3,5,9
	db	1,7,5,0,9,8,3,4,2,6
	db	6,1,2,3,0,4,5,9,7,8
	db	3,6,7,4,2,0,9,5,8,1
	db	5,8,6,9,7,2,0,1,3,4
	db	8,9,4,5,3,6,2,0,1,7
	db	9,4,3,8,6,1,7,2,0,5
	db	2,5,8,1,4,3,6,7,9,0
	;;;	Demo: see if the argument on the MS-DOS command line is valid
demo:	xor	bh,bh	; Zero-terminate the input
	mov	bl,[80h]
	mov	[bx+81h],bh
	mov	si,82h	; Start of input skipping first space
	call	damm	; Is it valid?
	mov	dx,ok	; If so, print OK
	jz	.print
	mov	dx,no 	; Otherwise, print NOT OK
.print:	mov	ah,9
	int	21h
	ret
section	.data
no:	db	'NOT '
ok: 	db	'OK$'