Compare commits

...

15 Commits

23 changed files with 253 additions and 131 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
*.rom
/build
/b
/o

17
README
View File

@ -1,17 +0,0 @@
kip fantasy computer based on the kmx20
kmx20 mini 32-bit stack processor
requires c11, meson, ninja, sdl2
build meson compile -C b
test meson test -C b
usage ./b/kip [ROM FILE]
./b/as [ASM FILE] [ROM FILE]
layout ./kip* -- sdl2-based emulator
./as -- assembler
./d/ -- documentation
./t/ -- tests
./x/ -- examples
patches, questions, comments welcome: kitty+kip@piapiac.org
or you can open issues & pull requests: http://git.vern.cc/kcp/kip
browse the updated git repository: https://git.cro.wtf/kip.git
more examples: https://git.cro.wtf/kcp/mow.git

46
README.md Normal file
View File

@ -0,0 +1,46 @@
# kip computer
The kip is a fantasy computer based on the 32-bit kmx20 stack processor. This repository holds an SDL2-based C11 emulator.
## Build
### Requirements
* A C11 Compiler
* Meson + Ninja
* Sdl2
* The source tree
### Acquiring the source
Kip is hosted on git at [git.cro.wtf](https://git.cro.wtf/kip.git/), and is mirrored at [git.vern.cc](http://git.vern.cc/kcp/kip).
### Building
```
$ git clone https://git.cro.wtf/kip.git
$ cd kip
$ meson setup b
$ meson compile -C b
$ meson test -C b # optional, just run tests
```
## Repository layout
* `./kip*` - sdl2-based emulator source files
* `./as.c` - assembler source
* `./d/` - documentation
* `./t/` - tests
* `./v/` - vim support
* `./w/` - doc -> html -> www
* `./x/` - examples
You can find more examples of code [git.cro.wtf/kcp/mow.git](https://git.cro.wtf/mow.git)
## Contributing
Patches, questions, comments welcome: [kitty+kip@piapiac.org](mailto:kitty+kip@piapiac.org)
You can open issues and pull requests at [git.vern.cc/kcp/kip](http://git.vern.cc/kcp/kip)
Pull the most updated git repository from [git.cro.wtf/kip.git](https://git.cro.wtf/kip.git)

View File

@ -1,31 +1,30 @@
---
kip manual: as
title: kip manual - as
...
# Kip kmx20 Assembler
# kip kmx20 assembler
This document is heavily incomplete; it is work-in-progress effort.
## Syntax
# Syntax
## Tokens
### Tokens
Tokens are generally split by whitespace.
## Colours
### Colours
A token has a type, or 'colour' based on its first character.
| Char | Description |
|------|-------------|
|`{` | Comment. All text until the next `}` is ignored. |
|`"` | String literal. This is included in the resultant binary literally. *(e.g. "meow" puts the string "meow" in the output binary)* |
|`#` | Hexadecimal literal. The amount of bytes included in the output binary is either 1, 2, or 4 based on length. Numbers are little-endian. *(e.g. #00 outputs a byte, #0000 half a word, and #00000000 a full word)* |
|`:` | Label definition |
|`@` | 32-bit reference to label *(e.g. `pw @label ju` would jump to the label defined by `:label`)* |
|`^` | 8-bit relative reference to label *(e.g. `pr ^label ju` would jump to the label defined by :label)* |
|`!` | Macro definition. words that follow are included in macro until `;` *(e.g. `!meow #0000 ;`)* |
|```` | Macro reference. *(e.g. `meow` (from above) will now output 2 bytes of `0s`)* |
|`-` | Assembler built-in. these can take some amount of arguments.
| Char | Description |
|:------|:------------------------------------------------------|
|`{` | Comment. All text until the next `}` is ignored. |
|`"` | String literal. This is included in the resultant binary literally. *(e.g. "meow" puts the string "meow" in the output binary)* |
|`#` | Hexadecimal literal. The amount of bytes included in the output binary is either 1, 2, or 4 based on length. Numbers are little-endian. *(e.g. #00 outputs a byte, #0000 half a word, and #00000000 a full word)* |
|`:` | Label definition |
|`@` | 32-bit reference to label *(e.g. `pw @label ju` would jump to the label defined by `:label`)* |
|`^` | 8-bit relative reference to label *(e.g. `pr ^label ju` would jump to the label defined by :label)* |
|`!` | Macro definition. words that follow are included in macro until `;` *(e.g. `!meow #0000 ;`)* |
|`` ` ``| Macro reference. *(e.g. `meow` (from above) will now output 2 bytes of `0s`)* |
|`-` | Assembler built-in. these can take some amount of arguments.
Without colour, it is treated as an instruction. See [kmx20](./kmx20.md) for ISA documentation.
Instructions can additionally have the following prefixes, which may affect the resulting opcode.
@ -33,7 +32,7 @@ Instructions can additionally have the following prefixes, which may affect the
- `~` F flag (flip stack manipulations from data <-> return stacks)
- `$` K flag (keep lhs on rhs)
## Builtins
### Builtins
- `-org #` Sets the origin for labels. The first -org is the entry point of the output file. Output ROMs are inserted at #100 in the CPU's memory, so you should generally start a program off with -org #0100.
- `-res #` Reserves some bytes in the output binary. Basically same as -org but relative to current address.

View File

@ -1,17 +1,25 @@
---
title: kip manual: kip computer
title: kip manual - kip computer
...
# Kip Computer
# kip computer
The kip is a fantasy computer based on the 32-bit [kmx20](./kmx20.md) stack processor.
It currently runs no operating system.
It ships with [kip-as](./kip-as.md) for assembling to kmx20 machine code.
To run kip programs, you will need a kip emulator. Check the [git repository](https://git.cro.wtf/kip.git)
for one written in C and SDL2.
## Devices
For now, see `../kip-io.def` in the git repository. Extensive documentation here is TODO
For now, see `../kip-io.def` in the git repository. Extensive documentation here is TODO!
## Interrupt Vector Table
| Port | Description |
|------|--------------------|
|:-----|:-------------------|
|`0x00`| Display VSYNC |
|`0x04`| Mouse Down |
|`0x08`| Mouse Up |

View File

@ -1,101 +1,105 @@
---
title: kip manual: kmx20
title: kip manual - kmx20
...
# kmx20 cpu
This document is heavily incomplete. It is a work-in-progress effort.
## Hardware registers
The kmx20 has 3 hardware registers,
- `ip` `Word` Instruction pointer
- `dp` `Byte` Data Stack Pointer
- `rp` `Byte` Return Stack Pointer
| Name | Size | Description |
|:-----|:-----|:-----------------------|
| `ip` | Word | Instruction pointer |
| `dp` | Byte | Data Stack Pointer |
| `rp` | Byte | Return Stack Pointer |
## Busses
The kmx20 has 2 data busses.
- mem
- Memory bus
- Byte-addressed
- Where data is to be read and writ
```
+---0x00000---+ <-- Interrupt Vector Table
| (rwx) |
+---0x00100---+ <-- Boot
| (rwx) | This is where the CPU resets to,
| | and where the emulator puts
| | loaded ROMs.
. .
. .
. .
| |
+---0x40000---+ <-- Data Stack
| (rw-) | Word-addressed by `dp
+---0x40400---+ <-- Return Stack
| (rw-) | Word-addressed by `rp
+---0x40800---+
```
- io
- Input/Output Bus
- Word-addressed
- Peripherals are directly connected to this bus
- See [kip.md](./kip.md) for kip computer i/o
- mem
- Memory bus
- Byte-addressed
- Where data is to be read and writ
- Interrupt Vector Table starts at address `#00000`
- CPU resets to address `#00100`
- Data stack lives in mem at `#40000`
- Word-addressed by `dp`
- Return stack lives in mem at `#40400`
- Word-addressed by `rp`
```
+---0x00000---+ <-- IVT
| (rwx) |
+---0x00100---+ <-- Boot
| (rwx) |
| |
| |
. .
. .
. .
| |
+---0x40000---+ <-- Data Stack
| (rw-) |
+---0x40400---+ <-- Return Stack
| (rw-) |
+---0x40800---+
```
- io
- Input/Output Bus
- Word-addressed
- Peripherals are directly connected to this bus
- See [kip.md](./kip.md) for kip computer i/o
## Instructions
Instructions take 1 byte in memory. Each binary digit corresponds to
Instructions take 1 byte in memory. If you looked at an instructions binary representation with letters: `0KFOOOOO`
```
XFOOOOOO
|||O: Opcode
||F: Flip return and data stacks
|| (eg 01000010 will put the next byte in memory onto the return stack)
|K: Keep left hand operands
| (eg (a--n) below becomes (a--a n))
|X: Unused
```
- `0` is unused
- `K` if set will keep *all* left hand operands. *(e.g. `(a -- n)` becomes `(a -- a n)`)*
- `F` if set will flip return and data stacks. *(e.g. `pb` with `F` puts the next byte on the return stack.)*
- `O` is the 5-bit opcode. See the table below.
## Opcodes
| Op | Stack effect | Description |
|----|--------------|-----------------------------------------------------------------------------|
|`np`|`--` | no-op |
|`ex`|`--` | halt execution |
|`pb`|`--n` | puts the next byte (8 bits) in memory onto the stack |
|`ph`|`--n` | ^ same but next half-word (16 bits) |
|`pw`|`--n` | ^ same but next word (32 bits) |
|`pr`|`--n` | puts ip+the next byte plus onto the stack |
|`fb`|`a--n` | fetches a byte from address \`a and puts it onto the stack |
|`fh`|`a--n` | ^ same but with half-word |
|`fw`|`a--n` | ^ same but with word |
|`mb`|`n a--` | truncate stack item \`n into a byte and put it in memory address \`a |
|`mh`|`n a--` | ^ same but with half-word |
|`mw`|`n a--` | ^ same but with word |
|`io`|`n p--` | move cell \`n to io port \`p |
|`ii`|`p--n` | gets cell from io port \`p and pushes it onto the stack |
|`ss`|`n-~n` | move cell from data stack to return stack |
|`dr`|`n--` | drop item from data stack |
|`sw`|`n m--m n` | swap items |
|`du`|`n--n n` | duplicate item on data stack |
|`ov`|`n m--n m n` | bring second item on data stack over |
|`ad`|`n m--n+m` | add |
|`su`|`n m--n-m` | subtract |
|`mu`|`n m--n*m` | multiply |
|`di`|`n m--n/m n%m`| div rem |
|`an`|`n m--n&m` | bitwise and |
|`or`|`n m--n|m` | bitwise or |
|`xr`|`n m--n^m` | bitwise xor |
|`sl`|`n m--n<<m` | bitwise shift left |
|`sr`|`n m--n>>m` | bitwise shift right |
|`sa`|`n m--n>>>m` | bitwise arithmetic shift right |
|`eq`|`n m--n==m` | logical equals |
|`lt`|`n m--n<m` | logical less than |
|`gt`|`n m--n>m` | logical greater than |
|`no`|`n--!n` | logical not |
|`ju`|`a--` | jump to address `a |
|`jc`|`n a--` | jump to address `a if `n!=0 |
|`ca`|`a-~r` | push ip onto return stack, then jump to address `a |
|`cc`|`n a-~r` | push ip onto return stack and jump to address `a if `n!=0 |
| Op | Stack effect | Description |
|:---|:-------------------|:----------------------------------------------------------------------------|
|`np`|`--` | no-op |
|`ex`|`--` | halt execution |
|`pb`|`--n` | puts the next byte (8 bits) in memory onto the stack |
|`ph`|`--n` | ^ same but next half-word (16 bits) |
|`pw`|`--n` | ^ same but next word (32 bits) |
|`pr`|`--n` | puts ip+the next byte plus onto the stack |
|`fb`|`a--n` | fetches a byte from address `a` and puts it onto the stack |
|`fh`|`a--n` | ^ same but with half-word |
|`fw`|`a--n` | ^ same but with word |
|`mb`|`n a--` | truncate stack item `n` into a byte and put it in memory address \`a |
|`mh`|`n a--` | ^ same but with half-word |
|`mw`|`n a--` | ^ same but with word |
|`io`|`n p--` | move cell `n` to io port `p` |
|`ii`|`p--n` | gets cell from io port `p` and pushes it onto the stack |
|`ss`|`n-~n` | move cell from data stack to return stack |
|`dr`|`n--` | drop item from data stack |
|`sw`|`n m--m n` | swap items |
|`du`|`n--n n` | duplicate item on data stack |
|`ov`|`n m--n m n` | bring second item on data stack over |
|`ad`|`n m--n+m` | add |
|`su`|`n m--n-m` | subtract |
|`mu`|`n m--n*m` | multiply |
|`di`|`n m--n/m n%m` | div rem |
|`an`|`n m--n&m` | bitwise and |
|`or`|`n m--n|m` | bitwise or |
|`xr`|`n m--n^m` | bitwise xor |
|`sl`|`n m--n<<m` | bitwise shift left |
|`sr`|`n m--n>>m` | bitwise shift right |
|`sa`|`n m--n>>>m` | bitwise arithmetic shift right |
|`eq`|`n m--n==m` | logical equals |
|`lt`|`n m--n<m` | logical less than |
|`gt`|`n m--n>m` | logical greater than |
|`no`|`n--!n` | logical not |
|`ju`|`a--` | jump to address `a` |
|`jc`|`n a--` | jump to address `a` if `n!=0` |
|`ca`|`a-~r` | push ip onto return stack, then jump to address `a` |
|`cc`|`n a-~r` | push ip onto return stack and jump to address `a` if `n!=0` |

1
v/ftdetect/x20.vim Normal file
View File

@ -0,0 +1 @@
au BufRead,BufNewFile *.x20 setfiletype x20

8
v/ftplugin/x20.vim Normal file
View File

@ -0,0 +1,8 @@
if exists("b:did_ftplugin")
finish
endif
setlocal commentstring={%s}
setlocal matchpairs={:},::;,!:;
let b:did_ftplugin = 1

15
v/syntax/x20.vim Normal file
View File

@ -0,0 +1,15 @@
syn match x20com "{.*}"
syn match x20fun "-\S*"
syn match x20num "#\S*\|@\S*\|\^\S*"
syn match x20pun ":\S*\|!\S*\|;"
syn region x20str matchgroup=x20str start=/"/ end=/"/
syn sync fromstart
hi link x20com comment
hi link x20fun type
hi link x20num number
hi link x20pun delimiter
hi link x20str string
let b:current_syntax='x20'

36
w/Makefile Normal file
View File

@ -0,0 +1,36 @@
OUT?=../o
IN?=../d
.SUFFIXES: .md .html
all: kip.html kip-as.html kmx20.html ${OUT}/template.html ${OUT}/style.css
cp ${OUT}/kip.html ${OUT}/index.html
kip.html: ${IN}/kip.md
kip-as.html: ${IN}/kip-as.md
kmx20.html: ${IN}/kmx20.md
${OUT}/template.html: template.html
cp template.html ${OUT}/template.html
${OUT}/style.css: style.css
cp style.css ${OUT}/style.css
deploy: all
scp -r ${OUT}/* kcp@cro.wtf:www/kip
clean:
rm -rf \
${OUT}/index.html \
${OUT}/kip.html \
${OUT}/kip-as.html \
${OUT}/kmx20.html \
${OUT}/template.html \
${OUT}/style.css
.md.html:
mkdir -p ${OUT}
pandoc \
-t html5 \
--template=template.html \
--lua-filter=./urls-md-to-html.lua \
-f markdown+pipe_tables $< \
-o ${OUT}/$@

4
w/style.css Normal file
View File

@ -0,0 +1,4 @@
body { font-family: sans-serif; }
code { padding: 0 .2em 0 .2em; display: inline-block; background-color: #eeeeee; border: 1px solid; }
table { padding: .4em; border: 1px solid; }

13
w/template.html Normal file
View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=yes"/>
<title>$title$</title>
<link href="style.css" rel="stylesheet"/>
</head>
<body>
<p><i>(<a href="./index.html">back home</a>)</i><p>
$body$
</body>
</html>

4
w/urls-md-to-html.lua Normal file
View File

@ -0,0 +1,4 @@
function Link(el)
el.target = string.gsub(el.target, "%.md", ".html")
return el
end

View File

@ -1,4 +1,4 @@
-inc "x/inc/dev.kmm"
-inc "x/inc/dev.x20"
-org #0100
:entry
pw #00000000 `disp/pal io

View File

@ -1,5 +1,5 @@
-inc "x/inc/dev.kmm"
-inc "x/inc/a.kmm"
-inc "x/inc/dev.x20"
-inc "x/inc/a.x20"
-org #0100
:entry
@ -9,8 +9,8 @@
ex
;
:s0 -inc "x/lib/s0.kmm" ;
:g -inc "x/lib/graphics.kmm" ;
:s0 -inc "x/lib/s0.x20 " ;
:g -inc "x/lib/graphics.x20" ;
:data
:hello-world "hello, world!!" #00 ;

View File

@ -1,5 +1,5 @@
-inc "x/inc/dev.kmm"
-inc "x/inc/a.kmm"
-inc "x/inc/dev.x20"
-inc "x/inc/a.x20"
-org #100
:entry
pr ^keeb-down `ivt/keeb/down mw
@ -11,8 +11,8 @@
:keeb-act pw @t/puts ca `keeb ii pr ^put ca pb `nl `term/0 io ~ju ;
:ascii? du pb #80 lt sw pb #1f gt an ~ju ;
:put du pr ^ascii? ca pr ^ascii jc dr ~ju :ascii `term/0 io ; ~ju ;
:s0 -inc "x/lib/s0.kmm" ;
:t -inc "x/lib/term.kmm" ;
:s0 -inc "x/lib/s0.x20" ;
:t -inc "x/lib/term.x20" ;
:data
:s0
:keeb-down "keyboard down: " #00 ;

View File

@ -1,4 +1,4 @@
-inc "x/inc/dev.kmm"
-inc "x/inc/dev.x20"
-org #0100
:entry
pr ^cursormove `ivt/disp/vsync mw