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 / JSAGE / ZSUS / TCJ / TCJ37BMM.WS < prev    next >
Text File  |  2000-06-30  |  26KB  |  591 lines

  1.  
  2.  
  3. TCJ #37
  4. _words in italics_
  5. .h1  main headings
  6. .h2  secondary headings
  7.  
  8.                 Advanced CP/M
  9.               Raw and Cooked Console I/O
  10.                Bridger Mitchell
  11.  
  12.                         The Computer Journal, Issue 37
  13.                           Reproduced with permission
  14.                            of author and publisher
  15.  
  16. .h1 ZSDOS News
  17.  
  18. The brand-new CP/M disk operating system -- ZSDOS -- that I announced
  19. in this column last fall is meeting an enthusiastic reception.  At
  20. that time I wrote that the quality of the design and testing that have
  21. gone into this project means we are unlikely to see a long series of
  22. revision numbers to fix bugs.  But I didn't mean to imply that a major
  23. upgrade, ZSDOS 2.0, might never appear!  Indeed, I should have gone on
  24. to say that we may expect further contributions from the design team.
  25.  
  26. In the first of a multi-part article in this issue of TCJ, two of the
  27. ZSDOS authors -- Hal Bower and Cameron Cotrill -- take you behind the
  28. scenes of the many innovations in the new DOS.  And several of you
  29. have asked about porting ZSDOS to banked-memory (HD64180, Z80)
  30. systems.  Well, early discussions are afoot to set specifications for
  31. a banked-memory version with well-defined memory-management services.
  32.  
  33. Meanwhile Carson Wilson, the third member of the team, has been avidly
  34. turning out system utilities with nifty new features and is at work on
  35. a Z-System version of a popular public-domain memory-based editor.
  36.  
  37. If you haven't already ordered it, ZSDOS is available from Plu*Perfect
  38. Systems and Sage Microsystems East.
  39.  
  40. .h1 Feedback Loop
  41.  
  42. With the demise of yet another magazine (Profiles) that provided some
  43. coverage of CP/M topics, TCJ takes on greater prominence as a
  44. continuing source of high-quality CP/M information.  Art Carlson and
  45. we regular columnists need your feedback and suggestions to keep
  46. expanding and broadening TCJ's material.
  47.  
  48. I've appreciated the cards and BBS messages several of you have sent.
  49. They indicate that you find these columns worthwhile, although not
  50. always fully digestible in one sitting!  I will continue to focus on
  51. more advanced technical topics relating to the CP/M operating system,
  52. aiming to get the core concepts and details into print.  I fully
  53. expect readers to extend, expand, revise and critique these pieces --
  54. that's how our hobby progresses!
  55.  
  56. I'd especially like to receive suggestions for topics for futureècolumns.  One early candidate is methods to make the Z-System external
  57. environment address available to applications that have not been coded
  58. as a Z-System tool, including compiler-generated .COM files.
  59.  
  60. I'd also welcome information about adding 3.5" and high-density 1.2MB
  61. 5.25" drives to CP/M systems.  I've recently customized
  62. DosDisk for an OEM to handle the AT-style 1.2MB floppy disk format.
  63. The DosDisk software could be similary extended to handle the 3.5"
  64. MS-DOS format, but in order for this to be usable the BIOS must talk
  65. to the drive.  Some of you have doubtless done this, or at least
  66. thought it through.  It would make a nice TCJ article!
  67.  
  68.  
  69. .h1 Unit-Record Input/Output
  70.  
  71. A processor is isolated and quite useless until it can talk to the
  72. "outside world".  Input and output are essential -- they supply the
  73. processor with data and enable it to report results.  Memory chips
  74. provide the fastest i/o.  After that come hard disks, floppy disks,
  75. magnetic tape, and serial channels at decreasing data rates. 
  76.  
  77. In TCJ #35 we covered file systems.  Input and output to files is done
  78. in blocks (physical sectors) of many bytes, and file storage devices
  79. (floppy disks, hard disks, tape drives, ram disks) are sometimes
  80. called block-devices.
  81.  
  82. Our interest in this column is input/output to/from _character_
  83. devices -- devices that normally supply or accept one byte at a
  84. time, such as a terminal, printer or modem.  Single-byte devices
  85. are sometimes called unit-record devices; they can be thought of
  86. as special block devices with a record length of one.
  87.  
  88. For many purposes it's useful to think of the computer's software
  89. environment as a series of rings.  At the outer ring are the
  90. application programs.  Just inside are the high-level languages,
  91. and inside that is the operating system.  Its outermost layer is
  92. the BDOS, providing a standardized, hardware-independent set of
  93. high-level services for access to the file structure and bundled
  94. input/output services to various devices. 
  95.  
  96. The next ring is the BIOS, providing all of the primitive
  97. input/output services needed by the BDOS.  It is the border land
  98. between a standard system and the specific computer.  At the BIOS
  99. jump table the interface is completely standardized, but within
  100. the BIOS the system designer must program down to bare metal,
  101. coding routines that know the precise conditions of the hardware
  102. -- disk drive, video display, printer handshaking conditions.
  103.  
  104. In general, applications will be more portable and easier to write if
  105. they confine their operating system access to the outer ring -- BDOS
  106. calls.  Yet there are good reasons for using BIOS calls in some
  107. applications, those that require highest performance or services
  108. unavailable from the BDOS.  And in a few cases, an application mustèforego portability and itself directly access the hardware, because no
  109. BIOS service is available; for example, to read a video terminal's
  110. screen or use a modem port.
  111.  
  112. The CP/M 2.2 BIOS provides character-device services for the
  113. basic device needed to command the system (the console),
  114. an auxiliary device, and a printer.  These services are:
  115.  
  116.     CONSTAT        Console Input Status
  117.     CONIN        Console Input
  118.     CONOUT        Console Output
  119.  
  120.     READER        Auxiliary Input
  121.     PUNCH        Auxiliary Output
  122.  
  123.     LISTSTAT    Printer Output Status
  124.     LIST        Printer Output
  125.  
  126. Each input or output service returns or sends a single byte.  For
  127. input, the routine waits until a byte is ready before it returns; for
  128. output, it waits until the device can accept the byte.
  129.  
  130. Strangely, only one BIOS input device and one output device has a
  131. status call function available to an application.   The BDOS or
  132. an application can determine, by calling CONSTAT, whether a
  133. character is waiting in the input (a key has been pressed). 
  134. Similarly, it can call LISTSTAT to see whether the printer is
  135. idle and can accept a character.
  136.  
  137. But there is no portable way, in CP/M 2.2, to determine whether the
  138. console device is ready to _accept_ a character.  All you can do
  139. is call CONOUT to send the character and wait, hoping that the
  140. device will eventually be ready.  This might seem all right (how
  141. would you run a CP/M system if you couldn't see its console
  142. output?).   But, consider an application that wants to keep the
  143. processor running at full efficiency (perhaps a video game, or just
  144. a smart display utility).   It would like to send a character to
  145. the console only when it knows that it will be processed immediately.
  146.  
  147. Internally, however, the BIOS must have a routine to determine
  148. the input and output status of every device.  In order to obtain
  149. a valid byte of input it must not access the physical device (a
  150. parallel port, an asynchronous receiver chip) until the device
  151. signals, by some type of status report, that a byte is ready.
  152. And similarly, the BIOS must not output a byte to a physical
  153. device (video ram, serial tranmsitter chip, parallel port) until
  154. the device signals that its buffer is empty and ready to recieve
  155. a byte. 
  156.  
  157.  
  158.  
  159. .h1 Cooked Input
  160. èThe BDOS provides standardized services to applications, hiding
  161. some of the tedious details of communicating with the input and
  162. output devices.  For the console device the BDOS provides
  163. _cooked_ (processed) input and output services, sparing the
  164. programmer the overhead of including this code in almost
  165. every application.  For applications needing raw console input and
  166. output, the BDOS also provides a raw (uncooked) function #6.
  167.  
  168. In CP/M 2.2, console single-character input function (#1) provides:
  169.     
  170.     . echo to console output
  171.     . flow control
  172.     . abort control
  173.     . tab expansion
  174.  
  175. In addition, the console line-input function (#10) provides
  176. limited line-editing and printer controls:
  177.  
  178.     . delete last-character (backspace)
  179.     . cancel line (^X or ^U)
  180.     . retype line (^R)
  181.     . list device output control
  182.  
  183. (Other function #10 editing controls -- delete and echo, and end
  184. physical line -- existed to serve paper-output teletypes.  BDOS
  185. patches and replacements such as ZSDOS have eliminated them.)
  186.  
  187. Both the console single-character output function (#2) and the
  188. string output function (#9) provide:
  189.  
  190.     . flow control
  191.  
  192. .h2 Flow Control and Lookahead
  193.  
  194. Flow control is the process of starting and stopping the flow of
  195. bytes over an input/output channel.  Our concern here is the
  196. control of bytes to the console device.  
  197.  
  198. The BDOS is designed so that the user can "freeze" a screen of
  199. messages by typing a Control-S -- the standard XOFF character. 
  200. Output will resume by typing Control-Q -- the standard XON
  201. character.  Actually, output resumes when any other character
  202. (except Control-C -- the abort character) is typed, but it's a
  203. good habit to use Control-Q to keep your fingers conditioned for
  204. systems, such as unix, that use the standard control characters.
  205.  
  206. In order for flow control to work, the application must print its
  207. messages using BDOS functions #2 and #9.
  208.  
  209. Flow control requires something that many -- including compiler
  210. authors and BDOS hackers -- have found astonishing:  the BDOS
  211. console-output functions must call the BIOS console _input_
  212. functions in order to perform a _lookahead_ function.  After all,èhow else could the BDOS know that the user had typed a Control-S
  213. to suspend output?
  214.  
  215. It works like this.  Before the BDOS sends a character to the
  216. console, it checks the console input status.  If no key has been
  217. pressed, the character is sent.
  218.  
  219. But suppose a key has been typed.  In this case the BDOS calls
  220. the BIOS console input function to get the character.  From this
  221. moment on, the character is no longer in the BIOS.  The BDOS then tests
  222. whether the character is a Control-S.  If it is, the BDOS waits
  223. for the _next_ keypress and only then sends the output character. 
  224. If it is _not_ Control-S (or Control-C, discussed below) the BDOS
  225. saves the character (say 'A') in a one-character buffer and sends the
  226. output character.
  227.  
  228. If the next operation is to print another character on the console,
  229. the BDOS test for flow control will become ineffective.  The BDOS has
  230. only the one-character buffer, which is now full (it's holding the
  231. 'A'), so it cannot check the next keypress for Control-S; if it did,
  232. and the character were anything else, it would have to throw away one
  233. of the input characters.
  234.  
  235. The lookahead function might perhaps have been better implemented by
  236. providing a "peek" subfunction to the BIOS CONIN -- return but retain
  237. the pending next character.
  238.  
  239. The key result is that the next console input character is moved from
  240. the BIOS into the BDOS one-character buffer as a result of any BDOS
  241. function #2 or #9 output.  As a consequence, any application that uses
  242. the _BIOS_ to obtain console input will sometimes "lose" a typed
  243. character, only to have it emerge when the BDOS is next used for input
  244. (function #1 or #10)!
  245.  
  246.  
  247. .h2 Coping with missing characters
  248.  
  249. The simplest rule I can give you for coping with missing
  250. characters is to  keep all console input/output at _one_ level of
  251. the operating system -- all BDOS or all BIOS -- within a single
  252. application.  For example, don't mix BDOS line input (function
  253. #10) and BIOS CONIN.
  254.  
  255. It's fairly common for applications to use the BIOS functions for
  256. console i/o, in order to speed up output and to get every possible
  257. keyboard character.  The Z3LIB and VLIB routines used in many Z-System
  258. utilities do so.  At the start of such an application you may need to
  259. check the BDOS, using function #11, to see if a fast keypress has
  260. already been sucked into the BDOS one-character buffer.  If it returns
  261. non-zero, you can get the character with function #1 (but that will
  262. echo).  In order to use function #6 successfully to get the character
  263. without echo, you need to have installed the Plu*Perfect Systems patch
  264. (described later).è
  265. Jay Sage has used the following method of obtaining input (a
  266. named-directory password) from BDOS function #10 with echoing shut
  267. off.  First, save the first byte of the BIOS CONOUT jump vector (it
  268. should be the JP opcode) and replace it with a RET opcode.  Next, call
  269. BDOS function #10.  When the BDOS calls the BIOS CONOUT to echo the
  270. character, the BIOS will return at once.  Then, immediately following
  271. the BDOS call, restore the first byte of the BIOS CONOUT jump.  (Note
  272. that he follows the sound principle of saving and restoring the
  273. environment, by saving and restoring the byte in the BIOS "jump
  274. vector".  he doesn't simply assume it is a JP.  It's possible that
  275. other code -- perhaps in an RSX -- has already patched this location.)
  276.  
  277. This trick is handy, but should be used only where no other solution
  278. is available.  In Jay's case, there was insufficient room in the Z34
  279. command processor to collect a password with function #6.  The
  280. difficulty with this approach is that during the time that the BIOS
  281. CONOUT is patched out it is possible that other processes would be
  282. generating console output.  What other processes could there be in
  283. CP/M?  If BackGrounder ii is loaded, a press of the <SUSPEND> key
  284. would temporarily suspend the current task and prompt for user input,
  285. but the prompt would be invisible!  Or an interrupt-driven task could
  286. generate a screen message that would be lost.
  287.  
  288.  
  289.  
  290. .h2 Abort Control
  291.  
  292. A Control-C will cause the BDOS to abort the current application,
  293. jumping directly to 0000, when it is:
  294.  
  295.     . the _first_ character typed after a Control-S
  296.       has halted output from function #2 or #9.    
  297.  
  298.     . the _first_ character typed to line-input
  299.       (function #10)
  300.  
  301. The abort control feature of the CP/M 2.2 BDOS is a mixed
  302. blessing at best.  It gives the user a handy way to kill a job
  303. that is scrolling unwanted output to the screen.  But it limits
  304. the use of edited BDOS line input to applications that can
  305. tolerate abrupt termination if the user happens to hit Control-C.
  306. As a result, most well-written applications must incorporate
  307. their own line editor in order to retain control to avoid being
  308. cancelled with unclosed files, open modem connections, or whatever.
  309.  
  310.  
  311. .h1 Cooked Output
  312.  
  313. In addition to flow control, which is a feature of cooked console
  314. input that controls the flow of output, the BDOS alters the raw
  315. output to the console by special processing of tabs and by
  316. creating a parallel stream of output for the printer.
  317. è.h2 Tab expansion
  318.  
  319. The BDOS expands the horizontal tab character (09h) to the number
  320. of spaces required to reach the next logical tab stop (every
  321. eight characters).  To do this it keeps a current-column count
  322. for all output to functions #2 and #10, resetting it to 0 on each
  323. carriage return.
  324.  
  325. This is a handy cooked-output service.  But to work successfully,
  326. all output on the line must go through these BDOS functions. 
  327. Avoid mixing BDOS and BIOS console output on the same line.
  328.  
  329. .h2  Echoing to the Printer
  330.  
  331. The BDOS maintains a flag that, when set, causes function #2 and
  332. #9 output to be echoed to the BIOS list device as well as the
  333. console output.  The flag is toggled when a Control-P is typed
  334. to function #10 -- the line-input function.
  335.  
  336. Control-P is very handy for getting a quick, selective printed
  337. record of some console output.  It can also mysteriously freeze
  338. your system when the printer is not ready.  When your computer locks
  339. up, make a habit of checking the attached external devices (printer,
  340. modem) before you resign yourself to pressing the reset button!
  341.  
  342.  
  343.  
  344. .h1 The Case of the Missing Character
  345.  
  346. If you've used a number of CP/M systems, you've probably had the
  347. puzzling and quite annoying experience of occasionally "losing"
  348. one character you have typed when running a program, only to have
  349. it pop up unexpectedly much later, perhaps at the next command
  350. prompt.  It's a difficult bug to reproduce, and occurs only on
  351. some systems.  This spooky gremlin is so perplexing that a user
  352. can begin to believe his computer is truly haunted!
  353.  
  354. Has CP/M been visited by the supernatural?  Probably not.  We've
  355. already seen how mixing BDOS and BIOS console functions can cause
  356. an input character to become stuck in the BDOS one-character
  357. buffer when subsequent input is obtained by BIOS calls.
  358.  
  359. Several years ago, Derek McKay, my partner at Plu*Perfect
  360. Systems, spotted another cause of missing characters -- a bug in
  361. Digital Research's original design of the CP/M 2.2 BDOS that used
  362. faulty logic in the handling of "raw" console input with BDOS
  363. function #6.  Moreover, Derek developed a Z80 patch that corrects
  364. the problem and fits in the original BDOS space.  This is an important
  365. improvement, because without it there is no totally reliable way
  366. to mix cooked BDOS console i/o with any type of raw i/o, either
  367. BIOS or BDOS.
  368.  
  369. We included the patch in the CP/M Enhancements that Plu*Perfect
  370. originally published for Kaypro systems.  More recently, the
  371. authors of ZSDOS have incorporated the same logic into theirèexcellent new DOS.  So, on these systems, the missing character
  372. doesn't manifest itself.
  373.  
  374. .h2 Raw Console Input
  375.  
  376. To understand how a character can disappear, and then reappear,
  377. we first need to examine the BDOS's raw console input function.
  378.  
  379. BDOS function #6 was intended to provide absolutely raw console
  380. input and output functions accessible by a BDOS call, with no
  381. input flow control and no output processing.  An application would
  382. use this function, for example, when it wanted to get a character
  383. without necessarily echoing it to the terminal. 
  384.  
  385. DRI attempted to squeeze input, input status, and output into a
  386. single BDOS function (probably to save 8080 code space) and in
  387. doing so somewhat limited the usefulness of this service.  To use
  388. function #6, set C=6 and
  389.  
  390.     E= 0FFh        to get a character, if ready
  391.     E= 0FEh        to get console input status
  392.     (E=0FDh        to wait for a character)
  393.     E= 0...0FCh    to output the value in E to the console
  394.  
  395. When used for input, function #6 returns a 1-byte value in A.  If
  396. A is 0, no character is waiting; a non-zero value is the input
  397. character.  Thus it is impossible to enter a nul character
  398. (Control-@ on most keyboards) when function #6 is used.  (This
  399. defect is significant for editors, which must therefore use
  400. BIOS functions for console i/o.)
  401.  
  402. When used for output, function #6 is limited to values 0h to 0FCh.
  403. Usually ok, this restriction makes some 8-bit coded graphics
  404. characters unprintable on a few terminals.  (The subfunction code 0FDh
  405. is used by CP/M Plus and ZSDOS to wait for the next character and
  406. return it.)
  407.  
  408. But the real bug in function #6 is its internal check for input
  409. status.  The original BDOS code (figure 1) calls the BIOS CONSTAT
  410. routine to determine if a character is waiting.  This is fine,
  411. except that another BDOS function may have called the lookahead
  412. routine to test for flow control and left the tested character in
  413. the lookahead buffer.  When that situation exists, function #6
  414. will return A=0 (no character waiting) until a key is typed, and
  415. then return the next typed character, not the one last typed and
  416. still in the buffer!
  417.  
  418. Meanwhile, the tested character continues to sit in the buffer. 
  419. Eventually, someone -- either the application program or the
  420. command processor -- will call a BDOS function that does check
  421. the lookahead buffer before returning a character.  It will find
  422. the character still there, and return the missing character!
  423. è.h2 Code
  424.  
  425. Figure 2 contains the replacement routine.  It calls a new
  426. "ckstat" routine to determine input status.  The new routine just
  427. fits into the space made available by rewriting the "lkahead"
  428. routine just above it in z80 code.
  429.  
  430. Note the exact logic of the ckstat routine.  By clever coding it
  431. returns two flag values -- nonzero and carry not set when the next
  432. character should be obtained from the BDOS and nonzero and carry
  433. set when the next character should be obtained from the BIOS.
  434.  
  435. With this new routine, the lkahead routine can determine from
  436. calling ckstat whether to call the BIOS CONIN.
  437.  
  438. .h2 Patching your BDOS
  439.  
  440. If you are running the original CP/M 2.2 BDOS you can upgrade it
  441. with the function #6 patch.  Using a debugger, first check that
  442. the original 8080 code is exactly as shown in the figures.  Then
  443. assemble just the patch code with the BDOS equate set to the base
  444. value for your system, and output a hex file.
  445.  
  446. The hardest part is getting the patch installed in your system.
  447. You can load it with a debugger, and then check memory to see that
  448. it is installed.  But if your system reloads the BDOS on a warm
  449. boot, the patch will be gone when the next program runs.  If
  450. that's the case, you will need get the patch into the SYSGEN.COM
  451. image of the BDOS.
  452.  
  453. Load SYSGEN.COM with a debugger.  On most systems, the BDOS image
  454. begins at 1200h.  Compare the bytes there and in the running BDOS
  455. in high memory and then compare the bytes at the patch locations
  456. in the image (by adding 1200h to the addresses in the figures
  457. here) and in high memory.  If all matches up, load the hex patch
  458. into the high BDOS, compare again, and then move just the patched
  459. bytes of the two upgraded routines to their corresponding
  460. location in the overlay:
  461.     
  462.     MBDOS+0123,BDOS+0141,1200+0123
  463.     MBDOS+02D4,BDOS+02EC,1200+02D4
  464.  
  465. Then save the appropriage number of pages of the modified XSYSGEN.COM.
  466. Run XSYSGEN and place the system on the boot tracks of a scratch
  467. disk.  Boot the disk, test the system for normal operation, and
  468. then with a debugger check the high BDOS to see that the patches
  469. are indeed in place.
  470.  
  471. Note that this patch will not work with ZRDOS or other replacement
  472. BDOSes.  It may be possible to write a functionally equivalent
  473. ZRDOS patch, if you can find enough free space in a BDOS that is
  474. already in Z80 code.
  475.  
  476. è
  477.      Figure 1.  Corrected CP/M 2.2 BDOS Function #6 Routine
  478.      ------------------------------------------------------
  479.  
  480. Authors: Derek McKay, Bridger Mitchell (Plu*Perfect Systems)
  481.  
  482.   0000    bdos       equ    0000h        ; base of CP/M 2.2 BDOS
  483.   00B7      abort       equ    bdos+00B7h    ; "jp 0000"
  484.   00FB      getchar  equ    bdos+00FBh    ; get next console input char.
  485.   0301      setretval equ    bdos+0301h    ; set return value in A
  486.   030A      charbuf  equ    bdos+030Ah    ; 1-character input buffer
  487.   0D91      exit       equ    bdos+0D91h    ; BDOS exit routine
  488.  
  489.   0E00    bios       equ    bdos+0e00h    ; base of BIOS
  490.   0E06      constat  equ    bios+6        ; console status
  491.   0E09      conin       equ    bios+9        ; console input
  492.   0E0C      conout   equ    bios+0Ch    ; console output    
  493.  
  494. ; -- original (8080) Direct Console I/O Routine --
  495. ;    malfuncting code marked with "***"
  496.  
  497.   02D4        org    bdos  + 2D4h    
  498.  
  499.   02D4    79    fn6:    ld    a,c
  500.   02D5    3C        inc    a
  501.   02D6    CA 02E0        jp    z,fn6in
  502.   02D9    3C        inc    a
  503.   02DA    CA 0E06    fn6s:    jp    z,constat    ; ***
  504.   02DD    C3 0E0C        jp    conout
  505.   02E0    CD 0E06    fn6in:    call    constat        ; ***
  506.   02E3    B7        or    a,a
  507.   02E4    CA 0D91        jp    z,exit
  508.   02E7    CD 0E09        call    conin        ; ***
  509.   02EA    C3 0301        jp    setretval
  510.  
  511. ; -- corrected (z80) routine --
  512.  
  513.   02D4        org    bdos  + 2D4h    
  514.         ;
  515.   02D4    79    fn6:    ld    a,c        ; if c == FF
  516.   02D5    3C        inc    a
  517.   02D6    28 08        jr    z,fn6in        ; ..get character
  518.   02D8    3C        inc    a        ; if c == FE
  519.   02D9    CA 0137        jp    z,ckstat    ; ..get input status
  520.                         ;   of buffer & bios
  521.   02DC    C3 0E0C        jp    conout        ; ..else output char
  522.         fn6in:    call    ckstat        ; check both buffer
  523.                         ;   and bios
  524.   02DF    CA 0D91        jp    z,exit        ; ..no char waiting,
  525.                         ;   return 0 status
  526.   02E2    CD 00FB        call    getchar        ; get char from buffer
  527.                         ;   or biosè  02E5    18 1A        jr    setretval    ; and return it
  528.         ;
  529.  
  530.  
  531.          Figure 2.  Console Look-Ahead Routines
  532.          --------------------------------------
  533.  
  534.  
  535. ; -- original (8080) console input look-ahead routine --
  536.  
  537.   0123        org    bdos + 0123h
  538.  
  539.   0123    3A 030A    lkahead:ld    a,(charbuf)
  540.   0126    B7        or    a,a
  541.   0127    C2 0145        jp    nz,return1
  542.   012A    CD 0E06        call    constat
  543.   012D    E6 01        and    1b
  544.   012F    C8        ret    z
  545.   0130    CD 0E09        call    conin
  546.   0133    FE 13        cp    'S'-'@'
  547.   0135    C2 0142        jp    nz,savechar
  548.   0138    CD 0E09        call    conin
  549.   013B    FE 03        cp    'C'-'@'
  550.   013D    CA 0000        jp    z,0000
  551.   0140    AF        xor    a,a
  552.   0141    C9        ret
  553.  
  554.   0142    32 030A    savechar:ld    (charbuf),a    ; save input char
  555.                         ; in buffer
  556.   0145    3E 01    return1:ld    a,1        ; return a non-zero
  557.   0147    C9        ret            ; character
  558.  
  559. ; -- shorter replacement (z80) routine --
  560.  
  561.   0123        org    bdos + 0123h
  562.  
  563.   0123    CD 0137    lkahead:call    ckstat        ; if no char waiting
  564.   0126    C8        ret    z        ; ..return
  565.   0127    DC 0E09        call    c,conin        ; if no char in buffer,
  566.                         ;   call bios
  567.   012A    FE 13        cp    'S'-'@'        ; if not ^S
  568.   012C    20 14        jr    nz,savechar    ; ..return the char
  569.   012E    CD 0E09        call    conin        ; ^S, so get next char
  570.   0131    FE 03        cp    'C'-'@'        ; if ^C
  571.   0133    28 82        jr    z,abort        ; ..abort
  572.   0135    AF        xor    a,a        ; else return false
  573.   0136    C9        ret            ;    status    
  574.  
  575. ; new check-console-status (z80) routine
  576.  
  577.   0137    3A 030A    ckstat:    ld    a,(charbuf)    ; if buffered char waiting
  578.   013A    B7        or    a,a        ; ..clear CY and return NZè  013B    C0        ret    nz
  579.   013C    CD 0E06        call    constat        ; else check bios for a char
  580.   013F    B7        or    a,a        ; if char waiting there
  581.   0140    0F        rrca            ; ..set CY and set NZ
  582.   0141    C9        ret
  583.  
  584. ; resume original (8080) code at 0142h
  585.  
  586. [This article was originally published in issue 37 of The Computer Journal,
  587. P.O. Box 12, South Plainfield, NJ 07080-0012 and is reproduced with the
  588. permission of the author and the publisher. Further reproduction for non-
  589. commercial purposes is authorized. This copyright notice must be retained.
  590. (c) Copyright 1989, 1991 Socrates Press and respective authors]
  591.