https://github.com/3shain/jscpu
Build a CPU out of logic gate in TypeScript
https://github.com/3shain/jscpu
Last synced: over 1 year ago
JSON representation
Build a CPU out of logic gate in TypeScript
- Host: GitHub
- URL: https://github.com/3shain/jscpu
- Owner: 3Shain
- Created: 2021-09-13T05:43:44.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2021-09-16T10:52:28.000Z (almost 5 years ago)
- Last Synced: 2025-03-28T15:54:38.257Z (over 1 year ago)
- Language: TypeScript
- Homepage: jscpu.vercel.app
- Size: 30.3 KB
- Stars: 1
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Build a CPU out of logic gate in TypeScript
It's romantic (meaning waste of time).
## How to play with it
```sh
pnpm install
cd packages/playground
pnpm exec vite
```
Then open the console.
Use `tick()` to create a clock cycle.
## Description
* 16-bits CPU. It's working.
* Up to 64KB RAM.
* 4 general purpose register. (can expand the number of them easily).
* Variable instruction cycle. (from 2 to ...)
* Variable machine code length. (from 2 to ...)
### Instructions
Current it can do:
* Copy data between immediate/register/memery
* Add/Substract
* Halt and do nothing
* Jump, w/ condition
* Stack (push,pop)
* Call/return
#### Layout
* 2*_n_ bytes
* 1st byte : instruction
* 1st bit: 8 bit mode (for instructions involving immediate/memory address)
* 2nd byte : register address
* 1st 4-bits is destination, followed by 4-bits source.
* Reg A: 0b0001
* Reg B: 0b0010
* others: immediate
Some instructions don't require register information (like JMP), so 2nd byte is not needed (directly followed by imm.)
#### References
* HALT
```jsx
0b00001111
```
* NOP
```jsx
0b00011011
```
* MOV reg imm (from imm. to register)
```jsx
0b00001000,,,
0b10001000,,
```
* MOV dst src (from register to register)
```jsx
0b00001001,
0b10001001,
```
* MOV reg mem
```jsx
0b00001010,,,
0b10001010,,,
```
* MOV mem reg
```jsx
0b00001011,,,
0b10001011,,,
```
* ADD dst src : add accumulator (A register) with [source] (register) and store the result in [dest] (register)
```jsx
0b00000100,
0b10000100,
```
* SUB dst src : substract: similar to add.
```jsx
0b00000101,
0b10000101,
```
* INC dst src
```jsx
0b00001100,
```
* DEC dst src
```jsx
0b00001101,
```
* JMP : unconditional jump
```jsx
0b00010100,,
```
* JZ : jump if zero
```jsx
0b00010110,,
```
> Flag zero: Avaliable after ADD/SUB/INC/DEC
* JNZ : jump if not zero
```jsx
0b00010111,,
```
* CALL reg
```jsx
0b00011000,<0000|source-register-addr>
```
* RET
```jsx
0b00011001
```
* PUSH reg
```jsx
0b00001101,<0000|source-register-addr>
0b10001101,<0000|source-register-addr>
```
* POP reg
```jsx
0b00001101,
0b10001101,
```
### CALL/RET
## TODO
* More instructions
* ALU related
* Interrupt
* Keyboard
* Timer
* A display (that's why I'm testing in browser)