HACKER Q&A
📣 Someone

What bug(s) make “LPRINT 0.00001” output “0.0XYZ1”?


https://en.wikipedia.org/wiki/Timex_Sinclair_1000#Bugs states:

  On the TS1000 and ZX81, the command:

    LPRINT 0.00001

  results in the Timex printer outputting 0.0XYZ1. 
I find that a curious bug (my best guess is that the “XYZ1” part is uninitialized memory, but even if that’s true, why would 0.00001 be special?), so I tried to track it down. to my surprise, I found very little. The best I found is https://www.tablix.org/~avian/spectrum/rom/zx81.htm, but that’s incomplete, and of the “Improved” ROM, which, presumably, doesn’t have that bug.

So, does anybody know how that bug came to be?


  👤 avian Accepted Answer ✓
The bug happens because a loop that prints zeros after the decimal point [1] doesn't reset the character to be printed after each iteration.

The buggy code stores the character '0' to be printed in register A and then calls PRINT-A in a loop. PRINT-A uses the alternate register set of the Z80 via an EXX instruction, hence it doesn't cobble the BC, DE and HL registers. However, it does alter the contents of register A. Since the content of A isn't reset to character '0' after the call, only the first 0 after the decimal point is printed correctly. Subsequent calls print out garbage left in A by PRINT-A.

The is further complicated by the fact the PRINT-A does conserve the contents of register A when printing to screen (in contrast to printing to the printer), hence why "PRINT 0.00001" works correctly. Based on the code, it might be that conservation of A in this case is purely a coincidence.

The fix for the bug is to reset the contents of the A register on each iteration [2]. This is achieved by simply changing the argument of the DJNZ jump at the end of the loop.

It seems this fix only exists in custom ROMs and wasn't shipped in official Sinclair ZX81 ROMs [3]. Hence even though [1] lists the "improved" Sinclair ROM, it still contains the bug. However TS1500 ROM does contain the fix [4] (line 3835).

[1] https://www.tablix.org/~avian/spectrum/rom/zx81.htm#L16B2

[2] https://web.archive.org/web/20120213193703/http://www.wearmo...

[3] https://web.archive.org/web/20190913081210/www.fruitcake.plu...

[4] http://www.user.dccnet.com/wrigter/TS1500vsZX81.htm