cpm

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 28, 2024 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package cpm is the main package for our emulator, it uses memory to emulate execution of things at the bios level.

The package mostly contains the implementation of the syscalls that CP/M programs would expect - along with a little machinery to wire up the Z80 emulator we're using and deal with FCB structures.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrExit will be used to handle a CP/M binary calling Exit.
	//
	// It should be handled and expected by callers.
	ErrExit = errors.New("EXIT")

	// ErrHalt will be used to note that the Z80 emulator executed a HALT
	// operation, and that terminated the execution of code.
	//
	// It should be handled and expected by callers.
	ErrHalt = errors.New("HALT")

	// ErrUnimplemented will be used to handle a CP/M binary calling an unimplemented syscall.
	//
	// It should be handled and expected by callers.
	ErrUnimplemented = errors.New("UNIMPLEMENTED")
)

Functions

func SysCallAuxRead added in v0.5.0

func SysCallAuxRead(cpm *CPM) error

SysCallAuxRead reads a single character from the auxillary input.

NOTE: Documentation implies this is blocking, but it seems like tastybasic and mbasic prefer it like this

func SysCallAuxWrite added in v0.5.0

func SysCallAuxWrite(cpm *CPM) error

SysCallAuxWrite writes the single character in the C register auxillary / punch output

func SysCallBDOSVersion added in v0.3.0

func SysCallBDOSVersion(cpm *CPM) error

SysCallBDOSVersion returns version details

func SysCallConsoleStatus added in v0.5.0

func SysCallConsoleStatus(cpm *CPM) error

SysCallConsoleStatus fakes a test for pending console (character) input.

func SysCallDeleteFile

func SysCallDeleteFile(cpm *CPM) error

SysCallDeleteFile deletes the filename(s) matching the pattern specified by the FCB in DE.

func SysCallDriveAllReset added in v0.2.0

func SysCallDriveAllReset(cpm *CPM) error

SysCallDriveAllReset resets the drives.

TODO: If there is a file named "$..." then we need to return 0xFF in A, which will be read by the CCP - as created by SUBMIT.COM

func SysCallDriveGet

func SysCallDriveGet(cpm *CPM) error

SysCallDriveGet returns the number of the active drive.

func SysCallDriveSet

func SysCallDriveSet(cpm *CPM) error

SysCallDriveSet updates the current drive number

func SysCallExit

func SysCallExit(cpm *CPM) error

SysCallExit implements the Exit syscall

func SysCallFileClose

func SysCallFileClose(cpm *CPM) error

SysCallFileClose closes the filename that matches the pattern on the FCB supplied in DE

func SysCallFileOpen

func SysCallFileOpen(cpm *CPM) error

SysCallFileOpen opens the filename that matches the pattern on the FCB supplied in DE

func SysCallFindFirst

func SysCallFindFirst(cpm *CPM) error

SysCallFindFirst finds the first filename, on disk, that matches the glob in the FCB supplied in DE.

func SysCallFindNext

func SysCallFindNext(cpm *CPM) error

SysCallFindNext finds the next filename that matches the glob set in the FCB in DE.

func SysCallGetDriveDPB

func SysCallGetDriveDPB(cpm *CPM) error

SysCallGetDriveDPB returns the address of the DPB, which is faked.

func SysCallGetIOByte added in v0.5.0

func SysCallGetIOByte(cpm *CPM) error

SysCallGetIOByte gets the IOByte, which is used to describe which devices are used for I/O. No CP/M utilities use it, except for STAT and PIP.

The IOByte lives at 0x0003 in RAM, so it is often accessed directly when it is used.

func SysCallLoginVec added in v0.3.0

func SysCallLoginVec(cpm *CPM) error

SysCallLoginVec returns the list of logged in drives.

func SysCallMakeFile

func SysCallMakeFile(cpm *CPM) error

SysCallMakeFile creates the file named in the FCB given in DE

func SysCallRawIO

func SysCallRawIO(cpm *CPM) error

SysCallRawIO handles both simple character output, and input.

func SysCallRead added in v0.2.0

func SysCallRead(cpm *CPM) error

SysCallRead reads a record from the file named in the FCB given in DE

func SysCallReadChar

func SysCallReadChar(cpm *CPM) error

SysCallReadChar reads a single character from the console.

func SysCallReadRand

func SysCallReadRand(cpm *CPM) error

SysCallReadRand reads a random block from the FCB pointed to by DE into the DMA area.

func SysCallReadString

func SysCallReadString(cpm *CPM) error

SysCallReadString reads a string from the console, into the buffer pointed to by DE.

func SysCallRenameFile added in v0.5.0

func SysCallRenameFile(cpm *CPM) error

SysCallRenameFile will handle a rename operation. Note that this will not handle cross-directory renames (i.e. file moving).

func SysCallSetDMA added in v0.3.0

func SysCallSetDMA(cpm *CPM) error

SysCallSetDMA updates the address of the DMA area, which is used for block I/O.

func SysCallSetIOByte added in v0.5.0

func SysCallSetIOByte(cpm *CPM) error

SysCallSetIOByte sets the IOByte, which is used to describe which devices are used for I/O. No CP/M utilities use it, except for STAT and PIP.

The IOByte lives at 0x0003 in RAM, so it is often accessed directly when it is used.

func SysCallUserNumber

func SysCallUserNumber(cpm *CPM) error

func SysCallWrite added in v0.2.0

func SysCallWrite(cpm *CPM) error

SysCallWrite writes a record to the file named in the FCB given in DE

func SysCallWriteChar

func SysCallWriteChar(cpm *CPM) error

SysCallWriteChar writes the single character in the E register to STDOUT.

func SysCallWriteRand added in v0.3.0

func SysCallWriteRand(cpm *CPM) error

SysCallWriteRand writes a random block from DMA area to the FCB pointed to by DE.

func SysCallWriteString

func SysCallWriteString(cpm *CPM) error

SysCallWriteString writes the $-terminated string pointed to by DE to STDOUT

Types

type CPM

type CPM struct {

	// Syscalls contains the syscalls we know how to emulate, indexed
	// by their ID.
	Syscalls map[uint8]CPMHandler

	// Memory contains the memory the system runs with.
	Memory *memory.Memory

	// CPU contains a pointer to the virtual CPU we use to execute
	// code.  The CP/M we're implementing is Z80-based, so we need to
	// be able to emulate that.
	CPU z80.CPU

	// Drives specifies whether we use sub-directories for the
	// CP/M drives we emulate, instead of the current working directory.
	Drives bool

	// Reader is where we get our STDIN from.
	//
	// TODO: We should have something similar for STDOUT.
	Reader *bufio.Reader

	// Logger holds a logger which we use for debugging and diagnostics.
	Logger *slog.Logger
	// contains filtered or unexported fields
}

CPM is the object that holds our emulator state

func New

func New(logger *slog.Logger) *CPM

New returns a new emulation object

func (*CPM) Execute

func (cpm *CPM) Execute(args []string) error

Execute executes our named binary, with the specified arguments.

The function will not return until the process being executed terminates, and any error will be returned.

func (*CPM) In added in v0.5.0

func (cpm *CPM) In(addr uint8) uint8

In is called to handle the I/O reading of a Z80 port.

This is called by our embedded Z80 emulator.

func (*CPM) LoadBinary added in v0.3.0

func (cpm *CPM) LoadBinary(filename string) error

LoadBinary loads the given CP/M binary at the default address of 0x0100, where it can then be launched by Execute.

func (*CPM) LoadCCP added in v0.3.0

func (cpm *CPM) LoadCCP()

LoadCCP loads the CCP into RAM, to be executed instead of an external binary.

This function modifies the "start" attribute, to ensure the CCP is loaded and executed at a higher address than the default of 0x0100.

func (*CPM) Out added in v0.5.0

func (cpm *CPM) Out(addr uint8, val uint8)

Out is called to handle the I/O writing to a Z80 port.

This is called by our embedded Z80 emulator, and this will be used by any system which used RST instructions to invoke the CP/M syscalls, rather than using "CALL 0x0005". Notable offenders include Microsoft's BASIC.

func (*CPM) SetDrives added in v0.3.0

func (cpm *CPM) SetDrives(enabled bool)

SetDrives enables/disables the use of subdirectories upon the host system to represent CP/M drives

type CPMHandler

type CPMHandler struct {
	// Desc contain the human-readable description of the given CP/M syscall.
	Desc string

	// Handler contains the function which should be involved for this syscall.
	Handler CPMHandlerType
}

CPMHandler contains details of a specific call we implement.

While we mostly need a "number to handler", mapping having a name is useful for the logs we produce.

type CPMHandlerType

type CPMHandlerType func(cpm *CPM) error

CPMHandlerType contains the signature of a CP/M bios function.

It is not expected that outside packages will want to add custom BIOS functions, or syscalls, but this is public so that it could be done if it was necessary.

type FileCache added in v0.3.0

type FileCache struct {
	// contains filtered or unexported fields
}

FileCache is used to cache filehandles, against FCB addresses.

This is primarily done as a speed optimization.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL