A colleague at work told me about a game he had been playing on Steam called TIS-100 which he had been particularly enjoying and using as a basis for competing against his friends with.
How do I explain this “game” though? Basically, you write small assembly language programs in a fictional language to move and translate numbers from inputs through to outputs, of an equally fictional broken piece of technology (the Tesselated Intelligence System — TIS, get it?).
The assembly language is really simple but with that comes the problem of solving the given tasks: you have to be quite inventive as to how you resolve them, often having to go to an enormous amount of trouble to bend the numbers to your will and implement what are really simple requirements.
Doris, my long-time blog reader can tell you that I have a penchant for assembly language from when I was a young Moon and even recently I wrote about my nostalgia here so needless to say, I bought it and am already hooked.
This small blog entry is just a brief introduction of to how to get going and maybe some waffle on how I solved some of the problems; I’m still exploring the program myself and I am sure there is lots more to uncover!
Playing the game
I had to do a lot of clicking and guessing at first because the manual for the game isn’t really a manual at all, at least not in the sense of other games you have bought. By that I mean, it doesn’t tell you how the screens are organised and what you are supposed to really do, believe it or not. To be fair, that’s all part of the stories narrative, but it does make it an interesting exercise when starting out.
The first part of the booklet just kind of tells you a whole load of nothing using made-up jargon, but the really important sections are the architecture (section 1), the instruction set (section 2) which is composed of the following:
and the various examples.
Starting the Game
When you first start the program, you will see a screen similar to this:
There are two main parts that I have found mattered. The tasks (the main section to the right, especially where you see words like NOMINAL) and the top-left under self-test diagnostics.
You start by selecting a task in the nominal section. Note however, when you play, you won’t see so many “NOMINALs” because they signify a solved problem. Here you can see I have clicked on SIGNAL EDGE DETECTOR.
That will highlight it whereupon you can click on “UNTITLED PROGRAM NOT YET SOLVED” in the top-left (see 2). That takes you to another screen where you can enter your program and run it, solving the task given. Hopefully.
Let’s take a look at the most simple task and how I dealt with that: “SELF-TEST DIAGNOSTIC“.
This starts off pretty easy – we are going to take values from the input and move them along to the output. Each of the boxes in the system can have up to 4 inputs and outputs, labelled UP, DOWN, LEFT and RIGHT. In this next image, you can see how I handled the A input, moving it to the A output (which you can’t quite see on the bottom-right).
Beginning with the top-right box, I take the input from IN.A and move it from above, to the left. In the box next to that (top-left), I take the input from the RIGHT and move it DOWN. This continues until eventually the values are shifted to their destination, OUT.A. You can’t see this in the image but I’m doing almost exactly the same thing on the other input and output.
To run (test) your program, you can either click the run button on the bottom left or you can step through the instructions, one at a time. Each of the boxes tell you what is in the acc(umulator) or bak registers of the processor as you go – hint: very useful when testing.
Press escape then click on RETURN TO THE SEGMENT LIST to go back to the main screen.
Now for something a little trickier: DIFFERENTIAL CONVERTER.
What makes this one a little harder is that we need to use the input values in two places: one for each output.
Here’s how I solved the crux of the problem – see if you can guess what each side of the program does.
Let’s start with the IN.B side on the the right. Here, we’re taking the input and storing it in the accumulator before shoving it to the box on the left. Next, we subtract what we get from the left box and move the result on down – that achieves the IN.B-IN.A portion. How about the left side?
You’d think that I should just be able to reverse the operations but as you can see, that’s not what I have done. I believe you are unable to send data to the same port at the same time without removing it, so in this case, I need to handle the subtraction first, but then retrieve the value from the BAK register (copied there with the SAV operation) and send that original number to the right. This is what I meant originally when I said you need to be a little creative about how you tackle these problems.
- Make good use of the step through feature when running programs – sometimes you need to see exactly what is going on.
- If the code hangs, it usually means you have a deadlock of some sort. Consider re-arranging the code as I did in one of my examples above.
- Refer to the examples in the guide – they can really help see what is possible.
- You are likely to run out of space when writing the programs – remember you can put labels on the same lines as code.
- When execution reaches the end of a block, it goes back to the top. Handy if you want that but if not, remember to use a JMP statement.
- There is no ability to compare with anything other than zero so if you want to compare with say the number 10, you need to subtract 10 and compare with 0.
- Don’t be afraid of deleting your code and starting again. On each iteration, you will get closer or at the very least, learn more.
There are many more puzzles to come and I think it is also possible to create your own, but anyway, I hope I have given you a flavour of how this game really is and that you will find it as intriguing and compelling as I do. Go and buy it – it’s as cheap as chips 🙂
Written by Stephen Moon
email: stephen at logicalmoon.com