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$'