Friday, 4 November 2022

Classic Rally-X Arcade Game Written in BASIC

I've been working on my attempt at a "re-programming" of Rally-X in BASIC for a while. But I've never quite been able to feel satisfied with it until today.  Darren Atkinson's  machine language subroutine for refreshing the screen from a large sequence of array strings was a big help.  Before it, I had been using a bunch of PRINT MID$ of the array strings, and it was just too slow to refresh the screen background in an adequate fashion.

Now it is just a barely noticeable page flipping background effect.  But the speed of game play was actually up to a point of being a little too fast for fair navigation with such a small window.  The enemy car can swoop in and really get you.  Part of the reason for that is that the key sensing routine that I was using consisted of the single check for all 4 directions:


But as I have learned from Greg Dionne, these key sensing PEEKs have their limitations, and will occasional "latch" when certain double key combinations are input. When that happens, the only way to "unlatch" and be able to input a desired direction is to release all keys, hit another key other than the one you were trying to input, and then select the arrow key you wanted.  It's a fairly intermittent and rare effect, so in many game application its not a problem. The advantage of needing to do only 2 PEEKs to get a direction outweigh the occasional quirky response.  But in this game good reliable responses are really needed.  The enemy can really get close, and every keystroke counts. So I switched to the keyboard rollover peeks suggested by Greg Dionne. That table provides absolutely reliable return values for the four direction keys.  But it uses individual IF statements to determine which keys are pressed:

50 GOTO 5

In the past I would have recoiled over using multiple IFs and preferred instead to use a single ONK(PEEK(2)ANDPEEK(17023)GOSUB1,2,34 method.  The use of a "lookup" K() array in combination with the simple PEEK method seemed highly efficient to me. But I have learned that in Micro Color BASIC the IF runs very quickly in terms of its implementation in the interpretation of each command, whereas ON/GOSUB does not run so quickly.  Also, I was able to eliminate the A() array, which removed a variable from the variable table, which is good for memory and also a source for a slight increase in speed.  The fewer the variables that must be searched for each variable reference,  the faster things go.  And, as I noted, the game was running just a little too quickly anyway, so I could afford a slight slowdown.

I've also searched for all the "speedups" that I can in terms of the code.  I've eliminated all
IF A<>0 THEN references and replaced them with
IFATHEN references
I've replaced more ON/GOSUBs used instead of simple IFs, in speed critical areas of the code (the main loop mostly).  I was able to include some actions as a direct part of the key movement IFs, rather making jumps to subroutines.

I think all these final edits have contributed to making the game truly a playable arcade style game in BASIC.  I was inspired to make these efforts by the Racing Car game jam on, where the challenge is simply to "have fun with our beloved retro computers," the retro programmers Facebook group

Here is a demo of game:

Unfortunately I can't do it justice simply because I'm carp when it comes to playing video games.  But if you would like to give it a try it can be played in the online TRS-80 MC-10 Javascript emulator:

Just select RALLYX from the Cassette menu and then type RUN and hit Enter in the green main screen.  The controls are WASD, just in case you can't read the characters in the chunky Semigraphics-6 font of the MC-10. The pixel resolution of that screen is 64 X 48, and there is not provision for regular text being displayed.  So unfortunately, the letters and numbers have to be rendered in the blocky pixels.  It takes a little getting used to, but with a little time you will be recognizing the letters and numbers.  It's just one of the limitations we users of this quirky 8-bit micro are used to.

Inspired by the smooth motion of the key input of RALLYX, I also decided to modify and update my version of Steven Wozniak's "Little Brickout."  Now it also uses Greg Dionne's PEEK method, and is much more responsive.  Since I was also using multiple IFs, I was able to make some improvements to the animation of the paddle that made it flicker less.  I could just remove the end of the paddle that needed to be removed to move it in a specific direction instead of both ends. Here's a vid of the new version:

Monday, 24 October 2022

"Mosquito" by Mr. Slump (1985)


I ported a game to the TRS-80 MC-10 from for the NEC PC-6001. It was originally published in MICOM BASIC magazine 1985-01 (see above). This new version uses the SG6 graphic mode of the MC-10 rather than the higher res graphics of the original that can be seen in this pic:

My version looks like this:

Programs like this are fairly easy to port because although the images on screen look like graphical sprites they are in fact rendered using a "graphic character" module on the NEC PC.  I think that module is mostly for producing text on screen using Japanese characters, but it can also simply render Roman characters.  So underneath the apparent graphic game, the program is just printing and moving text characters on screen.  All I had to do was switch those characters to semi-graphic 6 characters to get a quasi low res graphic game for the MC-10 curtesy of the creative BASIC programmers for the popular NEC PC-6001 series (an intro 8-bit computer for many Japanese kids back in the early 80s).

You can see how the graphic character module actually allows characters to be printed overtop of each other in the original. For example, the player "sprayer" is actually just an uppercase V and an uppercase D overlaying each other.  I think the author felt it looked like some standard garden spray can, perhaps with a kind of handle.  But I had to render the player sprayer as a simple block with a nozzle sticking out to the left.  You can only shoot left.

The instructions published with the game were the following:
Press "s" to start the game. Move the spray can around with the arrow keys (on the MC-10 these are AWSZ and I used Greg Dionne's suggested key-polling peeks for better responsiveness and true 8 way motion through key combinations). Press spacebar to spray it. If the spray hits a mosquito it will die. If it hits the = that appear on the screen it will stop the spray. Kill enough mosquitos and the level will advance. If a mosquito touches your spray can it is game over, it’s also game over when you run out of spray. You start with 20 shots of it.

I found myself wishing that the game had more than 20 shots, or that there was some way to earn more shots than ones you start with.  But it would seem you are limited only to those 20 shots.  At my level of play I would normally get around 250.  It would be neat to know if other better video game players could score higher.

It's publication details are Micom Basic (マイコンBASIC) December 1985.

As usual it can be played online using an MC-10 emulator here (at least for a little while as I test the game and others do as well).  It's listed on the "Other 8-Bit BASIC Game Ports" menu item once you launch "the game" on GameJolt:

Here's a vid playthrough:

Friday, 7 October 2022

David Meny's "Pirate Island" (1985)

I was contacted by David Meny about whether there was a place to play his old BASIC text adventure  games online (Escape from S.S.A.D.B. and Pirate Island).  I had already converted his SSADB (which he had noticed) and was working on his Pirate Island (PISLAND). He gave me permission to share them.

They can be played here:

In the course of porting Pirate Island, I noticed a few oddities:

First, the solution/walkthrough posted by Dorthy on the CASA archive seems to be missing an "OPEN DOOR" at the very beginning, which I needed to add to get out of the cabin you start in. It's possible the PC version she played was different.  The only thing with that possibility was that I worked from a PC GWBASIC source file that I found online.

Second, there seems no reason the player should be able to simply GET GARLIC after giving the captain the coordinates to find the Island.  The puzzle would seem to be that you should BUY the GARLIC from the cook after the captain gives you the bag of silver (your "pay") for providing the coordinates.  I think the fact that this changes after you give the coordinates to the Captain might simply be the result of a confusion between the flag variable for signaling that the correct coordinates have been provided and the flag for indicating that one has been given the bag of silver.  In any case, I changed it so you still have to BUY the GARLIC from the cook after your interaction with the captain, and also added a check that indicates that you do in fact have the silver to do so.  Otherwise, you could buy the garlic even without being given the silver (and you could also do it from any room, if you knew about it already).  I also added a check to allow you to GET the garlic (and not be killed by the cook) if you happened to put it down after buying it. I also fixed another oddity. You could put the bag of silver down but then you couldn't pick it up again (GET).  That routine only searched 12 items, instead of 14 (the bag of silver is item 14), so it couldn't see the bag was available to pick up if it was dropped.  I also noticed that the printing of a list of items in any room only seemed to print one item, even if others were in the room.  So I made it so that the program prints an exhaustive list of items in a room.

Finally, in the course of porting I streamlined the code and stripped out some redundant variables, fixed some problems with initialization and re-initialization and corrected a few spelling and style errors. I also had to shorten some messages in order to fit the program into the 20K available to expanded MC-10 (with its 16K expansion pack). I also changed it so that the SCORE actually adds to 200/200 when you win rather than 210/200 and I changed the way the score ratings function. Instead of not triggering a category reference if you happened to hit a score exactly at the junction between categories (i.e. searching on > rather than using a >= check to demarcate the categories), now the categories are exhaustive in the ranges they cover.

I also added a game SAVE and LOAD feature (it can only be used in a full emulator, not the online version).  In my correspondence with Mr. Meny I had asked whether his games had this function and he had commented that some recent online reviews he'd come across commented negatively on the absence of SAVE/LOAD, which he felt was a little humourous for relatively small 1980s BASIC text adventures.  I agree. The games don't need it, but it was helpful for me in game testing Pirate Island and relatively easy with the array save command of the MC-10 (CLOAD*Array). I just had to collate all the the arrays (and various flag variables) into a single comprehensive multidimensional array.

Here's a brief demo:

Wednesday, 10 August 2022

Darin Andersen's "Dark Castle" (1984)

I ran across a type-in game listed on the "Giant List of Classic Game Programmers".  It was called "Dark Castle" by Darin Andersen and published in Rainbow magazine. I thought that a program that made it to the Giant List from the Coco was worth looking up, as that list seems more disposed to documenting Atari and Commodore programs. It wasn't a game I'd heard of, but I found a disk and cassette version of it easily enough on the Coco Archive.

The original title screen

It had a really neat hi-res graphic title screen, but otherwise everything seemed to be rendered on the ordinary text screen. So I thought I could swap a Semigraphic 4 image and make a version for the MC-10.  I tried my hand at recreating the feel of the original. I think it came out okay.

New SG4 graphic title page

As with so many of my attempts to port old games to the MC-10, I think I stumbled across a number of bugs in the original.  However, it's often hard to be sure that they are bugs or if the programmer was simply satisfied with the way the game played.  In this case, I think it might be a little of both. Until I made the corrections I found it impossible to win the game, or even get close to winning.

I'm not a great game player, but I do a lot of testing when porting and after a while, you inevitably get better at playing.  You also have an intimate knowledge of the code to draw on for play strategies. So when it seemed impossible to make progress, I started to suspect that there were serious problems.

I would typically get killed in the first 5 rooms. The most common reason for this was simply waiting too long to use a "healing" spell.  Part of the reason for this failure was that there was no report of your health on screen.  Instead you had to press a key (I changed it to "R" instead of "I") to get a report (i.e. "information") of your stats.  Your "experience" (XP) was always listed on screen, but from what I could tell, it made no difference in game play.  It was simply a kind of score of the number of monsters you'd killed.  It seemed to make more sense for your health to be listed on screen so you could make a better judgement of when it was perilously low and that it was time to hit "H" for a "healing" (a healing spell?).  Otherwise, you had to continuously interrupt combat/play to check your stats, which was annoying.

Main Bugs

The other reason I died so easily was that all the monsters seemed to do the same level of damage (around 15-20), which could kill you in 5 or so hits. This was despite the fact that their stats seemed to indicate a range of power: hit points and damage done and experience gained.  But when I looked at how the damage done variable (D) was included in the calculation of an attack, I saw that it wasn't.  Instead the value used to calculate whether you had been hit, as adjusted by your armour and shield, was used (R).  So if you had a shield (1) and leather armour (2), an RND 0-19 value was generated, then the armour/shield value was subtracted, an a determination made of whether the value was below 12.  If so, you were saved from being hit. So, if you "rolled" a 19, this would be reduced to 16 from your armour adjustments and you would be hit since the value was above 11.  Then the damage done would also be this value.  So in effect the value of damage for any monster could only be between 12 and 19.  Actually, the math had the shield being subtracted from the armor and then the result subtracted from your random 19, which makes it worse for you to have a shield.  I fixed that.

277 '<><><>< MONSTER ATTACK
278 R=(20-0)*RND(0)     Why (20-0)?
279 R=R-(AC-SH)            Why subtract shield value (1) from armour (2-5) before subtracting both?
280 IFR <12 THEN 86      No hit if number is above 12
281 CLS 4
282 ST=ST-INT(R)          Why use the number calculated to hit as the damage?
283 PLAY "O1L255V30CEDV10O3"
284 IF ST<0 THEN CLS0:GOTO 286
285 GOTO 81

And I changed it so damage is determined by the number assigned for each monster type, which is stored in variable D when each monster is selected for an encounter.  So the more dangerous monsters can cause significantly more damage (Vampire and Beholder), but the weaker ones much less (blobs and orcs).

This also fixed a problem with the "hunger" routine. That routine cycles in colour from cyan to yellow to red (extreme hunger) as you move about and fight.  If you are in the red too long, then a value of 3 would be assigned to D and a call made to the monster hit routine. Since that routine didn't use D, but the last monster "to-hit" value (R)  instead of beginning to languish from hunger, you could die quite quickly.  In fact I didn't even realize that the hunger routine was doing this.  Every once and a while, it would just seem like an invisible monster had started hitting me after combat had finished. Now, hopefully, the player will realize that the red "hunger" light needs to be attended to before the player starves to death.

Another difficulty I faced was that you only run across Markets to replenish items every 15 rooms


This seemed crazy hard. You also had to make it through 45 rooms in total before branching to the final Gem/completion segment of the game, which also seemed a excessive slog.

134 IF RM=45 THEN 300

It is not uncommon for weapons to break, leaving you completely defenseless early on in the game.  Since the monsters travel one-to-one for your moves, if you lose a sword early and have no backup, which is likely at the beginning when your resources are scarce, you're done for.  There is no way to out-distance all the monsters you will encounter until a Market appears in room 15. It seemed unreasonable, so I shifted it to every 5 rooms for a Market to appear and I adjusted the treasure values earned from defeating the different monsters downward by half to help account for the higher frequency.  I also used the "experience" count to improve your ability (slowly) of avoiding weapon breaks (RPGs should reward experience). And when you buy an expensive "teleport" it will not only take you to a Market, but will jump you forward a room.  So hopefully now it won't be quite a slog.  A win should be within reach of an evening's play.  Perhaps back in the day (when software was scarce) the author and others would have accepted weeks of monumental and perhaps forlorn effort.  Perhaps playing for highest experience would have been reward enough when you were competing with friends around a single home computer.

Such reward might have had to be enough because it also seemed that the instructions for the final gem finding game stage were missing.

134 IF RM=45 THEN 300

The instructions begin at line 296 but no jump is made to that number.  So the player would just be thrown into that final game completion sequence at 300 without any hints about what they had to do, including the critical instruction to press "M" to bring up a map of the location of the gem.  So I changed it so that the instructions are shown and I tried to clarify them.  The sequence involves moving your blue dot across the screen while avoiding a spider (red dot).  You must run off the edge of the room in the appropriate directions to move yourself slowly towards the part of the room where the diamond is located.  Again, since the spider dot moves one-for-one for your moves, it will eventually zero-in on you and then keep hitting you until you are dead (you go into the final screen with your strength from the prior stage).  Again, it seemed unwinnable.  So I changed it to the spider moving 3 out of 4 of a random number of 4 for each of your moves.  So if you move carefully and make good judgments about which edges to head for, you can avoid contact.  I also made the position of the gem and the location of each spider random, rather than fixed.

Other Improvements

I improved the checks to avoid overlapping items on the screen such as where the Monster Portal and the Markets appear.

I got rid of all the redundant LET commands.  Tightened up the code and applied speedup techniques (removed spaces, IFTHENIF rather than AND, shortened variable names, removed redundant variables, packed lines, etc.)

I also tweaked the cost of a few items.  Fixed some spelling mistakes.  Added some "hit C key to continue" prompts.  Improved the movement bounds checking.

I added more detailed graphics for the monsters and other items in the rooms and also the player character graphic.  Here are the new monsters I created:

I think these look much better than the simple blocks and dot graphics used in the original.

Final Thoughts

There are probably many other tweaks and changes I have missed discussing here, but the above are the main ones.  I think I have made the game more playable and winnable than the original.  It is still tough.  You have to pay attention to hunger and your strength and make sure to buy enough food and "health" spells to replenish yourself.  You have to make other good purchase choices, such as getting extra replacement swords and bows as soon as possible. Other strategies include avoiding combat and simply heading for the door.  Use bow attacks to avoid damage. With some luck, you should be able to make it to room 20, where there will be a Market, which you can use to get your health maxed and proceed to room 21, which will trigger the final "Gem Room stage."

I think the original game might have been very frustrating.  I am doubtful that anyone ever made it to the end of the full 45 rooms before the Gem stage. And if they did make it to the Gem room, I imagine that few completed the game without the instructions to help them figure out what to do with the "moving dot" before the spider came and pummeled them to death.  So why did the game make it on to the "Giant List of Classic Game Programmers"?  It might have been based simply on the appeal of that super cool title screen!

Here's a playthrough of the fully updated version:

Tuesday, 26 July 2022

Larry Bethurum's 1966 "Bingo"

I have ported a very early BASIC game program from a Dartmouth-style BASIC to Micro Color BASIC for the TRS-80 MC-10. The source code I worked from required a fair amount of debugging to make sure that the game operated properly.  Although the game is noted in the Wikipedia discussion of the early history for video games, it was very difficult to find source code for it using Google.  Simple searches using the author's name and the game title didn't produce any links to source but only details like those mentioned in Wikipedia, such as:
Larry Bethurum, from the Phillips Exter Academy, submitted the BASIC source code of a bingo game to the DECUS user group. Comments in the code suggest the game was written on January 23, 1966 []
It was only when I returned to the mention in Wikipedia that I was able to chase down a reference link to the source code preserved on a Net archive site:,50110/bingo.gam.html

There were some major bugs in the source that would have prevented proper operation of the game:

1590 X=F
1600 Y=F
1610 IF B(X,Y)<>0 THEN 1740:REM FIXED ERROR-- CHANGED TO 1740 FROM 1720
1620 X=X+1
1630 Y=Y+1
1640 IF Y<F+5 THEN 1610
1650 IF Y=11 THEN 1700
1660 PRINT"YOU'VE GOT A   B I N G O * * *"
1670 W=1:WW=WW+1
1700 PRINT"I'VE GOT A   B I N G O * * * *"
1710 V=1:VV=VV+1

1740 X=F+4
1750 Y=F
1760 IF B(X,Y)<>0 THEN 1880
1770 X=X-1
1780 Y=Y+1
1790 IF Y<F+5 THEN 1760
1800 IF Y=11 THEN 1850
1810 PRINT"YOU'VE GOT A   B I N G O * * *"
1830 W=1:WW=WW+1
1850 PRINT"I'VE GOT A   B I N G O * * * *"
1870 V=1:VV=VV+1

The highlighted errors would prevent the program from jumping to the "slant check" for Bingo (bottom left to top right corner) at line 1740. And the error within that routine of assigning Y=X would have then prevented that routine from operating correctly even if it was jumped to.  Also, the search routines for the other directions used many jumps from out of uncompleted FOR/NEXT loops, which might not have caused problems on the original platform (some kind of DEC minicomputer) and BASIC, but put the Micro Color BASIC on the MC-10 into conniptions.  So I also had to change all those search routines so that proper exits from those FOR/NEXT loops occurred.

When the player chose to "play again" the program returned to a point at the beginning which involved re-DIMing already dimensioned arrays, which causes an error in Micro Color BASIC.  It also did not not zero certain variables like the win checks for each player stored in V and W or RESTORE the READ pointer for re-reading data. The original version of BASIC might have done this automatically, perhaps when re-dimensioning occurred, but in Micro Color BASIC, the process of re-starting had to be fixed to prevent these problems.  

It is possible that some of these bugs may have prevented users from having a particularly happy experience with the program, which might explain why there is so little record of the game on the Net today.  Or these might just have been bugs that entered into the program in the course of someone typing it in from the DECUS newsletter in which it was originally published.

The game was originally written for a system that would have printed its results on paper.  The program makes reference to "Dartmouth" as the location from which the program is being run which seems a reference to Dartmouth College, the original home of BASIC.  So it seems likely that the program was originally meant to be run on a Dartmouth BASIC time-share system using a printer as the primary output device. This would have prevented anything in the way of dynamic interaction between the user and the program. In effect, the program simply runs a virtual game of Bingo, which the user was encouraged to follow along with using "a pencil" and the printout of the two cards (the user's and the computer's).  The user is told to mark both their own and the program's card. Then the program would declare (and print) the winner at the end. So in the course of my debugging I decided to add some new options to increase the challenge of the game in keeping with its new 8-bit home computer environment.

I added MC-10 graphics around the bingo cards.  I added a display of the numbers on the cards being marked in reverse video.  Then I decided to add an arcade element.  The user must spot and "mark" the numbers of their own card under the constraint of a time limit. This was meant to recreate the tension of real Bingo players trying to keep track of all their cards and marking them with their dabbers as the numbers are called.  I added a very minor ability for the computer to also occasionally "miss" marking the number being called when in this mode.  I added a report at the end of the game of how many games the player wins and how many the computer wins.  Finally, I added a game level element which simply adjusts the speed of the delay for the player to hit the row number (1-5) of the number on their card for the number being called.  If they mess up and hit a wrong number, they fail to mark the number on their card.  The level also effects the degree of possibility that the computer will miss marking a number on its card.  However, if the user selects "no" to the "prompt mode" at program start-up the game will play like the original program.

The source for my version of the program can be found here:

The game can be played on GameJolt. Choose "Play Game" then the "Classic 8-bit BASIC game" menu option.  Select "BINGO" from the cassette menu and then type RUN.

Friday, 24 June 2022

Jim Menick's "Draw Poker"

I already posted about Jim Menick's BASIC text adventure game "Space Derelict."  That program was an example program from his book BASIC Adventure and Strategy Game Design (1984). Jason Scott mentions that there was a version of the book for the Apple, but I worked from a scan of an edition for the TRS-80 Model IV computer.  I have now cleaned up the scan of his example listing for the "strategy game" component of the book, which is a variation of Draw Poker. The "house rules" for that game are:

  • Each player starts with $100
  • $1 Ante
  • Minimum of (pair of) Jacks for opening
  • 3 raise limit
  • $5 bet limit
I don't know if these are standard rules, or idiosyncratic to this 5 person (including you) computer version of the game. The most interesting aspect of the game is that the other 4 A.I. players are apparently designed with unique playing strategies/styles.  They each have names:
  • Marvin
  • Gerry
  • Walter
  • Betsy
It's a very detailed variation of Poker in BASIC.  It seems to handle betting, passing, dealing around among the players, raising, dropping out, etc.  If you drop out, the other players continue to play without you.  I'm not sure if the players are good players, but they are certainly good enough to beat me and my meagre card skills, including the occasional bluff.  

The program was very large.  I had to engage in another of my monumental "shrinking exercises," which involve the following steps:
  1. Remove all spaces between commands and variables.
  2. Eliminate single command lines and pack multiple commands on lines as much as possible.
  3. Change as many multi-character variables as possible to single letter variables.
  4. Scan the code for redundant/duplicated code and then shift that to a subroutine.
  5. Shrink and streamline messaging, which had to be done anyway to shrink a 80 X 24 game screen down to a 32 X 16 screen of the TRS-80 MC-10.
  6. Omit <>0 references in IF statements.  The variable by itself, if a non zero, can simply trigger the if.
Before any of that could be done, I had to chase down all the typos and bugs from my transfer/typing of the game listing from a digital scan.  There were also some apparent errors in the listing, including a missing line at 28070 with a needed NEXT. This was for the winner determining subroutine. I think it just got dropped from being printed in the book.  There was also a reference to variable S5 at line 2642, which I think should be a reference to S5(X), since there is no other non-array S5 references in the code, and all the other references are to S5(X).  I switched it, hopefully it doesn't break something.

It is strange that there seems to be no preservation of the game on the Net.  Like Frank DaCosta's BASIC programming "How-to" book for the TRS-80, I think the listings were simply too long for many people to have had the fortitude to actually type-in and fully debug the game back in the day.  Perhaps, this coupled with the minor printing errors, simply drove people insane, and so beyond Menick himself (and De Costa), few might have ever obtained working copies of the game.  It would seem that neither author distributed/published working copies of their games by way of other media than in book form for typing-in.

I'll continue to bug test and see if other errors emerge.  I have yet to fully test the routines triggered when players lose all their money and drop out of the game and what happens when the human player runs out of doe.  That will simply take some time of test play.  Of course, if there is anyone out there who wants to contribute to game testing, the 5CARD can be played here (at least for the testing phase):

Just select the game from the cassette menu, and then type RUN.

Please let me know if you find any bugs or have any comments on the abilities of the 4 A.I. players.

I got a Full House!

Bug Addendum:

I have been intensively testing the game. In addition to a bunch of problems introduced by me in the process to get the game working and pared down to fit in an MC-10, I've found what I think are some existing bugs in the original program:
  1. There was an error in the routine that examines 2 pair hands to find the highest card.  Instead of looking at the cards in the hand and comparing which was higher, Menick compared the pointer array variable values to the positions of the first cards for each pair. Those values needed to be put into another array holding the values of the cards themselves to obtain their actual values as cards.  Pointers within, pointers within pointers!  He only went 2 levels deep when he needed 3-- easy to do in such a massive program with massive lines of these multiply embedded pointers.    This happens in my program around line 2901 which is a little subroutine I carved out so that it could also be used by the "Untranslated Player hand" routine latter in the program.  I also unpacked some of the "pointer within pointer" analysis to a subroutine to make the lines shorter, since those kinds of lookups happen a lot and have the same general format.
  2. The card replacement routine was really messed up.  If you didn't pick correctly and then simply hit N at the "Replace" prompts, it would realize that you hadn't selected enough cards to replace and take you back to start at the top of your card list again.  But it already had replaced the cards you selected and wouldn't turn them back to what they originally were. It also would not re-wind the cards drawn counter!  This meant that if you repeated hitting "N" and kept "restarting" your selection you could effectively eat through the entire remainder of the deck and blow the lid of the array holding those cards! That would cause a catastrophic "out of bounds" error.  So I revamped and stored your (up to) three selections, and then only change them after you have selected the cards you truly want.  So if you make errors, just hit N until it restarts the process as many times as you need.
  3. There are places where INPUT is used, such as for "Bet?" and ""How many Cards? selections.  But a numeric variable is used for input, which means if you happen to enter a letter, you get a new line and the message "Redo" and then a newline with a new prompt, which would cause the screen to scroll. Needless to say this really messed up the screen real-estate. So I switched the input to use a string variable and then assign it using VAL to the original numeric variable. So if you enter anything that is not a number it just assumes it's a zero.
  4. Minor issue with the game ending.  If you had exactly $1 left at the end it would let you ante up and enter the game with $0.  Then it would keep telling you you were trying to make an illegal bet in an endless loop.  I added logic to terminate the game if you had 0 after your ante.  I also made it so that if you get the pot up to over 480 it reports your "winnings" and thanks you for playing and ends the game. The other players are made to drop out if they have less than $5 each so if you have $500-16 there could be no players left for you to play with.  I don't know how the game would handle only you entering into the actual game play without other players. Menick doesn't seem to have considered this eventuality happening.  I guess he just thought his A.I. players were that good!  Anyway, the game now has a (hopefully) functioning win routine.
  5. This one is not really a bug, but it allowed me to push the memory needs down enough that I had enough space to put back in some of the more elaborate game messages. Menick used three string arrays for presenting the cards: One for holding the card's value, one for the suit and one for these two strings combined for the whole card.  E.g. 7  ,  H  and  7H.  This was done for each of the cards. These arrays were for 40 items each: 5 cards for each of the five players, and then up to 3 cards for each player's replacement cards.  Each time these were changed Menick had to update each of three string arrays: Value, Suit and Combined Value/Suit. The combined Value/Suit would used when a card needed to be printed on screen.  But since they were always changed together it seemed redundant to manage a separate "combined" string.  I just stripped it out and simply printed the Suit and Value strings together in the few places needed. The removal of an entire 40 item string array really freed up space, and broke the back of my memory woes. Menick didn't need to worry about such things since he was programming on a TRS-80 Model 4, which I believe had 128K (and at least 48K for BASIC), and not a measly 20K like the MC-10. Such luxury.
  6. At the beginning of the subroutine that checks for a straight flush in lines 2630-2647 a variable IN(X) is set to 0. Then a check is made after a search is made in the initial part of the routine for a straight to see if the value of IN(X)=1.  If it is then the subroutine is exited and the program moves on. If not, then the values for aces in the hands (14) are shifted to 1s and the whole routine is run again. I can only surmise that this is to check for a straight in the order A1234.  If straight is found for either the first search or second a branch is made to elsewhere. But if the second search occurs, no change is made to the value of IN(X) to indicate that the "second check" has occurred but no straight of the A1234 type found. So the routine just keeps being run in an endless loop. So I added IN(X)=1 after the first check for a straight is made, so that the branch out on S(X)=1 occurs after the second check.
  7. In testing the winning and losing subroutines of the game it became apparent that Menick must not have ever got to that point in his own play testing (or perhaps only on the Apple version).  I created the win and lose conditions by breaking out of the program during the Ante screen, and then changing the banks of each player stored in R(X) and then entering CONT. I was able to figure our that there was something wrong with the dropping out part of the program for "busted" players.  A variable P(X) had to be set to 1 after the "busted" message gets printed, but wasn't. That variable then triggers the awareness that the player is not able to Ante and is also used to prevent printing the player onscreen and skip them for dealing duties, etc.
  8. There was a problem with the routine that reexamines your hand after you make card replacements. Menick didn't re-initialize the variables storing your hand values before re-starting the hand analysis subroutine (starting at line 130). So if you had a hand with 2 pairs, and then selected new cards that left you with no recognized hand type (pair, 2 pairs, 3 of kind etc.) that routine wouldn't find anything to report about those recognized hands, so it wouldn't change the reporting variable, effectively leaving your hand with the type of hand identified from before making your replacements.  So if you started with a pair, and then replaced one of those cards in a way that left you with zilch, it would report that you still had a pair. It's possible that this might be a result of something that I changed, but I tried very early version of my edits of the game (I keep a succession) , and the problem was there, so I think it's original. Menick simply didn't test like I did by entering crazy entries again and again with the emulator cranked to the max speed.  It would be very rare (except for Betsy who seems to be a little rash) for players to smash up their own existing hands and then stay around (bluff) to the brutal end just to lose and see their hand described. They'd normally fold. So it's likely Menick wouldn't have noticed this bug. But by playing many games on high speed I noticed this first in my own hands (I was just replacing cards at random and sticking around to the end to make sure I could see all the hands to check them).  Then I noticed it happen in one of Betsy's hands too.
  9. I changed the annotation of how hands are reported. It now takes the form of "Full House 6's",  "Four T's" or "Three A's" etc. The subroutine at 32000 finds the value of the highest card for 4-of-a-kind and full house hands.  At line 3410 and 3440 I added a S$ before the GOSUB32000-- The S$ stores the apostrophe and S characters printed after the card number of the highest card in the hand. This annotation was missing from the determination of four-of-a-kind hands (except for one instance). The 32000 subroutine (now relocated to 85) would not work unless this annotation was present like it was for Full House hands.  I adjusted the 32000 routine to deal with the apostrophe and streamlined its operation. 

What are the different "playing styles" of the 4 A.I. players?  I haven't examined those routines in depth or read Menick's book in detail. I might do. If so, I will come back here and add an addendum to my addendum and let you folks know. Otherwise, if you want to examine the code yourself, it can be found here:

Final updates can be seen here:

Wednesday, 15 June 2022

"Star Command Sigma" by ASCII 1982

I had noticed several screen shots of a game called "Star Command Sigma" for the NEC PC6001. It looked like a BASIC game-- a rendition of the vast family tree of Star Trek games-- But since it was by ASCII, a major software company in Japan from the early days of home computing in the 80s, I expected that it would be especially well done. So when I finally got an emulator working for the NEC PC 6001 and located a huge repository of software, I went looking for it. I was able to list it to a file and get the source code. It was not hard to translate.

I have done other games from the NEC PC-6001 using James the Animal Tamer's Virtual NECTrek PC, which was a short lived North American variation of the PC-6001. The BASICs are similar Microsoft variations and the fact that they both use the Motorola MC6847 video chip makes things fairly straightforward.  The NEC uses LOCATE instead of PRINT@, but I just switch its two X and Y arguments to PRINT@X+32*Y, and get the same results. The NEC has some fancy graphics modes, such as the ability to define a virtual console/window on part of the screen, and some super sound generation. But I was able to translate most of this stuff in a downgraded way. One advantage of the MC-10 is that its screen printing and BASIC generally run faster. There is a speed sacrifice to be paid for all the NECs fancy abilities.

Here are some comparisons screenshots of the game working on the PC-6001 emulator and the Virtual MC-10.  They show some of the differences in how the two computer systems implement the MC6847:

NEC PC-6001
The NEC allows all the possible character colour layouts provided by the VDG, whereas the MC-10 can only easily access black on green text. The NEC also has an extended character set with lowercase and special symbols, such the degree symbol (little raised circle), which is used in the game.

You'll notice that the Klingon's are called "KLIMZONs" in the NEC variation. However, ASCII provide a variable for storing the name, so you can easily change it to Klingons. I guess they had to worry about copyright infringement, but they wanted customers to be able to easily switch  to full copyright infringement mode if they desired. You'll notice though that they still use an "E" for your ship (I wonder what that stands for?).

ASCII also embedded some strange characters at the beginning of each of the main menu item titles as they were listed in the DATA statements. These weird characters are processed when the titles are read in and combined in a single variable that reads "by ASCII."  I guess they were a little worried about copyright infringement of their own. It's kind of like Bill Gates multiple Easter eggs hidden in Microsoft BASIC, such as in the original Commodore BASIC for the PET, that can print out "Microsoft." If any one tried to pirate the code, Bill could just hit a few keystrokes and reveal the Easter egg message and claim ownership!  I thought of switching it to "JimG2022" or some such, but in the end, it's their program.  If they come gunning for me they can happily sell my version to the massive legions of MC-10 users out there!

The music is a bit of a mess.  First of all I don't read music.  Second, the MC-10 only has a simple SOUND command, and not the fancy PLAY command of the NEC.  Still I have butchered the notes listed in those PLAY commands to get some meagre semblance of the original musical refrains for the intro, win and lose screens. I had to be somewhat creative in the implementation of sound effects, but sometimes the program also used the simpler SOUND command, and in other cases I tried to take clues from the notes listed in PLAY commands.

The scrolling "window" allowed for by the CONSOLE command of the NEC had to be dispensed with.  Instead I went with a system of the top of the bottom half of the screen being used for commands, the middle for messages and help info, and the bottom line for combat messages. No scrolling is allowed.  Instead, as messages roll in, a small left pointing arrow appears in the bottom right corner.  When it does, you can hit a key to skip directly to the next message/event. Otherwise a brief pause will occur to allow the player to read the message before it is replaced or erased.

The game is very feature rich. There are options that I have not seen implemented in any other variation of the classic Super Star Trek game. I wont go into complete detail here, but it is a very well-thought out set of command options that will make for a challenging set of tactical decisions as you try to destroy all the Klingons, Oh, I mean Klimzons. The enemies even occasionally shoot torpedoes back at you, which you can launch a counter measure against using the
direction keys.  The NEC used the STICK command to read a direction from the joystick, but I switched it to this keypad arrangement. Hit one of these keys just after the enemy launches a torpedo (or when the left pointing "continue arrow" message is displayed) and you might get lucky in destroying the incoming torpedo. The enemies even move during combat (and other times) so you will find that occasionally they warp out of the way of danger or new ships can arrive to complicate your life.

Below is a playthrough. I lose. I didn't realize that a feature that allows you to get energy from a star is "paid for" by sucking time off of your countdown timer.  If I hadn't been so greedy (and ignorant of how all the features are interconnected) I might just have won!  See if you can spot the moment of my fateful decision...

While investigating the game I also discovered that ASCII went on to make a fancier graphic character version for the MSX line of computers:

So the MC-10 now has a neat little game recovered from the early 1980s to help it to keep pace with the "big boy" systems of the 8-bit era. I wonder of Mr. Godai (listed in the title screen above) is the same programmer who made the version for the NEC?  If so, thank you Mr. H. Godai for a wonderful game.


I modified the title page to make the sigma look more like the original:

I also fixed up some of the more awkward "Engrish" phraseology, such as "Torpedo is breakdown."  I changed this to "torpedo damaged" and modified "Klingon" to plural "Klingons" (etc.) on the status screen.  I still don't know what "Offensive cycle" means and what the number attached to it represents.  It's probably something like "threat level" or possibly, the number of combats you have had with Klingons, or something like that. If anyone has suggestions, I'd appreciate hearing them. Perhaps I'll change it if I figure it out.

I added plurals and gender neutral terms to the status report

Addendum to the Addendum

Curtis Boyle mentioned the program on the Cocotalk web show and commented that it was good to see a nice version of Star Trek on the MC-10.  However, it is actually an addition to a number of other Trek variations that I have ported to the MC-10 as part of my efforts to collect up classic BASIC programs for preservation purposes.  It's not Curtis's fault that he wasn't aware of these wider efforts on my part, although I might have made him feel that way when I made a video to bring these other Trek programs to his attention. I didn't mean to offend (Sorry Curtis).  Just goes to show how much tone is lacking from the quick messaging that forms such a part of digital life today. Much thanks to Curtis for the great job he does presenting the details of the projects and activities of the community. In any case, here's the vid with a run down of some of the other Trek offerings on the MC-10:

I've also made a special "all Trek" themed game list for the online MC-10 emulator. One program not mentioned in my video is "Save Spock", which if I recall correctly I ported from some obscure Coco disk:

Addendum to the Addendum Addendum
Noticed some spelling mistakes in the "Encounter in the Near Tholian Sector" game while reviewing my video. Don't know if those are mine from the porting process or from the original, but in any case I've fixed them up.