Cookbook¶
Recipes for common tasks using the oaknut Python API.
Reading files from a DFS floppy¶
from oaknut.dfs import DFS, ACORN_DFS_80T_SINGLE_SIDED
with DFS.from_file("games.ssd", ACORN_DFS_80T_SINGLE_SIDED) as dfs:
for entry in dfs.root.iterdir():
for child in entry.iterdir():
st = child.stat()
print(f"{child.path:12s} {st.load_address:08X} {st.length}")
Creating a DFS floppy from scratch¶
from oaknut.dfs import DFS, ACORN_DFS_80T_SINGLE_SIDED
with DFS.create_file("new.ssd", ACORN_DFS_80T_SINGLE_SIDED, title="MY DISC") as dfs:
(dfs.root / "$.HELLO").write_bytes(
b'PRINT "Hello!"\r',
load_address=0xFFFF,
exec_address=0xFFFF,
)
(dfs.root / "$.DATA").write_bytes(
b"\x00" * 256,
load_address=0x3000,
)
Working with ADFS images¶
from oaknut.adfs import ADFS
# Open a floppy image (format auto-detected from size)
with ADFS.from_file("disc.adl") as adfs:
print(f"Title: {adfs.title}")
print(f"Free: {adfs.free_space:,} bytes")
print(f"Geometry: {adfs.geometry}")
for entry in adfs.root.iterdir():
print(f" {entry.name}")
# Create a hard disc image
with ADFS.create_file("scsi0.dat", capacity_bytes=10*1024*1024, title="Server") as adfs:
(adfs.root / "ReadMe").write_bytes(b"Hello from ADFS\r")
(adfs.root / "Programs").mkdir()
(adfs.root / "Programs" / "Test").write_bytes(b"test data")
Accessing AFS partitions¶
An AFS partition lives in the tail cylinders of an ADFS hard disc image. Access it through the ADFS handle:
from oaknut.adfs import ADFS
with ADFS.from_file("scsi0.dat") as adfs:
afs = adfs.afs_partition
if afs is None:
print("No AFS partition")
else:
print(f"AFS disc name: {afs.disc_name}")
print(f"Free sectors: {afs.free_sectors}")
for user in afs.users.active:
flag = "S" if user.is_system else " "
print(f" {flag} {user.full_id}")
for entry in afs.root.iterdir():
print(f" {entry.name}")
Copying files between disc images¶
Use oaknut.file.copy_file() to copy a file between any two
path objects (DFS, ADFS, or AFS), with access attribute mapping:
from oaknut.adfs import ADFS
from oaknut.dfs import DFS, ACORN_DFS_80T_SINGLE_SIDED
from oaknut.file import copy_file
with DFS.from_file("source.ssd", ACORN_DFS_80T_SINGLE_SIDED) as dfs:
src = dfs.path("$.HELLO")
with ADFS.from_file("target.adl", mode="r+b") as adfs:
dst = adfs.root / "Hello"
copy_file(src, dst, target_fs="adfs")
Exporting with metadata sidecars¶
from pathlib import Path
from oaknut.adfs import ADFS
from oaknut.file import AcornMeta, MetaFormat, export_with_metadata
with ADFS.from_file("disc.adl") as adfs:
for entry in adfs.root.iterdir():
if entry.is_dir():
continue
data = entry.read_bytes()
st = entry.stat()
meta = AcornMeta(
load_addr=st.load_address,
exec_addr=st.exec_address,
attr=int(st.access),
)
export_with_metadata(
data,
Path("output") / entry.name,
meta,
meta_format=MetaFormat.INF_TRAD,
)
Initialising an AFS partition¶
from oaknut.adfs import ADFS
from oaknut.afs.wfsinit import AFSSizeSpec, InitSpec, UserSpec, initialise
from oaknut.afs.libraries import emplace_library
with ADFS.create_file("server.dat", capacity_bytes=10*1024*1024) as adfs:
# Partition and initialise AFS
initialise(
adfs,
spec=InitSpec(
disc_name="Server",
size=AFSSizeSpec.cylinders(200),
users=[
UserSpec("Syst", system=True),
UserSpec("guest", quota=2*1024*1024),
],
),
)
# Emplace library files
afs = adfs.afs_partition
with afs:
emplace_library(afs, "Library")
emplace_library(afs, "Library1")