User:Xaltonon
Out of the vast array of toys available from MechComp dispensers, one of the most confusing to newer mechanics is the Control Unit. It's a neat little device that can be programmed to accomplish a wide array of tasks. The MC14500B Industrial Control Unit is the real-life analogue of it.
Architecture
Registers
Registers are the memory of the microprocessor. There are several registers in the Control Unit. First, is RR, or the Result Register. It can only store one bit (0 or 1). Second, is the Input register. There are 8 inputs, labelled 0 through 7. They can be toggled on and off by sending a 0 or a 1 to the corresponding MechComp input. Input 0 is special, as it cannot be toggle on or off externally. It is always the complement (inverse) of RR. Lastly, there is the RAM. It has 8 bits of storage, again labelled 0 through 7. There is one other register, the Output register. It is write only, and has outputs 0 through 7. Values written to it are passed on (if the output is enabled) to other devices with the format Output Number:Output, eg. if you write the bit 1 to output 3, it will produce the signal 3:1. Two one-bit registers IEN and OEN are input enable and output enable flag bits respectively. If disabled, the input register cannot be read from and the output register and RAM cannot be written to (this only applies to RR, OEN and IEN themselves can still read/write to things).
Opcodes
The Control Unit has a ROM in hexadecimal that stores the program. The program loops after it finishes running. A command looks like this: Opcode, Operand. The processor chunks the ROM into pairs of bytes and execute them. These are the commands:
Mnemonic | Hex | Operand | Description |
---|---|---|---|
NOP | 0 | No | Does nothing. (Waits) |
LD | 1 | Input | Loads a value from the input number in the operand, and stores it in RR. Operands 0-7 are the input register. The RAM is accessed by the upper 8 operands (8-F). When an input is read (besides input 0), it is cleared. |
LDC | 2 | Input | Same as LD, but it takes the complement of the input and stores that. |
AND | 3 | Input | Takes the value from the input specified in the operand and computes the logical AND of RR and the input. The result is stored in RR. |
ANDC | 4 | Input | Same as AND, but takes the complement of the input. |
OR | 5 | Input | Takes the value from the input specified in the operand and computes the logical OR of RR and the input. The result is stored in RR. |
ORC | 6 | Input | Same as OR, but takes the complement of the input. |
XNOR | 7 | Input | Takes the value from the input specified in the operand and computes the logical XNOR of RR and the input. The result is stored in RR. |
STO | 8 | Output | Stores the value of RR in the output specified in the operand. Operands 0-7 are the output register. The RAM is accessed by the upper 8 operands (8-F). |
STOC | 9 | Output | Same as STO, but stores the complement of RR. |
IEN | A | Input | Sets the IEN flag to the input specified in the operand. |
OEN | B | Input | Sets the OEN flag to the input specified in the operand. |
JMP | C | Jump Amount | Jumps over an amount of bytes (in the ROM) determined by the operand. Operands 0-7 will add one to the operand, then jump backwards 4x that amount. Operands 8-F will subtract 7 from the operand, then jump forwards 4x that amount. |
RTN | D | No | Jumps over the instruction following itself. |
SKZ | E | No | Skips the next instruction if RR is zero. |
NOP | F | No | Does nothing. (Waits) |
Programming
Infinite Honking Device
Alright, so your brain has exploded from that load of information and you're wondering How the hell am I supposed to use any of this?!. It's actually not that complicated if you put it together piece by piece. Before you begin programming, set yourself a goal for what you want your device to accomplish. In this case, we want an infinite honking machine. We already know how to make the honks by creating a bike-horn/signaller assembly. We set the signaller any frequency we want, say 146.7, and any code, say 25. We'll have a wifi component activate the various honker assemblies by sending it the signal "code=25&message=ACTIVATE" over and over again. Make sure to enable forward all in the wifi component. The issue is, we need a way to loop this signal. A relay component with the send signal set to "code=25&message=ACTIVATE" can deal with the message part. Now, we need to program our control unit. We'll start by writing in assembly, by using the mnemonics themselves to represent opcodes. (From ; to the end of the line is a comment)
OEN 0 ;enable the output because RR is zero, so input 1 (!RR) is 1 STO 0 ;store the 0 from RR in output 1, so the unit outputs the signal "0:0"
Notice how even when we write 0 to an output, it still creates a signal, in this case 0:0 meaning output 0, data 0. Remember the Control Unit loops its program. Now we have to compile our program (yes, by hand) so the Control Unit can read it. We do this by looking up each opcode in the table, then writing down the hex digit for it, then the operand beside it. Now our program looks like this:
B080
B is the hex for OEN, 0 is its operand, 8 is the hex for STO, and 0 is its operand. Now our program can be loaded into the Control Unit. Toggle the unit on with a multitool, and watch as the signal 0:0 is repeated over and over again forever!
Improved Honking Device
There is one major flaw in this system. There is no way of enabling or disabling it remotely! That is the goal for the improved honking device. We'll designate input 1 and 2 on the Control Unit as our on/off switch. We have to send either a 1 to input 1 to turn it on and 1 to input 2 to turn it off. I'll leave it up to you to make a remote control to do this (it can be a signaller, a PDA, a button, or more), I will focus on the programming of the Control Unit itself.
AND 0 ;ANDs RR with input 0 (!RR), which always results in 0 (set RR to 0) IEN 0 ;RR is 0, so this will set IEN to 1 OEN 0 ;same thing for OEN LD 1 ;loads input 1 into RR (this clears it) SKZ STO 8 ;store it in RAM 1 if it's 1 LD 2 ;load off input SKZ STOC 8 ;if off input is on, put 0 in RAM 1 LD 8 ;get RAM 1 SKZ STO 0 ;output it if RAM 1 is on
Now, we compile it:
30A0B011E08812E09818E080
That's it! It may seem complicated, but when you write the assembly first, it isn't so bad.