ZX Interface 1: Difference between revisions

Jump to navigation Jump to search
Added the checksum formula to the data.
(Added the data checksum to the table.)
(Added the checksum formula to the data.)
Line 226: Line 226:
| 0200H || 0xnn || The data checksum.  
| 0200H || 0xnn || The data checksum.  
|-
|-
|}


=== Calculating the checksum ===
The checksum isn't a standard checksum, a parity, a logitudinal redundancy check or a a two's compliment checksum.
It starts as a basic 8-bit sum of each of the characters, but has additional calculated bits inserted to avoid the sum "255" ever being calculated at any stage during the sum process.
The assembly language in the Interface1 ROM is called with HL pointing to the buffer where the microdrive data is stored. It looks like this (below);
{| class="wikitable" style="text-align: left;"
|-
|SECTOR:||LD BC,$000E||14 bytes in the header. Entry point for headers, location 0x1426.
|-
| ||JR      SUM|| Calculate the checksum.
|-
|RECORD:||LD BC,$0200||200 bytes in the record. Location 0x142B
|-
|SUM:||PUSH    HL|| Enter with HL pointing to the buffer, either at the header, or the record contents. Store the start.
|-
| ||LD      E,$00||Zero the checksum to start.
|-
|LOOP:||LD      A,E|| Pick up the current checksum.
|-
| ||ADD    A,(HL)||Add a byte from the buffer to the checksum.
|-
| ||INC    HL||Move the pointer to the next byte in the buffer.
|-
| ||ADC    A,$01||Here's where it gets complicated. If the previous add overflowed, add Carry plus 1 ( add 2 ). Otherwise just add 1.
|-
| ||JR      Z,SKIP||However if the last checksum calculation was 0FF, now it will be zero, and the zero flag set. If it's zero, skip the next instruction.
|-
| ||DEC    A|| If not skipped, remove the 1 just added, however if two were added, then just subtract 1. If it was 0FF, just leave it as 00 now.
|-
|SKIP:||LD E,A||Store the sum so far...
|-
| ||DEC    BC||Reduce the counter of bytes in the buffer.
|-
| ||LD      A,B||We need to test if the counter is zero.
|-
| ||OR      C||Set the zero flag now if BC is zero.
|-
| ||JR      NZ,LOOP||If we haven't summed all the bytes in the buffer, loop back and iterate.
|-
| ||LD      A,E||Collect the checksum.
|-
| ||CP      (HL)||Byte after the buffer is where the checksum should be stored. Test the calculated checksum against the stored checksum.
|-
| ||LD      (HL),A||And regardless of whether it's right or wrong, write the correct checksum in there now... So this routine both checks and calculates the checksum.
|-
| ||POP    HL||Retrieve HL to point to the start of the buffer again.
|-
| ||RET||Zero flag is set if the checksum was correct. Can be tested by the routine that called this one.
|-
|}
The Pseudocode for this process, if calculated in a high level language looks something like this;
{| class="wikitable" style="text-align: left;"
|-
|Checksum = 0
|-
|while (bytes in buffer) do
|-
|...Add byte to checksum
|-
|...If checksum=255 then checksum=0
|-
|...If checksum>255 then checksum=(checksum modulo 256)+1
|-
|done
|-
|}
|}


34

edits

Navigation menu