
Ask HN: What bug(s) make “LPRINT 0.00001” output “0.0XYZ1”? - Someone
https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Timex_Sinclair_1000#Bugs states:<p><pre><code>  On the TS1000 and ZX81, the command:

    LPRINT 0.00001

  results in the Timex printer outputting 0.0XYZ1. 
</code></pre>
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:&#x2F;&#x2F;www.tablix.org&#x2F;~avian&#x2F;spectrum&#x2F;rom&#x2F;zx81.htm, but that’s incomplete, and of the “Improved” ROM, which, presumably, doesn’t have that bug.<p>So, does anybody know how that bug came to be?
======
avian
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](https://www.tablix.org/~avian/spectrum/rom/zx81.htm#L16B2)

[2]
[https://web.archive.org/web/20120213193703/http://www.wearmo...](https://web.archive.org/web/20120213193703/http://www.wearmouth.demon.co.uk/sg.htm#PF_ZEROS)

[3]
[https://web.archive.org/web/20190913081210/www.fruitcake.plu...](https://web.archive.org/web/20190913081210/www.fruitcake.plus.com/Sinclair/Interface2/Cartridges/Interface2_RC_New_ZX81.htm#ZX81bugs)

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

