ZX81 ROMs ("Unimproved" verses "Improved")


Copyright

I am unsure of the copyright on the ZX81 ROM. The original copyright was with Sinclair Research Ltd. I believe that the copyright for the Sinclair Spectrum ROMs was transferred to Amstrad PLC. It is debatable if the ZX81 copyright was transferred at this time. I am assuming that the ROMs are able to be released into the public domain (It's been 20 years!). If anyone knows differently, please let me know and I will withdraw the ROMs from this site.

 

Overview

Having bought one of the first ZX81 on the market, I am blessed with a ZX81 with an "unimproved" ROM. As far as I know, the unimproved ROM has not been published on the Web, until now! My unimproved ROM was read using a PROM programmer. The ROM is of device type 2364, but was read using the device type set to Motorola MCM 68764, which is pin-compatible. The unimproved ROM had a couple of problems, the most serious being a floating point bug (it seemed to think that the SQR of 0.25 was 1.3591409). The exact differences between the unimproved and improved ROM are described further below. The label names have been taken from Part A & Part B of the ROM Disassembly by Dr. Ian Logan & Dr. Frank O'Hara (good work guys, wherever you are now!).

 

Change Summary

"Unimproved"
Address Range
"Improved"
Address Range
Description of Change
0000-0EEE 0000-0EEE No change (other than offsets)
N/A 0EEF-0EF1 A new CALL instruction added to clear the workspace during the INPUT routine
0EEF-0F39 0EF2-0F3C No change (other than offsets)
0F3A-0F40 0F3D-0F43 Rewritten PAUSE routine to ensure bit 15 of FRAMES set.
0F41-102E 0F44-1031 No change (other than offsets)
102F-1034 1032-1038 Rewritten numeric processing routine to cater for syntax checking
1035-1732 1039-1736 No change (other than offsets)
1733-1735 N/A Deleted spurious instructions causing floating point bug
1736-1DFD 1737-1DFE No change (other than offsets)
1DFE-1DFF IDFF-1DFF One spare location removed
1E00-1FFF 1E00-1FFF No change to character map

 

Change Details

(1) A new CALL instruction added to clear the workspace during the INPUT routine

Unimproved:

0EE9 FD CB 08 7E INPUT: BIT 7,(IY+08) ; Test high byte of PPC for line number
0EED 20 2F   JR NZ,0F1E ; REPORT-8 (Input must have line number)
0EEF 21 2D 40   LD HL,402D ; FLAGX
0EF2 CB EE   SET 5,(HL) ; Set INPUT mode
0EF4 CB B6   RES 6,(HL) ; to string

Improved:

0EE9 FD CB 08 7E INPUT: BIT 7,(IY+08) ; Test high byte of PPC for line number
0EED 20 2F   JR NZ,0F21 ; REPORT-8 (Input must have line number)
0EEF CD A3 14   CALL 14A3 ; Call X-TEMP to clears the workspace
0EF2 21 2D 40   LD HL,402D ; FLAGX
0EF5 CB EE   SET 5,(HL) ; Set INPUT mode
0EF7 CB B6   RES 6,(HL) ; to string

 

(2) Rewritten PAUSE routine to ensure bit 15 of FRAMES set

Unimproved:

0F2F CD A7 0E PAUSE: CALL 0EA7 ; Call FIND-INT to get the PAUSE parameter
0F32 CD E7 02   CALL 02E7 ; Call SET-FAST to go into fast mode (but keep CDFLAG bit 6 set, indicating SLOW mode)
0F35 60   LD H,B ; Move PAUSE parameter into HL
0F36 69   LD L,C ; NB: This will be saved to FRAMES
0F37 CD 2D 02   CALL 022D ; Call DISPLAY-P to generate display until FRAMES zero or a key is pressed
0F3A CD 07 02   CALL 0207 ; Call SLOW/FAST to re-enter "normal" slow mode
0F3D FD CB 35 FE   SET (IY+35),7 ; Sets the top bit (bit 15) of FRAMES to indicate not in PAUSE
0F41 18 05   JR 0F4B ; Jump to D-BOUNCE

Improved:

0F32 CD A7 0E PAUSE: CALL 0EA7 ; Call FIND-INT to get the PAUSE parameter
0F35 CD E7 02   CALL 02E7 ; Call SET-FAST to go into fast mode (but keep CDFLAG bit 6 set, indicating SLOW mode)
0F38 60   LD H,B ; Move PAUSE parameter into HL
0F39 69   LD L,C ; NB: This will be saved to FRAMES
0F3A CD 2D 02   CALL 022D ; Call DISPLAY-P to generate display until FRAMES zero or a key is pressed
0F3D FD 36 35 FF   LD (IY+35),FF ; Set high byte of FRAMES
0F41 CD 07 02   CALL 0207 ; Call SLOW/FAST to re-enter "normal" slow mode
0F44 18 05   JR 0F4B ; Jump to D-BOUNCE

 

(3) Rewritten numeric processing routine to cater for syntax checking.

Unimproved:

1022 FE 26 S-LET-NUM: CP 26 ; Jump if dealing with a digit 'A'=26H
1024 38 1D   JR C,1043 ; to the S-DECIMAL routine
1026 CD 18 11   CALL 1118 ; We have a variable name. See if it exists by calling LOOK-VARS
1029 DA 4B 0D   JP C,0D4B ; REPORT-2 (Undefined variable)
102C CC A3 11   CALL Z,11A3 ; Call STK-VAR to stack parameters for a string or string array
102F FD CB 01 76   BIT 6,(IY+01) ; IY=4000H
1033 28 4E   JZ 1083 ; Jump to S-CONT-2 to continue processing if not a number
1035 23   INC HL ; A numeric value is to be stacked
1036 ED 5B 1C 40   LD DE,(401C) ; so fetch the old STKEND

Improved:

1025 FE 26 S-LET-NUM: CP 26 ; Jump if dealing with a digit 'A'=26H
1027 38 1E   JR C,1047 ; to the S-DECIMAL routine
1029 CD 1C 11   CALL 111C ; We have a variable name. See if it exists by calling LOOK-VARS
102C DA 4B 0D   JP C,0D4B ; REPORT-2 (Undefined variable)
102F CC A7 11   CALL Z,11A7 ; Call STK-VAR to stack parameters for a string or string array
1032 3A 01 40   LD A,(4001) ; Fetch the value of FLAGS
1035 FE C0   CP C0 ; Test bit 6 & 7 together
1037 38 4E   JR C,1087 ; Jump to S-CONT-2 to continue processing if not a number and/or are syntax checking
1039 23   INC HL ; A numeric value is to be stacked during line execution
103A ED 5B 1C 40   LD DE,(401C) ; so fetch the old STKEND

 

(4) Deleted spurious instructions causing floating point bug

Unimproved:

1732 D9 ADDEND-0: EXX   ; Fetch L', D' & E'
1733 7C   LD A,H  
1734 95   SUB L  
1735 67   LD H,A  
1736 AF   XOR A ; Clear the A register
1737 2E 00 ZEROS-4/5: LD L,0 ; Sign indicator

Improved:

1736 D9 ADDEND-0: EXX   ; Fetch L', D' & E'
1737 AF   XOR A ; Clear the A register
1738 2E 00 ZEROS-4/5: LD L,0 ; Sign indicator

 

(5) Offset Differences

The ROM contents also differs at various locations where the target of an address reference has changed. For example, the first of these differences is at 0029. This is part of a call to the floating point CALCULATE routine.

Unimproved:

0028 C3 9C 19   JP 199C ; CALCULATE

Improved:

0028 C3 9D 19   JP 199D ; CALCULATE

 

(6) Spare Bytes

Finally, at the end of the ROM (just prior to the character bitmaps) the unimproved ROM has two spare locations (1DFE & 1DFF) whereas the improved ROM only has one (1DFF). These locations contain FF.


(C) Copyright Mr. S. C. Agate, BSc (Hons.)
Last revised: 11 December 2001.
http://www.agate.f9.co.uk