Uncle Simon

Copyright © 2018 by Víctor Parada

Uncle Simon

This is a little game for the 2018 NOMAM's BASIC 10-liners Contest. This program fits in the new "stock" PUR-80 category, and it was written using Atari BASIC for the 8-bits ATARI XL/XE.


Just repeat what Uncle Simon says and beat him in his 9 rounds, each harder than the previous one.


Simon start Uncle Simon waits for you to be ready. Press the joystick button when you are.
Simon plays a tone Uncle Simon plays a single tone and waits for you to repeat it. Use the joystick and move it in the proper direction once.
Simon add tones Each time you repeat his tones, he adds another one to the sequence. You must remember the complete tune.
Simon round The first round's tune has only 5 tones. When you complete the round, a new round begins.
Simon faster Every round is longer and faster than the previous one. You must be aware!
Simon gameover If you forget a tone, you lose the game. You can see how far did you go in the challenge. Press the joystick button to face all the challenge again, with new tunes. If you hold the button, the first tone will appear immediately.
Simon win Only if you could follow all 9 tunes, you'll beat Uncle Simon and win the challenge. Press the button to try to beat him again.

Development of the game

The new rules for the PUR-80 category in the 2018 edition of the contest says that only "stock" BASIC dialects could be used. For the Atari XL/XE meant that Atari BASIC must be used. Neither TurboBASIC XL nor any other flavor of BASIC are allowed for this category.

TurboBASIC XL is an upgraded Atari BASIC, faster than it and with many featured added, like automatic initialization of variables and arrays at start, structured programming using REPEAT-UNTIL, WHILE-WEND and IF-ELSE-ENDIF, memory management using MOVE or DPOKE and other simple statements that performs a small task which in Atari BASIC many statements are required, like a single SOUND without parameters to turn off all the audio channels and PAUSE to give accurate timming to a game. Line numbers are required to enter the code, but it is possible to write full programs without a GOTO statement.

Without TurboBASIC XL, it looks like instead of 800 bytes (10 lines of 80 characters), only 300 are available. And 10 lines seem a not enought number as destinations of the flow control in a language dominated by the GOTO statement. This turns into a very different challenge. Good bye high quality games! Good bye player/missile animations!

I was tempted to try some ideas to replicate advanced features of TurboBASIC XL in Atari BASIC. The first one was to change internal memory pointers of Atari BASIC to make it believe that strings were in any place of the RAM/ROM and then to allow fast memory movements using string variables manipulation like substring assignment, but that required too many statements and expressions that took more than 25% of the available space just to initialize that. Take in count that a single A=DPEEK(88) statement in TurboBASIC XL needs to be written as A=PEEK(88)+PEEK(89)*256 in Atari BASIC, requiring 23 bytes instead of 11. A single DPOKE statement has to be replaced by two POKE statements in Atari BASIC, each with an ugly expression to find their respective byte value as a parameter.

To reduce the number of statements required to be the first statement of a line when it is the destination of a GOTO, FOR-NEXT loops could be used for iterations, and ON-GOTO could be used instead of IF-THEN, which enables a simulation of the ELSE of TurboBASIC XL instead of another split of a line and the use many lines for those contitions with two alternative blocks of statements.

As a proof of concept, I started to rewrite COPIÓN, an old game I wrote in the 80's, which is just a colorfull SIMON-like game.


COPIÓN, a SIMON like game

As graphics mode 2 (ANTIC mode 7) provides texts in 4 colors over a background of a 5th color, it seems to be the most practical example of a simple game to program. Also, as a tenliner is a kind of mini-game, I thought about some simple rules change to make it dynamic and interesting, introducing rounds starting short and slow but with increasing length and speed, with an end. A whole gameplay should not last more than 5 minutes, where you can win the challenge or lose if you fail... no fails are allowed!

The first thing I discarded was the redefined charset. In TurboBASIC XL only 2 MOVE and a single POKE statements are required to enable it, but in Atari BASIC two slow FOR-NEXT loops with POKE and PEEK() took valuable space in the source code. So I decided to distribute the text of the game in 4 regions in the screen and give a different color to each region. I also decided NOT to use POKE statements in this game, forcing me to use, for instance, SETCOLOR instead of to modify the hardware PF color registers.

The PF register for each text had to be selected in a convenient way. For example, the number of tones of the current round must be printed and could have more than 1 character, so the register for the default color for numbers should be assigned to that text group. The other important text group was the one with the round number, which could be printed using an expression to change the number into another ATASCII code, and that must be the one which uses the fewest number of chars in the expresions. The remaining ones, i.e. the title and the credits, were assigned randomly as they were static. Then, the respective position of the PF registers in screen are:

 1   0 

The name of the game for the title changed from "COPION" to "SIMON", then to "MINI SIMON", and it finally stayed as "UNCLE SIMON" to define a clear objetive and be consistent with the rules of the game. For the credits, I just left "NOMAM 2018".

As there were many text strings to be printed in different screen positions, I decided to use a FOR-NEXT loop and read texts and positions from DATA. DATA statements has the advantage in Atari BASIC that it could be placed anywhere in the listing, buat it will always be read in sequential order as expected.

The next step was to create the different game loops. I decided to start the main loop at the beginning of a line, as the game flow might return from different points of the code with GOTO or THEN and it might also abort when the player fails.

The first working version of the game required more than 1000 bytes of abbreviated code, but as it was in development stage, each statememt has its own line, including the data. After some rework, I could reduce it to about 850 bytes, but 12 lines of code were needed.

SIMON prototype

First working prototype of the game

One of the way to reduce the number of lines in conditional loops without the use of GOTO is using this special form of FOR-NEXT loop:


When the condition is true, the loop finishes. This works like the REPEAT-UNTIL block of code, except that it needs more bytes in the listing, but it is posible to use more than one loop on a single line or to span a big loop in many lines of code. I used this technique 3 times in the code: One to wait for a valid player's movement, one to wait for the joystick to be released, and one to wait for the joystick button to start a game. Then I put a 4th one as the main loop of the game, saving another line number.

More bytes were saved by removing some of the messages in the screen, like the initial values of the round and tones counters (both as zero), and by a merge of both effects routines in just one subroutine with a parameter to identify the kind of action to perform. Then I found that the same subroutine could be used to initialize the screen colors at startup, saving some bytes more.

As I could reduce the code to 10 lines and also went below 780 bytes, I decided to add a simple end of game message in addition to the sounds. As there was only one point of the code where the message would be printed at the end of the game, I set it up the string variable with the pesimistic word which would be printed somewhere in the screen when the player loses, but if the player wins, then the string should be changed to the optimistic text. Initially I set up the variable using a direct assign, the pesimistic one before the main loop and optimistic one just after the loop. I decided to print the message in the center of the screen, so I had to move all the elements some spaces away from the center.

I had to accomodate the DATA statements again to fill free space at the end of the lines. While doing that, I noticed that the 4th loop using the special form of loop could be changed back to the BASIC standard because the first statement was already at the start of a line. The only problem was that the optimistic message was asigned as the last statement of a line just after the NEXT statement, but that could be solved using ON-condition-GOTO, which lets BASIC continue executing statements after it in the same line if the condition is false.

Finally, in a new organization of the data, I decided to remove those POP statements I added to clean the FOR-NEXT stack and are left behind when the player failed a tone and a GOTO transfers the control outside of the nested loops, because the following statement would be a RUN, which includes the reset of that stack. I also changed the direct assignment of the end of the game messages to more READ statements, just to put all the text in the form of DATA.

When the game was ready, I noticed something that I forgot. As the game uses only the joystick as an input device, it is possible for the attract mode to start in the middle of a game. The only way to disable that is by storing a 0 at a given memory location, so I had to include POKE 77,0 even when I said I won't include POKE statements.

An extra activity was to write an AUTORUN.SYS file to automatically load and run the game at boot time, because DOS 2.5 does not have the ability to process AUTURUN.BAS files for Atari BASIC. There are many solutions out there, but I wanted to keep it simple ;-)

Return to my 10-liners page.

© 2018 by Víctor Parada - 2018-02-05 (updated: 2018-02-07)