Documentatie › SEDORIC
SEDORIC-schijfformaat & gereedschap
Primaire referentie: de SEDORIC 3.0-handleiding (sedna3_0.pdf),
gecontroleerd tegen «SEDORIC 3.0 à NU» van A. Chéramy en het gereedschap van het SCUMM-Oric / scoop-oric-project.
Niets is verzonnen: de onderstaande offsets zijn die van de handleiding, byte-exact geverifieerd tegen
de descriptordump die de handleiding zelf als voorbeeld geeft.
1. MFM_DISK-container
Header van 256 b: "MFM_DISK" + sides (u32 LE) + tracks (u32 LE) + geometry
(u32 LE). Daarna een trackblok van 6400 b per (kant, track), in SIDE-MAJOR-volgorde:
alle tracks van kant 0, dan alle van kant 1 (blok = side * tracks + track).
Elk trackblok: begingap 60×$4E, dan per sector
12×$00 | A1 A1 A1 FE [trk side sec size] CRC | 22×$4E | 12×$00 | A1 A1 A1 FB [256 data] CRC | 38×$4E,
$4E-opvulling tot 6400 b. CRC-16/CCITT (poly $1021, init $FFFF) over de 4
markerbytes + de data.
Een RAW-image (256-byte-sectoren aaneengeschakeld, dezelfde side-major-volgorde, zonder framing)
wordt geaccepteerd door sedoric-info en geproduceerd door oric1-emu --disk-create /
tools/sedoric_inject.py. tools/dsk_raw2mfm.py converteert RAW → MFM_DISK.
2. Systeemsectoren (track 20)
| Sector | Rol | Sleutelvelden |
|---|---|---|
| s1 Systeem | schijfnaam + autoexec | +9..+29 schijfnaam (21 b) · +0x1E..+0x59 INIST (60 b: ASCII-bootcommando's, gescheiden door :, afgesloten met #00) |
| s2 VTOC/bitmap | tellers | +2,+3 vrije sectoren (LE) · +4,+5 aantal bestanden (LE) |
| s4 Directory | catalogus | +0,+1 link naar volgende dir-sector (0=einde) · +2 high-water mark · 16-byte-items vanaf +16 |
Directory-item (16 b): name[9] ext[3] track sector
nsec status (V4 geldig bestand = $40; bit 7 = verwijderd).
Opmerking (gezien op Master-schijven): de VTOC-free/files-teller kan een
80-track-sjabloon zijn dat op een kleinere fysieke image is gestempeld — een sjabloon, geen herberekende
staat. sedoric-info rapporteert daarom zowel de VTOC-teller als het aantal bestanden dat werkelijk in de
catalogus is doorlopen.
3. Bestandsdescriptorsector
Aangewezen door het directory-item (track,sector). Echte dump uit de
handleiding (descriptor van het BANQUE-#7-systeembestand, p.16):
0 1 2 3 4 5 6 7 8 9 A B C D E F
00 00 FF 40 00 C4 FF C7 00 00 04 00 05 0B 05 0C 05 0D 05 0E 00 00
| Offset | Veld | Voorbeeld |
|---|---|---|
+0,+1 | link naar volgende descriptor (00 00 = geen) | 00 00 |
+2 | eerste-descriptor-marker | FF |
+3 | type: b0=AUTO, b6=datablok, b7=BASIC → $40=ML, $41=AUTO ML | 40 |
+4,+5 | laadadres (LE) | 00 C4 = $C400 |
+6,+7 | eindadres (LE) | FF C7 = $C7FF |
+8,+9 | uitvoeradres als AUTO (LE) | 00 00 |
+0xA,+0xB | aantal datasectoren (LE) | 04 00 = 4 |
+0xC.. | datasectorkaart (track,sector)×n, afgesloten 00 00 | 05 0B 05 0C 05 0D 05 0E 00 00 |
Deze dump corrigeert de oude tap2sedoric-implementatie die +3=0 liet (geen
type) en het sectoraantal op +9,+10 in big-endian schreef (overlappend met het uitvoeradres).
Gecorrigeerd sinds v1.64.0.
Geketende descriptoren (bestanden > 122 sectoren) — gevalideerd
Een descriptorsector bevat slechts een deel van de kaart: de 1e descriptor draagt de header (12 b)
en dan de kaart vanaf +0x0C (122 paren max, 0x0C..0xFE); elke volgende
descriptor draagt alleen de link +0,+1 en dan de kaart vanaf +0x02 (127
paren max). De link +0,+1 wijst naar de volgende descriptor (00 00 = laatste).
+0xA,+0xB (1e descriptor) = totaal aantal datasectoren. In situ
gevalideerd: een bestand van 150 sectoren (2 descriptoren) volledig geladen door LOAD.
tap2sedoric en sedoric_inject.py ketenen sinds v1.65.0.
4. Gereedschap
| Tool | Rol |
|---|---|
tap2sedoric <in.tap> -o out.dsk -b base.dsk [-n NAME.EXT] [-a] [-e EXEC] [-i "INIST"] | injecteert een CSAVE-.tap in een MFM-Sedoric-schijf (bestand + conforme descriptor + dir-item + VTOC; -a/-e AUTO, -i boot-autoexec) |
sedoric-info <disk.dsk> [--check FREE:FILES] | inspecteert VTOC, schijfnaam, INIST, catalogus en gedecodeerde descriptoren; --check = regressiebewaking op de tellers |
tools/sedoric_inject.py … | RAW-injectie (directe offsets) |
tools/dsk_raw2mfm.py <raw> <out.dsk> … | RAW → MFM_DISK (side-major-blokken) |
Typische RAW-keten: oric1-emu --disk-create base.raw (dan INIT bij boot voor een echte VTOC) →
sedoric_inject.py → dsk_raw2mfm.py → oric1-emu --disk-rom microdis.rom -d.
5. Multi-bestandsinjectie (limiet opgeheven)
Historisch alloceerden zowel tap2sedoric als sedoric_inject.py altijd vanaf
track 21 sector 1 zonder de reeds bezette sectoren te raadplegen: een tweede injectie op dezelfde schijf
overschreef de eerste.
Sinds v1.64.0 doorlopen beide tools de catalogus (volledige keten) en de sectorkaarten van de bestaande
descriptoren — inclusief de geketende catalogussectoren zelf — om bezette sectoren te markeren
vóór het alloceren. Geverifieerd door make test-sedoric-tools.
Directory-sectorketening (geïmplementeerd)
Wanneer de huidige catalogussector vol is (15 items), doorlopen de tools de keten via de link
+0,+1; als de hele keten vol is, alloceren ze een vrije sector, initialiseren die als lege catalogus
en ketenen die aan. Omdat catalogussectoren worden gelokaliseerd via track/sector-link, kan een geketende
catalogus op elke vrije sector staan. In situ gevalideerd.
6. Een machinecodebestand uitvoeren onder Sedoric (in situ gevalideerd recept)
Laden/uitvoeren geverifieerd in de emulator (bare boot + LOAD). Aangetroffen valkuilen en opgelost:
| Commando / geval | Resultaat |
|---|---|
PROBE typen (kale naam) bij Ready | ?SYNTAX ERROR — een kale naam start alleen een AUTO-BASIC |
LOADM"PROBE" | ?TYPE MISMATCH — LOADM is het cassette-ROM-commando |
CLOAD"PROBE" | geen fout maar laadt niets (BASIC-bestanden) |
LOAD"PROBE" op .BIN | ?FILE NOT FOUND — .COM is de standaardextensie |
LOAD"PROBE",J op AUTO | BREAK ON BYTE #5000 — ,J botst met de AUTO-flag |
LOAD"PROBE" op .COM AUTO (type $41) | laadt EN voert uit ✅ |
Recept: injecteer als .COM AUTO (tap2sedoric … -n NAME.COM -a -e EXEC),
dan bij Ready: LOAD"NAME". Het Sedoric-commando is LOAD
(detecteert BASIC vs binair automatisch via de typebyte +3), met opties ,A (adres) en
,J (jump).
Kale opstartbare Sedoric-master (deterministisch)
Om een zelfgemaakte .COM te valideren heb je een schijf nodig die naar Ready opstart zonder
concurrerende applicatie. Robuuste, timing-vrije methode:
tools/sedoric_mkbare.py disks/SEDO40u.DSK bare.dsk # neutraliseert de INIST
tools/sedoric_mkbare.py disks/SEDO40u.DSK auto.dsk 'LOAD"PROBE"' # of auto-start
Het neutraliseert (of vervangt) de INIST (track 20 sector 1, +0x1E..+0x59, MFM-sector-CRC
opnieuw berekend; RAW ook afgehandeld) → de schijf valt terug naar een kale SEDORIC V4.0 / Ready maar blijft
opstartbaar.
Een bestand laden vanuit machinecode (in situ gevalideerd recept)
Vanuit een draaiend ML-programma (gestart door LOAD) is de Sedoric-RAM-overlay niet
gemapt: de DOS-routines direct aanroepen ($DB2D zoeken, $E0EA lezen)
crasht. De robuuste weg loopt via de «!»-vector $0467 (in laag RAM, altijd
gemapt), die naar de overlay schakelt, de SEDORIC-interpreter ($D3AE) uitvoert op de regel aangewezen door
TXTPTR ($00E9/$00EA), en dan terugschakelt en RTS doet.
LDA #<CMD : STA $E9 ; TXTPTR = adres van de commandoregel
LDA #>CMD : STA $EA
JSR $0467 ; "!"-vector: voert het commando uit (overlay geregeld)
; ... bestand geladen; normale voortzetting ...
RTS
CMD: .byte "LOAD\"SCDATA\"", 0 ; SEDORIC-regel afgesloten met $00
Valkuil: de regel moet worden afgesloten met $00,
nooit met CR ($0D). Met CR voltooit de $D3AE-interpreter niet en doet geen
RTS. TXTPTR wijst naar het eerste teken (de L).
Sedoric-RAM-overlay ↔ BASIC-ROM-schakeling (gevalideerd)
Vanuit een door LOAD gestart ML-programma is de BASIC-ROM gemapt op $C000-$FFFF:
systeemvariabelen en routines staan in de overlay → schakel vóór elke
$C000+-toegang. Eenvoudigst: JSR $0477 (Sedoric-stub in laag RAM) — een
ROM↔overlay-toggle die station/kant/IRQ behoudt via de $04FB-shadow:
PHP:PHA:SEI : LDA $04FB : EOR #$02 : STA $04FB : STA $0314 : PLA:PLP:RTS
$0314-waarden: bit 1 (ROMDIS, $02) = 0 → RAM-overlay $C000-$DFFF,
= 1 → BASIC-ROM; bit 7 (EPROM, $80) = 1 → RAM-overlay $E000-$FFFF. Omdat
$0314 alleen-schrijven is, ga via de $04FB-shadow of $0477.
Een bestand per sector op een offset lezen (willekeurige toegang) — gevalideerd
Om N bytes op een offset te lezen zonder het hele bestand te laden. Overlay ON ($0477)
vereist.
BUFNOMgevuld +JSR $DB2D(SEARCH) →X = POSNMX, catalogussector in BUF3.LDA $C30C,X : LDY $C30D,X : JSR $DA5D→ descriptor geladen in BUF1 ($C100).- BUF1-indeling:
$C100/01volgende-descriptor-link ·$C102=FF·$C103type ·$C104-05load ·$C106-07end ·$C108-09exec ·$C10A-0Bsectoraantal · kaart vanaf$C10C. sect_index = off/256,byte_in_sect = off & 255. Stel DRIVE$C000, TRACK$C001, SECTOR$C002, RWBUF$C003/$C004in.JSR $DA73(XPRSEC). KopieerNbytes vanafbuffer + byte_in_sect.
XRWTS/XPRSEC-interface (handleiding, byte-exact): DRIVE $C000, TRACK $C001 (b7=kant
B), SECTOR $C002, RWBUF $C003/$C004. $C009 = DRVDEF, $C00A = DRVSYS.
Gereproduceerd uit docs/SEDORIC.md (gezaghebbende, actuele versie op GitHub, met de volledige recepten).