In the first part we've read chapters 1–14. We learned how to build electrical and logic circuits with light bulbs. At the end of the first part, we built a circuit based on them that counted from 0 to 256.
This time we will read the remaining chapters 15-25. By the end we will assemble the first memory that can store information and then connect it to an adder. We will build the first processor, from which we will make a primitive computer with input and output.
A byte is 8 bit. It values range from 00000000 to 11111111, 256 (28) options. Values are long, so instead of binary we can use hexadecimal to write them:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, 10, 11, 12, …
So then 101101102 = B616.
Paper is a basic external memory for people:
We write and we later read. We save and we later retrieve. We store and we later access
D-trigger from the previous chapters, the latch is a 1-bit memory. We can rename the output Q “data output” and the input Clk “write”. From 8 such latches, plus a 3-to-8 decoder and an 8-to-1 selector, we get random access memory (RAM):
Random access means that you can read value from any of the eight latches or write to them simply by changing the Address inputs.
When connecting two RAM 8×1 in parallel we get a RAM 8×2. When connected with a 2-to-1 selector and a 1-to-2 decoder (as two separate “latches” inside) you get a RAM 16×1.
Number of values in RAM array = 2Number of Address inputs
Random access memory is called volatile memory because...
It re- quires a constant supply of electricity to retain its contents
Let's finally build the computer™. Let's assume that by latches we always mean edge-triggering latches (when Clk goes from 0 to 1).
Let's connect the memory RAM to an adder with accumulation.
Suppose we need to find three sums. Let's represent in memory the values and the addresses of the values:
For addition the adder must now:
...Transfer [load] a byte from memory into the accumulator....Add a byte in memory to the contents of the accumulator....Take a sum in the accumulator and Store it in memory. ...Halt the automated adder
For the array in the figure above:
- Load the value at address 0000h into the accumulator.
- Add the value at address 0001h to the accumulator.
- Add the value at address 0002h to the accumulator.
- Store the contents of the accumulator at address 0003h.
- Load the value at address 0004h into the accumulator.
- Add the value at address 0005h to the accumulator.
- Store the contents of the accumulator at address 0006h.
- Load the value at address 0007h into the accumulator.
- Add the value at address 0008h to the accumulator.
- Add the value at address 0009h to the accumulator.
- Store the contents of the accumulator at address 000Ah.
- Halt the workings of the automated adder
To achieve this, we will accompany each number in memory with a code of the desired action. This will be done by a separate array RAM (“codes”), in which we will write the necessary actions:
“Data” and “codes” can be combined into one array, but to make it easier to work with command addresses, it is worth adding the “Jump” command, which will point to the address of the next command to run.
Also we add zero flag. Its output is 1 only if all its inputs are 0. With it, we can add other 4 operations:
|Add with Carry||22h||ADC|
|Subtract with Borrow||23h||SBB|
|Jump if Zero||31h||JZ|
|Jump if Carry||32h||JC|
|Jump if Not Zero||33h||JNZ|
|Jump if Not Carry||34h||JNC|
These commands are enough to multiply two numbers by each other:
To carry out these operations, you will need a circuit:
...Controllable cyclic procedures distinguish a computer from a calculator
In the circuit above, the memory is a 64 KB RAM array. The input and output are switches and lights on the memory control panel. Everything else is an 8-bit processor (central processing unit, CPU).
We can write commands using mnemonics, like this:
LOD A, [1003h] (1) Load; (2) Where to A: to accumulator; (3) Where from [1003h]: from address 1003h. STO [1003h], A (1) Store; (2) Where to: by address 1003h; (3) Where from: from accumulator. JNZ 0000h (1) Jump, if not Zero; (2) Where to: to operation by address 0000h. 1000h: 00h, A7h (!) Data: first and second bytes.
It’s better not to use actual numeric addresses when writing code because they can change. It’s better to use labels to refer to locations in memory
If we add labels, we get “assembler”. Here is a program for multiplying numbers:
BEGIN: LOD A, [RESULT + 1] ADD A, [NUM1 + 1] STO [RESULT + 1], A LOD A, [RESULT] ADC A, [NUM1] STO [RESULT], A LOD A, [NUM2 + 1] ADD A, [NEG1] STO [NUM2 + 1], A JNZ BEGIN NEG1: HLT NUM1: 00h, A7h NUM2: 00h, 1Ch RESULT: 00h, 00h
Relays were not suitable for building computers. As mechanical devices whose action was based on bending a metal plate, after prolonged operation they broke down. In the twentieth century they were replaced by radio tubes.
The computer we built earlier is a typical example of a von Neumann architecture. Its disadvantage is the long loading from memory.
In 1947, the semiconductor transistor appeared. Semiconductors are elements whose conductivity can be controlled (for example, silicon). If a semiconductor has excess electrons, it is an n-type semiconductor; in the opposite case, it is a p-type one.
A transistor consists of semiconductor elements: collector, base and emitter.
The transistors are suitable for building logic gates:
[Voltage in] between 0 and 0.8 volt [stands] for a logical 0 and between 2 and 5 volts for a logical 1. This is how TTL is insulated against noise
Propagation time is the time it takes for a change in the inputs to be reflected in the output, measures in nanoseconds.
A quartz crystal is used for the oscillator, the frequency of their oscillation is more than a million per second, this affects the speed.
In this chapter the author describes in detail how the Intel 8080 and Motorolla 6800 processors work. I will give here only an abbreviated description of the 8080.
Let's start with the circuit:
-5V, 5V and +12V is the power supply with voltage of -5, 5 and +12 volts, GND is the ground. The direction of the arrows on the other pins indicates the direction of the signal, some pins work in both directions.
Slashed zeros are syncing signals. A0 to A15 is the memory addresses. D0 to D7 data slots. Everything else is controlling signals.
The 8080 processor has 244 commands.
32 STA (Store to accumulator) 3A LDA (Load from accumulator)
Except for the accumulator, there are 6 registers B, C, D, E, H, L. (H and L stand for High and Low.) 8-bit values in HL registers are considered as a 16-bit pair, where second byte is stored in H, and the first on is in L. Registers allow to avoid constant memory access which makes the process faster.
63 codes for moving operations MOV from one register to another.
40 MOV B, B 41 MOV B, C (From C to B) … 5E MOV E, [HL] (From HL to E) 5F MOV E, A 60 MOV H, B … 68 MOV L, B … 70 MOV [HL], B … 76 HLT … 7F MOV A, A
MVI moves the data byte directly to the register or memory cell whose address is written in HL.
For arithmetic operations there are 32 commands. Addition (ADD), addition with carry (ADC), subtraction (SUB), subtraction with borrowing (SBB).
80 ADD A, B … 88 ADC A, B … 90 SUB A, B … 98 SBB A, B … 9F SBB A, A
There are also commands for logic operations. AND, OR, and XOR are executed bitwise. CMP is compare operation:
A0 AND A, B … A8 XOR A, B … B0 OR A, B … B8 CMP A, B … BF CMP A, A
CMA adds the contents of the accumulator to 1. DAA is for arithmetic operations with decimal numbers in BCD (Binary-coded decimal). When a number is in BCD this means it should be read “literally”. For example 27h in BCD is 27 and not 39.
Commands to increase and decrease the value of registers, accumulator or memory cell by 1: INR, DCR. 4 commands for cyclic shift: RLC, RRC, RAL, RAR. Commands for working with the stack: PUSH, POP.
CALL and RET are the commands for creating subprogramms. CALL writes to the stack the address of the command next to CALL, and the jump to the start of the subprogramm with Multiply label. When it's done, the RET command is executed. As a result the execution goes to the beginning of the stack.
Commands IN and OUT are for communication with the peripherals.
American Standard Code for Information Interchange, ASCII is a 7-bit text encoding. Its code values are in range from 00h to 7Fh. For storing each character, it uses 8 bits.
The ASCII contains punctuation marks, numbers, uppercase and lowercase letters and control characters. Codes of lowercase letters differ from corresponding uppercase letters by 20h, which makes it relatively easy to convert lowercase to uppercase and vice versa.
In order to encode something other than Latin, Unicode appeared. In it the characters take 2 bytes each, the first 128 characters are the same as ASCII.
The integral circuits that make up a computer are mounted on boards. The boards communicate with each other via a bus. The signals on this bus are divided into 4 categories:
- Addressable, for addressing RAM or referring to other devices.
- Data output, for transferring data into memory and to other devices.
- Data input, generated by various computer devices and fed to the microprocessor.
- Controls, generated by both the microprocessor and other devices that need to communicate something to the processor.
A bus in general use can become a standard
Busses need to be upgraded or replaced when microprocessors outgrow them, either in data width or in the number of address signals they output
There's also a story in this chapter about floppy disks and the cathode ray tube! 😃
The beam begins in the upper left corner and moves across the screen to the right, whereupon it zips back to the left to begin the second line
When the beam finishes the bottom line, it zips from the lower right corner of the screen to the upper left corner and the process begins again
To display text on the screen, the ASCII characters must be displayed as black and white pixels on the screen. The character generator translates the 7-bit ASCII code into a 64-bit code that determines the appearance of the character:
To color a pixel, you have to increase the number of bits allocated to it:
Number of Colors = 2Number of bits per pixel
Our computer now is missing two things:
- And a keyboard.
For the keyboard we need a special program—a keyboard handler, as well as a command processor.
In addition, we need a ROM—a permanent memory device, so that the entered information is not lost after power failure. A hard disk can be used as a ROM.
...You’ll have to keep track of what you’re storing where. ...You can’t just store some code located at one address and then later load it back into memory at another address and expect it to work
...The manual clerical work involved in keeping track of where everything is stored on the disk is just too much. At this point, you’re ready for a file system
File system is the information organization when it is divided into files. A file is a set of data with a common meaning, written in one or more sectors.
Fun fact about file names in and extension size of 3 characters:
Under CP/M, each file is identified with a two-part name. The first part is known as the filename and can have up to eight characters... the second part is known as the file type nd can have up to three characters stored in bytes 9 through 11
To start the operating system, it must be overwritten from disk into memory—boot. At the end of the boot, the OS is completely placed in memory, occupying its high addresses.
Application programs (applications) don't need to worry about tracks and sectors on disk when the OS is application programming interface, API.
API is hardware independent. That is, when writing programs for CP/M we don't need to know how the keyboard, monitor and disk work on a particular computer.
We are used to thinking of a continuous series of numbers, but computers work with discrete quantities.
To write a fraction, we can use a fixed point - assign a specific number of bits to decimal numbers. In this case, the decimal separator is always in a certain place in the number.
Fixed-point format works well only if you know that numbers aren’t going to get too large for the memory location that you’ve mapped out and that you won’t need more decimal places
Otherwise, for such numbers would have to reserve too much space in memory. To write numbers that can be both very large and very small a floating point is used.
Floating point numbers use scientific notation of numbers with significant part and order. But since we are working with binary numbers, the order will also indicate the degree of 2, not 10.
In normalized form, there is always one to the left of the separator:
1.01 × 22
1.101 × 22
Most computers use the IEEE Standard for Binary Floating-Point Arithmetic. There are two formats: simple precision (single precision, 4 bytes per number) and double precision (double precision, 8 bytes per number).
Fixed-point numbers are easy to determine by their appearance: the number of digits after the decimal point is the same accuracy. In the case of a floating-point...
Depending on the value of the exponent, sometimes a floating-point number can be accurate to a tiny fraction of a penny, and sometimes it’s not even accurate to the nearest dollar
If you were writing a program for a bank, and you were using single-precision floating-point arithmetic to store dollars and cents, you probably would be deeply disturbed to discover that $262,144.00 is the same as $262,144.01. Both these numbers are 1.00000000000000000000000 × 218
Programming in machine code is like eating with a toothpick
The first thing to do is to automate the translation from mnemonic commands (MOV, MVI, etc.) into real command codes. This is done by assemblers.
A new assembler has to be developed each time a new processor is introduced
Assembler programs have two disadvantages:
- They are painstaking to write;
- They are not portable: you cannot write an assembler for one processor and use it with another.
An assembler language is considered a low-level language because it communicates directly with the computer hardware. High-level languages don't do this.
A high-level language needs a syntax and a compiler or interpreter to work. The former is a set of rules for constructing expressions; the latter is a program that converts code into machine codes.
Later in this chapter there are some examples of Algol and BASIC programming, I won't give them here, but it's interesting to read them for fun.
To get a color on the CRT screen, you have to use not one, but three electron guns, one for each of the primary colors—red, green, blue.
The color coding table for the display adapter can be as follows:
The number of available colors is expressed like this:
Number of Colors = 2Number of bits per pixel
To work with sound, you need converters:
- DAC, digital-to-analog, to convert an electrical signal into sound;
- ADC, analog-to-digital, to convert sound to an electrical signal.
The voltage of the sound wave is converted to numbers at a constant rate, known as the sampling rate
“It all makes sense now”—that's what I would call the feeling I got after reading this book for the first time 😃
Everything written here I went through in school and university. This knowledge was there, but it wasn't... interconnected in my head. There was no strong confidence in how things actually worked, it was hard to move from one level of abstraction to another. Now everything is finally