Compare commits
5
Commits
3f95056eec
...
12cb489268
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
12cb489268 | ||
|
|
bd94059c08 | ||
|
|
9690ecf21f | ||
|
|
8ace20629b | ||
|
|
4e5710a1e6 |
Binary file not shown.
|
After Width: | Height: | Size: 79 KiB |
@@ -0,0 +1,8 @@
|
|||||||
|
# Media
|
||||||
|
|
||||||
|
Screenshots and anything else that is looked at rather than read or built.
|
||||||
|
|
||||||
|
Nothing here is used by the build or the tests. The repository's README links to what is
|
||||||
|
in here, and `Tests/docs.sh` checks that every one of those links lands, so a file removed
|
||||||
|
from here without the link going too will fail the suite rather than becoming a broken
|
||||||
|
image on the front page.
|
||||||
@@ -2,7 +2,11 @@
|
|||||||
|
|
||||||
SplitBit is an 8 bit computer that does not exist: a CPU with its own instruction set, split Program and Data memories, an interrupt and vector system, a bus that programs can enumerate, a memory controller that can write code into memory, and a disk. This repository is a C implementation of the machine, an assembler for it, a tool for its disks, and the software that runs on it, which now includes an operating system and an assembler written in SplitBit's own assembly language.
|
SplitBit is an 8 bit computer that does not exist: a CPU with its own instruction set, split Program and Data memories, an interrupt and vector system, a bus that programs can enumerate, a memory controller that can write code into memory, and a disk. This repository is a C implementation of the machine, an assembler for it, a tool for its disks, and the software that runs on it, which now includes an operating system and an assembler written in SplitBit's own assembly language.
|
||||||
|
|
||||||
**SplitBit assembles SplitBit.** `Programs/CosmOS/Assembler/` runs on the machine, reads source off a SplitBit disk, and writes a boot image or a loadable program back to it with no host involved. It builds the operating system it is running under, and it builds itself, both byte for byte identical to what the C assembler produces from the same source. The test suite then boots the CosmOS that CosmOS built and has *that* one assemble CosmOS again, and the second generation is identical to the first, so the machinery has been through itself. After that the host is a convenience rather than a necessity.
|

|
||||||
|
|
||||||
|
*The whole loop in one screen. `Asm.sbx` assembles `hello.asm` into `hello.sbx`; the shell loads that and runs it; then the monitor disassembles what is at 0x2000, which is the program the machine wrote for itself at the top of the screen. No host is involved at any point.*
|
||||||
|
|
||||||
|
**SplitBit assembles SplitBit.** [`Programs/CosmOS/Assembler/`](Programs/CosmOS/Assembler) runs on the machine, reads source off a SplitBit disk, and writes a boot image or a loadable program back to it with no host involved. It builds the operating system it is running under, and it builds itself, both byte for byte identical to what the C assembler produces from the same source. The test suite then boots the CosmOS that CosmOS built and has *that* one assemble CosmOS again, and the second generation is identical to the first, so the machinery has been through itself. After that the host is a convenience rather than a necessity.
|
||||||
|
|
||||||
```
|
```
|
||||||
> load Asm.sbx
|
> load Asm.sbx
|
||||||
@@ -16,15 +20,15 @@ wrote Asm.sbx: program 7533, data 4099, labels 555
|
|||||||
|
|
||||||
| Directory | What it holds |
|
| Directory | What it holds |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `Source/Emulator` | The machine: CPU, memory controller, devices, console, disk |
|
| [`Source/Emulator`](Source/Emulator) | The machine: CPU, memory controller, devices, console, disk |
|
||||||
| `Source/Assembler` | The assembler that runs on a host |
|
| [`Source/Assembler`](Source/Assembler) | The assembler that runs on a host |
|
||||||
| `Source/DiskTool` | SplitDisk, which reads and writes SplitBit's filesystem |
|
| [`Source/DiskTool`](Source/DiskTool) | SplitDisk, which reads and writes SplitBit's filesystem |
|
||||||
| `Programs/Examples` | Programs to read: hello, a calculator, Fibonacci, a prime sieve, Life |
|
| [`Programs/Examples`](Programs/Examples) | Programs to read: hello, a calculator, Fibonacci, a prime sieve, Life |
|
||||||
| `Programs/Libraries` | Code included by name rather than linked, since there is no linker |
|
| [`Programs/Libraries`](Programs/Libraries) | Code included by name rather than linked, since there is no linker |
|
||||||
| `Programs/Loader` | The standalone loader CosmOS grew out of |
|
| [`Programs/Loader`](Programs/Loader) | The standalone loader CosmOS grew out of |
|
||||||
| `Programs/CosmOS` | The operating system, its applications, and the native assembler |
|
| [`Programs/CosmOS`](Programs/CosmOS) | The operating system, its applications, and the native assembler |
|
||||||
| `Programs/testPrograms` | What the test suite drives |
|
| [`Programs/testPrograms`](Programs/testPrograms) | What the test suite drives |
|
||||||
| `Tests` | The suite: the manifest, the recorded output, and the scripts that check it |
|
| [`Tests`](Tests) | The suite: the manifest, the recorded output, and the scripts that check it |
|
||||||
|
|
||||||
## The Machine:
|
## The Machine:
|
||||||
|
|
||||||
@@ -55,6 +59,8 @@ make
|
|||||||
|
|
||||||
The sources are ISO C and build clean under `-std=c11 -pedantic` with `-Wall -Wextra`. Beyond ISO C they need POSIX.1-2008, which the makefile asks for by name, and `getopt_long` for the long form of the command line options.
|
The sources are ISO C and build clean under `-std=c11 -pedantic` with `-Wall -Wextra`. Beyond ISO C they need POSIX.1-2008, which the makefile asks for by name, and `getopt_long` for the long form of the command line options.
|
||||||
|
|
||||||
|
Building needs nothing else. **Running the tests needs `bash` and Python 3**, because two of the checking scripts are Python and one of them opens a pseudo-terminal to ask questions a recorded file cannot answer. They also use `stty`, `timeout`, and the usual text utilities: `sed`, `awk`, `grep`, `cmp`, `diff`, `tr`, `sort`, `wc`.
|
||||||
|
|
||||||
Assemble something and run it:
|
Assemble something and run it:
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -174,23 +180,23 @@ because a recorded file cannot answer its question:
|
|||||||
|
|
||||||
A cycle count is deliberately **not** part of a recorded result. The last line of the emulator's output has the number taken out before anything is compared, keeping only whether the program stopped on its own or ran into its limit, which is behaviour. Two instructions added to CosmOS used to move that number in six unrelated files at once, so a real difference would have arrived in a crowd of meaningless ones. Anything that wants to measure cycles should say so in a test of its own.
|
A cycle count is deliberately **not** part of a recorded result. The last line of the emulator's output has the number taken out before anything is compared, keeping only whether the program stopped on its own or ran into its limit, which is behaviour. Two instructions added to CosmOS used to move that number in six unrelated files at once, so a real difference would have arrived in a crowd of meaningless ones. Anything that wants to measure cycles should say so in a test of its own.
|
||||||
|
|
||||||
To rebuild both tools with the address and undefined behaviour sanitizers and run the suite under them:
|
To rebuild all three tools with the address and undefined behaviour sanitizers and run the suite under them:
|
||||||
|
|
||||||
```
|
```
|
||||||
make sanitize
|
make sanitize
|
||||||
```
|
```
|
||||||
|
|
||||||
This catches reads and writes past the end of an array, use after free, leaks, and undefined arithmetic. It also fills fresh allocations with a junk pattern, which turns a read of uninitialised memory from something that quietly works into something the tests notice. It takes about twice as long as `make test`, and puts the ordinary binaries back when it finishes.
|
This catches reads and writes past the end of an array, use after free, leaks, and undefined arithmetic. It also fills fresh allocations with a junk pattern, which turns a read of uninitialised memory from something that quietly works into something the tests notice. It runs everything `make test` runs, takes about twice as long, and puts the ordinary binaries back when it finishes.
|
||||||
|
|
||||||
## Documentation:
|
## Documentation:
|
||||||
|
|
||||||
Three documents, divided by what they are about rather than by who reads them.
|
Three documents, divided by what they are about rather than by who reads them.
|
||||||
|
|
||||||
The **SplitBit Programming Manual** describes **the machine**: the instruction set, the registers, the vector table, interrupts, devices, the memory controller, the console, storage, and faults. Everything here is true of any SplitBit, whatever is running on it.
|
**[SplitBit Programming Manual](SplitBit%20Programming%20Manual.md)** describes **the machine**: the instruction set, the registers, the vector table, interrupts, devices, the memory controller, the console, storage, and faults. Everything here is true of any SplitBit, whatever is running on it.
|
||||||
|
|
||||||
The **SplitBit Assembler Manual** describes **the language and the file formats**: literal values, labels, segments, the directives, the loadable program header, and the assembler that runs on SplitBit itself.
|
**[SplitBit Assembler Manual](SplitBit%20Assembler%20Manual.md)** describes **the language and the file formats**: literal values, labels, segments, the directives, the loadable program header, and the assembler that runs on SplitBit itself.
|
||||||
|
|
||||||
`Programs/CosmOS/README.md` describes **the operating system**: its shell, its applications, what a program may ask it for, and the libraries it owns. A different system on the same machine would answer all of that differently, which is why it is documented with the system rather than with the CPU.
|
[Programs/CosmOS/README.md](Programs/CosmOS/README.md) describes **the operating system**: its shell, its applications, what a program may ask it for, and the libraries it owns. A different system on the same machine would answer all of that differently, which is why it is documented with the system rather than with the CPU.
|
||||||
|
|
||||||
## License:
|
## License:
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# SplitBit Assembler Manual:
|
# The SplitBit Assembler Manual:
|
||||||
|
|
||||||
SplitBit assembly syntax is similar to many other assembler syntaxes. Whitespace at the start or end of a line is disregarded by the assembler and may be used to make programs more readable to the programmer. The Instruction Mnemonics are listed in the SplitBit Programming Manual, and the assembler is not case sensitive in regard to the mnemonics.
|
SplitBit assembly syntax is similar to many other assembler syntaxes. Whitespace at the start or end of a line is disregarded by the assembler and may be used to make programs more readable to the programmer. The Instruction Mnemonics are listed in the SplitBit Programming Manual, and the assembler is not case sensitive in regard to the mnemonics.
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,36 @@ for name in tracked.split(b"\0"):
|
|||||||
% (path, number, ", ".join("%r (U+%04X)" % (c, ord(c)) for c in odd)))
|
% (path, number, ", ".join("%r (U+%04X)" % (c, ord(c)) for c in odd)))
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# ---- Every link in the documents goes somewhere ----
|
||||||
|
#
|
||||||
|
# A link that does not resolve is the same kind of wrong as a stale claim: it looks like
|
||||||
|
# information and is not, and nobody notices until a stranger clicks it. The manuals have
|
||||||
|
# SPACES IN THEIR NAMES, so a link to one carries %20 and has to be unquoted before it can
|
||||||
|
# be looked for - which is the sort of thing that would otherwise be got wrong once and
|
||||||
|
# then reported as fine.
|
||||||
|
import os
|
||||||
|
import urllib.parse
|
||||||
|
|
||||||
|
for name in tracked.split(b"\0"):
|
||||||
|
if not name or not name.endswith(b".md"):
|
||||||
|
continue
|
||||||
|
path = name.decode()
|
||||||
|
here = os.path.dirname(path)
|
||||||
|
for match in re.finditer(r"\[[^\]]*\]\(([^)]+)\)", read(path)):
|
||||||
|
target = match.group(1)
|
||||||
|
if target.startswith(("http://", "https://", "#", "mailto:")):
|
||||||
|
continue
|
||||||
|
# A raw space ends the link early in most renderers, so the file existing is not
|
||||||
|
# enough - the manuals have spaces in their names and must carry %20.
|
||||||
|
if " " in target:
|
||||||
|
problems.append("%s links to \"%s\", which has a space in it: most renderers"
|
||||||
|
" stop at the space. Write it as %%20."
|
||||||
|
% (path, target))
|
||||||
|
continue
|
||||||
|
wanted = urllib.parse.unquote(target.split("#")[0])
|
||||||
|
if not os.path.exists(os.path.normpath(os.path.join(here, wanted))):
|
||||||
|
problems.append("%s links to %s, and there is nothing there" % (path, target))
|
||||||
|
|
||||||
# ---- Every instruction has a row, and every row is an instruction ----
|
# ---- Every instruction has a row, and every row is an instruction ----
|
||||||
#
|
#
|
||||||
# A mnemonic begins with a letter, which is what keeps the offset and size columns of the
|
# A mnemonic begins with a letter, which is what keeps the offset and size columns of the
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ PREFIX ?= /usr/local
|
|||||||
# editing a header rebuilds everything that includes it.
|
# editing a header rebuilds everything that includes it.
|
||||||
DEPFLAGS = -MMD -MP
|
DEPFLAGS = -MMD -MP
|
||||||
|
|
||||||
# Both tools use POSIX interfaces that ISO C does not have: realpath, clock_gettime,
|
# The emulator and the assembler use POSIX interfaces that ISO C does not have:
|
||||||
|
# realpath, clock_gettime,
|
||||||
# strdup, dirname and getopt. Asking for POSIX.1-2008 by name means the build does
|
# strdup, dirname and getopt. Asking for POSIX.1-2008 by name means the build does
|
||||||
# not rely on the compiler happening to default to a mode where those are visible,
|
# not rely on the compiler happening to default to a mode where those are visible,
|
||||||
# and it survives someone overriding CFLAGS, which is why it is kept separate.
|
# and it survives someone overriding CFLAGS, which is why it is kept separate.
|
||||||
@@ -104,10 +105,17 @@ test: $(EMU_TARGET) $(ASM_TARGET) $(DSK_TARGET) strict
|
|||||||
@echo
|
@echo
|
||||||
@./Tests/docs.sh
|
@./Tests/docs.sh
|
||||||
|
|
||||||
# Rebuild both tools with the address and undefined behaviour sanitizers and run
|
# Rebuild all three tools with the address and undefined behaviour sanitizers and run
|
||||||
# the test suite under them. Slower than 'make test', and worth running before a
|
# the test suite under them. Slower than 'make test', and worth running before a
|
||||||
# release or after anything that touches memory handling.
|
# release or after anything that touches memory handling.
|
||||||
#
|
#
|
||||||
|
# THE WHOLE SUITE, which it did not used to be: it built all three tools sanitized and
|
||||||
|
# then ran only run.sh and terminal.sh, so SplitDisk was compiled with the sanitizers and
|
||||||
|
# never exercised, and native.sh - which drives the assembler and the emulator harder than
|
||||||
|
# anything else here - was skipped. Those are the parts where block arithmetic on disk
|
||||||
|
# images and buffer indexing in two assemblers live, which is exactly what the sanitizers
|
||||||
|
# are for. Adding the three of them costs about six seconds.
|
||||||
|
#
|
||||||
# The sanitizers catch reads and writes off the end of an array, use after free,
|
# The sanitizers catch reads and writes off the end of an array, use after free,
|
||||||
# leaks, and undefined arithmetic. They also fill fresh allocations with a junk
|
# leaks, and undefined arithmetic. They also fill fresh allocations with a junk
|
||||||
# pattern, which is what turns a read of uninitialised memory from something that
|
# pattern, which is what turns a read of uninitialised memory from something that
|
||||||
@@ -123,7 +131,13 @@ sanitize:
|
|||||||
@echo "Running the test suite under AddressSanitizer and UndefinedBehaviorSanitizer."
|
@echo "Running the test suite under AddressSanitizer and UndefinedBehaviorSanitizer."
|
||||||
@./Tests/run.sh
|
@./Tests/run.sh
|
||||||
@echo
|
@echo
|
||||||
|
@./Tests/disk.sh
|
||||||
|
@echo
|
||||||
@./Tests/terminal.sh
|
@./Tests/terminal.sh
|
||||||
|
@echo
|
||||||
|
@./Tests/native.sh
|
||||||
|
@echo
|
||||||
|
@./Tests/docs.sh
|
||||||
@$(MAKE) --no-print-directory clean
|
@$(MAKE) --no-print-directory clean
|
||||||
@$(MAKE) --no-print-directory
|
@$(MAKE) --no-print-directory
|
||||||
@echo "Sanitizer run finished cleanly. Normal binaries rebuilt."
|
@echo "Sanitizer run finished cleanly. Normal binaries rebuilt."
|
||||||
|
|||||||
Reference in New Issue
Block a user