home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / MBUG / MBUG145.ARC / FCRLZH11.LBR / BUFFERS.DYC / BUFFERS.DYC
Text File  |  1979-12-31  |  24KB  |  701 lines

  1. ; BUFFERS is copyright (c) 1986 by:
  2. ;    C.B. Falconer, 680 Hartford Tpk, Hamden, Conn. 06517
  3. ; all rights reserved.                   (203) 281-1438
  4. ;
  5. ; BUFFERS is released to the public domain for non-profit private
  6. ; use only.  It may be freely copied, distributed, and used for
  7. ; such purposes.  It may not be sold, nor included in packages for
  8. ; sale, without the express written permission of C.B. Falconer.
  9. ;
  10. ; All components of BUFFERS.LBR are datestamped, and are protected
  11. ; by CCITCRC checksums (but not BUFFERS.LBR).  "crunched" components
  12. ; (indicated by a middle 'Z' in the filetype) may be extracted or
  13. ; typed by LT (included).  Execute LT with no parameters for help.
  14. ; "ccitcrc filename.typ" on any extracted component should yield
  15. ; a zero checksum.  Version no. is displayed by "TYPE bufflib.slr".
  16. ;
  17. ;    ------    General    ------
  18. ;
  19. ; BUFFERS provides a buffering mechanism for diskfiles, i/o devices,
  20. ; and others.  It provides for byte by byte extraction and insertion,
  21. ; and full du addressing.  A rich variety of utility routines are
  22. ; available.  The searchable library is BUFFLIB.REL or .SLR.
  23. ;
  24. ; BUFFERS is designed to operate correctly when the default drive and
  25. ; or user is changed after the files have been opened.  The code is
  26. ; re-entrant, 8080 executable, and need only appear once in any system.
  27. ; No data segment (except for an addressable end marker) is used, and
  28. ; the linked code may be mounted in ROM.  Buffer sizes and allocation
  29. ; are entirely up to the caller.  The procedures are also compatible
  30. ; with use in interrupt driven or polled i/o systems.
  31. ;
  32. ; NOTE: Various routines expect to operate with adequate stack space
  33. ; available.  In general, SP should be set to the TOP of available
  34. ; memory, and altered with extreme care.  This convention maximizes
  35. ; memory availablity by allowing dynamic assignment and release.
  36. ;
  37. ; Ver. 1.4 provides a cleaner user interface for file name parsing,
  38. ; adds tdzsf (type decimal right justified in field), and options
  39. ; (parse command line options).  pfnm, pfnmdu, getdu, nextch,
  40. ; skipblks were affected.  tdzsf, qwhite, lastch, options, blk, and
  41. ; blks (multiple blanks to console) were added.
  42. ;
  43. ; Ver. 1.3 up provide routines for dynamic stack frame allocation,
  44. ; deallocation, and access.  "move" has different parameters than in
  45. ; Ver. 1.2 (de and hl registers exchanged).
  46. ;
  47. ; Ver. 1.2 up provide routines for expanding and processing wild
  48. ; card specifications.
  49. ;
  50. ; For modification history, see BVER.MAC
  51. ;
  52. ; Various utility routines are also available.
  53. ;
  54. ; After familiarization most users will only require one of 
  55. ; BUFFLIB.SLR (in SLR format) or BUFFLIB.REL (in Microsoft format),
  56. ; depending on their linker, and BUFFERS.DOC, which summarizes all
  57. ; procedures available.  The source can be examined if needed.
  58. ;
  59. ; Examination of the various TESTn.MAC files will demonstrate usage.
  60. ; Linking procedures can be checked by comparison with the pre-linked
  61. ; TESTn.OBJ files provided.
  62. ;
  63. ; The buffer storage space MUST be supplied by the main program, and
  64. ; appropriate pointers passed.  Note that each buffer requires 12
  65. ; bytes of overhead space, in addition to the buffer proper. Programs
  66. ; should use the external b.ohead rather than 12, to allow for
  67. ; future changes.  System flags are kept in the first byte of the
  68. ; buffer.  The second byte is (at present) available for user use.
  69. ; The buffers should only be manipulated by the procedures provided.
  70. ;
  71. ; The disk file linkages provide for full DU control.  The default
  72. ; user (specified by a 0 byte) is that in effect when the file is
  73. ; opened.  Any user can be specified by (user_no + 1).  The file
  74. ; open primitives .FOPNR and .FOPNW are an exception in that they
  75. ; require the absolute user number.
  76. ;
  77. ; TESTn.MAC files are application examples.  Simply declare the
  78. ; appropriate routines as EXTRN, and link the master module with
  79. ; BUFFERS using the /s option.  However, you MUST control the DSEG
  80. ; allocation at link time for these examples.  You can check your
  81. ; linkage procedures by comparing the final .COM file with the
  82. ; two TESTn.OBJ files provided.  Differences in uninitialized data
  83. ; area (after the end of all code) do not matter.
  84. ;
  85. ; BUFFLIB.SLR is in SLR format, and 16 name characters are signifi-
  86. ; cant.  BUFFLIB.REL is in Microsoft format, and all names are trun-
  87. ; cated to 6 characters.  You should normally use the full routine
  88. ; names, and allow the linker and assembler to truncate.
  89. ;
  90. ; Any routine in the library may be over-ridden by linking a routine
  91. ; of the same name BEFORE the library search.  This allows customized
  92. ; versions of .IOPOLL to be used.
  93. ;
  94. ;        --------
  95. ;
  96. ; Linking instructions:
  97. ;
  98. ; With l80 or SLRNK
  99. ;    l80 /p:100,/d:8000,yourfile,bufflib/s,/u
  100. ; and note the next code byte free.  Exit and repeat replacing the
  101. ; "8000" above by this address.  (the 8000 is not a critical value)
  102. ; e.g. if the storage was shown as "100..cde" then enter
  103. ;    l80 /p:100,/d:cde,yourfile,bufflib/s,yourfile/n,/e
  104. ;
  105. ; NOTE: SLRNK shows last byte used, L80 shows next byte free. Thus
  106. ;    for SLRNK add 1 to the value displayed.
  107. ;
  108. ; NOTE: l80 will append unnecessary empty space to the output
  109. ;    file for uninitialized data areas.  Can be removed with DDT
  110. ;    and save, or with DDTZ and "k first,last" command.
  111. ;
  112. ; With SLRNK+
  113. ;    slrnk+ /a:100,/j,yourfile,bufflib/s,yourfile/n,/e
  114. ; and the data area will automatically be placed at the end.
  115. ;
  116. ; CAUTION: When using SLRNK or SLRNK+ do not intermix SLR and REL
  117. ; format files, because all REL (Microsoft) format files truncate
  118. ; module and entry names to 6 chars.  SLRNK and SLRNK+ use up to 16
  119. ; char. names, and thus may not find some entries.  SLRMAC and
  120. ; Z80ASM (from SLR) can create either format.
  121. ;
  122. ;    ------     ENTRY POINTS    -------
  123. ;
  124. ; NOTE: In the following, the notation "hl^" means the memory to
  125. ; which register hl is pointing, and similarly for de^ and bc^.
  126. ;
  127. ; NOTE: Each routine description is followed by a "registers affected"
  128. ; comment, e.g. "a,f", which annotates all registers that the routine
  129. ; may alter.  All others will not be changed.
  130. ;
  131. ;
  132. ; Standard i/o control bits, returned by BSTA. Alter in BUFFDEFN
  133. inrdy    equ    1
  134. ordy    equ    4
  135. ;
  136. ; Bits in b.flgs low order byte.  Hi byte available for user
  137. b.usrm    equ    01fh;    Mask for user area storage
  138. b.spare    equ    020h
  139. b.wrt    equ    040h;    {MUST be reset for read files.
  140. b.eof    equ    080h;    {MUST be set for write files.
  141. b.wflg    equ    b.eof+b.wrt
  142. ;
  143. ; structure of a buffer
  144.     aseg
  145.     org    0;    offsets relative to buffer start
  146. b.flgs:    ds    2;    gp flags. eof/user in lo byte
  147. b.size:    ds    2;    allocated space
  148. b.fcb:    ds    2;    attached fcb, if any
  149. b.cnt:    ds    2;    bytes currently in buffer
  150. b.rptr:    ds    2;    NEXT byte to read from buffer (index)
  151. b.wptr:    ds    2;    NEXT byte to write to buffer (index)
  152. b.body:    ds    0;    Actually b.size bytes
  153. b.ohead    equ    b.body
  154. ;
  155. ;    ------- Version control -------
  156. ;
  157. ; return a=version of bufflib in use, de pointer to version msg.
  158. ; a,d,e
  159. .bver:
  160. ;
  161. ; ------- Buffered file i/o routines, byte and block --------
  162. ;
  163. ; initialize buffer hl^, size bc, attached file de^, on user (a)
  164. ; (where a=0 for current, else 1 larger than user desired),
  165. ; for buffered file writes.  Create/rewind the output file.
  166. ; The caller must make (bc) + b.ohead bytes of storage available.
  167. ; Buffer size (bc) is rounded down to a multiple of 128
  168. ; a,f,(b,c)
  169. .bfwopen:
  170. ;
  171. ; initialize buffer hl^, size bc, attached file de^, on user (a)
  172. ; (where a=0 for current user, else 1 larger than user desired),
  173. ; for buffered file reads.  Carry if file not found.
  174. ; The caller must make (bc) + b.ohead bytes of storage available.
  175. ; Buffer size (bc) is rounded down to a multiple of 128
  176. ; a,f,(b,c)
  177. .bfropen:
  178. ;
  179. ; Close buffered write file hl^.  Carry for failure.
  180. ; Flush buffers to file.
  181. ; a,f
  182. .bfclose:
  183. ;
  184. ; Input (a) from buffered file via buffer hl^.
  185. ; Carry on eof or error.
  186. ; a,f
  187. .bfgetc:
  188. ;
  189. ; Put byte c to buffered file hl^.  Carry for write error
  190. ; a,f
  191. .bfputc:
  192. ;
  193. ; Read into buffer hl^ from attached disc file until less than
  194. ; 128 bytes free or eof.  Carry for eof on entry or read error.
  195. ; This delays the eof signal until .bload cannot read further
  196. ; data. Reset pointers for any extra portion not read
  197. ; Assumes no other access via wptr, i.e. input only buffer
  198. ; This code assumes buffer size to be a multiple of 128 bytes,
  199. ; so that single reads never need to "wrap around" the buffer.
  200. ; a,f
  201. .bload:
  202. ;
  203. ; swap file de^, user/flags a, for the file presently attached
  204. ; to buffer hl^.  Return de a pointer to the previous file, and
  205. ; a as the previous flags lo byte setting.
  206. ; This permits use of a single buffer for fast file transfers,
  207. ; using the .BLOAD and .BDUMP routines to control user access
  208. ; during file read/writes.
  209. ; a,f,d,e
  210. .bfswap:
  211. ;
  212. ; Write from buffer hl^ to attached disc file until less than
  213. ; 128 bytes stored.   Carry for write error.
  214. ; Reset pointers for any extra portion not written.
  215. ; Assumes no other access via rptr, i.e. output only buffer
  216. ; This code assumes buffer size to be a multiple of 128 bytes,
  217. ; so that single writes never need to "wrap around" the buffer.
  218. ; a,f
  219. .bdump:
  220. ;
  221. ; ------ Routines useful with interrupt or polled i/o -----
  222. ;
  223. ; get byte from buffer hl^ when ready, else wait.  Entry for
  224. ; interrupt driven systems.  This enables interrupts.  The .iopoll
  225. ; routine is called whenever no char. is ready in the buffer
  226. ; a,f
  227. .bgetc:
  228. ;
  229. ; get byte from buffer hl^, pause until ready.  Also an entry for
  230. ; interrupt driven systems.  This enables interrupts.  The .iopoll
  231. ; routine is always called at least once.  For polled systems
  232. ; a,f
  233. .bgetp:
  234. ;
  235. ; put byte (c) to buffer hl^ when ready, else wait.  Enables
  236. ; interrupts.  The .iopoll routine is called whenever the buffer
  237. ; is full.  For interrupt driven systems.
  238. ; a,f
  239. .bputc:
  240. ;
  241. ; put byte (c) to buffer hl^ when ready, else wait.  Also an entry
  242. ; for interrupt driven systems.  Enables interrupts.  The .iopoll
  243. ; routine is always called at least once.  For polled systems.
  244. ; a,f
  245. .bputp:
  246. ;
  247. ; Iopoll operation.  Null here.  Link in your own.
  248. ; Can replace interrupt driven io by action here
  249. ; a,f (allowed)
  250. .iopoll: ret    
  251. ;
  252. ; ------ Buffer primitives -------
  253. ;
  254. ; return bc=space available in buffer hl^. If buffer empty align
  255. ; pointers and return 0, else return 0ffh (ptrs unchanged)
  256. ; z flag set accordingly
  257. ; a,f,b,c
  258. .bspace:
  259. ;
  260. ; Fill buffer hl^ with (c) until it holds a multiple of
  261. ; 128 bytes.  Used in final flushing of output buffers.
  262. ; CAUTION: buffer must hold at least 128 bytes
  263. ; a,f
  264. .bfill:
  265. ;
  266. ; get byte from buffer hl^.  No ready/range checks. Clear carry
  267. ; a,f
  268. .bget:
  269. ;
  270. ; put byte c to buffer hl^.  No ready/range checks. Clear carry
  271. ; a,f
  272. .bput:
  273. ;
  274. ; Return ordy and inrdy bits in (a) for buffer hl^
  275. ; ordy means buffer can accept a byte, inrdy means buffer has a byte
  276. ; a,f
  277. .bsta:
  278. ;
  279. ; binit, but ensure size (bc) is a multiple of 128 by truncating
  280. ; a,f,c
  281. .bfinit:
  282. ;
  283. ; initialize buffer hl^ to empty, size bc, attach file de^
  284. ; set initial flags (lo byte only) to a, clear hi byte.
  285. ; For file reads the initial flag should be 0, for write b.wflg.
  286. ; The caller must make (bc) + b.ohead bytes of storage available.
  287. ; a,f
  288. .binit:
  289. ;
  290. ; Set pointers back to start for aligned read/writes.
  291. ; Discard any data in buffer. Return a=0 and z flag.
  292. ; a,f
  293. .bflush:
  294. ;
  295. ; Return bc := space available.
  296. ; If buffer empty return z flag, else 0ffh and non-z flag
  297. ; a,f,b,c
  298. .broom:
  299. ;
  300. ; Compute a CRC16 checksum over the content of buffer hl^.   The
  301. ; initial CRC checksum value is passed and returned in (bc).  It
  302. ; should be initialized to 0ffffh.  .bcrc entry does not initialize,
  303. ; thus allowing the crc checksum to be applied over multiple buffer
  304. ; loads.  This is intended to be used with large buffered transfers,
  305. ; between calls on .bload and the following .bdump.  A file re-read
  306. ; can then quickly verify an accurate transfer.  This code assumes
  307. ; the buffer never wraps, i.e. it is used solely for file/file
  308. ; transfers, so that it is always loaded from the bottom.  If not
  309. ; unloaded it should be flushed (use .bflush) before reloading.
  310. ; Carry for invalid buffer state.
  311. ; a,f,b,c
  312. .bcrc:
  313. ;
  314. ; -------- File name parsing routines and support ---------
  315. ;
  316. ; Parse the next field from the command line (de^) into fcb hl^.
  317. ; Drive id is set, name and type are parsed into fname and ftype,
  318. ; with any '*'s expanded into '?'s, and the fields are blank padded.
  319. ; At exit de points to the field terminating delimiter char, (a) is
  320. ; the count of '?' chars in fname & ftype fields, with flags set on
  321. ; it. Thus the Z flag on exit indicates no wild cards. (c) contains
  322. ; the drive specifier (if any), (b) holds 0 (default user).
  323. ; a,f,b,c,d,e,h,l
  324. .pfnm:
  325. ;
  326. ; Parse the next field from the command line (de^) into fcb hl^. Any
  327. ; drive/user specifications are recorded in c and b respectively,
  328. ; (which default to 0s), with drive recorded in the FCB.  Name and
  329. ; type are parsed into fname and ftype, with any '*'s expanded into
  330. ; '?'s, and the fields are blank padded.  At exit de points to the
  331. ; field terminating delimiter char., (a) is the count of '?' chars.
  332. ; in fname & ftype fields, with flags set on it, bc as above.
  333. ;
  334. ; NOTE that 0 means default user, and a specified user is returned
  335. ; as user no. + 1, i.e. the identical convention to that for drives.
  336. ; This also allows the user specification to be stored in a 5 or 6
  337. ; bit field, depending on whether the max user is 15 or 31.
  338. ; a,f,b,c,d,e,h,l
  339. .pfnmdu:
  340. ;
  341. ; .getdu returns any "du" spec. in b and c, with b = user, c = drv
  342. ; The default user is signified by a -1 value, default drive by 0
  343. ; At entry, de points to the start of the field to be parsed. At
  344. ; exit, either de is unchanged (no du found), or points to ':'.
  345. ;
  346. ; NOTE that the user convention here is different from that used
  347. ; in the remainder of the system.  Convert by incrementing.
  348. ; a,f,b,c,d,e
  349. .getdu:
  350. ;
  351. ; Parse any options from text line de^ into storage hl^.  Advance
  352. ; de to 1st non-blank character, and to option string delimiter
  353. ; if a valid option string found.  bc is a pointer to an option
  354. ; definition string, in the form:
  355. ;     bc^    char    Required "header" char for an option string
  356. ;    bc+1^    count    Number of options available
  357. ;    bc+2^    char    A char that may appear in the option string
  358. ;    ....    etc.     (for count chars)
  359. ; (The storage at bc^ is an image, and is never altered).
  360. ;
  361. ; At exit, if a valid option string is found, hl^ contains a copy
  362. ; of the definition string, with all chars found in the input
  363. ; string ZEROED.  i.e. a zero value means option set.  Options
  364. ; returns with a = 0ffh, and the NZ flag set in this case.
  365. ;
  366. ; If no valid option string is found, or some characters are not
  367. ; present in the image (or present more than once), hl^ contains
  368. ; an unmodified copy of the definition string, and options returns
  369. ; a = 0, with the Z flag set.
  370. ;
  371. ; All candidate characters are upshifted before testing.  Thus an
  372. ; option definition string containing lower case characters can never
  373. ; be matched.  Similarly, if the definition string contains 0 bytes,
  374. ; these are pre-matched locations.  This allows configuration of
  375. ; valid input options in the image string for installation purposes.
  376. ;
  377. ; An option string (not the definition string) consists of a trigger
  378. ; character, followed by a series of characters.  If any string char
  379. ; acter is not present in the option template, the whole string is not
  380. ; an option string, and input conditions are restored.  If all chars
  381. ; are present in the template, those positions are zeroed, and the
  382. ; input parser is advanced to the terminal blank (or control char).
  383. ;
  384. ; If a valid option list is found, 0ffh and nz is returned,
  385. ; otherwise 0 and z flag signal no valid option parsed.  In any
  386. ; case all initial blanks in the input string have been skipped.
  387. ; a,f,d,e
  388. .options:
  389. ;    
  390. ; initialize fcb hl^ to blanks and nulls
  391. ; a,f
  392. .initfcb:
  393. ;
  394. ; Open file de^ on user a for read.  User number is absolute.
  395. ; Carry if file not found.  Read mechanism must control user.
  396. ; If de^.drv is 0 (default drive) lock to current drive, to
  397. ; allow drive changes while the file is open.
  398. ; a,f
  399. .fopnr:
  400. ;
  401. ; Open file de^, user a, for write.  User number is absolute.
  402. ; Carry for error.  Purge any previous file.  Write mechanism must
  403. ; control user settings.  If de^.drv is 0 (default drive), lock to
  404. ; current drive to allow drive changes while the file is open.
  405. ; a,f
  406. .fopnw:
  407. ;
  408. ; reset current record, extent, file de^
  409. ; f
  410. .freset:
  411. ;
  412. ; If fcb de^ uses default drive, lock it to current drive.
  413. ; This allows drive switches after file is opened.
  414. ; a,f
  415. .drvlock:
  416. ;
  417. ;    ------- Wild card expansion routines --------
  418. ;
  419. ; Fill area hl^ up with wild card expansions of fcb de^, on the
  420. ; current user.  Returned entries are the 1st 16 bytes of the
  421. ; directory entry.  Return count of files in bc, pointer to
  422. ; unused buffer area in hl.  Zero flag if no matching files.
  423. ; CAUTION - modifies defdma setting.  Buffer must provide at
  424. ; least 128 bytes more than space required for storage.
  425. ; Carry for insufficient memory, (based on SP pointing to top
  426. ; of memory) when the search is truncated.
  427. ; This procedure is normally used only at initialization time.
  428. ; a,f,b,c,h,l
  429. .wildx::
  430. ;
  431. ; Copy file name from fcb hl^ to fcb de^,
  432. ; only in wild card locations of de^.
  433. ; a,f
  434. .fcwild:
  435. ;
  436. ; copy file name from hl^ to de^ fcbs (name/ext only)
  437. ; removing any attribute bits.
  438. ; a,f
  439. .fncpy:
  440. ;
  441. ; Reset the file name in fcb de^ from entry hl^, clear attribs.
  442. ; At entry hl points one byte below the fname field, i.e.
  443. ; to the user # entry of the file list.  At exit, the
  444. ; fcb de^ has the extent, record pointer, etc zeroed.
  445. ; The drive identifier byte is NOT altered.
  446. ; a returns the user no. in the list hl.
  447. ; This is used to scan file names from wildx lists
  448. ; a,f
  449. .nxtfn:
  450. ;
  451. ; next output file name.  Copy hl^ to de^, then update from
  452. ; bc^.  Thus all wild areas in entry hl^ are filled in with
  453. ; the actual chars in entry bc^.  For wild card copy operations
  454. ; normally bc is the input fcb, hl the output pattern (with
  455. ; wild cards), and de points to the actual output fcb.
  456. ; a,f
  457. .nxtout:
  458. ;
  459. ; Check fcbs hl^ and de^ have wild cards in the same areas.
  460. ; Carry if not.  This checks compatibility between input
  461. ; and output wild card specifications.
  462. .wldck:
  463. ;
  464. ; ------- Utility/support routines, available to user -------
  465. ;
  466. ; adv ptr hl^ by 128 modulo bc, de := unadvanced ptr, hl:= hl+1
  467. ; Wrap around signalled by no carry on exit with nz flag, when
  468. ; c returns the bytes to be wrapped.
  469. ; a,f,c,d,e,h,l
  470. .advance:
  471. ;
  472. ; advance de by 1, modulo bc
  473. ; a,f,d,e
  474. .advptr:
  475. ;
  476. ; Check hl for the value 0, preserve a.  Carry if zero
  477. ; f
  478. .nilchk:
  479. ;
  480. ; fill hl^ for b with a, advance hl
  481. ; f,b,h,l
  482. .fillc:
  483. ;
  484. ; move hl^ to de^ for bc bytes.  Advance ptrs de and hl
  485. ; guarded against 0 length move. 
  486. ; Interchanged source/dest regs 86/11/27 to agree with ldir <---*
  487. ; a,f,b,c,d,e,h,l
  488. .move:
  489. ;
  490. ; load de from hl^, advance hl by 2
  491. ; d,e,h,l
  492. .ldem:
  493. ;
  494. ; store de to hl^, advance hl by 2
  495. ; h,l
  496. .sdem:
  497. ;
  498. ; decrement word hl^, advance hl by 1 (to hi byte of m)
  499. ; z flag for zero after decrementing
  500. ; a,f,h,l
  501. .dcxm:
  502. ;
  503. ; increment word hl^, advance hl by 1 (to hi byte of m)
  504. ; z flag for zero after incrementing
  505. ; a,f,h,l
  506. .inxm:
  507. ;
  508. ; trade de^ and hl^ for c bytes
  509. ; a,f
  510. .mxchg:
  511. ;
  512. ; compare hl and de (unsigned)
  513. ; if de > hl then z reset, carry set
  514. ; if de = hl then z set,   carry clear
  515. ; if de < hl then z reset, carry clear
  516. ; (organized like "cmp r", using hl as accumulator)
  517. ; f
  518. .dcmp:
  519. ;
  520. ; subtract de from hl. Like "DAD d"
  521. ; f,h,l
  522. .dsub:
  523. ;
  524. ; This crc routine updates the checkword in bc using the byte
  525. ; passed in a.  The two byte checkword is produced by the
  526. ; generating polynomial x**16+x**12+x**5+1.  The checksum should
  527. ; be initialized to 0ffffh (i.e. 0ffffh is passed in bc when the
  528. ; checksum sequence is started). bc returns the new checksum.
  529. ; a,f,b,c
  530. .crc:
  531. ;
  532. ; Get next character from line, upshifted, Z flag for a delimiter,
  533. ; carry if the character is illegal or eoln.  No advance past eoln.
  534. ; Return char in a and leave de pointing to it. cy for eoln
  535. ; a,f,d,e
  536. .nextch:
  537. ;
  538. ; Return last character, as above.  Carry if invalid or eoln
  539. ; a,f
  540. .lastch:
  541. ;
  542. ; skip blanks and tabs in input line.  Carry on illegal chars.
  543. ; return the 1st non-blank char. found.
  544. ; a,f,d,e
  545. .skipblks:
  546. ;
  547. ; Advance to non-blank, line de^. "call .nextch ! call .skipblks"
  548. ; a,f,d,e
  549. .nxt:
  550. ;
  551. ; Check white space, carry for illegals or eoln. z flag for white
  552. .qwhite:
  553. ;
  554. ; upshift a if lower case
  555. ; a,f
  556. .upshft:
  557. ;
  558. ; check a for numeric char, carry if not
  559. ; f
  560. .qnum:
  561. ;
  562. ; unsigned integer multiply.  Reverse of .idiv
  563. ; operand range 0 to 65535, product 0 to 4295*10^6 (approx)
  564. ; (dehl) := (bc) * (de)
  565. ; d,e,h,l
  566. .imul:
  567. ;
  568. ; unsigned integer divide.  Reverse of .imul
  569. ;    (de) := (dehl) DIV (bc);    (hl) := (dehl) MOD (bc)
  570. ; carry for overflow (or zero divide), when registers unchanged
  571. ; divisor, remainder and quotient range 0 to 65535
  572. ; dividend range 0 to 4295*10^6 (approx)
  573. ; f, d, e, h, l
  574. .idiv:
  575. ;
  576. ; 2's complement (bc), leave (b) in (a)
  577. ; a,b,c
  578. .c2bc:
  579. ;
  580. ; 1's complement (bc), leave (b) in (a)
  581. ; a,b,c
  582. .c1bc:
  583. ;
  584. ; divide unsigned integer (hl) by 10
  585. ; remainder appears in (a) with flags set on it
  586. ; a,f,h,l
  587. .dten:
  588. ;
  589. ; convert 4 bit hex value to ascii in (a)
  590. ; a,f
  591. .hexa:
  592. ;
  593. ; xltusr imposes the same user/default relationship as used for
  594. ; drives, i.e. 0 returns the current logged in user, other values
  595. ; return value - 1.
  596. ; a,f
  597. .xltusr:
  598. ;
  599. ; get current user
  600. ; a,f
  601. .getusr:
  602. ;
  603. ; setuser # a
  604. ; a,f
  605. .setusr:
  606. ;
  607. ; bdos call #(a), preserve registers, set flags on returned (a)
  608. ; Do not use when 16 bit return values needed in hl.
  609. ; a,f
  610. .dos:
  611. ;
  612. ;    -----    Utility Console Output via bdos calls    -----
  613. ;
  614. ; output (a) in decimal to console, suppress leading zeroes
  615. ; f
  616. .tadzs:
  617. ;
  618. ; write (hl) in decimal to console, suppress leading zeroes.
  619. .tdzs:
  620. ;
  621. ; Write hl (dec) in minimum (a) char. field, right justified.
  622. ; (If the field is too small more columns are used). Max field 128
  623. ; a,f
  624. .tdzsf:
  625. ;
  626. ; write filename for fcb (de)^, user (a), to console, string format
  627. ; a,f
  628. .tfnam:
  629. ;
  630. ; console output (a)
  631. ; a,f
  632. .couta:
  633. ;
  634. ; Blank to console
  635. ; a,f
  636. .blk:
  637. ;
  638. ; (a) blanks to console.  0 value valid
  639. ; a,f
  640. .blks:
  641. ;
  642. ; cr & lf to console
  643. ; a,f
  644. .crlf:
  645. ;
  646. ; .crlf and then .t4hx
  647. .t4hxc:
  648. ;
  649. ; print (hl) in hex (4 chars.) on console
  650. ; a,f
  651. .t4hx:
  652. ;
  653. ; list a byte (a) as 2 ascii char.
  654. ; a,f
  655. .t2hx:
  656. ;
  657. ; convert (a) 4 lower bits to hex & print on console
  658. ; a,f
  659. .hxd:
  660. ;
  661. ;    ---   Stack frame allocation/deallocation/addressing    ----
  662. ;
  663. ;
  664. ; Allocate space for (bc) bytes on stack, rounding up to next 16
  665. ; at exit (sp)+2 points to allocated space.  See salloc.
  666. ; Exit with carry set if space requested too large (over 4k).
  667. ; Note that this does not check for stack overflow.
  668. ; a,f (sp)
  669. .sbcalloc:
  670. ;
  671. ; Allocate 16*a bytes on the stack, and leave a deallocate pointer
  672. ; on TOS.  Thus "pop h | sphl" will deallocate.  A maximum of 4096
  673. ; bytes can be allocated (a=0 means 256).  Remember to round up byte
  674. ; requirements to the next multiple of 16, or use sbcalloc entry.
  675. ; For more do the following in line:
  676. ;    mvi    a,0
  677. ;    call    salloc;        1st 4k
  678. ;    pop    h;        dealloc ptr, destroy hl
  679. ;    mvi    a,extra;    part from 4096 to 8192
  680. ;    call    salloc
  681. ;    xthl;            save dealloc to 1st part    
  682. ; At exit sp+2 is the lowest byte of the allocated memory.
  683. ; and carry is reset.
  684. ; a,f, (sp)
  685. .salloc:
  686. ;
  687. ; load hl from stack level l (with respect to caller).
  688. ; i.e. l=0 corresponds to sp = TOS
  689. ;      l=1 corresponds to sp+2 (value under TOS) etc.
  690. ; Use this like lhld, with relative word address in l.
  691. ; Maximum l value on entry is 127
  692. ; h,l
  693. .lhlstk:
  694. ;
  695. ;    ----    Data Segment Control    ----
  696. ;
  697. ; Marker for end of data segment. Value is that of FREE byte.
  698. ; LAST item in library.
  699.     dseg
  700. .endata    equ    $
  701.