cause of the major increase in output
fidelity. As a conscientious developer,
however, your reaction must be exactly the opposite. A rather small test
case required a considerable change
in the program. Now is the time to
investigate further and look for additional bugs. In all likelihood the
specification needs more refinement.
At the very least, a better test case for
the new functionality is needed. After
a bit of thought it becomes clear that
displaying a one-line-high pixel (1-by-
4) would make such a test case.
This can be done in three simple
steps.
1. Write an ordinary 4-by- 4 pixel on
screen.
2. Wait until the first line has been
drawn by the graphics hardware.
3. Quickly erase the pixel.
All that will be visible on screen is
the 1-by- 4 part of the pixel that was
drawn before you pulled the rug out
from under the 4-by- 4 pixel. Many pixels can be combined to create something seemingly impossible on a stock
TRS-80: a high-resolution diagonal
line.
The only thing missing is some way
of knowing which line the hardware is
drawing at any one point. Fortunately,
the graphics hardware generates an
interrupt when it draws a frame. When
that interrupt happens you know exactly where the graphics hardware is.
A few difficulties of construction remain, but they come down to trivial
matters such as putting in delays between the memory accesses to ensure
you turn pixels on and off in step with
each line being drawn.
Here the emulator is a boon. Making such a carefully timed procedure
work on real hardware is very difficult.
Any mistake in timing will result in
either no display because a pixel was
erased too quickly or a blocky line
caused by erasing pixels too slowly.
Not only does the debugger not care
about time, it eschews it entirely.
Single-stepping through the code is
useless. To be fair, the debugger cannot single-step the graphics hardware.
Even if it did, the phosphor would fade
from sight before you could see what
was happening.
The emulator can single-step the
the majority of
programs that run
under the emulator
will appear exactly
the same as when
run on original
hardware, but
if you pay very
close attention
you will see some
differences.
processor and the graphics. It can
show exactly what is being drawn and
point out when screen memory writes
happen at the incorrect times. In no
time at all a demonstration program
is written that shows a blocky line
in a simple emulator and a diagonal
line in a more accurate emulator (see
Figure 3).
the Real machine
The program is impressive as it must
read/write to the display with micro-second-level timing. The real excitement is running the program on the
original machine. After all, the output
of the emulator on a PC is theoretically compelling but it is actually producing graphics that pale in comparison
to anything else on the platform. On
the real machine it will produce something never before seen.
Sadly, the program utterly fails to
work on the real machine. Most of the
time the display is blank. It occasionally flashes the ordinary block line
for a frame, and very rarely one of the
small pixels shows up as if by fluke.
Once again, the accurate emulation
is not so accurate. The original tearing
effect proves that the fundamental approach is valid. What must be wrong
is the timing itself. For those strong
in software a number of experimental
programs can tease out the discrepan-cies. Hardware types will go straight
to the schematic diagrams that document the graphics hardware in detail.
Either way, several characteristics will
become evident:
˲ ˲ Each line takes 64 microseconds,
not 86. 8.
˲ ˲ There are 264 lines per frame; 192
visible and 72 hidden.
˲ ˲ A frame is 16,896 microseconds or
59.185 frames per second, not 60.
What’s most remarkable is how the
emulator appeared to be very accurate
in simulating a tear when it was, in
fact, quite wrong. So much has been
written about the brittleness of computer systems that it is easy to forget
how flexible and forgiving they can be
at times. The numbers bring some relief to the emulator code itself. What
appeared to be floating-point values
for timing are in fact just multiples of
the system clock. Simple, integer relationships exist between the speed of
the CPU and the graphics hardware.