@sfotty-pie/cli
Sfotty Pie CLI
Sfotty Pie CLI is an emulator for a hypothetical 6502-based computer. The current implementation allows you to write CLI programs with access to stdin, stdout, and stderr.
Usage
npx sfotty [options] [--] <program.65> [program args...]
Options (must come before the program filename; -- ends option parsing):
| Option | Description |
|---|---|
--trace |
Write a disassembled trace line to stderr for every instruction. |
--max-cycles=N |
Stop after emulating at most N CPU cycles. |
The process exit code is the one the guest program writes to EXIT (see below). The emulator itself exits with 1 for a missing filename or an invalid executable, 2 for a guest crash (CIM instruction or undefined I/O access), and 3 for an unrecognized option or an internal error.
Executable file format
| Offset | Size | Description |
|---|---|---|
| 0x0000 | 0x06 | Magic number (The word SFOTTY in ASCII) |
| 0x0006 | 0x04 | Reserved (must be zero) |
| 0x000A | 0x06 | Interrupt vectors |
| 0x0010 | variable | Program contents |
System documentation
The interrupt vectors are the NMI, reset, and IRQ vectors, in that order. They are loaded starting from the address $FFFA. The NMI and IRQ vectors are currently unused and should be set to 0. The reset vector at $FFFC is the main program entry.
The program contents are loaded starting from the address $0400.
Page 2 (addresses from $0200 to $02FF) is reserved for I/O operations. Currently, the following I/O operations are defined:
| Address | Name | Read / Write | Description |
|---|---|---|---|
$0200 |
EXIT |
W |
Any write here exits the program with the written exit code. |
$0201 |
STDIN |
R |
Read a byte from the standard input (blocking). |
$0202 |
STDOUT |
W |
Write a byte to the standard output. |
$0203 |
STDERR |
W |
Write a byte to the standard error. |
$0240 |
RAND |
R |
Read a random byte. |
$0241 |
FSTIN |
R |
Status of stdin: EOF if bit 7 set (blocks until decidable). |
When standard input is a terminal, it is line-buffered with echo and line editing; the program sees each line as it is entered. When it is redirected (a pipe or a file), the program receives it byte-for-byte.
Page 3 (addresses from $0300 to $03FF) will contain the command line arguments as a null-terminated list of null-terminated strings, truncated to fit the page (254 bytes plus the final two terminators).
Everything other than the I/O area is RAM, including the command line argument area, the program contents, and the interrupt vectors. Free areas will contain all zeroes.
Executing a CIM (also known as JAM, KIL, etc.) instruction crashes the program with exit code 2. On a crash (CIM or an access to an undefined I/O address), the emulator writes a debug dump to stderr: the CPU microstate, the registers, and a disassembly of the last instructions executed.
Sample programs
Executables for the sample programs are in the samples directory, assembled from the sources in src/samples with @sfotty-pie/spasm. Rebuild them with pnpm --filter @sfotty-pie/cli build:samples (after building spasm).
| Name | Description |
|---|---|
hello |
Prints "Hello world!" to stdout. |
cat |
Reads stdin and writes to stdout. |
echo |
Prints the arguments to stdout. |
guess |
Guess the number game. |
Run a built sample by passing its executable to the sfotty command (installed as a bin):
npx sfotty node_modules/@sfotty-pie/cli/samples/hello.65
npx sfotty node_modules/@sfotty-pie/cli/samples/echo.65 hello world
echo "meow" | npx sfotty node_modules/@sfotty-pie/cli/samples/cat.65
The sources are in node_modules/@sfotty-pie/cli/src/samples/. Assemble one yourself with the spasm assembler:
npx @sfotty-pie/spasm node_modules/@sfotty-pie/cli/src/samples/hello.s -o hello.65
npx sfotty hello.65
Ideas for future versions
- More I/O operations, such as file I/O and networking
- A
lib6502implementation - A
cc65library implementation
License and credits
MIT license.
- Fatih Aygün and contributors.