per
Veteran Member
Some time ago, I was talking about making my own CPU out of simple TTL logics. Now I actually have gotten around making one. It is not the easiest processor to program, but it should be possible to do most stuff with the instruction set I have implemented.
There is a lot of technical information below, but you don't ned to read it unless you are curious. There is a small non-technical pharagraph at the end.
The memory is organized quite odd. for each address, there is 16 bits (AKA: 16-bit words). However, the CPU is 8-bit, and everything within the CPU happens 8-bit at a time. The instruction is allways in the lower 8 bits of a word, and the high 8-bits is to be used as imed. data for that instruction, if the instruction says so. There is seperate functions to write/read to/from the High 8-bits and the Low 8-bits. There is also instructions for I/O.
The use of registers are also quite limited. All registers have their function, and there are no register for just storing a value. All operands in an instruction are actually defined as registers, even the ALU.
It is to note that all ALU functions have to be done quite manually; the ALU mode may be changed/set, data may be fed into the ALU input registers, the result must then be read from the ALU output register and then processed. It's quite flexible, but it uses more code to do less work.
There is one flag used when the ALU is in addition or subtraction mode. This is an overflow/carry flag, and it can be used with conditional instructions. There is in fact only 128 instructions, but all of them got an unconditional version and a conditional version. The unconditional ones are allways being executed, while the conditional ones are only being executed if the flag is set. There is also instructions to lock/unlock the flag in cause the ALU has to be used within blocks of conditional code.
There are no instructions for jumps, but jumps can be achieved by writing directly to the P register. By using the ALU and the conditional instructions, conditional jump and left-rotate operations are possible to achieve.
Last, the P register will only be able to address 256 instructions. Since this is by far from doing anything productive, I plan to divide this into four "windows" to a bigger memory pool. Changing the pointers will be done with I/O and some hardware on the memory board, whitch I haven't designed yet.
Registers:
ALU modes:
End of technincal stuff.
I estimate the CPU board to end up at about more or less 50 IC's, and the idea is to fit it on one board. Then there will be a board for RAM and ROM, and eventually there will be a board with serial I/O. For all this, I plan to make a front pannel connected to a bus with four slots. I should be able to disable each of the four slots by switches on the front panel, and I would also be able to controll the bus with the front panel.
As of price, I expect it to be expensive if I ever decides to make it. I don't know, but with four 1-square-foot boards and hundreds of components it can easily cost several hundred $. Maybe I'll be crazy enough one day...
There is a lot of technical information below, but you don't ned to read it unless you are curious. There is a small non-technical pharagraph at the end.
The memory is organized quite odd. for each address, there is 16 bits (AKA: 16-bit words). However, the CPU is 8-bit, and everything within the CPU happens 8-bit at a time. The instruction is allways in the lower 8 bits of a word, and the high 8-bits is to be used as imed. data for that instruction, if the instruction says so. There is seperate functions to write/read to/from the High 8-bits and the Low 8-bits. There is also instructions for I/O.
The use of registers are also quite limited. All registers have their function, and there are no register for just storing a value. All operands in an instruction are actually defined as registers, even the ALU.
It is to note that all ALU functions have to be done quite manually; the ALU mode may be changed/set, data may be fed into the ALU input registers, the result must then be read from the ALU output register and then processed. It's quite flexible, but it uses more code to do less work.
There is one flag used when the ALU is in addition or subtraction mode. This is an overflow/carry flag, and it can be used with conditional instructions. There is in fact only 128 instructions, but all of them got an unconditional version and a conditional version. The unconditional ones are allways being executed, while the conditional ones are only being executed if the flag is set. There is also instructions to lock/unlock the flag in cause the ALU has to be used within blocks of conditional code.
There are no instructions for jumps, but jumps can be achieved by writing directly to the P register. By using the ALU and the conditional instructions, conditional jump and left-rotate operations are possible to achieve.
Last, the P register will only be able to address 256 instructions. Since this is by far from doing anything productive, I plan to divide this into four "windows" to a bigger memory pool. Changing the pointers will be done with I/O and some hardware on the memory board, whitch I haven't designed yet.
Registers:
- A = Accumulator. Main input to the ALU. Can be written to, and the value stored can also be read as it is. It's value is constantly fed into the ALU.
- AL = Temporary ALU register. Secondary input to the ALU. Can be written to, but when read from, the result from the actual ALU operation is being returned.
- D = Data output register. This register serve as a buffer for the byte being written to memory durning a memory write instruction, and in out instructions too. A value can however be written to it and read as written, but it is to note that it will automaticly be updated if any memory Write/Out instructions occours.
- AD = Address register. All memory read/write in/out instructions uses this register for the address/port to read/write in/out from/to. This register must be set in advance of the read/write in/out instruction, and the value can also be read back.
- P = Instruction pointer. Points to the current instruction, and it is increased after every instruction is done executing, even after writes to this register. Can be written to in order to achieve jumps, and can also be read (usefull for indirect jumps).
- IL = Low input register. This is the lower 8 bits of the word making up the instruction. It can only be read, as all writes are redirected to the OL register
- IH = High input register. This is the same as IL, but with the upper 8 bits of the instruction word instead of the 8 lower bits. Writes are also redirected to OH, not OL.
- OL = Low output register. Lower 8 bits of the output register. The output register are a write-only register to a data-bus that is constantly holding the data of the output registers. Other cards can use this value for a various functions, only up to the imagination of the card's creator. Al reads are redirected to IL.
- OH = High output register. The same as OL, but with the upper 8 bits instead. It's also write-only, so all reads are redirected to IH.
- NO = Nothing. Reads the value of FFh, and nothing happens durning writes.
ALU modes:
- Add(ition)
- Sub(traction)
- And
- Or
- Xor
- Nand
- Exception: Lock flag
- Exception: Unlock flag
Code:
mov regD,regS = Register regS is read and the value returned is stored in regD.
sam func. = Sets the ALU mode to func.
hlt msk. = The CPU halts, but it can be restored with the recover input lines (1-3) that are masked in the 3-bit value of msk.
out [AD],regS = Register regS is written to register D and then Out'ed to the port defined in register AD.
in regD,[AD] = The In'ed value from the port defined by register AD is written to the register regD.
sth [AD],regS = It reads register regS and stores it in register D, and then stores it into the high 8 bits of the word pointed to by AD.
stl [AD],regS = It reads register regS and stores it in register D, and then stores it into the low 8 bits of the word pointed to by AD.
rdh regD,[AD] = The high 8 bits of the word pointed to by AD are read and stored in register regD.
rdl regD,[AD] = The low 8 bits of the word pointed to by AD are read and stored in register regD.
movc regD,regS = If the flag is set, then register regS is read and the value returned is stored in regD.
samc func. = If the flag is set, then sets the ALU mode to func.
hltc msk. = If the flag is set, then the CPU halts, but it can be restored with the recover input lines (1-3) that are masked in the 3-bit value of msk.
outc [AD],regS = If the flag is set, then register regS is written to register D and then Out'ed to the port defined in register AD.
inc regD,[AD] = If the flag is set, then the In'ed value from the port defined by register AD is written to the register regD.
sthc [AD],regS = If the flag is set, then it reads register regS and stores it in register D, and then stores it into the high 8 bits of the word pointed to by AD.
stlc [AD],regS = If the flag is set, then it reads register regS and stores it in register D, and then stores it into the low 8 bits of the word pointed to by AD.
rdhc regD,[AD] = If the flg is set, then the high 8 bits of the word pointed to by AD are read and stored in register regD.
rdlc regD,[AD] = If the flag is set, then the low 8 bits of the word pointed to by AD are read and stored in register regD.
End of technincal stuff.
I estimate the CPU board to end up at about more or less 50 IC's, and the idea is to fit it on one board. Then there will be a board for RAM and ROM, and eventually there will be a board with serial I/O. For all this, I plan to make a front pannel connected to a bus with four slots. I should be able to disable each of the four slots by switches on the front panel, and I would also be able to controll the bus with the front panel.
As of price, I expect it to be expensive if I ever decides to make it. I don't know, but with four 1-square-foot boards and hundreds of components it can easily cost several hundred $. Maybe I'll be crazy enough one day...