home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / asmutl / zsm23.lbr / XLIB.DZC / XLIB.DOC
Text File  |  1991-08-28  |  19KB  |  357 lines

  1. This library uses the same parameter passing mechanism as lib.l: see lib.doc
  2. for a discussion of this.
  3.  
  4.  
  5. _crypt:        c2 = _crypt(c1);
  6. _setcr:        _setcr(str);
  7.  
  8. _crypt and _setcr implement an encryption system: _setcr initiates the system,
  9. and repeated calls to _crypt encrypt or decrypt the data. The string passed
  10. to _setcr may be considered a password, this string is used to initiate the
  11. crypt system. Once this has been done, each character of plain text is passed
  12. to _crypt, which returns the encrypted result. It should be noted that the
  13. action performed by _crypt is self inverting, so in a typical application, a
  14. file might be processed byte by byte through _crypt, after a password had been
  15. passed to _setcr. This would generate an encrypted version of the file, which
  16. could be restored by repeating the process. NOTE: No guarantees are given as
  17. to the security of this system: you use it at your own risk. In practice the
  18. encryption process should deter casual perusal, although if the NSA were to
  19. set a Cray 2 on this they might be able to break it.
  20.  
  21.  
  22. _rnd:        i = _rnd(n);
  23.  
  24. This returns a random number from 0 to n - 1 (unsigned); This routine uses
  25. an algorithm based on multiply overflow, rather than remainder on division,
  26. so there is no weighting problem with repeated calls doing _rnd(40000)
  27.  
  28.  
  29. _rand:        i = _rand()
  30.  
  31. This returns a random 16 bit quantity.
  32.  
  33.  
  34. _srand:        _srand(a, b);
  35.  
  36. In _rnd & _rand, certain values are used to seed the random number
  37. generator, and while they may be different from one program to the next,
  38. for successive runs of a given program they will be the same, hence causing
  39. _rand to return the same sequence of numbers. _srand provides a means to
  40. reseed the R.N.G., this can be done in one of four ways:
  41.  
  42. 1. _srand(0) prints a "canned" string, and waits for the user to hit return.
  43. While it's waiting, a counter is kept running, and the resulting value is
  44. used to reseed the R.N.G.
  45.  
  46. 2. _srand(1, str) prints str, and waits for any character to be typed, again
  47. running the counter. Hwever it does not "eat" the character typed in the same
  48. way as _srand(0) will: typical use might be the signon message printed by an
  49. interactive program, and as soon as the user responds, the R.N.G. is reseeded,
  50. and the program can carry on.
  51.  
  52. 3. _srand(2) this one starts by reading the refresh register, then does some
  53. disk i/o, then gets a second value from the refresh register. It then uses
  54. the two 8 bit values as one 16 bit value to reseed the R.N.G.
  55.  
  56. 4. _srand(3, n) simply uses n directly to reseed the R.N.G. Note that n is
  57. used in combination with the current seed, so repeated _srand(3, n)'s with
  58. the same value of n will keep reseeding the R.N.G. to different states.
  59.  
  60. Any other value given as the first argument is used directly, the only
  61. reason that _srand(3, n) is present is to allow n to be 0, 1, 2 or 3.
  62.  
  63.  
  64. _setlin:    _setlin(x1, y1, x2, y2)
  65. _point:        i = _point(xp, yp)
  66.  
  67. _setlin and _point are a pair of routines that operate a straight line drawing
  68. algorithm. To set up, _setlin is called with the two endpoints of the line in
  69. x,y coordinates: drawing starts at x1,y1 and goes to x2,y2. _point gets the
  70. next point on the line: xp and yp are the addresses of two integer variables
  71. into which the coordinates are placed. The return value i will be true (non-
  72. zero) while the values put in xp and yp lie between x1,y1 and x2,y2, but after
  73. the last point (x2,y2) has been returned, _point starts returning false (zero)
  74. although it will continue to return coordinate pairs that extend the line.
  75.  
  76.  
  77. _assert:    _assert(test, fmt, a1, a2, a3, ...)
  78.  
  79. _assert is used to check a condition while a program is running: it inspects
  80. it's first argument, if true then _assert simply returns. If the first
  81. argument is false (zero) then the format and arguments are processed as in
  82. _printf producing an error message, after which the program aborts: control
  83. is passed back to CP/M.
  84.  
  85.  
  86. _initp        ok = _initp(array, size, width)
  87. _perm        ok = _perm()
  88.  
  89. These two handle generation of all possible permutations of a given data
  90. array. _initp is called to set the system up: array is the address of the
  91. data that will be permuted, size is the number of elements in the array,
  92. and width is the width of each one. Note that size must be between 1 and 16
  93. inclusive, and width must be between 1 and 255 inclusive. If the call is
  94. successful, ok is zero, if there is an error (size or width out of range)
  95. ok gets -1. _perm is called to generate the next permutation: it moves
  96. the data around within the array passed to _initp, so this area of memory
  97. must remain useable throughout the operation. If _initp has not been called
  98. or returned an error (-1) then _perm will also return -1, and take no
  99. other action. If _initp was successful, then _perm will return 1 until it
  100. generates the last permutation (i.e. the data in array is returned to it's
  101. original state), at which point it returns 0 to show that this is the final
  102. permutation. However, successive calls to _perm will continue to cycle
  103. through the same sequence of permutations, returning 1 again until the data
  104. returns to it's original order etc. etc.
  105.  
  106.  
  107. _printf,
  108. _sprintf,
  109. _fprintf,
  110. _xprintf:    The arguments passed to these are exactly as in the _printf
  111. family in LIB.L: however more options are available in the formatting. In all
  112. cases a '-' immediately following the '%' that introduces a format specifier
  113. indicates that the information should be left justified rather than the
  114. default right justification. In addition for strings ('%s') a second number
  115. can be given by preceding it with a period ('.'): the effect of this is to
  116. specify a maximum field width: so if %.10s was given, then at most ten
  117. characters from the string would be printed, the remainder would be discarded.
  118. This can be used in conjunction with a minimum field width: for example assume
  119. %12.10s was given. In this case there would always be at least two blanks on
  120. the left, because the output must be at least 12 characters wide, but only a
  121. maximum of 10 can be printed from the string. In addition two other numeric
  122. output formats are recognised. %r %R: these print in roman numerals for
  123. values between 1 and 4999 - %r uses lower case, and %R uses upper case. Zero
  124. is printed as '0' and values greater than 4999, which cannot be represented
  125. using the standard ASCII character set, are replaced by a number of '*'
  126. characters to signify the error. %a %A: these print in 'alphabetic' notation:
  127. zero is again printed as '0', but 1 becomes 'a' or 'A' (%a generates lower
  128. case, and %A generates upper case), 2 becomes 'b', 3 - 'c', ... 25 - 'y',
  129. 26 - 'z', 27 - 'aa', 28 - 'ab' and so on. As with all numeric outputs, %r, %R,
  130. %a and %A recognise a minimum field width before the format specifier, and
  131. the '-' to force left justification. Finally %z causes a 'recursive' _printf
  132. to occur. The argument is taken as the address of an array of integer words
  133. which is assumed to be the following: the first word is the address of a
  134. format string, and the second and subsequent words are the values to be
  135. processed by the format.
  136.  
  137.  
  138. _scanf,
  139. _sscanf,
  140. _fscanf,
  141. _xscanf:    These four routines form a set of routines for doing formatted
  142. input, in a similar manner to _printf et al. The parameters are similar:
  143. _scanf takes a format as it's first argument, followed by a series of pointers
  144. to locations where the scanned values are returned. _scanf reads from standard
  145. input (the keyboard, unless redirected - for an explanation of redirection
  146. read ARX.DOC). _sscanf takes an additional parameter before the format which
  147. is the address of a string (zero byte terminated) from which the scanning
  148. will be done. _fscanf has a similar first parameter, but in this case it is
  149. a file pointer such as _fopen would return (see LIB.DOC for an explanation
  150. of _fopen and file pointers). _xscanf takes the address of a procedure that
  151. can be called to get successive characters: this procedure must observe the
  152. standard protocol (can destroy de and a, value returned in hl, bc, ix, iy
  153. must be preserved). The format string is similar to that of _printf: to start
  154. a conversion a '%' character is given, followed by an optional assignment
  155. suppression character: '*', followed by an optional maximum field width given
  156. as a number, followed by a format specifier. Format specifiers are just like
  157. in _printf: 'd' for a number, 'u' for an unsigned number, 'o' for an octal
  158. number, 'x' for a hexadecimal number, 'b' for a binary number, 's' for a
  159. string, and 'c' for a character. Other characters in the format string must
  160. match the input, if a mismatch occurs then scanning stops. Note that since
  161. '%' has special meaning in the format string, if a '%' in the input is to be
  162. matched, then '%%' should be given in the format string. White space in the
  163. format string matches optional white space in the input stream, so it is a
  164. good idea to place a space after every conversion specifier in the format
  165. string to cause the input field delimiters to be consumed. In the simplest
  166. case _scanf will parse a sequence of fields separated by white space. As an
  167. example, if the format were:
  168.  
  169.     '%d %x %s'
  170.  
  171. then:
  172.  
  173.     '42 a3e hello '
  174.  
  175. would be suitable input. The arguments that should follow the above format
  176. are two pointers to integers: these will receive 42 and 0xa3e respectively,
  177. and the address of a character buffer that will receive the string 'hello'
  178. complete with a zero byte to terminate it. In this case scanf would return
  179. 3: it's return value is the number of successfully converted and assigned
  180. fields. Note that conversions that are not assigned because of a '*' are not
  181. included in the return count. Note however, if the format were:
  182.  
  183.     '%d %2x %s'
  184.  
  185. then the two integers would get 42 and 0xa3 (two characters maximum), and the
  186. string would receive 'e' (first byte following the 'a3'). Assignemt supression
  187. causes a field to be scanned, but it is then thrown away: so no argument
  188. should be pushed onto the stack to receive the scanned value. Note that if
  189. '%05s' is given as the format specifier, then normal white space supression
  190. is ignored: this simply transferrs the next five characters verbatim to the
  191. string buffer provided. There is a final conversion specifier that behaves
  192. somewhat like 's': it allows recognition of strings of arbitrary length, but
  193. delimited by non white space characters. If the format specifier is '[' then
  194. characters upto a matching ']' are taken as a set that defines what the string
  195. must be composed of. In cases where a range of characters (e.g. ABCDEFGHI)
  196. needs to be given A-I will suffice. Note also that characters are converted
  197. until one is found that is not in the range given in []: if the reverse is
  198. required, i.e. conversion of all characters not specified, then by providing
  199. a '^' as the first character, the sense of testing is reversed. Since ']',
  200. '^' and '-' have special meaning, they can be escaped by being preceded with
  201. a '\' (which can also escape itself). Note however, these significant
  202. characters should not be used as part of a range specifier: for example if
  203. the range 'WXYZ[\]' were being scanned, it would be necessary to do it as
  204. 'W-[\\\]' where the 'W-[' gives the first five, the '\\' gives a '\', and the
  205. '\]' gives the ']'. Note also, because of the way ZSM works, when assembling
  206. a string that contains a backslash it must itself be escaped to ZSM, so the
  207. above format in a ZSM source would appear as 'W-[\\\\\\]', because each '\\'
  208. pair in the ZSM db string source gets converted to a single '\' in the
  209. program. To give some working examples: if a CP/M directory name were to
  210. be converted to a drive, a filename, and an extension the following might
  211. be useable:
  212.  
  213.     '%c:%8[A-Z0-9].%3s'
  214.  
  215. where the '%c' would match the drive specifier and assign it into an integer
  216. pointer. The ':' matches, then the %8[A-Z0-9] would match an alphanumeric
  217. only string with a maximum length of 8 characters, followed by a '.' and
  218. another string of up to 3 characters. In this case however, a filename such
  219. as A:-HELP.TXT would fail as the '-' would not match. This can be better done
  220. by:
  221.  
  222.     '%c:%8[^.].%3s'
  223.  
  224. where the %8[^.] matches anything that is not a '.'. Of course in this case
  225. spaces would be considered valid characters, however by adding suitable
  226. characters to the group in the [], this problem could be avoided. One last
  227. word of warning: in all cases except 's' and '[' the parameter given must
  228. be a pointer to an integer, so that the value can be properly saved, and
  229. 's' and '[' require the address of a buffer big enough to take the string.
  230. In the case of scanning from a file (_fscanf) or from standard input (_scanf),
  231. -1 is returned if the first thing encountered in the input is an end of file.
  232. This is different from a zero which means that input was read, but could not
  233. be matched at all.
  234.  
  235.  
  236. _qsort        _qsort(array, size, width, test)
  237.  
  238. _qsort is used to sort an array in memory. It takes four parameters: the
  239. first is the address of the array to be sorted, the second is the number
  240. of elements in the array, the third is the width in bytes of each element,
  241. and the fourth is a routine that will be used to test if one element is
  242. smaller, equal to, or greater than a second. test will be called with the
  243. addresses of two elements from the array on the stack: as an example if
  244. the array contained integers, then the parameters given to test would be
  245. pointers to two of these integers, or if the array contained pointers to
  246. strings, test would receive pointers to pointer to strings. test should
  247. compare the two elements given to it and return a negative number if the
  248. first was smaller, zero if they were equal, and a positive number if the
  249. first was greater. Note that the first argument is given in terms of
  250. the standard calling order: test(arg1, arg2) - so in fact the first argument
  251. would be the one pushed immediately prior to the call to test: on the
  252. stack on entry to test would be:
  253.  
  254.             second arg
  255.             first arg
  256.             return address to _qsort
  257. stack pointer --->
  258.  
  259. Note that test must adhere to the standard calling convention: i.e. it can
  260. destroy de and a, it's result is returned in hl; and bc, ix and iy cannot
  261. be damaged.
  262.  
  263.  
  264. _search        pointer = _search(array, size, width, test, match)
  265.  
  266. _search scans a sorted array looking for a specific element. The first
  267. four parameters are exactly as in _qsort, however the array must already
  268. be sorted (i.e. by a call to _qsort). match is a pointer to an entry like
  269. those in the array (e.g. if the aray contained integers, match would be
  270. a pointer to an integer). _search returns the address in the array of the
  271. first element in the array greater than or equal to the match element, or
  272. NULL if all elements are less than match.
  273.  
  274.  
  275. _exec        _exec(program)
  276. _execl        _execl(program, arg1, arg2, ... argn, 0)
  277.  
  278. These two provide the means to chain from one program to another: in both
  279. cases the first parameter is the address of a string containing the name
  280. of the program to chain to. Note that the '.COM' extension is added by
  281. the routines. _exec simply invokes the program with no arguments, setting
  282. the command tail buffer at 0x0080 empty, and the default fcbs at 0x005c
  283. empty as well. _execl allows one or more arguments to be given to the
  284. program: arg1, arg2, etc. are pointers to strings containing the arguments:
  285. they are terminated by a NULL (zero) pointer. These are placed into the
  286. buffer at 0x0080, in the same manner as CCP does, in addition the default
  287. fcbs at 0x005c and 0x006c are initialised.
  288.  
  289.  
  290. _alloc        memory = _alloc(size)
  291.  
  292. _alloc provides a more flexible memory allocation system than _sbrk in LIB.L:
  293. in particular it is possible to return a block of memory to the system for
  294. further use. _alloc is the basic memory allocation routine: it takes a size
  295. and returns a pointer to a block of memory that many bytes big. NOTE: _alloc
  296. places certain internal accounting information in the area just outside
  297. the block returned, so when using this memory do not access areas anywhere
  298. outside it. Also note that unlike _sbrk, _alloc does not return contiguous
  299. memory. If there is insufficient memory available to fulfill the request,
  300. _alloc returns NULL (zero) to signify the error.
  301.  
  302.  
  303. _realloc    newmem = _realloc(memory, size)
  304.  
  305. _realloc allows a block of memory handed out by _alloc to have it's size
  306. changed after the fact. The first parameter should be a pointer previously
  307. returned by _alloc, and the second should be the new size. _realloc returns
  308. a pointer to the new area, which may not the at the same address. Note
  309. however that if the new pointer is different, than _realloc will copy as
  310. much of the original data as makes sense (i.e. the smaller of the original
  311. and new sizes)
  312.  
  313.  
  314. _free        _free(memory)
  315.  
  316. _free returns a block of memory previously given out by _alloc or _realloc
  317. to the system, for subsequent re-use. Note that the data contained in the
  318. memory is not affected, but it's validity cannot be guaranteed: _alloc or
  319. _realloc may hand portions of it out at any subsequent time.
  320.  
  321.  
  322. _xfree        _xfree(memory, size)
  323.  
  324. _xfree allows a piece of memory NOT given out by _alloc or _realloc to be
  325. added to the system for subsequent use. The first parameter is the address
  326. of the memory being handed to the _alloc system, and size should be it's
  327. size in bytes. This might be used to allow _alloc to use a large data table
  328. that was used once for initialisation, but would then remain idle.
  329.  
  330. Caveat: The above four routines require that strict discipline be maintained
  331. regarding their usage: if a program writes outside the bounds of a memory
  332. area given to it, or _free is handed an arbitrary pointer, then this may
  333. well lead to a program crash.
  334.  
  335.  
  336. _alloca        memory = _alloca(size)
  337.  
  338. _alloca is similar to _alloc, but it allocates memory in the stack frame
  339. of the procedure that called it. It allocates the memory by adjusting
  340. the stack pointer to create a block on the stack, and then returning a
  341. pointer to it. It is the responsibility of the calling procedure to reset
  342. the stack pointer: if #csv and #cret are in use, then the jump to #cret
  343. will clean up automatically, otherwise some other means must be found
  344. to reset the stack pointer. Note that any values pushed onto the stack
  345. before a call to _alloca cannot be subsequently popped off: they live above
  346. the block, and the stack pointer points to the bottom.
  347.  
  348.  
  349. The following is a list of further external labels that are reserved - these
  350. are used by the above routines, and their names should not clash with any
  351. external labels in the program being linked.
  352.  
  353.  
  354. #addcom        #alcb        #alcp        #argfcb        #doexec
  355. #doprnt        #doscan        #getmem        #seed        #setfcb
  356. #testdh
  357.