RO / EN

Chapter 5

Estimated reading time: 6–7 minutes

“So the exchange of data between ‘memory’ and the ‘central unit’ was done as though you were sending a newsletter today by carrier pigeon.”

It should be noted that MECIPT-1 did not have memory in the modern sense.

It had no fast RAM with direct access.

Everything was done on a drum: programmes and input data were stored on a magnetic drum from which they were fetched and transmitted to a processor that operated with a handful of working registers. The results had to be stored back on the drum as well. 

So the exchange of data between “memory” and the “central unit” was done as though you were sending a newsletter today by carrier pigeon. Sometimes the data from memory failed to arrive at the rendezvous with the drum address to which it had been sent, and had to wait for another revolution of the drum.

Our initial task was apparently simple: to write a programme that would calculate the sum of two numbers.

Evidently, “simplicity” is a relative concept. For me, it was rather like being asked to speak fluently a foreign language I did not know.

In the end, I grasped the logic of this silent yet vibrant and exceptionally easy-to-understand technology.

To perform the calculation one had to use the registers. So you placed the data from memory into the registers. The results you put back into memory.

What has changed conceptually since then? I should say nothing.

The von Neumann architecture (CPU + RAM) has held out heroically.

But the technological progress has been enormous.

Let us see what concept the much-awaited quantum computers will introduce. The QUBIT truly brings something new.

With a mixture of fear and curiosity, I began to write directly in machine code. Each instruction had its own operation code; each memory address I calculated with precision.

Whilst writing the reminiscences above,  the mischievous idea occurred to me to have ChatGPT 5.2 write a programme in MECIPT-1 machine code to add two numbers.

Then I gave it instructions to write a Python programme that would simulate the execution, in MECIPT-1 machine code, of the programme that adds two numbers.

It did not bat an eyelid, so to speak, and set about the work conscientiously.

I gave it a nearly complete prompt so that I would have as little work as possible adapting the Python script it was about to generate.

The prompt I gave it was the following:

Write a single Python file called: mecipt1_demo_slow_tts.py (standard libraries only).

Simulate the MECIPT-1 execution for the programme that adds 32,000 and 38,000.

Assumptions:

- Memory/drum: 1,024 addresses (0..1777 octal).

- The programme is already on the drum at address 400(dec)=0620(o) and consists exactly of:

 0620: left U 0144, right A 0145

 0621: left ME 0147, right AC 0094 (94 dec) => prints the number

 0622: left O 0000 (stop), right CU 0000 (nop)

- Data: M[100]=32000 (0144 o), M[101]=38000 (0145 o). Result in M[103]=M[0147 o].

- PC is in the form word.half: .0 = left instruction, .1 = right instruction.

- Display at each step:

 PC=....   RI=sign|opL(5b)|opR(5b)|addrL(10b)|addrR(10b)

 -> mnemonic + address (octal + decimal) + current S

 S(bin)=...

Effects:

- Teletype display (character by character) for the log lines.

- [TYPEWRITER] prints the result with a delay between characters.

Voice:

- Integrate ElevenLabs TTS: key ELEVENLABS_API_KEY from .env (in the current directory).

- Voice config from voice_config.py (COMPANION / ro-RO). Narration is BLOCKING between steps.

- If TTS is unavailable, the script runs without sound (no crash).

Before writing the code, say in 4–5 lines how you will proceed.

So I had 176 words in natural language, as you can see above, and I came away with 2,179 words written in Python (roughly 500 lines of code), plus a further 89 words generated by ChatGPT 5.2 in natural language to explain how it would proceed.

Here is what ChatGPT 5.2 replied, before generating the Python code.

Quote
I shall proceed as follows:

(1) I load ELEVENLABS_API_KEY from .env (in the current directory) and select the voice from voice_config.py (COMPANION/ro-RO), with fallback to the variables in .env.

(2) I build the MECIPT memory (1,024 addresses) and load the programme at 0620/0621/0622 and the data at 0144/0145.

(3) I run the fetch–decode–execute loop with PC = word.half and RI = current word, displaying each step in “teletype” + “typewriter” mode.

(4) Between steps, I generate TTS via ElevenLabs (with cache) and play the audio in blocking mode; if TTS fails, I continue without sound.
(5) At the end I display the result from memory and halt the demo.
EndQuote

For those unfamiliar with it:

ELEVENLABS is a well-known website where one has access to various synthetic voices in different languages for TTS services — Text To Speech.

Many other options exist.

Those who have arrived here with their IT credentials in hand may continue to see how the generated program worked

As I showed at the beginning of this chapter, MECIPT did not have fast RAM with direct access.

Everything was done on a drum: programmes, input data and final results were all stored and processed in the same physical space, sequentially.

The programme and data were loaded onto the drum using a small programme hardcoded into MECIPT-1, called a “loader.”

The punched tape was read by a special device that converted the perforations into electrical signals. The loader received these signals, interpreted them and wrote them to the drum at the addresses clearly indicated in the punched code, and the entire contents of the programme — instructions and data — were “downloaded” onto the drum before execution.

Nothing could be done partially or on the fly: everything had to be perfectly prepared in advance, in order, and synchronised with the rotation of the drum.

The central unit had only a few registers, but each had a clear role:

The Programme Counter (PC) stored the drum address of the next instruction to be executed;

The Instruction Register (RI) — the register into which the current instruction was loaded and decoded;

The Accumulator (the S register) performed the arithmetic and logical calculations.

You loaded the first number into the S register with one instruction, then with the next you added to the S register the second number located at the address specified in the addition instruction. That sentence expresses my first profound understanding in the science of computing.

Execution was sequential: the computer read an instruction from the drum, loaded it into the Instruction Register, decoded it and then carried out the action — if it was a calculation, it was processed in the Accumulator; if it was a write operation, the result was returned to the drum.

The fact that instructions and data were encoded in 31-bit binary words was an enormous advantage and a testament to the expertise of the Timișoara team.

Whilst many computer manufacturers, including some prestigious companies, had adopted 12-bit or 16-bit architectures, the Romanian engineers chose a 32-bit architecture — the same architecture that IBM would later adopt as the standard for its System/360.

The difference was more than cosmetic. The 31 bits allowed a single word to contain two instructions.

Let us see what a 31-bit word looks like when we are speaking of instructions:

RI = 0|00001|00101|0001100100|0001100101

In our simulator, the format is (I have marked it with separators):

0 = sign/control bit (in data words this is the sign of the number; in instruction words it usually remains 0) 

00001 = the opcode of the left instruction — opcode = the instruction code, in this case meaning load into the accumulator

00101 = the opcode of the right instruction, meaning add to the accumulator

0001100100 = the operand address of the left instruction — i.e. the drum address where the first number, 32,000, is located

0001100101 = the operand address of the right instruction — i.e. the drum address where the second number, 38,000, is located

1) So we decode the opcodes (the two instruction codes)

00001 in binary = 1 in decimal → opcode 1 → the U instruction

(U = “Load”: takes a number from memory and places it in the accumulator S)

00101 in binary = 5 in decimal → opcode 5 → the A instruction

(A = “Add”: adds the value from an address to S)

So far, we already know the two instructions:

left: U … load into the accumulator (S)

right: A … add to the accumulator

‍2) We decode the operand addresses — one for each instruction

Now comes the beautiful part: the 10 address bits.

0001100100 = 100 in decimal, the drum address where 32,000 resides

0001100101 = 101 in decimal, the drum address where 38,000 resides

How do they arrive at the “period” form, in octal, to be read more easily by programmers?

Through the simple trick: groups of 3 bits → one octal digit. 

Take 100 decimal in binary (without the leading zeroes): 1100100

Pad it with zeroes on the left to make a multiple of 3: 001 100 100

In octal that gives: 1 4 4 → 0144(o)

Likewise for 101: 1100101 → 001 100 101 → 145 → 0145(o)

So the addresses are:

left: 0144(o) = 100(dec)

right: 0145(o) = 101(dec)

3) The conclusion: the RI holds precisely these two instructions:

The left instruction: U 0144 → load into S the value from address 100 (the first number)

The right instruction: A 0145 → add to S the value from address 101 (the second number)

That is to say, this single memory word contains two complete commands, each with:

an opcode (what to do)

an address (what to work with)

And here lies a neat trick (and the reason it was more than cosmetic):

instead of reading one instruction per word from the drum, you read two in one go.

As though the drum, being a “wheel” that spins, were telling you:

“Since you’ve caught the moment… take the left and the right. By the time I come round again, another revolution will have passed.”

Furthermore, the 31 bits allowed integers ranging from approximately minus two billion to plus two billion, compared with a mere 32,768 on a 16-bit system — a crucial difference for serious economic and scientific computation.

This architecture offered programming that was more efficient, more concise and easier to understand than other systems of the era. It was rather like comparing a dictionary that gives a complete definition in a single entry with a dictionary in which you must leaf from one page to another to grasp the full meaning of a word.

With these explanations you may watch the film below, which simulates a programme written in MECIPT-1 assembly code for the addition of two numbers. Do not forget to turn on the sound.

The professor walked between the benches and looked over my shoulder. He smiled faintly, which I interpreted either as approval or as an act of compassion towards a novice. I learnt later that it was, in fact, the latter.

“Good, now we must transfer the programme onto the punched tape,” he announced.

And here another adventure began. A punched tape was a long roll of paper with holes that represented the code. The punching was done on a special machine, and every error meant starting the entire sequence again from the beginning.

When I had finished punching the programme, I took it to the computer “operator,” a mysterious figure who seemed to hold the key to the machine’s soul. The operator fed the tape into the reader and… we waited.

After a few moments that felt like an eternity, the operator handed me the result.

- End of Chapter 5 -