Expand description
§a2kit
main library
This library manipulates disk images suitable for emulators, with emphasis on Apple II. Manipulations can be done at a level as low as track bits, or as high as language files.
§Architecture
Disk image operations are built around three trait objects:
img::DiskImage
encodes/decodes disk tracks, does not try to interpret a file systemfs::DiskFS
imposes a file system on the already decoded track data- don’t confuse
std::fs
anda2kit::fs
- don’t confuse
fs::FileImage
provides a representation of a file that can be restored to a disk image
When a DiskFS
object is created it takes ownership of some DiskImage
.
It then uses this owned image as storage. Any changes are not permanent until the
image is saved to whatever file system is hosting a2kit.
§Language Services
Language modules are designed to be complementary to the needs of language servers that use the language server protocol (LSP). Specific language services are in modules named after the language, at present:
lang::applesoft
handles Applesoft BASIClang::integer
handles Integer BASIClang::merlin
handles Merlin assembly language
The language servers are in bin
and compile to separate executables. The language servers
and CLI both depend on lang
, but do not depend on each other.
§File Systems
In order to manipulate files, a2kit
must understand the file system it finds on the disk image.
As of this writing a2kit
supports
- CP/M 1,2,3
- Apple DOS 3.x
- FAT (e.g. MS-DOS)
- ProDOS
- Pascal File System
A simple example follows:
// DiskFS is always mutable because the underlying image can be stateful.
let mut disk = a2kit::create_fs_from_file("disk.woz")?;
// Get a text file from the disk image as a String.
let text = disk.read_text("README")?;
§Disk Images
In order to manipulate tracks and sectors, a2kit
must understand the way the track data is packed
into a disk image. As of this writing a2kit
supports
format | platforms | aliases |
---|---|---|
2MG | Apple II | |
D13 | Apple II | |
DO | Apple II | DSK |
PO | Apple II | DSK |
IMD | CP/M, FAT | |
IMG | FAT | DSK, IMA |
NIB | Apple II | |
TD0 | CP/M, FAT | |
WOZ | Apple II |
A simple example follows:
// DiskImage can be stateful and therefore is always mutable
let mut img = a2kit::create_img_from_file("disk.woz")?;
// Unlike DiskFS, we cannot access files, only tracks and sectors
let sector_data = img.read_sector(0,0,0)?;
// Disk images are *always* buffered, so writing only affects memory
img.write_sector(0,0,1,§or_data)?;
// Save the changes to local storage
a2kit::save_img(&mut img,"disk.woz")?;
§Disk Kinds
A disk image can typically represent some number of disk kinds (defined by mechanical and
encoding characteristics). The kinds a2kit
supports include
- Logical ProDOS volumes
- 3 inch CP/M formats (Amstrad 184K)
- 3.5 inch Apple formats (400K/800K)
- 3.5 inch IBM formats(720K through 2880K)
- 5.25 inch Apple formats (114K/140K)
- 5.25 inch IBM formats (160K through 1200K)
- 5.25 inch CP/M formats (Osborne 100K/200K, Kaypro 200K/400K)
- 8 inch CP/M formats (IBM 250K, Nabu 1M, TRS-80 600K)
Modules§
- BIOS module
- CLI Subcommands
- File System Module
- Disk Image Module
- Language Module
Macros§
- Get a byte value from the image into a JSON object as a hex string.
- Get a byte value from the image into a JSON object, adding the
_raw
terminus. The_pretty
terminus has to be added by hand. - get a multi-byte value from the image into a JSON object as hex string
- Get a multi-byte value from the image into a JSON object, adding the
_raw
terminus. The_pretty
terminus has to be added by hand. - Parse a hex string containing one byte and put value into the image using the given key path.
- Parse a hex string containing multiple bytes and put value into the image using the given key path.
- Put a variable length UTF8 string into the image using the given key path.
- Put a fixed length UTF8 string into the image using the given key path.
Structs§
- Cursor to walk a JSON tree.
Functions§
- Given a bytestream return a DiskFS, or Err if the bytestream cannot be interpreted. Optional
maybe_ext
restricts the image types that will be tried based on file extension. - Calls
create_fs_from_bytestream
getting the bytes from a file. The pathname must already be in the right format for the file system. File extension will be used to restrict image types that are tried, unless the extension is unknown, in which case all will be tried. - Calls
create_fs_from_bytestream
getting the bytes from stdin. All image types and file systems will be tried heuristically. - Given a bytestream return a disk image without any file system. Optional
maybe_ext
restricts the image types that will be tried based on file extension. N.b. the ordering for DSK types cannot always be determined without the file system. - Calls
create_img_from_bytestream
getting the bytes from a file. The pathname must already be in the right format for the file system. File extension will be used to restrict image types that are tried, unless the extension is unknown, in which case all will be tried. - Calls
create_img_from_bytestream
getting the bytes from stdin. All image types will be tried heuristically. - Display binary to stdout in columns of hex, +ascii, and -ascii
- This takes any bytes and makes an ascii friendly string by using hex escapes, e.g.,
\xFF
. ifescape_cc
is true, ascii control characters are also escaped. ifinverted
is true, assume we have negative ascii bytes. This is intended for directory strings, for language files uselang::bytes_to_escaped_string
- Calls
parse_escaped_ascii
withcaps=true
- Interpret a UTF8 string as pure ascii and put into bytes. Non-ascii characters are omitted from the result, but arbitrary bytes can be introduced using escapes, e.g.,
\xFF
. Literal hex escapes are created by coding the backslash, e.g.,\x5CxFF
. ifinverted
is true the sign of the non-escaped bytes is flipped. ifcaps
is true the ascii is put in upper case. This is suitable for either languages or directory strings. - Save the image file (make changes permanent)