home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 612b.lha / Bovs_v1.0 / Bovs.doc.pp / Bovs.doc
Text File  |  1992-03-01  |  25KB  |  488 lines

  1.                                    Bovs
  2.                                 Version 1.0
  3.                         Bryan's Overlay Supervisor
  4.                          Copyright 1992 Bryan Ford
  5.  
  6.  
  7.                                 Disclaimer
  8.                                 ~~~~~~~~~~
  9.  
  10.     This program is provided "as is" without warranty of any kind, either
  11. expressed or implied, including, but not limited to, the implied warranty
  12. of fitness for a particular purpose.  The entire risk as to the results,
  13. reliability and performance of this program is assumed by you.
  14.  
  15.  
  16.  
  17.                                Distribution
  18.                                ~~~~~~~~~~~~
  19.  
  20.     Bovs may be freely distributed as long as it is complete (none of the
  21. files listed below are left out), all of the files are unmodified, and no
  22. charge is made for such distribution other than a small fee to cover the
  23. cost of copying.  (In effect, no profit may be made through distribution of
  24. this program).  You may modify this code for your own personal use, but you
  25. may not distribute modified versions.  (If you improve Bovs, just send your
  26. modifications back to me - I'll incorporate them into the master, giving
  27. appropriate credit to you, and we won't have hundreds of different versions
  28. of Bovs floating around.)
  29.  
  30.     You may use the object code derived from this source code, or your own
  31. modified version of this source code, in your own public domain, freeware,
  32. shareware, or otherwise freely distributable programs, as long as you state
  33. that you used Bovs and mention the name of its author (Bryan Ford)
  34. somewhere in your documentation.  You do not need to obtain any kind of
  35. license to use it in freely distributable software.
  36.  
  37.     If you want to distribute Bovs or any modified version of it, in either
  38. source or object form, with or in a commercial package, you must first
  39. obtain a license from me (Bryan Ford).  The cost of the license will be
  40. equal to twice the retail price of the commercial program in which Bovs is
  41. used.  (This cost covers the license fee of MemMan, which Bovs uses and
  42. requires.)  Additionally, you must send me a copy of the program as soon as
  43. it is finished and released.  The license fee covers all future versions of
  44. your program; however you must send me copies of any major updates you
  45. release afterwards, if they still use Bovs.  This license cost will never
  46. increase, but I reserve the right to decrease or eliminate it.
  47.  
  48.     The Bovs distribution must contain the following files, complete and
  49. unmodified:
  50.  
  51.         Bovs.doc        Bovs documentation (this file)
  52.         Bovs.o          Linkable version of Bovs (assembled with OVERLAY=1)
  53.         Bst.o           Same, without overlay support (assembled with OVERLAY=0)
  54.         Bovs.h          Header file for SAS/C programs
  55.         Bovs.asm        Source code for Bovs (A68k)
  56.  
  57.         MemMan/MemMan.doc       MemMan documentation
  58.         MemMan/memman.library   MemMan runtime library
  59.         MemMan/MemMan.o         Linkable version of MemMan
  60.         MemMan/MemMan.fd        Entrypoints for memman.library
  61.         MemMan/MemMan.h         Header for C programs using MemMan
  62.         MemMan/MemMan.i         Same, for assembly language
  63.         MemMan/MemMan.asm       Source to MemMan (A68k)
  64.         MemMan/MemManLib.asm    Source to memman.library interface (A68k)
  65.         MemMan/Macros.i         Macros you'll need for the above two files
  66.         MemMan/LMKfile          SAS/C makefile for MemMan
  67.         MemMan/test             Program to test memman.library
  68.         MemMan/test.c           Source for MemMan test program
  69.  
  70.  
  71.  
  72.                                Introduction
  73.                                ~~~~~~~~~~~~
  74.  
  75.     Bovs (pronounced "boffs") is an overlay system designed to replace the
  76. standard overlay system supplied with SAS/C.  It acts as both overlay
  77. supervisor and startup code.  It provides many powerful features that the
  78. standard SAS/C startup code and overlay supervisor don't provide.  It is
  79. intended especially for large applications which need flexible and
  80. efficient use of memory.  It is used in my Shareware music player,
  81. MultiPlayer.
  82.  
  83.     Bovs currently requires SAS/C's linker, BLink (or a very compatible
  84. linker, if there is such), to create overlaid files.  However, other than
  85. that, SAS/C is not necessarily needed: you can write programs that use Bovs
  86. in assembly language or any other language that supports register arguments
  87. and the standard Amiga object file format.
  88.  
  89.     Programs that use Bovs can be started from Workbench or the CLI.  Both
  90. 1.3 and 2.0 are supported, but when run under 2.0 Bovs supports
  91. command-line parsing with ReadArgs().  If started from the CLI, Bovs
  92. detaches and runs your program in a separate process, freeing up the
  93. original CLI.
  94.  
  95.     Instead of the standard, rigidly-structured, hierarchially-organized
  96. overlay system that standard Amiga overlay systems use, Bovs uses a very
  97. flexible overlay method based on dynamic memory caching.  When overlaid
  98. code is called, the overlay node in which it is contained is loaded in if
  99. necessary, and the function is called.  However, overlay nodes are not
  100. flushed from memory when other overlay nodes at the same level are called.
  101. (In fact, Bovs doesn't even use overlay "levels".)  Instead, they remain in
  102. memory and immediately available until the memory they occupy is needed for
  103. something else.
  104.  
  105.     This is where MemMan comes in.  The Bovs distribution includes MemMan,
  106. a low-memory manager also written by myself, which allows programs to be
  107. called when any call to AllocMem() is about to fail, so they can free
  108. memory they don't need.  (Note that while Bovs currently only supports the
  109. BLink that comes with SAS/C, MemMan can be used by many compilers.  See
  110. MemMan's documentation for details.)  Bovs uses MemMan to unload overlay
  111. nodes that aren't currently in use when the system is about to run out of
  112. memory.
  113.  
  114.     Therefore, if the user of a Bovs program has lots of memory, Bovs ends
  115. up acting as a "delayed-loading" system, to speed up initial loading and
  116. load other parts of the program only when necessary.  After all parts of
  117. the program are loaded, if the user doesn't run out of memory, no more
  118. loading is done and calls to overlaid functions are instantaneous.
  119.  
  120.     To keep track of which overlay nodes are in use and which may be freed
  121. on demand, Bovs uses a system of nestable locks associated with each
  122. overlay node.  When an overlaid function is called, locking is handled
  123. automatically: Bovs locks the overlay node before calling the function,
  124. and unlocks it after the function returns.  However, your program may also
  125. specifically lock and unlock overlay nodes to ensure that they remain in
  126. memory at certain times.
  127.  
  128.  
  129.  
  130.                                Startup Code
  131.                                ~~~~~~~~~~~~
  132.  
  133.     Before getting into Bovs's overlay management, I'll describe how Bovs
  134. handles startup and exit.  First of all, Bovs may not be used along with
  135. "c.o" or any of the other standard startup code files.  Bovs does not
  136. support SAS's standard C-style memory allocation or file handling
  137. functions, or any other non-trivial standard library functions.  (You can
  138. still use string functions and such.)  Bovs is Amiga-only.
  139.  
  140.     Bovs is auto-detaching, so when your program is run from the CLI, a
  141. separate process is started for your program and the original CLI is given
  142. back to the user.  (Ever seen an auto-detaching overlaid program before?
  143. I'm pretty sure MultiPlayer was the first.)
  144.  
  145.     Somewhere in the non-overlaid part of your program (probably your main
  146. module), you'll have to define several variables containing various pieces
  147. of information Bovs needs during startup.  I'll give the C definitions for
  148. these variables; for assembly language, just add an underscore ('_') before
  149. the variable names.
  150.  
  151.     First, you need to define a longword variable called "stack" which
  152. contains the stack size required for your program.  Note that this value is
  153. only used if the program was loaded from the CLI and thus was detached from
  154. the original CLI process.  If you want a larger-than-normal stack, make
  155. sure you set this variable AND the stack size specified in the Workbench
  156. icon for your program.
  157.  
  158.     Second, you must define a pointer variable called "procname" which
  159. contains a pointer to a string containing the name for the process created
  160. when auto-detaching from the CLI.  (Note that this is a pointer to a
  161. string, not the string itself.)  Like the "stack" variable, this is not
  162. used when the program is run from Workbench.
  163.  
  164.     Third, you need to define a longword variable called "priority" which
  165. contains the Exec priority level at which your process is to run.  Unlike
  166. the above variables, this is used when your program is started from either
  167. the Workbench or the CLI.
  168.  
  169.     Finally, you must define two variables which Bovs passes to AmigaDOS
  170. 2.0's ReadArgs() function if your program is run under 2.0.  The variable
  171. "argtemplate" must be a string (not a pointer to a string) containing the
  172. standard argument template.  For example, MultiPlayer's "argtemplate"
  173. variable is "DIRECTORY,PLAY=MODULES/M,PROG=PROGRAM/K,SCREEN/K,NOREQUEST/S,
  174. NOWINDOW/S,NOREXX/S".  The variable "argarray" must be an array of
  175. longwords (it's usually convenient to define it as a structure in C) which
  176. AmigaDOS 2.0 will fill in with the parameters from the parsed argument
  177. template.  I won't go into the details of argument parsing; Commodore's
  178. documentation should suffice.
  179.  
  180.     In addition to these five variables, you must define the symbol "Main"
  181. ("@Main" in assembly language) as a function which will be the entrypoint
  182. of your program.  It must be defined like this:
  183.  
  184.     void __regargs Main(int arglen,char *argstr)
  185.                               D0           A0
  186.  
  187.     You may omit the "__regargs" keyword if you are compiling with register
  188. arguments as the default.  In any case, when Main() is called, "arglen"
  189. contains the length of the unparsed command line received directly from
  190. AmigaDOS, and "argstr" is a pointer to that command line.  (Bovs doesn't
  191. separate the command line into separate arguments like the standard startup
  192. code does; the name change from "main" to "Main" is intended to emphasize
  193. this difference.)  If your program is called from the Workbench, "arglen"
  194. will contain zero and "argstr" will contain the Workbench startup message.
  195.  
  196.     Note that the raw command line is available on entry even if the
  197. command line was also parsed with 2.0's ReadArgs() function.  Under 1.3,
  198. your "argtemplate" will remain unmodified and unused; under 2.0, you'll get
  199. both.  If you want compatibility with both 1.3 and 2.0, you should use the
  200. parameters in "argtemplate" if they have been filled in; otherwise do some
  201. minimal parsing of the raw command line yourself.
  202.  
  203.     On startup, you don't have any standard input or output streams, so
  204. don't be printing error messages to nonexistant file handles.  However,
  205. your current directory will be whatever the current directory was in the
  206. CLI your program started from, or if you started from Workbench, the
  207. directory containing your program icon.  You don't have to return to this
  208. directory before exiting your program.
  209.  
  210.     When the Main() function returns, Bovs frees all resources, closes the
  211. executable file, and ends the program.  You can also do this from anywhere
  212. in your program (as long as you're running from the original process Bovs
  213. started you in) by calling BExit(), described later.  Remember, Bovs
  214. provides NO resource tracking like standard C startup code does: you must
  215. free anything you allocate.  (Of course, Bovs will free anything it
  216. allocates.)
  217.  
  218.  
  219.  
  220.                                  Overlays
  221.                                  ~~~~~~~~
  222.  
  223.     First of all, be warned that the use of Bovs overlays is not completely
  224. transparent.  Even if you're already using overlays in your program,
  225. converting it to use Bovs will require a little work.  How much it requires
  226. depends on your program.  In this document, I'll assume that you are trying
  227. to convert a non-overlaid program into an overlaid program that uses Bovs.
  228. If you have already written an overlaid program, you shouldn't have too
  229. much trouble figuring out what you need to change to convert it to Bovs.
  230.  
  231.     Your program will have to have at least one non-overlaid object file,
  232. as well as one or more overlaid files.  You don't have to work out any
  233. complicated overlay call tree or anything: all the overlay nodes are on the
  234. same overlay "level", and any combination of them may be loaded at one
  235. time.  Overlay nodes may even call other overlay nodes, although you will
  236. have to fudge a little to get around some of BLink's error checking.
  237.  
  238.     You'll have to set up a WITH file that you pass to BLink to link your
  239. program.  In it, along with whatever other BLink options you want, supply
  240. an OVERLAY construct that looks something like this:
  241.  
  242. OVERLAY
  243. window.o windowspec.o
  244. progwin.o progwinspec.o
  245. prefswin.o prefswinspec.o
  246. flashy.o flash.o flashyspec.o
  247. rexx.o
  248. #
  249.  
  250.     (This is part of MultiPlayer's WITH file.)  All the object files on one
  251. line are linked into the same overlay node: they are loaded and unloaded
  252. together, and they may share data, make no-overhead calls to each other,
  253. and so on.  Each line specifies a separate overlay node.  Note that you
  254. should never use asterisks ('*') before the filenames, as Bovs neither
  255. needs nor supports hierarchial overlays.
  256.  
  257.     There are certain limitations to what you can do when programming with
  258. overlays.  First, you can't directly reference data in one overlay node
  259. from another overlay node, or from the root (the non-overlaid part of the
  260. program).  The only exception to this (and it's not really an exception) is
  261. if you name your data hunks "__MERGED", in which case BLink will merge the
  262. data into the root node's global data segment, and the data in effect is no
  263. longer associated with the overlay node it was defined in.  Compiling with
  264. SAS/C using the small data model will cause this to happen.  You should
  265. avoid putting too much overlay-node-specific data into the __MERGED hunk,
  266. because that data will be loaded all the time the program runs, even when
  267. the actual overlay node isn't loaded.  (To keep data out of the __MERGED
  268. hunk under SAS/C while still using the small data model, define your
  269. overlay-node-private variables as __far.)
  270.  
  271.     Bovs imposes very few restrictions on calling functions in overlay
  272. nodes.  Any time an overlaid function is called, BLink reroutes the call
  273. through an entrypoint in Bovs, which loads the required overlay node if it
  274. isn't already loaded, locks it, calls the function, and unlocks it when the
  275. function returns.  Theoretically, functions within overlay nodes could call
  276. functions in other overlay nodes with no problem.  However, BLink has some
  277. very inconvenient checking code that won't let you link a program in which
  278. one overlay node calls another.  (This is based on the assumption that
  279. loading one overlay node causes all other overlay nodes on the same level
  280. to be unloaded - which, with Bovs, is not true.)  For now, unless you find
  281. a way to hack BLink to disable this code (if you do, tell me how!), you'll
  282. have to create "stub" functions in some non-overlaid module to bounce calls
  283. back into other overlay nodes.
  284.  
  285.     Function calling conventions in Bovs are quite different from those
  286. used with the standard overlay manager.  In particular, no stack parameters
  287. are allowed when calling an overlaid function from outside the function's
  288. overlay node (when BLink has to route the function through Bovs).  This is
  289. because Bovs has to keep some information on the stack during the call so
  290. it can unlock the overlay node on returning.  (It can't just "load and
  291. jump" like the standard overlay supervisor can.)  The only parameters that
  292. are guaranteed to get to the called function are register parameters passed
  293. in A0 and A1.  (In SAS/C, with register arguments active, this amounts to
  294. the first pointer-type parameters; if you want to pass value parameters,
  295. just convert them them to void pointers.)  In addition, the register A4 is
  296. passed through to allow easy use of the small data model.
  297.  
  298.     If you pass register parameters to overlay functions when using Bovs,
  299. you'll get a bunch of annoying but meaningless warning messages from BLink
  300. telling you that the register parameters will get destroyed, because it
  301. thinks that overlay functions are supposed to be called with stack
  302. parameters.  For now, just let the warnings roll up your screen; I'm trying
  303. to get SAS to put an option in BLink to disable this checking, but so far
  304. I've had no luck.
  305.  
  306.     At this point things start getting really unconventional.  When an
  307. overlaid Bovs function is called, it actually receives one extra parameter
  308. that the caller never passed to it.  This parameter is passed in D0 (just
  309. define it as a 'long' in a SAS/C function prototype), and contains a
  310. "handle" on the overlay node in which the function resides.  This handle is
  311. only valid throughout that function call, unless the function locks the
  312. overlay node into memory with LockOverlay(), described later, before
  313. returning.  A valid handle passed to you will never be zero (unless you are
  314. using "Bst" instead of "Bovs" and have overlays disabled - this is
  315. described later), but other than that you can't assume anything about what
  316. it actually is.
  317.  
  318.     At this point, you should be able to implement simple overlaid programs
  319. using Bovs.  Bovs also has some extra features to make your programs sleek
  320. and efficient, which are described in the following sections.
  321.  
  322.  
  323.  
  324.                                  Functions
  325.                                  ~~~~~~~~~
  326.  
  327.     Bovs defines a few external functions which you may call during your
  328. program for various purposes.  Besides these, since MemMan must be linked
  329. into any program that uses Bovs, you may also call MemMan's memory
  330. management functions.  Do not call MMInit() or MMFinish() from your program
  331. - Bovs does that for you.  However, if you use MemMan directly, you must be
  332. sure to remove all MMNodes before terminating your program.  (See
  333. MemMan.doc for details on using MemMan.)
  334.  
  335.  
  336.     void BExit(void)
  337.  
  338.     Call this function to terminate your program.  Unlike standard exit
  339. functions, BExit() does not take any kind of return code: Workbench doesn't
  340. care about return codes, and the CLI process that started you no longer
  341. even knows that you exist, so there's really nobody to see your return code
  342. anyway.  Calling BExit() is effectively the same as returning from your
  343. Main() function.
  344.  
  345.     Of course, since Bovs does no resource tracking, you must be sure to
  346. free all resources before calling BExit().  Also, it may only be called
  347. from the original process that Bovs gave you.
  348.  
  349.  
  350.     void LockOverlay(long ovhan)
  351.                            D0
  352.     void UnlockOverlay(long ovhan)
  353.                               D0
  354.  
  355.     Given an overlay handle passed by Bovs to one of your overlaid
  356. functions, LockOverlay() will lock the overlay node containing that
  357. function in memory.  It will not be unloaded until you unlock the overlay
  358. node.  LockOverlay() calls may be nested, and every call to LockOverlay()
  359. must be paired with exactly one call to UnlockOverlay().  The only
  360. exception to this rule is that you don't have to unlock every locked
  361. overlay node before your program exits: Bovs will unload all loaded overlay
  362. nodes before exiting, locked or unlocked.  In any case, you must NEVER try
  363. to unlock an overlay node that you haven't already locked.
  364.  
  365.     You may only call LockOverlay() on a given overlay handle from within
  366. the function that was passed the handle, or from within a sub-function that
  367. it calls.  You MAY NOT pass an overlay handle back from an overlay function
  368. to the function that calls it.  In other words, the overlay handle is ONLY
  369. valid during the call to the overlaid function, unless you lock it within
  370. that function.
  371.  
  372.     When using LockOverlay() and UnlockOverlay() to ensure that a certain
  373. overlay node stays in memory at certain times, it is permissible for the
  374. main module or other overlay nodes to access the overlay node's data
  375. (indirectly through pointers, since direct references are not allowed), or
  376. to call functions in the overlay node through function pointers.  This can
  377. be desirable, for example, if you have some function that is very
  378. frequently called and you don't want the slight extra overhead of running
  379. through the overlay supervisor every time the function is called.  However,
  380. any time "outsiders" access a node's data or functions this way, you must
  381. be SURE that the overlay node is locked at the time, so it doesn't
  382. disappear on you.
  383.  
  384.     You may call UnlockOverlay() from anywhere in your program, as long as
  385. you are sure the overlay handle you're passing to it is valid and locked,
  386. and you're sure that the call will not pull out the carpet from under
  387. you.  To put it in simpler terms, an overlay node may be unlocked by (a) an
  388. "outsider" who has been given the overlay handle, or (b) a function within
  389. the overlay node which was called normally through the overlay supervisor
  390. (not directly through a function pointer).  Since functions called through
  391. function pointers are not automatically locked by Bovs throughout the call,
  392. if such a function were to unlock the last lock on its own overlay node, it
  393. could be unloaded while the function is still running. The only time when
  394. you may unlock the last lock on an overlay node from within such a function
  395. is in assembly language, if the call to UnlockOverlay() is done with a JMP
  396. instruction, causing the call to UnlockOverlay() to return directly to
  397. whatever "outsider" called the function in the first place.
  398.  
  399.     If this all sounds a little complicated at this point, don't panic:
  400. you only need to worry about this if you're using function pointers called
  401. by external modules.  If you stick to normal functions, there is not much
  402. you need to worry about.
  403.  
  404.  
  405.     long ResCall(void *routine,void *arg1,void *arg2)
  406.      D0                   A2          A0         A1
  407.  
  408.     This function is a little gimmick that you might find useful for
  409. creating sleek, fast programs.  It is used to call overlaid functions in a
  410. way slightly different than normal.  If some part of the program wants to
  411. call a function in another overlay node, normally it makes a call normally,
  412. and BLink reroutes the call to go through Bovs.  However, instead of
  413. calling the function directly, you can pass a pointer to it (which BLink
  414. turns into a pointer to one of its dynamically created rerouter routines)
  415. to ResCall, along with the parameters "arg1" and "arg2" which you would
  416. normally pass to the real function in A0 and A1.  ResCall then calls the
  417. function normally, with the parameters that you specify.
  418.  
  419.     If the overlay node containing the needed function is already loaded,
  420. then the function is called normally, and its return value (whatever it may
  421. be) is passed back in D0, as usual.  However, if the overlaid function is
  422. NOT resident, the function is not called at all, and Bovs returns with zero
  423. in D0 immediately, without loading the overlay node.
  424.  
  425.     Thus, ResCall provides a simple and convenient way to call an overlaid
  426. function only if that overlay node is already resident.  I have found this
  427. useful in many cases, but I'll let you figure them out yourself.  In any
  428. case, if the overlay node is resident and the function is called, all
  429. standard overlay function calling and locking conventions still apply.
  430.  
  431.  
  432.  
  433.                                    Bst.o
  434.                                    ~~~~~
  435.  
  436.     The alternate object file "Bst.o" (pronounced "beast") can be used in
  437. place of "Bovs.o" if you want Bovs's startup features without its overlay
  438. system, or if you want to create a non-overlaid version of a program that
  439. is normally overlaid.  Your normally overlaid functions may be called with
  440. anything (including zero) in D0, since they are not called through the
  441. overlay supervisor, and while the LockOverlay() and UnlockOverlay()
  442. functions still exist in Bst, they do nothing.  Therefore, as long as
  443. you're careful, you should be able to link your program in both overlaid
  444. and non-overlaid versions, and have it perform exactly the same either way.
  445. MultiPlayer's registered distribution, for example, contains both overlaid
  446. and non-overlaid versions of the MultiPlayer program, to best suit the
  447. user's preferences.
  448.  
  449.  
  450.  
  451.                                   History
  452.                                   ~~~~~~~
  453.  
  454. 1.0 (18-Feb-92)
  455.         First public release.
  456.  
  457.  
  458.  
  459.                               Contact Address
  460.                               ~~~~~~~~~~~~~~~
  461.  
  462.     I tend to move around a great deal, so mail sent directly to me
  463. sometimes has a hard time catching up.  If you want mail to reach me (it
  464. may take a while, but it WILL reach me), send it to this address:
  465.  
  466.         Bryan Ford
  467.         8749 Alta Hills Circle
  468.         Sandy, UT 84093
  469.  
  470.     I can be reached more quickly (for the time being anyway) on the phone
  471. or through one of the electronic mail addresses below:
  472.  
  473.         (801) 585-4619
  474.         bryan.ford@m.cc.utah.edu
  475.         baf0863@cc.utah.edu
  476.         baf0863@utahcca.bitnet
  477.  
  478.     If you want to get something to me through the mail more quickly, FIRST
  479. call or E-mail me to make sure I'm still here, then send it to this
  480. address:
  481.  
  482.         Bryan Ford
  483.         27104 Ballif Hall
  484.         University of Utah
  485.         Salt Lake City, UT 84112
  486.  
  487.  
  488.