vickyg2003 wrote:On your last copy i really tried to understand the checksum bytes. I hope to be able to get the jp1.2 version as well.
Use my MCE.xls spreadsheet as a guide, especially the "Checksum" tab.
https://www.hifi-remote.com/forums/dload ... e_id=14692
This is going to seem more complicated than it really is, but hopefully, once you get it, you'll see how simple it really is. But here's a high level overview.
As you know, each bit in the checksum is an XOR of a combination of bits from the 16-bit data stream, regardless of whether it's the 8-8 data for the keyboard or the 7-7-2 data for the mouse.
Now look at it from the point of view (POV) of the bits in the data stream. Each bit is used in one or more checksum bits. On the spreadsheet, if you look left to right, you are seeing it from the POV of the checksum, but if you look at it vertically, you are seeing it from the POV of the data. So, taking the first data bit (OBC bit7) as an example, it is used in the 1st, 3rd and 5th bits (checksum bits 7/5/3), so if that bit is set, we should XOR the value 1 with those bits in the checksum.
So, what I do in the code is, when I process the first data bit, I check if it's set, if it isn't I skip to the next bit, but if it is, I XOR "10101" with the checksum. The 2nd data bit is used in the 1st and 3rd checksum bits, so when I process the 2nd data bit, if it's set, I will XOR "10100" with the checksum.
So, how do I know which pattern to use for each data bit? That's where the extra data that I put in the data block comes into play, and the magic ingredient there was the LDCD command that I found.
First, the extra data in the data block is:
dw A8A0h
dw 9890h
dw 8878h
dw 7068h
dw 6058h
dw 5048h
dw 3830h
dw 2818h
where you'll notice that A8 is "10101-000" in binary, and A0 is "10100-000", and you'll remember that those are the first 2 checksum strings that I just mentioned a moment ago.
So, back to the LDCD command. To use that, you first have to load a memory address into a scratch register (ie, one of the Wx or RCx guys), then you can load the data at that address into another scratch register.
Here's the relevant code from my PB file:
Code: Select all
LDW WW2,#FF29h ;get the address of the last checksum key
LDCD W6,@W2 ;load the next checksum key
This is saying, load the address "FF29" into W2 (and W3 as it's a "word"), then use W2 to load the data at that address into W6. The last byte of my data block data is "18h", so that LDCD statement will load the value "18h" into W6.
The other cool thing with LDCD is that, when you use it, it automatically decreases the address that you used, so I start with FF29 as my address, then as soon as I do the LDCD move, the address in W2 becomes FF28.
Here's the checksum code
Code: Select all
CLR W1 ;clear the checksum result
LDW WW2,#FF29h ;get the address of the last checksum key
LD W8,#10h ;set loop count to 16
Loop: LDCD W6,@W2 ;load the next checksum key
RRC W4 ;rotate the input data right by 1
RRC W5 ;LSB ends up in CARRY
JRNC Loop2 ;skip XOR if CARRY not set
XOR W1,W6 ;XOR the key with the running result
Loop2: DJNZ W8,Loop
That code is saying (line by line)..
1. Clear the checksum, which I am holding in W1
2. Load the starting address (ie, the end of the checksum data block)
3. Use W8 as an index and set it to 16 (the number of data bits)
4. Grab the byte at W2 (ie, FF29), load it into W6 and reduce W2 by 1
5. Rotate the left byte of input data right by 1 bit (with the right bit falling into CARRY)
6. Rotate the CARRY bit into the right byte of input data, with the right bit of that byte falling into CARRY.
7. If CARRY is clear, skip #8 below
8. XOR the data in W6 (from #4 above) with W1 (the checksum)
9. Reduce the index by 1, and if it's not 0, loop back to step 4 above.
Those 2 "rotate" statements mean that I am rotating the entire 16 bit string right each time, with the right most bit falling into the CARRY and if the CARRY is set, I XOR the checksum. When the checksum routine is finished, I still have the original CARRY bit in there, so I need to rotate it one more time to get W4 and W5 back to their original values. I do this because I use them to help re-arrange the mouse data.
The biggest problem that I see in trying to port this to HCS08 is finding a version of LDCD in that assembler.
