Thanks to Pete Dring for the original idea which can be found at http://pddring.github.io/cpu-battle-tank/.

Any CPU can only work with very simple instructions to carry out any programming task. Battle Tanks is a way of creating instructions for a simulated CPU which produces a visual result for the student. To program the CPU you must use Assembly language which a very low level set of instructions to work with. Assembly language is often even more difficult to comprehend at first than higher level languages e.g. Visual Basic, Python, Smallbasic. Battle tanks gives you an insight into what is going on inside the CPU when you write a program to achieve a particular outcome.

If you were using a high level language to program the tank you would probably used commands such as:

Tank.MoveForward(2) # Moves tank 2 spaces forward
Tank.MoveBackward(5) # Moves tank 2 spaces forward
Tank.Turn(180) #Turn Tank 180 degrees
Tank.Fire() # Fire the gun

.. and so on.
            

How The CPU Works

The way this CPU simulator works is that it has a register (storage location) called the Accumulator that the user can load values into. These values can then be Output to one of four different channels, each of which controls the tank in a different way. Instructions to control the tank are written in Assembly language, which is then compiled into machine code which the CPU can understand and execute.

Output Channels

Below are the different Outputs channel number that must be used to control the tank...

To fully control the tank, each channel does something different depending on what number is Output to the channel. This is summarised below:

Channel 1 - Movement

0 = Tank Moves Forward
1 = Tank Moves Backwards
            

Channel 2 - Steering

0 = Tank Turns To Face North
2 = Tank Turns To Face East
4 = Tank Turns To Face South
6 = Tank Turns To Face West
            

Channel 3 - Aim Gun

0 = Tank Turns To Face North
1 = Tank Trusn To Face North East
2 = Tank Turns To Face East
3 = Tank Turns To Face South East
4 = Tank Turns To Face South
5 = Tank Turns To Face South West
6 = Tank Turns To Face West
7 = Tank Turns To Face North West
            

Channel 4 - Firing

0 = Fire Gun
            

To Control the tank, you need to decide what you want the tanks to do with each instruction eg. move, turn, fire and create Assembly language instructions for each step. To complete each instruction, you will have to decide what you want the tank to do, and then load that instruction it the accumulator, the data loaded into the accumulator can then be output to the appropriate output channel.e.g.

LDA 1 // Load the (Data) number 1 into the Accumulator
OUT 1  // Output the contents of accumulator to Channel 1 (Movement)
HLT - Stop the program
            

Data Labels

To make writing programs a little easier the programmer can use labels to assign values so that the assembly language is easier to read and the intention of the instruction easier to follow. Comments (instructions ignored when the code is compiled) must be prefaced by a double slash //

// this will be ignored by the compiler.
          

Writing Assembly Language Programs

The basic principle is to decide what you want to do e.g move the tank forwards, load that number (0) into the accumulator and then output the contents of the accumulator to the appropriate output channel (channel 1 for movement)

A first Assembly Language program to move the tank forwards 2 spaces

// Move Forwards
LDA Forwards    // //uses the label Forwards to load the value 0 into the Accumulator
OUT 1           // Move forwards by Outputting value 0 from accumulator to Output Channel 1
OUT 1           // Move forwards by Outputting value 0 from accumulator to Output Channel 1

HLT             // stop the CPU

//Data Labels - help to simplify code by attaching descriptions to the data values
Forwards    DAT 0   // assign the value 0 in the Label Forwards
Backwards   DAT 1   //assign the value 0 in the Label Backwards
          

Notice that there is no simple way to move more than one space at time, except repeat the Output instruction. This is one feature of low level languages; it often requires more instructions to achieve something that is relatively simple with higher level languages.

An Assembly Language program to move the tank forwards then backwards 2 spaces

// Move Forwards
LDA Forwards    //uses the label Forwards to load the value 0 into the Accumulator
OUT 1           // Move forwards by Outputting value 0 from accumulator to Output Channel 1
OUT 1           // Move forwards by Outputting value 0 from accumulator to Output Channel 1
//Move Backwards
LDA Backwards //uses the label Backwards to load the value 1 into the Accumulator
OUT 1           // Move Backwards
OUT 1          //// Move forwards by Outputting value 1 from accumulator to Output
Channel 1
HLT             // stop the CPU

//Data Labels - help to simplify code by attaching descriptions to the data values
Forwards    DAT 0   // assign the value 0 in the Label Forwards
Backwards   DAT 1   //assign the value 1 in the Label Backwards
          

Turning the tank. The tank can be steered in any one of 4 directions which correspond to compass points. (see the table above).

A simple assembly language program to get the tank to turn right (East):

//Turn Right
LDA East //uses the label East to load the value 2 into the Accumulator
OUT 2  //Turns the tank to the right (East) by outputting the contents of the Accumulator to Channel 2
HLT

//Data Labels - help to simplify code by attaching descriptions to the data values
North    DAT 0   // assign the value 0 to the Label North
East   DAT 2   //assign the value 0 to the Label East
South DAT 4   // assign the value 0 to the Label South
West DAT 6   // assign the value 0 to  the Label West
          

Movement and Turning. Move the tank 2 spaces forwards Turn West and Move 2 spaces Forward

// Move Forwards
LDA Forwards
OUT 1
OUT 1
//Turn Tank
LDA West
OUT 2
// Move Forwards
LDA Forwards
OUT 1
OUT 1

//Data Labels - help to simplify code by attaching descriptions to the data values
North    DAT 0   // assign the value 0 to the Label North
East   DAT 2   //assign the value 0 to the Label East
South DAT 4   // assign the value 0 to the Label South
West DAT 6   // assign the value 0 to the Label West
Forwards    DAT 0   // assign the value 0 in the Label Forwards
Backwards   DAT 1   //assign the value 0 in the Label Backwards