├── .gitattributes
├── .github
└── workflows
│ ├── make-docs.yml
│ └── nightly.yml
├── .gitignore
├── .gitmodules
├── .vscode
├── launch.json
└── settings.json
├── .zpm
├── pkgs.zig
└── project.zpm
├── LICENSE
├── README.md
├── apps
├── ascii-printer
│ └── main.asm
├── ashet-bios
│ ├── main.asm
│ └── main.old.asm
├── hello-world
│ └── main.asm
├── library
│ ├── ascii.inc
│ ├── ashet
│ │ ├── io-page.inc
│ │ └── syscalls.inc
│ └── bios.inc
├── minimal-firmware
│ └── firmware.asm
├── minimal
│ └── main.asm
└── web-firmware
│ ├── demo.asm
│ └── main.asm
├── build.zig
├── castle.bin
├── documentation
├── app-notes
│ ├── AN000 - Understanding the Instruction Set.md
│ ├── AN001 - The SPU Assembly Language.md
│ ├── AN002 - Standard Calling Convention.md
│ └── AN003 - Writing efficient code.md
├── design
│ ├── spu-mk-ii-logo-large.png
│ ├── spu-mk-ii-logo-small.png
│ ├── spu-mk-ii-logo.svg
│ └── spu-mk-ii-logo.txt
├── figures
│ ├── fr.svg
│ ├── genbits.lua
│ ├── instruction.svg
│ └── ir.svg
├── index.md
├── livedemo.md
├── manuals
│ ├── ashet-emulator.md
│ ├── assembler.md
│ ├── basic-emulator.md
│ └── disassembler.md
├── metadata
│ ├── an000.yaml
│ ├── an001.yaml
│ ├── an002.yaml
│ ├── an003.yaml
│ ├── ashet.yaml
│ ├── isa.yaml
│ ├── mmu.yaml
│ ├── vchip.yaml
│ └── vga.yaml
├── os
│ ├── boot.md
│ ├── index.md
│ ├── syscalls.md
│ └── ui.uxf
├── specs
│ ├── ashet-register-space.md
│ ├── ashet.md
│ ├── dma.md
│ ├── eth.md
│ ├── ide.md
│ ├── irq.md
│ ├── joystick.md
│ ├── mmu.md
│ ├── parport.md
│ ├── pcm.md
│ ├── ps2.md
│ ├── rtc.md
│ ├── spu-mark-ii.md
│ ├── timer.md
│ ├── uart.md
│ └── vga.md
└── website
│ ├── downloads.md
│ ├── imprint.htm
│ └── privacy.htm
├── mkdocs.yml
├── research-chamber
├── .gitignore
├── build.zig
├── libs
│ └── lpc1768
│ │ └── lpc1768.zig
└── src
│ ├── boot.zig
│ ├── linker.ld
│ └── main.zig
├── resources
├── castle.bit
├── castle.pcx
├── example.bit
├── example.png
└── keen.pcx
├── scratchpad
└── scratch.asm
├── soc
├── architecture.uxf
└── vhdl
│ ├── ._Real_._Math_.vhd
│ ├── .floorplanner.ini
│ ├── .gitignore
│ ├── .ncd_editor.ini
│ ├── .setting.ini
│ ├── .spread_sheet.ini
│ ├── .spreadsheet_view.ini
│ ├── env.sh
│ ├── execve-trace.txt
│ ├── firmware.mem
│ ├── ip-cores
│ ├── ._Real_._Math_.vhd
│ ├── dist_boot_rom.edn
│ ├── dist_boot_rom.ipx
│ ├── dist_boot_rom.jhd
│ ├── dist_boot_rom.lpc
│ ├── dist_boot_rom.naf
│ ├── dist_boot_rom.sym
│ ├── dist_boot_rom.vhd
│ ├── dist_boot_rom_tmpl.vhd
│ ├── embedded_function_block.edn
│ ├── embedded_function_block.ipx
│ ├── embedded_function_block.jhd
│ ├── embedded_function_block.lpc
│ ├── embedded_function_block.naf
│ ├── embedded_function_block.sym
│ ├── embedded_function_block.vhd
│ ├── embedded_function_block_tmpl.vhd
│ ├── fastram_ebr.edn
│ ├── fastram_ebr.ipx
│ ├── fastram_ebr.jhd
│ ├── fastram_ebr.lpc
│ ├── fastram_ebr.naf
│ ├── fastram_ebr.sym
│ ├── fastram_ebr.vhd
│ ├── fastram_ebr_tmpl.vhd
│ ├── hw_mult_16.edn
│ ├── hw_mult_16.ipx
│ ├── hw_mult_16.jhd
│ ├── hw_mult_16.lpc
│ ├── hw_mult_16.naf
│ ├── hw_mult_16.sym
│ ├── hw_mult_16.vhd
│ ├── hw_mult_16_tmpl.vhd
│ ├── tb_boot_rom_tmpl.vhd
│ ├── tb_dist_boot_rom_tmpl.vhd
│ ├── tb_fastram_ebr_tmpl.vhd
│ ├── tb_hw_mult_16_tmpl.vhd
│ ├── tb_vga_ram_tmpl.vhd
│ ├── tb_videoram_tmpl.vhd
│ ├── vga_pll.edn
│ ├── vga_pll.ipx
│ ├── vga_pll.jhd
│ ├── vga_pll.lpc
│ ├── vga_pll.naf
│ ├── vga_pll.sym
│ ├── vga_pll.vhd
│ ├── vga_pll_tmpl.vhd
│ ├── videoram.edn
│ ├── videoram.ipx
│ ├── videoram.jhd
│ ├── videoram.lpc
│ ├── videoram.naf
│ ├── videoram.sym
│ ├── videoram.vhd
│ └── videoram_tmpl.vhd
│ ├── programmer-conf.xcf
│ ├── simu
│ ├── .gitignore
│ ├── Makefile
│ ├── ip-cores
│ │ └── fastram_ebr.vhd
│ └── spu.gtkw
│ ├── spumark2.ldf
│ ├── spumark2.lpf
│ ├── src
│ ├── builtin-rom.vhd
│ ├── cpu.vhd
│ ├── cpu_types.vhd
│ ├── debug-port-in.vhd
│ ├── debug-port-out.vhd
│ ├── fastram.vhd
│ ├── fifo.vhd
│ ├── mmu.vhd
│ ├── register-ram.vhd
│ ├── rom.vhd
│ ├── root.vhd
│ ├── serial-port.vhd
│ ├── soc.vhd
│ ├── sram-controller.vhd
│ ├── uart_receiver.vhd
│ ├── uart_sender.vhd
│ └── vga.vhd
│ └── testbench.gtkw
├── specification
├── README.md
├── device_map.lua
├── devices
│ ├── irq.lua
│ └── uart.lua
├── gen-gpio-pins.lua
├── gen-register-space.lua
├── modules
│ ├── Database.lua
│ ├── Datasheet.lua
│ └── Peripherial.lua
└── render-documents.lua
├── tasks
├── README.md
├── build-website.sh
└── run-basic-emulator.sh
├── test
├── README.md
└── include.inc
├── todo.md
├── tools
├── assembler
│ ├── main.zig
│ └── mnemonics.zig
├── bit-loader
│ ├── main.zig
│ └── pcx.zig
├── common
│ ├── spu-2.h
│ ├── spu-mk2.zig
│ └── vt100.h
├── disassembler
│ └── main.zig
├── emulator
│ ├── pc-main.zig
│ ├── shared.zig
│ └── web-main.zig
├── hex2bin
│ └── main.zig
└── vscode-ext
│ ├── .eslintrc.json
│ ├── .gitignore
│ ├── .vscodeignore
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── language-configuration.json
│ ├── out
│ ├── main.js
│ └── main.js.map
│ ├── package-lock.json
│ ├── package.json
│ ├── render-mnemonics.zig
│ ├── src
│ ├── extension.js
│ └── mnemonics.js
│ ├── syntaxes
│ └── asm.tmLanguage.json
│ ├── update-mnemonics-js.sh
│ └── vsc-extension-quickstart.md
└── website
├── Makefile
├── livedemo.js
├── xterm
├── xterm.css
└── xterm.js
└── zip.py
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.zig text=auto eol=lf
2 |
--------------------------------------------------------------------------------
/.github/workflows/make-docs.yml:
--------------------------------------------------------------------------------
1 | name: Autogenerate Docs
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 |
7 | jobs:
8 | build:
9 | runs-on: ubuntu-latest
10 |
11 | steps:
12 | - uses: actions/checkout@v2
13 | with:
14 | submodules: "recursive"
15 |
16 | - name: Setup Python
17 | uses: actions/setup-python@v1
18 | with:
19 | python-version: '3.7'
20 | architecture: 'x64'
21 |
22 | - name: Install dependencies
23 | run: |
24 | python3 -m pip install --upgrade pip # install pip
25 | python3 -m pip install mkdocs # install mkdocs
26 | python3 -m pip install mkdocs-material # install material theme
27 |
28 | - name: Setup Zig
29 | uses: goto-bus-stop/setup-zig@v1
30 | with:
31 | version: master
32 |
33 | - name: Compile wasm emulator
34 | run: |
35 | mkdir -p zig-out/bin
36 | mkdir -p zig-out/firmware
37 | zig build wasm
38 |
39 | - name: Render site
40 | run: mkdocs build
41 |
42 | - name: Add static files
43 | run: cp -r website/* website-out/livedemo/
44 |
45 | - name: Add emulator
46 | run: cp zig-out/lib/emulator.wasm website-out/livedemo/emulator.wasm
47 |
48 | # - name: Deploy to Server
49 | # uses: easingthemes/ssh-deploy@v2.1.1
50 | # env:
51 | # SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_KEY }}
52 | # ARGS: "-rltgoDzvO --delete"
53 | # SOURCE: "website-out/"
54 | # REMOTE_HOST: ${{ secrets.DEPLOY_HOST }}
55 | # REMOTE_USER: ${{ secrets.DEPLOY_USERNAME }}
56 | # TARGET: "/home/${{ secrets.DEPLOY_USERNAME }}/website"
57 |
58 |
--------------------------------------------------------------------------------
/.github/workflows/nightly.yml:
--------------------------------------------------------------------------------
1 | name: Continuous Build
2 |
3 | on:
4 | push:
5 | branches: [master]
6 | pull_request:
7 | branches: [master]
8 | schedule:
9 | - cron: "0 5 * * *" # run at 5 AM UTC
10 |
11 | jobs:
12 | build-linux:
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - uses: actions/checkout@v2
17 | with:
18 | submodules: "recursive"
19 |
20 | - name: Install dependencies
21 | run: |
22 | sudo apt-get update
23 | sudo apt-get install --fix-missing libsdl2-dev libsdl2-image-dev
24 |
25 | - name: Setup Zig
26 | uses: goto-bus-stop/setup-zig@v1
27 | with:
28 | version: master
29 |
30 | - name: Build all software
31 | run: |
32 | mkdir -p zig-out/bin
33 | mkdir -p zig-out/firmware
34 | zig build install
35 |
36 | - name: Run Testsuite
37 | run: zig build test
38 |
39 | - name: Build firmware
40 | run: zig build firmware
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.o
2 | *.elf
3 | *.hex
4 | *.exe
5 | zig-cache
6 | build/
7 | zig-out/
8 | website-out/
9 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "tools/modules/zig-args"]
2 | path = tools/modules/zig-args
3 | url = https://github.com/masterQ32/zig-args
4 | [submodule "tools/modules/zig-ihex"]
5 | path = tools/modules/zig-ihex
6 | url = https://github.com/MasterQ32/zig-ihex
7 | [submodule "tools/modules/zig-serial"]
8 | path = tools/modules/zig-serial
9 | url = https://github.com/MasterQ32/zig-serial
10 | [submodule "tools/modules/SDL.zig"]
11 | path = tools/modules/SDL.zig
12 | url = https://github.com/MasterQ32/SDL.zig
13 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | // A launch configuration that launches the extension inside a new window
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | {
6 | "version": "0.2.0",
7 | "configurations": [
8 | {
9 | "name": "Extension",
10 | "type": "extensionHost",
11 | "request": "launch",
12 | "args": [
13 | "--extensionDevelopmentPath=${workspaceFolder}/tools/vscode-ext",
14 | "${workspaceFolder}/apps/firmware/main.asm"
15 | ]
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.useTabStops": false
3 | }
--------------------------------------------------------------------------------
/.zpm/pkgs.zig:
--------------------------------------------------------------------------------
1 | const std = @import("std");
2 |
3 | fn pkgRoot() []const u8 {
4 | return std.fs.path.dirname(@src().file) orelse ".";
5 | }
6 |
7 | pub const pkgs = struct {
8 | pub const ihex = std.build.Pkg{
9 | .name = "ihex",
10 | .path = .{ .path = pkgRoot() ++ "/../.zpm/../tools/modules/zig-ihex/ihex.zig" },
11 | .dependencies = &[_]std.build.Pkg{},
12 | };
13 | pub const serial = std.build.Pkg{
14 | .name = "serial",
15 | .path = .{ .path = pkgRoot() ++ "/../.zpm/../tools/modules/zig-serial/serial.zig" },
16 | .dependencies = &[_]std.build.Pkg{},
17 | };
18 | pub const @"spu-mk2" = std.build.Pkg{
19 | .name = "spu-mk2",
20 | .path = .{ .path = pkgRoot() ++ "/../.zpm/../tools/common/spu-mk2.zig" },
21 | .dependencies = &[_]std.build.Pkg{},
22 | };
23 | pub const sdl2 = std.build.Pkg{
24 | .name = "sdl2",
25 | .path = .{ .path = pkgRoot() ++ "/../.zpm/../tools/modules/SDL.zig/src/lib.zig" },
26 | .dependencies = &[_]std.build.Pkg{},
27 | };
28 | pub const args = std.build.Pkg{
29 | .name = "args",
30 | .path = .{ .path = pkgRoot() ++ "/../tools/modules/zig-args/args.zig" },
31 | .dependencies = &[_]std.build.Pkg{},
32 | };
33 | };
34 |
35 | pub const imports = struct {
36 | };
37 |
--------------------------------------------------------------------------------
/.zpm/project.zpm:
--------------------------------------------------------------------------------
1 | [ihex]
2 | file = ../tools/modules/zig-ihex/ihex.zig
3 |
4 | [serial]
5 | file = ../tools/modules/zig-serial/serial.zig
6 |
7 | [spu-mk2]
8 | file = ../tools/common/spu-mk2.zig
9 |
10 | [sdl2]
11 | file = ../tools/modules/SDL.zig/src/lib.zig
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Felix "xq" Queißner
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # The SPU Mark II Project
2 |
3 | A project that focuses on the development and improvement of the *SPU Mark II* instruction
4 | set architecture.
5 |
6 | Another focus is development and creation of a concrete implementation of the CPU in VHDL
7 | as well as building a small "home computer" around an FPGA board similar to other computers
8 | from the 80ies.
9 |
10 | ## SPU Mark II
11 |
12 |
13 |
14 | The SPU Mark II is a 16 bit *RISC*ish cpu that uses the [stack machine](https://en.wikipedia.org/wiki/Stack_machine)
15 | approach instead of a [register machine](https://en.wikipedia.org/wiki/Register_machine) approach.
16 |
17 | The instrution set is documented in [documentation/isa.md](documentation/isa.md).
18 |
19 | Short feature list:
20 | - Highly flexible instruction set
21 | - Conditional instructions instead of special conditional jumps or movs
22 | - Optional hardware multiplication/division units (WIP)
23 | - Optional interrupt handling (WIP)
24 |
25 | To get a feel for the instruction set, here's a small example for a `void puts(char*str)` function:
26 |
27 | ```asm
28 | puts:
29 | bpget ; function prologue
30 | spget
31 | bpset
32 |
33 | get 2 ; fetch arg 1
34 | puts_loop:
35 | ld8 [i0:peek] [f:yes]
36 | [ex:nonzero] st8 0x4000 ; Use MMIO for text output
37 | [ex:nonzero] add 1
38 | [ex:nonzero] jmp puts_loop
39 | pop
40 |
41 | bpget ; function epilogue
42 | spset
43 | bpset
44 | ret
45 | ```
46 |
47 | ## Ashet Home Computer
48 | The *Ashet Home Computer* is a computer built on top of the *SPU Mark II* cpu and
49 | provides a small environment to use the cpu.
50 |
51 | ### Planned Features
52 | - [MMU](documentation/specs/mmu.md)
53 | - Video Output (either FBAS or VGA)
54 | - Audio Output (signed 16 bit PCM)
55 | - SD Card Storage
56 | - Keyboard Interface
57 | - Joystick Port (C64 style)
58 | - UART interface
59 |
60 | ### Current Memory Map
61 |
62 | Note that this memory map right now does not utilize the MMU, so bus width is 16 bit.
63 |
64 | | Range | Function |
65 | |---------------------|--------------------|
66 | | `0x0000` … `0x3FFF` | Builtin ROM |
67 | | `0x4000` … `0x4FFF` | UART Interface |
68 | | `0x6000` … `0x60FF` | 256 byte fast RAM |
69 | | `0x6100` … `0x7FFF` | *Unmapped* |
70 | | `0x8000` … `0xFFFF` | 32k byte slow RAM |
71 |
--------------------------------------------------------------------------------
/apps/ascii-printer/main.asm:
--------------------------------------------------------------------------------
1 | ; Example application
2 | ; Repeatedly prints the values between 0x20 and 0x7F to the
3 | ; serial port
4 |
5 | .include "../library/bios.inc"
6 |
7 | .org APP_START
8 | st UART_TXD, '!'
9 | push 'A'
10 | loop:
11 | st UART_RXD [i1:peek]
12 | add 1
13 |
14 | cmp [i0:peek] 0x80
15 | [ex:zero] push ' ' [i1:pop]
16 | [ex:zero] st UART_TXD, '\r'
17 | [ex:zero] st UART_TXD, '\n'
18 | jmp loop
19 | end:
--------------------------------------------------------------------------------
/apps/ashet-bios/main.asm:
--------------------------------------------------------------------------------
1 | .include "../library/ashet/syscalls.inc"
2 | .include "../library/ashet/io-page.inc"
3 |
4 | .org 0x0000
5 |
6 | ; interrupt table at the start of the ROM
7 | ; this must be fixed in location
8 | bios.vectors:
9 | .dw bios.entrypoint ; Reset
10 | .dw bios.interrupt.handler.nmi ; NMI
11 | .dw bios.interrupt.handler.bus ; BUS
12 | .dw 0x0000 ; RESERVED
13 | .dw bios.interrupt.handler.arith ; ARITH
14 | .dw bios.interrupt.handler.software ; SOFTWARE
15 | .dw bios.interrupt.handler.reserved ; RESERVED
16 | .dw bios.interrupt.handler.irq ; IRQ
17 |
18 | ; the bios syscall table
19 | ; this must be fixed in location, each slot in the list is 2 word wide.
20 | bios.syscall.table:
21 | jmp bios.syscall.uart.setup
22 | jmp bios.syscall.uart.status
23 | jmp bios.syscall.uart.writeChar
24 | jmp bios.syscall.uart.readChar
25 |
26 | ; we spare half of the first page for potential future syscall entries
27 | ; so we don't have to relocate everything
28 |
29 | ; so the rest of the bios code starts after the first half page
30 | .org 0x0800
31 |
32 | bios.syscall.invalid:
33 | ret
34 |
35 | ; uart.setup(mode_selector: u16, baud_selector: u16) void
36 | ; changes the UART configuration
37 | ; mode_selector:
38 | ; 0…7 => uart [ COM1, COM2, IR1, -, … ]
39 | ; 8…9 => parity [ none, even, odd, - ]
40 | ; 10…10 => stop bits [ one, two ]
41 | ; 11…13 => data width [ 5, 6, 7, 8, 9, -, -, - ]
42 | ; baud_selector:
43 | ; 0 => 1200
44 | ; 1 => 2400
45 | ; 2 => 4800
46 | ; 3 => 19200
47 | ; 4 => 38400
48 | ; 5 => 57600
49 | ; 6 => 115200
50 | ;
51 | bios.syscall.uart.setup:
52 | ; TODO: Implement this
53 | ret
54 |
55 | ; uart.status(uart: u16) u16
56 | ; returns the status of a uart
57 | ; uart:
58 | ; 0…7 => uart [ COM1, COM2, IR1, -, … ]
59 | ; :
60 | ; 0…0 => ???
61 | ;
62 | bios.syscall.uart.status:
63 | set 2, 0x0000 ; just return empty status for now
64 | ret
65 |
66 | ; uart.writeChar(uart: u16, char: u16) void
67 | ; writes a character to the uart
68 | ; uart:
69 | ; 0…7 => uart [ COM1, COM2, IR1, -, … ]
70 | ; char:
71 | ; 0…9 => max bits to send over the wire
72 | ;
73 | bios.syscall.uart.writeChar:
74 | get -2
75 | st 0x4000
76 | ret
77 |
78 | ; uart.readChar(uart: u16) u16
79 | ; writes a character to the uart
80 | ; uart:
81 | ; 0…7 => uart [ COM1, COM2, IR1, -, … ]
82 | ; :
83 | ; 0…9 => the bits received from the wire
84 | ; 15…15 => if 1, the fifo was empty.
85 | ; FR.Z => if 1, the received bits are all 0
86 | ; FR.N => if 1, the fifo was empty.
87 | ;
88 | bios.syscall.uart.readChar:
89 | set 2, 0xFFFF ; just return "empty fifo" for now
90 | ret
91 |
92 | bios.interrupt.handler.nmi:
93 | st 'N', 0x4000
94 | jmp bios.hang
95 |
96 | bios.interrupt.handler.bus:
97 | st 'B', 0x4000
98 | jmp bios.hang
99 |
100 | bios.interrupt.handler.arith:
101 | st 'A', 0x4000
102 | iret
103 |
104 | bios.interrupt.handler.software:
105 | st 'S', 0x4000
106 | iret
107 |
108 | bios.interrupt.handler.reserved:
109 | st 'R', 0x4000
110 | iret
111 |
112 | bios.interrupt.handler.irq:
113 | st 'I', 0x4000
114 | iret
115 |
116 | bios.entrypoint:
117 | TODO: Rebuild this to be correct
118 | st 0x7FE1, 0xF002 ; map I/O page to second page 0x1000
119 |
120 | ; Map some RAM in the upper half
121 | st 0x8001, 0xF010
122 | st 0x8011, 0xF012
123 | st 0x8021, 0xF014
124 | st 0x8031, 0xF016
125 | st 0x8041, 0xF018
126 | st 0x8051, 0xF01A
127 | st 0x8061, 0xF01C
128 | st 0x8071, 0xF01E ; this will unmap the MMU from 0xF000
129 |
130 | st 0x0000, 0x1000 ; map framebuffer to 0x800000
131 | st 0x0080, 0x1002
132 |
133 | st 0x8101, 0x100E ; map RAM to 0x7000…0x7FFF for stack
134 |
135 | st 0x7F21, 0x1008 ; map UART0 to 0x4000
136 |
137 | ; init a stack
138 | spset 0x8000
139 | bpset 0x8000
140 |
141 | frset 0xFFF0, ~0x00F0
142 |
143 | st 'H', 0x4000
144 | st 'e', 0x4000
145 | st 'l', 0x4000
146 | st 'l', 0x4000
147 | st 'o', 0x4000
148 | st '\r', 0x4000
149 | st '\n', 0x4000
150 |
151 | push 0x80
152 | vga_loop:
153 | push 0x8000 ; push pixel offset
154 | vga_fill:
155 |
156 | dup ; duplicate address
157 | bswap [i0:peek]
158 | xor
159 | get -1
160 | add
161 |
162 | ;.dw 0x8001 ; enable tracing
163 | st8 [i1:peek]; store color to current pixel
164 | ;.dw 0x8000 ; disable tracing
165 |
166 | add 1 [f:yes] ; increment address by one
167 | [ex:nonzero] jmp vga_fill ; if it overflowed into 0x0000, stop looping
168 | pop ; remove address
169 | add 1
170 | jmp vga_loop
171 |
172 | .org 0x0500
173 | bios.hang:
174 | frset 0x0000 ; disable all maskable interrupts
175 | jmp bios.hang
176 |
177 |
--------------------------------------------------------------------------------
/apps/hello-world/main.asm:
--------------------------------------------------------------------------------
1 | ; Example application
2 | ; Prints "Hello, World!\r\n" to the serial console
3 | ; by using ROM routines, then returns to the BIOS.
4 |
5 | .include "../library/bios.inc"
6 |
7 | .equ UART_RXD,0x1000
8 |
9 | ; Programs start at 0x8000
10 | .org APP_START
11 |
12 | ; call puts(app_msg)
13 | push app_msg
14 | ld ROM_PUTS
15 | call
16 | pop
17 |
18 | ; wait until we receive a character from serial
19 | app_loop:
20 | ld UART_RXD [f:yes]
21 | [ex:less] jmp app_loop [i1:pop]
22 | pop
23 |
24 | ret
25 |
26 | app_msg:
27 | .asciiz "\rHello, World!"
28 | .align 2
29 |
--------------------------------------------------------------------------------
/apps/library/ascii.inc:
--------------------------------------------------------------------------------
1 | ; Provides common ASCII control characters as constants
2 |
3 | .equ ASCII_NUL, 0 ; null
4 | .equ ASCII_SOH, 1 ; start of heading
5 | .equ ASCII_STX, 2 ; start of text
6 | .equ ASCII_ETX, 3 ; end of text
7 | .equ ASCII_EOT, 4 ; end of transmission
8 | .equ ASCII_ENQ, 5 ; enquiry
9 | .equ ASCII_ACK, 6 ; acknowledge
10 | .equ ASCII_BEL, 7 ; bell
11 | .equ ASCII_BS, 8 ; backsace
12 | .equ ASCII_TAB, 9 ; horizontal tabulator
13 | .equ ASCII_LF, 10 ; line feed
14 | .equ ASCII_VT, 11 ; vertical tabulator
15 | .equ ASCII_FF, 12 ; form feed
16 | .equ ASCII_CR, 13 ; carriage return
17 | .equ ASCII_SO, 14 ; shift out
18 | .equ ASCII_SI, 15 ; shift in
19 | .equ ASCII_DLE, 16 ; data link escape
20 | .equ ASCII_DC1, 17 ; device control 1
21 | .equ ASCII_DC2, 18 ; device control 2
22 | .equ ASCII_DC3, 19 ; device control 3
23 | .equ ASCII_DC4, 20 ; device control 4
24 | .equ ASCII_NAK, 21 ; negative acknowledge
25 | .equ ASCII_SYN, 22 ; synchronous idle
26 | .equ ASCII_ETB, 23 ; end of transmission block
27 | .equ ASCII_CAN, 24 ; cancel
28 | .equ ASCII_EM, 25 ; end of medium
29 | .equ ASCII_SUB, 26 ; substitute
30 | .equ ASCII_ESC, 27 ; escape
31 | .equ ASCII_FS, 28 ; file separator
32 | .equ ASCII_GS, 29 ; group separator
33 | .equ ASCII_RS, 30 ; record separator
34 | .equ ASCII_US, 31 ; unit separator
35 | .equ ASCII_RUB, 127 ; rub out (what happens when you press the '<=' button that is called backspace
--------------------------------------------------------------------------------
/apps/library/ashet/io-page.inc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/apps/library/ashet/syscalls.inc:
--------------------------------------------------------------------------------
1 |
2 |
3 | .equ SYS_UART_SETUP, 16
4 | .equ SYS_UART_STATUS, 20
5 | .equ SYS_UART_WRITE_CHAR, 24
6 | .equ SYS_UART_READ_CHAR, 28
--------------------------------------------------------------------------------
/apps/library/bios.inc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ; This is the location of `puts(char * str)` in the ROM.
5 | ; We can use this to clarify where we're jumping to
6 | .equ ROM_PUTS, 0x0006
7 |
8 |
9 | ; Entry point for applications, BIOS will jump here after
10 | ; loading the application to memory.
11 | .equ APP_START, 0x8000
12 |
--------------------------------------------------------------------------------
/apps/minimal-firmware/firmware.asm:
--------------------------------------------------------------------------------
1 | .org 0x0000
2 |
3 | bpset 0x0000
4 | spset 0x0000
5 |
6 |
7 |
8 | push msg_hello
9 | ipget 2
10 | jmp serial_puts
11 | pop
12 |
13 | push 0x10
14 |
15 | mini_loop:
16 | push 0x0000
17 | ipget 2
18 | jmp sleep
19 | pop
20 |
21 | sub 1 [f:yes]
22 | [ex:nonzero] jmp mini_loop
23 | pop
24 |
25 | push msg_byte
26 | ipget 2
27 | jmp serial_puts
28 | pop
29 |
30 | .dw 0x8000 ; invalid opcode
31 |
32 | msg_hello:
33 | .asciiz "Hello, World!\r\n"
34 | msg_byte:
35 | .asciiz "Goodbye, Emulator!\r\n"
36 |
37 | ; fn(str: [*:0]const u8) void
38 | ; prints a string to the serial terminal
39 | .align 2
40 | serial_puts:
41 | bpget
42 | spget
43 | bpset
44 |
45 | get 2 ; arg 1
46 | .puts_loop:
47 | ld8 [i0:peek] [f:yes]
48 | [ex:nonzero] st8 0x4000
49 | [ex:nonzero] add 1
50 | [ex:nonzero] jmp .puts_loop
51 | pop
52 |
53 | bpget
54 | spset
55 | bpset
56 | ret
57 |
58 |
59 | sleep:
60 | bpget
61 | spget
62 | bpset
63 |
64 | get 0-2
65 |
66 | .loop:
67 | sub 1 [f:yes]
68 | nop
69 | nop
70 | [ex:nonzero] jmp .loop
71 | pop
72 |
73 | bpget
74 | spset
75 | bpset
76 | ret
--------------------------------------------------------------------------------
/apps/minimal/main.asm:
--------------------------------------------------------------------------------
1 | .org 0x8000
2 | st 0x4000, '!'
3 | jmp .
4 |
--------------------------------------------------------------------------------
/apps/web-firmware/demo.asm:
--------------------------------------------------------------------------------
1 | .equ ROM_START, 0x0000
2 | .equ SERIAL_PORT, 0x7FFE
3 | .equ RAM_START, 0x8000
4 |
5 | .org RAM_START
6 |
7 | entry_point:
8 |
9 | push message
10 |
11 | .loop:
12 | ld8 [i0:peek] [f:yes]
13 | [ex:zero] jmp .done
14 | st SERIAL_PORT
15 | add 1
16 | jmp .loop
17 | .done:
18 | pop ; remove 0 byte
19 | pop ; remove address
20 |
21 | ret ; return to bios
22 |
23 | message:
24 | .asciiz "Hello, World!\r\n"
--------------------------------------------------------------------------------
/castle.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ikskuh/spu-mark-ii/ec8e7e05f5c2cdfe4b4e98b369ce03df08885baa/castle.bin
--------------------------------------------------------------------------------
/documentation/app-notes/AN000 - Understanding the Instruction Set.md:
--------------------------------------------------------------------------------
1 | # AN000 - Understanding the Instruction Set
2 |
3 | ## Instructions
4 |
5 | Each instruction is composed of a set of bit fields defining the behaviour:
6 |
7 | - Command
8 | - Execution
9 | - Input 0
10 | - Input 1
11 | - Output
12 | - Flag Modifier
13 |
14 | The most relevant field is the *command* part. It defines what the CPU actually does
15 | with your data. There are 32 commands from which are some still reserved. They provide
16 | the ability to modify data (ALU), modify memory (load/store) or modify aux registers.
17 |
18 | Each *command* has two input values: *input 0* and *input 1*. These get fetched by the
19 | cpu and get passed two the *command*. It will then process both values and will yield
20 | an *output*. The cpu will then dispatch the output value as specified in the instruction.
21 |
22 | An *output* can be discarded, pushed to the stack or used as a jump target. This means
23 | that actually *all instructions can be jump instructions*! Discarding an output might
24 | sound unnecessary, but it has its uses as well:
25 |
26 | To remove a value from the stack, the *command* `COPY` is used and the output is just
27 | discarded. This means that we can fetch values from the stack and don't push new ones.
28 | We successfully implemented `pop` by assembling an instruction.
29 |
30 | Each instruction has also a bit that, when set, will update the flags of the cpu
31 | according to the *output* of the command. There are two flags relevant for the
32 | normal program control flow: *zero* and *negative*. These flags will only be changed
33 | when an instruction has the *modify flags* bit set. Then, the *zero* flag will be set
34 | when *output* is zero and the *negative* flag will be set when the highest significant
35 | bit in *output* is set (and thus is negative in two's complement).
36 |
37 | The flags can then be used to execute instructions conditionally. The *execution* field
38 | of an instruction defines for which combination of flags the instruction is actually
39 | executed. This is similar to other architectures like ARM or the Parallax Propeller that
40 | allow instructions to be executed conditionally instead of having a dedicated *conditional jump*,
41 | *conditional move* or similar. It is also different from instructions like the AVR *skip*
42 | which requires an additional fetch cycle.
43 |
44 | Conditional execution checks for different combinations of flags that are semantically
45 | relevant. This yields 7 conditions: always, less-or-equal, greater-or-equal, less-than,
46 | greater-than, non-equal (or non-zero) and equal (or zero).
47 |
48 | Now only two fields are unexplained: *input 0* and *input 1*. Both fields have the same
49 | semantics and the same options: *zero*, *immediate*, *peek* and *pop*.
50 |
51 | *Zero* is the simplest one and means that the input field gets set to 0. *Immediate* means
52 | that value for that field is encoded in the instruction itself and is not dependent on
53 | runtime properties. This is usually used for addresses, offsets, magic numbers or similar.
54 | *Peek* and *pop* both take the value of the stack top, and *pop* will remove the value
55 | from the stack whereas *peek* will keep the stack pointer itself untouched.
56 |
57 | ## Registers
58 |
59 | > TODO: Explain what the four core registers do
60 |
61 | ## Common Patterns
62 |
63 | > TODO: Explain how some coding patters are and how
64 | > to write basic code for the processor.
65 |
66 | ```asm
67 | ; Check an an 8 bit value
68 | sgxt [f:yes] [out:discard]
69 | ```
--------------------------------------------------------------------------------
/documentation/app-notes/AN002 - Standard Calling Convention.md:
--------------------------------------------------------------------------------
1 | # AN002 - Standard Calling Convention
2 |
3 | ## Call Site
4 |
5 | The caller of a function follows this procedure:
6 |
7 | 1. If function has a return value, push placeholder for the return value
8 | 2. Push arguments back-to-front on the stack
9 | 3. Push return address on the stack
10 | 4. Jump to the target function
11 | 5. Pop all arguments from stack
12 | 6. Process return value if any
13 |
14 | For a function without args and return value, the simplest call looks like this:
15 | ```asm
16 | ipget 2 ; Position-independent getter for return address
17 | jmp func ; Jump to function
18 | ```
19 |
20 | For a function with the C signature `int16_t sum(int16_t a, int16_t b)` the code
21 | looks like this:
22 | ```asm
23 | push 0 ; return value
24 | push b ; arg 2
25 | push a ; arg 1
26 | ipget 2 ; return address
27 | jmp func ; execute call
28 | pop ; remove arg 1
29 | pop ; remove arg 2
30 | ; here the return value is on top of the stack and can be processed further
31 | ```
32 |
33 | ## Function Site
34 |
35 | Functions called with the Standard Calling Convention need to modify the
36 | Base Pointer in order to access both function arguments as well as the return
37 | type. before modifying the Base Pointer, the old Base Pointer must be saved:
38 |
39 | ```asm
40 | func:
41 | bpget ; save caller base pointer on the stack
42 | spget ; \
43 | bpset ; + Set new base pointer to current stack stop
44 |
45 | … ; Function implement goes here
46 |
47 | bpget ; \
48 | spset ; + Restore previous stack frame
49 | bpset ; Restore caller base pointer
50 | ret ; Return to caller
51 | ```
52 |
53 | Inside the function, arguments, return value, return address and previous Base Pointer
54 | can be accessed by using `get` and `set`. The offsets for this are:
55 |
56 | | Offset | Value |
57 | |----------|---------------------|
58 | | 0 | caller Base Pointer |
59 | | 1 | return address |
60 | | 2+*c* | Argument *c* |
61 | | 2+*argc* | return value |
62 |
63 | Passing negative values to `get` or `set` will return values local to the function stack
64 | and thus allow simple access to local variables.
65 |
66 | A function implementing this C code:
67 |
68 | ```c
69 | int16_t sum(int16_t a, int16_t b)
70 | {
71 | return a + b;
72 | }
73 | ```
74 |
75 | looks like this:
76 |
77 | ```asm
78 | func:
79 | bpget ; save caller base pointer on the stack
80 | spget ; \
81 | bpset ; + Set new base pointer to current stack stop
82 |
83 | get 2
84 | get 3
85 | add
86 | set 4
87 |
88 | bpget ; \
89 | spset ; + Restore previous stack frame
90 | bpset ; Restore caller base pointer
91 | ret ; Return to caller
92 | ```
93 |
--------------------------------------------------------------------------------
/documentation/app-notes/AN003 - Writing efficient code.md:
--------------------------------------------------------------------------------
1 | # AN003 - Writing efficient code
2 |
3 | ## When should I use a conditional jump?
4 |
5 | (TBD)
6 |
7 | ## Merging instructions and combine effects
8 |
9 | (TBD)
--------------------------------------------------------------------------------
/documentation/design/spu-mk-ii-logo-large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ikskuh/spu-mark-ii/ec8e7e05f5c2cdfe4b4e98b369ce03df08885baa/documentation/design/spu-mk-ii-logo-large.png
--------------------------------------------------------------------------------
/documentation/design/spu-mk-ii-logo-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ikskuh/spu-mark-ii/ec8e7e05f5c2cdfe4b4e98b369ce03df08885baa/documentation/design/spu-mk-ii-logo-small.png
--------------------------------------------------------------------------------
/documentation/design/spu-mk-ii-logo.txt:
--------------------------------------------------------------------------------
1 | Logo created by Kitsu
2 |
3 | Font used:
4 | https://fontstruct.com/fontstructions/show/738493/av02_jetforce
5 |
6 | AV02 Jetforce
7 | by AV Perth (ConEAP)
8 | CC BY-NC-ND 3.0
--------------------------------------------------------------------------------
/documentation/figures/fr.svg:
--------------------------------------------------------------------------------
1 |
2 |
81 |
--------------------------------------------------------------------------------
/documentation/figures/genbits.lua:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env lua
2 |
3 | local args = {...}
4 |
5 | local bits = {
6 | -- {"0", 1}, -- {name, bits}
7 | }
8 |
9 | local original = "./genbits.lua"
10 | for i = 1, #args, 2 do
11 | local num = tonumber(args[i + 1])
12 | assert(num, "unable to numify " .. tostring(args[i + 1]))
13 | table.insert(bits, {args[i], num})
14 | original = original .. " " .. args[i] .. " " .. num
15 | end
16 |
17 | local bitCount = 0
18 | for _, v in ipairs(bits) do
19 | bitCount = bitCount + v[2]
20 | end
21 | local highBit = bitCount - 1
22 | for _, v in ipairs(bits) do
23 | local lowBit = ((highBit - v[2]) + 1)
24 | if highBit == lowBit then
25 | v[3] = "[" .. highBit .. "]"
26 | else
27 | v[3] = "[" .. highBit .. ":" .. lowBit .. "]"
28 | end
29 | highBit = highBit - v[2]
30 | end
31 |
32 | local margin = 24
33 | local bitWidth = 80
34 | local bitHeight = 56
35 | local width = (margin * 2) + (bitCount * bitWidth)
36 | local height = 120
37 | local bitY = 48
38 | local textY = 88
39 | local textYUp = 40
40 |
41 | print("")
42 | print("")
70 |
--------------------------------------------------------------------------------
/documentation/figures/instruction.svg:
--------------------------------------------------------------------------------
1 |
2 |
93 |
--------------------------------------------------------------------------------
/documentation/figures/ir.svg:
--------------------------------------------------------------------------------
1 |
2 |
81 |
--------------------------------------------------------------------------------
/documentation/index.md:
--------------------------------------------------------------------------------
1 | ## Introduction
2 |
3 | The Ashet Home Computer, or short just *Ashet* is a late 80ies style inspired [home computer](https://en.wikipedia.org/wiki/Home_computer) with a 16 bit cpu.
4 |
5 | Most components of *Ashet* are self-developed chips and computer components, like the *SPU Mark II* CPU, the yet unnamed MMU, video chip and blitter DMA.
6 |
7 | ## Goal of the project
8 |
9 | The goal is to create a home computer around the *SPU Mark II* CPU that can be used for games, music and demos. The CPU is a quite novel approach on instruction set style as well as the attempt to create a CPU that is easily programmed by humans and compilers the like.
10 |
11 | To overcome the 64k memory limitation own to 16 bit cpus is overcome by a paging unit providing 16 pages a 4096 byte that can be mapped to *any* page in a 16 MB large memory space. The I/O architecture is inspirted by the [Amiga 500](https://en.wikipedia.org/wiki/Amiga_500), like a DMA chip ("blitter") that allows trivial image/block transfers in memory as well as a graphics chip with sprite support. In contrast to the Amiga though the *Ashet* uses a 256 color linear framebuffer with a configurable palette of 16 bit colors, allowing the user to chose 256 of 65536 possible colors.
12 |
13 | ## State of the project
14 |
15 | Right now, everything is work in progress and a lot of links on this site will be broken or the documents will be incomplete, but get filled in the future. If you want to support the project, [mail me](mailto:contact@ashet.computer)!
16 |
17 | Most core components are either in *concept phase* or in *implementation phase*, some even near-completion
18 |
19 | - Hardware
20 | - SPU Mark II (nearly complete, only missing
21 | - UART serial port (nearly completion, misses only a good MMIO interface)
22 | - RAM interface (complete, RAM test works)
23 | - MMU (planning done, implementation is up next)
24 | - Toolchain
25 | - Assembler (work-in-progress, misses some directives and expression evaluation)
26 | - Debugging iterface to the SOC
27 | - Emulator (mirrors the state of hardware, will be updated as soon as HW gains new features)
--------------------------------------------------------------------------------
/documentation/manuals/ashet-emulator.md:
--------------------------------------------------------------------------------
1 | ## Ashet Emulator
2 |
3 | > (TBD)
--------------------------------------------------------------------------------
/documentation/manuals/assembler.md:
--------------------------------------------------------------------------------
1 | ## SPU Mk 2 Assembler
2 |
3 | > (TBD)
--------------------------------------------------------------------------------
/documentation/manuals/basic-emulator.md:
--------------------------------------------------------------------------------
1 | ## Basic SPU Mk 2 Assembler
2 |
3 | > (TBD)
--------------------------------------------------------------------------------
/documentation/manuals/disassembler.md:
--------------------------------------------------------------------------------
1 | ## SPU Mk 2 Disassembler
2 |
3 | > (TBD)
--------------------------------------------------------------------------------
/documentation/metadata/an000.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | title: Understanding the Instruction Set
3 | author:
4 | - Felix "xq" Queißner
5 | date: April 28, 2020
6 | abstract: |
7 | The SPU Mark II uses quite unique instruction set following a highly orthogonal programming style.
8 | In contrast to most cpus on the market, the SPU Mark II is a stack machine. This means that all operations move data to or from the stack. This does not mean that this cpu has no registers. There are auxiliary registers like a stack pointer SP or the instruction pointer IP.
9 |
--------------------------------------------------------------------------------
/documentation/metadata/an001.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | title: The SPU Assembly Language
3 | author:
4 | - Felix "xq" Queißner
5 | date: April 28, 2020
6 | abstract: |
7 | The highly flexible nature of the instruction set of the *SPU Mark II* makes it
8 | different to put all possible instructions into useful mnemonics. So the assembly
9 | language allows the coder to put modifiers on each instruction. These modifiers
10 | allow to change any field of the instruction they are put on.
11 |
--------------------------------------------------------------------------------
/documentation/metadata/an002.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | title: Standard Calling Convention
3 | author:
4 | - Felix "xq" Queißner
5 | date: April 28, 2020
6 | abstract: The Standard Calling Convention (SCC) is the default calling convention used for all SPU Mark II code.
--------------------------------------------------------------------------------
/documentation/metadata/an003.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | title: Writing efficient code
3 | author:
4 | - Felix "xq" Queißner
5 | date: April 28, 2020
6 | abstract: The SPU Mark II allows one to write very compact and efficient code. In this document, you learn about different tricks on how to do this.
--------------------------------------------------------------------------------
/documentation/metadata/ashet.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | title: Ashet Hardware Architecture
3 | author:
4 | - Felix "xq" Queißner
5 | date: Jan 19, 2021
6 | abstract: The document describes the system architecture of the Ashet Home Computer.
7 |
--------------------------------------------------------------------------------
/documentation/metadata/isa.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | title: The SPU Mark II Instruction Set Architecture
3 | author:
4 | - Felix "xq" Queißner
5 | date: April 28, 2020
6 | abstract: This is the documentation for the SPU Mark II instruction set architecture. It is a stack based 16 bit processor that features a highly configurable instruction set.
--------------------------------------------------------------------------------
/documentation/metadata/mmu.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | title: Ashet Primitive Bank Unit
3 | author:
4 | - Felix "xq" Queißner
5 | date: May 07, 2020
--------------------------------------------------------------------------------
/documentation/metadata/vchip.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | title: Unnamed DMA Chip
3 | author:
4 | - Felix "xq" Queißner
5 | date: May 07, 2020
6 | abstract: |
7 |
The RAM Blitter is a DMA unit that is developed for general purpose DMA transfers, as well as framebuffer modifications. It supports basic linear memory transfers as well as rectangle copies with image manipulation.
8 |
The RAM blitter also has a modes for drawing 2d vector graphics and a filling operation that allows color transfers.
9 |
--------------------------------------------------------------------------------
/documentation/metadata/vga.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | title: VGA Chip
3 | author:
4 | - Felix "xq" Queißner
5 | date: May 07, 2020
6 | abstract: The VGA Chip provides a framebuffer with 256×128 pixels output.
--------------------------------------------------------------------------------
/documentation/os/boot.md:
--------------------------------------------------------------------------------
1 | # Boot Process
2 |
3 | ## Brain Dump
4 |
5 | 1. `` Initialize default memory map
6 | 2. `` Initialize and detect HW
7 | 3. `` Create process "init"
8 | 4. `` Jump into "init" process
9 | 5. `` Check HDDs for an OS signature
10 | 6. `` Display boot menu
11 | 7. `` If nothing selected, create process with "ROM BASIC"
12 | 8. `` does its thing
--------------------------------------------------------------------------------
/documentation/os/index.md:
--------------------------------------------------------------------------------
1 | # AshetOS Overview
2 |
3 | ## Features
4 |
5 | - Boot management
6 | - Provide boot menu
7 | - Boot application/os from HDD
8 | - Load application via serial port
9 | - BIOS style functions
10 | - mass storage
11 | - serial ports
12 | - display
13 | - …
14 | - Cooperative multitasking
15 | - Memory management
16 |
17 | ## Builtin BASIC
18 |
19 | The AshetOS provides a builtin BASIC implementation that allows the users to use the hardware without any OS installed.
20 | The BASIC is compatible to Microsoft BASIC 4.0, but has some Ashet-specific extensions.
--------------------------------------------------------------------------------
/documentation/os/syscalls.md:
--------------------------------------------------------------------------------
1 | # List of Syscalls
2 |
3 | ## Serial Port
4 |
5 | - setup (baud, ...)
6 | - status
7 | - write char
8 | - read char
9 |
10 | ## Raw Mass Storage / Disk
11 |
12 | - detect
13 | - read sector
14 | - write sector
15 |
16 | ## File System I/O
17 |
18 | - stat
19 | - dir
20 | - open
21 | - read
22 | - write
23 | - close
24 | - mkdir
25 | - delete
26 | - truncate
27 | - move
28 |
29 | ## Display:
30 |
31 | - clear
32 | - loadPalette
33 | - loadBitmap
34 | - loadImage
35 | - printString
36 | - moveCursor
37 | - verticalScroll
38 | - horizontalScroll
39 | - setBorderColor
40 | - enableCursor
41 |
42 | ## Parallel Port
43 |
44 | - set direction
45 | - write
46 | - read
47 |
48 | ## Keyboard
49 |
50 | - status
51 | - read char
52 | - get key
53 |
54 | ## Mouse
55 |
56 | - status
57 | - readPos
58 | - show
59 | - hide
60 |
61 | ## Joystick
62 |
63 | - read
64 |
65 | ## RTC
66 |
67 | - read
68 | - write
69 | - read time
70 | - write time
71 | - read date
72 | - write date
73 |
74 | ## Memory
75 |
76 | - status
77 | - alloc page
78 | - free page
79 |
80 | ## Tasks
81 |
82 | - spawn
83 | - kill
84 | - status
85 | - yield
86 | - sleep
87 | - send
88 | - receive
--------------------------------------------------------------------------------
/documentation/os/ui.uxf:
--------------------------------------------------------------------------------
1 | 10UMLClass280220470210SimpleClass
--------------------------------------------------------------------------------
/documentation/specs/ashet-register-space.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Register Space
4 |
5 | ## Device Overview
6 |
7 | **[MMU](mmu.md):**
8 |
9 | - 1 Device
10 | - 18 Registers @ 16 Bit
11 |
12 | **[IRQ](irq.md):**
13 |
14 | - 1 Device
15 | - 6 Registers @ 16 Bit
16 |
17 | **[UART 16C550-Style](uart.md):**
18 |
19 | - 4 Devices
20 | - 8 Registers @ 8 Bit
21 |
22 | **[PS/2](ps2.md):**
23 |
24 | - 2 Devices
25 | - 2 Registers @ 16 Bit
26 |
27 | **[IDE / PATA](ide.md):**
28 |
29 | - 1 Device
30 | - 8 Registers @ 16 Bit
31 |
32 | **[Timer](timer.md):**
33 |
34 | - 2 Devices
35 | - 4 Registers @ 16 Bit
36 |
37 | **[RTC](rtc.md):**
38 |
39 | - 1 Device
40 | - 3 Registers @ 16 Bit
41 | - 8 Registers @ 8 Bit
42 |
43 | **[Joystick](joystick.md):**
44 |
45 | - 2 Devices
46 | - 1 Registers @ 8 Bit
47 |
48 | **[Parallel Port](parport.md):**
49 |
50 | - 1 Device
51 | - 3 Registers @ 8 Bit
52 |
53 | **[PCM Audio Control/Status](pcm.md):**
54 |
55 | - 1 Device
56 |
57 | **[DMA Control/Status](dma.md):**
58 |
59 | - 1 Device
60 |
61 | **[VGA Card](vga.md):**
62 |
63 | - 1 Device
64 | - 3 Registers @ 16 Bit
65 | - 2 Registers @ 8 Bit
66 |
67 | **[Ethernet](eth.md):**
68 |
69 | - 1 Device
70 | - 3 Registers @ 16 Bit
71 | - 7 Registers @ 8 Bit
72 |
73 | **[VGA Palette Memory](vga.md):**
74 |
75 | - 1 Device
76 | - 256 Registers @ 16 Bit
77 |
78 | ## Device Mapping
79 |
80 | | Address | Offset | Count | Peripherial |
81 | | ---------- | ------ | ----- | ---------------------------------- |
82 | | `0x7FE000` | 0 | 36 | [MMU](mmu.md) |
83 | | `0x7FE030` | 48 | 12 | [IRQ](irq.md) |
84 | | `0x7FE040` | 64 | 8 | [UART 16C550-Style (1)](uart.md) |
85 | | `0x7FE050` | 80 | 8 | [UART 16C550-Style (2)](uart.md) |
86 | | `0x7FE060` | 96 | 8 | [UART 16C550-Style (3)](uart.md) |
87 | | `0x7FE070` | 112 | 8 | [UART 16C550-Style (4)](uart.md) |
88 | | `0x7FE080` | 128 | 4 | [PS/2 (1)](ps2.md) |
89 | | `0x7FE090` | 144 | 4 | [PS/2 (2)](ps2.md) |
90 | | `0x7FE0A0` | 160 | 16 | [IDE / PATA](ide.md) |
91 | | `0x7FE0B0` | 176 | 8 | [Timer (1)](timer.md) |
92 | | `0x7FE0C0` | 192 | 8 | [Timer (2)](timer.md) |
93 | | `0x7FE0D0` | 208 | 14 | [RTC](rtc.md) |
94 | | `0x7FE0E0` | 224 | 1 | [Joystick (1)](joystick.md) |
95 | | `0x7FE0F0` | 240 | 1 | [Joystick (2)](joystick.md) |
96 | | `0x7FE100` | 256 | 3 | [Parallel Port](parport.md) |
97 | | `0x7FE110` | 272 | 0 | [PCM Audio Control/Status](pcm.md) |
98 | | `0x7FE110` | 272 | 0 | [DMA Control/Status](dma.md) |
99 | | `0x7FE110` | 272 | 8 | [VGA Card](vga.md) |
100 | | `0x7FE120` | 288 | 13 | [Ethernet](eth.md) |
101 | | `0x7FE200` | 512 | 512 | [VGA Palette Memory](vga.md) |
102 | | `0x7FE400` | 1024 | | _end of peripherials_ |
103 |
--------------------------------------------------------------------------------
/documentation/specs/ashet.md:
--------------------------------------------------------------------------------
1 | # Ashet Home Computer Specification
2 |
3 | **DISCLAIMER: This is a living document, do not take anything here for granted!**
4 |
5 | ## Hardware
6 |
7 | ### CPU
8 |
9 | - SPU Mark II, a 16 bit processor
10 |
11 | ### Memory
12 |
13 | - 8 MB of flash
14 | - Up to 8 MB of ram
15 |
16 | ### Peripherials
17 |
18 | - VGA video
19 | - 4 serial ports
20 | - 2 * RS232
21 | - 1 * USB Serial
22 | - 1 infrared serial interface for wireless data transfers
23 | - 2 PS/2 ports for keyboard and mouse
24 | - 2 IDE slots for mass storage
25 | - 2 (digital) joystick ports, compatible to c64/amiga/cpc/…
26 | - IEEE 1284 II parallel port
27 | - PCM audio interface
28 | - Real time clock
29 | - 10 MBit Ethernet
30 | - Possibly based on ENC28J60 or ENC624J600
31 |
32 | ## Memory Map
33 |
34 | | Address Range | Memory Type | Component |
35 | |---------------|-----------------|-------------------------------------|
36 | | `0x0*****` | (*Memory*) | up to 8 MB Flash ROM |
37 | | `0x7FE***` | (*Peripherial*) | [I/O Page](ashet-register-space.md) |
38 | | `0x7FF***` | (*Peripherial*) | VGA Sprite Data |
39 | | `0x80****` | (*Memory*) | up to 8 MB of RAM |
40 |
41 | The [I/O Page](ashet-register-space.md) contains all peripherial registers and links to the peripherial devices.
42 |
43 | ## DMA Devices
44 |
45 | The following devices have memory access (with priority top-to-bottom):
46 |
47 | - VGA Controller
48 | - Audio Controller
49 | - CPU
50 | - DMA Controller
51 |
52 | ## IRQ Table
53 |
54 | | IRQ Number | Peripherial |
55 | |------------|--------------|
56 | | 0 | `COM1` |
57 | | 1 | `COM2` |
58 | | 2 | `COM3` |
59 | | 3 | `COM4` |
60 | | 4 | `PER1` |
61 | | 5 | `PER2` |
62 | | 6 | `PCM` |
63 | | 7 | `DMA` |
64 | | 8 | `TIMER0` |
65 | | 9 | `TIMER1` |
66 | | 10 | `VGA` |
67 | | 11 | `ETHERNET` |
68 | | 11 … 31 | *unused* |
69 |
70 | ## Serial Ports
71 |
72 | | COM Name | Connector | Base Address |
73 | |----------|-----------|--------------|
74 | | `COM1` | USB | (TBD) |
75 | | `COM2` | RS232 1 | (TBD) |
76 | | `COM3` | RS232 2 | (TBD) |
77 | | `COM4` | IR | (TBD) |
78 |
79 | ## PS/2 Ports
80 |
81 | | Function | Connector | Base Address |
82 | |----------|-----------|--------------|
83 | | `PER1` | KEYBOARD | (TBD) |
84 | | `PER2` | MOUSE | (TBD) |
85 |
86 | ## Timers and RTC
87 |
88 | Timer 0 runs at 1 MHz, Timer 1 runs at 1 kHz.
--------------------------------------------------------------------------------
/documentation/specs/eth.md:
--------------------------------------------------------------------------------
1 | # Ethernet Interface
2 |
3 | ## Registers
4 |
5 | | Offset | Size | Access | Description |
6 | |---------|------|--------|------------------------|
7 | | `0x000` | 1 | R | Receive Data Register |
8 | | `0x000` | 1 | W | Send Data Register |
9 | | `0x002` | 2 | RW | Control/Status |
10 | | `0x004` | 2 | R | Receive Packet Length |
11 | | `0x006` | 2 | R | Send Packet Length |
12 | | `0x008` | 6*1 | R | Interface MAC address |
13 |
14 | ### `Control/Status`
15 |
16 | | Bit Range | Name |Access | Description |
17 | |-----------|-------|-------|--------------------------------------------------------------------------------------------------------|
18 | | `[0]` | `ENA` | RW | If `1`, the ethernet interface is enabled. |
19 | | `[1]` | `FUC` | RW | If `1`, unicast ethernet packets with a foreign MAC will be filtered. |
20 | | `[2]` | `FMC` | RW | If `1`, multicast ethernet packets will be filtered. |
21 | | `[3]` | `FBC` | RW | If `1`, broadcast ethernet packets will be filtered. |
22 | | `[4]` | `RTR` | RO | A packet is ready in the queue and can be read via the `Receive Data Register`. |
23 | | `[5]` | `RAK` | RW | Acknowledge received packet. Write this bit to `1` to signal that the incoming packet was fully processed and a new one can be provided if available. |
24 | | `[6]` | `SND` | RW | After bytes are written into `Send Data Register`, write `1` to signal that the packet should be sent. |
25 | | `[7]` | `SFL` | RW | Write `1` to this register to flush the send buffer and discard all bytes written. |
26 | | `[8]` | `PUC` | R | Is `1` when the currently ready receive packet is for the local MAC address |
27 | | `[9]` | `PMC` | R | Is `1` when the currently ready receive packet has a multicast MAC address. |
28 | | `[10]` | `PBC` | R | Is `1` when the currently ready receive packet has a broadcast MAC address. |
29 | | `[15:11]` | | | *reserved*, must be 0 |
30 |
31 | ### `Receive Packet Length`
32 |
33 | When a incoming packet is signalled via the `RTR` bit, this register will contain the remaining bytes of the packet to be read.
34 |
35 | Each read on the `Receive Data Register` will decrement this value until it reaches 0.
36 |
37 | ### `Send Packet Length`
38 |
39 | Contains the current number of bytes written into the `Send Data Register`. If 0, no bytes are currently in the send buffer.
40 |
41 | ### `Interface MAC address`
42 |
43 | These six byte contain the MAC address of the ethernet interface.
--------------------------------------------------------------------------------
/documentation/specs/ide.md:
--------------------------------------------------------------------------------
1 | # IDE / P-ATA / CompactFlash Interface
2 |
3 | Parallel ATA-Interface to two compact flash slots.
--------------------------------------------------------------------------------
/documentation/specs/irq.md:
--------------------------------------------------------------------------------
1 |
2 | # IRQ Controller
3 |
4 | - [Overview](#overview)
5 | - [Function](#function)
6 | - [Registers](#registers)
7 |
8 | ## Overview
9 |
10 | - Dispatch multiple IRQ lanes into a single lane
11 | - Acknowledge of IRQs
12 | - Masking of IRQs
13 | - up to 32 IRQs
14 |
15 | ## Function
16 |
17 | The IRQ controller manages up to 32 different IRQ sources that work with level-driven IRQs.
18 | If a source IRQ lane is *low*, the IRQ is assumed to be active. A IRQ becomes inactive when the
19 | source lane will go to *high*.
20 |
21 | When an IRQ becomes active, a corresponding bit is set in the `IRQ0` or `IRQ1` register and the output IRQ lane is pulled to *low*.
22 | The output IRQ lane is *low* until all bits in the `IRQ0` and `IRQ1` registers are `0`.
23 |
24 | To acknowledge that an IRQ was handled, write a `1` bit into `IRQ0` or `IRQ1` to tell the controller that this interrupt was handled.
25 | If the IRQ was previously active, it is now disabled.
26 |
27 | Masking interrupts is supported by writing a `1` bit to `MASK0` or `MASK1`. Interrupts will only become active when the IRQ lane is *low* and the corresponding bit in `MASK0` or `MASK1` is `0`. When the controller is reset, all interrupts are masked.
28 |
29 | ## Registers
30 |
31 | | Offset | Name | Size | Access | Description |
32 | |---------|-------|------|--------|--------------------------------------------|
33 | | `0x000` | IRQ0 | 2 | R | Active IRQs 0…15 |
34 | | `0x002` | IRQ1 | 2 | R | Active IRQs 16…31 |
35 | | `0x000` | ACK0 | 2 | W | Acknowledge IRQs 0…15 |
36 | | `0x002` | ACK1 | 2 | W | Acknowledge IRQs 16…31 |
37 | | `0x004` | MASK0 | 2 | R/W | Mask IRQs 0…15 |
38 | | `0x006` | MASK1 | 2 | R/W | Mask IRQs 16…31 |
39 |
40 | ### Active IRQs 0…15
41 |
42 | When read, all IRQs between 0 and 15 that were triggered since the last acknowledge are
43 | displayed as `1`. All non-triggered IRQs are `0`.
44 |
45 | ### Active IRQs 16…31
46 |
47 | When read, all IRQs between 16 and 31 that were triggered since the last acknowledge are
48 | displayed as `1`. All non-triggered IRQs are `0`.
49 |
50 | ### Acknowledge IRQs 0…15
51 |
52 | When writing to this register, all bits that are `1` in this register will be acknowledged and reset.
53 |
54 | ### Acknowledge IRQs 16…31
55 |
56 | When writing to this register, all bits that are `1` in this register will be acknowledged and reset.
57 |
58 | ### Mask IRQs 0…15
59 |
60 | When a bit is 1, the corresponding interrupt is masked and will not be able to get active. On controller reset, all interrupts are masked.
61 |
62 | ### Mask IRQs 16…31
63 |
64 | When a bit is 1, the corresponding interrupt is masked and will not be able to get active. On controller reset, all interrupts are masked.
65 |
66 |
--------------------------------------------------------------------------------
/documentation/specs/joystick.md:
--------------------------------------------------------------------------------
1 | # Joystick Port
2 |
3 |
--------------------------------------------------------------------------------
/documentation/specs/mmu.md:
--------------------------------------------------------------------------------
1 | # SimpleMMU
2 |
3 | ## Overview
4 | - 16 bit virtual addresses
5 | - 24 bit physical addresses
6 | - 16 banks a 4096 byte -> 64 kB address space
7 |
8 | ## Function
9 | The MMU translates virtual addresses in a physical addresses by utilizing 16 pages.
10 |
11 | Each page contains 4096 bytes of memory which can be write-protected.
12 |
13 | The physical address for a memory access is created by looking up the upper 12 bit in the page descriptor and taking the lower 12 bit of the virtual address:
14 |
15 | ```
16 | physical[23:12] := mmuConfig[virt[15..12]][15..4]
17 | physical[11:0] := virt[11..0]
18 | ```
19 |
20 | When a non-enabled page is accessed, the MMU raises a fault signal and sets the corresponding bit in the Page Fault Register.
21 |
22 | When a non-writeable page is beeing written, the MMU raises a fault signal and sets the corresponding bit in the Write Fault Register.
23 |
24 | ## Configuration
25 | The MMU configuration is mapped into the physical address space at a system-defined location and has the following layout:
26 |
27 | | Offset | Size | Access | Description |
28 | |---------|------|--------|-----------------------|
29 | | `0x000` | 2 | R/W | Page 0 Descriptor |
30 | | `0x002` | 2 | R/W | Page 1 Descriptor |
31 | | `0x004` | 2 | R/W | Page 2 Descriptor |
32 | | `0x006` | 2 | R/W | Page 3 Descriptor |
33 | | `0x008` | 2 | R/W | Page 4 Descriptor |
34 | | `0x00A` | 2 | R/W | Page 5 Descriptor |
35 | | `0x00C` | 2 | R/W | Page 6 Descriptor |
36 | | `0x00E` | 2 | R/W | Page 7 Descriptor |
37 | | `0x010` | 2 | R/W | Page 8 Descriptor |
38 | | `0x012` | 2 | R/W | Page 9 Descriptor |
39 | | `0x014` | 2 | R/W | Page 10 Descriptor |
40 | | `0x016` | 2 | R/W | Page 11 Descriptor |
41 | | `0x018` | 2 | R/W | Page 12 Descriptor |
42 | | `0x01A` | 2 | R/W | Page 13 Descriptor |
43 | | `0x01C` | 2 | R/W | Page 14 Descriptor |
44 | | `0x01E` | 2 | R/W | Page 15 Descriptor |
45 | | `0x020` | 2 | RO | Page Fault Register |
46 | | `0x022` | 2 | RO | Write Fault Register |
47 |
48 | Each page descriptor is 16 bit wide and organized in the following manner:
49 |
50 | | Bit Range | Name | Description |
51 | | --------- | ------ | ------------------------------------- |
52 | | `[0]` | **EN** | page mapping enabled |
53 | | `[1]` | **WP** | page is write protected |
54 | | `[2]` | **CA** | caching is enabled for this page |
55 | | `[3]` | | reserved, must be `0` |
56 | | `[15:4]` | **PA** | Upper 12 bits of the physical address |
57 |
58 | The Page Fault Register contains a bit for each page that flags if there was an access fault (page not mapped).
59 |
60 | The Write Fault Register contains a bit for each page that flags if there was a write fault (page was written, but write protected).
61 |
62 | Each Page Fault Register and Write Fault Register are beeing cleared to 0 after a read operation.
63 |
64 | ## I/Os
65 |
66 | - 24 output physical address lanes
67 | - 16 input virtual address lanes
68 | - 16 in/out data lanes to the bus
69 | - RE, WE input signal (from CPU)
70 | - RE, WE output signal (to Bus)
71 | - CS input to activate read-write access to the MMU
72 |
73 | ## Changelog
74 |
75 | ### v1.0
76 | - Initial version
77 |
78 |
--------------------------------------------------------------------------------
/documentation/specs/parport.md:
--------------------------------------------------------------------------------
1 | # IEEE 1284 II Parallel Port
2 |
3 | A parallel port component compatible to the IEEE 1284 II standard.
--------------------------------------------------------------------------------
/documentation/specs/pcm.md:
--------------------------------------------------------------------------------
1 | # PCM Audio Interface
2 |
3 |
4 |
5 |
6 | Required features:
7 |
8 | - Mute bit
9 | - Global gain register
10 | - Playback of 44100 Hz audio
11 | - 16 bit signed pcm
12 |
--------------------------------------------------------------------------------
/documentation/specs/ps2.md:
--------------------------------------------------------------------------------
1 | # PS/2 Controller
2 |
3 | Planned features:
4 | - Communicate with a PS/2 device (mouse, keyboard)
5 | - One controller per device
6 |
7 | ## Registers
8 |
9 | | Offset | Size | Access | Description |
10 | |---------|------|--------|------------------------|
11 | | `0x000` | 2 | R | Status Reqister |
12 | | `0x002` | 2 | R | Data Input |
13 | | `0x002` | 2 | W | Data Output |
14 |
15 | ### Status Register
16 |
17 | 0: Device Present
18 | 1: Input FIFO not full
19 | 2: Input FIFO full
20 | 3: Output FIFO not full
21 | 4: Output FIFO full
22 |
23 | ### Data Input
24 |
25 | Reading from this port either returns the value read or all bits set if no value is present in the input fifo.
26 |
27 | ### Data Output
28 |
29 | Writing to this port will either put a byte into the send fifo if not full or discard the value.
--------------------------------------------------------------------------------
/documentation/specs/rtc.md:
--------------------------------------------------------------------------------
1 | # RTC
2 |
3 | ## Registers
4 |
5 | | Offset | Size | Access | Description |
6 | |---------|------|--------|------------------------|
7 | | `0x000` | 1 | R | Current Day |
8 | | `0x001` | 1 | R | Current Month |
9 | | `0x002` | 2 | R | Current Year |
10 | | `0x004` | 1 | R | Current Hour |
11 | | `0x005` | 1 | R | Current Minute |
12 | | `0x006` | 1 | R | Set Data Day |
13 | | `0x007` | 1 | R | Set Data Month |
14 | | `0x008` | 2 | R | Set Data Year |
15 | | `0x00A` | 1 | R | Set Data Hour |
16 | | `0x00B` | 1 | R | Set Data Minute |
17 | | `0x00C` | 2 | RW | Control Register |
18 |
19 | ### `Control Register`
20 |
21 | | Bit Range | Description |
22 | |-----------|--------------------------------------------------------|
23 | | `[0]` | Write to `1` to write the time. Will always read as 0. |
24 | | `[15:1]` | *reserved*, must be 0 |
--------------------------------------------------------------------------------
/documentation/specs/timer.md:
--------------------------------------------------------------------------------
1 | # Timer
2 |
3 | Each timer runs at a defined frequency that is not necessarily the cpu frequency.
4 |
5 | ## Registers
6 |
7 | | Offset | Size | Access | Description |
8 | |---------|------|--------|------------------------|
9 | | `0x000` | 2 | RW | Timer Value |
10 | | `0x002` | 2 | RW | Timer Limit |
11 | | `0x004` | 2 | RW | Prescaler |
12 | | `0x006` | 2 | RW | Control |
13 |
14 | `Timer Value` increments each time `Prescaler`-1 clocks have happened. When `Timer Value` reaches `Timer Limit`, the `Timer Value` is reset to 0 and a IRQ is raised if enabled.
15 |
16 | ### Status / Control
17 |
18 | | Bit Range | Description |
19 | |-----------|-----------------------|
20 | | `[0]` | Enable Timer |
21 | | `[1]` | Enable IRQ |
22 | | `[15:2]` | *reserved*, must be 0 |
--------------------------------------------------------------------------------
/documentation/specs/uart.md:
--------------------------------------------------------------------------------
1 |
2 | # TinyUART
3 |
4 | A 16C550 compatible UART component.
5 |
6 | - [Features](#features)
7 | - [Registers](#registers)
8 |
9 | ## Features
10 |
11 | The TinyUART is a 16C550 compatible UART implementation that provides a fully featured UART interface including flow- and modem control.
12 |
13 | ## Registers
14 |
15 | | Offset | Name | Size | Access | Description |
16 | |---------|-------|------|--------|--------------------------------------------|
17 | | `0x000` | RBR | 1 | R | (DLAB=0) Receiver buffer |
18 | | `0x000` | THR | 1 | W | (DLAB=0) Transmitter holding register |
19 | | `0x001` | IER | 1 | R/W | (DLAB=0) Interrupt enable register |
20 | | `0x000` | DLL | 1 | R/W | (DLAB=1) Divisor latch (LSB) |
21 | | `0x001` | DLM | 1 | R/W | (DLAB=1) Divisor latch (MSB) |
22 | | `0x002` | IIR | 1 | R | Interrupt identification register |
23 | | `0x002` | FCR | 1 | W | FIFO control register |
24 | | `0x003` | LCR | 1 | R/W | Line control register |
25 | | `0x004` | MCR | 1 | R/W | Modem control register |
26 | | `0x005` | LSR | 1 | R | Line status register |
27 | | `0x006` | MSR | 1 | R | Modem status register |
28 | | `0x007` | SCR | 1 | R/W | Scratch register |
29 |
30 |
--------------------------------------------------------------------------------
/documentation/specs/vga.md:
--------------------------------------------------------------------------------
1 | # BasicVGA
2 |
3 | Planned features:
4 |
5 | - Modes:
6 | - Graphic 256×128, 8bpp, 60 Hz
7 | - (*planned*) Graphic, 2bpp, 60 Hz
8 | - 256 color palette support for RGB565
9 | - Output signal is 640x480 with double scaling and a border color
10 |
11 | ```
12 | # 640x480 59.38 Hz (CVT 0.31M3) hsync: 29.69 kHz; pclk: 23.75 MHz
13 | Modeline "640x480_60.00" 23.75 640 664 720 800 480 483 487 500 -hsync +vsync
14 | ```
15 |
16 | # Registers
17 |
18 | | Offset | Size | Access | Description |
19 | |----------|------|--------|-----------------------|
20 | | `0x0000` | 4 | R/W | Framebuffer Address |
21 | | `0x0004` | 2 | R/W | Border Color |
22 | | `0x0006` | 1 | R | Status Register |
23 | | `0x0007` | 1 | W | Control Register |
24 | | `0x1000` | 2 | R/W | Palette Entry 0 |
25 | | `0x1***` | 2 | R/W | Palette Entry * |
26 | | `0x1FFE` | 2 | R/W | Palette Entry 255 |
27 |
28 | ## Framebuffer Address
29 | Start address of the linear framebuffer. The frame buffer
30 | is stored row-major, so the first 128 byte are the the first
31 | row of pixels.
32 |
33 | The address is in 24 bit address format, the upper 8 bit are
34 | ignored by the VGA module. Also, the address is in physical
35 | layout, so the memory must not be mapped to be visible.
36 |
37 | ## Status Register
38 |
39 | - 0: HighRes
40 | - 1: *unused*
41 | - 2: VSync Active
42 | - 3: HSync Active
43 |
44 | When *HighRes* is `1`, the graphic mode is switched from 256×128,8bpp to 512×256,2bpp. In this mode, only 4 colors are available, but the size is horizontally and vertically doubled.
45 |
46 | ## Control Register
47 | Mirror register of the status register that allows writing several control commands into the VGA.
48 |
49 | - 0: HighRes
50 | - 1: *unused*
51 | - 2: N/A
52 | - 3: N/A
53 |
54 | # Sprite Unit
55 |
56 | **This part of the document isn't written yet. Please consider this not even a working draft.**
57 |
58 | The sprite unit is a built into two parts:
59 |
60 | - A 4096 byte memory section that stores both sprite pixels and sprite definitions
61 | - A set of registers that enable up to 8 sprites
62 |
63 | Facts:
64 |
65 | - 4096 byte storage for sprite data (one page)
66 | - Sprite size can be set in steps of 4 pixels width and height
67 | - Sprite size can be from 4×4 to 64×64 pixels.
68 | - Sprites always use 255 colors from the palette, color 0 is transparent
69 |
70 | ```c
71 | struct SpriteDef {
72 | u16 pixeldata_addr;
73 | u16 next_sprite_addr;
74 | i16 x;
75 | i8 y;
76 | u4 width;
77 | u4 height;
78 | }
79 | ```
80 |
81 | width = u4 & "00"
82 | height = u4 & "00"
83 |
84 |
--------------------------------------------------------------------------------
/documentation/website/downloads.md:
--------------------------------------------------------------------------------
1 | # Downloads
2 |
3 | ## Toolchain
4 |
5 | This bundle contains all available tools, core libraries, manuals (in html format) and other documents.
6 |
7 | - [Windows 64bit](downloads/ashet-toolchain-windows-x86_64.zip)
8 | - [Linux 64bit](downloads/ashet-toolchain-linux-x86_64.zip)
9 |
10 | ## Emulator
11 |
12 | - [Windows 64bit](downloads/emulator-windows-x86_64.exe)
13 | - [Linux 64bit](downloads/emulator-linux-x86_64)
14 |
15 | ## Assembler
16 |
17 | - [Windows 64bit](downloads/assembler-windows-x86_64.exe)
18 | - [Linux 64bit](downloads/assembler-linux-x86_64)
19 |
20 | ## Disassembler
21 |
22 | - [Windows 64bit](downloads/disassembler-windows-x86_64.exe)
23 | - [Linux 64bit](downloads/disassembler-linux-x86_64)
24 |
25 |
--------------------------------------------------------------------------------
/documentation/website/imprint.htm:
--------------------------------------------------------------------------------
1 |
Legal Disclosure
2 | Information in accordance with Section 5 TMG
3 |
Felix Queißner Schellingstraße 13 72622 Nürtingen
4 |
11 | Accountability for content
12 | The contents of our pages have been created with the utmost care. However, we cannot guarantee the contents'
13 | accuracy, completeness or topicality. According to statutory provisions, we are furthermore responsible for
14 | our own content on these web pages. In this matter, please note that we are not obliged to monitor
15 | the transmitted or saved information of third parties, or investigate circumstances pointing to illegal activity.
16 | Our obligations to remove or block the use of information under generally applicable laws remain unaffected by this as
17 | per
18 | §§ 8 to 10 of the Telemedia Act (TMG).
19 |
20 |
Accountability for links
21 | Responsibility for the content of
22 | external links (to web pages of third parties) lies solely with the operators of the linked pages. No violations were
23 | evident to us at the time of linking. Should any legal infringement become known to us, we will remove the respective
24 | link immediately.
Copyright Our web pages and their contents are subject to German copyright law. Unless
25 | expressly permitted by law, every form of utilizing, reproducing or processing
26 | works subject to copyright protection on our web pages requires the prior consent of the respective owner of the rights.
27 | Individual reproductions of a work are only allowed for private use.
28 | The materials from these pages are copyrighted and any unauthorized use may violate copyright laws.
29 |
30 |