osFileRead hands over a whole file, which settles anything under 64K and settles nothing above it. CosmOS's own source is above it - the sources together are 104K against 64K of Data Memory - so a machine that is going to assemble itself needs another way to ask. osFileInfo (0d26) says how many blocks a file occupies. osFileBlock (0d27) hands over one of them and says how many of its bytes belong to the file. Between them a program reads a file of any size through a buffer of 256. Blocks rather than bytes from osFileInfo is forced, not chosen: a file on a sixteen megabyte disk is up to twenty four bits long and a pointer holds sixteen. osFileBlock's count answers in DP3 for the same kind of reason - a whole block is 256 bytes, which does not fit in a register, and a count that reported it as zero would make every reader special-case the end. Nothing is kept open. Every call names the file, so there is no handle to leak and nothing left behind by a program that stops halfway. Taken at its word that means searching the directory once per block, so the system remembers where the last file it was asked about lives; every path that can change what a name means calls fileForget, including the shell's own delete and rename, which do not go through the services. Correctness never depends on the cache - a cache thrown away is indistinguishable from one never filled. Measured on a 329 block file: 7% of the run saved when the file is the first directory entry, 11% when it is the sixteenth. These two say WHY when the answer is no, which the others do not. Elsewhere the only useful response to a failure is to give up, so one value suffices. These are asked questions, and running off the end is how a reader learns it has finished, so it gets an answer of its own: 1 no disk, 2 no such file, 3 past the end, 4 the disk refused. Apps/Stream.asm reads an 84,000 byte file through 256 bytes. The check that matters is the second one: a small file read BOTH ways - whole with osFileRead and streamed - with the two checksums compared, so streaming is measured against the path already known to work rather than against a number someone wrote down. The checksum is Fletcher's rather than a sum, because a sum is the same whatever order the bytes arrived in and the order is exactly what streaming has to get right. Both checksums were also confirmed against the same arithmetic run on the host. The rest of the test is the cache: two files read alternately catch a memory that missed the name changing, and a rename catches one that missed the file moving - and that one would otherwise pass, since the blocks are still there holding the same bytes. The test file is generated rather than taken from the repository. The CosmOS sources would be a truer picture and would move the recorded checksum every time a line of CosmOS was edited, putting a real difference in a crowd of meaningless ones - the same trap the cycle counts used to set. cosmosBreak's recorded output moves by two bytes in two pointers: SbfsIndex added two bytes to the filesystem's data and Break prints the system addresses the registers happened to hold. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
396 lines
29 KiB
Plaintext
396 lines
29 KiB
Plaintext
# SplitBit test manifest
|
|
# Written by Anachronaut
|
|
#
|
|
# One test per line, fields separated by '|'. Blank lines and lines starting
|
|
# with '#' are ignored.
|
|
#
|
|
# name | source | mode | stdin | limit | disk
|
|
#
|
|
# source is relative to Programs/. Everything assembles from there with
|
|
# Libraries/ on the include path, and the binary is written into Tests/build.
|
|
#
|
|
# Modes:
|
|
# run Assemble, execute, compare all output against Tests/expected/<name>.out
|
|
# assemble Assemble only. For library files that have no entry point to run
|
|
# xfail Assembly is expected to fail. Records a known breakage so that
|
|
# fixing one is noticed, and so an accidental new one is too
|
|
#
|
|
# limit is a cycle count, for programs that never halt on their own. It is passed
|
|
# to the emulator as --cycles, which bounds the run by cycles rather than by wall
|
|
# clock time and so keeps the recorded output identical from one run to the next.
|
|
#
|
|
# disk names a disk image to attach, made fresh inside Tests/build for every run so that
|
|
# nothing a test writes can be seen by the next one. Leave it off for a machine with no
|
|
# disk, which is most of them. A trailing :ro attaches it write protected.
|
|
#
|
|
# A disk name with a directory in it, such as disks/sbfs.img, is one of the images that
|
|
# Tests/makedisks.sh builds with SplitDisk before the run. Those are used as they stand,
|
|
# so a test can read a filesystem written by the other implementation of the format.
|
|
# Every program is run with --fast, since the emulated cycle rate has no bearing
|
|
# on what a program prints.
|
|
|
|
# ---- Programs that halt on their own ----
|
|
hello | hello.asm | run | - | -
|
|
printHello | printHello.asm | run | - | -
|
|
8bitFibonacci | Fibonacci/8bitFibonacci.asm | run | - | -
|
|
16bitFibonacci | Fibonacci/16bitFibonacci.asm | run | - | -
|
|
32bitFibonacci | Fibonacci/32bitFibonacci.asm | run | - | -
|
|
8bitSieve | primeSieve/8bitSieve.asm | run | - | -
|
|
16bitSegmentedSieve | primeSieve/16bitSegmentedSieve.asm | run | - | -
|
|
# The four pointer rewrite. It emits exactly the same primes as the line above, which
|
|
# is the whole point of keeping both: the pair is a direct before and after.
|
|
16bitSegmentedSieveModern | primeSieve/16bitSegmentedSieveModern.asm | run | - | -
|
|
mathTest | testPrograms/mathTest.asm | run | - | -
|
|
printTest | testPrograms/printTest.asm | run | - | -
|
|
int16print | Libraries/int16print.asm | run | - | -
|
|
|
|
# ---- The multiple Data Pointer behaviour, which nothing else exercises ----
|
|
dataPointerTest | testPrograms/dataPointerTest.asm | run | - | -
|
|
twoPointerCopy | testPrograms/twoPointerCopy.asm | run | - | -
|
|
pointerTableTest | testPrograms/pointerTableTest.asm | run | - | -
|
|
staticTableTest | testPrograms/staticTableTest.asm | run | - | -
|
|
dispatchTest | testPrograms/dispatchTest.asm | run | - | -
|
|
|
|
# ---- Branching both ways round ----
|
|
# Each of the four conditions is checked taken and not taken, so a branch that always
|
|
# went the same way would be caught rather than looking right half the time.
|
|
branchTest | testPrograms/branchTest.asm | run | - | -
|
|
|
|
# ---- Moving an ALU result back into an operand register ----
|
|
moveQTest | testPrograms/moveQTest.asm | run | - | -
|
|
|
|
# ---- The memory controller ----
|
|
# Reading and writing Program Memory, which the instruction set deliberately cannot do,
|
|
# and the bank table that says what is reachable.
|
|
controllerReadTest | testPrograms/controllerReadTest.asm | run | - | -
|
|
controllerWriteTest | testPrograms/controllerWriteTest.asm | run | - | -
|
|
# Block transfers: between banks, within one, overlapping, and one that is refused.
|
|
blitTest | testPrograms/blitTest.asm | run | - | -
|
|
# Reading a filesystem that the host tool wrote. The two are separate implementations of
|
|
# one written format, so this is where any drift between them would show.
|
|
sbfsReadTest | testPrograms/sbfsReadTest.asm | run | - | - | disks/sbfs.img
|
|
# Walking the directory rather than searching it, which is what listing a disk needs.
|
|
# Twelve files is more than the eight an entry block holds, so the walk has to cross into
|
|
# the second directory block to see them all.
|
|
sbfsWalkTest | testPrograms/sbfsWalkTest.asm | run | - | - | disks/sbfs.img
|
|
|
|
# Writing a filesystem, then reading back what was written. The disk starts with a file
|
|
# on it, so allocation has to find room rather than start at the beginning.
|
|
sbfsWriteTest | testPrograms/sbfsWriteTest.asm | run | - | - | disks/write.img
|
|
# Deleting, renaming, and saving over something already there, which is what any tool that
|
|
# edits a document needs and what none of the tests above touch. The interesting line is
|
|
# the third: saving a longer version moves the file, because files here are contiguous and
|
|
# do not grow. The last two lines are a rename and a delete having actually happened.
|
|
sbfsEditTest | testPrograms/sbfsEditTest.asm | run | - | - | disks/edit.img
|
|
|
|
# Loading a program off a disk and running it. Everything below this line existed before
|
|
# the loader did; the only new part is the sixteen bytes on the front of a loadable
|
|
# program saying where it goes.
|
|
loader | loader.asm | run | - | - | disks/load.img
|
|
|
|
# Storage. The image is made fresh for each run, so block 3 starts as zeroes.
|
|
diskTest | testPrograms/diskTest.asm | run | - | - | disk.img
|
|
# The same disk attached write protected, so the device bars writes rather than software.
|
|
diskProtectTest | testPrograms/diskProtectTest.asm | run | - | - | protected.img:ro
|
|
|
|
# A program that loads a program: blits code into Program Memory, installs a vector at
|
|
# run time, and calls it. If the vector install ever silently failed, the SWI would fault
|
|
# with "no handler" rather than printing, so this test cannot pass by accident.
|
|
loaderTest | testPrograms/loaderTest.asm | run | - | -
|
|
|
|
# Giving a bank number to a device's memory, which is what an OS does at boot.
|
|
registerBankTest | testPrograms/registerBankTest.asm | run | - | -
|
|
# The fence: raised, walked into, clipped by a blit, read through, and lowered again.
|
|
fenceTest | testPrograms/fenceTest.asm | run | - | -
|
|
# Meant to fault: a bank knows how big it is.
|
|
bankBoundsTest | testPrograms/bankBoundsTest.asm | run | - | -
|
|
|
|
# ---- A device saying no ----
|
|
# Refusing is not interrupting: it stops the instruction that asked, rather than asking
|
|
# for attention later. The device on port 0x11 refuses everything so this path stays
|
|
# tested before the memory controller becomes its only real user.
|
|
refusalTest | testPrograms/refusalTest.asm | run | - | -
|
|
# The same, with nothing installed to catch it. Meant to fault.
|
|
refusalFaultTest | testPrograms/refusalFaultTest.asm | run | - | -
|
|
|
|
# ---- Asking the machine what it is made of ----
|
|
registryTest | testPrograms/registryTest.asm | run | - | -
|
|
|
|
# ---- Moving the cursor along ----
|
|
paddingTest | testPrograms/paddingTest.asm | run | - | -
|
|
|
|
# ---- Finding the Stack, and moving it ----
|
|
stackPointerTest | testPrograms/stackPointerTest.asm | run | - | -
|
|
# MVDS, the dangerous one: a system taking its Stack back from a program that stopped
|
|
# without unwinding. The sequence is the one the Programming Manual prints under "The
|
|
# Stack Pointer, Set By Hand", so the manual's example cannot quietly stop working.
|
|
stackReclaimTest | testPrograms/stackReclaimTest.asm | run | - | -
|
|
|
|
# ---- The Interrupt Flag ----
|
|
# Nothing reads the flag yet. This checks that setting and clearing it leaves
|
|
# the registers and the Carry Flag it shares a byte with untouched.
|
|
interruptFlagTest | testPrograms/interruptFlagTest.asm | run | - | -
|
|
|
|
# ---- Vectors laid down by the assembler ----
|
|
# These are the interrupt path end to end. Until #Vectors existed, none of them could
|
|
# be written as a source file at all, because nothing could install a handler.
|
|
vectorTest | testPrograms/vectorTest.asm | run | - | -
|
|
# Numbers written down and numbers handed out, in one program. A vector number only matters
|
|
# where two separately assembled programs have to agree about it, so those are pinned by
|
|
# hand from a range the assembler never allocates, and everything else is drawn from above
|
|
# it. This pins both ends of that range and leaves a third to the assembler, then calls all
|
|
# three by name: a number going astray shows up as the wrong word rather than as silence.
|
|
pinnedVectorTest | testPrograms/pinnedVectorTest.asm | run | - | -
|
|
# A service handing something back, which RETI otherwise makes impossible: it restores every
|
|
# register from the frame, so a handler that worked something out has no way to say so. The
|
|
# answer is written into the frame over the saved register. All three cases are here - a
|
|
# service that says nothing and leaves Q exactly as it found it, one that answers in Q, and
|
|
# one that answers in DP3 - because the first is what makes the other two safe to rely on.
|
|
serviceReturnTest | testPrograms/serviceReturnTest.asm | run | - | -
|
|
deviceTest | testPrograms/deviceTest.asm | run | - | -
|
|
faultResumeTest | testPrograms/faultResumeTest.asm | run | - | -
|
|
# The worked example out of the Assembler Manual, so the manual cannot go stale.
|
|
interruptExample | testPrograms/interruptExample.asm | run | - | -
|
|
|
|
# ---- Holding a device off, and then letting it through ----
|
|
# Faults on purpose. The fault is the proof that the line was answered, and where it
|
|
# lands in the output is the proof of when.
|
|
maskTest | testPrograms/maskTest.asm | run | - | -
|
|
|
|
# ---- Dispatching through a vector with nothing in it ----
|
|
# Also meant to fault. Until the assembler can lay a vector table down, every entry
|
|
# reads as zero, so this is the only half of the interrupt path a source file can
|
|
# reach on its own. The round trip through a handler is covered by hand built
|
|
# binaries until #Vectors arrives.
|
|
swiFaultTest | testPrograms/swiFaultTest.asm | run | - | -
|
|
|
|
# ---- Meeting a byte that is not an instruction ----
|
|
# This one is meant to fault. It checks the CPU stops, says what it found and
|
|
# where, and exits non zero, rather than stepping over it and carrying on.
|
|
faultTest | testPrograms/faultTest.asm | run | - | -
|
|
|
|
# ---- The modern console library ----
|
|
# Every routine in console.asm, called with the cases that are easy to get wrong: a zero,
|
|
# the largest thing that fits, and a leading zero that should not print. The reading half
|
|
# is given a line longer than its buffer, so truncation and the swallowing of the rest
|
|
# are shown rather than assumed.
|
|
consoleTest | testPrograms/consoleTest.asm | run | consoleTest.in | -
|
|
# The console's status and control ports. Input here is a file rather than a terminal, so
|
|
# key mode has no terminal to change and only the mode bit moves: that is deliberate, since
|
|
# a program has to behave the same either way and a test needing a terminal could not run.
|
|
# What it pins down is that READY is clear at the end of input while ENDED is set, so a
|
|
# loop reading while READY stops on its own instead of taking imaginary bytes forever.
|
|
consoleModeTest | testPrograms/consoleModeTest.asm | run | consoleModeTest.in | -
|
|
# The console interrupting instead of being asked. The main program never touches the
|
|
# console at all, so every byte in that output was delivered by a handler. It also pins
|
|
# down the two things that make the feature usable rather than merely present: the end of
|
|
# input raises the line once, so an interrupt-driven program is told when to stop, and a
|
|
# handler that does not read the byte is not called again, so nothing storms.
|
|
consoleInterruptTest | testPrograms/consoleInterruptTest.asm | run | consoleInterruptTest.in | -
|
|
# Picking a typed line apart, which is how the shell understands anything. Includes a
|
|
# string beginning with a zero: the assembler strips the quotes before deciding what a
|
|
# token is, so such a string looked like a malformed literal and was refused.
|
|
textTest | testPrograms/textTest.asm | run | - | -
|
|
# Strings that spell instructions. The quotes are gone by the time a token is classified, so
|
|
# "ADD" in a Data Segment was assembled as the ADD instruction and refused with a message
|
|
# about a mistake nobody had made. Mnemonics match without regard to case, so "or" and "and"
|
|
# were caught too - ordinary words to want in a message.
|
|
stringMnemonic | testPrograms/stringMnemonic.asm | run | - | -
|
|
|
|
# ---- CosmOS ----
|
|
# The system and its shell, driven by a script of commands. This is the first thing that
|
|
# uses the machine as a machine rather than exercising one part of it: it boots, mounts a
|
|
# disk written by the host tool, reads lines, and walks a directory to answer 'dir'.
|
|
cosmos | CosmOS/Source/cosmos.asm | run | cosmos.in | - | disks/sbfs.img
|
|
# The same with nothing attached. A shell that only works with a disk in the drive is not
|
|
# finished, so the empty machine is a case in its own right rather than an accident.
|
|
cosmosNoDisk | CosmOS/Source/cosmos.asm | run | cosmosNoDisk.in | -
|
|
# Loading a program and running it, which is the whole machine at once: the filesystem
|
|
# finds it, the controller writes it into Program Memory, the vector table carries its
|
|
# requests back to the system, and MVDS takes the Stack back when it stops. Every way
|
|
# load can refuse is tried first, and run is asked for twice, so the Stack being reclaimed
|
|
# rather than merely abandoned is what makes the second one work.
|
|
cosmosRun | CosmOS/Source/cosmos.asm | run | cosmosRun.in | - | disks/cosmos.img
|
|
# The monitor, which is part of the shell rather than a program: a mode you go into and stay
|
|
# in. The targets are chosen to be stable - a loaded program's code and data, and the bank
|
|
# table - rather than the system's own code, which would churn whenever any library changed.
|
|
#
|
|
# Looking at the bank table is worth having on its own. It is the machine describing itself,
|
|
# and it shows the disk buffer that sbfsMount registered as bank 3 at boot.
|
|
#
|
|
# The last part is what the mode is FOR: a program typed in as bytes, run with g, and the
|
|
# prompt that comes back is the monitor's own. A program giving the machine back lands where
|
|
# it was started from, so looking at something and running it do not interrupt each other.
|
|
#
|
|
# It also asks to write into bank 2, the controller's own table, which is published read
|
|
# only. That used to stop the machine, and the recorded output of this test contained the
|
|
# crash without anybody noticing, which is what blessing a result without reading it buys.
|
|
#
|
|
# It ends with a whole program typed in: a string poked into Data Memory, instructions
|
|
# assembled into Program Memory, and the result run - which prints something no assembler
|
|
# ever saw. The mnemonics deliberately include a lower case one, both selector forms, an
|
|
# instruction that does not exist and one missing its value, so that the refusals are
|
|
# recorded next to the successes and a failed line is shown writing nothing.
|
|
cosmosMonitor | CosmOS/Source/cosmos.asm | run | cosmosMonitor.in | - | disks/cosmos.img
|
|
# The original hello.asm, brought over as an application. It is not much of a program,
|
|
# but it is the one that talks to the hardware directly: it writes to port 0x00 instead
|
|
# of calling osPrintString, so it is the case where a program reaches past the system and
|
|
# the system has to get control back anyway. run is asked for twice for the same reason
|
|
# it is in cosmosRun, and here it also says the Stack comes back from a program that never
|
|
# entered a service handler at all.
|
|
cosmosHello | CosmOS/Source/cosmos.asm | run | cosmosHello.in | - | disks/cosmos.img
|
|
# Life, which is the one program that had no end state to reach. It stops when the board
|
|
# settles, and the glider does settle: it crosses the field, hits the dead border, and
|
|
# collapses into a block at generation 54. NO CYCLE LIMIT ON PURPOSE. Whether it stops on
|
|
# its own is the whole point of the port, and a limit would answer that question for it.
|
|
#
|
|
# NOTHING IS TYPED AFTER run, and that is load bearing rather than tidy. Life polls the
|
|
# console between generations, and a byte sitting in the pipe is a byte waiting on the
|
|
# console as far as the machine is concerned - exactly as typing ahead at a terminal
|
|
# would be. An "exit" on the next line stops it at generation 1 and gets eaten. The shell
|
|
# ends the run by reaching the end of input instead, the way cosmosNoDisk does.
|
|
cosmosLife | CosmOS/Source/cosmos.asm | run | cosmosLife.in | - | disks/cosmos.img
|
|
# The other half of that: a key IS waiting, so it stops at once instead of at generation
|
|
# 54. The two together are what say the poll is reading the console rather than always
|
|
# answering the same way.
|
|
cosmosLifeKey | CosmOS/Source/cosmos.asm | run | cosmosLifeKey.in | - | disks/cosmos.img
|
|
# A whole game of Snake, played by a script. Life is watched; this is steered, and it is
|
|
# the first program on this machine that reads the console without ever waiting for it.
|
|
# One key is taken per frame, so twelve bytes in the pipe are twelve moves rather than
|
|
# twelve moves at once: six turn it down the board and six take it left onto the food. So
|
|
# what is recorded is a turn, a meal, a longer snake, and then a wall.
|
|
cosmosSnake | CosmOS/Source/cosmos.asm | run | cosmosSnake.in | - | disks/cosmos.img
|
|
# A loaded program that brings a vector of its own, which nothing could do until the
|
|
# loadable format could carry one. It is run TWICE on purpose: installing has to be exactly
|
|
# undone by removing, and the way that fails is asymmetrically, so the second run is the one
|
|
# that catches it. The dump afterwards is the proof that the table was put back - the
|
|
# console's slot at FE00 is zero again, and CosmOS's own disk handler further along is
|
|
# untouched by a program having installed over the top of it.
|
|
cosmosKeys | CosmOS/Source/cosmos.asm | run | cosmosKeys.in | - | disks/cosmos.img
|
|
# The shell taking things off a disk and calling them something else, which is the last of
|
|
# CosmOS's original four verbs to be built and the first time anything has changed a disk
|
|
# from the shell. Its own image, because it changes what is on it: a fixture named with a
|
|
# directory is used as it stands, so a test that writes to a shared one changes what every
|
|
# test after it sees. The refusals are here too - deleting what is not there, renaming with
|
|
# a name missing, and renaming something to a name already taken.
|
|
cosmosFiles | CosmOS/Source/cosmos.asm | run | cosmosFiles.in | - | disks/files.img
|
|
# A program being told what it is for. Nothing loaded before this could be told anything,
|
|
# so every app did the same thing however it was started - which is fine for a demo and no
|
|
# use at all to a tool that edits a named document. Run three times: with nothing, with a
|
|
# name, and with several words, since what arrives is the rest of the line rather than a
|
|
# list and it is the program's business what to make of it.
|
|
cosmosSay | CosmOS/Source/cosmos.asm | run | cosmosSay.in | - | disks/cosmos.img
|
|
# A program stopping itself to be looked at. Two breakpoints, so what is checked is not only
|
|
# that one fires but that the SECOND one does - which is the whole difference between this
|
|
# design and one that overwrites an instruction, since an overwritten instruction has to be
|
|
# put back to continue and putting it back is the same act as disarming the breakpoint.
|
|
# Every value shown comes out of the interrupt frame rather than the registers, because by
|
|
# the time the handler runs the registers are the handler's.
|
|
cosmosBreak | CosmOS/Source/cosmos.asm | run | cosmosBreak.in | - | disks/cosmos.img
|
|
# The editor, which is the first program on this machine that makes a file a person typed:
|
|
# every byte on every other image here was put there by the host tool. It is run twice in
|
|
# one session, and that is the test rather than a flourish - the second run reads back what
|
|
# the first one wrote, so the whole path is checked at once: read a name from the argument,
|
|
# split a file into lines, edit them, build a file back out of them, and save it over
|
|
# something that was already there and is now a different size.
|
|
cosmosEdit | CosmOS/Source/cosmos.asm | run | cosmosEdit.in | - | disks/editor.img
|
|
# The file services, exercised by a program that includes NOTHING but the service names: no
|
|
# filesystem library, no console library. It writes a file, reads it back, says how long it
|
|
# was, renames it and deletes it, in 645 bytes - against the editor's 4941, which does less
|
|
# with files and carries the filesystem inside it. That difference is the whole case for the
|
|
# service layer, and this is where it is checked rather than argued.
|
|
cosmosServices | CosmOS/Source/cosmos.asm | run | cosmosFiles2.in | - | disks/services.img
|
|
# Streaming, which is what a file bigger than memory needs. The disk here holds 84000
|
|
# bytes in one file and the machine has 64K of Data Memory, so there is no arrangement of
|
|
# osFileRead that could get at it: the program reads it through a buffer of one block.
|
|
#
|
|
# THE CHECK THAT MATTERS IS THE SECOND ONE. A small file is read both ways - whole with
|
|
# osFileRead, and streamed - and the two checksums have to agree, so streaming is measured
|
|
# against the path that already worked rather than against a number somebody wrote down.
|
|
# The checksum is Fletcher's rather than a sum, because a sum is the same whatever order
|
|
# the bytes arrived in and the order is exactly what streaming has to get right.
|
|
#
|
|
# The rest of it is the lookup the system keeps so that reading four hundred blocks of one
|
|
# file does not search the directory four hundred times. Two files read alternately catch a
|
|
# memory that does not notice the name changed, and a rename catches one that does not
|
|
# notice the file moved - and that one would otherwise pass, since the blocks are still
|
|
# there and still hold the same bytes.
|
|
cosmosStream | CosmOS/Source/cosmos.asm | run | cosmosStream.in | - | disks/stream.img
|
|
# The programs CosmOS loads, checked on their own so that a failure here reads as "the app
|
|
# does not assemble" rather than as a broken disk image.
|
|
app-greet | CosmOS/Apps/greet.asm | assemble | - | -
|
|
app-hello | CosmOS/Apps/hello.asm | assemble | - | -
|
|
app-Life | CosmOS/Apps/Life.asm | assemble | - | -
|
|
app-Snake | CosmOS/Apps/Snake.asm | assemble | - | -
|
|
app-Keys | CosmOS/Apps/Keys.asm | assemble | - | -
|
|
app-Say | CosmOS/Apps/Say.asm | assemble | - | -
|
|
app-Break | CosmOS/Apps/Break.asm | assemble | - | -
|
|
app-Edit | CosmOS/Apps/Edit.asm | assemble | - | -
|
|
app-Files | CosmOS/Apps/Files.asm | assemble | - | -
|
|
app-Stream | CosmOS/Apps/Stream.asm | assemble | - | -
|
|
|
|
# ---- Programs driven by console input ----
|
|
inputTest | inputTest.asm | run | inputTest.in | -
|
|
inputTestOld | testPrograms/inputTest.asm | run | inputTest.in | -
|
|
replCalculator | replCalculator.asm | run | replCalculator.in | -
|
|
|
|
# ---- Programs that run forever by design, bounded by a cycle count ----
|
|
# 3,000,000 cycles is about fourteen generations of the glider, which puts
|
|
# evolveBoard and its pointer juggling through its paces many times over.
|
|
16x16Life | gameOfLife/16x16Life.asm | run | - | 3000000
|
|
# The four pointer rewrite, on the same budget so the two can be compared directly.
|
|
# Note that this cannot show a speed difference: frameDelay is 255 by 255 and swamps
|
|
# the simulation, so both versions render the same fourteen generations and produce
|
|
# identical bytes. What it checks is that the rewrite still evolves the board the same
|
|
# way, which is what a regression test is for.
|
|
16x16LifeModern | gameOfLife/16x16LifeModern.asm | run | - | 3000000
|
|
|
|
# ---- Libraries: no entry point, so only check that they assemble ----
|
|
# The CosmOS libraries assemble on their own, unlike print.asm below, which cannot: it
|
|
# begins with a branch to a label only the including program defines. That difference is
|
|
# the point of the rewrite, so both halves of it are recorded here.
|
|
lib-console | CosmOS/Source/console.asm | assemble | - | -
|
|
lib-text | CosmOS/Source/text.asm | assemble | - | -
|
|
lib-sbfs | CosmOS/Source/sbfs.asm | assemble | - | -
|
|
lib-int8 | Libraries/int8.asm | assemble | - | -
|
|
lib-int16 | Libraries/int16.asm | assemble | - | -
|
|
lib-int32 | Libraries/int32.asm | assemble | - | -
|
|
lib-math | Libraries/math.asm | assemble | - | -
|
|
|
|
# ---- Deliberately broken, to check the assembler still diagnoses them ----
|
|
# These are not programs anyone meant to run. Each one contains a single mistake
|
|
# that the assembler used to accept quietly, and is here so that it cannot start
|
|
# being accepted quietly again.
|
|
diagDuplicateLabel | testPrograms/diagnostics/duplicateLabel.asm | xfail | - | -
|
|
diagBareInclude | testPrograms/diagnostics/bareInclude.asm | xfail | - | -
|
|
diagUnknownVector | testPrograms/diagnostics/unknownVector.asm | xfail | - | -
|
|
diagDuplicateVector | testPrograms/diagnostics/duplicateVector.asm | xfail | - | -
|
|
# The two mistakes that pinning a number makes possible. Numbers the assembler hands out
|
|
# cannot collide; numbers a person writes down can, and can also be written outside the
|
|
# range set aside for them.
|
|
# A string in the Program Segment, which used to assemble to nothing at all and say so to
|
|
# nobody. Strings only have a case for the Data buffer, so one aimed anywhere else fell
|
|
# through and vanished.
|
|
diagStringInProgram | testPrograms/diagnostics/stringInProgram.asm | xfail | - | -
|
|
diagPinnedRange | testPrograms/diagnostics/pinnedVectorRange.asm | xfail | - | -
|
|
diagPinnedTaken | testPrograms/diagnostics/pinnedVectorTaken.asm | xfail | - | -
|
|
diagBareSWI | testPrograms/diagnostics/bareSWI.asm | xfail | - | -
|
|
diagAlignOutside | testPrograms/diagnostics/alignOutside.asm | xfail | - | -
|
|
diagBareAlign | testPrograms/diagnostics/bareAlign.asm | xfail | - | -
|
|
# One segment based and the other forgotten, which is how the ported Fib-8 put its data
|
|
# on top of the console's variables. It assembled and it ran, so nothing but the assembler
|
|
# was ever going to catch it.
|
|
diagUnbasedSegment | testPrograms/diagnostics/unbasedSegment.asm | xfail | - | -
|
|
|
|
# ---- Known breakages, recorded rather than ignored ----
|
|
# print.asm branches to 'start', which only the including program defines.
|
|
lib-print | Libraries/print.asm | xfail | - | -
|
|
# These three call print.asm routines but have no #Include line at all. They are
|
|
# only ever pulled in by printTest.asm, so they are not standalone programs.
|
|
printDecimalTest | testPrograms/printDecimalTest.asm | xfail | - | -
|
|
printDigitTest | testPrograms/printDigitTest.asm | xfail | - | -
|
|
printHexTest | testPrograms/printHexTest.asm | xfail | - | -
|
|
# shiftTest calls printDecimal, which print.asm does not have. It looks like the
|
|
# routine was renamed and this caller was never updated.
|
|
shiftTest | testPrograms/shiftTest.asm | xfail | - | -
|