55 lines
1.6 KiB
Plaintext
55 lines
1.6 KiB
Plaintext
org 100h
|
|
jmp demo
|
|
;;; Given an 0-terminated ASCII string containing digits in [DE],
|
|
;;; see if it matches its check digit. Returns with zero flag set
|
|
;;; if the string matches.
|
|
damm: mvi c,0 ; Interim digit in C, starts off at 0.
|
|
ldax d ; Get current byte from string
|
|
inx d ; Advance the pointer
|
|
ana a ; Is the byte zero?
|
|
jnz $+5 ; If not, go look up interim digit
|
|
cmp c ; But if so, see if the interim digit is also zero
|
|
ret ; And return whether this was the case
|
|
sui '0' ; Subtract ASCII 0
|
|
mov b,a ; Keep digit to be processed in B
|
|
mov a,c ; Calculate C*10 (interim digit row index)
|
|
add a ; * 2
|
|
add a ; * 4
|
|
add c ; * 5
|
|
add a ; * 10
|
|
add b ; Add column index
|
|
lxi h,dammit
|
|
add l ; Table lookup (assuming H doesn't change, i.e. it
|
|
mov l,a ; doesn't cross a page boundary).
|
|
mov c,m ; Get new interim digit from table
|
|
jmp damm+2 ; And check next character
|
|
;;; Table of interim digits
|
|
;;; NOTE: must not cross page boundary
|
|
dammit: db 0,3,1,7,5,9,8,6,4,2
|
|
db 7,0,9,2,1,5,4,8,6,3
|
|
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 code: see if the argument on the CP/M command line
|
|
;;; matches its input.
|
|
demo: lxi h,80h ; Zero-terminate input
|
|
mov e,m
|
|
mvi d,0
|
|
inx d
|
|
dad d
|
|
mov m,d
|
|
lxi d,82h ; Command line argument, skipping first space
|
|
call damm ; See if it validates
|
|
mvi c,9
|
|
lxi d,ok ; Print OK...
|
|
jz 5 ; ...if the checksum matches,
|
|
lxi d,no ; Print NOT OK otherwise.
|
|
jmp 5
|
|
no: db 'NOT '
|
|
ok: db 'OK$'
|