[][src]Crate pir_8_emu

An implementation of the pir-8 ISA.

The library

pir-8-emu can be thought of as consisting of layers:

The first layer is the isa module, which contains a pure implementation of the pir-8 ISA, and can be used on its own to parse/generate binaries and assembly at the instruction level.

The second layer is the vm module, which contains parts of VM memory and port handling.

The third layer is the micro module, which contains a full stack-based microcode implementation, and can be used to fully emulate a pir-8 machine (see example inside).

The fourth layer is the various binutils, which contain useful parts of the executables, like AssemblerDirective and OutputWithQueue, or NativePortHandler.

These utilities can be used to quickly and correctly build off existing solutions, but may have some quirks or be less absolutely generic (e.g. Vm will allow you to integrate a fully (as-emulator) controllable and functional pir-8 virtual machine in about 5 lines, but it needs to have the INS SP register be observed after each μOp (see example inside)).

The binaries

The headers link to manpages with more detailed usage instructions:

pir-8-as

An assembler with an… idiosyncratic syntax:

LOAD IMM WIDE C&D
:label load-offset full message -1

:label save loop
MOVE D X
LOAD IMM BYTE Y
1
ALU ADD
MOVE S D
MOVE C X
LOAD IMM BYTE Y
0
ALU ADDC
MOVE S C
MADR WRITE C&D

LOAD IMM BYTE A
0                ; port number
LOAD IND B
PORT OUT B

MOVE B S
COMP S

LOAD IMM WIDE ADR
:label load full end
JMZG
LOAD IMM WIDE ADR
:label load full loop
JUMP

:label save end
HALT


:label save message
:literal "*pounces on u* OwO what's whis?"

If you'd rather use a more normal syntax, CatPlusPlus has also made a fasm-based assembler:

include 'pir8.finc'

origin 0x0002

	load a, [0x0000]
	load b, [0x0001]

top:
	move x, a
	move y, b
	sub

	jmpz exit

	move s, a
	comp b

	jmpl lt

	sub
	move a, s
	jump top

lt:
	move y, a
	move x, b
	sub
	move b, s
	jump top

exit:
	move d, a
	halt

pir-8-disasm

A dissassembler with a ndisasm-based frontend:

$ pir-8-disasm -k 0x27,31 test-data/copy-any-length-literal-to-port.p8b
00000000   1E   LOAD IMM C
00000001   00 D 0x00
00000002   1A   LOAD IMM X
00000003   27 D 0x27
00000004   1B   LOAD IMM Y
00000005   01 D 0x01
00000006   31   ALU SUB
00000007   4A   MOVE S X
00000008   4F   MOVE S D
00000009   7A   MOVE D X
0000000A   1B   LOAD IMM Y
0000000B   01 D 0x01
0000000C   30   ALU ADD
0000000D   4F   MOVE S D
0000000E   72   MOVE C X
0000000F   1B   LOAD IMM Y
00000010   00 D 0x00
00000011   32   ALU ADDC
00000012   4E   MOVE S C
00000013   0D   MADR WRITE C&D
00000014   1C   LOAD IMM A
00000015   00 D 0x00
00000016   25   LOAD IND B
00000017   E5   PORT OUT B
00000018   69   MOVE B S
00000019   F1   COMP S
0000001A   1C   LOAD IMM A
0000001B   00 D 0x00
0000001C   1D   LOAD IMM B
0000001D   26 D 0x26
0000001E   0C   MADR WRITE A&B
0000001F   14   JMZG
00000020   1C   LOAD IMM A
00000021   00 D 0x00
00000022   1D   LOAD IMM B
00000023   09 D 0x09
00000024   0C   MADR WRITE A&B
00000025   17   JUMP
00000026   FF   HALT
00000027      S skipping 0x1F bytes

pir-8-emu

The emulator in-of itself:

Emulator screenshot

Example programs

Apart from the two forthlaid above, take a look at the test-data/ directory in the git repo, which contains a mix of assembler programs (.p8a), program binaries (.p8b), and derivations/hand-assemblies (.diz).

Native handlers

For more information, consult the documentation on RawNativePortHandler.

For examples, take a look at the handler-examples/ directory in the git repo. Running make at the root thereof should build them without much hassle, if it doesn't, please open an issue.

The include/pir-8-emu/port_handler.h file contains C declarations.

Special thanks

To all who support further development on Patreon, in particular:

  • ThePhD

Modules

binutils

Additional utilities used to implement the binaries

isa

All data specified directly in the ISA.

micro

Microcode implementation

options

Executable option parsing and management.

util

Module containing various utility functions.

vm

Various parts of the virtual machine implementation

Structs

ReadWriteMarker

Marker for wrapper types that need to track when they were read from/written to.

Traits

ReadWritable

Generic trait for objects that can track whether they've been read from and/or written to.