home *** CD-ROM | disk | FTP | other *** search
/ AMOS PD CD / amospdcd.iso / 601-625 / apd606 / articles / extension2.nba < prev    next >
Encoding:
Text File  |  1992-01-12  |  16.1 KB  |  421 lines

  1.        ---------------------------------
  2.        LDos V1(3) for AMOS1.3 and above.
  3.        LDos is (C) Niklas Sjöberg 1992
  4.        ---------------------------------
  5.  
  6.                 PART ONE - General file commands
  7.                 --------------------------------
  8.  
  9.        These commands will in conjunction  with  the  string-commands
  10.     totally  replace  all  AMOS  file  I/O,  except for special bank-
  11.     loading, like sprites music etc. They require  a  bit  more  work
  12.     than  the  standard  commands,  but  gives you total control over
  13.     memoryusage string contents and lengths. And most important, they
  14.     are very fast. Lstr for example is about 13-22 times faster  than
  15.     Chr$(Peek()) when compiled! (This is almost the same as a vanilla
  16.     A500 vs a 33 Mhz 030 card) All loading and saving is done to/from
  17.     banks  meaning  minimal  usage  of  the string-buffer and you may
  18.     easily decide the bank-size and change it at run-time,  which  is
  19.     impossible  with  Set Buffer which is set once and for all. There
  20.     is a bunch of commands which lets you  process  the  bank  before
  21.     copying    it  to  strings  and  thus  eliminates  the  risk  for
  22.     "incorrect" strings, containing unwanted characters.    (see part
  23.     about string-commands for more information)
  24. ++  Since some might find Lload/Lstr a bit hard to use , I decided to
  25. ++  include  some  easy to  change  procedures which  works like Line
  26. ++  Input. See the hint section.
  27.  
  28.        Lopen - Open a file for input and/or output.
  29.        Lopen Channel,"Name",MODE
  30.  
  31.        where
  32.  
  33.        Channel can range from 1 to 3, MODE  either 0  for opening  an
  34.     existing file or 1 for creating a new. WARNING! If the file exist
  35.     and  MODE is 1 the file will be erased. (the file will be 0 bytes
  36.     long) Both Load- and Save-operations can be  performed  on  files
  37.     opened by Lopen (unlike AMOS standard Open).
  38.     Example: _OLD=0 : Lopen 1,"s:startup-sequence",_OLD
  39.  
  40.  
  41.        Lclose - Close a file.
  42.        Lclose Channel
  43.  
  44.     where
  45.  
  46.        Channel is a previously opened file.  Files  opened  with  the
  47.     standard  AMOS-command Open In or Open Out can not be closed with
  48.     this command.
  49.  
  50.        WARNING! Do not ever forget to close a file, especially  those
  51.     you  save  to,  otherwise the file, or even the whole disk can be
  52.     corrupt!!! (Ldos will automatically close all open files when the
  53.     program exits, but if a system-crash occur your file will be lost
  54.     if you haven't closed it)
  55.     Example: Lclose 1
  56.  
  57.  
  58.        Lload - Load any number of bytes from a file.
  59.        A=Lload(Channel,DEST,LENGTH)
  60.  
  61.     where
  62.  
  63.        Channel belongs to  a  file  opened  by  Lopen.  DEST  is  the
  64.     startaddress  of  an  AMOS-bank and LENGTH is the number of bytes
  65.     (characters) you wish to load. A will contain the number of bytes
  66.     actually read. If A is less than LENGTH you reached  the  end  of
  67.     the file. If A equals to -1, a filerror occurred. It is perfectly
  68.     legal to request more data than the file contains,  no error will
  69.     be produced because of this.
  70.     Example: BYTE=Lload(1,Start(10), Length(10))
  71.              If BYTE= -1 Then Print "FileError!" : End
  72.              Print "Loaded ";BYTE;" bytes."
  73.  
  74.     Lsave - Save any number of bytes to a file.
  75.     A=Lsave(Channel,SOURCE,LENGTH)
  76.  
  77.     where
  78.  
  79.        SOURCE is the startaddress of a bank and LENGTH the number  of
  80.     bytes  you  wish  to  write to disk. If A doesn't equal to LENGTH
  81.     a disk-error probably occurred (like disk full, or  write  error)
  82.     dos.library  should normally return -1 on disk-error, but as soon
  83.     as A doesn't equal to the length you specified you should  regard
  84.     this as an error.
  85.     Example: BYTE=Lsave(1, Start(10), Length(10))
  86.              If BYTE <> Length(10) Then Print "FileError!" : End
  87.  
  88.     Lseek - Change position in a file.
  89.     P=Lseek(Channel,POS)
  90.  
  91.     where
  92.  
  93.        POS is the offset you wish to move to. (Offsets  are  relative
  94.     to  the BEGINNING of the file). If the operation was successful P
  95.     will contain the same value as POS. If   POS is  <0  no  movement
  96.     will  take  place,  and  the current position in the file will be
  97.     returned.
  98.     Example: Print Lseek(1,0)   : Rem start of file
  99.              Print Lseek(1,100) : Rem move to 100
  100.              Print Lseek(1,-1)  : Report position
  101.  
  102.     Lold    - MAY CURRENTLY NOT BE USED!!
  103.     Lcreate - MAY CURRENTLY NOT BE USED!!
  104.  
  105.        These are here for  future  versions, currently  the  compiler
  106.     seems  to  mess  up values of reserved variables (or I got it all
  107.     wrong)  (most  likely  I  got  it  wrong,  but  this   type    of
  108.     "instructions"  isn't  explained  in the PD-source that come with
  109.     AMOS)
  110.  
  111.     Lget Comment - Get a FileNote
  112.     A$=Lget Comment("FileName")
  113.  
  114.     where
  115.  
  116.        A$ will contain nothing if there  was  no  filenote.  This  of
  117.     course also works on directories.
  118.  
  119.     Lset Comment - Set a FileNote
  120.     Lset Comment "FileName","Comment"
  121.  
  122.     where
  123.  
  124.        "Comment" may not be longer than 79 characters and also  works
  125.     on directories as well.
  126.  
  127.     Lget Prot - Get the protection-bits of a file
  128.     A=Lget Prot("FileName")
  129.  
  130.     where
  131.  
  132.        A will contain a bit-pattern meaning :
  133.  
  134.  
  135.         Bit 7   =       H       ACTIVE  HIGH (Hidden)
  136.         Bit 6   =       S       ACTIVE  HIGH (Script)
  137.         Bit 5   =       P       ACTIVE  HIGH (Pure)
  138.         Bit 4   =       A       ACTIVE  HIGH (Archived)
  139.         Bit 3   =       R       ACTIVE  LOW  (Readable)
  140.         Bit 2   =       W       ACTIVE  LOW  (Writable)
  141.         Bit 1   =       E       ACTIVE  LOW  (Executable)
  142.         Bit 0   =       D       ACTIVE  LOW  (Deleteable)
  143.  
  144.       This command also works on directories but it  seems  like  DOS
  145.     doesn't  care about  some flags when it comes to directories. For
  146.     instance DOS will let you read a directory  even  if  the  R-flag
  147.     wasn't   activated.  Logically  DOS  shouldn't  let  you  read  a
  148.     directory which isn't readable but this is the way it  works.  If
  149.     you are running Kickstart 1.2 or 1.3 DOS neglects most flags.
  150.        When a flag is active low, it means that when that bit is zero
  151.     the flag  is active. If, for instance, bit 0  would  equal  to  0
  152.     that file or directory wouldn't be deleteable.
  153. ++  Of course above should be  " bit 0 would equal to 1,  that file or
  154. ++  directory wouldn't be deleteable"
  155.  
  156.  
  157.     Lset Prot - Set the protectionflags for a file.
  158.     Lset Prot "FileName",MASK
  159.  
  160.     where
  161.  
  162.        MASK is a bitpattern like above.
  163.     Example: Lset Prot "c:myCommand",%00000000 : Rem ----rwed
  164.              Lset Prot "s:myScript",%01000000  : Rem -s--rwed
  165.  
  166.     Lsize - Return the size of a file.
  167.     S=Lsize("FileName")
  168.  
  169.     where
  170.  
  171.        S is the filesize. The file do not need to be open.  Note that
  172.     it is legal to to specify a directory as well. If "FileName" is a
  173.     directory zero is always returned.
  174.  
  175.     Lfile Type - See if the name is a file or a directory.
  176.     A=Lfile Type("FileName")
  177.  
  178.     where
  179.  
  180.        A is greater than 0 if it is a directory, or  negative  if  it
  181.     is  a file. You don't need to supply a directoryname with a slash
  182.     ("/") it will work anyway.
  183.     Example: If Lfile Type(F$) >0
  184.                 Print F$;" is a directory"
  185.              Else
  186.                 Print F$;" is a file"
  187.              EndIf
  188.  
  189.     Lcat First - "Lock" on a directory.
  190.     F$=Lcat First("Directory")
  191.  
  192.     where
  193.  
  194.        If successful F$ will contain the file- or directoryname. Lcat
  195.     Next will return the next file/dir or an  empty  string.  If  the
  196.     directory  didn't  exist  the  error  "Invalid  Filename" will be
  197.     produced (this is because I wanted to keep as few  error-messages
  198.     as possible)
  199.  
  200.     Lcat Next - Get the next lock (name) in a directory.
  201.     F$=Lcat Next
  202.  
  203.     where
  204.  
  205.        If F$ is empty, there are no  more  files/directories in  this
  206.     directory.  Lcat  Next won't work if you haven't used Lcat First.
  207.     These two  Lcat-commands  works  almost  as  the  original  AMOS-
  208.     commands  Dir  First$  and Dir Next$ with the exception that Lcat
  209.     First actually returns the path, requested  by  you  and  doesn't
  210.     read  in all the files and directories like Dir First$. Obviously
  211.     Lcat Next, unlike Dir Next$, has to access the disk  to  get  the
  212.     next filename. To produce a directory/file-listing which lets the
  213.     user stop the program at any time, you could  do  something  like
  214.     this :
  215.  
  216.          F$=Lcat First("SYS:")
  217.          Print "Listing contents of ";F$
  218.          Repeat
  219.             Exit If Inkey$<>""
  220.             F$=Lcat Next
  221.             If Lcat Type>0
  222.                F$=F$+At(40,)+Pen$(5)+"(DIRECTORY)"+Pen$(1)
  223.             EndIf
  224.             Print F$
  225.          Until F$=""
  226.  
  227.        As you can see Lcat Next only returns the  file/directoryname,
  228.     there  are  no  sizes or "*" which makes it harder to process the
  229.     strings. Instead you can after a call to Lcat First, or Lcat Next
  230.     call any of the other Lcat-commands for  more  information  about
  231.     the  file/directory. Since the file/dir already is examined once,
  232.     none of the other Lcat-commands  actually  needs  to  access  the
  233.     disk. This speed things up a bit and prevents disktrashing.
  234.  
  235.     Lcat Type - Find out if the name is a directory or a file.
  236.     A=Lcat Type
  237.  
  238.     where
  239.  
  240.        A can be either positive,  for  directories, or  negative  for
  241.     files.  This  is  a bit easier than the "*" provided by Dir Next$
  242.     in front of the directoryname.
  243.  
  244.  
  245.     Lcat Prot - Get the protectionflags.
  246.     A=Lcat Prot
  247.  
  248.     where
  249.  
  250.        se above Lget Prot for more information.
  251.  
  252.     Lcat Size - Get the filesize
  253.     S=Lcat Size
  254.  
  255.     where
  256.  
  257.        S will contain the number of bytes in the file. Note  that  it
  258.     is fully legal to call this command even if the current "file" is
  259.     a  directory!  If  the current name belongs to a directory S will
  260.     contain 0. (Keep in mind that  files  which  are  zero  bytes  do
  261.     exist, so don't use this method instead of Lcat Type)
  262.  
  263.     Lcat Blocks - Return how many blocks the file occupies.
  264.     B=Lcat Blocks
  265.  
  266.        (May be useful when doing size check (copy FFS  ->  SFS).  FFS
  267.     can hold 512 bytes of data in one block, SFS only 488. It is also
  268.     said that 2.x/3.x shall support different block-sizes(?))
  269.  
  270.     Lcat Stamp - Return the datestamp of the file/directory.
  271.     S=Lcat Stamp
  272.  
  273.        See Ldate, Lstamp for more  information  on  how  to  use  and
  274.     process this stamp. (The format is the same as used by AmigaDOS)
  275.  
  276.     Lcat Comment - Get the file- or directorynote.
  277.     A$=Lcat Comment
  278.  
  279.        See Lget Comment for more information.
  280.  
  281. *-  Lcat Push - Store Lcat-info for later use.
  282. *-  Lcat Push ADR
  283.  
  284. *-  where
  285.  
  286. *-     ADR points to a reserved bank where Lcat temporarily can store
  287. *-  its datas.  Each time you push something 264 bytes are  used  and
  288. *-  the  next  datas should thus be copied to ADR+264. As some of you
  289. *-  may have noticed  it  wasn't  possible  to  run  recursive  Lcat-
  290. *-  procedures  before,  since  Lcat always uses the same memory-area
  291. *-  when storing filelocks  and  information.  Using  Lcat  Push  you
  292. *-  simply move this internal data to a bank reserved by you. You may
  293. *-  now  use  Lcat on a different device/directory. When you're ready
  294. *-  call Lcat Pull and you're back exactly where you stopped.
  295.  
  296. *-  Lcat Pull - Restore Lcat-info which has been stored with Lcat Push.
  297. *-  Lcat Pull ADR
  298.  
  299. *-  where
  300.  
  301. *-     ADR points to the start of a block which has been  created  by
  302. *-  Lcat  Push.  Please  note that if this address not contains Lcat-
  303. *-  data AmigaDOS  MAY crash if you're unlucky!!  If  ADR  points  to
  304. *-  NULLs  (empty  bank)  you  will receive the errormessage "No more
  305. *-  entries in this dir!".
  306.  
  307. *-  WARNING!
  308.  
  309. *-     If you don't pull all your pushed datas DOS won't be  able  to
  310. *-  deallocate the memory used for the pushed files/directories. This
  311. *-  means that  whenever your program is  run  available  memory will
  312. *-  decrease and can not be  restored until the system is re-booted.
  313. *-  See different recursive routines for more information.
  314.  
  315. *-  Ldev First - Get the first device in the systemlist
  316. *-  A$=Ldev First(ADR)
  317.  
  318. *-  where
  319.  
  320. *-     A$ will contain the first device found in your system  (if  it
  321. *-  is  empty  something  is  very wrong). ADR should point to a bank
  322. *-  where optional info can be stored. The info stored in the bank is
  323. *-  mostly  for  advanced  users  to  be  used  in  special    cases.
  324. *-  Interesting info for all users ought to be devicetype, unitnumber
  325. *-  and the name of the device which handles it. Please note that the
  326. *-  devicename  (like  DF0:  etc.)  NOT  contains  a colon (":"). The
  327. *-  information stored at ADR is given below.  The bank  must  be  AT
  328. *-  LEAST 80 bytes large, no checking is done to ensure this.
  329.  
  330. *-  See the example 'Devices.AMOS' for more information and help.
  331.  
  332. *-  Ldev Next - Get the next name(s) in the systemlist.
  333. *-  A$=Ldev Next(ADR)
  334.  
  335. *-  where
  336.  
  337. *-     This command works almost identically  to  Ldev  First  except
  338. *-  that  it  will return an empty string when the last device in the
  339. *-  list has been returned. If you continue to call Ldev  Next  after
  340. *-  this  an errormessage will be generated. Note that it is possible
  341. *-  at any time to call Ldev First if you for  some  reason  like  to
  342. *-  start over in the list.
  343.  
  344. *-  DeviceInfo, returned at ADR and the following 40 longwords:
  345. *-  (entries marked with * are explained below)
  346.  
  347. *-  ADR+0  Devicetype*
  348. *-  ADR+4  Unitnumber
  349. *-  ADR+8  Devicename*
  350. *-  ADR+12 Tablesize (see includes on this)
  351. *-  ADR+16 Blocksize, given in number of longwords
  352. *-  ADR+20 -not used-
  353. *-  ADR+24 Number of heads (surfaces)
  354. *-  ADR+28 -not used-
  355. *-  ADR+32 Number of blocks per track
  356. *-  ADR+36 Reserved blocks (usually 2)
  357. *-  ADR+40 -not used-
  358. *-  ADR+44 Interleave (usually 0)
  359. *-  ADR+48 Starting cylinder
  360. *-  ADR+52 Max cylinder
  361. *-  ADR+56 Number of buffers
  362. *-  ADR+60 BuffMemType (1 for PUBLIC, 3 for FAST and 5 for CHIP)
  363. *-  ADR+64 Maxtransfer
  364. *-  ADR+68 MASK-value (DMA-devices)
  365. *-  ADR+72 Bootpriority
  366. *-  ADR+76 Dostype ($444f5300 for OFS and $444f5301 for FFS)
  367.  
  368. *-     DeviceTypes is zero for all true DOS-devices (like CON:, DF0:,
  369. *-  DH0: etc.), 1 if it is an assignment and 2 for volumes. It can be
  370. *-  a bit tricky to separate non-drive devices, like  CON:/RAW:  etc.
  371. *-  from  normal devices which you can save files to. A rather simple
  372. *-  way to tell which is which is to check ADR+8 (Devicename)  if  it
  373. *-  contains  a devicename. If it does, you can count on that you can
  374. *-  save files to the device. If devicename is empty and type is zero
  375. *-  it is a non-filesystem device.
  376.  
  377. *-     Devicename (ADR+8) contains a pointer to a  transformed  BSTR-
  378. *-  string.  The  first  "character" shows how long the string is, or
  379. *-  zero. Start of the string is thus ST=Leek(ADR+8). Length  of  the
  380. *-  string  is  P=Peek(ST)  and  the  text  starts at ST+1. Note that
  381. *-  Devicename normally is NULL-terminated (ends with a  Chr$(0))  so
  382. *-  it  is  wise to subtract Chr$(0) from the resulting string before
  383. *-  usage.   However,  don't  count  on  that  all  names  are  NULL-
  384. *-  terminated, asdg.vdisk.device for example isn't!
  385.  
  386. ++  Lldir$ - Change the current directory
  387. ++  LLdir$ "new-dir"
  388.  
  389. ++  where
  390.  
  391. ++     newdir is a device/volume/dirname. If you change the dir using
  392. ++  the Dir$-command and then try to open a  file  using  Lopen,  the
  393. ++  file  probably  couldn't  be found, since Ldos hadn't noticed the
  394. ++  directory-change (as always, AMOS handles this  internal  :-(..).
  395. ++  There are two ways of using LLdir$ in your program:
  396.  
  397. ++     a) Set Dir$ to desired value, and call LLdir$ Dir$. Ldos  will
  398. ++   now work in the same path as AMOS.
  399.  
  400. ++     b) NEVER use Dir$ in your program (or direct mode as  long  as
  401. ++  AMOS  is  running). Instead, use LLdir$, just like you would have
  402. ++  used Dir$. What LLdir$ does is to change the program's (AMOS's or
  403. ++  the compiled program) current directory using a system call. What
  404. ++  AMOS's Dir$-command does is to probably add the new path to  some
  405. ++  internal variable that is appended to all subsequent calls to any
  406. ++  file  related  commands.  However, another problem arises..  When
  407. ++  you bring up AMOS's filerequester AMOS changes the Dir$-string so
  408. ++  Ldos will once again become confused.  If your  compiled  program
  409. ++  never uses AMOS's own filerequester (use Lfreq) stick with LLdir$
  410. ++  If you run the interpreter, use option a).
  411.     Example: LLdir$ Dir$
  412.              LLdir$ "SYS:"
  413.  
  414. CONTINUED IN NEXT ARTICLE.
  415.  
  416.  
  417.  
  418.  
  419.  
  420.  
  421.