In times of widespread domination of tablets and smartphones, it is hard to believe that, quite recently, one could get a lot of pleasure by playing with a calculator. Of course, I mean not a normal (or even engineering) calculator, but a
programmable one . I want to talk about a device that literally turned my life around and actually pushed me to become a programmer.
In the late 70s of the last century, with the computer technology in the USSR was tight. My father worked as a programmer. In my memory will remain forever and trips to his work in the Central Department Store, where I played in
him with the computer
Minsk and the long stuffing programs with brass rings on the tablets for Sparks, used at that time by Sberbank. To have, in my personal possession, something capable of carrying out programs, I, of course, could not even dream of.
Everything changed with the advent of programmable calculators (PMK). Now I could dream. This is exactly what I did, reading articles in the
Technique of Youth , since it was not possible to acquire this programmable miracle in Kazan. But, one day, my parents and I went to Moscow.
Having made considerable efforts, I convinced my parents to buy the
MK-61 which was not cheap at that time, and, on surrender, the filing of old
Quant magazines, after which, having barricaded themselves in the apartment of our relatives, I stopped reacting to external irritants, right up to the time of departure.
')
I re-read everything that was printed at that time on programmable calculators, started a common notebook and diligently rewrote the programs I liked the most. Gradually, I approached the fact that I was able to make corrections and improvements in them (the experience gained in the vigils on programming Sparks was not in vain). After a while, I was able to write programs on my own.
When I was already fairly well accustomed to the MK-61, one of my friends had purchased an improved version -
MK-52 . According to the command system, it practically did not differ from the MK-61, but had the opportunity to save programs in the EPROM and was supplied with several cartridges with ready-made programs. Of course, I immediately wanted to write something specifically for her.
Lyrical digressionI must say that the issue of storing programs for the PMK, at that time, was of great interest. Each time typing a rather large program anew was really uncomfortable. In addition, the introduced program was required to be carefully re-checked for various kinds of errors.
Enthusiasts have proposed many circuit solutions to this problem. Once I even saw an article describing a device for storing calculator programs on magnetic tapes. The release of the MK-52 put an end to this not simple question.
The choice fell on "Battleship". I wanted to do it for a long time, but I couldn’t have crammed into all the required functionality in the short space of the calculator. The ability to load programs from the EPROM allowed the program to be divided into two parts. The first block - arranged the ships, the second (the actual game) provided a dialogue with the user. Part of the subroutines was used by both blocks.
Here is how this miracle looked (the picture is not for the faint of heart) Since in this form, this cave painting is practically impossible to decipher, I will give this code in a more readable form:
Ship placement unit00|46 01.07 02.12 03.08 04.11 05.34 06.15 07.45 08|53 09:75 10.06 11.53 12:67 13.5E 14:08 15.62 16.53 17:37 18.6E 19.01 20.11 21.4E 22|53 23:34 24.6E 25.02 26.10 27.4E 28.53 29:34 30.5D 31:08 32.63 33.50 34|62 35.02 36.10 37|65 38.12 39.01 40.10 41.DE 42.38 43.BE 44.52 45.11 46.4E 47.53 48:58 49.6E 50.02 51.10 52.4E 53.53 54:58 55.5D 56:22 57.27 58|61 59|65 60.12 61.01 62.10 63.DE 64.38 65.BE 66.52 67|65 68.12 69.01 70.10 71.DE 72.37 73.35 74.52 75|66 76.01 77.01 78.12 79.20 80.10 81.35 82.46 83.07 84.12 85.07 86.10 87.4E 88.65 89.04 90.15 91.12 92.45 93.01 94.11 95.59 96:A2 97.65 98.07 99.15 A0.13 A1.45 A2|52
Loadable game block 00.40 01.50 02.57 03:41 04.0B 05.15 06.45 07.14 08.06 09.10 10.4E 11.02 12.53 13:67 14.57 15:22 16.0F 17.DE 18.39 19.BE 20.64 21.52 22|53 23:75 24.01 25.53 26:67 27.5E 28.22 29.15 30.53 31:59 32.6E 33.06 34.11 35.62 36.12 37.65 38.17 39.11 40.52 41|53 42:58 43.6E 44.01 45.11 46.4E 47.53 48:58
Here I use command codes, since their designations proposed by the manufacturer of the PMC are not very convenient for printing “listings”. The correspondence of the codes to the commands can be seen on the table (kindly drawn by me in the same years):
A brief tour of the command systemWith some practice, command codes were easily remembered (which was necessary, since the entered programs needed to be checked). The most frequently used were:
- Arithmetic instructions (10–13) that perform the corresponding action with two lower registers of the operational stack (X, Y) and placing the result in X
- Commands for writing and reading from memory registers (40-4E and 60-6E respectively)
- Commands that control the execution of the program (50-5E), among which should be noted the stop command (50), as well as the commands for calling the subroutine (53) and returning from it (52)
- The indirect addressing commands (B0-BE, D0-DE) were very useful, allowing you to access the memory register whose number was written to another register
Although hexadecimal digits were used in the command codes, their display on the screen caused footage from the Predator movie:

For convenience, I selected in the code the addresses of transition teams (a colon after the team address), as well as entry points (a vertical bar). This allows you to more clearly see the relationship of the subroutines (the subroutine call command is particularly interesting, located at address 22 and providing a kind of “polymorphism.” When accessing this subroutine, control was transferred to different places, depending on which block was loaded).
It can be noted that the transitions to the middle (and not to the beginning) of the subroutines were not something extraordinary. Due to the extremely limited size of addressable memory, literally everything had to be saved. The transitions to the address of another transition (interpreted in this case as a command code) were considered as special chic.
Since there is no longer a working calculator at hand, I used an
emulator :

All prepared images were uploaded to
GitHub .
The first
image can be used for the placement of "ships":

The initial value for the pseudo-random number generator (0.1234567) can be changed. After launching the program (i / o s / n), the program works for quite a long time, ultimately deriving the address for loading the game module from the EPROM (the ability to automatically access the EPROM from the program was absent):

Since the emulator (at least the version I used) completely ignored my attempts to access the EPROM, I prepared an
image with a game module hammered in by my hands and a ship layout already completed.
The arrangement itself is stored in memory registers from the 7th to the D. Here is an example of the second line (the 8th register):

The twos encode the position of the "ships". Based on the above initial value, the following arrangement was generated:
0 0 0 0 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0
You can see that the program has placed nine non-contiguous "single-deck ships" on a field of 7x7 cells.
To start the game, you must enter the number of ships (9 w / o s / n) and then enter the coordinates of the "shots" (for example, 2 V ^ 2 s / n). Since we spotted the location of the “ships”, we had no difficulty in sinking the “single-point”:

However, the second time it will not be possible to get on it:

Let's try (2 ^ 2 / ). As expected, the calculator strikes back:

The first digit here is the vertical coordinate (starting from the bottom up), the second is horizontal (from left to right).
A little later, I noticed that by changing just a couple of commands (in the very first photo with the text of the program, they are marked in red), it is possible to ensure that the ships being placed can touch, not the corners, but the sides (images
0003 and
0004 ). The result was the following arrangement of "multi-fenders":
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0
God knows that, but not bad, considering that only two teams had to be changed.
Separately, it should be said about bugs (even more likely about bugs), although this is a topic for a separate article, if not their cycle. The fact is that the calculators of the series being described were literally crammed with various examples of errors and undocumented behavior. Among the amateurs, this led to the development of a culture of exploring these undocumented possibilities, known under the generic name
EGOGG .
Some examples of such bugs are funny, others are dangerous, and some of them are surprisingly useful. A good example of such potentially useful behavior is the execution of the “enter order” (VP) command after writing to the memory register. In the program execution mode, it led to the "cutting off" of the first digit of the number in the X register (displayed on the indicator), and with step-by-step execution (yes yes, it was like that), the team worked out quite well. To achieve any other reasonable way of such a result was impossible.
Frightened by the non-standard behavior of the VP team, I corrected the program by changing the sequence of commands 35.VP 36.1, to 35.IP2 36.x (in the 2nd register I had to store the constant 10). Since there is no live calculator, I can no longer verify whether the command to the VI resulted in an error in this context. Under the emulator, both options work quite normally.
Unfortunately, I do not know the implementation of an emulator that reproduces all examples of undocumented behavior.
After all this, there were Microsha, BK-shki and Spectrum. There was
EU-1046 , which I encountered at the institute. There were PDP-shki and VAX-s. Before the advent of the IBM PC, the wait was not long.