Kuidas lugeda/kirjutada JUKU ketaste tõmmiseid?¶
Aastal 2022 ei olnud veel dokumenteeritud, millega ja kuidas lugeda JUKU kahepoolseid flopisid ja huvilised katsetasid kettatõmmiste lugemist eri tööriistadega, saavutades mõnedega neist osalist edu. Allolev on kogemuslugu sellest, kuidas võtsin kätte ja närisin end läbi JUKU flopiketta andmevormingust, mida selle käigus õppisin ja pidasin vajalikuks avalikkusega jagada. Lugu on täiendatud üldistava raamistuse, täpsemate arvutuste ja praktiliste soovitustega lõpuosas.
JUKU 786/788 kB kettad on kahepoolsed topelttihedusega (DSDD) kettad, millel on kummalgi poolel 80 rada, mis on jaotatud 40 sektorisse, millest igaüks mahutab 128 baiti. See teeb kokku 2x80 = 160 rada, 40x128 = 5120 baiti ehk 5 kB ja kokku ketta suuruseks 160x5120 = 819 200 baiti ehk 819 kB. Lugemise teeb keerukaks, et need baidid pole talletatud sisu mõttes mitte järjest, vaid "segamini paisatud". Seetõttu ei või seda võtta järjestikuse 819 kB andmekogumina ja selle osiste olemasolu ignoreerida, vaid tuleb segadus selle eri taseme põhjusest lähtuvalt likvideerida.
Töö teevad ära cpmtools ja libdsk käsikäes ning vajalikud konfifailid on:
- diskdefs (võib käia nt
/etc/cpmtools
või/usr/local/share
alla) - libdskrc (võib käia nt
/usr/local/share/LibDsk
alla või kodukataloogi kujul.libdskrc
)
Aga huvilistele ka veidi pikemalt köögipoolest...
FDMAINT | DEC Rainbow 100 |
---|---|
![]() |
![]() |
JUKU jaoks fundamentaalsel opsüsteemi tasemel lähtutakse CP/Mi 128-baidisest sektorisuurusest, mis tähendab, et rajad on kettal jagatud 40 sektorisse ja iga rada on 40x128 = 5120 baiti. Füüsilisel JUKU flopil on rajad aga jagatud 10 sektorisse, mille kaupa arvutatakse ja kirjutatakse tegelikule füüsilisele kettale andmete kontrollsummad. See tähendab, et füüsilisel kettal on CP/Mi 128-baidised sektorid omakorda koondatud neljakaupa 512 baidistesse sektoritesse, st raja maht on 10x4x128 = 10x512 = 5120 baiti. Kuna andmete kodeerimine/dekodeerimine flopi magnetpinnalt on korraldatud riistvara tasemel, siis ei pea andmetõmmiste töötlemisel füüsilise flopiketta omadustele tähelepanu pöörama ning võib piirduda opsüsteemi tasemel kättesaadava andmete vorminguga.
Kasutusel oleva CP/Mi failisüsteemi loogilise ploki suurus on 4096 baiti, igasse sellisesse plokki mahub 32 sektorit, loogilisi plokke mahub kogu ketta mahu sisse 819200/4096 = 200. Ketta kaks esimest rada on reserveeritud süsteemi buutimiseks ja seetõttu jääb loogiliste plokkide jaoks reaalselt 819200 - 2x5120 = 808 960 baiti, mis mahutab 808960/4096 = 197,5 loogilist plokki, mis oleks kokku 197,5x4096 / 1024 = 790 kB. Poolikut loogilist plokki kettale kirjutada pole tark mõte ja kuna esimene loogiline plokk on kasutusel kataloogiplokina, siis tegelike failide jaoks kasutatavaid plokke mahub kettale 196. Seega on JUKU ketta tegelik kasutatav maht 196x4096 = 802 816 baiti, mis on omakorda 802816/1024 = 784 kB. Kuna loogilise ploki maht on 32x128 = 4096 baiti ja füüsilise raja maht on 40x128 = 5120 baiti, siis isegi kui üks on neist on lihtsalt 4 kB ja teine 5 kB, siis kettaga toimetamise eri tasmetel eri ühikutega opereerimine muudab üldpildi kettatõmmiste töötlemisel segaseks ning teeb keerukamaks andmete struktuuri tuletamise nende sisust.
JUKU ketaste spetsiifiline topeltsegadus¶
JUKU EKDOS 2.30 lähtekoodi päises on dokumenteeritud rasvases kirjas, et ketta formaadi aluseks on DEC Rainbow 100 flopiformaat. Lähtekood annab ka teada ülejäänud juba mainitud parameetrid:
; DPB constants for 5" 96 TPI DSDD diskettes (2x80 tracks):
TRACKS EQU 160 ; 5"DD
BLKSIZ EQU 4096 ; block length
DIRTRK EQU 2 ; directory track # (3 if 5"SD)
BLOCKS EQU 197 ; (TRACKS-DIRTRK)*CPMSPT/(BLKSIZ/128)-1
DIRENT EQU 128 ; directory entries
DIRCHK EQU 20H
Need vastavad üldjoontes ülal tehtud arvutustele, kuigi kommentaaris toodud tehte (TRACKS-DIRTRK)*CPMSPT/(BLKSIZ/128)-1
tulemuseks oleks tegelikult 196,5, millest on justkui ümardamise teel saadud 197. Koodis kasutatud väärtus on küll korrektne, aga selgituseks toodud tehe võib olla põhjuseks, miks toob opsüsteem JUKU flopiketta kasutatavaks mahuks 786 kB, sest 196,5x4096 = 804864 baiti, mille järel 804864/1024 = 786 kB. Reaalsuses mahub aga JUKU flopile kas 784 kB jagu faile või 788 kB jagu loogilisi plokke koos kataloogiplokiga. Lisanduv poolik loogiline plokk on opsüsteemile kättesaadav ja seega pole avakraanil toodud osutused 786 kB ketastele otseselt valed, aga ei JUKU enda ega CP/Mi tarkvara ei suuda üldiselt fantoomploki 2048 baidiga korrektselt ümber käia ning parimal juhul saab seda kasutada salajaste sõnumite talletamiseks.
Kuna JUKU flopid ei ole andmete keerulise struktuuri tõttu loetavad tavapäraste CP/Mi andmetõmmiste töötlemise tööriistade jaoks, siis tasub panna tähele, et juba DEC Rainbow 100 on ajalooliselt tunnustatud peavalu, sest selle paisktabel ei ühildunud teiste tootjate standarditega. JUKU kasutab/viitab Rainbow kettaformaati ilmselt pigem juhuslikel põhjustel või kuna selle kettalugeja ühendas kaks ühepoolset kettalugejat ning sobis seega teatud määral koodidoonoriks -- igatahes JUKU paisktabel tundub peale vaadates veel omal moel eksootiline ja on samuti leitav lähtekoodist:
; *** Sector translate vectors, two 40 byte areas ***
;
TRANS: DB 1,2,3,4,9,10,11,12
DB 17,18,19,20,25,26,27,28
DB 33,34,35,36,5,6,7,8
DB 13,14,15,16,21,22,23,24
DB 29,30,31,32,37,38,39,40
;
TRANS1: DB 1,2,3,4,9,10,11,12
DB 17,18,19,20,25,26,27,28
DB 33,34,35,36,5,6,7,8
DB 13,14,15,16,21,22,23,24
DB 29,30,31,32,37,38,39,40
Kui lähemalt vaadata, siis on näha, et selline paisktabel ehk skew table koosneb tegelikult neljastest plokkidest nagu 1,2,3,4
või 33,34,35,36
ja tabeli lihtsustatud väljendus oleks õigupoolest 1,3,5,7,9,2,4,6,8,10
. Selline oleks paisktabel, kui see määratleda lähtuvalt JUKU flopide 4x128 = 512-baidistest füüsilistest sektoritest. See tähendab, et sektoreid iga üksiku raja kohta loetakse nii, et esmalt loetakse paarituarvulise järjekorranumbriga ja siis kõik paarisarvulise järjekorranumbriga 512-baidisteks ühendatud sektorid, millest kumbagi on raja kohta viis. Sellist järjest lugemise vältimist oli omal ajal väidetavalt vaja, et arvutid kettalt tulevaid andmeid ikka töödelda jõuaks ja puhvrid ei hakkaks üle ajama:
"Standard CP/M systems are shipped with a skew factor of 6, where six physical sectors are skipped between each logical read operation. This skew factor allows enough time between sectors for most programs to load their buffers without missing the next sector. In particular computer systems that use fast processors, memory, and disk subsystems, the skew factor might be changed to improve overall response."
Pole teada, kas sellist aeglustamist oli JUKU flopiseadmete puhul reaalselt vaja, aga tänapäeva mõistes on ilmselt tegu tarbetu abinõuga ning seetõttu ei tee me kindlasti midagi halba, kui paisktabelit loetavuse mõttes lihtsustame. Küll aga ei piisa, kui söödame oma lihtsustatud või ka lihtsustamata paisktabeli cpmtools'ile, sest kuigi ketta algus loetakse enam-vähem, siis esimestest failidest edasi läheb kõik juba parajaks segapudruks.
Kui seda valminud putru lähemalt vaadelda, selgub et JUKU kettaformaadil veel teine standardist hälbiv iseärasus, mis ei seostu üldse paisktabelitega ja muudab kettad tavalisi CP/Mi kettalid lugevatele tööriistadele arusaamatuks. Nimelt kirjutatakse JUKU ketta ühe poole rajad täis ja siis minnakse teise poole radu kirjutama uuesti algusest, st ketta teisest servast. Tavapärane on kirjutada radu kordamööda ühele ja teisele poolele või hakata rajanumbritega ühte kettaserva jõudes nendega teiselt poolelt tagasi tulema. Seega on JUKU flopidel tavapäraste ketaste suhtes segadus kahes mõttes, esiteks paisktabeli tõttu ja teiseks radade paigutuse tõttu kettal. Ette rutates võib ütelda, et algse hüpoteesi kohaselt kurja juureks oletatud paisktabel osutub radade segaduse lahendamise järel õigupoolest täiesti standardseks.
Millega ja mispidi neid siis lugeda?¶
Tegelikult cpmtools koos libdsk'i kettaseadetega loeb JUKU diskid edukalt välja. Mõlemad on olemas kõigile viisakatele tänapäeva opsüsteemidele, aga peab veenduma, kas cpmtools'i seadetes ehk ülal viidatud diskdef
failis saab viidata libdsk'i seadetes määratletud .libdskrc
kirjetele. Sisuliselt on vaja teha kahte asja:
-
Tuleb
.libdiskrc
failis määratleda kettatõmmis kui kahe lugemispeaga loetav, st parameeterheads = 2
ja silindrite arvuks määrata ühe poole radade arvcylinders = 80
. Kettapooltele kirjutatavate radade järjekorra kohta peab ütlema, et neid kirjutatakse ketta väljast sissepoole liikudes järjest ning kui üks pool saab täis, siis jätkatakse teise poolega uuesti väljast sissepoole ehk parameetersides = outout
. Kettatõmmise tüübi nimeks määrame JUKU ehk paneme pealkirjaks[juku]
. -
Tuleb cpmtools'i
diskdefs
failis määratleda sobiv radade ja sektorite arv, määratleda eriotstarbelised rajad nagu süsteemile määratud kaks rada parameetrigaboottrk 2
ja failide asukohti kettal kirjeldav rada parameetrigamaxdir 128
. Ütlasi tulebdiskdefs
failis osutada, et kasutataks libdsk'i geomeetriat kettapoolte lugemiseks ning seda teeb parameeterlibdsk:format juku
. Siin tuleb nüüd määratleda ka paisktabel ja seda on võimalik määratleda EKDOSi lähtekoodi viisil või lihtsustada nii, nagu ülal osutasin.
Kui alustuseks vaadata JUKU enda utiliite, siis need näitavad ketta eri parameetreid samuti üpris erinevalt:
STAT | KULT | DOCTOR |
---|---|---|
![]() |
![]() |
![]() |
JUKU CP/Mil põhinevale 128-baidisele sektorisuurusele truuks jäädes peaksime määrama .libdiskrc
failis parameetrid ilmselt nii:
[juku-origin]
description = JUKU E5101 5.25" DSDD (2 x 80 x 40 * 128)
sides = outout
cylinders = 80
heads = 2
secsize = 128
sectors = 40
datarate = DD
Samamoodi austades algset paisktabelit peaks olema diskdefs
kirje (küll tuleb tabeli väärtused muuta nullist algavaks):
# JUKU E5101 original (DEC Rainbow 100 feat DSDD)
diskdef juku-origin
seclen 128
tracks 160
sectrk 40
blocksize 4096
skewtab 0,1,2,3,8,9,10,11,16,17,18,19,24,25,26,27,32,33,34,35,4,5,6,7,12,13,14,15,20,21,22,23,28,29,30,31,36,37,38,39
boottrk 2
maxdir 128
os 2.2
libdsk:format juku-origin
end
Kui lihtsustame aga paisktabeli ja ühendame CP/Mi 128-baidised sektorid neljakaupa üheks 512-baidiseks füüsiliseks sektoriks, siis peaks sobima vastavalt:
[juku]
description = JUKU E5101 5.25" DSDD (2 x 80 x 10 * 512)
sides = outout
cylinders = 80
heads = 2
secsize = 512
sectors = 10
datarate = DD
Ja cpmtools'i diskdefs
lühendatud paisktabeliga on lõpuks ketta poolte lugemise segaduse eemaldamise järel täiesti tavaline paiskfaktor väärtusega 2 ehk skew 2
:
# JUKU E5101 \w optimized skew (DEC Rainbow 100 feat DSDD)
diskdef juku
seclen 512
tracks 160
sectrk 10
blocksize 4096
skew 2
#skewtab 0,2,4,6,8,1,3,5,7,9
boottrk 2
maxdir 128
os 2.2
libdsk:format juku
end
Kuna cpmtools'i kõik versioonid kõigi libdsk'i versioonidega praktikas ei ühildu, siis pole välistatud ka libdsk'i seadistustes määratletud geomeetria ignoreerimine, aga sel juhul võiks saada näiteks kirjeldada kõik sektorid ja plokid ühel rajal üheainsa suure paisktabelina. Selline häkk teeks tabeli umbes 160x10x4 ≈ 6 kB pikkuseks, mis ei ole küll tänapeäva mõistes päris maailmalõpp, aga cpmtools ei pruugi vaikimisi nii pikka tabelit seedida. Libdsk'i seadistamisel võiks doonoriks sobida ka mõne acorn flopi geomeetria, mis on üks väheseid, milles outout
lugemisviis kasutusel olla olnud (vt "used by some Acorn formats [and JUKU]"). Lõppeks võib lihtsaim viis Gordioni sõlme raiumiseks olla, kui teha elementaarsed muudatused otse cpmtools'i lähtekoodi ja kompileerida see ise.
Lõppseis ja töö viljad¶
Lõpptulemus näeb cpmtools'i fsed.cpm -f juku-origin ORIG.CPM
ekraanil välja nii:
Info (I) | Datamap (M) | Kataloogikirje (0x5000) |
---|---|---|
![]() |
![]() |
![]() |
Ühtlasi peaks töötama kõik cpmtools'i käsud, millega brausida ketaste sisu ning teha failioperatsioone kopeerimisest kustutamiseni:
cpmls -f juku DISK.CPM
cpmls -f juku -licF DISK.CPM
cpmcp -f juku GAMES.CPM 0:*.* jukugames
cpmcp -f juku GAMESX.CPM jukugames/INDY.* 0:
Kui määrata juku
keskkonnamuutujas CPMTOOLSFMT
vaikimisi formaadiks, siis võib -f juku
ka ära jätta:
CPMTOOLSFMT="juku"
export CPMTOOLSFMT
Toetatud kettatüüpide ja -vormingute nimekirju libdsk'i poolel näitavad dskutil -types
ja dskutil -formats
, cpmtools lubatud formaatide nimekirja ei paista väljastavat ja nendega tuleb tutvuda diskdefs
seadistusfaili tasemel. Õigupoolest on JUKU ketaste lugemiseks täiendavate libdsk'i vahenditeta vaja cpmtools'i lähtekoodi täiendada vaid ühe reaga kahes funktsioons, mis juhendaks neid otsima radu kettatõmmisel õigest kohast ja sellise täiendusega CpmtoolsGUI eksperimentaalse JUKU versiooni leiab siit.
Alates 2025. aasta juulist suudab aga lisapingutusteta töödelda JUKU kettaid ka Fluxengine'i arendusversioon.
On küll mõnevõrra tüütu kaevuda ajalooliste kettaformaatide iseärasustesse, kuid mõningase pusimise ja loomkatsete tulemusel saab ka maailma kõige unikaalsema CP/Mi kettaformaadi loetud. JUKU tunnustuseks võib ütelda, et tõenäoliselt pole kunagi eksisteerinud ühtegi teist arvutisüsteemi, mis oleks ilma pusserdamiseta JUKU kettaid suutnud lugeda -- seega kaksteist punkti ja ugrikrüpto eriauhind teadurile, kes selle vormingu välja mõtles!
P. S. Füüsilistest ketastest tõmmiste tegemine on ka huvitav, aga eraldi kirjatükki vääriv teema.