I came up with the following code to check to see if the last 2 bytes of a 12-byte value read in from a RDM6300 card reader is actually the checksum of the first 10 bytes.
;card sample data out in decimal: 88003FF259 1C
;in hex: 38h,38h,30h,30h,33h,46h,46h,32h,35h,39h 31h,43h
;main entry point here
rfidvalidate:
;Wrecks R3,R2,R1,A. Returns: C=0=OK,1=bad
clr A ;clear accumulator (used to calculate checksum)
mov R2,#6h ;read 6 pairs of hex digits...
mov R1,#RFIDPSTART+1 ;starting at memory location R1 (start of data)
readbytes:
push ACC ;save accumulator
lcall rfid2asc ;read and convert hex character to binary equivalent
mov A,R3 ;store it for now
lcall rfid2asc ;read and convert next hex character to binary equivalent
swap A ;1st hex character was high byte.
orl A,R3 ;append 2nd hex character to make real byte
mov R3,A ;hold onto the byte
pop ACC ;restore checksum accumulator
xrl A,R3 ;and xor checksum with new value received
djnz R2,readbytes ;keep going until all 6 pairs of hex digits are read
clr C ;assume everything is OK
jz rfidcsum ;if after all xor operations, value is zero, there's no error
setb C ;here we indicate error (C=1)
rfidcsum:
ret
rfid2asc:
push ACC ;save accumulator again to prevent high byte from corruption
mov A,@R1 ;get hex character (value is 30h through 39h or 41h through 46h)...
inc R1 ;and advance pointer
clr C ;clear carry...
subb A,#30h ;so subtract won't subtract #31h
anl A,#01Fh ;force result to lower 5 bits **
jnb ACC.4,noa2f ;if 5th bit is set then value is Ah through Fh...
anl A,#0Fh ;only accept low nibble **
add A,#9h ;and add 9 to the result to get proper value
noa2f:
anl A,#0Fh ;only accept low nibble again **
mov R3,A ;and save result
pop ACC ;so that our old accumulator restores.
ret
;** starred comments represent extra code I put in to increase sanity
; (incase the reader hardware breaks)
My card reader I bought on ebay is based on the RDM6300 protocol and a link to the data format is found here: https://www.scribd.com/document/234332424/RDM6300
Can this code somehow be improved so that it takes up less space, runs with fewer clock cycles and uses fewer registers and takes up less memory? The only thing OK with taking up memory is the data space for the 12 incoming characters.