# 教程/红石计算机

## 概述

事实上在不了解计算机是如何工作的情况下是无法建造计算机的。此教程旨在解释你需要知道的所有内容，但这确实需要一点对计算机科学的了。我们将涉及的最深层次是IGCSE CS。

## 第一节， 建造一台计算机的教程

### The MASIC Computer

The MASIC computer aims to be a one-size-fits-all computer and does not specialize in one task, so it is fully programmable by reading its own memory (explained in Section 2: instruction sets). The simple I/O is great for multipurpose use and the memory is sufficiently sized. It runs at quite a fast speed (because of its small size).

### Step 1: Memory and Address Decoders (PRACTICE)

#### Address Decoder

0000 0000 (notice output 1 is lit)
0000 0001 (notice 2nd output is lit)
0000 0010
0000 0011

This is the design for the address decoder we are going to build.

Above is a simple 2-bit state, so it has two inputs (left and right) through the repeaters. The output is the redstone line above which will turn OFF when the state is met. The state is whether the redstone input will turn OFF the redstone line above; if so, the state is the redstone inputs. In the above case, the left must be turned OFF (0) and the right (blue) must be turned ON (1) to yield an OFF on the top redstone line. So it expects a state of OFF ON (aka 01 for binary).

They are colored blue for bits which should be ON (1) for it to stop powering the top redstone line. Once every bit stops powering the redstone line, it then turns off.

These are basically either one or two NOT gates feeding into a OR gate and then NOT the output.

Above is an 8-bit state, it expects 8 inputs in exactly the order 0000 1101. So that state it expects is 0000 1101. So the redstone torches power the inputs, and so we see the redstone line on the top turns OFF (only when exactly three redstone torches are placed in that exact order of 0000 1101).

Now if we put multiple of these together, we can count up in binary with the blue bits to get all 255 states of 8 bits. The one below is 8 bits, and has four state expectations. See the right images to see it in action. Now each green output can be a memory cell, and if we continue counting in binary, it will reach 255.

The input is 0000 0011 (see the redstone torches for input) and where the blue bits match the current state, the green output is ON.

• 0000 0000 - first signal out (on the images on the right)
• 0000 0001 - second signal out
• 0000 0010 - third signal out
• 0000 0011 - fourth signal out

So now we keep counting up in binary to get up to 0000 1111 and stop there; we should now have 24 (16) state expectors. Now we're done with the address decoder. We do not continue counting up to 1111 1111 because of instruction set limitations, explained in section 3: instruction sets

### Step 2: Building an Arithmetic Logic Unit (THEORY)

The Arithmetic Logic Unit referred to as the ALU will compare and perform mathematical operations with binary numbers and communicate the results with the Control Unit, the central component of the computer (and Central Processing Unit but that is going to be as big as the computer itself). Many tutorials will want the reader to build an ALU first, and therefore the topic is covered very widely around the internet.

The ALU we will be building can perform four important operations on two inputs and return a correct output. A, B, being both 8-bit inputs

• A + B (Add A to B)
• A >> (bitshift A right (the same as binary divide by 2))
• << A (bitshift A left (the same as binary multiply by 2))
• NOT A (The opposite of A)

There can also be multiple ALUs inside a computer, as some programs require a lot of operations to run, which do not depend on the previous operations (so they can be threaded) so delegating them to different ALUs could significantly speed up the program.

binary adder

#### Adding two numbers

In an adding unit, for each bit (for our computer, we require four, hence 4-bit), there is a full adder. The full adder will take three inputs, each input can be either 1 or 0. The first two will be the user's input and the third will be the carry input. The carry input is the output of the previous full adder, this will be explained later. The adder will output two statements: first, the output and then the carry output, which is sent as input into the next full adder, a place value up. For example, I wish to add the number 0101 to 1011. The first full adder will consider the first place value, 1 and 1 as their two inputs (we are reading right to left). There is no carry input as there is no previous full adder. The full adder will add 1 and 1; which is 0, and carries a 1 to the next place value. The next full adder would add 0 and 1 and the carry input would be 1 which the previous full adder stated. The output of 0 and 1 would be 1 but there is a carry input of 1 and therefore will add 0 and 1 and 1, which is 0 and carries a 1 to the next place value. Reviewing addition in binary should resolve any confusion.

full binary adder

All ALUs, to perform adding operations, require the presence of multiple adders. Every two bits will feed into an adder which, when joined with other adders, will produce an output which is the sum of the two bytes added together. An adder has an input, an output, and two carry input/output as would a person carry when doing the addition of 9 + 1 or 01 + 01. The adders are made of logic gates which is possible by the nomenclature of binary. Tutorials/Arithmetic logic gives a very detailed look into full adders and half adders, for now, there is a schematic of how to construct one. It gives four inputs/outputs and should be connected with other adders to create a unit. For this example, we will connect four adders together in our four-bit computer so that we can take in all four bits to make an output. There will be an input carry missing from the first adder, this is because there is nothing to carry from the bit before it, it is the first bit. The input carry will remain at zero. There will also be an output carry missing from the fourth adder, and the output of this will be ignored as we can only support four bits. The additional fourth carry output is wired to the overflow flag to signify the operation couldn't be done. This is called a binary overflow.

So basically, go into Minecraft and build a full binary adder (picture show) and connect them up. There should be eight inputs and outputs. Try placing levers and redstone lamps at the respective ends to test your creation. So 0010 + 0011 should yield 0101 (2 + 3 = 5, we are reading right not left).

##### Fractional numbers

A computer takes care of numbers less than one by form of float-point arithmetic, it is only so useful in larger-bit computers (16-64 bits) and computers which do need to use numbers less than one. Floating-point arithmetic or arbitrary-precision arithmetic are two ways to achieve this. Another simpler but less efficient way would be to assign all numbers a power of two so that they are 'bumped up' by the power of two chosen. The player must do this to every number and assume the one as one times the power of the two you have chosen. For example, 5 = 1012 so 5 × 23 = 1010002; five is bumped up by three. So now, one in your new system would be 1 × 23 = 10002 and that would leave room for 0.1, 0.01 or 0.001; 0.01 * 23 = 102. This leads to a more complicated setup for your computer.

#### Subtracting two numbers

An adder with all labeled parts.

The subtraction of numbers is surprisingly simple. The ALU first must change the second number (the value subtracting by) and convert it from a positive number to a negative number. A two's complement is when you invert the binary number (so that all the 0s are 1s and 1s are 0s) and add one to it.

Example: do 10 subtract 9

 1. 0000 1001 (9 in binary, we want -9, not 9) 2. 1111 0110 (Invert 9, so that all 0s are 1s and 1s are 0s) 3. 1111 0111 add one (this the two's complement of 9) 4. 0000 1010 (10 in binary) +1111 0111 add two's complement of 9 (aka -9) ---- 0000 0001 result (10 + (-9) = 1) (there is an overflow, this just means that the result is not a negative number)

This poses the complexity of signed numbers.[1] This is a weight to the binary number to assign it as a positive or negative number. Whether the result is a negative or positive number is determined by the overflow flag. If there is an overflow, this means that the number is positive and otherwise, negative.

To implement this, you can ask the ALU to do 3 operations. To do A subtract B, the operations are

Operation: A SUB B

• NOT B
• (set B to) B ADD 1
• (set A to) A ADD B
• RETURN A

#### Multiplying two numbers

Multiplication is repeated addition, so the easiest (inefficiently) is to add A to a variable B amount of times.

Here's pseudomachine code for it

Operation: A * B

• C = 0
• (set C to) C ADD A
• (set B to) B SUB 1
• JUMP IF (B > 0) TO LINE 2
• RETURN C

However, there are more efficient ways of multiplication. A good method is to repeatedly bitshift the first number to the location of each 1 in the second number and sum it.

There are underscores to mark indents, since padding with 0s are less intuitive. subscript 2 means in binary, and decimal numbers are also in bold

 __ __11 3 (notice that there are 2 1s) x_ 1011 11 ---- __ __11 We shift 112 by 010 since the 1st bit of 10112 is 12 +_ _110 We shift 112 by 110 since the 2nd bit of 10112 is a 12 +1 1000 We shift 112 by 310 since the 4nd bit of 10112 is a 12 ---- the 3rd bit of 10112 is 02 so we do not add a 112 there 10 0001 33 (result)

so this is more efficient for larger numbers.

Operation: A * B

• C = 0
• D = 0
• (Set A to) << A (bitshift A to the left)
• JUMP IF (BIT (D) OF B == 0) TO LINE 6
• (Set C to) C ADD A
• (Set D to) D ADD 1
• JUMP IF (D < LENGTH OF B) TO LINE 3
• RETURN C

Don't forget that

<< A (bitshift to the left) is effectively, A * 2

and

>> A (bitshift to the right) is effectively, A / 2

If the numbers are predictable or the CPU must do a lot of similar numbers in bulk, consider using a look-up table to quickly get results to frequently called multiplication. Is this a way of hard-coding your answers and is used in extreme cases.

### Step 3: Instruction set and machine architecture (THEORY)

This is pretty fun, this part.

Elaborating on Chapter 2: Instruction Set, we will be creating one for ours.

For the MASIC Computer, the computer which we are building, have an 8-bit system, so that means each instruction on each slot of the stack memory will be 8 bits. The stack memory is the memory where any information can be stored and is on the RAM. There will be a counter, called the program counter, which increments by 1 every cycle. A cycle is the CPU fetching the instruction, decoding the instruction (finding out what to do with the instruction) and executing the instruction (doing what it tells it to do). Then it moves on to the next one by incrementing the program counter and reading the information at that location in the stack memory.

So each byte in the stack memory has 8 bits for us to work with.

0000 0000

and some instructions require an address, say loading memory into a register so that we can perform operations (such as addition) on it. Each instruction will be split into two parts, each 4 bits. The first is the TYPE. the TYPE will specify what the computer must do and the ADDRESS will be where the value we will perform our operations are located.

OPCODE OPERAND

so 4 bits for the TYPE, we can have 2^4 types, so 16 different ones. Our computer will have two registers, so one bit will be for specifying the register the operation will executing on and is denoted by an x.

Instructions are put in the same place as memory and as the ADDRESS part of the instruction is only four bits, we can only reference memory from 1-16 lines, requiring some clever programming to fit larger programs. Memory is also limited to 16 bytes per program. Values and instructions are essentially the same thing, so if you write an instruction to store it onto a line that previously-stored an instruction, that effectively overwrites the instruction with a value. Accidental execution of values might be a problem, so a STOP command must be used to prevent any errors. This is a whole lot to understand, so good sources are https://www.computerscience.gcse.guru/theory/high-low-level-languages and https://scratch.mit.edu/projects/881462/ <-- really helpful actually. and also don't forget to take both CS and ICT for your IGCSEs.

#### Prerequisites

The section will cover simple topics and components commonly found in a computer, so information from chapter 2 will be used, such as the ALU, RAM, registers and binary manipulation.

#### The MASIC Instruction Set

Since the computer Here is the first draft of the instruction set, with only essentials. This is based on other assembly languages, but changed to adapt to our architecture. There are two registers, so we need instructions to perform operations on both registers.

BINARY OPCODE COMMENT
0000 LOAD R1 Load the ADDRESS into register 1
0001 STORE R1 Store contents of register 2 into ADDRESS
0010 JUMP R1 IF Jump to line ADDRESS if register 1 is equal to 0
0011 ADD R1 Add contents at ADDRESS to register 1
0100 <<R1 Bitshift register 1 left
0101 NOT R1 Bitwise NOT register 1
0110 JUMP Jump to line OPERAND
0111 STOP Terminate the program.
1000 LOAD R2 Load the ADDRESS into register 2
1001 STORE R2 Store contents of register 1 into ADDRESS
1010 JUMP R2 IF Jump to line ADDRESS if register 2 is equal to 0
1011 ADD R2 Add ADDRESS to register 2
1100 <<R2 Bitshift register 2 left
1101 NOT R2 Bitwise NOT register 2
1110 OUT R1 Outputs register 1
1111

To translate:

1000 0011 means LOAD R2 3 because LOADR2 is 1000 and 0011 is 3.

These can be in a process so that functions can be performed.

#### Writing programs

This one does the Fibonacci sequence: (0,1,1,2,3,5,8... etc.)

FIBONACCI
LINE BINARY INSTRUCTION COMMENT
1 0000 1110 LOAD R1 14 set register 1 to 0 (the value at line 14)
2 0011 1111 ADD R1 16 add the value at line 16
3 1110 0000 OUT R1 output the register
4 0001 1111 STORE R1 16 put that in line 16
5 0011 1110 ADD R1 15 add the value at line 15
6 1110 0000 OUT R1 output the register again
7 0001 1110 STORE R1 15 now put the output back
8 0110 0010 JUMP 2 we don't have to reset the register so we loop back to line 2.
...
14 0000 0000 0
15 0000 0001 1
16 0000 0001 1

The previous is an example of a low-level assembly language. If it was written in a high level language such as C++, it would look more like this:

```#include <iostream>
using namespace std;
int main()
{
int n, t1 = 0, t2 = 1, nextTerm = 0;
cout << "Enter the number of terms: ";
cin >> n;
cout << "Fibonacci Series: ";
for (int i = 1; i <= n; ++i)
{
// Prints the first two terms.
if(i == 1)
{
cout << " " << t1;
continue;
}
if(i == 2)
{
cout << t2 << " ";
continue;
}
nextTerm = t1 + t2;
t1 = t2;
t2 = nextTerm;

cout << nextTerm << " ";
}
return 0;
}
```

#### Instruction Cycle

Rounded squares are components, squares are registers. Green arrows are busses

The instruction set is the lower assembly language, so we want to integrate that more with the hardware side. This revolves around the fetch-decode-execute cycle (explained above). In the CPU, there will be 4 important registers,

the Program Counter (PC), keeps track of which program the computer is currently on

the Memory Address Register (MAR), keeps track of where the next memory location will be

the Memory Data Register (MDR), keeps track of what the memory AT the location is

the Current Instruction Register (CIR), keeps track of what instruction is currently being worked on

and the ALU Accumulator (ACC). keeps track of the input and output from the ALU

There are also four components to keep in mind, the Address Decoder, the memory, the Instruction Decoder and the ALU.

FETCH The program will get the next instruction.

1. PC sends the instruction number to the MAR
2. PC increments by 1, to prepare for the next instruction
3. Address Decoder decodes the address, and requests information at that address from the memory
4. MDR receives the requested information (in the case of the picture, if the MAR is 0001, it receives 'LOADR1 1')

DECODE The program will identify what the instruction is

1. CIR receives the information from the MDR, through the information flow
2. Instruction Decoder decodes the instruction and what to do

EXECUTE The program will execute the instruction

1. In the case of the picture, the program receives 'LOADR1 1' as the instruction, the Instruction Decoder splits the instruction up into the opcode and the operand.

The opcode is 'LOADR1' and the operand is '1'.

1. Operand is sent to the MAR, to get the information at that address
2. MDR receives the information at that address (in the example, it is the same line)

Now four things could happen depending on what the instruction is.

If the instruction is an ADD instruction, the ACC will be told to receive the information from the information flow and the ALU will perform operations on it, outputting it to the ACC again.

If the instruction is a LOAD instruction, the CU will load the instruction to the register.

If the instruction is a STORE instruction, the CU will instead SET the data at the location specified by the MAR in the memory.

If the instruction is a OUT instruction, the CU will send the instruction to the output peripheral.

REPEAT The instruction cycle repeats itself until it reaches a STOP instruction or runs out of memory

## 红石计算机的规划

• 执行模型（内存的计算机组织与程序存储和执行）
• 字节大小（信息的大小，你的红石计算机用这些执行命令）
• 命令集（红石计算机的一个结构）
• 内存大小（数据可以存储在内存中，可存储数据多少取决于内存大小）

## 执行模型

### 哈佛结构

The Harvard architecture 检索器分离的命令组成一个活跃的程序从数据访问器的程序在执行期间访问。 　　编写的程序对电脑使用哈佛架构可能执行的任务达到快100%访问主内存总线。但是要注意，哈佛架构的某些记忆电路体积会很大。

### 冯·诺依曼结构

The von Neumann architecture使用一个两步的过程来执行命令。首先，加载内存包含下一个命令，然后新命令加载是允许访问相同的内存，因为它执行，使用一个内存的程序和数据促进元编程技术像编译器和自我修改代码。 　　 冯诺依曼体系结构是第一个提出模型的计算和几乎所有真实的计算机是冯·诺依曼在《自然》杂志上。

## 位宽与指令位数

4 8
8 8
8 16
16 16

### 数据字符

1 （ 2 ^ 1 - 1 ） 1
7 （ 2 ^ 3 - 1 ） 3
15 （ 2 ^ 4 - 1 ） 4
255 （ 2 ^ 8 - 1 ） 8
65535 （ 2 ^ 16 - 1 ） 16
4294967295 （ 2 ^ 32 - 1 ） 32

# 计算机的设计

## 命令集架构

#### 过渡

##### 命令

• 加、减、乘、除
• 从RAM/ROM/第三存储器的读/写
• 读取和写入数据到内存
• 分支的其他部分代码
• 比较寄存器
• 计算一个逻辑函数 （NAND，NOR，NOT etc.）

## 机器架构

### 数据通道

#### 算术逻辑单元(简称ALU)

ALU是计算机最重要的组件之一，在现实生活和Minecraft中。首先，你必须选择你希望能够实现的功能。大多数时候，这些都是加法、减法和一组逻辑选项。

## 提示

• 你也可以使用一些像是WorldEdit的模组
• 如果你在生存模式没有太多的红石中继器 你可以用两个红石火把代替
• 利用颜色进行分区（例如用蓝色羊毛建造RAM（随机存取存贮器），黄色羊毛建造ALU（算术逻辑部件运算器）等）