(* Aos, Copyright 2001, Pieter Muller, ETH Zurich *) MODULE ISO9660Volumes; (* AUTHOR "?/be"; PURPOSE "ISO 9660 volume (ported from Native Oberon)" *) (** non-portable *) IMPORT KernelLog, Plugins, Disks, Files; CONST debug = FALSE; getBlockDebug = FALSE; CONST (* svr *) SS = 2048; (* sector size *) MaxRetries = 10; TYPE Volume* = OBJECT (Files.Volume) VAR dev-: Disks.Device; bpc: LONGINT; (* bytes per sector *) spc: LONGINT; (* sectors per cluster *) PROCEDURE Finalize*; VAR res: LONGINT; BEGIN {EXCLUSIVE} IF debug THEN KernelLog.String("Entering OFSISO9660Volumes.Finalize"); KernelLog.Ln END; EXCL(dev.flags, Disks.Mounted); dev.Close(res) END Finalize; PROCEDURE Available*(): LONGINT; BEGIN RETURN 0 END Available; PROCEDURE GetBlock*(adr: LONGINT; VAR blk: ARRAY OF CHAR); VAR res, i: LONGINT; BEGIN {EXCLUSIVE} ASSERT(dev # NIL, 101); i := 0; REPEAT dev.Transfer(Disks.Read, adr, 1, blk, 0, res); INC(i) UNTIL (res = 0) OR (i >= MaxRetries); IF getBlockDebug & (i > 1) THEN KernelLog.String("GetBlock; "); KernelLog.Int(i, 0); KernelLog.String(" retries"); KernelLog.Ln END; ASSERT(res = 0, 102) END GetBlock; PROCEDURE AllocBlock*(hint: Files.Address; VAR adr: Files.Address); BEGIN HALT(301) END AllocBlock; PROCEDURE FreeBlock*(adr: Files.Address); BEGIN HALT(301) END FreeBlock; PROCEDURE MarkBlock*(adr: Files.Address); BEGIN HALT(301) END MarkBlock; PROCEDURE Marked*(adr: Files.Address): BOOLEAN; BEGIN HALT(301) END Marked; END Volume; PROCEDURE GetISO9660Volume(p: Files.Parameters; dev: Disks.Device); VAR vol: Volume; b: ARRAY SS OF CHAR; BEGIN NEW(vol); vol.flags := {}; vol.dev := dev; INCL(vol.flags, Files.ReadOnly); INCL(vol.flags, Files.Removable); vol.bpc := SS; vol.spc := 1; vol.GetBlock(16, b); (* dummy; necessary after disc change *) COPY(vol.dev.name, vol.name); vol.blockSize := vol.bpc; IF debug THEN KernelLog.String("GetISO9660Volume"); KernelLog.Ln; KernelLog.String(" spc="); KernelLog.Int(vol.spc, 0); KernelLog.String(" bpc="); KernelLog.Int(vol.bpc, 0); KernelLog.Ln END; p.vol := vol END GetISO9660Volume; (** Generate a new ISO9660 volume object. Files.Par: device [# part (ignored)] *) PROCEDURE New*(context : Files.Parameters); VAR name: Plugins.Name; i, ignore, res: LONGINT; table: Plugins.Table; dev: Disks.Device; BEGIN context.vol := NIL; Files.GetDevPart(context.arg, name, ignore); IF (name # "") THEN Disks.registry.GetAll(table); IF (table # NIL) THEN context.out.String("ISO9660Volumes: Device "); context.out.String(name); i := 0; WHILE (i # LEN(table)) & (table[i].name # name) DO INC(i) END; IF (i < LEN(table)) THEN dev := table[i](Disks.Device); dev.Open(res); IF (res = Disks.Ok) THEN IF ~(Disks.Mounted IN dev.table[0].flags) THEN GetISO9660Volume(context, dev); ELSE context.error.String(" already mounted") END; IF (context.vol = NIL) THEN dev.Close(res) (* close again - ignore res *) END ELSE context.error.String(" cannot open device"); context.error.Ln; END ELSE context.error.String(" not found"); context.error.Ln; END; END END; END New; END ISO9660Volumes. OFSTools.Mount TEST "IDE1.0" OFSISO9660Volumes.New OFSN2KFiles.NewFS OFSTools.Mount A "Diskette0" OFSISO9660Volumes.New OFSN2KFiles.NewFS OFSTools.Unmount ^ TEST A System.Free OFSISO9660Volumes ~