From 692414ab6d44c4661af6c52db1213f15cd5fb554 Mon Sep 17 00:00:00 2001 From: Zellyn Hunter Date: Tue, 8 Nov 2016 23:37:15 -0500 Subject: [PATCH] Working on NakedOS/Super-Mon data structures --- lib/disk/disk.go | 28 ++++++- lib/dos33/dos33.go | 7 +- lib/supermon/supermon.go | 128 +++++++++++++++++++++++++++++ lib/supermon/supermon_test.go | 60 ++++++++++++++ lib/supermon/testdata/chacha20.dsk | Bin 0 -> 143360 bytes 5 files changed, 213 insertions(+), 10 deletions(-) create mode 100644 lib/supermon/supermon.go create mode 100644 lib/supermon/supermon_test.go create mode 100644 lib/supermon/testdata/chacha20.dsk diff --git a/lib/disk/disk.go b/lib/disk/disk.go index 5f772ea..b709406 100644 --- a/lib/disk/disk.go +++ b/lib/disk/disk.go @@ -9,6 +9,26 @@ import ( "io/ioutil" ) +// Dos33LogicalToPhysicalSectorMap maps logical sector numbers to physical ones. +// See [UtA2 9-42 - Read Routines]. +var Dos33LogicalToPhysicalSectorMap = []byte{ + 0x00, 0x0D, 0x0B, 0x09, 0x07, 0x05, 0x03, 0x01, + 0x0E, 0x0C, 0x0A, 0x08, 0x06, 0x04, 0x02, 0x0F, +} + +// Dos33PhysicalToLogicalSectorMap maps physical sector numbers to logical ones. +// See [UtA2 9-42 - Read Routines]. +var Dos33PhysicalToLogicalSectorMap = []byte{ + 0x00, 0x07, 0x0E, 0x06, 0x0D, 0x05, 0x0C, 0x04, + 0x0B, 0x03, 0x0A, 0x02, 0x09, 0x01, 0x08, 0x0F, +} + +// TrackSector is a pair of track/sector bytes. +type TrackSector struct { + Track byte + Sector byte +} + type SectorDisk interface { // ReadLogicalSector reads a single logical sector from the disk. It // always returns 256 byes. @@ -50,10 +70,10 @@ func LoadDSK(filename string) (DSK, error) { // ReadLogicalSector reads a single logical sector from the disk. It // always returns 256 byes. func (d DSK) ReadLogicalSector(track byte, sector byte) ([]byte, error) { - if track < 0 || track >= DOS33Tracks { + if track >= DOS33Tracks { return nil, fmt.Errorf("Expected track between 0 and %d; got %d", DOS33Tracks-1, track) } - if sector < 0 || sector >= DOS33Sectors { + if sector >= DOS33Sectors { return nil, fmt.Errorf("Expected sector between 0 and %d; got %d", DOS33Sectors-1, sector) } @@ -66,10 +86,10 @@ func (d DSK) ReadLogicalSector(track byte, sector byte) ([]byte, error) { // WriteLogicalSector writes a single logical sector to a disk. It // expects exactly 256 bytes. func (d DSK) WriteLogicalSector(track byte, sector byte, data []byte) error { - if track < 0 || track >= DOS33Tracks { + if track >= DOS33Tracks { return fmt.Errorf("Expected track between 0 and %d; got %d", DOS33Tracks-1, track) } - if sector < 0 || sector >= DOS33Sectors { + if sector >= DOS33Sectors { return fmt.Errorf("Expected sector between 0 and %d; got %d", DOS33Sectors-1, sector) } if len(data) != 256 { diff --git a/lib/dos33/dos33.go b/lib/dos33/dos33.go index 495d5cf..49000c5 100644 --- a/lib/dos33/dos33.go +++ b/lib/dos33/dos33.go @@ -346,11 +346,6 @@ func (fd *FileDesc) FilenameString() string { return strings.TrimRight(string(slice), " ") } -type TrackSector struct { - Track byte - Sector byte -} - // TrackSectorList is the struct used to represent DOS 3.3 // Track/Sector List sectors. type TrackSectorList struct { @@ -361,7 +356,7 @@ type TrackSectorList struct { Unused2 [2]byte // Not used SectorOffset uint16 // Sector offset in file of the first sector described by this list. Unused3 [5]byte // Not used - TrackSectors [122]TrackSector + TrackSectors [122]disk.TrackSector } // ToSector marshals the TrackSectorList to bytes. diff --git a/lib/supermon/supermon.go b/lib/supermon/supermon.go new file mode 100644 index 0000000..1327193 --- /dev/null +++ b/lib/supermon/supermon.go @@ -0,0 +1,128 @@ +// Copyright © 2016 Zellyn Hunter + +// Package supermon contains routines for working with the on-disk +// structures of NakedOS/Super-Mon disks. +package supermon + +import ( + "fmt" + + "github.com/zellyn/diskii/lib/disk" +) + +const ( + // FileIllegal (zero) is not allowed in the sector map. + FileIllegal = 0 + // FileFree signifies unused space in the sector map. + FileFree = 0xff + // FileReserved signifies space used by NakedOS in the sector map. + FileReserved = 0xfe +) + +// SectorDiskShim is a shim to undo DOS 3.3 sector mapping: +// NakedOS/Super-Mon disks are typically represented as DOS 3.3 .dsk +// images, but NakedOS does no sector mapping. +type SectorDiskShim struct { + Dos33 disk.SectorDisk +} + +// ReadLogicalSector reads a single logical sector from the disk. It +// always returns 256 byes. +func (s SectorDiskShim) ReadLogicalSector(track byte, sector byte) ([]byte, error) { + if sector >= 16 { + return nil, fmt.Errorf("Expected sector between 0 and 15; got %d", sector) + } + sector = disk.Dos33PhysicalToLogicalSectorMap[int(sector)] + return s.Dos33.ReadLogicalSector(track, sector) +} + +// WriteLogicalSector writes a single logical sector to a disk. It +// expects exactly 256 bytes. +func (s SectorDiskShim) WriteLogicalSector(track byte, sector byte, data []byte) error { + if sector >= 16 { + return fmt.Errorf("Expected sector between 0 and 15; got %d", sector) + } + sector = disk.Dos33PhysicalToLogicalSectorMap[int(sector)] + return s.Dos33.WriteLogicalSector(track, sector, data) +} + +// SectorMap is the list of sectors by file. It's always 560 bytes +// long (35 tracks * 16 sectors). +type SectorMap []byte + +// LoadSectorMap loads a NakedOS sector map. +func LoadSectorMap(sd disk.SectorDisk) (SectorMap, error) { + sm := SectorMap(make([]byte, 560)) + sector09, err := sd.ReadLogicalSector(0, 9) + if err != nil { + return sm, err + } + sector0A, err := sd.ReadLogicalSector(0, 0xA) + if err != nil { + return sm, err + } + sector0B, err := sd.ReadLogicalSector(0, 0xB) + if err != nil { + return sm, err + } + copy(sm[0:0x30], sector09[0xd0:]) + copy(sm[0x30:0x130], sector0A) + copy(sm[0x130:0x230], sector0B) + return sm, nil +} + +// FileForSector returns the file that owns the given track/sector. +func (sm SectorMap) FileForSector(track, sector byte) byte { + if track >= 35 { + panic(fmt.Sprintf("FileForSector called with track=%d > 34", track)) + } + if sector >= 16 { + panic(fmt.Sprintf("FileForSector called with sector=%d > 15", sector)) + } + return sm[int(track)*16+int(sector)] +} + +// SectorsForFile returns the list of sectors that belong to the given +// file. +func (sm SectorMap) SectorsForFile(file byte) []disk.TrackSector { + var result []disk.TrackSector + for track := byte(0); track < 35; track++ { + for sector := byte(0); sector < 16; sector++ { + if file == sm.FileForSector(track, sector) { + result = append(result, disk.TrackSector{Track: track, Sector: sector}) + } + } + } + return result +} + +func (sm SectorMap) Verify() error { + for sector := byte(0); sector <= 0xB; sector++ { + if file := sm.FileForSector(0, sector); file != FileReserved { + return fmt.Errorf("Expected track 0, sectors 0-C to be reserved (0xFE), but got 0x%02X in sector %X", file, sector) + } + } + + for track := byte(0); track < 35; track++ { + for sector := byte(0); sector < 16; sector++ { + file := sm.FileForSector(track, sector) + if file == FileIllegal { + return fmt.Errorf("Found illegal sector map value (%02X), in track %X sector %X", FileIllegal, track, sector) + } + } + } + + return nil +} + +// SectorsByFile returns a map of file number to slice of sectors. +func (sm SectorMap) SectorsByFile() map[byte][]disk.TrackSector { + result := map[byte][]disk.TrackSector{} + for file := byte(0x01); file < FileReserved; file++ { + sectors := sm.SectorsForFile(file) + if len(sectors) > 0 { + result[file] = sectors + } + } + return result +} diff --git a/lib/supermon/supermon_test.go b/lib/supermon/supermon_test.go new file mode 100644 index 0000000..ad6718d --- /dev/null +++ b/lib/supermon/supermon_test.go @@ -0,0 +1,60 @@ +// Copyright © 2016 Zellyn Hunter + +package supermon + +import ( + "testing" + + "github.com/zellyn/diskii/lib/disk" +) + +// loadSectorMap loads a sector map for the disk image contained in +// filename. +func loadSectorMap(filename string) (SectorMap, error) { + dsk, err := disk.LoadDSK(filename) + if err != nil { + return nil, err + } + sd := SectorDiskShim{Dos33: dsk} + sm, err := LoadSectorMap(sd) + if err != nil { + return nil, err + } + return sm, nil +} + +// TestReadSectorMap tests the reading of the sector map of a test +// disk. +func TestReadSectorMap(t *testing.T) { + sm, err := loadSectorMap("testdata/chacha20.dsk") + if err != nil { + t.Fatal(err) + } + if err := sm.Verify(); err != nil { + t.Fatal(err) + } + + testData := []struct { + file byte + length int + name string + }{ + {1, 0x02, "FHELLO"}, + {2, 0x17, "FSUPERMON"}, + {3, 0x10, "FSYMTBL1"}, + {4, 0x10, "FSYMTBL2"}, + {5, 0x1E, "FMONHELP"}, + {6, 0x08, "FSHORTSUP"}, + {7, 0x1F, "FSHRTHELP"}, + {8, 0x04, "FSHORT"}, + {9, 0x60, "FCHACHA"}, + } + + sectorsByFile := sm.SectorsByFile() + for _, tt := range testData { + sectors := sectorsByFile[tt.file] + if len(sectors) != tt.length { + t.Errorf("Want %q to be %d sectors long; got %d", tt.name, tt.length, len(sectors)) + } + } +} diff --git a/lib/supermon/testdata/chacha20.dsk b/lib/supermon/testdata/chacha20.dsk new file mode 100644 index 0000000000000000000000000000000000000000..38b831bff00281376522e55b577bf0ec00edb5f5 GIT binary patch literal 143360 zcmeFa3s_Uf+BQ5%03nrEWz_JDj=x9;$Vb|@;{Sc+r7KL_kX|dyT1SWuWvUO zOlHl@nl&?P=DF|ZSy|6;9#QBFvfqn%I_8;rf})KV10M&iVlj^t@er!CV{9r1v96R| z(GIQP`Sma!^CVT!CC$x!*`JYn87V|Ad2PI0fA+BWOuDuxO?zgWR)tQY1IV!mRcaAy zqrJk|>1{OJc)J6Lf4G@>KuZ>0IE9A4bX?w5OH|v;t z$y1WYCfg+slI5mMAP64gNlA*5v<5?({~+55xkX=U=`iAOUn=v6;wDFCdB!`*#}RS- zoC(>HI;|7Kr8rt=risp|K`soBM9#NUwd8_+gcke~-@lNI?fMb;M@&Bp0p*(g{X;st%nRWQ7BnL_sD1EP4bk-=7oF8X9p0&@@5YUYn|ko zn`JmK-P44ao`5g41(JZTwHGCfbCZN&n`SXjXz8w4DNPgmhZRU5pcN3PaZEi60y1&f zuGpqnhTAmzUpBD*GE-5PS7WTDt{ltPP}JeFGWteEo$&}&dY!5%sk@}FrF13ND-_gk zpTm{LI!aej%@k47#dJKiAZ$){YOyy3yRrxPCOV>~F7 zwHJx@CW&-{XHTL%Si5HCUI62f|At4(IQiJa`8p3zay;5KR>wS-2K2x7U(KTbgLw{~ z2ywYD(M#m;%t1Qy|pYoyWW*?Aif_$DDZ)p*y&EB4UrvA6KlE5Yfwm5QwyU*#NYxnm$*0tN@?wx zK{AET1ER11Z0Tgu-CfIJTyf2%9x`H$JIx_u2Wxpyj3^pH1`H-U-Sf&k#CfIg|AvRk zf#N~I^b(I9WgawwHbKqMyt9L4_?}&LfvBKK}r6P8D=hQOU0p z{%(5-Cmc#GApsdJQX0MU`gr)0io;sldF(ujs~HsC?-|dbUhY`wrr6@f&!xGF^=|ZJ z#ag$#b{?PaKj`pvlNLnNOB}nWrNhHoUP5NDjXqezrGr6ynK%qTZ@pV|e>{Ry4UAEy zXy-}u5}ny~c@-XdF2f_fcZF*I>a5t{{3$I`Y;?|pyED;^XmiyF@(dm|S`T&@oKyQ( zXF((F2QeB!cI^gd!NuT^{3?$ksWUUEcB8YPCfJk`XsMJPO3V^y9_Iwo=zz2cxe#Mr z={v+|S2`C5k0BuD_ru?#fHtkC^pVdXu}smb4S1rJ=Cx|`+Oz_0n3SC6qFCyxSm~;W zcU2^~DmJ<*wz(?yxaR%c^?=ejZ?o$G%9)yd=13-=zhGXbe;))8LpTOORBn;hc`tHG z72Kxg0vvqdn#ai`q^>!E2Qa z{biP)%5>LKNiYd0w4>Z3*+)G=FJ-5wxG55qOUkSQiC)X{0Tr7~9t_L+Cx@p*P^ciB zNbgYx!L4zpI0fN)lajAzHFo|xZ71vs&koOtU}|6nige6b?WZ;VC7S^HoSM&^XE^DYM{0ZDfm!eh6a=>B=X155^86xylaxU?z&t^6>#X zQm+E>bcf-I*+F_r;}9 zN4((*)sV{^^=<>Tx9I(pPWmJbkFRWQ5#@cUg+C1OFyt0o?*T$|dKkVNS~2q!ZXEn! zlvnlOIk8KkV|tsJZeqG8;5jkFL;@4=P;Bj?O^VbW`jKKA4$^S2y@w_gxjpo7#ZNf* z2tIt!LwhP3@L^*Q9j0jNq3sm>UO05@rJWRBI5q;ud~nRSmnId#y|laH4SYDU7b*?u zr8x@X7us8K;svCgd_j*?oX4@^7qpL}1jkBWz-h!wdYr=hB^-`^38#&DNjoSK`r&YW zKjd!gr(G4B@F8G<%|Cr?|I5z+jBx+;XV8EBari&{`4!{-+Yx{;9$D{7a@>x*;gLK6 zZuEGHNtNmt2la#+0Dar02?gV&sWg%j{2}?Z9>i-ySoi3D)-k$&W{n4Hqj{`+VqjWK zNE$|rAHs~y3Tv(P5UVG&AThw2Og=$&*m@R7s@}XBk6q&pOo!AHmvw*wP${`$2rUP6 zgs2MP>g{W4JQ#B`)0Kv=NxxJ%5yytm{VE^$fP60I2)hfXgPuI-!-0Lr5Ge} zP3eFWkmrf>cmR=DHnwGn0U>3FRfv5+?r}rvaboA%L}#X;P3tjVN(8zpAJJdW2eBW} ztj#xi>?0rZK*)`48Vjp;oRlEkbK&1av(BafhHr@@mXjt`%y*}eNzD#2*2Ys)I-V7EB9cA(qBQB^GiM04wI*{)x>CQ^d*``DHPSe)ZEr1 z_PV0RLn@PxmC45yrW-xz0ELJL-~+-tzl{faMqY~+E~UT52rP&PEyneFkS~VlPcycP zW-Z;L?_peEvWs|75ZKzF}4928FY4X=C zM`7a+=&hI$srP{BjMtk@Hq3oJVoI&0?=WXxov-nf<^%#pDQ*gK4e4cq^q&M&zcuqR zYYTYu+ojs9$$3m8fI)6P#-zo_8ITG&@d0((eoH%#oJJ5%d*>zl_vt|0`L!%gmpbh| zGLU}cRUPMFI*uR!RpgfPuToh+?N{x6`l`K8JTo%)?LYAS4>^Z^I+B-v^w{weCr|x+ zrts{!qVvU7HMPe2D_5`IxOwaLox6=q4_h8Re$v|3-r3dt)cmaXm*;&iUiOpUyQ^&J zenmSb2tXQq1`*z_K7$NQk98nwT@;U84%3&d3}Q#0OX`k?E=5XbMYf9~*M-itrWaAp z3bl*kCl`9IJc!Qo8T81S{s^?wtOdD_iaeJyxsLhBCEY?qbmc)zOHSZojkBWMaewc1sfz34B>DYfm4+pyTaG(_|^XWhj)!=|#8PAi3za8_R=l6*?H+ ztRJeh0hl>YCh!5C0%}f}8UB-#X5cEhWa|sLFeQ=*F%fT>G;VY@AdNZ_PQCF$EhKNe zkg8BhP

PJCu0Oq(94kaQk~Rk);11$c29dK& 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 HpTPeDQeoH1 literal 0 HcmV?d00001