

The PC8 Computer
Written March 9, 2004
As
the graphics operator for the Pirates Television Network in the late
1980s, I wanted to be able to prepare several bar graphs before each telecast.
To:
Pirates Television Network Announcers
Date:
March 19, 1988
On
three or four baseball telecasts late last season, we displayed teamcomparison
stats with the help of animated bar graphs like the one below.
We feel that this helps the viewers see what the stats mean, so we
plan to use these bar graphs on a regular basis this year.
To
avoid having any questions arise on the air, here are a few notes
about these stats.
The
numbers are based on the stats coming into the game.
Sometimes we might be able to update them to include what the teams
have done so far in tonight's game, but if we do so, we'll tell you
"this is updated" through your headset.
With
two exceptions, the #1 ranking goes to the team that has the largest
number in the league in the given category, regardless of whether
having a large number is good or bad. For example, the team
with the most errors is ranked #1 in errors. The two exceptions
are golf scores and team ERA. In those two categories only, the
team with the smallest number is ranked #1.
One
type of team comparison shows wonlost record under special
circumstances. For example, against lefthanded starters the
average N.L. team has a 56 record, while the Padres are 48 (ranked
#12) and the Bucs are 54 (ranked #2). For your information,
the rankings and the length of the bars are based on the wonlost percentages,
which are .454, .333, and .556 in this example. But we don't
show those percentages on the screen; there are enough numbers
already with the records themselves. 
The
numbers were readily available from the printed league stats, but
how long should the bars be?
The
longest bar that would fit on the TV screen was about 32 characters
long. To make that represent 141 doubles would require one
character for 4.4 doubles. So the other two bars, for 130
doubles and 124 doubles, should be 30 and 28 characters long
respectively, like this:
•••••••••••••••••••••••••••••• 130
•••••••••••••••••••••••••••••••• 141
••••••••••••••••••••••••••••
124
But
those three bars are almost the same length. The graph would
reveal that there really wasn't that much difference among the
numbers, while as broadcasters we want to make a story out of
the stats. We want to make it seem as though any small
differences are significant. We'd like to ignore the left half
of the bars and magnify the right half.
What
would it be like if we exaggerated the difference by making the
longest bar 32 characters but the shortest just 8 characters,
regardless of the numbers they represent? The middle bar could
be made proportional to the other two. The result would look
like this:
•••••••••••••••• 130
•••••••••••••••••••••••••••••••• 141
•••••••• 124
That
gives us a definite and obvious difference, but it's perhaps too
exaggerated. I decided that the best compromise would to average
the results of these two methods of calculation.
A
fair amount of numbercrunching would be required to do this, and I
didn't have a lot of spare time on the day of a game. The
problem called for a computer!
I
considered bringing my home computer along, a laptopsized Tandy
Model 100, but I discovered that there was a smaller, more portable
device available — the Tandy PC8 Pocket Computer.
Its
instruction manual called it "one of the most sophisticated
handheld computers in the world today." It boasted a
fourbit processor and a whopping two kilobytes of RAM. On
February 6, 1988, in preparation for the upcoming baseball season, I
purchased one for $59.95 at the Radio Shack at the Monroeville Mall.
Later
that year I spent an equal amount for a printer/cassette interface,
as shown below.
The
computer itself — less than 5½" long, less than half
an inch thick, weighing only three ounces — could be tucked into
a pocket of my briefcase and sit in a blank area on top of my Chyron keyboard.
(On the display is a boxing timer. More about that later.
I've used the PC8 as a backup on boxing telecasts as recently as 2003!)
When
I wasn't on the road, the black accessory cradle offered AC power, a
thermal addingmachine printer, and an interface for storing programs
on an audio cassette recorder.
The
PC8 is completely obsolete now, of course, compared to Palm Pilots
and such. But it could be programmed in BASIC, and I wrote
programs to do what I wanted.
To:
Any Substitute Chyron Operators
Date:
March 19, 1988
We
present comparative team statistics using bar graphs, so that the
viewers can more easily grasp what the stats are telling us. A
typical lowerthird panel looks like this:

The
panel is also animated. When you press a key, an autodisplay
causes the bars and numbers to reveal. 
Making
this autodisplay is fairly tricky. Here's how it's done.
Arithmetic
Your
raw data comes from the MLB/IBM Notes, the league statistics that
are available a few hours before game time. For each category
(doubles in our example), those notes list the totals for each of the
twelve teams in the National League. But you need to figure the
league average and the rankings of the two teams playing on tonight's telecast.
You
also need the proper lengths for the three bars on the graph.
Here's how I determine appropriate lengths.
Let
G be the biggest of the three numbers (141 in our example).
The bar corresponding to G is 32 characters long, because that's the
longest that will comfortably fit on the screen.
Let
E be the smallest of the three numbers (or 124). The bar
corresponding to E is always between 4 and 20 characters long, the
actual formula being 16E/G + 4. In our example, that formula
works out to 18 characters.
Let
N be the middle number, or 130. The bar of middle length is
given by the formula 16N/G + 12(NE)/(GE) + 4. In our example,
that becomes 23.
The
Computer
To
make these computations much easier, we use a checkbooksize
computer, a Tandy PC8. Here's how to run the program.
Turn
on the power switch. Press DEF and N.
The
computer asks for VISITORS.
If the visitors have 141 doubles, press 1, 4, 1, and ENTER.
The
computer asks for HOMETEAM.
Press 1, 2, 4, and ENTER.
Now
the computer asks for numbers for the other ten teams in the
league. Enter these.
Normally
these numbers are entered without decimal points. If the
category is batting averages, enter 265, not .265, because the latter
would confuse the computer.
But
you can use a decimal point for a special purpose: categorical
wonlost records, for example on grass fields or in extra
innings. In that case, enter each record as if wins were
dollars and losses were cents. A 75 record would be entered as
7.05, for example.
After
all twelve numbers have been entered, the computer will give you
three sets of answers like this:
NL
AV 1.23.130 
(press
ENTER to see next set) 
V
I S #4.32.141 
(press
ENTER to see next set) 
HOM
#8.18.124 
(press
ENTER to start another calculation) 
The
numbers between the decimal points are the lengths of the bars.
The numbers on the right go at the end of the bars. (Of
course, if you've been entering "dollars and cents," the
numbers on the right will be something like 8.08,
which you would type as 88 on the screen). And the rankings
are indicated by # signs.
The
Frame
Read
2294 from the message disk. Retype "BUCS" and
"PHILS" as necessary. Change the palette as
necessary; yellow should be the visitors' team color (normally 706
for the Pirates), and red should be the home team's color.
Rerecord at 2294.
The
Autodisplay
Call
up the existing autodisplay from 2270. [An autodisplay is a
programmable routine used by the Chyron character generator to play
back "keystrokes" very rapidly for animation purposes.
In this case, a bar on the screen is printed out by typing as many
as 32 characters, each character being the letter I, shifted to the
left so that it's touching its neighbor.]
Now
for each set of data, delete parts of the autodisplay and replace
them with new numbers. The parts to be deleted and replaced are underlined
in the listing below. When you're finished, check the operation
of the autodisplay. Then record it at an address between 2270
and 2292. (It's so long that it will take two addresses.)
COMMENTS 
AUTODISPLAY
STEPS 
set
up MGM 
CTRL
M CURD DO CURR CURR 3 DO CTRL 
move
Plaque 
CTRL
G CNPG CLER AUX2 AUX1 SHRU CTRL 
read
2294 
FNT2
WHIT ERAS AUX2 AUX2 AUX9 AUX4 READ 
type
heading 
HOME
FNT3 D
FNT2 O
U
B L
E
S 
center
and shift it 
CHRO
SHRR SHRR SHRR 
wait
for gray bar 
TAB
FNT2 GREN DELY 0000 space 
draw
it 
DEFS
0023
SHCL SHCL SHCL SCHL I DEFE 
type
NL avg, pause 
WHIT
1
3
0
DELY 0030 TAB 
type
visitors rank 
#
SHCL SCHL SCHL space
SHCL SHCL SHCL 4 
ready
for yellow bar 
TAB
YELW space 
draw
it 
DEFS
0032
SHCL SHCL SHCL SHCL I DEFE 
type
visitors number, pause 
WHIT 1
4 1 DELY TAB 
type
home rank 
#
SHCL SHCL SHCL space SHCL
SHCL SHCL 8 
ready
for red bar 
TAB
RED space 
draw
it 
DEFS
0018 SHCL SHCL SHCL SHCL I DEFE 
type
home number 
WHITE 1 2 4
END 

By
the next season, I had taught the PC8 some new tricks.
Because of its very limited memory — only 1,278 bytes for
programs and data — I had to delete the feature where it could
rank teams' records like 75 and 88 by calculating the winning
percentage. However, I managed to squeeze in all of the
following routines.
Date:
February, 1989
Re:
Instructions and PC8 Basic programs for baseball
Career
Earned Run Average
Press
DEF = to begin. Computer asks twice for IP.X
(where
X is thirds of an inning) and ER.
[One set of numbers refers to the pitcher's career coming into this
season, as listed in the press guide; the other set refers to this
season.] It adds the pairs of numbers and gives you the
composite ERA.
600:"=":
CLEAR
605:FOR
I=1 TO 2
620:INPUT
"IP.X ";P
If
P is 44.1, that means 44 and onethird innings
625:INPUT
"ER ";R
630:Q=Q+
INT P+3.3333*(P INT P)
Q
is P converted to decimal form as 44.33333 innings
635:X=X+R
650:NEXT
I
660:USING
"####.##"
665:PRINT
.005+9X/Q
This
is the earned run average, rounded to two decimal places
670:GOTO
600
Updating
Batting Average
DEF
B to begin. The display reads 910.
0.0. 000.
where 910
is a Chyron address to identify the player, 0.0.
means that he's 0 for 0 in tonight's game, and the last number is his
updated season batting average.
Use
the number keys to give commands as follows.
7 
8 
9 
switch
to other team 
enter
season data 
x 
4 
5 
6 
move
up on scorecard 
increase
hits (and AB) 
increase
outs (and AB) 
1 
2 
3 
move
down 
decrease
hits 
decrease
outs 
After
you've called 8 to enter season atbats and hits, the display will
show the batting average. If the player is replaced during the
game, call 8 again [to enter the new player's atbats and hits].
When
you're not using the computer, turn off the power. When you
turn the power back on, use DEF Z (instead of DEF B) to resume
without erasing your old data.
700:"B":
CLEAR :Z=1
705:DIM
B(18)
710:"Z":V=A(Z)
715:U=B(Z)
B(Z)
is compressed data of the form 2.034, where 34 is atbats for the
season (coming into the game), 2 is atbats tonight, and Z ranges
from 1 to 18 for the eighteen players currently in the game
720:WAIT
12
725:S=
INT V:T= INT U
S
is hits tonight, T is atbats tonight
730:U=T+1000*(UT)
735:V=S+1000*(VS)
V
and U are the seasonplustonight hits and atbats
740:IF
U=0 THEN LET W=0:GOTO 750
745:W=
INT (.5+1000*V/U)
W
is the updated batting average
750:B(0)=900+10*Z85*(Z>9)
755:PRINT
B(0);" ";S;T;" ";W
Now
the computer waits for the operator's command to go to a subroutine
760:U=
VAL INKEY$
765:IF
U=0 THEN GOTO 755
770:V=1+2*(U>3)
This
makes V either +1 or 1
775:ON
U GOSUB 810,820,830,810,820,830,870,880
780:GOTO
710
810:Z=ZV
812:IF
Z=0 THEN LET Z=18
814:IF
Z=19 THEN LET Z=1
818:RETURN
This
changes Z, the player index
820:A(Z)=A(Z)+V
This
increments tonight's hits by either +1 or 1
830:B(Z)=B(Z)+V:
RETURN
And
this increments tonight's atbats
870:Z=Z+918*(Z>9):
RETURN
This
changes Z by 9, which gets us to the other team
880:INPUT
"AB ";X
882:INPUT
"H ";Y
884:A(Z)=Y/1000
886:B(Z)=X/1000
888:RETURN
This
stores the season numbers in the A(Z) and B(Z) arrays
National
League Rankings
DEF
N to begin. Enter 12 numbers (without decimal points).
Then the computer will give you three answers of the form VIS
#3.24.82,
where the number between the periods is the length of the bar in the
bar graph and the other two numbers should appear before and after
the bar, respectively. Press ENTER to see the next answer, and
ENTER again to restart the program.
900:"N":
CLEAR
902:DIM
T$(2)*7
904:T$(0)="NL
AV"
906:T$(1)="VIS
#"
908:T$(2)="HOM
#"
910:DIM
N(5),R(2)
914:INPUT
"VISITORS ";N(1)
916:INPUT
"HOMETEAM ";N(2)
918:IF
N(1)>N(2) THEN GOTO 926
920:R(1)=1:E=N(1):G=N(2)
Make
the rank of the visitors #1, while the hometeam remains #0; the
smallest of the three bars is the visitors' stat; and the largest of
the three bars is the hometeam's stat
922:IF
E=G THEN LET R(1)=0
If
both stats entered so far are the same, then the ranks of both teams
should be #0
924:GOTO
930
926:R(2)=1:E=N(2):G=N(1)
Make
the rank of the hometeam #1, while the visitors remain #0; the
smallest bar is the hometeam's stat; and the largest bar is the
visitors' stat
930:Z=E+G
Z
accumulates the sum of all the stats; the average will be Z/12
931:FOR
I=0 TO 9
932:IF
I=9 THEN INPUT "ONE MORE? ";D: GOTO 938
934:INPUT
"N.L. TEAM ";D
938:Z=Z+D
939:FOR
J=1 TO 2
940:IF
D>N(J) THEN LET R(J)=R(J)+1
If
the stat just entered is greater than the stat of visitor or
hometeam, then increment the rank of that team
942:NEXT
J: NEXT I
943:N(0)=
INT (Z/12+.5)
This
is the league average, rounded to a whole number
946:IF
N(0)>G THEN LET G=N(0)
If
the league average is greater than the largest bar G, then set the
largest bar to the league average
948:IF
N(0)<E THEN LET E=N(0)
If
the league average is less than the smallest bar E, then set the
smallest bar to the league average
950:FOR
I=0 TO 2
N(0),
N(1), and N(2) are the stats for the three bars
952:X=1+3*(N(I)E)/(GE)
X
will range from 1, if N(I)=E, to 4, if N(I)=G
954:Y=N(I)/G
Y
is the fraction that N(I) is of the largest bar
956:X=X/8+Y/2
This
averages X and Y
958:L=
INT (X*32+.5)
And
L is the number of characters in the bar
960:PRINT
T$(I);R(I)+1;L;N(I)
962:NEXT
I
964:GOTO
900 
I
soon found another use for the PC8 besides baseball.
There
are no scoreboards at professional boxing matches. The sport
has stubbornly remained in the 19th century, announcing each round by
carrying a numbered card around the ring while refusing to let the
fans see the roundbyround judges' scores — or a clock.
It's
not as though the timing is complicated. Unless the referee
calls a timeout for an injury or something, the clock runs
continuously: three minutes for Round 1, a oneminute break,
three minutes for Round 2, another oneminute break, and so on.
When
a bout is televised, we in the television graphics department have
to generate our own clock and superimpose it on the screen. We
start it from 3:00 when the bell rings to begin a round, then count
down towards zero, when hopefully the bell will ring again.
(Because there's some uncertainty about all this, we remove our
unofficial clock from the screen with five seconds left. If it
shows "0:00" at some time other than the end of the round,
conspiracyminded viewers might think that the ringside timekeeper
has cheated by sounding the bell early or late. Or worse, they
might think that the TV crew doesn't know how to keep time.)

The
PC8 and I flew to Tokyo in February, 1990, to work the HBO telecast
of Mike Tyson's upset loss to Buster Douglas. 
Typically,
my graphics coordinator starts and stops a stopwatch. So does
someone at ringside. They tell me when to start and stop the
clock on the screen.
But
I want to have my own independent time indication, in case my
colleagues get distracted. And a simple stopwatch isn't really
good enough. It can't remind me which round we're in, nor can
it warn me how soon the next round will start.
I
solved all these problems in 1988 by writing another BASIC program
for the handy PC8, turning it into a "smart" customized stopwatch.
Beginning
with 3:00
ROUND 1,
it waits for my keystroke. When the first bell rings, I hit
ENTER, and the PC8 starts counting down. After 0:00
ROUND 1
it keeps on going; the next second is 3:59
ROUND 2,
and it counts down the minute intermission until 3:00
ROUND 2
when the bell should signal the resumption of boxing.
The
PC8 will keep going like this all night with no further
intervention from me. However, its time may need to be
corrected occasionally, and there are various buttons for that
purpose. The one that I use most often is B, for bell, which
reduces the seconds to zero and holds them there until the bell rings
and I release the button.
October
21, 1988
PC8
Program for Timing Boxing Matches
100:"A"
Can
begin with DEF A
102:M=3:S=0:R=1
Parameters
for start of match: 3 minutes, 0 seconds left in round 1
106:WAIT
110:INPUT
"ROUND ";R
Manual
input if desired
112:INPUT
"MINUTES ";M
114:INPUT
"SECONDS ";S
116:D$="<ENTER>"
117:GOSUB
145
Waits
for ENTER before proceeding
118:WAIT
54
Timing
delay
120:D$="
ROUND "
121:GOSUB
145
Prints
(to the LCD display) once a second
125:S=S1
126:I$=
INKEY$
127:IF
I$="A" THEN GOTO 100
Press
A to restart with new parameters
128:IF
I$="Z" THEN LET S=10*INT((S+5)/10)
Hold
Z to hack to nearest 10 seconds
129:IF
I$="B" THEN LET S=0
Hold
B to zero the seconds; when bell rings, release
130:IF
I$="H" THEN LET S=S+1
Hold
H to halt the count temporarily, adding one second back in each second
131:IF
S>1 THEN GOTO 140
If
seconds haven't gone below zero, loop another second; otherwise next minute:
132:S=59
134:M=M+1
135:IF
M>1 THEN GOTO 140
If
minutes haven't gone below zero, loop another second; otherwise next round:
137:M=3
138:R=R+1
140:GOTO
120
145:F$=
STR$ (M)+":"+RIGHT$ ( STR$ (S+100),2)
146:PRINT
" ";F$;D$;STR$ (R)
149:RETURN 
I
loved the fact that I could customize this little device to behave
in a special way that suited my purposes exactly. And that, in
fact, is the essence of a programmable computer.

