To create the data file on the Commodore 64 is a bit simpler than on the Apple II. Here the data can be read and written in the same loop. My limited experience on the Apple II was that did not work, I had to first read into arrays, then I could write out. That said I am learning across these platforms so there could be an easier way on the Apple.
General process on the Commodore 64:
Ensure formatted disk is in the drive (or emulated drive)
Line 100 opens the file for output (writing) as a sequential file as file #2
Lines 115 to 130 read and write out the batting order/roster numbers to be used in the program
This needs to be added to the Apple and Atari versions
Lines 150 to 190 reads then writes to file the 30 sets of player data
Lines 300 to 340 reads then writes to file the 18 sets of pitcher data
Line 380 closes the file
To see the full program listing with DATA statements see the Resource tab or click here c64_data_util
1 rem utility to save ssbb data in file
100 open 2,8,2,”@0:sbdatap,s,w”
110 let c$=chr$(44):let f$=chr$(13)
115 for i= 1 to 18
120 read x
125 print#2, x;f$
130 next i
150 for i=1 to 30
160 read n$,h$,l$,r$
170 print n$
185 print#2, n$;c$;h$;f$
188 print#2, l$;c$;r$;f$
190 next i
300 for i=1 to 18
310 read n$, h$,l$
320 print n$
330 print#2, n$;c$;h$;c$;l$;f$
340 next i
1000 rem sample of file data below
9000 data 8,4,3,7,9,5,2,6,1 : data 6,5,4,7,8,9,3,2,1
9001 data “ty cobb”,”l5aof+2cf+1 ”
9002 data “*gpe23p4$gpkvcns+dkg/gf/a1fggg”,”*4$e3nngvgkv2cfsdff1k+pga1/g/g”
To create player/pitcher data file for the Apple II what I found worked was this general process
a. dimension arrays to read data (lines 10-15 below)
b. read in data (lines 101 to 140)
c. Open data file on disk (lines 205 to 220)
line 205 creates a string variable to hold the file name
line 210 opens the file
line 220 sets the file mode to write (so we can write to the file)
at this point all print commands will go to the file.
d. Write out the file (lines 230 to 270 write out the data in the arrays)
e. close file (line 285)
see the Resources tab or click here APPLEII_DATA_UTIL utility for the full program listing with DATA statements
1 REM APPLEII SUPERSTAR BASEBALL
2 REM DATA SAVE UTILITIY
10 DIM NM$(49)
12 DIM HD$(49)
13 DIM LT$(49):DIM RT$(31)
15 DIM F$(10)
101 PRINT “READING DATA”
103 REM PLAYER DATA
105 FOR I= 1 TO 30
110 READ NM$(I),HD$(I), LT$(I), RT$(I)
120 NEXT I
128 REM PITCHER DATA
130 FOR I=31 TO 48
135 READ NM$(I),HD$(I), LT$(I)
140 NEXT I
201 PRINT “SAVING DATA”
205 LET F$=”SBDATAP”
210 PRINT CHR$(4)”OPEN”F$
220 PRINT CHR$(4)”WRITE”F$
228 REM PLAYER DATA
230 FOR I=1 TO 30
240 PRINT NM$(I) : PRINT HD$(I)
242 PRINT LT$(I) : PRINT RT$(I)
250 NEXT I
253 REM PITCHER DATA
255 FOR I=31 TO 48
260 PRINT NM$(I) : PRINT HD$(I)
265 PRINT LT$(I)
270 NEXT I
In the Timex Sinclair 2068 / ZX-Spectrum original version of the program all of the player data from the paper cards were stored in DATA statements. This made sense because the RESTORE command in this BASIC allows for a variable to be used to restore to a specific line number. For example RESTORE 9000+pnum would place the read pointer to the exact line for the player’s data indexed by PNUM. So this allowed for simple subroutines to access specific data. In these other versions of BASIC RESTORE does not work in this way. So I am taking a different approach to the player data, it will be stored on disk (or virtual disk for emulators) and read into arrays in the program. This means the DATA statements will not be in the actual program code, but there will be some utility programs to create the data files. This will also lead to new data files for the other cards that are part of the original game, and other player data that is available on the internet.
To create these data files I will need the READ from DATA statements and the ability to open files, read/write to files and close files.
Since there are many parts to this I will add a separate post for Apple II, Atari and Commodore 64. I am also going to suspend the TI 99/4A at this time as there are some inherent challenges with memory and file handling also the complexity of converting to four systems at once is really slowing me down.
Here is the statement chart for READ and DATA statements, there is very little difference if any across the systems.
Timex Sinclair 2068
DATA “test”, 123
READ A$, N
DATA “test”, 123
READ A$, N
DATA “test”, 123 (” ” are optional for text
READ A$, N
DATA “test”, 123
READ A$, N
DATA “test”, 123
READ A$, N
The data for players and pitchers is structure such that there are four data elements for a player
The first two for this player are in line 9004
1. Player name
2. Player ratings (bat hand, speed, bunt ability, then upto five, 4 character blocks for position and defensive rating for that position). For Honus Wagner he hits R, speed rating of 5, A bunter. Plays Short Stop wit a 17 defensive rating, third base, second base, first base and outfield.
in line 9104 the hitting results versus left handed then right handed pitcher are elements 3 and 4.
9004 DATA “HONUS WAGNER”,”R5ASS173B+72B+41B+4OF+4″
9104 DATA “KK4$3PE*K311F2C/PD/PGVGA+NSFFG”, “*4$3///SN$EG2CSN1ND+PP+AGFKVFP”
For Pitchers (here in line 9303) is
2. Pitching hand (R or L) and Starter or Relief Pitcher (S or R)
In line 9403 is the data for pitching outcomes
There are 15 sets of player data and 9 sets of pitcher data for each team.
9303 DATA “WALTER JOHNSTON”, “RS”
9403 DATA ” F K BGG KF BX “
In the last post printing at specific locations on the screen was reviewed. This post will look at one way user input can be captured. While there are many ways to do this, the generic INPUT (ACCEPT for TI 99) was used. Additionally, input validation is performed. There are many ways this can be done as well, here simple IF…THEN is being used, except for TI99 where the validation is built into the ACCEPT command. Also the Main Menu screen in the user interface has been built for each of the four systems. Also note that full source code as it is being developed can be accessed from the main page menu above from the Source Code link.
Accept user input at Row R and Column C
Timex Sinclair 2068
always at bottom of the screen
VTAB(22):HTAB(1): INPUT “TEXTMSG“;P$
POSITION 1,21: PRINT “TEXTMSG”; POSITION 19,21: INPUT P$
r=22:c=1: gosub 401: print “enter selection : “; :
input p$ (gosub 401 has cursor position see above)
DISPLAY AT (21,1): “TEXTMSG ”
ACCEPT AT (21,19) VALIDATE(“ynYN”): P$
A prompt of selection of the home team is added to the splash screen from last post and is accomplished with the following code :
9718 VTAB(20):HTAB(1): INPUT “Home team (A)L or (N)L : “;P$
9719 IF P$<>”n” AND P$<>”a” AND p$<>”A” AND p$<>”N” THEN GOTO 9718
Line 9718 positions the print cursor at the bottom left of the screen, and input command allows for a text prompt to be added, and the variable P$ will hold the user’s typed response. Line 9719 uses an IF … THEN statement to check and see if the response is a Upper or Lower case A or N. If not the GOTO statement will send back to line 9718 to again ask for input.
In a similar fashion the main menu screen is drawn, and the user’s selection is prompted for, additional code will be added to address the responses in a future post.
Atari also uses the INPUT command, but it does not allow for a prompt to be embedded. The prompt is simply printed before the input command is run to provide the prompt as you can see in the code below:
9716 POSITION 1,21:PRINT “HOME TEAM? (A)L OR (N)L : “;
9717 POSITION 27,21: INPUT P$
9718 IF P$<>”N” AND P$<>”A” AND P$<>”a” AND P$<>”n” THEN GOTO 9716
Line 9716 prints the prompt, 9717 takes input into P$, line 9718 checks the validity of the input.
and in like fashion the main menu is built and response requested:
9733 PRINT CHR$(125)
9734 POSITION 12,5: PRINT “MENU”
9735 POSITION 7,7: PRINT “(1) HOME LINE UP”: POSITION 7,8: PRINT “(2) HOME PITCERS”
9736 POSITION 7,10: PRINT “(3) VISITOR LINEUP”: POSITION 7,11: PRINT “(4) VISITOR PITCHERS”
9737 POSITION 7,13: PRINT “(P)LAY BALL”
9738 POSITION 1,21: PRINT “ENTER SELECTION : “;
9740 POSITION 19,21: INPUT P$
The C64 INPUT command also allows for a text prompt, and as you remember from last post the cursor position is set in a subroutine at line 401. (the emulator needs to have all code sent in lowercase, but shows as upper case as seen below).
9718 r=20:c=1: gosub 401: input “home team (a)l or (n)l : “;p$
The TI 99/4A extended BASIC has a robust command for taking user input, it is the ACCEPT AT command. Take a look at the two lines of code below. Line 9718 prints the input prompt, and line 9719 positions the cursor at row 20 and column 26, sets the the validation string to only accept upper an lower case A, N and limits the size of the input to 1 character, and assigns to P$. The ACCEPT will not allow the program to continue until the user inputs a valid character. Thus no checking for valid input is needed.
9718 DISPLAY AT (20,1): “HOME TEAM (A)L OR (N)L : ”
9719 ACCEPT AT (20,26)VALIDATE(“ANan”) SIZE(1):P$
and the same approach for the main menu.
9733 CALL CLEAR
9734 DISPLAY AT (5,12):”MENU”
9735 DISPLAY AT (7,7):”(1) HOME LINE UP”:: DISPLAY AT (8,7):”(2) HOME PITCERS”
9736 DISPLAY AT (10,7):”(3) VISITOR LINEUP”:: DISPLAY AT (11,7):”(4) VISITOR PITCHERS”
9737 DISPLAY AT (13,7):”(P)LAY BALL”
9738 DISPLAY AT (21,1): “ENTER SELECTION : ”
9740 ACCEPT AT (21,19) VALIDATE(“1234PQpq”): P$
With the very basics of REM and Colors and clearing the screen addressed, in lines 1 -9 of the original program, next comes the splash screen. This also presents the next challenge, screen sizes. I recently read a twitter post that went something like, a programming language does not create the programming environment. While the splash screen is created with what appears to be some simple print statements, however before any discussion of printing on the screen it’s important to understand the size of the screens for each of the four computers compared to the Timex Sinclair 2068, here is a reference to the sizes:
TS 2068 22 rows 32 columns plus 2 rows for input (23-24)
Atari 24 rows 40columns (with POKE 82,0) default is 38 columns
Apple II 24 rows 40 columns
Commodore 64 25 rows 40 columns
TI 99/4A 24 rows 28 columns
The conversion will need to take into consideration that Atari, Apple II, and C64 have more columns than the TS 2068, which will require some adjustment, but there will be plenty of space. The TI 99/4A has two less columns, which will be ok for the splash screen, but may prove problematic once we get to the game screens.
Also I continue to think about “features” of each system that in a vacuum may not matter, however in porting software do matter. For example think about your favorite computer, then simply clear the screen and print “GREETING PROFESSOR FALKEN.” (my version of hello world) – where did it print?
All but the TI 99/4A print in the upper left corner of the screen, TI 99/4A prints on the last line on the screen. Also one needs to think about printing starting at a certain point on the screen, and that’s what will discussing in this post.
Here is what the splash screen looks like on the original, and the source code that creates it below:
9700 REM splash
9703 LET AL=1: LET NL=2
9705 PAPER 1: INK 7 : BORDER 0: CLS
9710 PRINT AT 3,5;”SUPERSTAR BASEBALL V 1.0″
9715 PRINT AT 5,8;” Presented by…”
9716 PRINT AT 7,7;”ANDIAR COMPUTER LABS”
9717 PRINT AT 9,6;”SPECIAL EDITION FOR”: PRINT AT 10,5;”@RETROCHALLENGE 7/2015″
The Sinclair BASIC PRINT AT R,C; prints at Row R and Column C. I will use R and C as row and column variables as we look at how each of the four BASICS allow for this type of printing.
so now to translate into the four BASICS, with a couple of rules or assumptions :
game display will be in rows 1-22
input will be on rows 23, 24
centering of test will need to account for wider screens areas
as the game screens are built wider screens my be leverage for additional display
Being able to print at specific locations on the screen will be needed to build the splash screen and for all the screens in the program. Here is a chart showing the commands for each system to accomplish this. A list of all the commands to date can be seen if you click on the RESOURCES menu at the top of this page.
print at a specific location R=Row down screen C=Column left to right
TIMEX SINCLAIR 2068
PRINT AT R,C;
VTAB(R): HTAB(C): PRINT
POSITION C,R : PRINT
POKE 780,0 POKE 781,R POKE 782,C SYS 65520
DISPLAY AT (R,C):”XXXXX”
From the table we see that the command POSITION C,R puts the print cursor to column C and Row R, the order of C and R is “opposite” compared to the other the other BASICS, and did provide some getting used to. Also slight adjustments to columns have been made to account for the wider screen. See the code below and screen shot.
9700 REM SPLASH
9702 POKE 82,0 : REM SET LEFT MARGIN TO 0
9703 LET AL=1:LET NL=2
9710 POSITION 8,3:PRINT “SUPERSTAR BASEBALL V 1.0”
9711 POSITION 14,5:PRINT “PRESENTED BY…”
9712 POSITION 10,7:PRINT “ANDIAR SOFTWARE LABS”
9713 POSITION 8,9:PRINT “SPECIAL ATARI EDITION FOR”
9714 POSITION 9,10:PRINT “BASICINROM.WORDPRESS.COM”
In Applesoft BASIC the screen locations can be set with VTAB(R) to set in which row and HTAB(C) in which column one wants the cursor. These are then follow by the PRINT commands. Here is the code and screen shot:
9710 VTAB(3): HTAB(8): PRINT “SUPERSTART BASEBALL V 1.O”
9711 VTAB(5): HTAB(14): PRINT “PRESENTED BY …”
9712 VTAB(7): HTAB(10): PRINT “ANDIAR SOFTWARE LABS”
9713 VTAB(9): HTAB(7): PRINT “SPECIAL APPLE II EDITION FOR”
9714 VTAB(10): HTAB(9): PRINT “BASICINROM.WORDPRESS.COM”
The most common approach to printing at screen locations on the Commodore utilize a system call after poking in the screen locations into memory. Poke 781,R gets the row, POKE 782,C gets the column, 780,0 and SYS 65520 complete the call. Using this line 9710 would look like this :
9710 poke 781,3: poke 782,8: poke 780,0 : sys 65520: print “superstar baseball v 1.0” but this is too long of a line for C64 to handle. Plus this will be a pain to type over and over so a subroutine will be built to help here. In looking at the original source code there is room at line 400’s for some utility subroutines, as I aspect there will be need for more in the future. Here is the subroutine to position the cursor :
the main code can now set the variables r and c and call 401. This all necessitates a couple other additions to the code. Line 11 is introduce from the original source to call the splash screen as a subroutine, and 9799 is added for now to return back after the splash screen. Line 99 is need to end the program due the gosub calls. Why is the code in lower case you ask? The emulator reads capitals as special characters so keeping everything in lower case works.
This conversion is pretty easy for the TI 99/4A as PRINT AT AND DISPLAY AT WORK similarly. But, we are starting to see the limitations of the screen size for TI 99/4A. This is going to be an issue for game play. Also memory is going to be an issue, a standard 4A has 16K, that may soon bring this to a halt, unless the emulator has a way to simulate additional memory.
Here’s the code and screen shot:
1 REM SUPERSTAR BASEBALL TI
9 CALL SCREEN(5) :: FOR I=1 TO 12 :: CALL COLOR(I,16,5) :: NEXT I:: CALL CLEAR
9700 REM SPLASH
9710 DISPLAY AT (3,2):”SUPERSTAR BASEBALL V 1.00″
9711 DISPLAY AT (5,6):”PRESENTED BY …”
9712 DISPLAY AT (7,4):”ANDIAR SOFTWARE LABS”
9713 DISPLAY AT (9,1 ):”SPECIAL TI99/4A EDITION FOR”
9715 DISPLAY AT (10,2):”BASICINROM.WORDPRESS.COM”
9799 ACCEPT AT (20,1):A$
So somehow I can’t bring myself to leave Atari BASIC out of this exercise. The retro-community is buzzing with Atari, especially with the ANTIC ATARI PODCAST, I had to find out what the excitement is about.
So I here I will catch up ATARI to the party so far, converting the following Sinclair BASIC code to have a REM statement to name the program, set the background color to blue, text to white and clear the screen:
1 REM SSBB FOR TS2068
9 INK 7: PAPER 1 : CLS
so here is the respective Atari code.
1 REM SSBB
9 GRAPHICS 0:SETCOLOR 2,7,0:SETCOLOR 1,1,14:PRINT CHR$(125)
As it turn out it took me an hour to figure out how the SETCOLOR commands, easy know that I understand but it took a while.
SETCOLOR X,Y,Z : where X is 2 for screen color and 1 for text color, Y is the color and Z is the luminance or brightness of the color (must be even numbe 0-14, larger is brighter)
To set the screen color to blue X=2 and Y=7 (blue) and Z=0 (dark)
To set the text color to white X=1, Y=1 (grey) and Z=14 (max brightness)
Similar to the Commodore 64 the clear screen is accomplished with a PRINT CHR$ and the control character code is 125