SYNCSUMs
One day, I was typing a system-check program into our computer. I took four and a half hours to enter the program. As I was about to run it, an awful thought occurred to me: What if I had made an error in my typing? Since the program had access to all parts of the system, a typo could be fatal. I decided to check it against the listing . . . once. Then I ran it. The end result—that I overwrote the system disk—is irrelevant. But what is important is this: If the program listing had included the program’s SYNCSUM, I would have known better.
What is a SYNCSUM? A SYNCSUM is what is known as a checksum, or, rather, a modified version of a checksum. The checksum is a method of checking to see whether a program has been entered correctly by letting the computer add up all the bytes in a program. To use this error-checking method, you simply compare the checksum of the original program with the checksum of the program you have entered. If the numbers are not the same, you have made an error in entering the program. If the numbers are the same, the chances are about 90% that you have entered the program correctly.
In the ZX81, a certain area of memory is used to hold the current program. This area begins where the area for the system variables ends. For the ZX81 it is 16509 decimal (407D hex). A system variable points to the first byte of the display file (i.e., the address of the last byte of the program plus one). This variable is stored at location 16396.
The assembly language program shown in Listing 1 is used to generate the current program’s SYNCSUM on the ZX81 system. You will notice that is is not adding all the bytes, but XORing them together. This is the modification of the standard checksum method referred to earlier. You will end up with a number which is less than 256.
To use the SYNCSUM program on a Basic program requires that the SYNCSUM program be resident (i.e., in memory) all the time. This can be accomplished first, by reserving some memory (RAM) such that Basic will not tamper with it, and, second, by loading the SYNCSUM routine into this area. Listing 2 is a program to reserve the required amount of memory, 27 bytes. Listing 3 is the program to load the machine language SYNCSUM generation program into this previously reserved memory space.
These programs should be run at the beginning of any session of computer use when you may want to know a programs’s SYNCSUM. From the time they are run until the computer is turned off, obtaining the SYNCSUM is simple: type PRINT USR(x), where x = your memory size (for example, 1024, 2048, 16384) – 27 + 16384, followed by NEWLINE as always. Thus x will equal 17381 for 1K, 18405 for 2K, and 32741 for 16K.
Enter (or LOAD) the RSV program (Listing 2) and then RUN and NEWLINE. Next enter or LOAD the LDR program (Listing 3). Press RUN and NEWLINE. Hit NEWLINE and you will return to program mode. The SYNCSUM routine is now resident.
On a ZX81 system, type NEW and NEWLINE.
You can now begin entering your program. Once again, you can LOAD your program if you like. You can obtain the SYNCSUM at any point along the way via the PRINT USR (x) command (see above for the size of x). When you have finished and you are sure your program is correct, call for the SYNCSUM for the entire program. Write it down at the end of your program for future reference. Be sure to include it after the end of any programs submitted to SYNC.
I hope this idea is as helpful to ZX81 owners as it is to the rest of the computer world.
Until next issue, same relativistic time period, same non-euclidian universe.
Listing 1.
Label Hex Assembly Code Comments
8KSSUM: 217D40 LD HL,16509 ;HL=Start
ED5B0C40 LD DE,(D-FILE) ;DE=Stop
0600 LD B,00 ;B=00 (Result Accumulator)
LOOP: 7C LD A,H ;If HL≠DE then XORNXT
BA CP D
2008 JR NZ,XORNXT
7D LD A,L
BB CP E
2004 JR NZ,XORNXT
DONE: ;else done
48 LD C,B ;low byte returned is SYNCSUM
0600 LD B,00 ;high byte is 00
C9 RET
XORNXT: ;XOR the next byte into the
;Result Accumulator.
78 LD A,B ;Get current RA
AE XOR (HL) ;XOR it in
47 LD B,A ;put back result into RA
23 INC HL ;bump pointer
18EE JR LOOP ;go back for next byte
Listing 2: 8K ROM RSV.
10 LET R=27 [the number of bytes to reserve]
20 LET RAMTOP=PEEK(16388)+PEEK(16389)*256-R
30 POKE 16388,RAMTOP-256*INT(RAMTOP/256)
40 POKE 16389,INT(RAMTOP/256)
50 NEW
Listing 3: 8K ROM LDR
10 REM 217040ED5B124006007CBA20087DBB
2004680600C978AE472318EE
20 LET RT=PEEK(16388)+PEEK(16389)*256
30 FOR B=0 TO 26
40 LET X=((PEEK(16509+5+B*2)-28)*16+(PEEK
(16509+5+B*2+1)-28))
50 POKE RT+B,X
60 NEXT B
Media
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.