Oberon/A2/Oberon.ISO9660Volumes.Mod

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