(*-------------------------------------------------------------------------*)
(*                                                                         *)
(*  Amiga Oberon Interface Module: Dos          Date: 16-Jun-90            *)
(*                                                                         *)
(*   © 1990 by Fridtjof Siebert                                            *)
(*                                                                         *)
(*-------------------------------------------------------------------------*)

MODULE Dos;

IMPORT e: Exec, s: SYSTEM;

CONST
 dosName * = "dos.library";

(* accessMode bei Open(): *)
 readWrite * = 1004;
 readOnly * = 1005;
 oldFile * = readOnly;
 newFile * = 1006;

(* mode der Seek(): *)
 beginning * = -1;
 current * = 0;
 end * = 1;

(* accessMode bei Lock(): *)
 sharedLock * = -2;
 exclusiveLock * = -1;
 accessRead * = sharedLock;     (* synonym *)
 accessWrite * = exclusiveLock; (* synonym *)

 ticksPerSecond * = 50;

TYPE
 BSTR * = BPOINTER TO ARRAY 256 OF CHAR;
 DeviceListPtr * = BPOINTER TO DeviceList;
 DeviceListVolPtr * = BPOINTER TO DeviceListVol;
 FileHandlePtr * = BPOINTER TO FileHandle;
 FileLockPtr * = BPOINTER TO FileLock;
 Date * = STRUCT
  days * : LONGINT;
  minute * : LONGINT;
  tick * : LONGINT;
 END;
 DatePtr * = POINTER TO Date;

CONST
(* ProtectionFlags *)
  delete     * = 0;
  execute    * = 1;
  writeProt  * = 2;
  readProt   * = 3;
  archive    * = 4;
  pure       * = 5;
  script     * = 6;
  hidden     * = 7;

TYPE
 FileInfoBlockPtr * = POINTER TO FileInfoBlock;
 FileInfoBlock * = STRUCT
  diskKey * : LONGINT;
  dirEntryType * : LONGINT;
  fileName * : ARRAY 108 OF CHAR;
  protection * : LONGSET; (* ProtectionFlags *)
  entryType * : LONGINT;
  size * : LONGINT;
  numBlocks * : LONGINT;
  date * : Date;
  comment * : ARRAY 80 OF CHAR;
  reserved * : ARRAY 36 OF CHAR;
 END;
 InfoDataPtr * = POINTER TO InfoData;
 InfoData * = STRUCT
  numSoftErrors * : LONGINT;
  unitNumber * : LONGINT;
  diskState * : LONGINT;
  numBlocks * : LONGINT;
  numBlocksUsed * : LONGINT;
  bytesPerBlock * : LONGINT;
  diskType * : LONGINT;
  volumeNode * : DeviceListPtr;
  inUse * : LONGINT;
 END;

CONST
(* InfoData.diskState * :  *)
 writeProtect * = 80;
 validating * = 81;
 validated * = 82;

(* InfoData.diskType * :  *)
 noDiskPresent  * = -1;
 unreadableDisk * = s.VAL(LONGINT,"BAD\o"); (* 42414400H *)
 dosDisk        * = s.VAL(LONGINT,"DOS\o"); (* 444F5300H *)
 notReallyDos   * = s.VAL(LONGINT,"NDOS" ); (* 4E444F53H *)
 kickstartDisk  * = s.VAL(LONGINT,"KICK" ); (* 4B49434BH *)

(* Ergebnisse von IoErr() * :  *)
 noFreeStore * = 103;
 taskTableFull * = 105;
 lineTooLong * = 120;
 fileNotObject * = 121;
 invalidResidentLibrary * = 122;
 noDefaultDir * = 201;
 objectInUse * = 202;
 objectExists * = 203;
 dirNotFound * = 204;
 objectNotFound * = 205;
 badStreamName * = 206;
 objectTooLarge * = 207;
 actionNotKnown * = 209;
 invalidComponentName * = 210;
 invalidLock * = 211;
 objectWrongType * = 212;
 diskNotValidated * = 213;
 diskWriteProtected * = 214;
 renameAcrossDevices * = 215;
 directoryNotEmpty * = 216;
 tooManyLevels * = 217;
 deviceNotMounted * = 218;
 seekError * = 219;
 commentTooBig * = 220;
 diskFull * = 221;
 deleteProtected * = 222;
 writeProtected * = 223;
 readProtected * = 224;
 notADosDisk * = 225;
 noDisk * = 226;
 noMoreEntries * = 232;

(* ReturnCode für Exit() * :  (in Oberon bitte stattdessen HALT() nehmen! *)
 ok * = 0;
 warn * = 5;
 error * = 10;
 fail * = 20;

(* break Signalbits *)
 ctrlC * = 12;
 ctrlD * = 13;
 ctrlE * = 14;
 ctrlF * = 15;

TYPE
 CommandLineInterfacePtr * = BPOINTER TO CommandLineInterface;
 ProcessId * = e.MsgPortPtr;
 ProcessPtr * = POINTER TO Process;
 Process * = STRUCT
  task * : e.Task;
  msgPort * : e.MsgPort;
  pad * : INTEGER;
  segList * : e.BPTR;
  stackSize * : LONGINT;
  globVec * : e.ADDRESS;
  taskNum * : LONGINT;
  stackBase * : e.BPTR;
  result2 * : LONGINT;
  currentDir * : FileLockPtr;
  cis * : FileHandlePtr;
  cos * : FileHandlePtr;
  consoleTask * : ProcessId;
  fileSystemTask * : ProcessId;
  cli * : CommandLineInterfacePtr;
  returnAddr * : e.ADDRESS;
  pktWait * : e.ADDRESS;
  windowPtr * : e.ADDRESS;
 END;
 FileHandle * = STRUCT
  link * : e.MessagePtr;
  port * : e.MsgPortPtr;
  type * : ProcessId;
  buf * : LONGINT;
  pos * : LONGINT;
  end * : LONGINT;
  func1 * : LONGINT;
  func2 * : LONGINT;
  func3 * : LONGINT;
  arg1 * : LONGINT;
  arg2 * : LONGINT;
 END;
 DosPacket * = STRUCT
  link * : e.MessagePtr;
  port * : e.MsgPortPtr;
  type * : LONGINT; (* Action *)
  res1 * : LONGINT; (* Status *)
  res2 * : LONGINT; (* Status2 *)
  arg1 * : LONGINT; (* BufAddr *)
  arg2 * : LONGINT;
  arg3 * : LONGINT;
  arg4 * : LONGINT;
  arg5 * : LONGINT;
  arg6 * : LONGINT;
  arg7 * : LONGINT;
 END;
 DosPacketPtr * = POINTER TO DosPacket;
 StandardPacket * = STRUCT
  msg * : e.Message;
  pkt * : DosPacket;
 END;
 StandardPacketPtr * = POINTER TO StandardPacket;

CONST

(* DosPacket.type *)
 nil * = 0;
 getBlock * = 2;
 setMap * = 4;
 die * = 5;
 event * = 6;
 currentVolume * = 7;
 locateObject * = 8;
 renameDisk * = 9;
 write * = ORD('W');
 read * = ORD('R');
 freeLock * = 15;
 deleteObject * = 16;
 renameObject * = 17;
 moreCache * = 18;
 copyDir * = 19;
 waitChar * = 20;
 setProtect * = 21;
 createDir * = 22;
 examineObject * = 23;
 examineNext * = 24;
 diskInfo * = 25;
 info * = 26;
 flush * = 27;
 setComment * = 28;
 parent * = 29;
 timer * = 30;
 inhibit * = 31;
 diskType * = 32;
 diskChange * = 33;
 setDate * = 34;
 screenMode * = 994;
 readReturn * = 1001;
 writeReturn * = 1002;
 findUpdate * = 1004;
 findInput * = 1005;
 findOutput * = 1006;
 actionEnd * = 1007;
 seek * = 1008;
 truncate * = 1022;
 writeLock * = 1023;

TYPE
 RootNodePtr * = POINTER TO RootNode;
 DosLibrary * = STRUCT
  lib * : e.Library;
  root * : RootNodePtr;
  gv * : e.ADDRESS;
  a2 * : LONGINT;
  a5 * : LONGINT;
  a6 * : LONGINT;
 END;
 DosLibraryPtr * = POINTER TO DosLibrary;
 TaskArray * = STRUCT
  maxCli * : LONGINT;
  cli * : ARRAY 100 OF ProcessId;
 END;
 DosEnvecPtr * = BPOINTER TO DosEnvec;
 DosInfoPtr * = BPOINTER TO DosInfo;
 FileSysStartupMsgPtr * = BPOINTER TO FileSysStartupMsg;
 TaskArrayPtr * = BPOINTER TO TaskArray;
 ResidentSegmentPtr * = BPOINTER TO ResidentSegment;
 ResidentSegment * = STRUCT
  next * : ResidentSegmentPtr;
  usecount * : LONGINT;
  segment * : e.BPTR;
(*  name * : ARRAY OF CHAR; [0] * = length, [1..] * = string *)
 END;
 RootNode * = STRUCT
  taskArray * : TaskArrayPtr;
  consoleSegment * : e.BPTR;
  time * : Date;
  restartSeg * : e.BPTR;
  info * : DosInfoPtr;
  fileHandlerSegment * : e.BPTR;
 END;
 DosInfo * = STRUCT
  mcName * : BSTR;
  devInfo * : DeviceListPtr;
  devices * : e.BPTR;
  handlers * : e.BPTR;
  netHand * : ResidentSegmentPtr;
 END;
 PathInfoPtr * = BPOINTER TO PathInfo;
 PathInfo * = STRUCT
  nextPath * : PathInfoPtr;
  lock * : FileLockPtr;
 END;
 CommandLineInterface * = STRUCT
  result2 * : LONGINT;
  setName * : BSTR;
  commandDir * : PathInfoPtr;
  returnCode * : LONGINT;
  commandName * : BSTR;
  failLevel * : LONGINT;
  prompt * : BSTR;
  standardInput * : FileHandlePtr;
  currentInput * : FileHandlePtr;
  commandFile * : BSTR;
  interactive * : LONGINT; (* LONGBOOLEAN *)
  background * : LONGINT; (* LONGBOOLEAN *)
  currentOutput * : FileHandlePtr;
  defaultStack * : LONGINT;
  standardOutput * : FileHandlePtr;
  module * : e.BPTR;
 END;

CONST
(* DeviceListType *)
 device    * = 0;
 directory * = 1;
 volume    * = 2;

TYPE
 DeviceList * = STRUCT
  next * : DeviceListPtr;
  type * : LONGINT; (* DeviceListType *)
  task * : ProcessId;
  lock * : FileLockPtr;
  handler * : BSTR;
  stackSize * : LONGINT;
  priority * : LONGINT;
  startup * : FileSysStartupMsgPtr;
  segList * : e.BPTR;
  globVec * : e.BPTR;
  name * : BSTR;
 END;
 DeviceListVol * = STRUCT  (* für Volumes *)
  next * : DeviceListPtr;
  type * : LONGINT; (* DeviceListType *)
  task * : ProcessId;
  lock * : FileLockPtr;
  volumeDate * : Date;
  lockList * : FileLockPtr;
  diskType * : LONGINT;
  unused * : LONGINT;
  name * : BSTR;
 END;

 DeviceNode * = DeviceList;
 DeviceNodePtr * = POINTER TO DeviceNode;
 DeviceNodeVol * = DeviceListVol;
 DeviceNodeVolPtr * = POINTER TO DeviceNodeVol;

 DosEnvec * = STRUCT
  tableSize * : LONGINT;
  sizeBlock * : LONGINT;
  secOrg * : LONGINT;
  surfaces * : LONGINT;
  sectorsPerBlock * : LONGINT;
  blocksPerTrack * : LONGINT;
  reserved * : LONGINT;
  preAlloc * : LONGINT;
  interleave * : LONGINT;
  lowCyl * : LONGINT;
  highCyl * : LONGINT;
  numBuffers * : LONGINT;
  bufMemType * : LONGINT;
  maxTransfers * : LONGINT;
  mask * : LONGSET;
  bootPri * : LONGINT;
  dosType * : ARRAY 4 OF CHAR;
 END;
 FileLock * = STRUCT
  link * : FileLockPtr;
  key * : LONGINT;
  access * : LONGINT;
  task * : ProcessId;
  volume * : DeviceListPtr;
 END;
 FileSysStartupMsg * = STRUCT
  unit * : LONGINT;
  device * : BSTR;
  environ * : DosEnvecPtr;
  flags * : LONGSET;
 END;

VAR
  dos * :  DosLibraryPtr;

PROCEDURE Close* {dos,- 36}(file{1}:  FileHandlePtr);
PROCEDURE CreateDir* {dos,-120}(name{1}: ARRAY OF CHAR): FileLockPtr;
PROCEDURE CreateProc* {dos,-138}(name{1}: ARRAY OF CHAR;
                                 pri{2}: LONGINT;
                                 segment{3}: e.BPTR;
                                 stackSize{4}: LONGINT): ProcessId;
PROCEDURE CurrentDir* {dos,-126}(lock{1}: FileLockPtr): FileLockPtr;
PROCEDURE DateStamp* {dos,-192}(VAR v{1}: Date);
PROCEDURE Delay* {dos,-198}(ticks{1}: LONGINT);
PROCEDURE DeleteFile* {dos,- 72}(name{1}: ARRAY OF CHAR): BOOLEAN;
PROCEDURE DeviceProc* {dos,-174}(name{1}: ARRAY OF CHAR): ProcessId;
PROCEDURE DupLock* {dos,- 96}(lock{1}: FileLockPtr): FileLockPtr;
PROCEDURE Examine* {dos,-102}(lock{1}: FileLockPtr;
           infoBlock{2}: FileInfoBlockPtr): BOOLEAN;
PROCEDURE Execute* {dos,-222}(commandString{1}: ARRAY OF CHAR;
           input{2}: FileHandlePtr;
           output{3}: FileHandlePtr): BOOLEAN;
PROCEDURE Exit* {dos,-144}(returnCode{1}: LONGINT);
PROCEDURE ExNext* {dos,-108}(lock{1}: FileLockPtr;
           infoBlock{2}: FileInfoBlockPtr): BOOLEAN;
PROCEDURE GetPacket* {dos,-162}(wait{1}: LONGINT): DosPacketPtr;
PROCEDURE Info* {dos,-114}(lock{1}: FileLockPtr;
           parameterBlock{2}: InfoDataPtr): BOOLEAN;
PROCEDURE Input* {dos,- 54}(): FileHandlePtr;
PROCEDURE IoErr* {dos,-132}(): LONGINT;
PROCEDURE IsInteractive* {dos,-216}(file{1}: FileHandlePtr): BOOLEAN;
PROCEDURE LoadSeg* {dos,-150}(name{1}: ARRAY OF CHAR): e.BPTR;
PROCEDURE Lock* {dos,- 84}(name{1}: ARRAY OF CHAR;
               accessMode{2}: LONGINT): FileLockPtr;
PROCEDURE Open* {dos,- 30}(name{1}: ARRAY OF CHAR;
           accessMode{2}: LONGINT): FileHandlePtr;
PROCEDURE Output* {dos,- 60}(): FileHandlePtr;
PROCEDURE ParentDir* {dos,-210}(lock{1}: FileLockPtr): FileLockPtr;
PROCEDURE QueuePacket* {dos,-168}(packet{1}: DosPacketPtr): LONGINT;
PROCEDURE Read* {dos,- 42}(file{1}: FileHandlePtr;
               buffer{2}: ARRAY OF BYTE;
               length{3}: LONGINT): LONGINT;
PROCEDURE Rename* {dos,- 78}(oldName{1},newName{2}: ARRAY OF CHAR): BOOLEAN;
PROCEDURE Seek* {dos,- 66}(file{1}: FileHandlePtr;
               position{2}: LONGINT;
               mode{3}: LONGINT): LONGINT;
PROCEDURE SetComment* {dos,-180}(name{1},comment{2}: ARRAY OF CHAR): BOOLEAN;
PROCEDURE SetProtection* {dos,-186}(name{1}: ARRAY OF CHAR;
                                    mask{2}: LONGSET (* ProtectionFlags *)
                                    ): BOOLEAN;
PROCEDURE UnLoadSeg* {dos,-156}(segment{1}: e.BPTR);
PROCEDURE UnLock* {dos,- 90}(lock{1}: FileLockPtr);
PROCEDURE WaitForChar* {dos,-204}(file{1}: FileHandlePtr;
                                  timeout{2}: LONGINT): BOOLEAN;
PROCEDURE Write* {dos,- 48}(file{1}: FileHandlePtr;
                            buffer{2}: ARRAY OF BYTE;
                            length{3}: LONGINT): LONGINT;

(* $OvflChk- $RangeChk- $StackChk- $NilChk- $ReturnChk- $CaseChk- *)

BEGIN

 dos :=  s.VAL(DosLibraryPtr,e.OpenLibrary(dosName,33));
 IF dos = NIL THEN HALT(0) END;

CLOSE

 IF dos#NIL THEN e.CloseLibrary(s.VAL(e.LibraryPtr,dos)) END;

END Dos.

