11# build - Build a disc image from files
22
33``` bash
4- beebtools build < dir> < output> [-t 40| 80] [--title TITLE] [--boot OFF| LOAD| RUN| EXEC] [--strict]
4+ beebtools build < dir> < output> [-t 40| 80] [--title TITLE] [--boot OFF| LOAD| RUN| EXEC] [--force] [-- strict]
55```
66
77Assembles a disc image from a directory of files with ` .inf ` sidecars. The
@@ -10,70 +10,81 @@ or `.adl`).
1010
1111## Source directory layout
1212
13- The source directory should have the same hierarchical layout produced by
14- ` extract -a --inf ` :
13+ The source directory should have the layout produced by ` extract -a ` . The
14+ builder supports both flat (default) and hierarchical layouts.
1515
16- - ** DFS** : one subdirectory per directory character (` $/ ` , ` T/ ` ), with each
17- data file accompanied by a ` .inf ` sidecar. For DSD images, ` side0/ ` and
18- ` side1/ ` subdirectories are expected.
16+ ### Flat layout (default from ` extract -a ` )
1917
20- - ** ADFS ** : a ` $ ` directory at the top level containing the file hierarchy,
21- with subdirectories matching the ADFS tree structure. Subdirectories are
22- created on the image automatically .
18+ All files sit in one directory, named by their full Acorn path with dots
19+ as separators. Each data file has a companion ` .inf ` sidecar. A ` $.inf `
20+ carries the disc title and boot option .
2321
24- ### DFS example layout
22+ ** DFS example: **
2523
2624```
2725working/
28- $/
29- BOOT
30- BOOT.inf # $.BOOT FF1900 FF8023 000100
31- MENU
32- MENU.inf # $.MENU FF0E00 FF802B 000400
33- T/
34- MYPROG
35- MYPROG.inf # T.MYPROG FF0E00 FF802B 000800
26+ $.inf # $ 00000000 00000000 00000000 00 TITLE=MY%20DISC OPT=3
27+ $.BOOT.bin
28+ $.BOOT.bin.inf # $.BOOT FF1900 FF8023 000100 00
29+ $.MENU.bas
30+ $.MENU.bas.inf # $.MENU FF0E00 FF802B 000400 00
31+ T.MYPROG.bas
32+ T.MYPROG.bas.inf # T.MYPROG FF0E00 FF802B 000800 00
33+ ```
34+
35+ ** ADFS example:**
36+
37+ ```
38+ working/
39+ $.inf
40+ $.GAMES.inf # directory metadata
41+ $.GAMES.ELITE.bin
42+ $.GAMES.ELITE.bin.inf # $.GAMES.ELITE FFFF0E00 FFFF802B 004000 00
43+ $.DATA.inf # directory metadata
44+ $.DATA.SCORES.bin
45+ $.DATA.SCORES.bin.inf # $.DATA.SCORES FF0000 FF0000 001000 00
3646```
3747
38- Each ` .inf ` file uses the standard DFS format: ` DIR.NAME LOAD EXEC SIZE [L] ` .
39- The directory character in the ` .inf ` content matches the subdirectory the file
40- sits in.
48+ For DSD images, the builder expects ` side0/ ` and ` side1/ ` subdirectories,
49+ each with its own flat layout and ` $.inf ` .
4150
42- ### ADFS example layout
51+ ### Hierarchical layout (from ` extract -a --mkdirs ` )
52+
53+ One subdirectory per DFS directory character or ADFS path. This is the
54+ layout produced when ` --mkdirs ` is passed to ` extract ` .
55+
56+ ** DFS example:**
4357
4458```
4559working/
60+ $.inf
4661 $/
47- BOOT
48- BOOT.inf # $.BOOT FF1900 FF8023 000100
49- GAMES/
50- ELITE
51- ELITE.inf # $.GAMES.ELITE FFFF0E00 FFFF802B 004000
52- DATA/
53- SCORES
54- SCORES.inf # $.GAMES.DATA.SCORES FF0000 FF0000 001000
62+ BOOT.bin
63+ BOOT.bin.inf # $.BOOT FF1900 FF8023 000100 00
64+ T/
65+ MYPROG.bas
66+ MYPROG.bas.inf # T.MYPROG FF0E00 FF802B 000800 00
5567```
5668
57- For ADFS, the directory tree on the filesystem mirrors the ADFS directory
58- hierarchy. Each ` .inf ` sidecar must contain the ** full ADFS path** of the file
59- (e.g. ` $.GAMES.ELITE ` , not just ` $.ELITE ` ), because ` build ` reads the path
60- from the ` .inf ` content when adding the file to the image.
69+ The builder auto-detects which layout is present by looking for ` .inf `
70+ sidecars in the source tree. Both layouts round-trip correctly.
6171
62- Subdirectories do not need their own ` .inf ` files - ` build ` creates them
63- automatically as it walks the filesystem tree.
72+ ### $.inf as source of truth
6473
65- ## Round-trip workflow
74+ When a ` $.inf ` exists in the source directory, the builder uses its
75+ ` TITLE= ` and ` OPT= ` values for the disc title and boot option. Explicit
76+ ` --title ` /` --boot ` flags emit a warning when they conflict with ` $.inf ` ;
77+ pass ` --force ` to override.
6678
67- The easiest way to get a valid source directory is to extract from an existing
68- image:
79+ ## Round-trip workflow
6980
7081``` bash
7182# DFS round-trip
72- beebtools extract original.ssd -a --inf - d working/
83+ beebtools extract original.ssd -a -d working/
7384beebtools build working/ modified.ssd --title " MODIFIED"
7485
7586# ADFS round-trip
76- beebtools extract original.adf -a --inf - d working/
87+ beebtools extract original.adf -a -d working/
7788beebtools build working/ modified.adf --title " MODIFIED"
7889```
7990
@@ -95,14 +106,12 @@ beebtools add mydisc.adf game.bin --name $.GAMES.ELITE --load 0E00 --exec 802B
95106
96107** Option 2: ` build ` ** (better for many files)
97108
98- Create the directory tree manually with ` .inf ` sidecars, then build in one
99- step. You must write the ` .inf ` files yourself with the correct paths and
100- addresses:
109+ Create a directory with ` .inf ` sidecars, then build in one step. You must
110+ write the ` .inf ` files yourself with the correct paths and addresses:
101111
102112``` bash
103- mkdir -p working/\$ /GAMES
104- echo ' $.LOADER 001900 001900 000400' > working/\$ /LOADER.inf
105- echo ' $.GAMES.ELITE FFFF0E00 FFFF802B 004000' > working/\$ /GAMES/ELITE.inf
113+ echo ' $.LOADER 001900 001900 000400 00' > working/$.LOADER.bin.inf
114+ echo ' $.GAMES.ELITE FFFF0E00 FFFF802B 004000 00' > working/$.GAMES.ELITE.bin.inf
106115# ... copy the actual data files alongside each .inf ...
107116beebtools build working/ mydisc.adf --title " MY DISC"
108117```
@@ -114,7 +123,7 @@ the builder places the file at that exact sector instead of allocating a fresh
114123range. This enables byte-exact round-trips on discs whose catalogue entries
115124share sectors (notably Level 9 copy-protected games).
116125
117- ` extract -a --inf ` writes ` X_START_SECTOR ` on every sidecar automatically, so
126+ ` extract -a ` writes ` X_START_SECTOR ` on every sidecar automatically, so
118127the default extract-and-rebuild cycle preserves original sector positions without
119128any extra flags.
120129
@@ -131,6 +140,9 @@ for the full story.
131140
132141- ` --boot ` - boot option: OFF, LOAD, RUN, or EXEC (numbers 0-3 also accepted)
133142
143+ - ` --force ` - override ` $.inf ` disc metadata with explicit ` --title ` /` --boot `
144+ values
145+
134146- ` --strict ` - enforce DFS spec-compliance on filenames. Rejects non-printable
135147 bytes, ` . ` , ` # ` , ` * ` , ` : ` , ` " ` , and space. Use when authoring new discs where
136148 spec conformance matters. Default behaviour accepts any 7-bit byte, matching
0 commit comments