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 / KAYPRO / KP-HOST.LBR / KPBYE.AZM / KPBYE.ASM
Assembly Source File  |  2000-06-30  |  152KB  |  6,182 lines

  1.  
  2. ; BYE510H - REMOTE CONSOLE PROGRAM FOR CP/M AND MODEM - 03/17/87
  3. ;
  4. ;
  5. ;    *** SPECIAL HBBS VERSION FOR MIDNIGHT MAINTENANCE - 03/15/87 ****
  6. ;     (Set EXFIL1 to YES if using HSAVE.COM to backup files
  7. ;     (Set EXFIL2 to YES if using HMNT.COM to rehash and re-
  8. ;     number messages.)
  9. ;
  10. ;     (Put your I/O and clock inserts at ++++)
  11. ;
  12. ;        For use with CP/M 2 or CP/M 3
  13. ;
  14. ;    NOTE:    Read the BYE5.HIS in this .LBR to review
  15. ;        update history and to see changes imple-
  16. ;        mented by this version.
  17. ;
  18. ;
  19. ; BYE5 replaces all previous BYE2, BYE3, BYE4, BYE+, and MBYE series and
  20. ; also supports the latest available technology for RCP/M systems.  BYE5
  21. ; will work with KMD04 and XMODEM-116 or later revisions.
  22. ;
  23. ;=======================================================================
  24. ;
  25. ; NOTE: This program is copyrighted (c) 1986 by Irv Hoff, Wayne Masters
  26. ;    and George Peace.  All rights reserved.  Users are hereby
  27. ;    granted a limited license to copy this program for personal use
  28. ;    only.  The program may be distributed unmodified to all inter-
  29. ;    ested parties.    No fee or other consideration shall be accepted
  30. ;    by any party or parties.  In accordance with the copyright law
  31. ;    of 1978, form TX has been sent to the U.S. Government Copyright
  32. ;    Office.
  33. ;
  34. ;     =     =     =     =     =     =     =     =
  35. ;
  36. ;    If you have changes that you would like to see in a forthcoming
  37. ;    general release, please forward them for consideration.  This
  38. ;    seems to be the only way to control the modifications that have
  39. ;    run rampant in previous versions of public domain programs.  It
  40. ;    has taken many hours to correct problems some of these changes
  41. ;    have caused, particularly when used with assemblers that have
  42. ;    characteristics different from the one being currently used or
  43. ;    if other equates are selected.
  44. ;
  45. ;    Send/call any suggestions or requests for help to:
  46. ;
  47. ;    Wayne Masters        Irv Hoff, W6FFC     George Peace
  48. ;   (408) 378-3798 voice     (415) 948-2166 voice    (717) 657-0285 voice
  49. ;
  50. ;            Potpourri RCPM             CP/M-3 George Peace
  51. ;            (408) 378-7474             (717) 657-8699
  52. ;
  53. ;     =     =     =     =     =     =     =     =
  54. ;
  55. ;    If using M80, remove the ";" at the beginning of the ASEG line.
  56. ;
  57.     ASEG        ; Needed for M80, but RMAC can't handle it
  58. ;
  59. ; This program allows modem callers to use a CP/M system just as if they
  60. ; were seated at the system console.  Special assembly-time options al-
  61. ; low limiting the caller's access by password and/or access to only a
  62. ; message-service program.  A number of external inserts are available
  63. ; to adapt this program to various computers, clocks and  modems.  It
  64. ; may be assembled with ASM, LASM, MAC, RMAC, SLRMAC or M80.  If the
  65. ; ZCPR3 equate is YES, a  macro assembler such as MAC, M80 or SLRMAC
  66. ; will be required.  If the program will not assemble correctly with
  67. ; M80, check the insert that was added, it likely is not configured
  68. ; properly.
  69. ;
  70. ; BYE5 will continue supporting what the Sysop's organizations have re-
  71. ; quested, not personal preferences.
  72. ;                    -  Wayne Masters
  73. ;
  74. ;=======================================================================
  75. ;
  76. ; The following files are inside this library to assist you in installa-
  77. ; tion:
  78. ;
  79. ; BYE5.DOC    For general installation and extended BDOS functions
  80. ; B5-CPM3.DOC    Specific instructions for CP/M 3 installation
  81. ; BYE5.HIS    BYE5 update history (read this to see latest features)
  82. ; BYE5-INS.INF    Computer-specific inserts currently available (CP/M 2 & 3)
  83. ; B5-TIME.INF    Clock inserts currently available (CP/M 2 & 3)
  84. ; B5IM-1.DOC    Intelligent (smart) modem configuration information
  85. ; BYE5nnC.AQM    Condensed version of BYE5 for small floppy based systems
  86. ;
  87. ;=======================================================================
  88. ;
  89. ; If the CPM3 equate is YES, BYE5 uses an RSX loader to attach itself to
  90. ; your operating system (see B5-CPM3.DOC).  For CP/M-2 users, (CPM3 NO),
  91. ; BYE5 uses a special loader that is built into the program to automati-
  92. ; cally move itself below CCP. This does not require any alteration in
  93. ; the location of CP/M by using MOVECPM.  All you need to do is: (1)
  94. ; choose the desired options, (2) patch in the insert for your computer
  95. ; in the special area near the start marked "+++ Install your I/O port
  96. ; insert here +++", (3) patch in the insert for your clock at label TIME
  97. ; (if CLOCK is YES), (4) then finish editing, assemble, load and use.
  98. ;
  99. ; Most users of this program will have a modem such as an Anchor, Hayes,
  100. ; ProModem, U.S.Robotics, or Racal Vadic Maxwell.   All these types are
  101. ; "intelligent" modems.  If using this type of modem, set the IMODEM
  102. ; and B5IM equates to 'YES'.  Otherwise leave them set to 'NO' and BYE
  103. ; assumes you have a "dumb" auto-answer modem,    (such as a Bell 212A).
  104. ; This readily adapts the program to a wide variety of modems and I/O
  105. ; serial types.
  106. ;
  107. ; NOTE:  Two support libraries exist for BYE5...
  108. ;     BYE5-INS.LBR contains all available computer-specific inserts
  109. ;     B5-CLOCK.LBR contains all available clock inserts.
  110. ;
  111. ; Be sure to check Potpourri for the latest version of these inserts.
  112. ; Many have been corrected and/or updated by users of BYE5 and the one(s)
  113. ; you have may not be the latest version.
  114. ;
  115. ; The program does the following:
  116. ;
  117. ;    If you type BYE E, BYE will load and execute as though it has
  118. ;    a valid carrier or caller.  Handy for debug, else it:
  119. ;
  120. ;    1) Hangs up the phone
  121. ;    2) Awaits ring if B5IM is YES, (or carrier detect if B5IM is NO)
  122. ;       allows exit to CP/M if local KEYB types CTL-C
  123. ;    3) Answers the phone and outputs carrier
  124. ;    4) Awaits incoming carrier.  If none found in 30 seconds goes
  125. ;       back to step 1
  126. ;    5) Detects the speed of caller and sets local cpu to that speed
  127. ;    6) Asks number of nulls (0-9) (optional)
  128. ;    7) Sets the log-in time (if TIMEON is YES)
  129. ;    8) Types the "WELCOME" file from disk, (optional) allowing
  130. ;        CTL-C to skip it
  131. ;    9) Asks for a password (optional), allowing 3 tries to get
  132. ;        it right.  When entered drops into CP/M
  133. ;      10) Caller can leave by hanging up, (any time carrier is
  134. ;        lost, it waits then goes back to step 1) or the caller
  135. ;        may type the program name (BYE).
  136. ;                    - Notes by Wayne Masters
  137. ;
  138. ;=======================================================================
  139. ;
  140. MAIN    EQU    5
  141. VERS    EQU    10
  142. MONTH    EQU    08
  143. DAY    EQU    01
  144. YEAR    EQU    86
  145. ;
  146. ;
  147. ; System equates
  148. ;
  149. YES    EQU    0FFH
  150. NO    EQU    0
  151. ;
  152. ;
  153. ; You will likely also want to change the password, located below at
  154. ; label 'PASSWD' (if you set PWRQD YES).  If you are using a BBS.COM
  155. ; file then PWRQD is normally left NO.
  156. ;
  157. ;***********************************************************************
  158. ;
  159. ;          OPTION CONFIGURATION SECTION
  160. ;
  161. ;***********************************************************************
  162. ;
  163. ;-----------------------------------------------------------------------
  164. ;               BYE5 configuration
  165. ;
  166. ;
  167. LOCMD    EQU    61        ; BYE's  lowest extended BDOS call
  168. HICMD    EQU    LOCMD+27    ; BYE's highest extended BDOS call
  169. CCPL    EQU    8        ; Number of sectors for CCP size (8 is
  170.                 ;   normal for 2k.  Apples with Micro-
  171.                 ;   soft CP/M v2.23 use 9.  Systems with
  172.                 ;   Trantor WL BIOS, set to 0 and set
  173.                 ;   TRANWL YES.  For older versions of
  174.                 ;   Trantor BIOS start with 24 and work
  175.                 ;   down until it stops working (typi-
  176.                 ;   cally 24 or 16).  An updated Trantor
  177.                 ;   (WL) BIOS is advised for RCP/M use
  178.                 ;   if running a large BBS program.
  179.                 ;   CP/M-3 does not use this or TRANWL
  180.                 ;   equates.
  181. ;
  182. ;-----------------------------------------------------------------------
  183. ;           Modem Type
  184. ;
  185. IMODEM    EQU    YES        ; Yes, for intelligent modem, including
  186.                 ;   Hayes
  187. B5IM    EQU    YES        ; Yes, your modem uses AT protocol, like
  188.                 ;   Hayes
  189. ;
  190. ;
  191. ; Set one (and only one) of the following HS equates to YES
  192. ;
  193. HS9600    EQU    NO        ; Yes, if modem's high speed is 9600 bps
  194. HS4800    EQU    NO        ; Yes, if modem's high speed is 4800 bps
  195. HS2400    EQU    NO        ; Yes, if modem's high speed is 2400 bps
  196. HS1200    EQU    YES        ; Yes, if modem's high speed is 1200 bps
  197. HS300    EQU    NO        ; Yes, if modem's high speed is  300 bps
  198. ;
  199. ;
  200. ; The next 7 equates are only used if B5IM is YES
  201. ;
  202. DOATZ    EQU    NO        ; Yes to do ATZ between calls.    If your
  203.                 ;   modem reverts to auto-answer after
  204.                 ;   ATZ, set this NO.  It speeds up the
  205.                 ;   turnaround between calls AND pre-
  206.                 ;   vents modem from answering while
  207.                 ;   BYE5 is trying to reinitialize for
  208.                 ;   the next call.  Most modems (Hayes
  209.                 ;   and clones) don't need it.
  210. ECHO    EQU    YES        ; Yes for Hayes, ProModem, Courier, R-V
  211.                 ;   Maxwell, NO for all others (USR,
  212.                 ;   Anchor, etc.)
  213. ANCHOR    EQU    NO        ; Yes, if you have a Mark XII
  214. NODTR    EQU    NO        ; Yes, modem or computer does not sup-
  215.                 ;   port DTR such as Anchor Mark XII or
  216.                 ;   some Osborne-1's.  NOTE OS-1 users..
  217.                 ;   BYE5 can handle your NODTR problem,
  218.                 ;   but will NOT work unless you install
  219.                 ;   the hardware mod to fix the carrier
  220.                 ;   detect logic.  The same mod also
  221.                 ;   fixes the DTR problem, so you should
  222.                 ;   install the whole mother board modi-
  223.                 ;   fication kit and set this NO
  224. NOATA    EQU    NO        ; Yes, if you have an older Password,
  225.                 ;   212A or S-100 that will not execute
  226.                 ;   the ATA command after ring is de-
  227.                 ;   tected. Newer firmware works.
  228. OFFHK    EQU    NO        ; Yes, if you want BYE to put your phone
  229.                 ;   off-hook (ATH1) when running locally
  230.                 ;   (E) or exiting to CP/M (instead of
  231.                 ;   Using ATS0=0)
  232. SHORTB    EQU    NO        ; Yes, for modems that that can't accept
  233.                 ;   a 30 character CMD string, like the
  234.                 ;   MultiModem.
  235. ;
  236. ;-----------------------------------------------------------------------
  237. ;             General Equates
  238. ;
  239. HARDLOG    EQU    NO        ; Yes, echo remote input to printer
  240. PRINTER    EQU    NO        ; Yes, if your bbs uses printer for er-
  241.                 ;   ror msgs. or if you use ^P remotely.
  242.                 ;   QBBS users say YES if QENTER is set
  243.                 ;   to print callers data.  NOTE, if you
  244.                 ;   use your printer I/O drivers for
  245.                 ;   for your modem, then say YES to this
  246. COMFILE    EQU    NO        ; Yes, chain to a .COM file on carrier
  247.                 ;   detect
  248. COMDRV    EQU    'A'        ; Drive to look for .COM file on
  249. COMUSR    EQU    0        ; User# of .COM file to be called after
  250.                 ;   answer
  251. DISKLOG    EQU    NO        ;*Yes, echo remote input to disk file
  252.                 ;   Warning..this code requires approxi-
  253.                 ;   mately 1200 bytes extra.  Large BBS
  254.                 ;   program may have enough room if this
  255.                 ;   feature is selected.
  256. LOGUSR    EQU    14        ; User number of SYS.LOG file
  257. LOGDRV    EQU    'A'        ; Drive for SYS.LOG file
  258. EXFILE    EQU    NO        ; Yes, chain to a .COM file when BYE
  259.                 ;   logs off a caller (even when he
  260.                 ;   types BYE).  Your EXIT.COM file must
  261.                 ;   preserve the stack and do a RETURN
  262.                 ;   (not warmboot) to reenter BYE cor-
  263.                 ;   rectly or use the EXRET method below
  264.                 ;   CPM3 or HBBS users must say YES to
  265.                 ;   this.  QBBS users must say NO, MBBS
  266.                 ;   NO if CP/M 2 or MBBS YES with CPM3.
  267.                 ;
  268. ; =  =    =  =  =  =  =  =  =  =    =  =  =  =  =  =  =  =    =  =  =  =  =  =
  269. ;        special HBBS maintenance options
  270. ;
  271. EXFIL1    EQU    NO        ;*Backs up HBBS message files with HSAVE
  272. EXFIL2    EQU    NO        ;*Packs and renumbers HBBS message files
  273.                 ;   with HMNT
  274. ANYLOS    EQU    NO        ; Want a backup after any carrier loss?
  275.                 ;   (preferred if using volataive RAMDISK)
  276. RAMDSK    EQU    NO        ; Yes if using RAMDISK and want message
  277.                 ;   rehash to be done on backup drive
  278. ;
  279. ;
  280. ; Following two only used if RAMDSK is set YES, so files may be copied
  281. ; back to original drive/user via auxiliary program called HSAVE.COM.
  282. ;
  283. BCKUPDR    EQU    'B'        ; Drive used for message backup
  284. BCKUPUS    EQU    14        ; User area for message backup
  285. ;
  286. ;        end of special HBBS maintenance options
  287. ; =  =    =  =  =  =  =  =  =  =    =  =  =  =  =  =  =  =    =  =  =  =  =  =
  288. ;
  289. EXRET    EQU    NO        ; YES, if your exit file can't preserve
  290.                 ;   the stack and do a normal RETURN.
  291.                 ;   MBASIC, "C", and some Pascal pro-
  292.                 ;   grams can't do the stack save-return
  293.                 ;   easily.  Simply POKE FCB+1 (5DH)
  294.                 ;   with 'r' (small r) and dDo a warm-
  295.                 ;   boot (SYSTEM) and BYE5 will handle
  296.                 ;   your exit file return correctly.
  297. BYHANG    EQU    NO        ;*Yes, for BYE5 to say goodbye and dis-
  298.                 ;   connect the phone BEFORE calling
  299.                 ;   your EXIT file.  METAL, & OxGate
  300.                 ;   users must say YES.  HBBS say NO.
  301. EXDRV    EQU    'A'        ; Drive to look for exit .COM file on
  302. EXUSR    EQU    14        ; User # of .COM file to be called upon
  303.                 ;   exit
  304. MSGFIL    EQU    NO        ; Yes, if your BBS system allows mes-
  305.                 ;   sages to be uploaded by KMD, NUKMD
  306.                 ;   or MBKMD.  These programs set a flag
  307.                 ;   that will cause your MSG.COM file to
  308.                 ;   be executed.  The .COM file must be
  309.                 ;   on the same D/U as COMFILE.  Your
  310.                 ;   MSG.COM file can append (then erase)
  311.                 ;   the uploaded message(s) to your mes-
  312.                 ;   sage file.    Your MSG.COM file must
  313.                 ;   preserve the stack and do a RETURN
  314.                 ;   (not warmboot) to renter BYE.  You
  315.                 ;   can select the name of MSG.COM at
  316.                 ;   label MSGFCB: (default name is
  317.                 ;   MFMSG.COM)
  318. NO25TH    EQU    NO        ; Yes, you wish to display LASTCALR data
  319.                 ;   (^W).  You may also print a header
  320.                 ;   above the LC data.    Put your custom-
  321.                 ;   ized header at label LCHEAD:  MBBS,
  322.                 ;   HBBS, QBBS users must say YES
  323. NO25BF    EQU    78        ; Size (bytes) of lc buffer needed by
  324.                 ;   your BBS. MBBS, QBBS = 65, METAL,
  325.                 ;   HBBS, OXGATE =78
  326. READLC    EQU    NO        ; Yes, to have BYE read your LASTCALR
  327.                 ;   file, No if your BBS pokes LASTCALR
  328.                 ;   into BYE.  MBBS, HBBS, QBBS, METAL,
  329.                 ;   and OxGate users say NO
  330. LCDRV    EQU    'A'        ; Drive to find LASTCALR or LASTCALR.DAT
  331. LCUSR    EQU    14        ; User # of LASTCALR or LASTCALR.DAT file
  332. ;
  333. SKTERM    EQU    NO        ;*Yes, to skip the code that waits for
  334.                 ;   the caller to get his modem program
  335.                 ;   into terminal mode.  Caution...The
  336.                 ;   caller may miss your opening welcome
  337.                 ;   text if you set this equate yes.  If
  338.                 ;   your BBS program has code built in
  339.                 ;   to make sure the caller is ready AND
  340.                 ;   in terminal mode, set to yes
  341. WBDRIV    EQU    'A'-41H        ; Drive to log to on first warmboot to cp/m
  342.                 ; Some add-on hard disk systems want C
  343. ;
  344. WELFILE    EQU    YES        ; Yes, to send a WELCOME file
  345. WELDRV    EQU    'A'        ; Drive to look for WELCOME??? file
  346. WELUSR    EQU    0        ; User number of WELCOME??? file
  347. ;
  348. CLRSCR    EQU    NO        ; Yes, to auto-clear local CRT screen
  349.                 ;   between calls.  No, will still allow
  350.                 ;   you to use ^Z to manually clear it.
  351.                 ;   you are allowed a 6 byte sequence
  352.                 ;   below.  The example is for an <ESC>:
  353.                 ;   if you use a ctrl-key (example, ^Z),
  354.                 ;   set CLRCH1 EQU 'Z'-40H.  Set all
  355.                 ;   unused bytes 0.  Leave this NO until
  356.                 ;   everything is working
  357. CLRCH1    EQU    1BH        ; Set these for your clear screen sequence
  358. CLRCH2    EQU    ':'        ; 1B is escape and ESC : clears my screen
  359. CLRCH3    EQU    0        ; (Byte 3 if you need it).
  360. CLRCH4    EQU    0        ; Six bytes allowed for clear screen
  361. CLRCH5    EQU    0        ; Sequence and you can also clear your
  362. CLRCH6    EQU    0        ; 25th line if desired.
  363. ;
  364. PRGRSS    EQU    YES        ; Yes, for helpful progress reports on
  365.                 ;   CRT.  Leave this YES until every-
  366.                 ;   thing is working
  367. PRNTGB    EQU    YES        ; Yes, print "Goodbye..." message
  368. PRNTWB    EQU    NO        ; Yes, print a string for each warm boot
  369. PWRQD    EQU    YES        ; Yes, password needed for CP/M access
  370. ;
  371. TOVALUE    EQU    5        ; Minutes of no-activity allowed.  255 max.
  372. ;-----------------------------------------------------------------------
  373. ;
  374. RVIDEO    EQU    NO        ; Yes, display local messages in reverse
  375.                 ; Video when caller is online.    (Set
  376.                 ;   your on/off sequence below).  This
  377.                 ;   also works with half intensity in-
  378.                 ;   stead of reverse video.
  379. RVON1    EQU    1BH        ; Set your reverse-on sequence in these 4
  380. RVON2    EQU    'G'        ; Bytes.  Set unused bytes to nulls (0).
  381. RVON3    EQU    '4'        ; 1BH is escape, ESC G4 is reverse video
  382. RVON4    EQU    0        ; ON for the Televideo 925 terminal
  383. ;
  384. RVOFF1    EQU    1BH        ; Now set the reverse-off sequence as above
  385. RVOFF2    EQU    'G'        ; ESC G0 is reverse video OFF for the 925
  386. RVOFF3    EQU    '0'
  387. RVOFF4    EQU    0        ; Set unused bytes to 0
  388. ;
  389. ;
  390. ;-----------------------------------------------------------------------
  391. ;          System and Hardware dependent options
  392. ;
  393. CPM3    EQU    NO        ; Yes, installing with CP/M 3.0, see
  394.                 ;   B5-CPM3.DOC
  395. ;
  396. ;
  397. ; The next six equates are only for CPM3 users
  398. ;
  399. CCPPLUS    EQU    NO        ; Yes, CCP+ installed.
  400. ;
  401. HISTRSX    EQU    NO        ; Yes, clear command line HISTory if
  402.                 ;   HIST+ RSX is installed
  403. SDRV1    EQU    1        ; Set these 4 equates to the default
  404. SDRV2    EQU    0FFH        ; Drive search chain.
  405. SDRV3    EQU    0FFH        ; 0 = current, 0FFH = end of chain.
  406. SDRV4    EQU    0FFH        ; 1 = A, 2 = B, etc.
  407. ;
  408. ; End of CPM3 only
  409. ;
  410. CLOSS    EQU    1        ; If carrier dies, wait 1 second, then
  411.                 ;   hang up
  412. CTRLC    EQU    'K'-'@'        ; Map ^C to this character
  413. DOWNMIN    EQU    2        ; Number of min after Sysop types ^O to
  414.                 ;   logout
  415. LOSER    EQU    NO        ; Yes, warm boot overwrites part of the
  416.                 ;   BIOS
  417. MHZ    EQU    4        ; Processor clock in MHz
  418. MOTOR    EQU    NO        ; Yes power up/down drives between calls
  419. TRANWL    EQU    NO        ; Yes if running Trantor WL BIOS system
  420. ;
  421. ;-----------------------------------------------------------------------
  422. ;             Filtered characters
  423. ; BYE5 filters incoming modem noise by ignoring those characters most
  424. ; frequently generated by noisy modems or marginal phone connections.
  425. ; Also, some incoming characters may cause your local terminal to do
  426. ; strange (and sometimes undocumented) things.    The most common char-
  427. ; acters generated by noisy modem connections are the left brace ({),
  428. ; the delete character (07F) and nulls (00H).  An example of problem
  429. ; characters for the TRS-80 is the backward slash (\).    You may select
  430. ; any 4 characters below for BYE5 to filter from the incoming modem.
  431. ; Set any, or all, to nulls (00H) if you choose not to use the modem
  432. ; filter code.
  433. ;
  434. FILT1    EQU    7BH        ; Left brace
  435. FILT2    EQU    7FH        ; Delete character
  436. FILT3    EQU    60H        ; Backward slash (TRS-80 problem)
  437. FILT4    EQU    00H        ; Null
  438. ;
  439. ;-----------------------------------------------------------------------
  440. ;             Function Keys
  441. ;
  442. LEADIN    EQU    YES        ;*Yes, to use lead-in character for
  443.                 ;   F-keys instead of single CTL chars.
  444. ;
  445.      IF    LEADIN
  446. LEADKY    EQU    '\'        ; Key to use for lead-in.  Choose a sel-
  447.                 ;   dom used key.
  448.      ENDIF            ; LEADIN
  449. ;
  450. ;
  451. ; If LEADIN is YES, you must type the LEADKY first, then the character
  452. ; inside the ' ' below.  If LEADIN is NO, the following characters are
  453. ; used as a single control key.  Select only your character preference
  454. ; inside the ' ', and leave the -40H alone.  Either option will accept
  455. ; upper and lower case.
  456. ;
  457. ANSKEY    EQU    'A'-40H        ; Key to force modem to answer the phone
  458. BLNKKEY    EQU    'B'-40H        ; Key to toggle remote terminal on/off
  459. LOGKEY    EQU    'D'-40H        ; Key to flip disk log file save.
  460. BELLKEY    EQU    'G'-40H        ; Key to toggle bells on console
  461. LCKEY    EQU    'L'-40H        ; Key to force return to local CP/M af-
  462.                 ;   ter current caller logs off (and
  463.                 ;   alert Sysop)
  464. TWITKEY    EQU    'N'-40H        ; Keycode to hangup modem manually
  465. SYSDKEY    EQU    'O'-40H        ; Key to print "System going down in
  466.                 ; N min.."
  467. MSGKEY    EQU    'Q'-40H        ; Keycode to print "Message from SYSOP:"
  468. TIMEKEY    EQU    'T'-40H        ; Key for Sysop to display time (if
  469.                 ;   TIMEON)
  470. ULTKEY    EQU    'U'-40H        ; Key to grant current caller unlimited
  471.                 ;   time.  Also enables all the flag
  472.                 ;   bits in LCPTR
  473. WHOKEY    EQU    'W'-40H        ; Key to display LASTCALR if NO25TH is
  474.                 ;   Yes
  475. XITKEY    EQU    'X'-40H        ; Key to exit from "Message from Sysop"
  476.                 ;   loop
  477. ZCREEN    EQU    'Z'-40H        ; Key to manually clear your screen
  478. ;
  479. ;-----------------------------------------------------------------------
  480. ;               RBBS Type
  481. ;
  482. ; Set only one, or none of the following BBS equates to YES.  If COMFILE
  483. ; YES and none of the below are selected you will have an undefined label
  484. ; COMFCB during assembly.
  485. ;
  486. METAL    EQU    NO        ; Yes, running METAL BBS system.
  487. ;
  488. MBBS    EQU    NO        ; Yes, running MBBS4n BBS system
  489. MBSDRV    EQU    'A'        ; Drive where you keep MBBS.COM
  490. MBSUSR    EQU    0        ; User area for MBBS.COM - LOGIN.COM and
  491.                 ;   MFGMSG.COM must both be on COMDRV
  492.                 ;   and COMUSR selected above
  493. ;
  494. MINICK    EQU    NO        ; Yes, running MINICBBS..you must also
  495.                 ;   create your COMFCB label
  496. ;
  497. OXGATE    EQU    NO        ; Yes, running OxGate BBS system
  498. HBBS    EQU    NO        ; Yes, running HBBS system
  499. QBBS    EQU    NO        ; Yes, running QBBS system
  500. RBBS    EQU    NO        ; Yes, running RBBS, sets/resets
  501.                 ;   'WRTLOC' flag
  502. IOVAL    EQU    0        ; Initial value for IOBYTE (if MINICK
  503.                 ;   is YES)
  504. LMBELL    EQU    NO        ; Yes, your bbs uses a low-memory bell
  505.                 ;   flag, Yes for MBBS and RBBS users.
  506. KILBEL    EQU    03BH        ; Byte for low memory bell toggle flag
  507. ;
  508. ;
  509. ; Some BBS systems require a flag to be reset to allow reentry to the
  510. ; BBS from CP/M (older versions of RBBS do).  If you run a BBS that uses
  511. ; this technique, then set RTOK to YES, and define the byte to reset at
  512. ; RTOKFG.  BYE5 will reset this byte to zero between calls.
  513. ;
  514. RTOK    EQU    NO        ; Yes, to reset the following byte be-
  515. RTOKFG    EQU    020H        ; Tween calls.    HBBS users should say
  516.                 ; Yes, and set RTOKFG EQU to your REENTR
  517.                 ; Byte, normally 20H.
  518. ;
  519. ;-----------------------------------------------------------------------
  520. ;               Clock/Time Equates
  521. ;
  522. ; NOTE... Be sure to set the CLOCK and TIMEON equates the same way in
  523. ; both BYE5 and KMD.
  524. ;
  525. CLOCK    EQU    NO        ; If YES, add your clock reader code at
  526.                 ;   the start of label TIME: and store
  527.                 ;   binary values in CCHOUR and CCMIN
  528.                 ;   HBBS and QBBS users must say YES
  529. BCD2BIN    EQU    NO        ; Yes, your clock routine calls BCDBIN
  530. BIN2BCD    EQU    NO        ; Yes, your clock routine calls BINBCD
  531. TIMEON    EQU    NO        ; Yes, if you want BYE5 to keep track of
  532.                 ;   time-on-system and log off user
  533.                 ;   after MAXMIN.  This works without a
  534.                 ;   clock if you use KMD
  535. MAXMIN    EQU    60        ; Minutes for maximum time allowed on
  536.                 ;   system.  Recommend 60 if CLOCK and
  537.                 ;   TIMEON are YES, and 45 if CLOCK is
  538.                 ;   NO and TIMEON YES.    (255 minutes
  539.                 ;   maximum).  0= No restrictions.
  540. ;
  541. ; NOTE, the previous callers timeon is preserved for your exit or login
  542. ; program to access in BYE's fixed lookup table at label LCPTR.  You may
  543. ; choose to store that data in low memory, or elsewhere by changing the
  544. ; LCTON equate to a new address.  LCTON is found just after BYE's fixed
  545. ; lookup table.
  546. ;
  547. PRNTOS    EQU    NO        ; Yes, print Time-left-on-system on
  548.                 ;   warmboots.    If WHEEL is on or if
  549.                 ;   MXTIME=0, this will print the time
  550.                 ;   on system rather than time left.
  551. RSPEED    EQU    NO        ; Yes, restricting prime time to a min-
  552.                 ;   imum speed (a clock read routine is
  553.                 ;   required if YES - see CLOCK).
  554. ;
  555.      IF    RSPEED        ; 24 hour clock, 00=midnight, 23=11PM
  556. HOUR1    EQU    19        ; Start of prime-time (19=7:00 PM)
  557. HOUR2    EQU    23        ; End of prime-time (23=11:00 PM)
  558. SPEED    EQU    5        ; Minimum speed accepted (5=1200 baud).
  559.                 ;   Change OFFMSG to match your times,
  560.                 ;   baud rate and time zone.  OFFMSG is
  561.                 ;   a message at end of the source code.
  562.      ENDIF            ; RSPEED
  563. ;
  564. ;-----------------------------------------------------------------------
  565. ;              CCP Options
  566. ;
  567. ZCPR2    EQU    NO        ; Yes, if running ZCPR2 or ZCMD29 or
  568.                 ;   if using CP/M 3 with wheel byte
  569. ZCPR3    EQU    NO        ; Yes, if running ZCPR3
  570. ;
  571. ;
  572. ; NOTE: requires MAC.COM to assemble if ZCPR3 set YES
  573. ;
  574.      IF    ZCPR3
  575.     MACLIB    Z3BASE        ; Requires MAC to assemble...otherwise
  576.                 ;   enter constants directly..see label
  577.                 ;   DOZ3 for required EQU's
  578.      ENDIF            ; ZCPR3
  579. ;
  580. ;
  581. ; NZCPR/ZCMD/ZCPR all use bytes (at 3DH/3EH/3FH) to store the maximum
  582. ; drive, wheel status, and maximum user area.  Some BBS systems poke
  583. ; these low memory bytes to reset these (for Sysop, etc.)  Other BBS
  584. ; systems (like OxGate) poke the bytes in BYE that do the same thing.
  585. ; The equate USEZCPR allows you to select where you want to poke things.
  586. ; For OxGate, set it to NO, for RBBS, you probably want it set to YES.
  587. ; If you are NOT using NZCPR/ZCMD/ZCPR then set USEZCPR to NO.
  588. ;
  589. USEZCPR    EQU    NO        ; Yes, if using ZCPR/NZCPR/ZCMD to set
  590.                 ;   bytes
  591. CHEKDU    EQU    NO        ; Yes, if you want BYE to police MAXDRIV
  592.                 ;   and MAXUSER.  No, if your CCP can do
  593.                 ;   that (saves a lot of code).  In
  594.                 ;   either case, BYE keeps correct
  595.                 ;   values in these low memory bytes
  596. MAXDRIV    EQU    003DH        ; ZCPR lolcation of MAXDRIV byte
  597. WHEEL    EQU    003EH        ; Location of ZCPR's wheel flag
  598. MAXUSER    EQU    003FH        ; ZCPR location of MAXUSR byte
  599. MAXDRV    EQU    'B'-'@'        ; Highest drive supported
  600. MAXUSR    EQU    15        ; Highest user area
  601. SYSDRV    EQU    'B'-'@'        ; Highest local drive supported
  602. SYSUSR    EQU    15        ; Highest local user area (0-15)
  603. ;
  604. ; If CHGPATH is YES, BYE automagically will change the .COM path to suit
  605. ; which mode it is in.    An example of this is: when remote, the path is
  606. ; $$:, A0: -- when local, MY path is $$:, A0:, A15: which allows keeping
  607. ; PIP and FORMAT and other nasties up in A15: -- See REMPATH and SYSPATH
  608. ; DB's at end of program for current paths.  If the Sysop uses the ^B to
  609. ; blank the remote console, the Wheel byte is set and SYSPATH is setup
  610. ; for the Sysop.  The wheel byte is reset and REMPATH setup when ^B is
  611. ; used the second time to turn the remote back on.
  612. ;
  613. CHGPATH    EQU    NO        ; Yes, if changing ZCPR's external path
  614. EXTPATH    EQU    0040H        ; ZCPR external path default location
  615. ;
  616. ;-----------------------------------------------------------------------
  617. ;             MSPEED values
  618. ;
  619. MSPEED    EQU    03CH        ; Baud rate pointer
  620. BP110    EQU    0        ; 110 baud - baud rate pntrs for MSPEED
  621. BP300    EQU    1        ; 300 baud
  622. BP450    EQU    2        ; 450 baud
  623. BP600    EQU    3        ; 600 baud
  624. BP710    EQU    4        ; 710 baud
  625. BP1200    EQU    5        ; 1200 baud
  626. BP2400    EQU    6        ; 2400 baud
  627. BP4800    EQU    7        ; 4800 baud
  628. BP9600    EQU    8        ; 9600 baud
  629. BP19200    EQU    9        ; 19200 baud
  630. ;
  631. ;-----------------------------------------------------------------------
  632. ;            Motor controlled drives
  633. ;
  634. ; These values suit a Compupro/Viasyn Disk1A with YE-DATA 180 20cm
  635. ; drives.  Alter to suit your needs if your disk controller supports
  636. ; motor control.
  637. ;
  638.      IF    MOTOR
  639. DISK    EQU    0C3H        ; Disk control port
  640. DISKON    EQU    080H        ; Motors on
  641. DISKOFF    EQU    000H        ; Motors off
  642.      ENDIF            ; MOTOR
  643. ;
  644. ;-----------------------------------------------------------------------
  645. ;             if using LOSER
  646. ;
  647. ; There are some cases where warm boot overwrites the initial BIOS jump
  648. ; table.  This problem was solved for the Superbrain 3.0 bios by find-
  649. ; ing a warmboot call to HIGH in the BIOS.  This call is then patched by
  650. ; BYE.    The form of the call is:     WBCALL   CALL  WMSTRT
  651. ;
  652.      IF    LOSER
  653. WBCALL    EQU    0E260H        ; Check this in your BIOS
  654. ;
  655. ;
  656. ; The following location is called
  657. ;
  658. WMSTRT    EQU    0E566H        ; Check this in your BIOS
  659.      ENDIF            ; LOSER
  660. ;
  661. ;-----------------------------------------------------------------------
  662. ;
  663. ;         END OF OPTION CONFIGURATION SECTION FOR BYE5
  664. ;
  665. ;-----------------------------------------------------------------------
  666. ;
  667.      IF    NOT CPM3
  668.     ORG    100H
  669. ;
  670. ;-------------------- Special Loader Routine ---------------------------
  671. ;
  672. START:    LXI    SP,ISTACK    ; Set stack for initialization routine
  673.     MVI    C,32
  674.     MVI    E,241
  675.     CALL    BDOS        ; See if BYE is running
  676.     CPI    77        ; Yes, if (A)=77
  677.     JNZ    STARTA        ; No, we must relocate code
  678. ;
  679. ;
  680. ; Ok, we're sure that BYE's already there
  681. ;
  682.     LHLD    BDOS+1        ; Load BDOS vector
  683.     INX    H        ; Compute start of BYE5
  684.     INX    H
  685.     INX    H
  686.     PCHL            ; Go execute already loaded code
  687.      ENDIF            ; NOT CPM3
  688. ;
  689. STARTA:     IF    COMFILE    AND (NOT CPM3)
  690.     LXI    H,COMFCB+1    ; BBS com filename
  691.     LXI    D,ENTMSG    ; Display buffer
  692.     MVI    B,8        ; Length of filename
  693. ;
  694. STAR1:    MOV    A,M        ; Move it to display buffer
  695.     CPI    ' '        ; Stop on first space
  696.     JZ    STAR2
  697.     STAX    D
  698.     INX    D
  699.     INX    H
  700.     DCR    B
  701.     JNZ    STAR1        ; Loop until space or 8 chars found
  702. ;
  703. STAR2:    XRA    A
  704.     STAX    D        ; Store 0 as print terminator
  705.      ENDIF            ; COMFILE AND NOT CPM3
  706. ;
  707.      IF    EXFILE AND (NOT    CPM3)
  708.     LXI    H,EXITFCB+1    ; Exit com filename
  709.     LXI    D,EXTMSG    ; Display buffer
  710.     MVI    B,8        ; Length of filename
  711. ;
  712. STAR3:    MOV    A,M        ; Move it to display buffer
  713.     CPI    ' '        ; Stop on first space
  714.     JZ    STAR4
  715.     STAX    D
  716.     INX    D
  717.     INX    H
  718.     DCR    B
  719.     JNZ    STAR3        ; Loop until space or 8 chars found
  720. ;
  721. STAR4:    XRA    A
  722.     STAX    D        ; Store 0 as print terminator
  723.      ENDIF            ; EXFILE AND NOT CPM3
  724. ;
  725.      IF    MSGFIL AND (NOT    CPM3)
  726.     LXI    H,MSGFCB+1    ; Message com filename
  727.     LXI    D,MSGMSG    ; Display buffer
  728.     MVI    B,8        ; Length of filename
  729. ;
  730. STAR5:    MOV    A,M        ; Move it to display buffer
  731.     CPI    ' '        ; Stop on first space
  732.     JZ    STAR6
  733.     STAX    D
  734.     INX    D
  735.     INX    H
  736.     DCR    B
  737.     JNZ    STAR5        ; Loop until space or 8 chars found
  738. ;
  739. STAR6:    XRA    A
  740.     STAX    D        ; Store 0 as print terminator
  741.      ENDIF            ; MSGFIL AND NOT CPM3
  742. ;
  743.      IF    LMBELL AND (NOT    CPM3)
  744.     LDA    BELLON
  745.     CMA
  746.     STA    KILBEL        ; Prep the low memory bell flag
  747.      ENDIF            ; LMBELL AND NOT CPM3
  748. ;
  749.      IF    NOT CPM3
  750.     LHLD    BDOS+1        ; Load BDOS vector
  751.     LXI    D,-(CCPL*256)-8    ; 2k btyes in CCP plus offset
  752.     DAD    D        ; Make room for the CCP
  753. ;
  754. ;
  755. ; HL now contains the destination address of BYE5
  756. ;
  757.     LXI    D,OBJEND-1    ; Set up the source pointer
  758.     LXI    B,OBJEND-BEGOBJ    ; Set up byte counter
  759. ;
  760. BLOCK:    LDAX    D        ; Get program byte
  761.     MOV    M,A        ; Move program byte
  762.     MOV    A,B        ; Get byte count
  763.     ORA    C        ; Finished block transfer?
  764.     JZ    UPDATE        ; Yes, check on the opcode values
  765.     DCX    D        ; No, set source pointer
  766.     DCX    H        ; Set destination pointer
  767.     DCX    B        ; Set byte counter
  768.     JMP    BLOCK        ; Continue block transfer until finished
  769. ;
  770. UPDATE:    XCHG            ; Move the source addrress into 'HL'
  771.     CALL    NEGHL        ; Prepare value for subtraction
  772.     DAD    D        ; Form the program offset
  773.     SHLD    OFFSET        ; Save the program offset
  774.     XCHG            ; Set up the offset register
  775.     LXI    H,ENDOBJ    ; Get  the ending addr of the prgm code
  776.     DAD    D        ; Form new ending addr (new location)
  777.     SHLD    ENDRNG        ; Save the ending addr of the prgm code
  778.     LXI    H,BEGOBJ    ; Get  the start address of program code
  779.     DAD    D        ; Form new beginning addr (new location)
  780. ;
  781. ;
  782. ; The following code determines whether or not an address is within the
  783. ; BYE prgm and sets it to the new address if it is - otherwise it will
  784. ; not disturb the code.
  785. ;
  786.     DCX    H        ; Set up the source pointer for the
  787.                 ; Modification routine entry
  788. MODIFY:    INX    H        ; Point to the next (hopefully) instr.
  789.     DB    LXID        ; Get the address of the end of BYE5
  790. ;
  791. ENDRNG:    DW    0
  792.     MOV    A,E
  793.     SUB    L
  794.     MOV    A,D
  795.     SBB    H        ; Have we finished moving this block?
  796.     JC    BEGIN        ; Yes, we can begin now.
  797. ;
  798. ;
  799. ; Here is where we test for the 3-byte opcodes
  800. ;
  801.     MVI    B,INST3E-INST3    ; Get number of elements in the table
  802.     LXI    D,INST3        ; Set up the 3-byte opcodes table ptr
  803. ;
  804. THRBYT:    LDAX    D        ; Get opcode byte from table
  805.     CMP    M        ; Is this byte a 3-byte opcode?
  806.     JZ    CHANGE        ; Change the 2nd and 3rd bytes if needed
  807.     INX    D        ; No, advance table pointer
  808.     DCR    B        ; End of 3-byte table?
  809.     JNZ    THRBYT        ; No, keep looking
  810. ;
  811. ;
  812. ; Skip all the 2-byte opcodes - this keeps the transfer program from
  813. ; trying to figure out what the second byte is.
  814. ;
  815.     MVI    B,INST2E-INST2    ; Get the number of table elements
  816.     LXI    D,INST2        ; Set up the 2-byte-opcodes-table ptr
  817. ;
  818. TWOBYT:    LDAX    D        ; Get opcode byte from table
  819.     CMP    M        ; Is this byte a 2-byte opcode?
  820.     JZ    SKIP        ; Yes, skip it and continue
  821.     DCR    B        ; No, end of 2-byte table?
  822.     INX    D        ; Advance table pointer
  823.     JNZ    TWOBYT        ; No, keep looking
  824.     JMP    MODIFY        ; Yes, a one-byte opcode, keep going
  825. ;
  826. SKIP:    INX    H        ; Advance object code pointera
  827.     JMP    MODIFY        ; Continue search
  828. ;
  829. CHANGE:    LXI    D,OBJEND    ; Set up end of range pointer
  830.     LXI    B,BEGOBJ    ; Set up beginning of range pointer
  831. ;
  832. ;
  833. ; See if the address is above the range
  834. ;
  835.     INX    H        ; Advance pointer to the LSB of the addr
  836.     MOV    A,E
  837.     SUB    M
  838.     INX    H        ; Advance pointer to the MSB of the addr
  839.     MOV    A,D
  840.     SBB    M
  841.     JC    MODIFY
  842. ;
  843. ;
  844. ; See if the address is below the range
  845. ;
  846.     DCX    H        ; Set ptr back to the LSB of the addr
  847.     MOV    A,M
  848.     SUB    C
  849.     INX    H        ; Advance pointer to the MSB of the addr
  850.     MOV    A,M
  851.     SBB    B
  852.     JC    MODIFY
  853. ;
  854. ;
  855. ; Update the value of this address by adding the offset to it
  856. ;
  857.     DCX    H        ; Set ptra back to LSB of the address
  858.     DB    LXID        ; Load DE with the offset value
  859. ;
  860. OFFSET:    DW    0
  861.     MOV    A,M        ; Get base address
  862.     ADD    E        ; Change LSB to new address
  863.     MOV    M,A        ; Update memory
  864.     INX    H        ; Advance pointer to the MSB of the addr
  865.     MOV    A,M        ; Get the MSB of the base addr
  866.     ADC    D        ; Change LSB to new address
  867.     MOV    M,A        ; Update memory
  868.     JMP    MODIFY        ; Take care of the next instruction
  869. ;
  870. ;
  871. ; Small subroutine to negate the contents of HL
  872. ;
  873. NEGHL:    MOV    A,H
  874.     CMA
  875.     MOV    H,A        ; Get the complement of the MSB
  876.     MOV    A,L
  877.     CMA
  878.     MOV    L,A        ; Get the complement of the LSBb
  879.     INX    H        ; Make 'HL' totally negative
  880.     RET
  881. ;.....
  882. ;
  883. ;
  884. ; Prepare to branch to the BYE5 program
  885. ;
  886. BEGIN:    LHLD    BDOS+1
  887.     PUSH    H
  888.     LXI    D,BEGOBJ
  889.     LHLD    OFFSET        ; Get prgram offset
  890.     DAD    D        ; Form address of new BDOS address
  891.     SHLD    BDOS+1        ; Update BDOS vector
  892.      ENDIF            ; NOT CPM3
  893. ;
  894.      IF    TRANWL AND (NOT    CPM3)
  895.     PUSH    H        ; Find where it's at
  896.     CALL    FNDWL
  897.     POP    D
  898.     JC    NOWL
  899.     MOV    M,E
  900.     INX    H
  901.     MOV    M,D
  902. ;
  903. NOWL:    XCHG
  904.      ENDIF            ; TRANWL AND NOT CPM3
  905. ;
  906.      IF    NOT CPM3
  907.     INX    H
  908.     POP    D
  909.     MOV    M,E
  910.     INX    H
  911.     MOV    M,D
  912.     INX    H
  913.     PCHL            ; Jump to relocated BYE5 program
  914.      ENDIF            ; NOT CPM3
  915. ;
  916.      IF    TRANWL AND (NOT    CPM3)
  917. HHSIG    EQU    12
  918. HSSIG    EQU    14
  919. HHSHL    EQU    16
  920. HLSHL    EQU    18
  921. HBSHL    EQU    36
  922. HDRVR    EQU    22
  923. HPCT    EQU    25
  924. PCMGR    EQU    4*2
  925. WWHSIG    EQU    'W'
  926. WWLSIG    EQU    'H'
  927. SIGWBT    EQU    'B'
  928. SIGUB    EQU    'L'
  929. SIGSD    EQU    'S'
  930. ;
  931. ;
  932. ; FNDWL.......
  933. ;    Input: none:
  934. ;    Output:
  935. ;        CY set.  Trantor Universal Bios is not loaded
  936. ;        CY clr.  HL -> var where adrs of lowest shell has to
  937. ;                be stored.
  938. ;             BC -> lowest shell.
  939. ;        DE is preserved.
  940. ;
  941. FNDWL:    PUSH    D
  942. ;
  943. ;    Scan downwards from High memory trying to find
  944. ;    any WW shell.
  945. ;
  946.     LXI    B,0FF06H
  947. ;
  948. ASHELL:    LXI    H,HHSIG
  949.     DAD    B
  950.     MOV    A,M
  951.     CPI    WWHSIG
  952.     JNZ    NSHELL
  953.     INX    H
  954.     MOV    A,M
  955.     CPI    WWLSIG
  956.     JZ    WWLINK
  957. ;
  958. NSHELL:    DCR    B
  959.     LDA    7
  960.     DCR    A
  961.     CMP    B
  962.     JC    ASHELL
  963.     STC
  964.     POP    D
  965.     RET
  966. ;.....
  967. ;
  968. ;
  969. ; Locate the Warm boot shell
  970. ;
  971. WWLINK:    LXI    H,HSSIG
  972.     DAD    B
  973.     MOV    A,M
  974.     CPI    SIGWBT
  975.     JZ    WBFND
  976.     LXI    H,HHSHL
  977.     DAD    B
  978.     MOV    C,M
  979.     INX    H
  980.     MOV    B,M
  981.     JMP    WWLINK
  982. ;
  983. ;
  984. ; Build pointer to wb.lowestshell
  985. ;
  986. WBFND:    LXI    H,HBSHL
  987.     DAD    B
  988.     ORA    A
  989. ;
  990. WLEXIT:    POP    D
  991.     RET
  992.      ENDIF            ; TRANWL AND NOT CPM3
  993. ;
  994. ;.....
  995. ;
  996. ;
  997.      IF    NOT CPM3
  998. ;
  999. ; The following table defines the 3-byte load instructions used in the
  1000. ; 8080 instruction set.
  1001. ;
  1002. INST3:    DB    001H,011H,021H,022H,02AH,031H,032H,03AH,0C2H
  1003.     DB    0C3H,0C4H,0CAH,0CCH,0CDH,0D2H,0D4H,0DAH,0DCH
  1004.     DB    0E2H,0E4H,0EAH,0ECH,0F2H,0F4H,0FAH,0FCH
  1005. INST3E    EQU    $        ; End of 3 byte op codes
  1006. ;
  1007. ;
  1008. ; The following table is the listing of the 2-byte opcodes used in the
  1009. ; 8080 instruction code set.
  1010. ;
  1011. INST2:    DB    006H,00EH,016H,01EH,026H,02EH,036H,03EH,0C6H
  1012.     DB    0CEH,0D3H,0D6H,0DBH,0DEH,0E6H,0EEH,0F6H,0FEH
  1013. INST2E    EQU    $        ; End of 2 byte op codes
  1014.      ENDIF            ; NOT CPM3
  1015. ;
  1016.  
  1017. ; This is a Resident System Extension (RSX) intended to run under CP/M
  1018. ; Plus.  The RSX is called via BDOS function 60 (in register C) with
  1019. ; register pair DE pointing to the RSX parameter block.
  1020. ;
  1021.      IF    CPM3        ; Loader for CP/M 3.0
  1022. ;
  1023. ; RSX Prefix Structure
  1024. ;
  1025. SERIAL:    DB    0,0,0,0,0,0    ; Room to insert serial number
  1026. STARTX:    JMP    FTEST        ; Beginning of program
  1027. NEXT:    DB    0C3H        ; Jump instruction op-code
  1028.     DW    0        ; Next module in line (or BDOS)
  1029. PREV:    DW    0        ; Previous module
  1030. REMOV:    DB    0FFH        ; Remove flag initially set
  1031. NONBNK:    DB    0        ; >0 to load only in non-banked CP/M
  1032. RSXNAM:    DB    'BYE5    '    ; The name of this RSX
  1033. LOADER:    DB    0        ; Loader flag
  1034.     DB    0,0        ; Reserved
  1035. ;
  1036. ;
  1037. ; BDOS function 60 sub-functions used by this RSX
  1038. ;
  1039. ;      4    Bye test for CCP+
  1040. ;      7    Return address of BYE control block (address of MXUSR)
  1041. ;     11    Remove any RSX's below BYE.  This is an immediate
  1042. ;        removal via a call to the CPM3 LOADER.    I am hoping
  1043. ;        for future KMD support of this function so that any
  1044. ;        uploads will not go into a library currently opend
  1045. ;        by LD in the upload area.
  1046. ;    101    Initialize function code
  1047. ;    102    Terminate function code
  1048. ;
  1049. ;
  1050. ; Miscellaneous data/constants
  1051. ;
  1052. INIFLG:    DB    NOTINIT        ; If not reset, all operations rejected
  1053. INIT    EQU    00        ; Initialized
  1054. NOTINIT    EQU    0FFH        ; Not initialized
  1055. ;
  1056. ;
  1057. ;-----------------------------------------------------------------------
  1058. ;           Entry point to the RSX
  1059. ;-----------------------------------------------------------------------
  1060. ;
  1061. FTEST:    MOV    A,C        ; Get BDOS function
  1062.     CPI    60        ; Could this one be for us?
  1063.     JNZ    NEXT        ; Nope - ignore this function
  1064. ;
  1065.     LDAX    D        ; Get the sub-function
  1066.      ENDIF            ; CPM3
  1067. ;
  1068.      IF    CPM3 AND CCPPLUS
  1069.     CPI    4        ; Is it bye test for CCP+?
  1070.     JZ    TSTBYE
  1071.      ENDIF            ; CPM3 AND CCPPLUS
  1072. ;
  1073.      IF    CPM3
  1074.     CPI    7        ; Is it return Variables address
  1075.     JZ    GMXUSR
  1076.     CPI    11        ; Is it remove lower RSX's ?
  1077.     JZ    DELRSX
  1078.     CPI    101        ; Is it initialize?
  1079.     JZ    RSXINT
  1080.     CPI    102        ; Is it terminate?
  1081.     JZ    RSXTRM
  1082.     JMP    NEXT        ; No match, try next RSX
  1083. ;
  1084. ;-----------------------------------------------------------------------
  1085. ;             RSX control functions
  1086. ;-----------------------------------------------------------------------
  1087. ;
  1088. ; Initialize the RSX environment for subsequent calls
  1089. ;
  1090. ; This routine establishes the environment for all other calls to the
  1091. ; RSX.    The operation is completed only if the RSX is not in an initial-
  1092. ; ized state.  If the RSX is already initialized, the function is
  1093. ; bypassed and an error status is passed back to the caller.
  1094. ;
  1095. RSXINT:    LDA    INIFLG        ; Get the initialize indicator
  1096.     CPI    NOTINIT        ; Is this a clean copy?
  1097.     JNZ    RSXIN2        ; No - can't reinitialize, use RESET
  1098.     XRA    A        ; Get a zero
  1099.     STA    REMOV        ; Mark the RSX resident
  1100.     STA    INIFLG        ; And mark this RSX as open for business
  1101.      ENDIF            ; CPM3
  1102. ;
  1103.      IF    COMFILE    AND CPM3
  1104.     LXI    H,COMFCB+1    ; BBS com filename
  1105.     LXI    D,ENTMSG    ; Display buffer
  1106.     MVI    B,8        ; Length of filename
  1107. ;
  1108. STAR1:    MOV    A,M        ; Move it to display buffer
  1109.     CPI    ' '        ; Stop on first space
  1110.     JZ    STAR2
  1111.     STAX    D
  1112.     INX    D
  1113.     INX    H
  1114.     DCR    B
  1115.     JNZ    STAR1        ; Loop until space or 8 chars found
  1116. ;
  1117. STAR2:    XRA    A
  1118.     STAX    D        ; Store 0 as print terminator
  1119.      ENDIF            ; COMFILE AND CPM3
  1120. ;
  1121.      IF    EXFILE AND CPM3
  1122.     LXI    H,EXITFCB+1    ; Exit .COM filename
  1123.     LXI    D,EXTMSG    ; Display buffer
  1124.     MVI    B,8        ; Length of filename
  1125. ;
  1126. STAR3:    MOV    A,M        ; Move it to display buffer
  1127.     CPI    ' '        ; Stop on first space
  1128.     JZ    STAR4
  1129.     STAX    D
  1130.     INX    D
  1131.     INX    H
  1132.     DCR    B
  1133.     JNZ    STAR3        ; Loop until space or 8 chars found
  1134. ;
  1135. STAR4:    XRA    A
  1136.     STAX    D        ; Store 0 as print terminator
  1137.      ENDIF            ; EXFILE AND CPM3
  1138. ;
  1139.      IF    MSGFIL AND CPM3
  1140.     LXI    H,MSGFCB+1    ; Message com filename
  1141.     LXI    D,MSGMSG    ; Display buffer
  1142.     MVI    B,8        ; Length of filename
  1143. ;
  1144. STAR5:    MOV    A,M        ; Move it to display buffer
  1145.     CPI    ' '        ; Stop on first space
  1146.     JZ    STAR6
  1147.     STAX    D
  1148.     INX    D
  1149.     INX    H
  1150.     DCR    B
  1151.     JNZ    STAR5        ; Loop until space or 8 chars found
  1152. ;
  1153. STAR6:    XRA    A
  1154.     STAX    D        ; Store 0 as print terminator
  1155.      ENDIF            ; MSGFIL AND CPM3
  1156. ;
  1157.      IF    LMBELL AND CPM3
  1158.     LDA    BELLON
  1159.     CMA
  1160.     STA    KILBEL        ; Prep the low memory bell flag
  1161.      ENDIF            ; LMBELL AND CPM3
  1162. ;
  1163.      IF    CPM3
  1164.     JMP    BGOBJ2        ; Go fire it up
  1165. ;
  1166. RSXIN2:
  1167.     MVI    A,0FFH        ; Get an error code
  1168. ;
  1169. RSXIN9:    RET            ; All done - return to caller
  1170. ;.....
  1171. ;
  1172. ;
  1173. ; Disengage this RSX
  1174. ;
  1175. RSXTRM:    CALL    MDCARCK        ; Check for caller still logged on
  1176.     JNZ    START0        ; Have carrier - log caller off, reset
  1177.     CALL    UNPATCH        ; Remove BIOS overrides
  1178.     JMP    BGOBJ2        ; Clean up and restart this program
  1179. ;
  1180. RSXCLR:    MVI    A,0FFH
  1181.     STA    INIFLG        ; Reset the initializaton flag to pre-
  1182.                 ; Vent further access
  1183.     STA    REMOV        ; Flag to drop this RSX on next warm boot
  1184.     XRA    A        ; Get a zero
  1185.     RET
  1186.      ENDIF            ; CPM3
  1187. ;
  1188.      IF    CPM3 AND CCPPLUS
  1189. ;........
  1190. ;
  1191. ;Bye present test for CCP+
  1192. ;
  1193. TSTBYE:
  1194.     XRA    A        ; Say that we are here
  1195.     RET
  1196.      ENDIF            ; CPM3 AND CCPPLUS
  1197. ;
  1198.      IF    CPM3
  1199. ;.......
  1200. ;
  1201. ;Return address of bye control block
  1202. ;
  1203. GMXUSR:
  1204.     LXI    H,MXUSR
  1205.     RET
  1206.      ENDIF            ; CPM3
  1207. ;
  1208. ;.......
  1209. ;
  1210. ;Delete any RSX's below bye
  1211. ;
  1212. DELRSX:     IF    CPM3 AND HISTRSX
  1213.     MVI    C,60        ; BDOS function to call an RSX
  1214.     LXI    D,RSXCL        ; Parameter passed to RSX
  1215.     CALL    NEXT
  1216.      ENDIF            ; CPM3 AND HISTRSX
  1217. ;
  1218.      IF    CPM3
  1219.     LHLD    PREV        ; Get address of previous RSX
  1220.     MVI    L,0EH        ; Point to remove flag
  1221.     MVI    C,59        ; So that the loader will
  1222.     LXI    D,0        ; Remove the RSX's
  1223. DELLP:
  1224.     MOV    A,H
  1225.     ORA    A        ; At base page?
  1226.     JZ    NEXT        ; All done.  Let loader do it.
  1227.     MVI    M,0FFH        ; Set remove flag
  1228.     DCR    L
  1229.     MOV    H,M        ; Get previous RSX page
  1230.     INR    L        ; Back to remove flag
  1231.     JMP    DELLP
  1232.      ENDIF            ; CPM3
  1233. ;.....
  1234. ;
  1235. ;
  1236. ; Set aside space for the stack region
  1237. ;
  1238.     DS    40
  1239. ISTACK:    DW    0        ; Top of stack
  1240. ;
  1241. ;
  1242. ;-----------------------------------------------------------------------
  1243. ;
  1244. ;           THE FOLLOWING CODE GETS MOVED
  1245. ;           TO HIGH RAM BY THE LOADER OR RSX
  1246. ;           PROGRAM, WHERE IT IS EXECUTED.
  1247. ;
  1248. ;-----------------------------------------------------------------------
  1249. ;
  1250.      IF    NOT CPM3
  1251. BEGOBJ:    JMP    0        ; Filled by BEGIN
  1252.      ENDIF            ; NOT CPM3
  1253. ;
  1254. BGOBJ2:    JMP    START0        ; Hop over fixed vectors
  1255. ;
  1256. MCBOOT:    JMP    MBOOT        ; Off to warm boot
  1257.     JMP    PRNLOG        ; Go print out items of interest
  1258. ;.....
  1259. ;
  1260. ;
  1261. ; Variables follow in a predefined order that can be manipulated by a
  1262. ; passworded or other program to give special users different capabili-
  1263. ; ties.
  1264. ;
  1265. ;-----------------------------------------------------------------------
  1266. ;
  1267. ; Here is a quickie handy reference table to use so we do not get mixed
  1268. ; up.  Please do not change the order of it in any future changes.
  1269. ;
  1270. ; |mxusr|mxdrv|toval|nulls|ulcsw|lfeeds|wrtloc|hardon|lostflg|covect|
  1271. ; |1 byt|1 byt|1 byt|1 byt|1 byt|1 byte|1 byte|1 byte|1 byte |2 byes|
  1272. ;
  1273. ; |BYE    |bell |stat |lcbuf|mxtme|rtcbuf|
  1274. ; |3 byt|1 byt|1 byt|2 byt|1 byt|2 byte|
  1275. ;-----------------------------------------------------------------------
  1276. ;
  1277. MXUSR:    DB    MAXUSR        ; Runtime maximum user area available
  1278. MXDRV:    DB    MAXDRV        ; Runtime maximum drive available
  1279. TOVAL:    DB    TOVALUE        ; Number of mins. to wait before timeout
  1280. NULLS:    DB    0        ; Number of nulls after <cr>
  1281. ULCSW:    DB    0        ; Upper case only switch (32=upper case)
  1282. LFEEDS:    DB    0        ; Line feed mask (0=don't mask)
  1283. WRTLOC:    DB    0        ; Location RBBS pokes so BYE won't hang
  1284. HARDON:    DB    0FFH        ; If 0, hardlog is deactivated
  1285. MDMOFF:    DB    0        ; If 0FFH, do not output to modem
  1286. COVECT:    DW    0        ; Console output vector for XMODEM
  1287. HDROFF    EQU    $-MCBOOT    ; Offset to 'BYE' that follows
  1288.     DB    'BYE'        ; Tells XMODEM that BYE is being used
  1289. BELLON:    DB    0FFH        ; If 0FFH ok to send bell (Chat) to con-
  1290.                 ; Sole, 00H=belloff.  This only affects
  1291.                 ; Your initial default choice
  1292. LCPTR:    JMP    LCDATA        ; First byte is user access restrictions
  1293.                 ; And flags while user is logged on,
  1294.                 ; Used for his total time-on after
  1295.                 ; Logoff.  LCDATA is address of buffer
  1296.                 ; For NO25TH data, NO25BF in length
  1297. MXTIME:    JMP    RTCBUF        ; First bye holds maximum time allowed
  1298.                 ; Next 2 bytes point to the real time
  1299.                 ; Clock buffer
  1300. ;
  1301. ;
  1302. ;        end of BYE5's fixed lookup table
  1303. ;-----------------------------------------------------------------------
  1304. ;
  1305. LCTON    EQU    LCPTR        ; Byte to store last caller's time-on-
  1306.                 ; System value (in binary).  You may
  1307.                 ; Equate this to a low-memory byte or
  1308.                 ; Use this byte in the BYE fixed var-
  1309.                 ; Iable table...can then be used by
  1310.                 ; Your entry/exit program to determine
  1311.                 ; How long the previous caller was on.
  1312. ;
  1313. ;-----------------------------------------------------------------------
  1314. ;
  1315. ;      THIS IS THE OFFICIAL START OF THE BYE PROGRAM
  1316. ;
  1317. ;-----------------------------------------------------------------------
  1318. ;
  1319. ;       ++++ Install your user defined subroutines here ++++
  1320. ;
  1321. ;    You may install a subroutine here that has the label SRUDEF
  1322. ;    that can be called from a transient program like your entry/
  1323. ;    exit .com file.  To access it, MVI C,84  CALL BDOS from your
  1324. ;    program.  Make sure this subroutine has a RET at the end.
  1325. ;    The transient program making a BDOS 84 call may pass data to
  1326. ;    this subroutine in any register(s) except A and C.  This routine
  1327. ;    can return data to the calling program in any register(s).
  1328. ;
  1329. SRUDEF:    RET            ; SubRoutine U DEFine for BDOS call 84
  1330. ;
  1331. ;-----------------------------------------------------------------------
  1332. ;
  1333. ; B5KP-1.INS  -  Kaypro insert for BYE5  -  07/17/85
  1334. ;
  1335. ;           Z80-SIO and 8116 baudrate generator
  1336. ;              by Irv Hoff
  1337. ;
  1338. ;
  1339. ;        Note:  This is an insert, not an overlay.
  1340. ;
  1341. ;
  1342. ;    MODEM=DCE    COMPUTER=DTE
  1343. ;
  1344. ;    TXD    2  -->    2    RXD    received data
  1345. ;    RXD    3  <--    3    TXD    tranmitted data
  1346. ;    SG    7  ---    7    SG    signal ground
  1347. ;    DCD    8  -->    8    DCD    carrier detect
  1348. ;    DTR    20 <--    20    DTR    data terminal ready
  1349. ;
  1350. ;                    - Notes by Irv Hoff
  1351. ;
  1352. ; =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =
  1353. ;
  1354. ; 07/17/85  Written for use with BYE5    - Irv Hoff
  1355. ;
  1356. ; =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =
  1357. ;
  1358. ;
  1359. PORT    EQU    04H        ; Data port
  1360. MDCTL1    EQU    PORT+2        ; Modem control port
  1361. BRPORT    EQU    00H        ; Baud rate generator port
  1362. ;
  1363. MDRCV    EQU    1        ; Modem receive ready bit
  1364. MDSND    EQU    4        ; Modem send ready bit
  1365. MDDCD    EQU    8        ; Data carrier detect
  1366. ;
  1367. ;
  1368. ; Divisors for the 8116 baudrate generator
  1369. ;
  1370. BD300    EQU    5        ; 300 baud
  1371. BD1200    EQU    7        ; 1200 bps
  1372. BD2400    EQU    10        ; 2400 bps
  1373. ;
  1374. ;
  1375. ;-----------------------------------------------------------------------
  1376. ;
  1377. ; See if we still have a carrier - if not, return with the zero flat set
  1378. ;
  1379. MDCARCK:MVI    A,10H        ; Reset status
  1380.     OUT    MDCTL1
  1381.     IN    MDCTL1        ; Get status
  1382.     ANI    MDDCD        ; Check for carrier
  1383.     RET
  1384. ;.....
  1385. ;
  1386. ;
  1387. ; Disconnect and wait for an incoming call
  1388. ;
  1389. MDINIT:    MVI    A,0        ; Setup to write register 0
  1390.     OUT    MDCTL1
  1391.     MVI    A,18H        ; Reset channel
  1392.     OUT    MDCTL1
  1393. ;
  1394.     MVI    A,4        ; Setup to write register 4
  1395.     OUT    MDCTL1
  1396.     MVI    A,44H        ; Set 16x, 1 stop bit, no parity
  1397.     OUT    MDCTL1
  1398. ;
  1399.     MVI    A,3        ; Setup to write register 3
  1400.     OUT    MDCTL1
  1401.     MVI    A,0C1H        ; 8 bits, Rx enable
  1402.     OUT    MDCTL1
  1403. ;
  1404.     MVI    A,5        ; Setup to write register 5
  1405.     OUT    MDCTL1
  1406.     MVI    A,68H        ; DTR off
  1407.     OUT    MDCTL1
  1408. ;
  1409.     PUSH    B        ; Save in case it's being used elsewhere
  1410.     MVI    B,20        ; 2 second delay to drop any carrier
  1411. ;
  1412. OFFTI:    CALL    DELAY        ; 1 second delay
  1413.     DCR    B
  1414.     JNZ    OFFTI        ; Keep looping until finished
  1415.     POP    B        ; Restore 'BC'
  1416. ;
  1417.     MVI    A,5        ; Setup to write register 5
  1418.     OUT    MDCTL1
  1419.     MVI    A,0E8H        ; Turn DTR back on
  1420.     OUT    MDCTL1
  1421. ;
  1422.      IF    IMODEM        ; If using an intellegent modem
  1423.     CALL    IMINIT        ; Go initialize it now
  1424.      ENDIF            ; IMODEM
  1425. ;
  1426.     RET
  1427. ;.....
  1428. ;
  1429. ;
  1430. ; Input a character from the modem port
  1431. ;
  1432. MDINP:    IN    PORT        ; Get character
  1433.     RET
  1434. ;.....
  1435. ;
  1436. ;
  1437. ; Check the status to see if a character is available.    If not, return
  1438. ; with the zero flag set.  If yes, use 0FFH to clear the flag.
  1439. ;
  1440. MDINST:    IN    MDCTL1        ; Get status
  1441.     ANI    MDRCV        ; Got a character
  1442.     RZ            ; Return if none
  1443.     ORI    0FFH        ; Otherwise set the proper flag
  1444.     RET
  1445. ;.....
  1446. ;
  1447. ;
  1448. ; Send a character to the modem
  1449. ;
  1450. MDOUTP:    OUT    PORT        ; Send it
  1451.     RET
  1452. ;.....
  1453. ;
  1454. ;
  1455. ; See if the output is ready for another character
  1456. ;
  1457. MDOUTST:IN    MDCTL1        ; Get status
  1458.     ANI    MDSND        ; Ready for a character?
  1459.     RET
  1460. ;.....
  1461. ;
  1462. ;
  1463. ; Reinitialize the modem and hang up the phone by dropping DTR and
  1464. ; leaving it inactive.
  1465. ;
  1466. MDQUIT:     IF    IMODEM
  1467.     CALL    IMQUIT
  1468.      ENDIF            ; IMODEM
  1469. ;
  1470. ;
  1471. ; Called by the main program after caller types BYE
  1472. ;
  1473. MDSTOP:    MVI    A,5        ; Setup to write register 5
  1474.     OUT    MDCTL1
  1475.     MVI    A,68H        ; Turn off DTR until next time
  1476.     OUT    MDCTL1
  1477.     RET
  1478. ;.....
  1479. ;
  1480. ;
  1481. ; The following routine sets the baud rate.  BYE5 asks for the maximum
  1482. ; speed you have available.
  1483. ;
  1484. SETINV:    ORI    0FFH        ; Make sure zero flag is not set
  1485.     RET
  1486. ;.....
  1487. ;
  1488. ;
  1489. SET300:    MVI    A,BD300
  1490.     JMP    SETBAUD
  1491. ;
  1492. SET1200:MVI    A,BD1200
  1493.     JMP    SETBAUD
  1494. ;
  1495. SET2400:MVI    A,BD2400
  1496. ;
  1497. ;
  1498. ; Sets the baudrate
  1499. ;
  1500. SETBAUD:OUT    BRPORT
  1501.     XRA    A        ; Say baudrate is ok
  1502.     RET
  1503. ;.....
  1504. ;
  1505. ;                   end
  1506. ;----------------------------------------------------------------------:
  1507. ;
  1508. ;      ++++ Install your Modem dependent insert here ++++
  1509. ;          (If B5IM is YES you don't need one)
  1510. ;
  1511. ;-----------------------------------------------------------------------
  1512. ;
  1513. ;         ++++ Install your TIME routine here ++++
  1514. ;
  1515. ; If you have a clock and wish to use TIMEON or RSPEED, please replace
  1516. ; the following code with your clock read code.  Use as many instruc-
  1517. ; tions as you need but make sure you store binary, not BCD values in
  1518. ; CCHOUR and CCMIN.  Use RTCBUF to store BCD clock data, then use BCDBIN
  1519. ; to convert it to binary for CCHOUR and CCMIN.  See B5C-QXnn.INS as an
  1520. ; example of handling a BCD clock, or B5C-SDS.INS for a BIOS interrupt-
  1521. ; driven clock that runs in binary (hex).  All registers are saved before
  1522. ; TIME is called, so you don't have to save them.
  1523. ;
  1524. ; NOTE... Set BCD2BIN to YES if your clock routine calls BCDBIN
  1525. ;      Set BIN2BCD to YES if your clock routine calls BINBCD
  1526. ;
  1527. TIME:    RET
  1528. ;             end of clock routine
  1529. ;-----------------------------------------------------------------------
  1530. ;            start B5IM code
  1531. ;
  1532.      IF    B5IM
  1533. IMRING:    CALL    MDINST        ; Character ready from modem?
  1534.     RZ            ; No
  1535.     CALL    MDINP        ; Get the modem response code
  1536.     ANI    7FH        ; Strip parity
  1537.      ENDIF            ; B5IM
  1538. ;
  1539.      IF    B5IM AND PRGRSS
  1540.     CALL    RCDISP        ; Display RC for local Sysop
  1541.     PUSH    PSW
  1542.     LXI    H,LFMSG
  1543.     CALL    PRINTL        ; Turn up a line on CRT
  1544.     POP    PSW
  1545.      ENDIF            ; PRGRSS
  1546. ;
  1547.      IF    B5IM
  1548.     CPI    CR
  1549.     RZ
  1550.     CPI    LF
  1551.     RZ
  1552.     CPI    '2'        ; Ring?
  1553.     JNZ    REDOIT        ; No, something wrong, start over
  1554.      ENDIF            ; B5IM
  1555. ;
  1556. IMRIN1:     IF    B5IM AND (NOT NOATA)
  1557.     MVI    B,5        ; Must let the phone quit ringing first
  1558.     CALL    DLP1        ; Usually takes from 1.4 to 3.7 seconds
  1559.     CALL    EATALL        ; Swallow c/r or lf from result code
  1560. ;
  1561. IMRIN2:    LXI    H,B5ATA
  1562.     CALL    IMSEND        ; Send ATA to modem
  1563.      ENDIF            ; B5IM AND NOT NOATA
  1564. ;
  1565.      IF    B5IM
  1566.     LXI    B,30000        ; Check for RC every 1 ms for 30 secs
  1567. ;
  1568. MDR1:    CALL    MDINST
  1569.     JZ    RCHEK        ; And wait for response
  1570.     CALL    MDINP        ; Then fetch it
  1571.     ANI    07FH        ; And strip parity
  1572.      ENDIF            ; B5IM
  1573. ;
  1574.      IF    B5IM AND PRGRSS
  1575.     CALL    RCDISP        ; And show results code (RC)
  1576.      ENDIF            ; B5IM AND PRGRSS
  1577. ;
  1578.      IF    B5IM
  1579.     CPI    CR
  1580.     JZ    MDR1
  1581.     CPI    LF
  1582.     JZ    MDR1
  1583.     CPI    '2'        ; Missed ring indicator?
  1584.     JZ    IMRIN1        ; Answer again
  1585.     CPI    '3'        ; Carrier wait timeout?
  1586.     JZ    REDOIT        ; Yep, timeout (voice call maybe)
  1587.     CPI    '4'        ; Error?
  1588.     JZ    REDOIT        ; Start over
  1589.     CPI    '1'        ; 300 baud or 2400 bps?
  1590.     JNZ    MDR2        ; No, check for 1200 bps
  1591. ;
  1592. ;
  1593. ; Get next character if first was a '1'
  1594. ;
  1595.     CALL    CHECK1        ; Let's see if it's a 1, 10 or 11
  1596.      ENDIF            ; B5IM
  1597. ;
  1598.      IF    B5IM AND PRGRSS
  1599.     CALL    RCDISP        ; Show RC to local terminal
  1600.      ENDIF            ; B5IM AND PRGRSS
  1601. ;
  1602.      IF    B5IM
  1603.     CPI    '0'
  1604.     JZ    SET24        ; For Vadic and Hayes, 10 means 2400 bps
  1605. ;
  1606.     JMP    SET3        ; Was 1 (300 baud)
  1607. ;
  1608. MDR2:    CPI    '5'        ; 1200 bps?
  1609.     JZ    SET12        ; Yes
  1610.     CPI    '6'        ; Some modems use 6
  1611.     JZ    SET24
  1612.     CPI    '9'        ; Or 9
  1613.     JZ    SET24        ; For Connect-2400
  1614.      ENDIF            ; B5IM
  1615. ;
  1616.      IF    B5IM AND ANCHOR
  1617.     JMP    SET3        ; If it wasn't a 3 or 5 it means the
  1618.                 ; Anchor connected at 300 but sent RC
  1619.                 ; At wrong speed
  1620.      ENDIF            ; B5IM AND ANCHOR
  1621. ;
  1622.      IF    B5IM
  1623.     JMP    MDR1        ; Wait 30 seconds for valid response
  1624. ;
  1625. RCHEK:    CALL    KDELAY        ; Wait 1 millisecond
  1626.     DCX    B
  1627.     MOV    A,C
  1628.     ORA    B        ; Time up?
  1629.     JNZ    MDR1        ; No, Keep trying
  1630. ;
  1631. REDOIT:    POP    H        ; Go reset if none of these responses
  1632.     LXI    H,VCNUM        ; Update the voice call
  1633.     INR    M        ; Counter
  1634.      ENDIF            ; B5IM
  1635. ;
  1636.      IF    B5IM AND DISKLOG
  1637.     CALL    OPENLOG        ; Make sure log file is on
  1638.     LXI    H,VOCMSG
  1639.     CALL    WRTMSG        ; Put voice call message into log
  1640.     MVI    E,0
  1641.     CALL    TSTHRD        ; Close the log file
  1642.      ENDIF            ; B5IM AND DISKLOG
  1643. ;
  1644.      IF    B5IM
  1645.     LXI    H,LFMSG
  1646.     CALL    PRINTL        ; Turn up a line on crt
  1647.     CALL    MDSTOP        ; Turn dtr off while we reset
  1648.     JMP    HANGUP1
  1649.      ENDIF            ; B5IM
  1650. ;
  1651.      IF    B5IM AND PRGRSS
  1652. RCDISP:    PUSH    B
  1653.     PUSH    H
  1654.     PUSH    PSW        ; Save A
  1655.     STA    RCSHOW
  1656.     LXI    H,RCSHOW    ; And show results code (RC)
  1657.     CALL    PRINTL
  1658.     POP    PSW
  1659.     PUSH    PSW
  1660.     CPI    CR
  1661.     JNZ    RCDIS1
  1662.     MVI    A,LF
  1663.     STA    RCSHOW        ; Force a LF after a CR
  1664.     LXI    H,RCSHOW
  1665.     CALL    PRINTL
  1666. ;
  1667. RCDIS1:    POP    PSW
  1668.     POP    H
  1669.     POP    B
  1670.     RET
  1671.      ENDIF            ; B5IM AND PRGRSS
  1672. ;.....
  1673. ;
  1674. ;
  1675.      IF    B5IM
  1676. CHECK1:    LXI    B,500        ; Try up to 500 ms
  1677. ;
  1678. CHECK2:    CALL    KDELAY
  1679.     DCX    B
  1680.     MOV    A,B
  1681.     ORA    C
  1682.     JZ    CHECK3        ; 500 ms is up
  1683.     CALL    MDINST        ; Character ready?
  1684.     JZ    CHECK2        ; No, keep waiting
  1685.     CALL    MDINP        ; Yes, fetch it
  1686.     ANI    07FH        ; And strip parity
  1687.     RET            ; And return
  1688. ;
  1689. CHECK3:    MVI    A,0FFH        ; Set error code
  1690.     RET            ; And return
  1691. ;.....
  1692. ;
  1693. ;
  1694. SET24:    CALL    DLP        ; 1 sec delay
  1695.     CALL    SET2400        ; Set port to 2400 bps
  1696.     MVI    A,BP2400
  1697.     STA    MSPEED        ; Set speed indicator
  1698.     JMP    FINISH
  1699. ;
  1700. SET3:    CALL    DLP
  1701.     CALL    SET300        ; Set port to 300 baud
  1702.     MVI    A,BP300
  1703.     STA    MSPEED        ; Set speed indicator
  1704.     JMP    FINISH
  1705. ;
  1706. SET12:    CALL    DLP
  1707.     CALL    SET1200        ; Set port to 1200 bps
  1708.     MVI    A,BP1200
  1709.     STA    MSPEED        ; And speed indicator
  1710. ;
  1711. FINISH:    CALL    MDCARCK        ; Still have carrier?
  1712.     JZ    REDOIT        ; No, reset modem
  1713.     POP    H        ; Reset CALL on the stack
  1714.     CALL    PATCH        ; Patch the jump table
  1715.     MVI    B,1        ; 0.1 sec more
  1716.     CALL    DLP1        ; Wait to enter terminal mode
  1717.     JMP    ANSW        ; And greet the user at his speed
  1718. ;.....
  1719. ;
  1720. ;
  1721. ; Initialize the modem for normal unattended operation.
  1722. ;
  1723. IMINIT:    CALL    DLP
  1724.     CALL    EATALL
  1725.      ENDIF
  1726. ;
  1727.      IF    B5IM AND DOATZ
  1728.     LXI    H,B5ATZ        ; Reset the modem
  1729.     CALL    IMSEND
  1730.     CALL    DLP
  1731.     CALL    EATALL        ; Swallow the response
  1732.      ENDIF            ; B5IM AND DOATZ
  1733. ;
  1734.      IF    B5IM
  1735.     LXI    H,B5INIT
  1736.     CALL    IMSEND        ; Go initialize the modem
  1737.      ENDIF            ; B5IM
  1738. ;
  1739.      IF    B5IM AND SHORTB
  1740.     CALL    DLP
  1741.     CALL    EATALL
  1742.     LXI    H,B5INT1
  1743.     CALL    IMSEND        ; Use 2 strings for short buff. modems
  1744.      ENDIF            ; B5IM AND SHORTB
  1745. ;
  1746.      IF    B5IM AND PRGRSS
  1747. IMINT1:    CALL    CHECK1
  1748.     CPI    0FFH        ; No result code?
  1749.     JZ    IMINT2        ; Yes, inform Sysop and retry
  1750.     CPI    '0'        ; Executed ok?
  1751.     CZ    RCDISP        ; Display result code
  1752.     JZ    IMINT3        ; And continue
  1753.     CPI    '4'        ; Modem error?
  1754.     CZ    RCDISP
  1755.     JNZ    IMINT1        ; Wait for a zero or four or 0FFH
  1756. ;
  1757. IMINT2:    LXI    H,CMDERR    ; We have a 4 or 0FFH
  1758.     CALL    PRINTL        ; Inform Sysop of problem
  1759.     JMP    IMINIT        ; Try it again
  1760.      ENDIF            ; B5IM AND PRGRSS AND NOT ANCHOR
  1761. ;
  1762.      IF    B5IM
  1763. IMINT3:    LXI    H,LFMSG
  1764.     CALL    PRINTL        ; Turn up a line on crt
  1765.     CALL    DLP
  1766.     CALL    EATALL        ; Get any garble from the modem
  1767.     RET
  1768. ;.....
  1769. ;
  1770. ;
  1771. ; Delay about one second to let modem get stabilized before or after a
  1772. ; command string.
  1773. ;
  1774. DLP:    MVI    B,10
  1775. ;
  1776. DLP1:    CALL    DELAY
  1777.     DCR    B
  1778.     JNZ    DLP1
  1779.     RET
  1780. ;
  1781. EATALL:    CALL    CHECK1
  1782.     CPI    0FFH        ; All characters eaten?
  1783.     JNZ    EATALL        ; No, keep eating
  1784.     RET
  1785. ;.....
  1786. ;
  1787. ;
  1788. ; De-initiaize the modem.  When the operator uses CTL-C followed by any-
  1789. ; thing but "R", this call will return the modem to default settings.
  1790. ;
  1791. IMQUIT:    LXI    H,LFMSG
  1792.     CALL    PRINTL        ; Turn up a line on crt
  1793.      ENDIF            ; B5IM
  1794. ;
  1795.      IF    B5IM AND DOATZ
  1796.     CALL    DLP
  1797.     CALL    EATALL
  1798.     LXI    H,B5ATZ
  1799.     CALL    IMSEND        ; Send ATZ message to modem
  1800.      ENDIF            ; B5IM AND DOATZ
  1801. ;
  1802.      IF    B5IM
  1803.     CALL    DLP
  1804.     CALL    EATALL
  1805.      ENDIF            ; B5IM
  1806. ;
  1807.      IF    B5IM AND (NOT OFFHK)
  1808.     LXI    H,B5USR
  1809.     CALL    IMSEND        ; Send ATS0=0 to modem
  1810.     CALL    EATALL
  1811.      ENDIF            ; B5IM AND NOT OFFHK
  1812. ;
  1813.      IF    B5IM AND OFFHK
  1814.     LXI    H,B5ATH1    ; Send ATH1 to the modem
  1815.     CALL    IMSEND
  1816.      ENDIF            ; B5IM AND OFFHK
  1817. ;
  1818.      IF    B5IM
  1819.     RET
  1820. ;.....
  1821. ;
  1822. ;
  1823. ; Send a command string to the modem. (If ECHO) Verify, reset the modem
  1824. ; and resend string if echo fails.
  1825. ;
  1826. IMSEND:    PUSH    B        ; Save 'BC' registers
  1827.     SHLD    ADDSTR        ; Save start of command string
  1828. ;
  1829. IMSEN1:    CALL    MDOUTST        ; Modem ready for character?
  1830.     JZ    IMSEN1        ; No, go check again
  1831.     MOV    A,M        ; Get the character
  1832.     PUSH    PSW
  1833.     CALL    MDOUTP        ; Send the character
  1834.     POP    PSW
  1835.      ENDIF            ; B5IM
  1836. ;
  1837.      IF    B5IM AND PRGRSS
  1838.     CALL    RCDISP        ; Display the command string
  1839.      ENDIF            ; B5IM AND PRGRSS
  1840. ;
  1841.      IF    B5IM AND ECHO    ; Hayes needs echo checking
  1842.     CALL    CHECK1        ; Get the echo character
  1843.     CMP    M        ; Same?
  1844.     JNZ    NOECHO        ; No, let's resend entire command string
  1845.      ENDIF            ; B5IM AND ECHO
  1846. ;
  1847.      IF    B5IM
  1848.     INX    H        ; Point to next
  1849.     MOV    A,M        ; Get next character
  1850.     ORA    A        ; Has all been sent
  1851.     JNZ    IMSEN1        ; No, go send another character
  1852.     POP    B        ; Restore the BC registers
  1853.     RET            ; Return past end of message
  1854.      ENDIF            ; B5IM
  1855. ;
  1856. NOECHO:     IF    B5IM AND ECHO AND PRGRSS
  1857.     LXI    H,NOEMSG
  1858.     CALL    PRINTL        ; Inform Sysop of echo error
  1859.      ENDIF            ; B5IM AND ECHO AND PRGRSS
  1860. ;
  1861.      IF    B5IM AND ECHO
  1862.     CALL    MDOUTST        ; Wait for modem ready
  1863.     JZ    NOECHO
  1864.     MVI    A,CR
  1865.     CALL    MDOUTP        ; Force a c/r to end command string
  1866.     CALL    DLP        ; Let modem settle
  1867.     CALL    EATALL        ; Make sure input is clear
  1868.     LHLD    ADDSTR        ; Restore address of command string
  1869.     JMP    IMSEN1        ; And send it again
  1870.      ENDIF            ; B5IM AND ECHO
  1871. ;.....
  1872. ;
  1873. ;
  1874.      IF    B5IM AND NODTR
  1875. IMHANG:    CALL    EATALL
  1876.     MVI    B,30        ; Some modems need 3 sec, doesn't hurt
  1877.                 ; Others
  1878.     CALL    DLP1        ; This routine will hang up the phone
  1879.     LXI    H,B5ESC        ; Using +++ATH
  1880.     CALL    IMSEND
  1881.     CALL    EATALL
  1882.     MVI    B,15
  1883.     CALL    DLP1
  1884.     LXI    H,B5ATH
  1885.     CALL    IMSEND        ; For modems without DTR support
  1886.     CALL    DLP
  1887.     RET
  1888.      ENDIF            ; B5IM AND NODTR
  1889. ;.....
  1890. ;
  1891. ;            end of B5IM code
  1892. ;-----------------------------------------------------------------------
  1893. ;
  1894. IMDONE:    CALL    DELAY
  1895. ;
  1896.      IF    NOT NODTR
  1897.     CALL    MDSTOP        ; Drop DTR-***This is a new label just
  1898.                 ; After MDQUIT that drops DTR and
  1899.                 ; Returns.
  1900.      ENDIF            ; NOT NODTR
  1901. ;
  1902.     CALL    MDCARCK        ; Carrier?
  1903.     RZ            ; Carrier gone, return
  1904. ;
  1905.      IF    B5IM AND NODTR
  1906.     CALL    IMHANG        ; Send +++ATH
  1907.      ENDIF            ; B5IM AND NODTR
  1908. ;
  1909.     JMP    IMDONE        ; Keep looping
  1910. ;
  1911. ;-----------------------------------------------------------------------
  1912. ;
  1913. ; If the carrier is lost - hang up, await ring.  Otherwise, say goodbye,
  1914. ; and hang-up.
  1915. ;
  1916. START0:     IF    TIMEON
  1917.     LDA    TON
  1918.     STA    LCTON        ; Preserve last callers time-on for
  1919.                 ; Entry pgm
  1920.      ENDIF            ; TIMEON
  1921. ;
  1922.      IF    NOT CPM3
  1923.     LHLD    BDOS+1        ; Get beginning address of BYE5 program
  1924.     SHLD    BDADDR        ; Save address of BYE5 start
  1925.      ENDIF            ; NOT CPM3
  1926. ;
  1927. ;
  1928. ;
  1929. ; Patch in BYE's BDOS interceptor
  1930. ;
  1931.      IF    CPM3
  1932.     LHLD    STARTX+1
  1933.      ENDIF            ; CPM3
  1934. ;
  1935.      IF    NOT CPM3
  1936.     LHLD    BEGOBJ+1    ; Get real bdos call
  1937.      ENDIF            ; NOT CPM3
  1938. ;
  1939.     MOV    A,H        ; Get high address byte
  1940.     LXI    D,BYERSX    ; Have to do it this way to fool the
  1941.                 ; Relocator
  1942.     CMP    D        ; Already pointed to BYERSX?
  1943.     JZ    NORPTC        ; Then don't patch again
  1944.     SHLD    REALBD+1    ; Save it in the interceptor routine
  1945.     LXI    H,BYERSX    ; Get address of interceptor routine
  1946. ;
  1947.      IF    CPM3
  1948.     SHLD    STARTX+1    ; So we intercept BDOS calls
  1949.      ENDIF            ; CPM3
  1950. ;
  1951.      IF    NOT CPM3
  1952.     SHLD    BEGOBJ+1    ; Save it so it goes through our ex-
  1953.                 ; Tended BDOS
  1954.      ENDIF            ; NOT CPM3
  1955. ;
  1956. NORPTC:    XRA    A        ; A=0
  1957.     STA    MDMOFF        ; Show no carrier lost
  1958.     STA    ULCSW        ; Reset upper/lower case flag
  1959.     STA    LFEEDS        ; And line feed flag
  1960.     STA    WRTLOC        ; And write-in-progress flag
  1961.     STA    OPTION        ; And option flag
  1962. ;
  1963.      IF    TIMEON AND CLOCK AND (NOT EXFILE)
  1964.     CALL    MDCARCK
  1965.     CNZ    RMTOS        ; Report final time-on-system
  1966.      ENDIF            ; TIMEON AND CLOCK
  1967. ;
  1968. ;
  1969. ; Set MINICK to 'YES' if you use MINICBBS and want to take advantage of
  1970. ; its feature which can prevent the modem from hanging up if the caller
  1971. ; should happen to disconnect during a file update.  MINICBBS sets the
  1972. ; high-order bit of IOBYTE (address 0003H) to indicate a file update is
  1973. ; in progress.
  1974. ;
  1975.      IF    MINICK
  1976.     MVI    A,IOVAL        ; Get proper initial value
  1977.     STA    IOBYTE        ; Set it in IOBYTE
  1978.      ENDIF            ; MINICK
  1979. ;
  1980.      IF    MBBS
  1981.     LXI    SP,STACK
  1982.     CALL    MDCARCK
  1983.     JZ    START1        ; No carrier, skip this
  1984.     LDA    LCDATA
  1985.     CPI    ' '        ; User logged in?
  1986.     JZ    GOODBY        ; No, carry on
  1987.     XRA    A
  1988.     STA    0        ; Prep mbbs
  1989.     MVI    A,0FFH
  1990.     STA    WRTLOC        ; To prevent hangup
  1991.     LDA    FCB+1
  1992.     CPI    'C'        ; Comments requested?
  1993.     JZ    MBBSC        ; Yes, do comments
  1994.      ENDIF            ; MBBS
  1995. ;
  1996.      IF    MBBS AND PRNTGB
  1997.     LXI    H,GBMSG
  1998.     CALL    PRINTB        ; Say goodbye to user
  1999.      ENDIF            ; MBBS AND PRNTGB
  2000. ;
  2001.      IF    MBBS
  2002. MBBS01:    CALL    IMDONE        ; Drop carrier and fix so phone won't
  2003.     JMP    MBBSNC        ; Answer and tell Sysop
  2004. ;
  2005. MBBSC:    STA    OPTION        ; So we know to load MBBS or login
  2006.     LXI    H,MBBS1
  2007.     CALL    PRINTB        ; Wait for MBBS to load
  2008.     CALL    LODCOM        ; Load mbbs for comments
  2009.     CALL    MDCARCK        ; Did user wait for all this?
  2010.     JZ    MBBSNC        ; No, tell Sysop and load login
  2011.     MVI    A,0CDH
  2012.     STA    0        ; So MBBS will ask for comments
  2013.     CALL    100H        ; Now do it
  2014. ;
  2015. MBBSNC:    LXI    H,MBBS2
  2016.     CALL    PRINTL        ; Tell Sysop about log off
  2017.     MVI    A,0FFH
  2018.     STA    MDMOFF        ; So BYE5 will handle rest of this
  2019.     MVI    A,'E'
  2020.     STA    OPTION        ; So BYE5 will trap MBBS return
  2021.     CALL    LODCOM        ; Load login
  2022.     CALL    100H        ; Let login finish user stats
  2023.      ENDIF            ; MBBS
  2024. ;
  2025.     CALL    MDCARCK        ; Call modem carrier check routine
  2026.     JNZ    GOODBY        ; We have carrier, so say bye bye...
  2027. ;
  2028. START1:     IF    COMFILE
  2029.     LDA    FCB+1
  2030.     STA    OPTION        ; So remote cannot type BYE E
  2031.     MVI    A,' '
  2032.     STA    FCB+1
  2033.      ENDIF            ; COMFILE
  2034. ;
  2035. ;
  2036. ; Get the System Parameter Block address, common memory base page,
  2037. ; BDOS base page for use in main program or overlays.
  2038. ;
  2039.      IF    CPM3
  2040.     MVI    C,GTSCB        ; Return base page of SCB
  2041.     LXI    D,SCBPB
  2042.     CALL    BDOS
  2043.     SHLD    SCBBASE        ; Save SCB address
  2044.     MVI    L,SCBCOM    ; 0FAH = common memory base page
  2045.     MOV    A,M
  2046.     STA    MEMBASE        ; Save common memory base page
  2047.     MVI    L,SCBBDOS    ; 99H = base page of BDOS
  2048.     MOV    A,M
  2049.     STA    BDOSBASE    ; Save base page of BDOS system
  2050.      ENDIF            ; CPM3
  2051. ;
  2052. ;
  2053. ; Identify version of program
  2054. ;
  2055.     CALL    PATCH        ; Copies vectors for PRINTL
  2056.     CALL    UNPATCH
  2057.     LXI    H,VMSG        ; Signon message
  2058.     CALL    PRINTL
  2059. ;
  2060.     JMP    HANGUP        ; We know it is local, so prepare for
  2061.                 ; Next caller
  2062. ;
  2063. GOODBY:     IF    EXFILE
  2064.     JMP    LOGOFF        ; Run the exit file
  2065.      ENDIF            ; EXFILE
  2066. ;
  2067.      IF    PRNTGB AND (NOT    EXFILE)
  2068.     LXI    H,GBMSG        ; Goodbye message
  2069.     CALL    PRINTB        ; Print this message
  2070.      ENDIF            ; PRNTGB AND NOT EXFILE
  2071. ;
  2072.      IF    NOT EXFILE
  2073.     CALL    IMDONE        ; Hang up the phone before doing this
  2074.     CALL    UNPATCH        ; Undo BIOS patches
  2075.      ENDIF            ; NOT EXFILE
  2076. ;
  2077. ;.....
  2078. ;
  2079.      IF    DISKLOG    AND (NOT EXFILE)
  2080.     LXI    H,DSCMSG    ; Disconnect message
  2081.     CALL    WRTMSG        ; Put it into log file
  2082.      ENDIF            ; DISKLOG AND NOT EXFILE
  2083. ;
  2084. ;
  2085. ; Nobody there, or we are done.
  2086. ;
  2087. HANGUP:    LXI    SP,STACK    ; Set up local stack
  2088. ;
  2089.      IF    DISKLOG
  2090.     XRA    A
  2091.     STA    BDOSFL
  2092.     STA    LOGTOG
  2093.     MOV    E,A
  2094.     CALL    TSTHRD        ; This will close log file
  2095.      ENDIF
  2096. ;
  2097.      IF    CPM3
  2098.     CALL    DELRSX        ; Remove any RSX's below BYE
  2099.     LXI    D,DEFPW
  2100.     MVI    C,DEFPAS
  2101.     CALL    REALBD        ; Set default password to blanks
  2102.      ENDIF            ; CPM3
  2103. ;
  2104.      IF    COMFILE
  2105.     LXI    H,ENTMSG
  2106.     CALL    PRINTL        ; Show it's the entry file
  2107.     CALL    LODCOM        ; Load the .COM file
  2108.      ENDIF            ; COMFILE
  2109. ;
  2110. ;
  2111. ; Set drive/user, then give summary and initialize for next call
  2112. ;
  2113. HANGUP1:MVI    A,WBDRIV    ; Force next warmboot to user 0
  2114.     STA    0004H        ; And drive wbdriv
  2115. ;
  2116.      IF    CPM3
  2117.     CALL    SETDRIVE    ; Set to wbdriv
  2118.     XRA    A
  2119.     CALL    SETUSER        ; Set user to zero
  2120.      ENDIF            ; CPM3
  2121. ;
  2122.     XRA    A
  2123.     STA    MDMOFF        ; Clear modem status
  2124.     STA    WRTLOC        ; And wrtloc
  2125.     STA    TON        ; Reset time-on-system
  2126.     STA    MSFLAG        ; Reset status for no-activity timer
  2127. ;
  2128.      IF    RTOK
  2129.     STA    RTOKFG        ; So RBBS can be re-entered
  2130.      ENDIF            ; RTOK
  2131. ;
  2132.      IF    CPM3
  2133.     LHLD    SCBBASE        ; Get address of SCB
  2134.     MVI    L,0D4H
  2135.     MOV    M,A        ; Reset ^P mode
  2136.     MVI    L,0CAH
  2137.     MOV    M,A        ; Set CTL-H mode
  2138.     INR    L
  2139.     DCR    A
  2140.     MOV    M,A        ; Set RUB/DEL mode
  2141.      ENDIF            ; CPM3
  2142. ;
  2143.      IF    CPM3 AND CCPPLUS
  2144.     MVI    L,0A4H
  2145.     MOV    A,M
  2146.     ORI    80H        ; Turn on directory name display
  2147.     MOV    M,A
  2148.      ENDIF            ; CPM3 AND CCPPLUS
  2149. ;
  2150.      IF    CPM3
  2151.     MOV    D,H
  2152.     MVI    E,0E8H        ; Point to drive search chain
  2153.     LXI    H,DRVSRC
  2154.     MVI    B,4
  2155.     CALL    MOVE        ; Set the drive search chain
  2156.      ENDIF
  2157. ;
  2158.      IF    NO25TH OR MBBS
  2159.     LXI    H,LFMSG
  2160.     CALL    PRINTL
  2161.     LXI    H,LCDATA
  2162.     CALL    PRINTL        ; Show Sysop who was just on
  2163.      ENDIF            ; NO25TH
  2164. ;
  2165.      IF    NO25TH OR MBBS
  2166.     LXI    H,LCDATA
  2167.     MVI    B,NO25BF
  2168.     CALL    ZEROM        ; Fill with zeros for PRINTL
  2169.     LXI    H,LCFILL
  2170.     LXI    D,LCDATA
  2171.     MVI    B,15
  2172.     CALL    MOVE        ; Put filler msg into LASTCALR for now
  2173.      ENDIF            ; NO25TH OR MBBS
  2174. ;
  2175.      IF    TIMEON
  2176.     LXI    H,TONMSG
  2177.     CALL    PRINTL        ; Show him how long he was on
  2178.     XRA    A
  2179.     LXI    H,TONMSD
  2180.     CALL    DEC8        ; So next message will be 0
  2181.      ENDIF            ; TIMEON
  2182. ;
  2183.      IF    TIMEON OR CLOCK
  2184.     MVI    A,255
  2185.     STA    TCHKFG        ; Show clock not read
  2186.      ENDIF            ; TIMEON OR CLOCK
  2187. ;
  2188.     CALL    CALSUM        ; Give Sysop call summary
  2189. ;
  2190.      IF    B5IM AND HS9600
  2191.     CALL    SET9600
  2192.      ENDIF            ; B5IM AND HS9600
  2193. ;
  2194.      IF    B5IM AND HS4800
  2195.     CALL    SET4800
  2196.      ENDIF            ; B5IM AND HS4800
  2197. ;
  2198.      IF    B5IM AND HS2400
  2199.     CALL    SET2400        ; Talk to the modem at its highest speed
  2200.      ENDIF            ; B5IM AND HS2400
  2201. ;
  2202.      IF    B5IM AND HS1200
  2203.     CALL    SET1200
  2204.      ENDIF            ; B5IM AND HS1200
  2205. ;
  2206.      IF    B5IM AND HS300
  2207.     CALL    SET300
  2208.      ENDIF            ; B5IM AND HS300
  2209. ;
  2210.     CALL    MDINIT        ; Call modem initialization routine
  2211. ;
  2212.     MVI    A,0C3H        ; Clear any traps left from .COM file
  2213.     STA    0
  2214. ;
  2215.      IF    ZCPR3
  2216.     MVI    A,MAXDRV
  2217.     STA    0FE2CH        ; For ZCPR3 use
  2218.     MVI    A,MAXUSR
  2219.     STA    0FE2DH        ; For ZCPR3 use
  2220.      ENDIF            ; ZCPR3
  2221. ;
  2222.     LDA    LCDFLG
  2223.     ORA    A        ; Sysop want the system?
  2224.     JNZ    BEXCPM        ; Yes, exit with bells
  2225. ;
  2226.      IF    CLRSCR
  2227.     CALL    CLEARIT        ; Clear local crt screen
  2228.      ENDIF            ; CLRSCR
  2229. ;
  2230.      IF    COMFILE
  2231.     LDA    OPTION
  2232.     CPI    'E'        ; Execute comfile locally?
  2233.     JNZ    MOTOFF        ; No, continue
  2234.      ENDIF            ; COMFILE
  2235. ;
  2236. ERUN:     IF    COMFILE    AND B5IM
  2237.     CALL    IMQUIT
  2238.      ENDIF            ; COMFILE AND B5IM
  2239. ;
  2240.      IF    COMFILE    AND (NOT B5IM)
  2241.     CALL    MDQUIT        ; Fix modem so won't answer phone
  2242.      ENDIF            ; COMFILE AND NOT B5IM
  2243. ;
  2244.      IF    COMFILE
  2245.     MVI    A,0FFH
  2246.     STA    MDMOFF        ; Turn modem off
  2247.     STA    WRTLOC        ; And write flag
  2248.     MVI    A,'L'-30H
  2249.     STA    MSPEED        ; Some BBS's need this, rest don't care
  2250.     JMP    ANSW        ; Skip this
  2251.      ENDIF            ; COMFILE
  2252. ;
  2253. MOTOFF:     IF    MOTOR
  2254.     CALL    DSKOFF        ; Turn off drives
  2255.      ENDIF            ; MOTOR
  2256. ;.....
  2257. ;
  2258. ;
  2259. ; Await ringing - check local keyboard for CTL-C exit request.    Note:
  2260. ; Must do input via BDOS because CBIOS patches are not done until the
  2261. ; call comes in.
  2262. ;
  2263. RINGWT:    CALL    CONSTAT
  2264.     ORA    A
  2265.     JZ    RINGW1
  2266.     CALL    VCONIN        ; Character typed
  2267.     ANI    7FH        ; Strip parity bit
  2268.     CPI    'C'-40H        ; CTL-C?
  2269.     CZ    USRCHK        ; Check for exit
  2270.     CALL    CKFUNC        ; Check for function keys
  2271.  
  2272. RINGW1:     IF    B5IM
  2273.     CALL    IMRING        ; This routine does it all
  2274.     JZ    RINGWT
  2275.      ENDIF            ; B5IM
  2276. ;
  2277.      IF    NOT B5IM
  2278.     CALL    MDCARCK        ; Carrier?
  2279.     JZ    RINGWT        ; No, keep looping
  2280.      ENDIF            ; NOT B5IM
  2281. ;
  2282. ;
  2283. ;-----------------------------------------------------------------------
  2284. ;              answer routine
  2285. ;
  2286. ANSW:     IF    NOT CPM3
  2287.     CALL    BDCHEK
  2288.      ENDIF            ; NOT CPM3
  2289. ;
  2290.      IF    MOTOR
  2291.     CALL    DSKON        ; Turn on drives
  2292.      ENDIF            ; MOTOR
  2293. ;
  2294.      IF    (NOT USEZCPR) AND (ZCPR2 OR ZCPR3)
  2295.     MVI    A,MAXUSR    ; Reset maximum user area
  2296.     STA    MXUSR        ; Set it in bye
  2297.     INR    A        ; Bump it
  2298.     STA    MAXUSER        ; Set it in ZCPR
  2299.     MVI    A,MAXDRV    ; Reset maximum drive
  2300.     STA    MXDRV
  2301.     DCR    A
  2302.     STA    MAXDRIV
  2303.      ENDIF            ; ZCPR2 OR ZCPR3 AND NOT USEZCPR
  2304. ;
  2305.      IF    CHGPATH        ; If external ZCPR path
  2306.     CALL    REMPAT        ; Set up the secure path for caller
  2307.      ENDIF            ; CHGPATH
  2308. ;
  2309.     XRA    A        ; Make sure line feeds are on again
  2310.     STA    LFEEDS
  2311.     STA    CDOFF        ; Limit for waiting for c/r
  2312.     STA    FKFLAG        ; F-key lead-in flag
  2313. ;
  2314.      IF    ZCPR2 OR ZCPR3    ; Only when using ZCPR w/secure mode
  2315.     STA    WHEEL        ; Answer the phone in non-wheel mode
  2316.      ENDIF            ; ZCPR
  2317. ;
  2318.     MVI    A,TOVALUE    ; Reset timeout count
  2319.     STA    TOVAL
  2320. ;
  2321.      IF    COMFILE
  2322.     LDA    OPTION
  2323.     CPI    'E'
  2324.     JZ    WELCOME        ; Skip this if running local
  2325.      ENDIF            ; COMFILE
  2326. ;
  2327.     LXI    H,CWCAR        ; Get # of attempts
  2328.     INR    M        ; And add one
  2329. ;
  2330.      IF    B5IM
  2331.     JMP    WELCOME        ; Skip the old fashion CR detect method
  2332.      ENDIF            ; B5IM
  2333. ;
  2334.      IF    NOT B5IM
  2335. ANSWA:    CALL    SET300
  2336.     MVI    A,BP300        ; Poke in MSPEED value
  2337.     STA    MSPEED
  2338.     CALL    MDINP        ; Clear garbage characters
  2339.     CALL    MDINP
  2340. ;
  2341. ;
  2342. ; Now test input for baud rate - FIRST, check for 300 baud
  2343. ;
  2344. ANSWB:    CALL    PATCH        ; Patch jump table
  2345.      ENDIF            ; NOT B5IM
  2346. ;
  2347.      IF    PRGRSS AND (NOT    B5IM)
  2348.     LXI    H,MSG30
  2349.     CALL    PRINTL        ; Print locally
  2350.      ENDIF            ; PRGRSS AND NOT B5IM
  2351. ;
  2352.      IF    NOT B5IM
  2353.     CALL    TSTBAUD        ; See if 300 baud
  2354.     JZ    WELCOME        ; Yes, exit
  2355.      ENDIF            ; NOT B5IM
  2356. ;
  2357. ;
  2358. ; Now check for 1200 bps
  2359. ;
  2360.      IF    PRGRSS AND (NOT    B5IM) AND (HS1200 OR HS2400)
  2361.     LXI    H,MSG12
  2362.     CALL    PRINTL        ; Print locally
  2363.      ENDIF            ; PRGRSS AND NOT B5IM
  2364. ;
  2365.      IF    (NOT B5IM) AND (HS1200 OR HS2400)
  2366.     CALL    SET1200        ; Now check 1200 bps
  2367.     JNZ    ANS0
  2368.     MVI    A,BP1200    ; Set the MSPEED pointer
  2369.     STA    MSPEED
  2370.     CALL    MDINP        ; Clear garbage
  2371.     CALL    TSTBAUD        ; Check baud rate
  2372.     JZ    WELCOME
  2373.      ENDIF            ; NOT B5IM
  2374. ;
  2375. ANS0:     IF    PRGRSS AND (NOT    B5IM) AND HS2400
  2376.     LXI    H,MSG24
  2377.     CALL    PRINTL        ; Print locally
  2378.      ENDIF            ; PRGRSS AND NOT B5IM
  2379. ;
  2380.      IF    (NOT B5IM) AND HS2400
  2381.     CALL    SET2400        ; Check for 2400 baud
  2382.     JNZ    BADDO        ; Start over
  2383.     MVI    A,BP2400    ; Set speed indicator
  2384.     STA    MSPEED
  2385.     CALL    MDINP        ; Clear garbage
  2386.     CALL    TSTBAUD        ; Check it
  2387.     JZ    WELCOME
  2388.      ENDIF            ; NOT B5IM AND HS2400
  2389. ;
  2390.      IF    NOT B5IM
  2391. BADDO:    CALL    UNPATCH        ; Restore original jump table
  2392.     JMP    ANSWA        ; Test more - invalid baud rate
  2393.      ENDIF            ; NOT B5IM
  2394. ;.....
  2395. ;
  2396.      IF    CPM3
  2397. DRVSRC:    DB    SDRV1,SDRV2,SDRV3,SDRV4    ; Default drive search chain
  2398. DEFPW:    DB    '        '    ; Default password
  2399. RSXCL:    DB    56        ; Subfunction to clear command line
  2400.                 ; History from HIST RSX
  2401.      ENDIF            ; CPM3
  2402. ;
  2403. ;              end of answer routine
  2404. ;-----------------------------------------------------------------------
  2405. ;
  2406.      IF    NOT CPM3
  2407. BDCHEK:    PUSH    H        ; To make truly universal, (???) this
  2408.     DB    LXIH        ; Program always re-stores the BDOS
  2409. ;
  2410. BDADDR:    DW    0000H        ; Pointer at 6 and 7 set up location for
  2411.     SHLD    6        ; Beginning address of CONSOLX CTL
  2412.     POP    H        ; At every chance.  This replaces the
  2413.     RET            ; WMLOCK & OLDBD as in BYE2 AND BYE3
  2414.      ENDIF            ; NOT CPM3
  2415. ;.....
  2416. ;
  2417. ;
  2418. ;-----------------------------------------------------------------------
  2419. ;
  2420. ; Common routine to check for carrier lost - called from console out
  2421. ;
  2422. CHECK:     IF    MINICK
  2423.     LDA    IOBYTE        ; Get IOBYTE
  2424.     ANI    80H        ; Test for disk update
  2425.     RNZ            ; Busy, wait until done
  2426.      ENDIF            ; MINICK
  2427. ;
  2428.      IF    HBBS OR    MBBS OR    QBBS OR    RBBS
  2429.     LDA    WRTLOC        ; Get write in progress flag
  2430.     ORA    A
  2431.     RNZ            ; Busy, wait until done
  2432.      ENDIF            ; HBBS OR MBBS OR QBBS OR RBBS
  2433. ;
  2434.     LDA    MDMOFF
  2435.     ORA    A        ; Know modem off?
  2436.     RNZ            ; Yes, skip this
  2437.     CALL    CARCK        ; See if carrier still on
  2438.     RNC            ; All ok
  2439. ;
  2440. ;
  2441. ; Carrier is lost, inform Sysop
  2442. ;
  2443.     LXI    SP,STACK    ; Insure valid stack
  2444.     LXI    H,CLMSG        ; Carrier lost message
  2445.     CALL    PRINTL        ; Send this Message
  2446. ;
  2447.      IF    DISKLOG
  2448.     XRA    A
  2449.     STA    BDOSFL
  2450.     LXI    H,CARMSG
  2451.     CALL    WRTMSG        ; Put carrier lost msg in SYS.LOG
  2452.     JMP    LOGOFF
  2453. ;
  2454. DROPIT:
  2455.     LXI    SP,STACK    ; Insure valid stack
  2456.     XRA    A
  2457.     STA    BDOSFL
  2458.     LXI    H,DRPMSG
  2459.     CALL    WRTMSG        ; Put dropped message into log
  2460.      ENDIF            ; DISKLOG
  2461. ;
  2462. ;
  2463. ; Come here to log off a user
  2464. ;
  2465. LOGOFF:    LXI    SP,STACK    ; Ensure valid stack
  2466. ;
  2467.      IF    NOT CPM3
  2468.     CALL    BDCHEK        ; In case carrier lost in LUX
  2469.      ENDIF            ; NOT CPM3
  2470. ;
  2471.     CALL    PATCH        ; We need this so bye is in the loop
  2472. ;
  2473.      IF    TIMEON
  2474.     LDA    TON
  2475.     STA    LCTON        ; Preserve caller's time-on for
  2476.                 ; Entry/exit pgm
  2477.      ENDIF            ; TIMEON
  2478. ;
  2479.     CALL    MDCARCK
  2480.     JZ    LOGOF1        ; Skip over goodby data
  2481. ;
  2482.      IF    NOT BYHANG
  2483.     JMP    LOGOF2        ; Skip goodbye and hangup
  2484.      ENDIF            ; NOT BYHANG
  2485. ;
  2486.      IF    TIMEON AND CLOCK
  2487.     CALL    RMTOS        ; Report users final timeon
  2488.      ENDIF            ; TIMEON AND CLOCK
  2489. ;
  2490.      IF    PRNTGB
  2491.     LXI    H,GBMSG
  2492.     CALL    PRINTB        ; Say goodbye
  2493.      ENDIF            ; PRNTGB
  2494. ;
  2495. LOGOF1:    MVI    A,255
  2496.     STA    MDMOFF        ; Show known loss of carrier
  2497.     STA    TCHKFG        ; Reset time flag
  2498.     CALL    IMDONE        ; Make sure phone is disconnected
  2499. ;
  2500. LOGOF2:     IF    MBBS
  2501.     XRA    A
  2502.     STA    FCB+1        ; Prepare to exit thru MBBS
  2503.     STA    0
  2504.     STA    MXTIME
  2505.     LDA    LCDATA        ; If user was logged in
  2506.     CPI    ' '
  2507.     JNZ    MBBS01        ; User logged in so exit thru MBBS
  2508.      ENDIF            ; MBBS
  2509. ;
  2510.      IF    EXFILE
  2511.     LXI    H,EXTMSG
  2512.     CALL    PRINTL        ; So Sysop knows exit file is executing
  2513.     MVI    C,SETUSR    ; Select user area for EXITFILE
  2514.     MVI    E,EXUSR
  2515.     CALL    BDOS
  2516.     MVI    C,SELDSK    ; Select default drive for EXITFILE
  2517.     MVI    E,EXDRV-'A'
  2518.     CALL    BDOS
  2519.     CALL    LODEX
  2520.     CALL    100H        ; EXITFIL was loaded ok, so run it
  2521.      ENDIF            ; EXFILE
  2522. ;
  2523.      IF    EXFILE AND (NOT    BYHANG)
  2524.     CALL    MDCARCK        ; Still have carrier after EXFILE ran?
  2525.     JZ    LOGOF3        ; No, skip this
  2526.      ENDIF            ; EXFILE AND NOT BYHANG
  2527. ;
  2528.      IF    CLOCK AND TIMEON AND EXFILE AND    (NOT BYHANG)
  2529.     CALL    RMTOS        ; Print time data
  2530.      ENDIF            ; CLOCK.....
  2531. ;
  2532.      IF    PRNTGB AND EXFILE AND (NOT BYHANG)
  2533.     LXI    H,GBMSG
  2534.     CALL    PRINTB        ; Pring goodbye
  2535.      ENDIF            ; PRNTGB...
  2536. ;
  2537. LOGOF3:
  2538.      IF    EXFIL1 OR EXFIL2
  2539.     LDA    MSPEED        ; Flag set by HBBS
  2540.      ENDIF            ; EXFIL1 OR EXFIL2
  2541. ;
  2542.      IF    ANYLOS AND (EXFIL1 OR EXFIL2)
  2543.     CPI    44H        ; Time to just backup the files?
  2544.     JZ    ARCIVE        ; Yes, go do it
  2545.      ENDIF            ; ANYLOS AND (EXFILE1 OR EXFIL2)
  2546. ;
  2547.      IF    EXFIL1 OR EXFIL2
  2548.     CPI    66H        ; Time to archive??
  2549.     JZ    ARCIVE        ; Yes, go do it
  2550.      ENDIF            ; EXFIL1 OR EXFIL2
  2551. ;
  2552.     JMP    PREOFF        ; Prepare for next caller
  2553. ;
  2554.      IF    EXFIL1 OR EXFIL2
  2555. ARCIVE:    CALL    MDINIT        ; Hang up and initialize modem
  2556.     CALL    IMQUIT        ; Set offhook among other things
  2557.     MVI    A,0FFH
  2558.     STA    MDMOFF        ; Blank the modem for now
  2559.      ENDIF            ; EXFIL1 OR EXFIL2
  2560. ;
  2561. ARCIVE1:
  2562.      IF    EXFIL1
  2563.     LXI    H,EX1MSG
  2564.     CALL    PRINTL        ; So Sysop knows exit file 1 is executing
  2565.     LXI    SP,STACK    ; Insure valid stack
  2566.     CALL    SETDU
  2567.     CALL    LODEX1
  2568.     CALL    100H        ; Exit file 2 was loaded ok, so run it
  2569.      ENDIF            ; EXFIL1
  2570. ;
  2571.      IF    EXFIL2
  2572.     LDA    MSPEED
  2573.      ENDIF            ; EXFIL2
  2574. ;
  2575.      IF    EXFIL2 AND ANYLOS
  2576.     CPI    44H        ; Just doing a backup this time?
  2577.     JZ    ARCIVE2        ; If yes, exit
  2578.      ENDIF            ; EXFIL2 AND ANYLOS
  2579. ;
  2580.      IF    EXFIL2
  2581.     LXI    H,EX2MSG
  2582.     CALL    PRINTL
  2583.     LXI    SP,STACK    ; Insure valid stack
  2584.      ENDIF            ; EXFIL2
  2585. ;
  2586.      IF    EXFIL2 AND NOT RAMDSK
  2587.     CALL    LODEX2
  2588.     JNZ    ARCIVE2
  2589.     CALL    100H
  2590.      ENDIF            ; EXFIL2 AND NOT RAMDSK
  2591. ;
  2592.      IF    EXFIL2 AND RAMDSK
  2593.     CALL    SETDU1
  2594.     CALL    LODEX2
  2595.     JNZ    ARCIVE2
  2596.     CALL    100H
  2597.     LXI    H,EX3MSG
  2598.     CALL    PRINTL
  2599.     LXI    SP,STACK    ; Insure valid stack
  2600.     CALL    LODEX3        ; Copy files back to the original D/U
  2601.     CALL    100H
  2602.      ENDIF            ; EXFIL2 AND RAMDSK
  2603. ;
  2604. ARCIVE2:MVI    A,07FH        ; Reset the flag for no maintenance
  2605.     STA    MSPEED
  2606.     JMP    PREOFF        ; Prepare for next caller
  2607. ;.....
  2608. ;
  2609. ;
  2610.      IF    EXFIL1
  2611. SETDU:    MVI    C,SETUSR    ; Select set user BDOS call
  2612.     MVI    E,EXUSR        ; Select user area same as for EXIT file
  2613.     CALL    BDOS
  2614.     MVI    C,SELDSK    ; Select set drive BDOS call
  2615.     MVI    E,EXDRV-'A'    ; Select drive same as for EXIT file
  2616.     CALL    BDOS
  2617.     RET
  2618.      ENDIF            ; EXFIL1
  2619. ;.....
  2620. ;
  2621. ;
  2622.      IF    EXFIL2 AND RAMDSK
  2623. SETDU1:    MVI    C,SETUSR    ; Select set user BDOS call
  2624.     MVI    E,BCKUPUS    ; <<== user area for backup files
  2625.     CALL    BDOS
  2626.     MVI    C,SELDSK    ; Select drive used for backup files
  2627.     MVI    E,BCKUPDR-'A'    ; <<== drive for backup files
  2628.     CALL    BDOS
  2629.     RET
  2630.      ENDIF            ; EXFIL2 AND RAMDSK
  2631. ;.....
  2632. ;
  2633. ;
  2634. ;-----------------------------------------------------------------------
  2635. ;
  2636. ; Function key routines
  2637. ;
  2638. CKFUNC:     IF    LEADIN
  2639.     PUSH    PSW        ; Save character
  2640.     CPI    LEADKY        ; Lead-in key typed?
  2641.     JNZ    FKEY1        ; No, see if already typed
  2642.     MVI    A,0FFH        ; Yes, set the lead-in flag
  2643.     STA    FKFLAG
  2644.     POP    PSW        ; Reset stack
  2645.     MVI    A,07FH        ; DEL for buffer
  2646.     RET
  2647. ;
  2648. FKEY1:    LDA    FKFLAG
  2649.     ORA    A        ; Lead-in already typed?
  2650.     JZ    FKEXIT        ; No, exit
  2651.     XRA    A        ; Yes, reset the flag
  2652.     STA    FKFLAG
  2653.     POP    PSW        ; Get char back
  2654.     ANI    1FH        ; Make it a ctrl character
  2655.      ENDIF            ; LEADIN
  2656. ;
  2657.      IF    B5IM AND (NOT NOATA)
  2658.     MOV    B,A
  2659.     PUSH    B        ; Save the character
  2660.     CALL    MDCARCK        ; Carrier?
  2661.     POP    B
  2662.     MOV    A,B
  2663.     JNZ    ANSKNO        ; Can't do this with carrier
  2664.     CPI    ANSKEY        ; Sysop wants BYE to answer the phone
  2665.     CZ    IMRIN2        ; So do it, IMRIN2 will restore the call
  2666. ;
  2667. ANSKNO:     ENDIF            ; B5IM AND NOT NOATA
  2668. ;
  2669.      IF    NO25TH OR MBBS
  2670.     CPI    WHOKEY
  2671.     JZ    WHOSIT        ; Display last caller data
  2672.      ENDIF            ; NO25TH OR MBBS
  2673. ;
  2674.      IF    TIMEON
  2675.     CPI    TIMEKEY
  2676.     JZ    DTIME        ; Case running local, allow debug
  2677.      ENDIF            ; TIMEON
  2678. ;
  2679.     CPI    ZCREEN
  2680.     JZ    CLEARIT        ; Sysop wants to clear his screen
  2681.     CPI    BELLKEY
  2682.     JZ    BELLTOG        ; Toggle bell on/off
  2683. ;
  2684.      IF    DISKLOG
  2685.     CPI    LOGKEY
  2686.     JZ    LOGFLP        ; Toggle disk log on/off
  2687.      ENDIF            ; DISKLOG
  2688.     MOV    B,A
  2689.     PUSH    B
  2690.     CALL    MDCARCK        ; See if carrier is on, because
  2691.     POP    B
  2692.     MOV    A,B
  2693.     RZ            ; The following keys are useless without
  2694.                 ; It.
  2695.     CPI    LCKEY
  2696.     JZ    LCDOIT        ; Sysop wants the system when caller is thru
  2697.     CPI    ULTKEY
  2698.     JZ    ULTIME        ; Give current user unlimited timeon
  2699.     CPI    BLNKKEY        ; Turn off caller's output for a moment?
  2700.     JZ    BLNKTOG        ; (this is a toggle)
  2701.     CPI    SYSDKEY
  2702.     JZ    SYSDOWN        ; Tell caller system is going down
  2703.     CPI    TWITKEY
  2704.     PUSH    PSW
  2705.     CZ    IMDONE        ; Hang up on the twit
  2706.     POP    PSW
  2707. ;
  2708.      IF    NOT DISKLOG
  2709.     JZ    LOGOFF        ; Then check for exit file
  2710.      ENDIF            ; NOT DISKLOG
  2711. ;
  2712.      IF    DISKLOG
  2713.     JZ    DROPIT        ; Hang up on the twit
  2714.      ENDIF            ; DISKLOG
  2715. ;
  2716.     CPI    MSGKEY
  2717.     RNZ
  2718. ;
  2719. ;
  2720. ; Message from Sysop
  2721. ;
  2722.     LXI    H,MFSMSG    ; SYSOP message
  2723.     CALL    PRINTB        ; Tell caller you want to say something
  2724. ;
  2725. SYSML:    CALL    VCONIN        ; Get key from Sysop
  2726.     CPI    XITKEY        ; If exit key, exit loop
  2727.     JZ    SYSMX
  2728.     MOV    C,A        ; Else echo to console and modem
  2729.     PUSH    PSW
  2730.     CALL    MOUTPUT
  2731.     POP    PSW
  2732.     CPI    'H'-'@'        ; If BS, do BS/SP/BS
  2733.     JZ    SYSMBS
  2734.     CPI    CR        ; If CR, do CRLF
  2735.     JZ    SYSMCR
  2736.     JMP    SYSML
  2737. ;
  2738. SYSMCR:    MVI    C,LF        ; Do linefeed after CR
  2739.     JMP    SYSECH
  2740. ;
  2741. SYSMBS:    MVI    C,' '
  2742.     CALL    MOUTPUT
  2743.     MVI    C,'H'-'@'
  2744. ;
  2745. SYSECH:    CALL    MOUTPUT
  2746.     JMP    SYSML
  2747. ;
  2748. SYSMX:    MVI    C,CR        ; Do crlf
  2749.     CALL    MOUTPUT
  2750.     MVI    C,LF
  2751.     CALL    MOUTPUT
  2752.     CALL    MDINP
  2753.     CALL    MDINP        ; Clear caller junk first
  2754.     MVI    A,CR        ; Return with c/r for buffer
  2755.     RET
  2756. ;.....
  2757. ;
  2758. ;
  2759. ; System Going down
  2760. ;
  2761. SYSDOWN:LXI    H,SGDMSG    ; System going down message
  2762.     CALL    PRINTB        ; Send this message
  2763. ;
  2764.      IF    TIMEON
  2765.     CALL    TCHECK        ; Calculate current time-on-system
  2766.     LDA    TON        ; Fetch it
  2767.     ADI    DOWNMIN        ; Give him this much longer
  2768.     STA    MXTIME        ; And BYE will log him off
  2769.      ENDIF            ; TIMEON
  2770. ;
  2771.     MVI    A,CR        ; Return with CR for buffer
  2772.     RET
  2773. ;.....
  2774. ;
  2775. LCDOIT:    LXI    H,LCDMSG
  2776.     CALL    PRINTL        ; Show sysop it's flagged
  2777.     MVI    A,07FH
  2778.     STA    LCDFLG        ; Set the flag
  2779.     RET
  2780. ;
  2781. ;
  2782. ; Toggle bell
  2783. ;
  2784. BELLTOG:LDA    BELLON        ; Get bell status
  2785.     ORA    A
  2786.     MVI    A,0FFH        ; Prepare for on
  2787.     LXI    H,BELMON
  2788.     JZ    BELLT1        ; Go turn bell on
  2789.     XRA    A        ; Else turn bell off
  2790.     LXI    H,BELMOFF
  2791. ;
  2792. BELLT1:    STA    BELLON
  2793. ;
  2794.      IF    LMBELL
  2795.     ORA    A
  2796.     JZ    BELLT2        ; We will toggle whatever we just stored
  2797.     XRA    A
  2798.     JMP    BELLT3
  2799. BELLT2:    MVI    A,0FFH
  2800. ;
  2801. BELLT3:    STA    KILBEL        ; For MBBS/RBBS etal
  2802.      ENDIF            ; LMBELL
  2803. ;
  2804.     CALL    PRINTL        ; Print status message locally
  2805.     MVI    A,07FH        ; DEL for buffer
  2806.     RET
  2807. ;.....
  2808. ;
  2809. ;
  2810. ULTIME:    XRA    A
  2811.     STA    MXTIME        ; Give current caller unlimited time
  2812.     MVI    A,0FFH
  2813.     STA    LCPTR        ; Also enable all the flag bits
  2814.     LXI    H,ULTMSG
  2815.     CALL    PRINTL        ; So Sysop will know
  2816.     MVI    A,CR        ; C/R for buffer
  2817.     RET
  2818. ;
  2819. ;
  2820. ; Toggle blankout
  2821. ;
  2822. BLNKTOG:LDA    MDMOFF
  2823.     ORA    A        ; If zero, make 0FFH
  2824. ;
  2825.      IF    ZCPR2 OR ZCPR3
  2826.     JZ    DUSET        ; Store Sysops d/u values
  2827.     CALL    RETDU        ; Restore normal d/u values
  2828.      ENDIF            ; ZCPR2 OR ZCPR3
  2829. ;
  2830.      IF    (NOT ZCPR2) AND    (NOT ZCPR3)
  2831.     MVI    A,0FFH        ; (we do not use CMA, because MDMOFF
  2832.     LXI    H,SCRMOFF
  2833.     JZ    BLNKT1        ; Could equal a different value like 1)
  2834.     XRA    A        ; If not zero, make it zero
  2835.     LXI    H,SCRMON
  2836.      ENDIF            ; NOT ZCPR2 AND NOT ZCPR3
  2837. ;
  2838. BLNKT1:    STA    MDMOFF
  2839. ;
  2840.      IF    ZCPR2 OR ZCPR3
  2841.     STA    WHEEL        ; Set wheel for Sysop
  2842.      ENDIF            ; ZCPR2 OR ZCPR3
  2843. ;
  2844.     CALL    PRINTL
  2845.     MVI    A,CR        ; Return with cr for buffer
  2846.     RET
  2847. ;.....
  2848. ;
  2849. ;
  2850. DUSET:     IF    ZCPR3
  2851.     MVI    A,SYSUSR    ; Sysops maxuser
  2852.     STA    0FE2DH        ; To low memory
  2853.     MVI    A,SYSDRV    ; Sysops maxdriv
  2854.     STA    0FE2CH        ; To low memory
  2855.      ENDIF            ; ZCPR3
  2856. ;
  2857.      IF    ZCPR2 OR ZCPR3
  2858.     LDA    LCPTR
  2859.     STA    CDOFF        ; Save flag register
  2860.      ENDIF            ; ZCPR2 OR ZCPR3
  2861. ;
  2862.  
  2863.      IF    CHGPATH
  2864.     CALL    SYSPAT        ; Setup Sysops path
  2865.      ENDIF            ; CHGPATH
  2866. ;
  2867.      IF    ZCPR2 OR ZCPR3
  2868.     MVI    A,0FFH        ; Wheel on, modem off
  2869.     STA    LCPTR        ; Enable all options
  2870.     LXI    H,SCRMOFF    ; Correct message
  2871.     JMP    BLNKT1
  2872. ;
  2873. RETDU:    LDA    MXUSR        ; Callers allowed maxuser
  2874.     INR    A
  2875.     STA    MAXUSER        ; To low memory
  2876.     LDA    MXDRV        ; Callers allowed maxdriv
  2877.     DCR    A
  2878.     STA    MAXDRIV        ; To low memory
  2879.     LDA    CDOFF
  2880.     STA    LCPTR        ; Restore flag register
  2881.      ENDIF            ; ZCPR2 OR ZCPR3
  2882. ;
  2883.      IF    CHGPATH
  2884.     CALL    REMPAT        ; Setup remote users path
  2885.      ENDIF            ; CHGPATH
  2886. ;
  2887.      IF    ZCPR2 OR ZCPR3
  2888.     XRA    A        ; Wheel off, modem on
  2889.     LXI    H,SCRMON    ; Correct message
  2890.     RET
  2891.      ENDIF            ; ZCPR2 OR ZCPR3
  2892. ;
  2893.      IF    NO25TH OR MBBS
  2894. WHOSIT:    LXI    H,CRMSG        ; Turn up a fresh line
  2895.     CALL    PRINTL
  2896.     LXI    H,LCHEAD    ; Print customized header (if any)
  2897.     CALL    PRINTL
  2898.     LXI    H,LCDATA
  2899.     CALL    PRINTL        ; Show Sysop lastcaller data
  2900.     LXI    H,CRMSG
  2901.     CALL    PRINTL        ; New line for neatness
  2902.     MVI    A,07FH        ; DEL for buffer
  2903.     RET
  2904.      ENDIF            ; NO25TH OR MBBS
  2905. ;.....
  2906. ;
  2907. ;
  2908.      IF    TIMEON
  2909. DTIME:    CALL    TCHECK        ; Read time
  2910.     LXI    H,LFMSG
  2911.     CALL    PRINTL
  2912.     LDA    MXTIME
  2913.     ORA    A
  2914.     JZ    DTIME1        ; Unlimited time
  2915.     LXI    H,TLNMSG    ; Else print time-left...
  2916.      ENDIF            ; TIMEON
  2917. ;
  2918.      IF    TIMEON AND (ZCPR2 OR ZCPR3)
  2919.     LDA    WHEEL
  2920.     ORA    A
  2921.     JNZ    DTIME1        ; Unlimited time
  2922.      ENDIF            ; TIMEON AND ZCPR2 OR ZCPR3
  2923. ;
  2924.      IF    TIMEON
  2925.     JMP    DTIME2
  2926. DTIME1:    LXI    H,TONMSG
  2927. DTIME2:    CALL    PRINTL        ; Print time-on or time-left-on system
  2928.     LXI    H,LFMSG
  2929.     CALL    PRINTL
  2930.     MVI    A,07FH        ; DEL for buffer
  2931.     RET
  2932.      ENDIF            ; TIMEON
  2933. ;.....
  2934. ;
  2935. ;
  2936. CLEARIT:LXI    H,CLRSEQ
  2937.     CALL    PRINTL        ; Clear local screen
  2938.     MVI    A,LF
  2939.     RET            ; LF for buffer
  2940. ;
  2941.      IF    LEADIN
  2942. FKEXIT:    POP    PSW
  2943.     RET
  2944.      ENDIF            ; LEADIN
  2945. ;.....
  2946. ;
  2947. ;          end of function key routines
  2948. ;------------------------------------------------------------------------
  2949. ;
  2950. ; BYE's BDOS interceptor (See BYE5.DOC for more information)
  2951. ;
  2952. REALBD:    JMP    0        ; Will be filled in to pnt to REAL BDOS
  2953. ;
  2954. BYERSX:
  2955. ;
  2956.      IF    DISKLOG
  2957.     MOV    A,C
  2958.     CPI    15        ; Is it file open?
  2959.     JNZ    NOT15B
  2960.     LDA    LOGTOG        ; Are we to toggle log file?
  2961.     ORA    A
  2962.     JZ    NOT15
  2963.     PUSH    D
  2964.     CALL    LOGFLP        ; Open/close log file
  2965.     POP    D
  2966.     XRA    A
  2967.     STA    LOGTOG        ; Reset toggle
  2968.     JMP    NOT15A
  2969. NOT15:
  2970.     LDA    DSKLOG        ; Get log status
  2971.     ORA    A
  2972.     JZ    NOT15A        ; Skip if not open
  2973.     PUSH    D        ; Save callers FCB address
  2974.     CALL    SETLUS        ; Set up the log environment
  2975.     LXI    D,LOGFCB
  2976.     MVI    C,16
  2977.     CALL    REALBD        ; Update directory for log file
  2978.     CALL    CLRLUS        ; Back to normal environment
  2979.     POP    D        ; Restore callers FCB address
  2980. NOT15A:
  2981.     MVI    C,15        ; Restore open function code
  2982. NOT15B:
  2983.     CALL    STBDOS        ; Set bdos call in progress flag
  2984.     LDA    DSKLOG
  2985.     ORA    A        ; Is log on?
  2986.     MOV    A,C        ; Get the function
  2987.     JZ    NOLOGTEST    ; Skip tests if log is off
  2988.      ENDIF            ; DISKLOG
  2989. ;
  2990.      IF    DISKLOG    AND CPM3
  2991.     CPI    98        ; Is it free blocks (only called by CCP)
  2992.     JNZ    NOT98
  2993.     CALL    SETLUS        ; Set up log file environment
  2994.     LXI    D,LOGFCB
  2995.     MVI    C,16
  2996.     CALL    REALBD        ; Update directory entry for file
  2997.     CALL    CLRLUS        ; Return to normal environment
  2998.     MVI    C,98
  2999.     JMP    REALBD        ; And on to BDOS
  3000. NOT98:
  3001.     CPI    13        ; Is it disk reset?
  3002.     JNZ    NOT13
  3003.     LXI    D,80H
  3004.     MVI    C,26
  3005.     CALL    REALBD        ; First set DMA to default
  3006.     MVI    E,0
  3007.     MVI    C,14
  3008.     CALL    REALBD        ; Next select disk A:
  3009.     LXI    D,0FFFFH    ; Reset all drives
  3010.     MVI    C,37
  3011.     MOV    A,C
  3012. NOT13:
  3013.     CPI    37        ; Is it reset drives?
  3014.     JNZ    NOT37
  3015.     MOV    A,E
  3016.     ANI    0FEH        ; Do not reset drive A:
  3017.     MOV    E,A
  3018.     JMP    REALBD
  3019. NOT37:
  3020.      ENDIF            ; DISKLOG AND CPM3
  3021. ;
  3022.      IF    DISKLOG    AND (NOT CPM3)
  3023.     CPI    13        ; Is it Disk reset?
  3024.     JNZ    NOT13
  3025.     CALL    SETLUS        ; Set up log file environment
  3026.     LXI    D,LOGFCB
  3027.     MVI    C,16
  3028.     CALL    REALBD        ; Update directory entry for file
  3029.     CALL    CLRLUS        ; Return to normal environment
  3030.     MVI    C,13
  3031.     JMP    REALBD        ; And on to BDOS
  3032. NOT13:
  3033.      ENDIF            ; DISKLOG AND NOT CPM3
  3034. ;
  3035.      IF    DISKLOG
  3036.     CPI    1        ; Console input?
  3037.     JNZ    NOT1
  3038.     CALL    REALBD        ; Get the char
  3039.     JMP    HARDWR        ; And on to log write routine
  3040. NOT1:
  3041.     CPI    6        ; Direct console I/O?
  3042.     JNZ    NOT6
  3043.     MOV    A,E        ; Get direct console I/O function
  3044.     INR    A        ; Only intercept 0FFh
  3045.     JNZ    REALBD
  3046.     CALL    REALBD        ; Get the char
  3047.     ORA    A        ; Anything there?
  3048.     RZ            ; Back to caller if nothing
  3049. ;
  3050. HARDWR:                ; Save char in log file
  3051.     CALL    STKNEW        ; Switch to local stack
  3052.     PUSH    PSW
  3053.     ANI    7FH
  3054.     CALL    WRBYTE        ; Write the character
  3055.     CPI    CR        ; Is it return?
  3056.     JNZ    HARRET
  3057.     MVI    A,LF        ; If CR, must also put LF in log file
  3058.     CALL    WRBYTE
  3059. HARRET:
  3060.     POP    PSW        ; Restore original character
  3061.     RET
  3062. ;
  3063. NOT6:
  3064.     CPI    10        ; Is it input console buffer?
  3065.     JNZ    NOLOGTEST
  3066.     PUSH    D        ; Save address of buffer
  3067.     CALL    REALBD        ; Fill the buffer
  3068.     POP    H
  3069.     INX    H        ; Point to length
  3070.     MOV    A,M        ; Get length
  3071.     ORA    A
  3072.     RZ            ; Return if nothing there
  3073.     CALL    STKNEW        ; Switch to local stack
  3074.     PUSH    H
  3075.     CALL    WRTTIM        ; Time stamp the line
  3076.     POP    H
  3077.     MOV    B,M        ; Get length
  3078.     INX    H
  3079. B10LOP:                ; Loop to write the log file
  3080.     MOV    A,M
  3081.     CALL    WRBYTE        ; Send a byte to log
  3082.     INX    H
  3083.     DCR    B
  3084.     JNZ    B10LOP
  3085.     JMP    WRCRLF        ; Exit with final CRLF
  3086. ;
  3087. NOLOGTEST:
  3088.      ENDIF            ; DISKLOG
  3089. ;
  3090.      IF    DISKLOG    AND (NOT CPM3)
  3091.     CPI    26        ; Is it set DMA?
  3092.     JNZ    NOTDMA
  3093.     XCHG
  3094.     SHLD    OLDDMA        ; Keep a copy of current DMA
  3095.     XCHG
  3096.     JMP    REALBD
  3097. NOTDMA:
  3098.      ENDIF            ; DISKLOG AND NOT CPM3
  3099. ;
  3100.     MOV    A,C        ; BDOS doesn't care if we use 'A'
  3101.     CPI    32        ; Is it USER command?
  3102.     JZ    TSTUSR
  3103.     CPI    LOCMD        ; Is it less than lowest BYE command?
  3104.     JC    REALBD
  3105.     CPI    HICMD+1        ; Is it higher than the highest BYE
  3106.                 ; Command?
  3107.     JNC    REALBD
  3108. ;
  3109. ;
  3110. ; Ok, it's one of our commands, Let's handle it
  3111. ;
  3112.     SUI    LOCMD        ; Commands now range from 0..highcommand
  3113.     PUSH    D
  3114.     MOV    E,A        ; Save copy of command in A
  3115.     ADD    A        ; A=2*A
  3116.     ADD    E        ; A=3*A  3x offset for each vector
  3117.     MOV    E,A        ; Make command offset 16-bits
  3118.     MVI    D,0        ; DE = offset into table
  3119.     LXI    H,RSXTBL
  3120.     DAD    D        ; HL points to entry in RSXTBL now
  3121.     POP    D
  3122.     MOV    A,E        ; Generalized movement of input data
  3123.     PCHL            ; Jump to entry in rsx table
  3124. ;
  3125. RSXTBL:    JMP    MDINST        ; Get modem input status         61
  3126.     JMP    MDOUTST        ; Get modem output status         62
  3127.     JMP    MDOUTP        ; Output character to modem         63
  3128.     JMP    MDINP        ; Input character from modem         64
  3129.     JMP    MDCARCK        ; Get modem carrier status         65
  3130.     JMP    CONSTAT        ; Get console input status         66
  3131.     JMP    CONIN        ; Get console input character         67
  3132.     JMP    RCONOT        ; Send character to console         68
  3133.     JMP    RMXDRV        ; Set/get maximum drive          69
  3134.     JMP    RMXUSR        ; Set/get maximum user area         70
  3135.     JMP    RMTOUT        ; Set/get timeout value          71
  3136.     JMP    RMNULL        ; Set/get nulls              72
  3137.     JMP    RMULC        ; Set upper/lower case flag         73
  3138.     JMP    RMLFM        ; Set line feed mask             74
  3139.     JMP    RMWRT        ; Set/get wrtloc flag             75
  3140.     JMP    RMHDR        ; Set/get hardon flag             76
  3141.     JMP    RMOFF        ; Set/get mdmoff flag             77
  3142.     JMP    RMBELL        ; Set/get console bell flag         78
  3143.     JMP    RMRTC        ; Call TCHECK & return TON & RTC address 79
  3144.     JMP    RMLCBF        ; Return LC buffer address         80
  3145.     JMP    RMMXT        ; Set/get maximum time on system     81
  3146.     JMP    RMLTIM        ; Set login time             82
  3147.     JMP    RMTOS        ; Print TOS message to caller/Sysop     83
  3148.     JMP    SRUDEF        ; SubRoutine U, the user DEFines     84
  3149.     JMP    RMXLCP        ; Set/get LCPTR.  When a user is logged  85
  3150.                 ; In, LCPTR is a bit mapped status
  3151.                 ; Register.  If no user is logged in,
  3152.                 ; LCPTR contains previous callers Timeon
  3153.     JMP    LOGSTAT        ; Set/get log open status         86
  3154.     JMP    LOGPUT        ; Write a string into log file         87
  3155.     JMP    IMDONE        ; Hangup phone and return to calling pgm 88
  3156. ;
  3157. ;
  3158. ; BYE existance test
  3159. ;
  3160. TSTUSR:    MOV    A,E        ; Get E register value
  3161.     CPI    241        ; Special call for extended BDOS?
  3162.     JNZ    REALBD        ; No, was for normal BDOS
  3163.     MVI    A,77        ; Was for us, say we're here
  3164.     RET
  3165. ;
  3166. RCONOT:    MOV    C,E        ; Get byte to send
  3167.     JMP    VCONOUT
  3168. ;
  3169. RMXDRV:    LXI    H,MXDRV        ; Set/get maximum drive
  3170. ;;;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  3171.   shld 0010h
  3172.     JMP    SETGET1
  3173. ;
  3174. RMXUSR:    LXI    H,MXUSR        ; Set/get maximum user area
  3175. ;;;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  3176.   shld 0012h
  3177.     
  3178.     JMP    SETGET1
  3179. ;
  3180. RMNULL:    LXI    H,NULLS        ; Set/get nulls
  3181.     JMP    SETGET1
  3182. ;
  3183. RMTOUT:    LXI    H,TOVAL        ; Set/get timeout value
  3184.     JMP    SETGET1
  3185. ;
  3186. RMULC:    LXI    H,ULCSW        ; Set/get upper-lowercase flag
  3187.     JMP    SETGET1
  3188. ;
  3189. RMLFM:    LXI    H,LFEEDS    ; Set/get line-feed mask
  3190.     JMP    SETGET2
  3191. ;
  3192. RMHDR:    LXI    H,HARDON    ; Set/get hard-log
  3193.     JMP    SETGET2
  3194. ;
  3195. RMWRT:    LXI    H,WRTLOC    ; Set/get RBBS WRTLOC flag
  3196.     JMP    SETGET2
  3197. ;
  3198. RMOFF:    LXI    H,MDMOFF    ; Set/get modem-off flag
  3199.     JMP    SETGET2
  3200. ;
  3201. RMBELL:    LXI    H,BELLON    ; Set/get console-bell flag
  3202.     JMP    SETGET2
  3203. ;
  3204. RMRTC:     IF    TIMEON
  3205.     CALL    TCHECK        ; TCHECK returns TON with/without clock
  3206.      ENDIF            ; TIMEON
  3207. ;
  3208.      IF    CLOCK AND (NOT TIMEON)
  3209.     CALL    TIME        ; In case caller just wants time
  3210.      ENDIF            ; CLOCK AND NOT TIMEON
  3211. ;
  3212.     LDA    TON
  3213.     LXI    H,RTCBUF    ; Return address of RTC buffer
  3214.     RET
  3215. ;
  3216. RMXLCP:    LXI    H,LCPTR        ; Address of LCPTR
  3217.     INR    A        ; If (255), return current value
  3218.     JZ    SGET1        ; So do it
  3219.     MOV    M,D        ; If (A)<>255, store (D) in LCPTR (0-255)
  3220.     RET
  3221. ;
  3222. RMLCBF:    LXI    H,LCDATA    ; Return address of LC data buffer
  3223.     RET
  3224. ;
  3225. RMMXT:    LXI    H,MXTIME    ; Set/get maximum time allowed on system
  3226.     JMP    SETGET1
  3227. ;
  3228. RMLTIM:    STA    LMIN        ; Set login time
  3229.     MOV    A,D
  3230.     STA    LHOUR
  3231.     RET
  3232. ;
  3233. RMTOS:     IF    TIMEON        ; Only do this if we can..otherwise RET
  3234.     CALL    TCHECK        ; Set time in message
  3235.     LDA    MXTIME
  3236.     ORA    A
  3237.     JZ    RMTOS1        ; Unlimited time
  3238.     LXI    H,TLNMSG    ; Else print time-left...
  3239.      ENDIF            ; TIMEON
  3240. ;
  3241.      IF    TIMEON AND (ZCPR2 OR ZCPR3)
  3242.     LDA    WHEEL
  3243.     ORA    A
  3244.     JNZ    RMTOS1        ; Unlimited time
  3245.      ENDIF            ; TIMEON AND ZCPR2 OR ZCPR3
  3246. ;
  3247.      IF    TIMEON
  3248.     JMP    RMTOS2
  3249. RMTOS1:    LXI    H,TONMSG
  3250. RMTOS2:    CALL    PRINTB        ; Print it
  3251.      ENDIF            ; TIMEON
  3252.     RET
  3253. ;.....
  3254. ;
  3255. ;
  3256. ; SETGET1 - if A=0..254 then poke value with A
  3257. ;      - if A=255    then return with current value
  3258. ;
  3259. SETGET1:INR    A        ; If A was 255, Z flag will now be set
  3260.     JZ    SGET1        ; We want to get current value
  3261.     DCR    A
  3262.     MOV    M,A        ; No, set current value
  3263. ;;;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  3264.   sta 0014h
  3265.     RET
  3266. ;
  3267. SGET1:    MOV    A,M        ; Return with current value in A
  3268. ;;;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  3269.   sta 0015h
  3270.     RET
  3271. ;.....
  3272. ;
  3273. ;
  3274. ; SETGET2 - if A=0    then poke value with 0
  3275. ;      - if A=1    then poke value with 255
  3276. ;      - if A=255    then return with current value
  3277. ;
  3278. SETGET2:INR    A        ; If A was 255, Z flag will now be set
  3279.     JZ    SGET1        ; We want to get current value
  3280.     DCR    A        ; If it's zero, then poke a zero
  3281.     JZ    SGET2W
  3282.     MVI    A,255        ; Else poke a 255
  3283. ;
  3284. SGET2W:    MOV    M,A
  3285.     RET
  3286. ;.....
  3287. ;
  3288. ;
  3289. ;-----------------------------------------------------------------------
  3290. ;
  3291. CONIN:    PUSH    B
  3292.     PUSH    D
  3293.     PUSH    H
  3294.     CALL    VCONIN
  3295.     CALL    CKFUNC
  3296.     POP    H
  3297.     POP    D
  3298.     POP    B
  3299.     RET
  3300. ;.....
  3301. ;
  3302. ;
  3303. ;-----------------------------------------------------------------------
  3304. ;
  3305. CONOUT:    PUSH    B
  3306.     PUSH    D
  3307.     PUSH    H
  3308.     MOV    A,C
  3309.     ANI    07FH
  3310.     CNZ    VCONOUT        ; Don't send nulls to local console
  3311.     POP    H
  3312.     POP    D
  3313.     POP    B
  3314.     RET
  3315. ;.....
  3316. ;
  3317. ;
  3318. ;-----------------------------------------------------------------------
  3319. ;
  3320. CONSTAT:PUSH    B
  3321.     PUSH    D
  3322.     PUSH    H
  3323.     CALL    VCONSTAT
  3324.     POP    H
  3325.     POP    D
  3326.     POP    B
  3327.     RET
  3328. ;.....
  3329. ;
  3330. ;
  3331. ;-----------------------------------------------------------------------
  3332. ;
  3333. ; .1 sec delay routine
  3334. ;
  3335. DELAY:    PUSH    B
  3336.     LXI    B,4167*MHZ    ; Timing constant * clock MHz
  3337. ;
  3338. DELAY1:    DCX    B
  3339.     MOV    A,B
  3340.     ORA    C
  3341.     JNZ    DELAY1
  3342.     POP    B
  3343.     RET
  3344. ;.....
  3345. ;
  3346. ;
  3347. ; 1 millisecond delay routine
  3348. ;
  3349. KDELAY:    PUSH    B
  3350.     LXI    B,42*MHZ    ; Timing constant * clock MHz
  3351.     JMP    DELAY1
  3352. ;.....
  3353. ;
  3354. ;
  3355. ;-----------------------------------------------------------------------
  3356. ;
  3357. ; Here to exit to CP/M, first reset the Port/Modem to default status
  3358. ;
  3359. BEXCPM:    LXI    H,BELMSG    ; Sysop typed LCKEY so alert him that
  3360.     CALL    PRINTL        ; The system is his
  3361. ;
  3362. EXCPM:     IF    B5IM
  3363.     CALL    IMQUIT        ; Send ATS0=0 or ATH1M0 but keep DTR high
  3364.      ENDIF            ; B5IM
  3365. ;
  3366.      IF    NOT B5IM
  3367.     CALL    MDQUIT        ; Exit with DTR low
  3368.      ENDIF            ; NOT B5IM
  3369. ;
  3370.      IF    MOTOR
  3371.     CALL    DSKON        ; Turn on drives
  3372.      ENDIF            ; MOTOR
  3373. ;
  3374.      IF    DISKLOG
  3375.     MVI    E,0
  3376.     CALL    TSTHRD        ; Make sure log file is closed
  3377.      ENDIF            ; DISKLOG
  3378. ;
  3379.     LHLD    REALBD+1    ; Get real bdos vector
  3380. ;
  3381.      IF    CPM3
  3382.     SHLD    STARTX+1    ; Restore for cpm3 exit
  3383.      ENDIF            ; CPM3
  3384. ;
  3385.      IF    NOT CPM3
  3386.     SHLD    BDOS+1        ; Save it so CP/M doesn't crash
  3387.      ENDIF            ; NOT CPM3
  3388. ;
  3389.      IF    ZCPR2 OR ZCPR3
  3390.     MVI    A,0FFH
  3391.     STA    WHEEL        ; Restore wheel byte for SYSOP
  3392.      ENDIF            ; ZCPR2 OR ZCPR3
  3393. ;
  3394.      IF    ZCPR3
  3395.     MVI    A,SYSUSR
  3396.     STA    0FE2DH        ; And MAXUSR
  3397.     MVI    A,SYSDRV
  3398.     STA    0FE2CH        ; And MAXDRIV
  3399.      ENDIF            ; ZCPR3
  3400. ;
  3401.      IF    CHGPATH        ; If external zcpr path
  3402.     CALL    SYSPAT        ; Setup Sysop's path
  3403.      ENDIF            ; CHGPATH
  3404. ;
  3405.      IF    ZCPR3
  3406.     CALL    DOZ3        ; ZCPR3 re-initialization
  3407.      ENDIF            ; ZCPR3
  3408. ;
  3409.      IF    CPM3
  3410.     CALL    RSXCLR        ; Unload this RSX
  3411.      ENDIF            ; CPM3
  3412. ;
  3413.     CALL    UNPATCH        ; And then...
  3414.     MVI    A,0C3H
  3415.     STA    000H        ; Reset in case running local
  3416.     JMP    0000H        ; Warm boot CP/M
  3417. ;.....
  3418. ;
  3419. ;
  3420. ; ZCPR3 command line buffer, shell stack, TCAP stuff
  3421. ;
  3422.      IF    ZCPR3
  3423. DOZ3:    LHLD    Z3CL        ; Z3CL is the address of the MCLB
  3424.     MVI    M,0
  3425. ;
  3426. ;
  3427. ; Command line done, now do shell stack
  3428. ;
  3429.     LXI    H,SHSTK        ; SHSTK is the addr of the Shell Stack
  3430.     CALL    ZERO128
  3431. ;
  3432. ;
  3433. ; Now initialize  TCAP
  3434. ;
  3435.     LXI    H,Z3ENV+128    ; Z3ENV is the address of the Environ-
  3436.     CALL    ZERO128        ; Ment Descriptor...the TCAP is the
  3437.                 ; Second 128 bytes
  3438. ;
  3439. ;
  3440. ; Also clean up message buffers
  3441. ;
  3442.     LXI    H,Z3MSG        ; Z3MSG is the addr of the msg buffers
  3443.     MVI    B,80
  3444.     CALL    ZEROM
  3445.     RET
  3446. ;.....
  3447. ;
  3448. ;
  3449. ; Routine to zero memory blocks
  3450. ;
  3451. ZERO128:MVI    B,128
  3452.      ENDIF            ; ZCPR3
  3453. ;
  3454. ZEROM:    MVI    M,0
  3455.     INX    H
  3456.     DCR    B
  3457.     JNZ    ZEROM
  3458.     RET
  3459. ;.....
  3460. ;
  3461. ;
  3462. ;-----------------------------------------------------------------------
  3463. ;
  3464. ; Loss of carrier test and drive/user validation
  3465. ;
  3466. CARCK:     IF    LMBELL
  3467.     LDA    KILBEL
  3468.     CMA
  3469.     STA    BELLON        ; Counteract MBBS foolishness
  3470.      ENDIF            ; LMBELL
  3471. ;
  3472.     LDA    MDMOFF
  3473.     ORA    A        ; Known loss?
  3474.     JNZ    CARCK2        ; Yes, allow d/u check locally
  3475. ;
  3476.      IF    EXFIL1 OR EXFIL2
  3477.     LDA    MSPEED        ; Check for archiving on
  3478.      ENDIF            ; EXFIL1 OR EXFIL2
  3479. ;
  3480.      IF    ANYLOS AND (EXFIL1 OR EXFIL2)
  3481.     CPI    44H        ; Just backing up files?
  3482.     RZ            ; Yes, skip carrier check  for now
  3483.      ENDIF            ; ANYLOS AND (EXFIL1 OR EXFIL2)
  3484. ;
  3485.      IF    EXFIL1 OR EXFIL2
  3486.     CPI    66H        ; Backing up files plus updating?
  3487.     RZ            ; Yes, skip carrier check  for now
  3488.      ENDIF            ; EXFIL1 OR EXFIL2
  3489. ;
  3490.     CALL    MDCARCK        ; Carrier there?
  3491.     JNZ    CARCK2        ; Yep, go onto other checks...
  3492.     PUSH    B        ; Preserve so we can use it
  3493.     MVI    B,CLOSS*10    ; Set for 'CLOSS' seconds
  3494. ;
  3495. CARLP:    CALL    DELAY        ; Wait .1 seconds
  3496.     CALL    MDCARCK        ; Check for carrier
  3497.     MOV    A,B        ; Get count back in a
  3498.     POP    B        ; Fix stack in case all is ok
  3499.     JNZ    CARCK2        ; Got carrier, continue on
  3500.     DCR    A        ; Count time down
  3501.     STC            ; In case this is the end of 'time'
  3502.     RZ            ; Return if timed out
  3503. ;
  3504.     PUSH    B        ; Preserve 'BC'
  3505.     MOV    B,A        ; Get counter value in 'B'
  3506.     JMP    CARLP        ; Keep checking
  3507. ;
  3508. ;
  3509. ; Now test drive #'s and (if CP/M 2.x) user #'s to insure that maximums
  3510. ; are not exceeded.
  3511. ;
  3512. CARCK2:     IF    USEZCPR    AND (ZCPR2 OR ZCPR3)
  3513.     LDA    MAXDRIV
  3514.     INR    A
  3515.     STA    MXDRV
  3516.     LDA    MAXUSER        ; Get it from ZCPR/ZCMD
  3517.     DCR    A        ; Drop it one
  3518.     STA    MXUSR        ; Save it in bye
  3519.      ENDIF            ; USEZCPR
  3520. ;
  3521.      IF    (NOT USEZCPR) AND (ZCPR2 OR ZCPR3)
  3522.     LDA    MXDRV        ; Older versions did not do this if
  3523.     DCR    A        ; Wheel was set -- BAD KARMA
  3524.     STA    MAXDRIV
  3525.     LDA    MXUSR        ; Get it from BYE
  3526.     INR    A        ; Bump it
  3527.     STA    MAXUSER        ; Save it in ZCPR
  3528.      ENDIF            ; NOT USEZCPR
  3529. ;
  3530.      IF    CHEKDU
  3531.     LDA    0004H        ; Check disk/user #
  3532.     ANI    0FH        ; Isolate drive
  3533.     PUSH    H        ; Save 'HL'
  3534.     LXI    H,MXDRV        ; Point to allowed # of drives
  3535.     CMP    M        ; Valid drive?
  3536.     JC    CARCK3        ; Yes, skip this junk
  3537.     LDA    0004H        ; Get whole login byte
  3538.     ANI    0F0H        ; Retain user #
  3539.     ORI    WBDRIV        ; And force drive to wbdriv
  3540.     STA    0004H        ; Update login byte
  3541.      ENDIF            ; CHEKDU
  3542. ;
  3543.      IF    CPM3 AND CHEKDU
  3544.     MVI    A,WBDRIV    ; Zero drive message
  3545.     CALL    SETDRIVE
  3546.      ENDIF            ; CPM3 AND CHEKDU
  3547. ;
  3548.      IF    CHEKDU
  3549.     LXI    H,IDMSG        ; Incorrect Drive Message
  3550.     CALL    PRINTB        ; Tell user what he did
  3551.     JMP    0000H        ; Warm boot
  3552. ;...
  3553. ;
  3554. ;
  3555. CARCK3:    LDA    0004H        ; Get login byte
  3556.     ANI    0F0H        ; Isolate user #
  3557.     RRC            ; Move to low bits
  3558.     RRC
  3559.     RRC
  3560.     RRC
  3561.     LXI    H,MXUSR        ; Point to maximum user number
  3562.     CMP    M        ; Valid user #?
  3563.     JC    CARCK4        ; Yes, don't change
  3564.     JZ    CARCK4
  3565.     LDA    0004H        ; Get login byte again
  3566.     ANI    0FH        ; Keep drive, zero user area
  3567.     STA    0004H        ; Update login byte
  3568.      ENDIF            ; CHEKDU
  3569. ;
  3570.      IF    CPM3 AND CHEKDU
  3571.     XRA    A        ; Zero user request
  3572.     CALL    SETUSER
  3573.      ENDIF            ; CPM3 AND CHEKDU
  3574. ;
  3575.      IF    CHEKDU
  3576.     LXI    H,IUMSG        ; Invalid User message
  3577.     CALL    PRINTB        ; Tell him what happened
  3578.     JMP    0000H        ; Warm boot
  3579. ;...
  3580. ;
  3581. ;
  3582. CARCK4:    POP    H        ; Restore 'HL'
  3583.      ENDIF            ; CHEKDU
  3584. ;
  3585.     ORA    A
  3586.     RET
  3587. ;.....
  3588. ;
  3589. ;
  3590. ;-----------------------------------------------------------------------
  3591. ;             print routines
  3592. ;
  3593. ; The following code has been modified to accomodate the automatic
  3594. ; loader.  (The loader may modify a constant, so all messages have been
  3595. ; placed at the end of the program and just moved to high memory.)
  3596. ;
  3597. ; Print on both consoles ** USE ONLY IF IN PATCHED MODE **
  3598. ;
  3599. PRINTB:    PUSH    B        ; Save BC
  3600.     PUSH    PSW        ; And status regs
  3601. ;
  3602. PRBL:    MOV    C,M        ; Get character
  3603.     CALL    MOUTPUT        ; Output it
  3604.     INX    H        ; Point to next character
  3605.     MOV    A,M        ; Test for end of message
  3606.     ORA    A
  3607.     JNZ    PRBL
  3608.     POP    PSW        ; Restore status regs
  3609.     POP    B        ; Restore BC
  3610.     RET
  3611. ;.....
  3612. ;
  3613. ;
  3614. ; Print locally only
  3615. ;
  3616. PRINTL:    PUSH    B        ; Save BC
  3617.     PUSH    PSW        ; And status regs
  3618. ;
  3619.      IF    RVIDEO
  3620.     CALL    MDCARCK        ; Carrier on?
  3621.     JZ    PRLL        ; No, skip reverse video sequence
  3622.     PUSH    H        ; Save original string address
  3623.     LXI    H,RVIDON
  3624.     CALL    PRTREV        ; Print reverse-on sequence
  3625.     POP    H        ; Restore original string
  3626.      ENDIF            ; RVIDEO
  3627. ;
  3628. PRLL:    MOV    C,M        ; Get character
  3629.     CALL    CONOUT        ; Output it
  3630.     INX    H        ; Point to next character
  3631.     MOV    A,M        ; Test for end of message
  3632.     ORA    A
  3633.     JNZ    PRLL
  3634. ;
  3635.      IF    RVIDEO
  3636.     CALL    MDCARCK        ; Carrier on?
  3637.     LXI    H,RVIDOFF
  3638.     CNZ    PRTREV        ; Yes, send the reverse-off sequence
  3639.      ENDIF            ; RVIDEO
  3640. ;
  3641.     POP    PSW        ; Restore status regs
  3642.     POP    B        ; Restore BC
  3643.     RET
  3644. ;
  3645.      IF    RVIDEO
  3646. PRTREV:    MOV    C,M
  3647.     CALL    CONOUT        ; Send the character
  3648.     INX    H
  3649.     MOV    A,M
  3650.     ORA    A        ; End of string?
  3651.     RZ            ; Yes, exit
  3652.     JMP    PRTREV        ; Else keep sending
  3653.      ENDIF            ; RVIDEO
  3654. ;
  3655. ;.....
  3656. ;
  3657. ;
  3658. ;-----------------------------------------------------------------------
  3659. ;
  3660. LISTOUT:PUSH    B
  3661.     PUSH    D
  3662.     PUSH    H
  3663.     PUSH    PSW
  3664. ;
  3665.      IF    NOT CPM3
  3666.     CALL    BDCHEK
  3667.      ENDIF            ; NOT CPM3
  3668. ;
  3669.     MOV    C,A
  3670.     CALL    VLISTOUT
  3671.     POP    PSW
  3672.     POP    H
  3673.     POP    D
  3674.     POP    B
  3675.     RET
  3676. ;.....
  3677. ;
  3678. ;
  3679. ;---------------------------------------------------------------------------
  3680.      IF    DISKLOG
  3681. ;
  3682. ;
  3683. ; Toggle disk log on/off
  3684. ;
  3685. ;
  3686. LOGFLP:    LDA    BDOSFL
  3687.     ORA    A        ; Are we in BDOS function?
  3688.     JZ    LOGFLP1        ; Ok to proceed if not
  3689.     STA    LOGTOG        ; Otherwise, save toggle flag
  3690.     MVI    A,07FH        ; DEL for buffer
  3691.     RET            ; And exit
  3692. LOGFLP1:
  3693.     CALL    STKNEW        ; Switch to local stack
  3694.     LXI    H,DSKLOG
  3695.     MOV    A,M
  3696.     ORA    A        ; What is the status?
  3697.     JZ    OPENLOG
  3698.     XRA    A
  3699.     JP    CLSHRD        ; Go and close it
  3700. OPENLOG:
  3701.     LXI    H,DSKLOG
  3702. OPNHRD:
  3703.     INR    M
  3704.     DCR    M
  3705.     MVI    A,07FH
  3706.     RNZ            ; Return if already open
  3707.     ORI    0FFH
  3708.     MOV    M,A        ; Set the flag
  3709.     CALL    OPNLOG        ; Open the log file
  3710.     LXI    H,OPNMSG
  3711.     CALL    PRINTL        ; Tell sysop log file is open
  3712.     MVI    A,07FH        ; DEL for buffer
  3713.     RET
  3714. TSTHRD:                ; Close/open request via BDOS
  3715.     MOV    A,E        ; Get request state
  3716.     LXI    H,DSKLOG
  3717.     ORA    M        ; Both zero?
  3718.     RZ            ; Return if already closed
  3719.     CALL    STKNEW        ; Switch to local stack
  3720.     MOV    A,E
  3721.     ORA    A
  3722.     JNZ    OPNHRD        ; Jump if to open
  3723. CLSHRD:
  3724.     MOV    M,A        ; Reset log flag
  3725.     CALL    WRCRLF        ; Write final cr,lf
  3726.     CALL    CLSLOG        ; Close the log file
  3727.     LXI    H,CLSMSG
  3728.     CALL    PRINTL        ; Tell sysop log file is closed
  3729.     MVI    A,07FH        ; DEL for buffer
  3730.     RET
  3731. ;.....
  3732. ;
  3733. ;
  3734. ; Log file routines
  3735. ;
  3736. CLSLOG:                ; Close the log file
  3737.     MVI    A,26
  3738.     CALL    WRBY        ; Put EOF into log file
  3739.     CALL    WRITE        ; Write the last sector
  3740.     CALL    SETLUS        ; Set to log user
  3741.     LXI    D,LOGFCB
  3742.     MVI    C,16
  3743.     CALL    REALBD        ; Close the log file
  3744.     JMP    CLRLUS        ; Reset current user number
  3745. ;
  3746. OPNLOG:                ; Open the log file
  3747.     CALL    SETLUS        ; Set to log user
  3748.     XRA    A
  3749.     STA    WOFFSET        ; Init log write offset
  3750.     LXI    H,LOGFCB+12
  3751.     LXI    D,LOGFCB+13
  3752.     MVI    M,0
  3753.     MVI    B,23
  3754.     CALL    MOVE        ; Clear SYS.LOG FCB to zeros
  3755.     LXI    D,LOGFCB
  3756.     MVI    C,15
  3757.     CALL    REALBD        ; Attempt to open SYS.LOG file
  3758.     INR    A        ; Any errors ?
  3759.     JNZ    NOLOGMAKE    ; No need to create new file if exists
  3760.     LXI    D,LOGFCB
  3761.     MVI    C,22
  3762.     CALL    REALBD        ; Create new SYS.LOG file
  3763. NOLOGMAKE:
  3764.     LXI    D,LOGFCB
  3765.     MVI    C,35
  3766.     CALL    REALBD        ; Determine SYS.LOG file size
  3767.     LHLD    LOGFCB+33    ; Get the file size
  3768.     MOV    A,H
  3769.     ORA    L        ; Is it zero?
  3770.     JZ    CLRLUS        ; All set up if empty
  3771.     DCX    H        ; Point to last record
  3772.     SHLD    LOGFCB+33    ; Put it back
  3773.     LXI    D,LOGFCB
  3774.     MVI    C,33
  3775.     CALL    REALBD        ; Read the last record
  3776.     LXI    B,128        ; Init offset and counter
  3777.     MVI    A,26        ; Just a CTRL-Z (eof marker)
  3778.     LXI    H,RECORD    ; Point to start of record
  3779. FINDEOF:
  3780.     CMP    M        ; Is it EOF?
  3781.     JZ    FOUNDEOF
  3782.     INX    H
  3783.     INR    B
  3784.     DCR    C
  3785.     JNZ    FINDEOF        ; Loop through last record
  3786.     DCR    B        ; If not found, assume end of record
  3787. FOUNDEOF:
  3788.     LXI    H,WOFFSET    ; Point to SYS.LOG write offset
  3789.     MOV    M,B        ; Save write offset
  3790.     JMP    CLRLUS
  3791.      ENDIF            ; DISKLOG
  3792. ;
  3793.      IF    DISKLOG    AND CPM3
  3794. SETLUS:                ; Set to log file user
  3795.     LHLD    SCBBASE
  3796.     MVI    L,0E0H
  3797.     MOV    A,M        ; Get current user number
  3798.     LXI    D,OLDLUS
  3799.     STAX    D        ; Save it
  3800.     MVI    M,LOGUSR    ; Set to log user
  3801.     MVI    L,0E6H
  3802.     INX    D
  3803.     MOV    A,M        ; Get current multi-sector count
  3804.     MVI    M,1        ; Set multi-sector count to 1
  3805.     STAX    D        ; Save old multi-sector count
  3806.     MVI    L,0D8H        ; Point to current DMA
  3807.     INX    D
  3808.     MOV    A,M        ; Get low DMA
  3809.     STAX    D
  3810.     INR    L
  3811.     INX    D
  3812.     MOV    A,M        ; Get high DMA
  3813.     STAX    D
  3814.     LXI    D,RECORD
  3815.     MVI    C,26
  3816.     JMP    REALBD        ; Set DMA and return via BDOS
  3817. ;
  3818. CLRLUS:                ; Return to current user #
  3819.     LHLD    SCBBASE
  3820.     MVI    L,0E0H
  3821.     LXI    D,OLDLUS    ; Point to save area
  3822.     LDAX    D        ; Get old user #
  3823.     MOV    M,A        ; Restore it
  3824.     MVI    L,0E6H
  3825.     INX    D
  3826.     LDAX    D        ; Get old multi-sector count
  3827.     MOV    M,A        ; Restore it
  3828.     INX    D
  3829.     XCHG
  3830.     MOV    E,M        ; Get old DMA low
  3831.     INX    H
  3832.     MOV    D,M        ; Get old DMA high
  3833.     MVI    C,26
  3834.     JMP    REALBD        ; Set old DMA and return via BDOS
  3835.      ENDIF            ; DISKLOG AND CPM3
  3836. ;
  3837.      IF    DISKLOG    AND (NOT CPM3)
  3838. SETLUS:                ; Set up Log file environment
  3839.     MVI    E,255
  3840.     MVI    C,32
  3841.     CALL    REALBD        ; Get current user number
  3842.     STA    OLDLUS        ; Save it
  3843.     MVI    E,LOGUSR
  3844.     MVI    C,32
  3845.     CALL    REALBD
  3846.     LXI    D,RECORD
  3847.     MVI    C,26
  3848.     JMP    REALBD        ; Set the DMA and return via BDOS
  3849. ;
  3850. CLRLUS:                ; Restore current environment
  3851.     LDA    OLDLUS        ; Get old user number
  3852.     MOV    E,A
  3853.     MVI    C,32
  3854.     CALL    REALBD        ; Restore old user number
  3855.     LHLD    OLDDMA        ; Get old DMA address
  3856.     XCHG
  3857.     MVI    C,26
  3858.     JMP    REALBD        ; Set the old DMA and return via BDOS
  3859.      ENDIF            ; DISKLOG AND NOT CPM3
  3860. ;
  3861.      IF    DISKLOG
  3862. ADDHLA:
  3863.     ADD    L
  3864.     MOV    L,A
  3865.     RNC
  3866.     INR    H
  3867.     RET
  3868. ;
  3869. WRBYTE:                ; Write a byte to log file
  3870.     PUSH    H
  3871.     PUSH    D
  3872.     PUSH    B
  3873.     PUSH    PSW
  3874.     CPI    ' '        ; Is it printable?
  3875.     JNC    WROK        ; Jump if ok
  3876.     CPI    CR        ; CR ?
  3877.     JZ    WROK
  3878.     CPI    LF        ; LF ?
  3879.     JZ    WROK
  3880.     CPI    8        ; BACK SPACE ?
  3881.     JZ    WROK
  3882.     MVI    A,'^'
  3883.     CALL    WRBY        ; Write control char prefix
  3884.     POP    PSW
  3885.     PUSH    PSW
  3886.     ADI    40H        ; Make it printable
  3887. WROK:
  3888.     CALL    WRBY
  3889.     POP    PSW
  3890.     POP    B
  3891.     POP    D
  3892.     POP    H
  3893.     RET
  3894. ;
  3895. WRBY:
  3896.     PUSH    PSW
  3897.     LDA    WOFFSET        ; Get write offset
  3898.     LXI    H,RECORD
  3899.     CALL    ADDHLA        ; Form address
  3900.     POP    PSW        ; Restore char
  3901.     MOV    M,A        ; Put it in buffer
  3902.     LXI    H,WOFFSET
  3903.     MOV    A,M
  3904.     INR    A        ; Bump offset
  3905.     CM    WRITE        ; Write it out if buffer full
  3906.     MOV    M,A        ; Save offset
  3907.     RET
  3908. ;
  3909. WRITE:                ; Write a sector to log file
  3910.     LDA    WOFFSET
  3911.     ORA    A        ; Is it empty?
  3912.     RZ            ; Return if nothing to write
  3913.     PUSH    H
  3914.     CALL    SETLUS        ; Set up log file environment
  3915.     LXI    D,LOGFCB
  3916.     MVI    C,21
  3917.     CALL    REALBD        ; Write the sector
  3918.     CALL    CLRLUS        ; Restore environment
  3919.     XRA    A        ; Set offset to 0
  3920.     POP    H
  3921.     RET
  3922. ;
  3923. WRCRLF:                ; Write a cr, lf to log file
  3924.     MVI    A,CR
  3925.     CALL    WRBYTE
  3926.     MVI    A,LF
  3927.     JMP    WRBYTE
  3928. ;
  3929. WRTMSG:                ; Write message at [HL] to log file
  3930.     LDA    DSKLOG
  3931.     ORA    A
  3932.     RZ            ; Do nothing if no log
  3933.     PUSH    H
  3934.     CALL    WRTTIM        ; Time stamp the message
  3935.     POP    H
  3936. WRTMS1:
  3937.     MOV    A,M
  3938.     ORA    A
  3939.     JZ    WRCRLF        ; If at end, exit through crlf
  3940.     CALL    WRBYTE        ; Write the byte
  3941.     INX    H
  3942.     JMP    WRTMS1
  3943. ;
  3944. WRTTIM:                ; Time stamp the log file
  3945.      ENDIF            ; DISKLOG
  3946. ;
  3947.      IF    DISKLOG    AND CLOCK
  3948.     CALL    TIME        ; Update the time
  3949.      ENDIF            ; DISKLOG AND CLOCK
  3950. ;
  3951.      IF    DISKLOG
  3952.     LXI    H,RTCBUF    ; Point to hour
  3953.     CALL    WRTA
  3954.     MVI    A,':'
  3955.     CALL    WRBYTE
  3956.     INX    H        ; Point to minute
  3957.     CALL    WRTA
  3958.     MVI    A,' '
  3959.     JMP    WRBYTE        ; Write final space
  3960. ;
  3961. WRTA:                ; Write time (BCD) to log file
  3962.     MOV    A,M
  3963.     RAR
  3964.     RAR
  3965.     RAR
  3966.     RAR
  3967.     CALL    WRTHEX        ; Write first BCD digit
  3968.     MOV    A,M
  3969. WRTHEX:
  3970.     ANI    0FH        ; Isolate digit
  3971.     ADI    '0'        ; Convert to ascii
  3972.     JMP    WRBYTE        ; Exit through write byte
  3973. ;....
  3974. ;
  3975. ; Set the BDOS call in progress flag so that bios calls do not write to
  3976. ; log file as well.
  3977. ;
  3978. STBDOS:
  3979.     MVI    A,0FFH
  3980.     STA    BDOSFL        ; Set bdos call in progress flag
  3981.     POP    H        ; Retrieve return address
  3982.     SHLD    CALLIN+1    ; Modify call instruction
  3983. CALLIN:
  3984.     CALL    0        ; Return to caller
  3985.     PUSH    PSW        ; Return from caller gets us here
  3986.     XRA    A
  3987.     STA    BDOSFL        ; Reset bdos call in progress flag
  3988.     POP    PSW
  3989.     RET
  3990. ;
  3991. STKNEW:                ; Switch to local stack for log write
  3992.     SHLD    HLSAVE        ; Save HL
  3993.     POP    H        ; Retrieve return address
  3994.     SHLD    USRCAL+1    ; Modify call instruction
  3995.     LXI    H,0
  3996.     DAD    SP
  3997.     SHLD    OLDSP        ; Save old stack
  3998.     LXI    SP,NEWSTK    ; Set up new stack
  3999.     LHLD    HLSAVE        ; Restore HL
  4000. USRCAL:
  4001.     CALL    0        ; Back to caller
  4002.     LXI    SP,0        ; Restore old stack
  4003. OLDSP    EQU    $-2
  4004.     RET
  4005. ;.....
  4006. ;
  4007. ; Function 86 - LOGSTAT
  4008. ;     E = 0FFH    Return log status in A
  4009. ;     E = 1        Turn log on
  4010. ;     E = 0        Turn log off
  4011. ; If the equate DISKLOG is NO, A = 77 on return from this call
  4012. ;
  4013. LOGSTAT:
  4014.     MOV    A,E
  4015.     INR    A        ; Test for FFH
  4016.     JNZ    TSTHRD        ; Go turn log on/off
  4017.     LDA    DSKLOG        ; Get log status
  4018.     ORA    A
  4019.     RZ
  4020.     ORI    0FFH
  4021.     RET
  4022. ;.....
  4023. ;
  4024. ; Function 87 - LOGPUT Write a string at [DE] to log file
  4025. ;
  4026. LOGPUT:
  4027.     CALL    STKNEW        ; Switch to local stack
  4028.     XCHG            ; String address into HL
  4029.     JMP    WRTMSG        ; And go write it out
  4030.      ENDIF            ; DISKLOG
  4031. ;
  4032.      IF    NOT DISKLOG
  4033. LOGSTAT:
  4034. LOGPUT:
  4035.     MVI    A,77        ; Say disklog doesn't exist
  4036.     RET
  4037.      ENDIF            ; NOT DISKLOG
  4038. ;
  4039.      IF    DISKLOG
  4040. PUTSL:
  4041.     MVI    A,'/'
  4042.     STAX    D
  4043.     INX    D
  4044.     RET
  4045. ;
  4046. DATEMSG:
  4047.     MOV    A,M
  4048.     RAR
  4049.     RAR
  4050.     RAR
  4051.     RAR
  4052.     CALL    PUTDATE
  4053.     MOV    A,M
  4054.     INX    H
  4055. PUTDATE:
  4056.     ANI    0FH
  4057.     ADI    '0'
  4058.     STAX    D
  4059.     INX    D
  4060.     RET
  4061.      ENDIF            ; DISKLOG
  4062. ;
  4063. ;....
  4064. ;
  4065. ;-----------------------------------------------------------------------
  4066. ;               .COM file routine
  4067. ;
  4068. ; Routine to load the .COM file
  4069. ;
  4070. LODCOM:     IF    COMFILE
  4071.     MVI    C,SELDSK
  4072.     MVI    E,COMDRV-'A'    ; Select drive with .COM file on
  4073.     CALL    BDOS
  4074.     MVI    C,SETUSR    ; Set CP/M user area function
  4075.     MVI    E,COMUSR    ; Location of our COMFILE
  4076.     CALL    BDOS
  4077.      ENDIF            ; COMFILE
  4078. ;
  4079.      IF    MSGFIL        ; Routine to load message file handler
  4080.     LDA    000H
  4081.     CPI    0C2H        ; Flag that says KMD RM'ed a file
  4082.     JNZ    NOMSGF        ; No message file uploaded
  4083.     XRA    A
  4084.     STA    MSGFCB        ; Prep the fcb
  4085.     LXI    H,MSGFCB
  4086.     SHLD    CURRFCB
  4087.     LXI    H,MSGFCB+12
  4088.     MVI    B,21
  4089.     CALL    ZEROM
  4090.     LXI    D,MSGFCB    ; Ready to load it now
  4091.     JMP    LODCM2        ; So do it
  4092. ;
  4093. NOMSGF:     ENDIF            ; MSGFIL
  4094. ;
  4095.      IF    MBBS
  4096.     LDA    OPTION
  4097.     CPI    'C'        ; MBBS for comments, login otherwise
  4098.     JNZ    LODCM1        ; Load login
  4099.     MVI    C,SELDSK
  4100.     MVI    E,MBSDRV-'A'
  4101.     CALL    BDOS        ; Select mbbs.com drive
  4102.     MVI    C,SETUSR
  4103.     MVI    E,MBSUSR
  4104.     CALL    BDOS        ; Select mbbs.com user
  4105.     XRA    A
  4106.     STA    OPTION        ; Clear option flag
  4107.     STA    FCB+1        ; And FCB to avoid loop
  4108.     STA    CM2FCB
  4109.     LXI    H,CM2FCB    ; MBBS fcb
  4110.     SHLD    CURRFCB
  4111.     LXI    H,CM2FCB+12
  4112.     MVI    B,21
  4113.     CALL    ZEROM        ; Clear rest of fcb
  4114.     LXI    D,CM2FCB
  4115.     JMP    LODCM2        ; Load MBBS
  4116.      ENDIF            ; MBBS
  4117. ;
  4118.      IF    COMFILE
  4119. LODCM1:    LXI    H,COMFCB
  4120.     SHLD    CURRFCB
  4121.     XRA    A        ; Initialize FCB
  4122.     STA    COMFCB
  4123.     LXI    H,COMFCB+12
  4124.     MVI    B,21
  4125.     CALL    ZEROM
  4126.     LXI    D,COMFCB
  4127. ;
  4128. LODCM2:    CALL    OPENFIL
  4129.     JZ    ABORT
  4130.     JMP    LOADFIL
  4131.      ENDIF            ; COMFILE
  4132. ;
  4133. LODEX:     IF    EXFILE
  4134.     LXI    H,EXITFCB
  4135.     SHLD    CURRFCB
  4136.     LXI    H,EXITFCB+12
  4137.     MVI    B,21
  4138.     CALL    ZEROM
  4139.     LXI    D,EXITFCB
  4140.     CALL    OPENFIL
  4141.     JZ    ABORT        ; Cannot open file, finish BYE hangup
  4142.     JMP    LOADFIL
  4143.      ENDIF            ; EXFILE
  4144. ;
  4145. LODEX1:     IF    EXFIL1
  4146.     LXI    H,EX1FCB
  4147.     SHLD    CURRFCB
  4148.     LXI    H,EX1FCB+12
  4149.     MVI    B,21
  4150.     CALL    ZEROM
  4151.     LXI    D,EX1FCB
  4152.     CALL    OPENFIL
  4153.     JZ    ABORT        ; Cannot open file, finish BYE hangup
  4154.     JMP    LOADFIL
  4155.      ENDIF            ; EXFILE1
  4156. ;
  4157. LODEX2:     IF    EXFIL2
  4158.     LXI    H,EX2FCB
  4159.     SHLD    CURRFCB
  4160.     LXI    H,EX2FCB+12
  4161.     MVI    B,21
  4162.     CALL    ZEROM
  4163.     LXI    D,EX2FCB
  4164.     CALL    OPENFIL
  4165.     JZ    ABORT        ; Cannot open file, finish BYE hangup
  4166.     JMP    LOADFIL
  4167.      ENDIF            ; EXFIL2
  4168. ;
  4169. LODEX3:     IF    EXFIL2 AND RAMDSK
  4170.     LXI    H,EX3FCB
  4171.     SHLD    CURRFCB
  4172.     LXI    H,EX3FCB+12
  4173.     MVI    B,21
  4174.     CALL    ZEROM
  4175.     LXI    D,EX3FCB
  4176.     CALL    OPENFIL
  4177.     JZ    ABORT
  4178.      ENDIF            ; EXFIL2 AND RAMDSK
  4179. ;
  4180. ;
  4181. ; Now load the file
  4182. ;
  4183.      IF    COMFILE    OR EXFILE
  4184. LOADFIL:LHLD    6        ; Get top of memory
  4185.     LXI    D,-80H
  4186.     DAD    D
  4187.     PUSH    H        ; Save on stack
  4188.     LXI    D,80H        ; TPA-80H
  4189.     LXI    B,0        ; Keep a record counter
  4190.     PUSH    B        ; Save counter
  4191.     PUSH    D        ; And load address
  4192. ;
  4193. GLOOP:    POP    D        ; Get TPA address
  4194.     LXI    H,80H        ; Point to next address to read to
  4195.     DAD    D        ; HL has the address
  4196.     POP    B        ; Increment the counter
  4197. ;
  4198. ;
  4199. ; Check for load past top-of-memory
  4200. ;
  4201.     POP    D        ; Get (top-of-memory)
  4202.     PUSH    D        ; Resave for next time
  4203.     MOV    A,E        ; Subtract: (top) - (address)
  4204.     SUB    L
  4205.     MOV    A,D        ; Only the carry needed
  4206.     SBB    H
  4207.     JNC    SIZEOK        ; CY=better MOVCPM
  4208.     LXI    H,PTSMSG
  4209.     JMP    ERRXIT
  4210. ;
  4211. SIZEOK:    INX    B
  4212.     PUSH    B
  4213.     PUSH    H        ; Save TPA address
  4214.     XCHG            ; Align registers
  4215.     MVI    C,STDMA        ; Tell BDOS where to put record
  4216.     CALL    BDOS
  4217.     LHLD    CURRFCB        ; Point to aprropriate FCB
  4218.     XCHG
  4219.     MVI    C,READ
  4220.     CALL    BDOS
  4221.     ORA    A
  4222.     JZ    GLOOP        ; A=0 if more to read
  4223.     POP    B        ; Unjunk stack
  4224.     POP    B        ; This is our counter
  4225.     POP    H        ; More junk on stack
  4226.     MOV    A,B        ; Check for zero
  4227.     ORA    C
  4228.     JZ    ABORT        ; We should have read something
  4229.     LXI    D,80H        ; We did, reset DMA to 80H
  4230.     MVI    C,STDMA
  4231.     CALL    BDOS
  4232.     LXI    H,CFLMSG
  4233.     CALL    PRINTL
  4234.     RET
  4235. ;.....
  4236. ;
  4237. ;
  4238. ABORT:    LXI    H,CNFMSG
  4239. ;
  4240. ERRXIT:    CALL    PRINTL
  4241.     MVI    A,0CDH        ; Force logoff
  4242.     STA    000H        ; And system reset
  4243.     JMP    000H        ; Via warm boot trap
  4244.      ENDIF            ; COMFILE OR EXFILE
  4245. ;.....
  4246. ;
  4247. ;
  4248. OPENFIL: IF    CPM3
  4249.     PUSH    D        ; Save FCB address
  4250.     LXI    D,0080H
  4251.     MVI    C,STDMA
  4252.     CALL    BDOS        ; Set DMA to 0080H
  4253.     POP    D        ; Get back pointer to FCB
  4254.     PUSH    D        ; Save FCB pointer again
  4255.     MVI    C,SEARCH    ; Search for first match
  4256.     CALL    BDOS
  4257.     INR    A        ; Did a file match?
  4258.     POP    D
  4259.     RZ            ; No, return
  4260.     PUSH    D
  4261.     DCR    A        ; A=directory code (0-3)
  4262.     ADD    A        ; *2
  4263.     ADD    A        ; *4
  4264.     ADD    A        ; *8
  4265.     ADD    A        ; *16
  4266.     ADD    A        ; *32
  4267.     MOV    E,A
  4268.     MVI    D,0
  4269.     LXI    H,0080H        ; Add (32*dir code) to default DMA
  4270.     DAD    D        ; To find first match filename
  4271.     POP    D        ; DE=FCB
  4272.     PUSH    D        ; Save DE again
  4273.     INX    H        ; Move HL past user # byte in buffer
  4274.     INX    D        ; Move DE past drive # in FCB
  4275.     MVI    B,11
  4276.     CALL    MOVE        ; Move name found to FCB
  4277.     POP    D        ; And continue with the open
  4278.      ENDIF            ; CPM3
  4279. ;
  4280.     MVI    C,OPEN        ; Open file pointed to by 'DE'
  4281.     CALL    BDOS
  4282.     INR    A
  4283.     RET
  4284. ;.....
  4285. ;
  4286. ;            end of .COM file routine
  4287. ;-----------------------------------------------------------------------
  4288. ;
  4289. ; Boot trap - becomes disconnect if JMP at 0 has been altered
  4290. ;
  4291. MBOOT:    LDA    OPTION
  4292.     CPI    0FFH        ; Local cp/m with BYE5 running?
  4293.     JZ    VWARMBT        ; Yes, skip this check
  4294. ;
  4295.     LXI    SP,STACK    ; Ensure good stack
  4296. ;
  4297.      IF    EXRET
  4298.     LDA    FCB+1
  4299.     CPI    'r'        ; Returning from an exit file?
  4300.     JZ    PREOFF        ; Then prepare for next call
  4301.      ENDIF            ; EXRET
  4302. ;
  4303.      IF    EXFIL2
  4304.     LDA    MSPEED
  4305.     CPI    07FH        ; Returning from ARCIVE?
  4306.     JZ    PREOFF        ; Yes, skip to next call
  4307.      ENDIF            ; EXFIL2
  4308. ;
  4309.      IF    MSGFIL        ; See if KMD RM'ed a file
  4310.     LDA    0000H
  4311.     CPI    0C2H        ; Flag left by KMD?
  4312.     JNZ    MBOOT1        ; No, continue
  4313.     LXI    H,MSGMSG    ; Let Sysop know what file is sought
  4314.     CALL    PRINTL
  4315.     CALL    LODCOM        ; Try to load it
  4316.     MVI    A,0C3H        ; Reset the flag
  4317.     STA    000H
  4318.     CALL    0100H        ; Now run the message file handler
  4319.     LXI    SP,STACK    ; Restore the stack
  4320. ;
  4321. MBOOT1:     ENDIF            ; MSGFIL
  4322. ;
  4323.      IF    CPM3
  4324.     MVI    B,0B3H        ; Offset to CHAIN PROGRAM flag in SCB
  4325.     CALL    GETSCB        ; Get byte from SCB
  4326.     ANI    080H        ; In the middle of a CHAIN PROGRAM now?
  4327.     JNZ    VWARMBT        ; Yes, skip checks
  4328.      ENDIF            ; CPM3
  4329. ;
  4330.      IF    (COMFILE OR EXFILE) AND    (NOT HBBS)
  4331.     LDA    OPTION
  4332.     CPI    'E'        ; Return from local test?
  4333.     JNZ    MBOOT2        ; No, continue
  4334.     MVI    A,' '
  4335.     STA    FCB+1        ; Fool system
  4336.     STA    OPTION
  4337.     CALL    UNPATCH        ; Yes, restore
  4338.      ENDIF            ; COMFILE OR EXFILE AND NOT HBBS
  4339. ;
  4340.      IF    EXFILE AND (NOT    HBBS) AND (NOT MBBS)
  4341.     JMP    LOGOFF        ; Run exit file locally
  4342.      ENDIF            ; EXFILE AND NOT HBBS/MBBS
  4343. ;
  4344.      IF    COMFILE    AND (NOT HBBS)
  4345.     JMP    START0        ; And start fresh
  4346.      ENDIF            ; COMFILE AND NOT HBBS
  4347. ;
  4348. MBOOT2:    LDA    0        ; Look at opcode
  4349.     CPI    0C3H        ; Is it still a jmp?
  4350. ;
  4351.      IF    MBBS
  4352.     JNZ    NORPTC        ; Let login take over
  4353.      ENDIF            ; MBBS
  4354. ;
  4355.      IF    NOT MBBS
  4356.     JNZ    LOGOFF        ; Check for exit file
  4357.      ENDIF            ; NOT MBBS
  4358. ;
  4359.      IF    NOT CPM3
  4360.     CALL    BDCHEK
  4361.      ENDIF            ; NOT CPM3
  4362. ;
  4363.      IF    (NO25TH    OR MBBS) AND READLC
  4364.     LDA    LCDATA        ; See if lastcalr has been read
  4365.     CPI    ' '        ; Or data poked by a BBS, like MBBS
  4366.     JNZ    NO25EX        ; Yes, skip this
  4367.     XRA    A        ; Else, let's pick up the lastcalr file
  4368.     STA    FCBRNO        ; Prepare FCB for lastcalr
  4369.     LXI    H,LCNAME
  4370.     LXI    D,FCB
  4371.     MVI    B,13
  4372.     CALL    MOVE        ; Move rest of FCB
  4373.     MVI    C,0DH        ; Reset disk and
  4374.     CALL    BDOS        ; Set for default buffer
  4375.     MVI    C,SELDSK
  4376.     MVI    E,LCDRV-'A'
  4377.     CALL    BDOS        ; Set drive
  4378.     MVI    C,SETUSR
  4379.     MVI    E,LCUSR
  4380.     CALL    BDOS        ; And user
  4381.     LXI    D,FCB
  4382.     CALL    OPENFIL        ; Open it
  4383.     LXI    H,LCMSG1
  4384.     CZ    PRINTL        ; Error msg
  4385.     JZ    NO25EX        ; No file available, exit
  4386.     LXI    D,FCB
  4387.     MVI    C,READ
  4388.     CALL    BDOS        ; Read 1 record max
  4389.     LXI    H,LCMSG1
  4390.     ORA    A
  4391.     CNZ    PRINTL        ; Say error
  4392.     LXI    H,80H
  4393.     LXI    D,LCDATA
  4394.     MVI    B,NO25BF    ; Size of buffer
  4395.     CALL    MOVE        ; Move data into bye's internal buffer
  4396.     MVI    B,NO25BF    ; Max we will display
  4397.     LXI    H,LCDATA
  4398. ;
  4399. NO25RD:    MOV    A,M
  4400.     CPI    'Z'-'@'        ; EOF?
  4401.     JZ    NO25ZD
  4402.     CPI    ','
  4403.     CZ    NO25SP        ; Change commas and semicolons to spaces
  4404.     CPI    ';'
  4405.     CZ    NO25SP
  4406.     CPI    CR
  4407.     CZ    NO25SP        ; Convert cr's and lf's to spaces
  4408.     CPI    LF
  4409.     CZ    NO25SP
  4410.     DCR    B
  4411.     JZ    NO25ZD
  4412.     INX    H        ; Get next byte
  4413.     JMP    NO25RD
  4414. ;
  4415. NO25ZD:    XRA    A
  4416.     MOV    M,A        ; Set terminator for print routine
  4417.     STA    04H
  4418.      ENDIF            ; READLC
  4419. ;
  4420.      IF    NO25TH OR MBBS
  4421. NO25EX:    CALL    WHOSIT
  4422.      ENDIF            ; NO25TH OR MBBS
  4423. ;
  4424.      IF    PRNTWB
  4425.     LXI    H,WBMSG
  4426.     CALL    PRINTB        ; Print the following message:
  4427.      ENDIF            ; PRNTWB
  4428. ;
  4429.      IF    TIMEON AND CLOCK AND PRNTOS
  4430.     CALL    RMTOS        ; Display timeon
  4431.      ENDIF            ; TIMEON
  4432. ;
  4433.     JMP    VWARMBT        ; Go do a warm boot
  4434. ;
  4435.      IF    (NO25TH    OR MBBS) AND READLC
  4436. NO25SP:    MVI    A,' '        ; Space
  4437.     MOV    M,A        ; To lcdata
  4438.     RET
  4439.      ENDIF            ; NO25TH OR MBBS
  4440. ;.....
  4441. ;
  4442. ;
  4443. ;-----------------------------------------------------------------------
  4444. ;
  4445. ; Modem input function, checks local console first
  4446. ;
  4447. MINPUT:     IF    NOT CPM3
  4448.     CALL    BDCHEK
  4449.      ENDIF            ; CPM3
  4450. ;
  4451.     XRA    A        ; Reset MSTAT no-activity flag
  4452.     STA    MSFLAG
  4453. MINP2:    CALL    MSTAT        ; Nope, check for modem input
  4454.     ORA    A        ; Got modem input?
  4455.     JZ    MINP2        ; Nope, loop again
  4456.     CALL    CONSTAT
  4457.     ORA    A
  4458.     JNZ    CONIN
  4459. MINP3:    CALL    MDINP        ; Yep, get modem character
  4460.     ANI    7FH        ; Strip off any high bits
  4461.     CPI    FILT4        ; Ignore nulls
  4462.     JZ    MINP2
  4463.     CPI    FILT1        ; Ignore left braces
  4464.     JZ    MINP2
  4465.     CPI    FILT2        ; Was it a delete?
  4466.     JZ    MINP2        ; Filter this too
  4467.     CPI    FILT3        ; "`" causes TRS-80 glitch
  4468.     JZ    MINP2        ; So filter it too
  4469. ;
  4470.      IF    ZCPR2 OR ZCPR3
  4471.     MOV    B,A        ; Save byte in B
  4472.     LDA    WHEEL
  4473.     ORA    A
  4474.     MOV    A,B        ; Get character back
  4475.     JNZ    MINP4        ; It's a wheel, don't trap ^P
  4476.      ENDIF            ; ZCPR2 OR ZCPR3
  4477. ;
  4478.     CPI    'P'-'@'        ; Is it a ^P?
  4479.     JZ    MINP2        ; Ignore CTL-P unless wheel is set
  4480. ;
  4481. MINP4:     IF    HARDLOG
  4482.     PUSH    B
  4483.     MOV    B,A        ; Put a copy of the character in B
  4484.     LDA    HARDON        ; If HARDON=0 then turn HARDLOG off (so
  4485.     ORA    A        ; SYSOP does not waste paper while he
  4486.     MOV    A,B        ; Playing ZORK from work.)
  4487.     POP    B
  4488.     JZ    NOLOG
  4489.     CPI    20H
  4490.     JNC    MINP5
  4491.     CPI    CR
  4492.     JNZ    NOLOG
  4493. ;
  4494. MINP5:    CALL    LISTOUT        ; Echo on printer
  4495.     CPI    CR
  4496.     JNZ    NOLOG        ; Return needs linefeed
  4497.     MVI    A,LF
  4498.     CALL    LISTOUT        ; So send it
  4499.     MVI    A,CR        ; Get back CR
  4500.      ENDIF            ; HARDLOG
  4501. ;
  4502. NOLOG:
  4503.      IF    DISKLOG
  4504.     MOV    C,A
  4505.     LDA    DSKLOG
  4506.     ORA    A        ; Is disk log on?
  4507.     JZ    NOHARD
  4508.     LDA    BDOSFL
  4509.     ORA    A        ; Are we in a BDOS function call?
  4510.     JNZ    NOHARD
  4511.     CALL    STKNEW        ; Switch to local stack
  4512.     PUSH    H
  4513.     PUSH    B
  4514.     LDA    TIMSFL        ; Should we time stamp the log file?
  4515.     ORA    A
  4516.     CNZ    WRTTIM
  4517.     POP    B
  4518.     POP    H
  4519.     MOV    A,C
  4520.     CALL    WRBYTE        ; Write out the byte
  4521.     CPI    CR        ; Is it CR?
  4522.     MVI    A,LF
  4523.     CZ    WRBYTE        ; Send LF if CR.
  4524.     MVI    A,0
  4525.     JNZ    HRDL1
  4526.     DCR    A        ; Say that we have to time stamp next time
  4527. HRDL1:
  4528.     STA    TIMSFL
  4529. NOHARD:
  4530.     MOV    A,C
  4531.      ENDIF            ; DISKLOG
  4532. ;
  4533.     CPI    'C'-'@'        ; Is it ^C?
  4534.     RNZ            ; No, pass it through
  4535.     LDA    0        ; See if warm boot disabled
  4536.     CPI    0C3H        ; Jump means warm boot ok
  4537.     MVI    A,3        ; So return with a ^C
  4538.     RZ
  4539.     MVI    A,CTRLC        ; Else convert to different character
  4540.     RET
  4541. ;.....
  4542. ;
  4543. ;
  4544. ;-----------------------------------------------------------------------
  4545. ;
  4546. ; Modem output function
  4547. ;
  4548. MOUTPUT: IF    NOT CPM3
  4549.     CALL    BDCHEK
  4550.      ENDIF            ; NOT CPM3
  4551. ;
  4552.     XRA    A
  4553.     STA    MSFLAG        ; Reset no-activity flag
  4554. ;
  4555. ; If we already know carrier is lost, do not check for it again or loop
  4556. ; trying to output.
  4557. ;
  4558.      IF    COMFILE    AND TIMEON AND CLOCK
  4559.     LDA    OPTION
  4560.     CPI    'E'        ; Running locally?
  4561.     JNZ    MONOTE        ; No, continue
  4562.     MOV    A,C        ; Check character
  4563.     CPI    LF        ; One check per line
  4564.     CZ    TCHECK        ; Keep clock updated, TCHECK saves
  4565.                 ; Registers
  4566. MONOTE:     ENDIF            ; COMFILE AND TIMEON AND CLOCK
  4567. ;
  4568.     LDA    MDMOFF        ; Known loss of carrier?
  4569.     ORA    A
  4570.     PUSH    PSW
  4571.     CNZ    CONOUT        ; Output to local only
  4572.     POP    PSW
  4573.     RNZ            ; Then exit
  4574. ;
  4575. MOUTA:    CALL    CHECK        ; Carrier still on?
  4576.     CALL    MDOUTST        ; Check modem output status
  4577.     JZ    MOUTA
  4578.     MOV    A,C        ; Get character
  4579.     ANI    7FH        ; Strip parity bit
  4580.     RZ            ; Don't output DEL to remote
  4581.     CPI    60H        ; Check for lower case
  4582.     JC    MOUTP2        ; Skip if not lower case
  4583.     CPI    7FH        ; Check for rubout
  4584.     JZ    MOUTP2
  4585.     PUSH    H
  4586.     LXI    H,ULCSW        ; Subtract either 20H or nothing
  4587.     SUB    M
  4588.     POP    H
  4589.     MOV    C,A        ; Force on local as well as remote
  4590. ;
  4591. MOUTP2:    CPI    LF        ; We have a toggle for line feeds
  4592.     JNZ    MOUTP3        ; Nope, not a LF
  4593. ;
  4594.      IF    TIMEON
  4595.     CALL    TCHECK        ; Update/check clock and timeon
  4596.      ENDIF            ; TIMEON
  4597. ;
  4598.     LDA    LFEEDS        ; Yes, see if we can send it...
  4599.     ORA    A        ; Set flags
  4600.     MVI    A,0        ; Prepare with a null
  4601.     JNZ    MOUTP3        ; Nope, don't (instead, send a null)
  4602.     MVI    A,LF        ; Yes, it's ok to send the line feed
  4603. ;
  4604. MOUTP3:    CALL    MDOUTP        ; Output character to modem
  4605. ;
  4606.     PUSH    PSW        ; Save character
  4607.     CPI    'G'-'@'        ; Is it a bell?
  4608.     JNZ    NOTBEL
  4609.     LDA    BELLON        ; Get flag
  4610.     ORA    A
  4611.     JZ    ISBELL
  4612. ;
  4613. NOTBEL:    CALL    CONOUT        ; Send to regular BIOS
  4614. ;
  4615. ISBELL:    POP    PSW        ; Get character again
  4616. ;
  4617. ;
  4618. ; Check for nulls
  4619. ;
  4620.     CPI    LF        ; Time for nulls?
  4621.     RNZ            ; No, return
  4622. ;
  4623. ;
  4624. ; Send nulls if requested
  4625. ;
  4626.     LDA    NULLS        ; Get count
  4627.     ORA    A        ; Any?
  4628.     RZ            ; No
  4629.     PUSH    B
  4630.     MOV    B,A        ; Save count
  4631. ;
  4632. NULLP:    CALL    MDOUTST        ; Modem ready?
  4633.     JZ    NULLP
  4634.     XRA    A        ; 00H is a null
  4635.     CALL    MDOUTP        ; Send a null
  4636.     DCR    B        ; Another?
  4637.     JNZ    NULLP        ; Yes, loop
  4638.     POP    B
  4639.     RET
  4640. ;.....
  4641. ;
  4642. ;
  4643. ;-----------------------------------------------------------------------
  4644. ;
  4645. ; Move (HL) to (DE), length in (B)
  4646. ;
  4647. MOVE:    MOV    A,M        ; Get a byte
  4648.     STAX    D        ; Put at new home
  4649.     INX    D        ; Bump pointers
  4650.     INX    H
  4651.     DCR    B        ; Decrement byte count
  4652.     JNZ    MOVE        ; If more, do it
  4653.     RET            ; If not, return
  4654. ;.....
  4655. ;
  4656. ;
  4657. ;-----------------------------------------------------------------------
  4658. ;
  4659. ; Modem status test and no-activity timer routine
  4660. ;
  4661. MSTAT:     IF    NOT CPM3
  4662.     CALL    BDCHEK        ; Set 6 to safety
  4663.      ENDIF            ; NOT CPM3
  4664. ;
  4665.     CALL    CONSTAT
  4666.     ORA    A
  4667.     JNZ    MSTAT0
  4668.     LDA    MDMOFF
  4669.     ORA    A
  4670.     MVI    A,0
  4671.     RNZ            ; Don't let remote input while modem is
  4672.                 ; Muted
  4673.     CALL    CHECK        ; Check for carrier lost
  4674.     CALL    MDINST        ; Get modem input status
  4675.     ORA    A        ; Character available?
  4676.     JZ    MSTAT1        ; Nope
  4677. MSTAT0:
  4678.     PUSH    PSW        ; Yep, save return status
  4679.     XRA    A        ; Clear no-activity flag
  4680.     STA    MSFLAG
  4681.     POP    PSW        ; Restore return status
  4682.     RET            ; And return
  4683. ;
  4684. MSTAT1:    LDA    MSFLAG        ; Get the no-activity flag
  4685.     ORA    A        ; First time here?
  4686.     MVI    A,0FFH        ; Reset virgin flag in all cases
  4687.     STA    MSFLAG
  4688.     JNZ    MSTAT3        ; Nope
  4689.     LDA    TOVAL        ; Yep, get number of minutes to wait
  4690. MSTAT2:    STA    TOCNTM        ; Initialize minutes counter
  4691.     PUSH    H        ; Save registers
  4692.     LXI    H,42000        ; Initialize loop counter
  4693.     SHLD    TOCNT
  4694.     POP    H        ; Restore registers
  4695. MSTAT3:    CALL    KDELAY        ; Wait a millisecond
  4696.     PUSH    H        ; Save registers
  4697.     LHLD    TOCNT        ; Get the loop counter
  4698.     DCX    H        ; Bump down
  4699.     SHLD    TOCNT        ; And save
  4700.     MOV    A,H        ; Done this loop?
  4701.     ORA    L
  4702.     POP    H        ; Restore registers
  4703.     JZ    MSTAT4        ; Yep
  4704.     XRA    A        ; Nope, clear return status
  4705.     RET            ; And return
  4706. MSTAT4:    MVI    A,'G'-'@'    ; Beep the user
  4707.     CALL    MDOUTP
  4708.     LDA    TOCNTM        ; Bump down minutes counter
  4709.     DCR    A        ; Done?
  4710.     JNZ    MSTAT2        ; Nope
  4711. ;
  4712. TMOUT:    LXI    H,ITOMSG    ; Yep, caller time-out
  4713.     LXI    SP,STACK    ; Restore stack
  4714.     CALL    PRINTB
  4715.     CALL    PATCH        ; In case LUX was running
  4716. ;
  4717.      IF    DISKLOG
  4718.     XRA    A
  4719.     STA    BDOSFL
  4720.     LXI    H,TMOMSG
  4721.     CALL    WRTMSG        ; Put input timeout into log file
  4722.      ENDIF            ; DISKLOG
  4723. ;
  4724.      IF    MBBS
  4725.     JMP    NORPTC        ; Let mbbs/login log him off
  4726.      ENDIF            ; MBBS
  4727. ;
  4728.      IF    NOT MBBS
  4729.     JMP    LOGOFF        ; Check for exit file
  4730.      ENDIF            ; NOT MBBS
  4731. ;.....
  4732. ;
  4733. ;
  4734. ;-----------------------------------------------------------------------
  4735. ;
  4736. ; This is the jmp table which is copied on top of the one pointed to by
  4737. ; location 1 in CP/M.
  4738. ;
  4739. NEWJTBL:JMP    MCBOOT        ; Cold boot
  4740.     JMP    MBOOT        ; Warm boot
  4741.     JMP    MSTAT        ; Modem status test
  4742.     JMP    MINPUT        ; Modem input routine
  4743.     JMP    MOUTPUT        ; Modem output routine
  4744. ;
  4745.      IF    (NOT HARDLOG) AND (NOT PRINTER)
  4746.     RET            ; Modem list device
  4747.     NOP
  4748.     NOP
  4749.     RET            ; Modem punch device
  4750.     NOP
  4751.     NOP
  4752.     RET            ; Modem reader device
  4753.     NOP
  4754.     NOP
  4755.      ENDIF            ; NOT HARDLOG AND NOT PRINTER
  4756. ;.....
  4757. ;
  4758. ;-----------------------------------------------------------------------
  4759. ;
  4760.      IF    MOTOR
  4761. DSKON:    PUSH    PSW        ; Save 'A' and flags
  4762.     MVI    A,DISKON    ; Turn on motors
  4763.     OUT    DISK
  4764.     PUSH    H        ; Now, wait a long time
  4765.     LXI    H,0000
  4766. ;
  4767. DSKLP:    XTHL
  4768.     XTHL
  4769.     DCX    H        ; Count loop
  4770.     MOV    A,H        ; Check if done?
  4771.     ORA    L
  4772.     JNZ    DSKLP
  4773.     POP    H        ; Restore HL
  4774.     POP    PSW        ; And 'A' and flags
  4775.     RET
  4776. ;
  4777. DSKOFF:    PUSH    PSW        ; Save 'A' and flags
  4778.     MVI    A,DISKOFF    ; Turn motors off
  4779.     OUT    DISK
  4780.     POP    PSW
  4781.     RET
  4782.      ENDIF            ; MOTOR
  4783. ;.....
  4784. ;
  4785. ;
  4786. ;-----------------------------------------------------------------------
  4787. ;
  4788. NWBCALL: IF    LOSER
  4789.     CALL    WMSTRT        ; Warm boot disk read
  4790.     CALL    PATCH        ; Fix BIOS again after WMSTRT
  4791.      ENDIF            ; LOSER
  4792. ;
  4793.      IF    NOT CPM3
  4794.     CALL    BDCHEK
  4795.      ENDIF            ; NOT CPM3
  4796. ;
  4797.     RET
  4798. ;.....
  4799. ;
  4800. ;
  4801. ;-----------------------------------------------------------------------
  4802. ;
  4803. ; Patch in the new JMP table (saving the old)
  4804. ;
  4805. PATCH:    LDA    PTFLAG
  4806.     ORA    A
  4807.     JNZ    SKPTH        ; Save the original jump table only once
  4808. ;
  4809.     CALL    TBLADDR        ; HL= CP/M BIOS jump table
  4810.     LXI    D,VCOLDBT    ; Point to save location
  4811.     MVI    B,24        ; Save all vectors
  4812.     CALL    MOVE        ; Move it
  4813.     LHLD    VCONOUT+1    ; Get the original CONOUT address
  4814.     SHLD    COVECT        ; Store for use with XMODEM programs
  4815. ;
  4816. ;
  4817. ; Now move the new JMP table to CP/M
  4818. ;
  4819. SKPTH:    CALL    TBLADDR        ; HL= CP/M BIOS jump table
  4820.     XCHG            ; Move it to 'DE'
  4821.     LXI    H,NEWJTBL    ; Point to new jump table
  4822.     CALL    MOVE        ; Move it
  4823.     MVI    A,0FFH
  4824.     STA    PTFLAG
  4825. ;
  4826.      IF    LOSER
  4827.     LXI    H,NWBCALL    ; Set new warm boot call
  4828.     SHLD    WBCALL+1    ; Store the new address
  4829.      ENDIF            ; LOSER
  4830. ;
  4831.     RET
  4832. ;.....
  4833. ;
  4834. ;
  4835. ;-----------------------------------------------------------------------
  4836. ;
  4837. ; PRNLOG is called to print out the BYE version # and USRLOG info.  It
  4838. ; can be called from outside the program, using the vector after MCBOOT.
  4839. ;
  4840. PRNLOG:    LXI    H,VMSG
  4841.     CALL    PRINTL
  4842.     CALL    CALSUM
  4843.     RET
  4844. ;
  4845. CALSUM:    LDA    CWCAR        ; Get 8 bit number
  4846.     LXI    H,ATMSN        ; Address to store ascii
  4847.     CALL    DEC8        ; And convert to ascii
  4848.     LXI    H,ATMSG        ; Print Callers with carrier detected
  4849.     CALL    PRINTL        ; To local crt
  4850. ;
  4851.      IF    B5IM        ; Print # of voice calls
  4852.     LDA    VCNUM
  4853.     LXI    H,VCMSN        ; Put ascii here
  4854.     CALL    DEC8
  4855.     LXI    H,VCMSG
  4856.     CALL    PRINTL
  4857.      ENDIF            ; B5IM
  4858. ;
  4859.      IF    PWRQD
  4860.     LDA    NWPWD        ; 8 bit counter
  4861.     LXI    H,NWMSD        ; Put ascii here
  4862.     CALL    DEC8
  4863.     LXI    H,NWMSG        ; Print callers who knew password
  4864.     CALL    PRINTL
  4865.      ENDIF            ; PWRQD
  4866. ;
  4867.     LXI    H,LFMSG
  4868.     CALL    PRINTL        ; Turn up a line
  4869.     RET            ; End of call summary
  4870. ;.....
  4871. ;
  4872. ;
  4873. ;-----------------------------------------------------------------------
  4874. ;
  4875. ; Readbyte routine - used to read the welcome file
  4876. ;
  4877.      IF    WELFILE
  4878. RDBYTE:    MOV    A,H        ; Time to read?
  4879.     ORA    A        ; If at 100H, no read required
  4880.     JZ    NORD
  4881. ;
  4882. ;
  4883. ; Have to read a sector
  4884. ;
  4885.     LXI    D,FCB
  4886.     MVI    C,READ
  4887.     CALL    BDOS
  4888.     ORA    A        ; Ok?
  4889.     MVI    A,1AH        ; Fake up EOF
  4890.     RNZ            ; Return EOF if bad
  4891.     LXI    H,80H
  4892. ;
  4893. NORD:    MOV    A,M        ; Get character
  4894.     INX    H        ; Point to next byte
  4895.     RET
  4896.      ENDIF            ; WELFILE
  4897. ;.....
  4898. ;
  4899. ;
  4900. ;-----------------------------------------------------------------------
  4901. ;
  4902. ; Calculate HL=CP/M's jump table, B=length
  4903. ;
  4904. TBLADDR:LHLD    1        ; Get BIOS pointer
  4905.     DCX    H        ; Skip to cold boot
  4906.     DCX    H
  4907.     DCX    H
  4908. ;
  4909.      IF    HARDLOG    OR PRINTER ; Retain list device?
  4910.     MVI    B,15        ; Don't move lister jump
  4911.      ENDIF            ; HARDLOG
  4912. ;
  4913.      IF    (NOT HARDLOG) AND (NOT PRINTER)
  4914.     MVI    B,24        ; Move all jumps
  4915.      ENDIF            ; NOT HARDLOG
  4916. ;
  4917.     RET
  4918. ;.....
  4919. ;
  4920. ;
  4921. ;-----------------------------------------------------------------------
  4922. ;
  4923. ; TSTBAUD attempts to read a CR, LF or CTL-C and returns with zero flag
  4924. ; if the character read is one of these three.
  4925. ;
  4926.      IF    NOT B5IM
  4927. TSTBAUD:CALL    MDCARCK        ; Check carrier first
  4928.     JZ    PREOFF        ; Carrier is gone, start over
  4929.     LDA    CDOFF
  4930.     INR    A
  4931.     STA    CDOFF
  4932.     CPI    60        ; Allow 1 minute for c/r detect
  4933.     JZ    PREOFF        ; Hangup and start over
  4934.     MVI    D,20        ; Check for 2 sec for current baud rate
  4935. ;
  4936. TSTB1:    MVI    B,1        ; At .1 sec intervals
  4937.     PUSH    D
  4938.     CALL    DELAY
  4939.     CALL    MDINST        ; See if character available
  4940.     ORA    A
  4941.     JZ    TSTB2        ; None yet
  4942.     CALL    MDINP        ; Yes, read the character
  4943.     ANI    7FH
  4944.     POP    D        ; Restore the stack
  4945.     JMP    TSTB3        ; And see if it is right character
  4946. ;
  4947. TSTB2:    POP    D        ; Restore DE
  4948.     DCR    D        ; And decrement the count
  4949.     MOV    A,D
  4950.     ORA    A        ; 2 sec's up??
  4951.     JNZ    TSTB1        ; No, try again
  4952.     MVI    A,0FFH        ; Dummy character
  4953. ;
  4954. TSTB3:    CPI    CR        ; If a CR
  4955.     RZ
  4956.     CPI    LF        ; If a LF
  4957.     RZ
  4958.     CPI    'C'-40H        ; If a CTL-C
  4959.     RET            ; Return with proper flags set
  4960.      ENDIF            ; NOT B5IM
  4961. ;.....
  4962. ;
  4963. ;
  4964. ;-----------------------------------------------------------------------
  4965. ;
  4966. UNPATCH:CALL    TBLADDR        ; HL= CP/M BIOS jump table
  4967.     XCHG            ; Move to DE
  4968.     LXI    H,VCOLDBT    ; Get saved table
  4969.     CALL    MOVE        ; Move original table back
  4970. ;
  4971.      IF    LOSER
  4972.     LXI    H,WMSTRT    ; Load old call location
  4973.     SHLD    WBCALL+1    ; Restore old call
  4974.      ENDIF            ; LOSER
  4975. ;
  4976.     RET
  4977. ;.....
  4978. ;
  4979. ;
  4980. ;-----------------------------------------------------------------------
  4981. ;
  4982. USRCHK:    CALL    PRNLOG        ; Give info
  4983.     LXI    H,RS1MSG
  4984.     CALL    PRINTL        ; Prompt to resume waiting for ring
  4985. ;
  4986. PRNREL:    CALL    CONSTAT        ; Reply?
  4987.     ORA    A
  4988.     JZ    PRNREL        ; Wait until answered
  4989.     CALL    VCONIN        ; Then get it
  4990.     CPI    60H        ; Lower case?
  4991.     JC    $+5        ; Skip conversion
  4992.     SBI    20H        ; Else make upper case
  4993.     CPI    'E'        ; Execute com file?
  4994.     JZ    USRUN        ; Yes
  4995.     CPI    'J'        ; Jump to cp/m with BYE5 patched?
  4996.     JZ    JMPCPM        ; Yes, exit to cp/m with BYE5 patched
  4997.     CPI    'R'        ; Is answer resume?
  4998.     JZ    PRNRES        ; Go do it if so
  4999.     LXI    H,CRMSG
  5000.     CALL    PRINTL        ; Turn up a fresh line
  5001.     JNZ    EXCPM        ; And warm boot CP/M
  5002. ;
  5003. PRNRES:    LXI    H,RS2MSG
  5004.     CALL    PRINTL        ; Resume via BDOS after message
  5005. ;
  5006.      IF    CLRSCR
  5007.     CALL    CLEARIT        ; Clear the screen
  5008.      ENDIF            ; CLRSCR
  5009. ;
  5010.     RET
  5011. ;
  5012. USRUN:    MVI    A,'E'
  5013.     STA    OPTION        ; Fake it
  5014.     JMP    ERUN        ; For Sysop
  5015. ;
  5016. JMPCPM:     IF    B5IM
  5017.     CALL    IMQUIT        ; Fix modem so it won't answer
  5018.      ENDIF            ; B5IM
  5019. ;
  5020.      IF    NOT B5IM
  5021.     CALL    MDQUIT
  5022.      ENDIF            ; NOT B5IM
  5023. ;
  5024.     CALL    PATCH        ; Leave BYE5 attached
  5025.     MVI    A,0C3H
  5026.     STA    000H        ; Restore JMP instruction
  5027.     MVI    A,0FFH        ; And set all the right flags
  5028.     STA    MDMOFF
  5029.     STA    OPTION
  5030.     STA    WRTLOC
  5031. ;
  5032.      IF    ZCPR2 OR ZCPR3
  5033.     STA    WHEEL        ; Including wheel byte for sysop
  5034.      ENDIF            ; ZCPR
  5035. ;
  5036.     JMP    000H        ; Warmboot with BYE5 attached
  5037. ;.....
  5038. ;
  5039. ;
  5040. ;-----------------------------------------------------------------------
  5041. ;        WELCOME routine (note no extent used)
  5042. ;
  5043. ; Welcome to the system
  5044. ;
  5045. WELCOME: IF    CLOCK
  5046.     CALL    TIME        ; Read current time
  5047.     LDA    CCHOUR        ; And set
  5048.     STA    LHOUR        ; The users
  5049.     LDA    CCMIN        ; Login
  5050.     STA    LMIN        ; Time for later use
  5051.      ENDIF            ; CLOCK
  5052. ;
  5053.      IF    DISKLOG
  5054.     CALL    OPENLOG        ; Make sure the log file is on
  5055.     LXI    H,RTCBUF+5
  5056.     LXI    D,CDAY
  5057.     CALL    DATEMSG        ; Put month into message
  5058.     CALL    PUTSL        ; Put a slash
  5059.     CALL    DATEMSG        ; Put day into message
  5060.     CALL    PUTSL
  5061.     LXI    H,RTCBUF+4
  5062.     CALL    DATEMSG        ; Put year into message
  5063.     LDA    MSPEED        ; Get speed
  5064.     ADI    '0'        ; Make it ascii
  5065.     STA    CONMS1        ; Stuff it into message
  5066.     LXI    H,CONMSG
  5067.     CALL    WRTMSG        ; Put connect message into log file
  5068.      ENDIF            ; DISKLOG
  5069. ;
  5070.      IF    TIMEON OR CLOCK
  5071.     MVI    A,MAXMIN    ; Set number of minutes
  5072.     STA    MXTIME        ; Into mxtime
  5073.     XRA    A
  5074.     STA    TCHKFG        ; Show it's ok to check time
  5075.      ENDIF            ; TIMEON OR CLOCK
  5076. ;
  5077.      IF    COMFILE
  5078.     LDA    OPTION
  5079.     CPI    'E'
  5080.     MVI    A,0        ; Prepare default nulls in case
  5081.     STA    NULLS
  5082.     JZ    WELC1        ; Skip this if running locally
  5083.      ENDIF            ; COMFILE
  5084. ;
  5085.     LDA    MSPEED
  5086.     ADI    3        ; Value for nulls until BBS resets it
  5087.     STA    NULLS
  5088. ;
  5089.     LXI    H,TERMSG
  5090.     CALL    PRINTB        ; Let sysop/caller know you're online
  5091.     CALL    MDINP
  5092.     CALL    MDINP        ; Clear garbage from modem input
  5093. ;
  5094.      IF    NOT SKTERM
  5095.     CALL    MINPUT        ; Accept any character, then proceed
  5096.      ENDIF            ; NOT SKTERM
  5097. ;
  5098. ;
  5099. WELC1:    LXI    H,CRMSG        ; Carriage Return, Line Feed
  5100.     CALL    PRINTB        ; Send this message
  5101. ;
  5102.      IF    RSPEED
  5103.     LDA    OPTION
  5104.     CPI    'E'        ; Running locally?
  5105.     JZ    SPDOK        ; Yes, skip this
  5106.     XRA    A        ; Clear status
  5107.     LDA    MSPEED        ; See what speed the user is at
  5108.     SUI    SPEED        ; Is it acceptable?
  5109.     JNC    SPDOK        ; Yes, continue
  5110.     CALL    TIME        ; Get current time
  5111.     MVI    A,HOUR1        ; Start of prime-time
  5112. ;
  5113. SPD01:    LXI    H,CCHOUR    ; Point at current hour
  5114.     CMP    M        ; Equal?
  5115.     JZ    SPDOFF        ; Yes, dump him
  5116.     INR    A        ; Check for
  5117.     CPI    HOUR2        ; End of prime-time
  5118.     JZ    SPDOK        ; Not prime-time so let him on
  5119.     CPI    24        ; Past midnight?
  5120.     JNZ    SPD01        ; No, continue
  5121.     XRA    A        ; Yes set to 00 hour
  5122.     JMP    SPD01        ; And continue
  5123. ;
  5124. SPDOFF:    LXI    H,OFFMSG    ; Point at logoff message
  5125.     CALL    PRINTB        ; And tell him why
  5126.     JMP    PREOFF        ; Then log him off
  5127.      ENDIF            ; RSPEED
  5128. ;
  5129. ;
  5130. ; Print the welcome file
  5131. ;
  5132. SPDOK:     IF    WELFILE
  5133.     LXI    H,WELFILN    ; Source
  5134.     LXI    D,FCB        ; Destination
  5135.     MVI    B,13        ; Length
  5136.     CALL    MOVE        ; Move the name
  5137.     LXI    D,80H        ; Set DMA address to 80H
  5138.     MVI    C,STDMA
  5139.     CALL    BDOS
  5140.     MVI    C,SETUSR    ; Set user number for WELCOME file
  5141.     MVI    E,WELUSR
  5142.     CALL    BDOS
  5143. ;
  5144. ;
  5145. ; Open the WELCOME file
  5146. ;
  5147.     MVI    C,SELDSK    ; Select default drive for WELCOME file
  5148.     MVI    E,WELDRV-'A'
  5149.     CALL    BDOS
  5150.     LXI    D,FCB
  5151.     CALL    OPENFIL
  5152. ;
  5153. ;
  5154. ; Did it exist?
  5155. ;
  5156.     JZ    PASSINT        ; No WELCOME file
  5157. ;
  5158. ;
  5159. ; Got a file, type it
  5160. ;
  5161.     XRA    A        ; A=0
  5162.     STA    FCBRNO        ; Zero record number
  5163.     LXI    H,100H        ; Get initial buffer pointer
  5164. ;
  5165. ;
  5166. ; Type the WELCOME file
  5167. ;
  5168. WELTYPE:CALL    RDBYTE        ; Get a byte
  5169.     CPI    'Z'-'@'        ; EOF?
  5170.     JZ    PASSINT        ; Yes, done
  5171.     MOV    C,A        ; Setup for type
  5172.     CALL    MOUTPUT        ; Type the character
  5173.     CALL    CONSTAT
  5174.     ORA    A
  5175.     JZ    WELT1
  5176.     CALL    CONIN
  5177.     JMP    WELT2
  5178. WELT1:    CALL    MSTAT        ; Check for character typed
  5179.     ORA    A
  5180.     JZ    WELTYPE        ; No, loop
  5181.     CALL    MINPUT        ; Yes, get character
  5182. WELT2:    CPI    'C'-'@'        ; Did user type a CTL-C to end listing?
  5183.     JZ    PASSINT
  5184.     CPI    'K'-'@'        ; CTL-K to end listing?
  5185.     JZ    PASSINT
  5186.     CPI    'K'        ; Capital-K to end listing?
  5187.     JZ    PASSINT
  5188.     CPI    'k'        ; Small-k to end listing?
  5189.     JZ    PASSINT
  5190.     CPI    'S'-'@'        ; CTL-S to delay listing?
  5191.     JNZ    WELTYPE        ; No, loop until EOF
  5192. ;
  5193. WAIT:    CALL    CONSTAT
  5194.     ORA    A
  5195.     JZ    WAIT1
  5196.     CALL    CONIN
  5197.     JMP    WAIT2
  5198. ;
  5199. WAIT1:    CALL    MSTAT
  5200.     ORA    A        ; Has another char been typed?
  5201.     JZ    WAIT        ; No, wait
  5202.     CALL    MINPUT        ; Yes, check character
  5203. ;
  5204. WAIT2:    CPI    'C'-'@'        ; Did user type a CTL-C to end listing?
  5205.     JZ    PASSINT
  5206.     CPI    'K'-'@'        ; CTL-K to end listing?
  5207.     JZ    PASSINT
  5208.     CPI    'K'        ; Capital-K to end listing?
  5209.     JZ    PASSINT
  5210.     CPI    'k'        ; Small-k to end listing?
  5211.     JNZ    WELTYPE        ; None of these, loop until EOF
  5212.      ENDIF            ; WELFILE
  5213. ;
  5214. ;
  5215. ; Get the password
  5216. ;
  5217. PASSINT: IF    PWRQD
  5218.     MVI    D,3        ; 3 tries at password
  5219. ;
  5220. PASSINP:LXI    H,PWMSG        ; Password message
  5221.     CALL    PRINTB        ; Send this message
  5222.     LXI    H,PASSWD    ; Point to password
  5223.     MVI    E,0        ; No missed letters
  5224. ;
  5225. PWMLP:    CALL    MINPUT        ; Get a character
  5226.     CPI    60H        ; Lower case?
  5227.     JC    NOTLC        ; No,
  5228.     ANI    5FH        ; Make upper case alpha
  5229. ;
  5230. NOTLC:    PUSH    PSW        ; Save character input
  5231.     CPI    20H        ; Is character a control code?
  5232.     JNC    PWDIS        ; Pass if displayable
  5233.     MVI    C,'^'        ; Dislay if control map to up arrow
  5234.     CALL    CONOUT
  5235.     POP    PSW
  5236.     PUSH    PSW
  5237.     ADI    40H
  5238. ;
  5239. PWDIS:    MOV    C,A
  5240.     CALL    CONOUT        ; Output character locally
  5241.     POP    PSW        ; Restore 'A' reg.
  5242.     CPI    'U'-40H        ; CTL-U?
  5243.     JZ    PASSINP        ; Yes, abort, and retry
  5244.     CMP    M        ; Match password?
  5245.     JZ    PWMAT
  5246.     MVI    E,1        ; No, show miss
  5247.     CPI    CR        ; CR?
  5248.     JNZ    PWMLP        ; No, wait for CR
  5249. ;
  5250. ;
  5251. ; Password did not match
  5252. ;
  5253. PWNMAT:    LXI    H,WRGMSG    ; Wrong password message
  5254.     CALL    PRINTB        ; Send this message
  5255.     DCR    D        ; More tries?
  5256.     JNZ    PASSINP        ; Yes
  5257.     JMP    PREOFF        ; No, go hang up
  5258. ;
  5259. ;
  5260. ; Character matched in password
  5261. ;
  5262. PWMAT:    INX    H        ; To next character
  5263.     CPI    CR        ; End?
  5264.     JNZ    PWMLP        ; No, loop
  5265. ;
  5266. ;
  5267. ; End of password, any missed characters?
  5268. ;
  5269.     MOV    A,E        ; Get flag
  5270.     ORA    A
  5271.     JNZ    PWNMAT        ; Not right
  5272. ;
  5273.     LXI    H,NWPWD        ; Get last value
  5274.     INR    M        ; And add one
  5275.      ENDIF            ; PWRQD
  5276. ;
  5277.      IF    COMFILE
  5278.     MVI    C,SETUSR
  5279.     MVI    E,COMUSR    ; Switch to .COM file user area
  5280.     CALL    BDOS
  5281.     MVI    C,SELDSK    ; In case welcome
  5282.     MVI    E,COMDRV-'A'    ; Is on different drive
  5283.     CALL    BDOS        ; Than com file
  5284.     MVI    A,' '        ; Fool the system so that the .COM file
  5285.     STA    FCB+1        ; Will see a space at FCB+1 for default
  5286.      ENDIF            ; COMFILE
  5287. ;
  5288. ; Either run the COM file or warmboot to cp/m
  5289. ;
  5290.      IF    ZCPR3 AND COMFILE
  5291.     CALL    DOZ3        ; ZCPR3 re-initialization
  5292.      ENDIF            ; ZCPR3 and COMFILE
  5293. ;
  5294.      IF    COMFILE
  5295.     CALL    PATCH        ; Run under bye if running "E" option
  5296.     CALL    100H        ; Execute com file
  5297.      ENDIF            ; COMFILE
  5298. ;
  5299.     JMP    0000H        ; Warm boot now for "normal" CP/M use
  5300. ;......
  5301. ;
  5302. PREOFF:
  5303.     LXI    SP,STACK    ; Insure valid stack
  5304.     CALL    IMDONE        ; Hangup the phone
  5305.     CALL    UNPATCH
  5306.     XRA    A
  5307.     STA    OPTION        ; Reset the local "E" option
  5308. ;
  5309.      IF    DISKLOG
  5310.     LXI    H,DSCMSG
  5311.     CALL    WRTMSG        ; Put disconnect msg into SYS.LOG
  5312.      ENDIF            ; DISKLOG
  5313. ;
  5314.     JMP    HANGUP        ; And prep for next call
  5315. ;.....
  5316. ;
  5317. ;-----------------------------------------------------------------------
  5318. ;           calculate user's elapsed time
  5319. ;
  5320. ; Calculate time on system.  Log him off if =>MAXMIN unless  WHEEL is
  5321. ; on, or MXTIME=0.  If MXTIME = 255, user not logged in.
  5322. ;
  5323.      IF    TIMEON OR CLOCK
  5324. TCHECK:    LDA    TCHKFG
  5325.     INR    A
  5326.     RZ            ; If mxtime was 255, user not logged in
  5327.     PUSH    B
  5328.     PUSH    D
  5329.     PUSH    H
  5330.      ENDIF            ; TIMEON OR CLOCK
  5331. ;
  5332.      IF    TIMEON AND (NOT    CLOCK)
  5333.     LDA    TON
  5334.     JMP    TCNCLK
  5335.      ENDIF            ; NOT CLOCK
  5336. ;
  5337.      IF    TIMEON AND CLOCK
  5338.     CALL    TIME        ; Get current time
  5339.     LDA    LHOUR        ; (LHOUR)=log-in hour 0-23
  5340.     CALL    TCX60        ; Convert to minutes, results in (HL)
  5341.     LDA    LMIN        ; (LMIN)=log-in minutes, 0-59
  5342.     LXI    D,0        ; Clear (DE)
  5343.     MOV    E,A        ; (LMIN) to (DE)
  5344.     DAD    D        ; (HL)+(DE)=(HL)
  5345.     PUSH    H        ; Save log-in minutes on stack
  5346.     LDA    CCHOUR        ; (CCHOUR)=current hour, 0-23
  5347.     LXI    H,LHOUR        ; Let's see if we crossed midnight
  5348.     SUB    M
  5349.     JNC    TCOK        ; No, we're ok
  5350.     LDA    CCHOUR        ; Yes, let's add 24
  5351.     ADI    24
  5352.     STA    CCHOUR        ; Now we're ok
  5353. ;
  5354. TCOK:    LDA    CCHOUR        ; (CCHOUR) is now => than (LHOUR)
  5355.     CALL    TCX60        ; Convert it to minutes
  5356.     LDA    CCMIN        ; Current minutes, 0-59
  5357.     LXI    D,0        ; Clear (DE)
  5358.     MOV    E,A        ; CCMIN to (DE)
  5359.     DAD    D        ; (HL) now has current time in minutes
  5360.     POP    D        ; (DE) now has log-in time
  5361.     CALL    TCDIF        ; Get the difference, (HL)-(DE)=(HL)
  5362.     MOV    A,L        ; Only save LSB, 0-255 is plenty
  5363.     STA    TON        ; And save it
  5364.      ENDIF            ; TIMEON AND CLOCK
  5365. ;
  5366.      IF    TIMEON
  5367. TCNCLK:    LXI    H,TONMSD    ; (A)=TON, (HL)=address to store ascii
  5368.     CALL    DEC8        ; Convert timeon to ascii
  5369.     LDA    TON
  5370.     MOV    B,A
  5371.     LDA    MXTIME
  5372.     SUB    B        ; Calculate time-left
  5373.     LXI    H,TLNMSD
  5374.     CALL    DEC8        ; And save it as ascii
  5375.     POP    H
  5376.     POP    D
  5377.     POP    B
  5378.      ENDIF            ; TIMEON
  5379. ;
  5380.      IF    TIMEON AND (ZCPR2 OR ZCPR3)
  5381.     LDA    WHEEL
  5382.     ORA    A        ; Maybe he typed his password for user
  5383.     RNZ
  5384.      ENDIF            ; TIMEON AND ZCPR
  5385. ;
  5386.      IF    TIMEON
  5387.     LDA    MXTIME
  5388.     ORA    A        ; Special user?
  5389.     RZ            ; Yes, exit
  5390.     PUSH    B        ; Else, check his timeon
  5391.     MOV    B,A        ; Move it to 'B'
  5392.     LDA    TON
  5393.     SUB    B        ; Subtract max time allowed
  5394.     POP    B
  5395.     RC            ; Still time left
  5396.     LXI    SP,STACK    ; Insure valid stack
  5397.     MVI    A,255
  5398.     STA    TCHKFG        ; Reset time flag
  5399.     XRA    A
  5400.     LXI    H,TLNMSD
  5401.     CALL    DEC8        ; Make sure time-left =0
  5402.     LXI    H,TIMEUP    ; Time is up, inform user
  5403.     CALL    PRINTB
  5404.     CALL    PATCH        ; In case LUX was running
  5405.      ENDIF            ; TIMEON
  5406. ;
  5407.      IF    DISKLOG    AND TIMEON
  5408.     XRA    A
  5409.     STA    BDOSFL
  5410.     LXI    H,TLMMSG
  5411.     CALL    WRTMSG        ; Put time limit message into log file
  5412.      ENDIF            ; DISKLOG AND TIMEON
  5413. ;
  5414.      IF    MBBS AND TIMEON
  5415.     XRA    A
  5416.     STA    MXTIME
  5417.     JMP    NORPTC        ; Let login do it
  5418.      ENDIF            ; MBBS AND TIMEON
  5419. ;
  5420.      IF    TIMEON AND (NOT    MBBS)
  5421.     JMP    LOGOFF        ; Check for exit file
  5422.      ENDIF            ; TIMEON AND NOT MBBS
  5423. ;.....
  5424. ;
  5425. ; TCX60 will multiply (A)x60, results in (HL).
  5426. ;
  5427.      IF    CLOCK
  5428. TCX60:    LXI    H,0        ; (HL)=0
  5429.     ORA    A
  5430.     RZ            ; If (A)=0, no x60 needed
  5431.     LXI    D,60        ; Multiplier
  5432. ;
  5433. TCX61:    DAD    D        ; X60
  5434.     DCR    A        ; Done?
  5435.     JNZ    TCX61        ; No
  5436.     RET
  5437. ;.....
  5438. ;
  5439. ;
  5440. ; TCDIF will subtract (DE) from (HL), results in (HL).
  5441. ; (HL) normally has the larger number
  5442. ;
  5443. TCDIF:    MOV    A,L        ; LSB of (HL)
  5444.     SUB    E        ; LSB of (DE)
  5445.     MOV    L,A        ; Back to L
  5446.     MOV    A,H        ; MSB of (HL)
  5447.     SBB    D        ; MSB of (DE) and carry flag
  5448.     MOV    H,A        ; (HL) now has difference
  5449.     RET
  5450.      ENDIF            ; CLOCK
  5451. ;
  5452. ;-----------------------------------------------------------------------
  5453. ;             BCD to Binary converter
  5454. ;
  5455. ; This routine will convert an 8 bit BCD number (0-99) to binary.
  5456. ;
  5457. ;  To use:
  5458. ;    LDA    BCDNUMBER
  5459. ;    CALL    BCDBIN
  5460. ;
  5461. ; The routine returns with the binary number in the 'A' register.
  5462. ;
  5463.      IF    BCD2BIN
  5464. BCDBIN:    PUSH    D
  5465.     MOV    E,A        ; Save original byte
  5466.     ANI    15
  5467.     MOV    D,A        ; Save low nibble
  5468.     MOV    A,E
  5469.     ANI    240        ; Mask LSN
  5470.     RRC            ; X2
  5471.     MOV    E,A
  5472.     RRC            ; X4
  5473.     RRC            ; X8
  5474.     ADD    E        ; X10
  5475.     ADD    D        ; Low nibble
  5476.     POP    D
  5477.     RET
  5478. ;
  5479.      ENDIF            ; BCD2BIN
  5480. ;.....
  5481. ;
  5482. ;
  5483. ; BINBCD will convert a 0-99 binary number to 0-99 BCD number.    Call
  5484. ; with (A)=binary number 0-99. (A)=0-99 BCD on exit
  5485. ;
  5486.      IF    BIN2BCD
  5487. BINBCD:    PUSH    D
  5488.     MVI    E,255        ; -1
  5489. ;
  5490. BLP:    INR    E        ; Increment tens counter
  5491.     SUI    10        ; Subtract 10 each pass
  5492.     JNC    BLP
  5493.     ADI    10        ; Get back number
  5494.     MOV    D,A
  5495.     MOV    A,E
  5496.     RLC            ; Shift over to MSN
  5497.     RLC
  5498.     RLC
  5499.     RLC
  5500.     ADD    D        ; Add in ones position
  5501.     POP    D
  5502.     RET
  5503.      ENDIF            ; BIN2BCD
  5504. ;.....
  5505. ;
  5506. ;
  5507. ;-----------------------------------------------------------------------
  5508. ;
  5509. ; DEC8 will convert an 8 bit binary number in A to 3 ASCII bytes.
  5510. ; HL points to the MSB location where the ASCII bytes will be stored.
  5511. ; Leading zeros are suppressed and spaces are stored in unused bytes.
  5512. ;
  5513. DEC8:    PUSH    PSW
  5514.     PUSH    H
  5515.     MVI    A,' '
  5516.     MOV    M,A        ; Clear destination with spaces
  5517.     INX    H
  5518.     MOV    M,A
  5519.     INX    H
  5520.     MOV    M,A
  5521.     POP    H
  5522.     POP    PSW
  5523.     PUSH    B
  5524.     PUSH    D
  5525.     MVI    E,0        ; Leading zero flag
  5526.     MVI    D,100
  5527. ;
  5528. DEC81:    MVI    C,'0'-1
  5529. ;
  5530. DEC82:    INR    C
  5531.     SUB    D        ; 100 or 10
  5532.     JNC    DEC82        ; Still +
  5533.     ADD    D        ; Now add it back
  5534.     MOV    B,A        ; Remainder
  5535.     MOV    A,C        ; Get 100/10
  5536.     CPI    '1'        ; Zero?
  5537.     JNC    DEC84        ; Yes
  5538.     MOV    A,E        ; Check flag
  5539.     ORA    A        ; Reset?
  5540.     MOV    A,C        ; Restore byte
  5541.     JZ    DEC85        ; Leading zeros are skipped
  5542. ;
  5543. DEC84:    MOV    M,A        ; Store it in buffer pointed at by HL
  5544.     INX    H        ; Increment storage location
  5545.     MVI    E,0FFH        ; Set zero flag
  5546. ;
  5547. DEC85:    MOV    A,D
  5548.     SUI    90        ; 100 to 10
  5549.     MOV    D,A
  5550.     MOV    A,B        ; Remainder
  5551.     JNC    DEC81        ; Do it again
  5552.     ADI    '0'        ; Make ascii
  5553.     MOV    M,A        ; And store it
  5554.     POP    D
  5555.     POP    B
  5556.     RET
  5557. ;.....
  5558. ;
  5559. ;
  5560. ;-----------------------------------------------------------------------
  5561. ;
  5562.      IF    CHGPATH        ; To alter path
  5563. REMPAT:    LXI    H,REMPATH    ; Source=remote path
  5564.     LXI    D,EXTPATH    ; Dest=external path at 0040H
  5565.     MVI    B,LREMP        ; Length of remote path
  5566.     CALL    MOVE
  5567.     RET
  5568. ;
  5569. SYSPAT:    LXI    H,SYSPATH    ; Source=SYSOP's path
  5570.     LXI    D,EXTPATH    ; Dest=external path at 0040H
  5571.     MVI    B,LSYSP        ; Length of new path
  5572.     CALL    MOVE
  5573.     RET
  5574.      ENDIF            ; CHGPATH
  5575. ;.....
  5576. ;
  5577. ;
  5578. ;-----------------------------------------------------------------------
  5579. ;          SCB manipulation for CP/M Plus
  5580. ;
  5581. ; Set SCB byte at offset in [B] to value in [A]
  5582. ;
  5583.      IF    CPM3
  5584. SETSCB:    LHLD    SCBBASE        ; Get SCB pointer
  5585.     MOV    L,B        ; Set the offset
  5586.     MOV    M,A        ; Save the byte
  5587.     RET
  5588. ;
  5589. ;
  5590. ; Get SCB byte at offset in [B] to [A]
  5591. ;
  5592. GETSCB:    LHLD    SCBBASE        ; Get SCB pointer
  5593.     MOV    L,B        ; Set the offset
  5594.     MOV    A,M        ; Get the byte
  5595.     RET
  5596. ;
  5597. ;
  5598. ; Set user number to value in [A]
  5599. ;
  5600. SETUSER:MVI    B,0B0H        ; B0 = CCP user number
  5601.     CALL    SETSCB        ; Set CCP user number
  5602.     MVI    B,0E0H        ; E0 = BDOS user number
  5603.     JMP    SETSCB        ; Set BDOS user number
  5604. ;
  5605. ;
  5606. ; Set drive to value in [B]
  5607. ;
  5608. SETDRIVE:
  5609.     MVI    B,0AFH        ; AF = CCP drive
  5610.     CALL    SETSCB        ; Set CCP drive
  5611.     MVI    B,0DAH        ; DA = BDOS drive
  5612.     JMP    SETSCB        ; Set BDOS drive
  5613.      ENDIF            ; CPM3
  5614. ;.....
  5615. ;
  5616. ;        End of SCB manipulation routines
  5617. ;-----------------------------------------------------------------------
  5618. ;
  5619.      IF    NOT CPM3
  5620. ENDOBJ    EQU    $
  5621.      ENDIF            ; NOT CPM3
  5622. ;
  5623. ;           end of main body of program
  5624. ;-----------------------------------------------------------------------
  5625. ;
  5626. ;  ------------------------------------------------
  5627. ;  START B5IM COMMANDS    (Set B5IM EQU YES to use this)
  5628. ;  ------------------------------------------------
  5629. ;
  5630.      IF    B5IM AND DOATZ
  5631. B5ATZ:    DB    'ATZ',CR,0    ; Reset modem
  5632.      ENDIF            ; B5IM AND DOATZ
  5633. ;
  5634.      IF    B5IM AND NODTR
  5635. B5ESC:    DB    '+++',0        ; Escape sequence for command mode
  5636. B5ATH:    DB    'ATH',CR,0    ; Hangup phone
  5637.      ENDIF            ; B5IM AND NODTR
  5638. ;
  5639.      IF    B5IM AND OFFHK
  5640. B5ATH1:    DB    'ATH1'        ; Take phone off-hook
  5641.      ENDIF            ; B5IM AND OFFHK
  5642. ;
  5643.      IF    B5IM AND OFFHK AND (NOT    ANCHOR)
  5644.     DB    'M0'        ; Make sure speaker is off
  5645.      ENDIF            ; OFFHK AND NOT ANCHOR
  5646. ;
  5647.      IF    B5IM AND OFFHK
  5648.     DB    CR,0        ; End the command line
  5649.      ENDIF            ; B5IM AND OFFHK
  5650. ;
  5651.      IF    B5IM
  5652. B5ATA:    DB    'ATA',CR,0    ; Answer the phone
  5653. ADDSTR:    DW    0        ; Address of command string
  5654. VCMSG:    DB    CR,LF,'Voice calls: '
  5655. VCMSN:    DB    '   ',0
  5656. VCNUM:    DB    0        ; Counter for voice calls
  5657.      ENDIF            ; B5IM
  5658. ;
  5659.      IF    B5IM AND PRGRSS
  5660. RCSHOW:    DB    '_',0        ; Will be stored by PRGRSS
  5661. NOEMSG:    DB    CR,LF,'Echo error',CR,LF,0
  5662. CMDERR:    DB    'Modem error',CR,LF,0
  5663.      ENDIF            ; B5IM AND PRGRSS
  5664. ;
  5665.      IF    B5IM
  5666. B5INIT:    DB    'AT'        ; Attention
  5667.      ENDIF            ; B5IM
  5668. ;
  5669.      IF    B5IM AND ECHO
  5670.     DB    'E1'        ; Echo back characters sent to modem
  5671.      ENDIF            ; B5IM AND ECHO
  5672. ;
  5673.      IF    B5IM AND (NOT ECHO)
  5674.     DB    'E0'        ; Don't do echo verification
  5675.      ENDIF            ; B5IM AND NOT ECHO
  5676. ;
  5677.      IF    B5IM
  5678.     DB    'Q0'        ; Send result codes
  5679.     DB    'V0'        ; Terse mode
  5680.     DB    'S2=128'    ; Change + to different character
  5681.      ENDIF            ; B5IM
  5682. ;
  5683.      IF    B5IM AND (NOT NOATA)
  5684.     DB    'S0=0'        ; No auto-answer (we will use 'ATA')
  5685.      ENDIF            ; B5IM AND NOT NOATA
  5686. ;
  5687.      IF    B5IM AND NOATA
  5688.     DB    'S0=1'        ; Will answer on first ring
  5689.      ENDIF            ; B5IM AND NOATA
  5690. ;
  5691.      IF    B5IM AND SHORTB
  5692.     DB    CR,0
  5693. B5INT1:    DB    'AT'
  5694.      ENDIF            ; B5IM AND SHORTB
  5695. ;
  5696.      IF    B5IM AND (NOT ANCHOR)
  5697.     DB    'M0'        ; Speaker off
  5698.     DB    'S10=25'    ; 2 1/2 sec wait after carrier loss to
  5699.                 ; Hang up
  5700.      ENDIF            ; B5IM AND NOT ANCHOR
  5701. ;
  5702.      IF    B5IM AND (NOT HS300) AND (NOT ANCHOR)
  5703.     DB    'X1'        ; Extended response codes beyond '4'
  5704.      ENDIF            ; B5IM AND NOT HS300 AND NOT ANCHOR
  5705. ;
  5706.      IF    B5IM
  5707.     DB    'H0'        ; Put modem on-hook
  5708.     DB    CR,0        ; CR finishes command string
  5709.      ENDIF            ; B5IM
  5710. ;
  5711.      IF    B5IM AND (NOT OFFHK)
  5712. B5USR:    DB    'ATS0=0',CR,0    ; This helps the Password and S-100
  5713.      ENDIF            ; B5IM
  5714. ;.....
  5715. ;
  5716. ;          end of B5IM command strings
  5717. ;-----------------------------------------------------------------------
  5718. ;                messages
  5719. ;
  5720.      IF    PRGRSS AND (NOT    B5IM)
  5721. MSG30:    DB    '300 baud test',CR,LF,0
  5722. MSG12:    DB    '1200 baud test',CR,LF,0
  5723. MSG24:    DB    '2400 baud test',CR,LF,0
  5724.      ENDIF            ; PRGRSS AND (NOT B5IM)
  5725. ;
  5726. ;
  5727. ; Program version number message
  5728. ;
  5729. VMSG:    DB    CR,LF,'BYE',MAIN+'0'
  5730.     DB    VERS/10+'0',VERS MOD 10+'0',' - '
  5731.     DB    MONTH/10+'0',MONTH MOD 10+'0','/'
  5732.     DB    DAY/10+'0',DAY MOD 10+'0','/'
  5733.     DB    YEAR/10+'0',YEAR MOD 10+'0',CR,LF,LF,0
  5734. ;
  5735. CLRSEQ:    DB    CLRCH1,CLRCH2,CLRCH3,CLRCH4,CLRCH5,CLRCH6,0
  5736. ;
  5737.      IF    RVIDEO
  5738. RVIDON:    DB    RVON1,RVON2,RVON3,RVON4,0
  5739. RVIDOFF:DB    RVOFF1,RVOFF2,RVOFF3,RVOFF4,0
  5740.      ENDIF            ; RVIDEO
  5741. ;
  5742. BELMSG:    DB    7,7,0        ; Alert sysop that system is available
  5743. CDOFF:    DB    0
  5744. OPTION:    DB    0
  5745. ;
  5746.      IF    RSPEED
  5747. OFFMSG:    DB    CR,LF,'Sorry, only 1200 or 2400 bps allowed from '
  5748.     DB    '7PM-11PM'
  5749.     DB    CR,LF,CR,LF,' Call back before/after 7-11PM Pacific'
  5750.     DB    CR,LF,0
  5751.      ENDIF            ; RSPEED
  5752. ;
  5753.      IF    TIMEON
  5754. TIMEUP:    DB    7,CR,LF,CR,LF
  5755.     DB    ' Your time is up - Please call back tomorrow..'
  5756.     DB    CR,LF,7,0
  5757. TONMSG:    DB    CR,LF,'Minutes on system: '
  5758. TONMSD:    DB    '0   ',CR,LF,0
  5759. TLNMSG:    DB    CR,LF,'Minutes left.... '
  5760. TLNMSD:    DB    '0   ',CR,LF,0
  5761.      ENDIF            ; TIMEON
  5762. ;
  5763. ;
  5764. ; Real-Time clock buffer.  Store BCD values into this area if TIMEON
  5765. ; is YES and your clock is read as BCD values for time and date.  Use
  5766. ; BCDBIN to convert HH and MM to binary and store those values in
  5767. ; CCHOUR and CCMIN.
  5768. ;
  5769. ; (NOTE: 99:99:99 INDICATES CLOCK IS NOT RUNNING OR NOT AVAILABLE)
  5770. ;
  5771. RTCBUF:    DB    99H,99H,99H    ; HH:MM:SS (BCD 24hr time)
  5772.                 ; 00:00:00-23:59:59
  5773.     DB    19H,85H,02H,18H    ; YYYY/MM/DD (BCD ISO date)
  5774. ;
  5775. TON:    DB    0,0        ; (Total time on system-binary integer)
  5776. CCHOUR:    DB    0        ; Current clock hour in binary
  5777. CCMIN:    DB    0        ; Current clock minute in binary
  5778. LHOUR:    DB    0        ; Login hour in binary
  5779. LMIN:    DB    0        ; Login minutes in binary
  5780. TCHKFG:    DB    0        ; Tcheck flag, 0 = OK, 255 = not OK to
  5781.                 ; Check
  5782. ;
  5783. CRMSG:    DB    CR,LF,CR,LF,0
  5784. ;
  5785. TERMSG:    DB    CR,LF,'BYE5', VERS/10+'0',VERS MOD 10+'0',' (c)'
  5786. ;
  5787.      IF    NOT SKTERM
  5788.     DB    ' - any key to continue: '
  5789.      ENDIF            ; NOT SKTERM
  5790. ;
  5791.     DB    0        ; End of message
  5792. ;
  5793. FKFLAG:    DB    0
  5794. PTFLAG:    DB    0
  5795. ;
  5796.      IF    PRNTGB
  5797. GBMSG:    DB    CR,LF,'  Goodbye, call again...',CR,LF,'      '
  5798.     DB    CR,LF,0
  5799.      ENDIF            ; PRNTGB
  5800. ;
  5801. LDMSG:    DB    CR,LF,'Load Successful...'
  5802.     DB    CR,LF,0
  5803. ;
  5804. RS1MSG:     IF    COMFILE
  5805.     DB    CR,LF,'<E>xecute .COM file,'
  5806.      ENDIF            ; COMFILE
  5807. ;
  5808.     DB    CR,LF,'<R>esume BYE,'
  5809.     DB    CR,LF,'<J>ump to CP/M with BYE5 attached,'
  5810.     DB    CR,LF,'<ret> for  normal unpatched  CP/M: ',0
  5811. ;
  5812. RS2MSG:    DB    '  Resuming...',CR,LF,0
  5813. ATMSG:    DB    CR,LF,'Modem calls: '
  5814. ATMSN:    DB    '   ',0
  5815. CWCAR:    DB    0        ; Counter for carrier detected calls
  5816. ;
  5817. ;
  5818. ; Access password (ends in carriage return) - keep password here
  5819. ;
  5820.      IF    PWRQD
  5821. PASSWD:    DB    'DDT'        ; The password itself
  5822.     DB    CR        ; End of password, CR-only to erase it
  5823. ;
  5824. ;
  5825. ; (Allow room for larger password to be entered, up to 10 characters)
  5826. ;
  5827.     DB    0,0,0,0,0,0,0
  5828. ;
  5829. PWMSG:    DB    CR,LF,'Enter Password: ',0
  5830. WRGMSG:    DB    'Incorrect password',CR,LF,0
  5831. NWMSG:    DB    CR,LF,'Passwords: '
  5832. NWMSD:    DB    '   ',0
  5833. NWPWD:    DB    0        ; Counter for correct password callers
  5834.      ENDIF            ; PWRQD
  5835. ;
  5836.      IF    CHEKDU
  5837. IDMSG:    DB    '> [Invalid drive]',0
  5838. IUMSG:    DB    '> [Invalid user#]',0
  5839.      ENDIF            ; CHEKDU
  5840. ;
  5841. CLMSG:    DB    CR,LF,LF,'[Carrier lost]',CR,LF,0
  5842. ITOMSG:    DB    CR,LF,LF,'[Input timed out]',7,CR,LF,0
  5843. LCDMSG:    DB    CR,LF,LF,'[Last call]',CR,LF,0
  5844. ULTMSG:    DB    CR,LF,'[Unlimited Time]',CR,LF,0
  5845. SCRMON:    DB    CR,LF,'[Remote on]',CR,LF,0
  5846. SCRMOFF:DB    CR,LF,'[Remote off]',CR,LF,0
  5847. BELMON:    DB    CR,LF,'[Bell on]',CR,LF,LF,0
  5848. BELMOFF:DB    CR,LF,'[Bell off]',CR,LF,LF,0
  5849. MFSMSG:    DB    CR,LF,'Message from Sysop: ',CR,LF,0
  5850. SGDMSG:    DB    CR,LF,'Going down in ',DOWNMIN+'0'
  5851.     DB    ' min.',CR,LF,0
  5852. LFMSG:    DB    CR,LF,0
  5853. LCDFLG:    DB    0
  5854. ;
  5855.      IF    PRNTWB
  5856. WBMSG:    DB    CR,LF,'Booting CP/M...',CR,LF
  5857.     DB    0
  5858.      ENDIF            ; PRNTWB
  5859. ;
  5860.      IF    CPM3
  5861. SCBPB:    DB    3AH,0        ; Parameter block for extracting SCB
  5862.                 ; Start address
  5863.      ENDIF            ; CPM3
  5864. ;
  5865.      IF    COMFILE    OR EXFILE
  5866. PTSMSG:    DB    '++ TPA too small ++',0
  5867. CNFMSG:    DB    '.COM ++ Not found-abort ++',CR,LF,0
  5868. ENTMSG:    DB    'Entry   ',0    ; Filled by loader
  5869. CFLMSG:    DB    '.COM loaded',CR,LF,LF,0
  5870.      ENDIF            ; COMFILE OR EXFILE
  5871. ;
  5872.      IF    EXFILE
  5873. EXTMSG:    DB    'Exit    ',0    ; Filled by loader
  5874.      ENDIF            ; EXFILE
  5875. ;
  5876.      IF    EXFIL1
  5877. EX1MSG:    DB    'HSAVE',0
  5878.      ENDIF            ; EXFIL1
  5879. ;
  5880.      IF    EXFIL2
  5881. EX2MSG:    DB    'HMNT',0
  5882.      ENDIF            ; EXFIL2
  5883. ;
  5884.      IF    EXFIL2 AND RAMDSK
  5885. EX3MSG:    DB    'BSAVE',0
  5886.      ENDIF            ; EXFIL2 AND RAMDSK
  5887. ;
  5888.      IF    MSGFIL
  5889. MSGFCB:    DB    0,'MFMSG   COM'    ; Put name of your message handler here
  5890.     DB    0,0,0,0,0,0,0    ; 21 for rest of FCB
  5891.     DB    0,0,0,0,0,0,0
  5892.     DB    0,0,0,0,0,0,0
  5893. MSGMSG:    DB    'MSGNAME ',0    ; Filled by loader
  5894.      ENDIF            ; MSGFIL
  5895. ;
  5896.      IF    WELFILE
  5897. WELFILN:DB    0,'WELCOME ???'    ; WELCOME file name, must be 11 chars.
  5898.     DB    0        ; WELCOME or WELCOME.TXT will work
  5899.      ENDIF            ; WELFILE
  5900. ;
  5901. CM2FCB:     IF    MBBS
  5902.     DB    0,'MBBS    COM'    ; For mbbs4n
  5903.     DB    0,0,0,0,0,0,0    ; 21 for rest of FCB
  5904.     DB    0,0,0,0,0,0,0
  5905.     DB    0,0,0,0,0,0,0
  5906.      ENDIF            ; MBBS
  5907. ;
  5908.      IF    COMFILE    AND RBBS
  5909. COMFCB:    DB    0,'RBBS    COM'    ; COM file name, must be 11 characters
  5910.     DB    0,0,0,0,0,0,0    ; 21 for rest of FCB
  5911.     DB    0,0,0,0,0,0,0
  5912.     DB    0,0,0,0,0,0,0
  5913.      ENDIF            ; COMFILE AND RBBS
  5914. ;
  5915.      IF    COMFILE    AND OXGATE
  5916. COMFCB:    DB    0,'OXENTR  COM'    ; OxGate entry module
  5917.     DB    0,0,0,0,0,0,0    ; 21 for rest of FCB
  5918.     DB    0,0,0,0,0,0,0
  5919.     DB    0,0,0,0,0,0,0
  5920.      ENDIF            ; COMFILE AND OXGATE
  5921. ;
  5922.      IF    COMFILE    AND METAL
  5923. COMFCB:    DB    0,'MENTR   COM'    ; Metal entry file
  5924.     DB    0,0,0,0,0,0,0    ; 21 for rest of FCB
  5925.     DB    0,0,0,0,0,0,0
  5926.     DB    0,0,0,0,0,0,0
  5927.      ENDIF            ; COMFILE AND METAL
  5928. ;
  5929.      IF    COMFILE    AND MBBS
  5930. COMFCB:    DB    0,'LOGIN   COM'    ; Mbbs entry file
  5931.     DB    0,0,0,0,0,0,0    ; 21 for rest of FCB
  5932.     DB    0,0,0,0,0,0,0
  5933.     DB    0,0,0,0,0,0,0
  5934.      ENDIF            ; COMFILE AND MBBS
  5935. ;
  5936.      IF    COMFILE    AND HBBS
  5937. COMFCB:    DB    0,'BBS     COM'    ; PBBS entry file
  5938.     DB    0,0,0,0,0,0,0    ; 21 more for fcb
  5939.     DB    0,0,0,0,0,0,0
  5940.     DB    0,0,0,0,0,0,0
  5941.      ENDIF            ; COMFILE AND HBBS
  5942. ;
  5943.      IF    COMFILE    AND QBBS
  5944. COMFCB:    DB    0,'QENTER  COM'    ; QBBS entry module
  5945.     DB    0,0,0,0,0,0,0    ; 21 for rest of FCB
  5946.     DB    0,0,0,0,0,0,0
  5947.     DB    0,0,0,0,0,0,0
  5948.      ENDIF            ; COMFILE AND QBBS
  5949. ;
  5950. EXITFCB: IF    EXFILE AND QBBS
  5951.     DB    0,'QEXIT   COM'    ; Exit filename, must be 11 characters
  5952.     DB    0,0,0,0,0,0,0    ; 21 for rest of FCB
  5953.     DB    0,0,0,0,0,0,0
  5954.     DB    0,0,0,0,0,0,0
  5955.      ENDIF            ; EXFILE AND QBBS
  5956. ;
  5957.      IF    EXFILE AND OXGATE
  5958.     DB    0,'OXEXIT  COM'    ; Exit filename, must be 11 characters
  5959.     DB    0,0,0,0,0,0,0    ; 21 for rest of FCB
  5960.     DB    0,0,0,0,0,0,0
  5961.     DB    0,0,0,0,0,0,0
  5962.      ENDIF            ; EXFILE AND OXGATE
  5963. ;
  5964.      IF    EXFILE AND METAL
  5965.     DB    0,'MEXIT   COM'    ; Exit filename, must be 11 characters
  5966.     DB    0,0,0,0,0,0,0    ; 21 for rest of FCB
  5967.     DB    0,0,0,0,0,0,0
  5968.     DB    0,0,0,0,0,0,0
  5969.      ENDIF            ; EXFILE AND METAL
  5970. ;
  5971.      IF    EXFILE AND HBBS
  5972.     DB    0,'HBYE    COM'    ; Exit filename, must be 11 characters
  5973.     DB    0,0,0,0,0,0,0    ; 21 for rest of FCB
  5974.     DB    0,0,0,0,0,0,0
  5975.     DB    0,0,0,0,0,0,0
  5976.      ENDIF            ; EXFILE AND HBBS
  5977. ;
  5978. EX1FCB:     IF    EXFIL1 AND HBBS
  5979.     DB    0,'HSAVE   COM'    ; Exit filename, must be 11 characters
  5980.     DB    0,'$S',0,0,0,0    ; 21 for rest of FCB
  5981.     DB    0,0,0,0,0,0,0
  5982.     DB    0,0,0,0,0,0,0
  5983.      ENDIF            ; EXFIL1 AND HBBS
  5984. ;
  5985. EX2FCB:     IF    EXFIL2 AND HBBS
  5986.     DB    0,'HMNT    COM'    ; Exit filename, must be 11 characters
  5987.     DB    0,'$S',0,0,0,0    ; 21 for rest of FCB
  5988.     DB    0,0,0,0,0,0,0
  5989.     DB    0,0,0,0,0,0,0
  5990.      ENDIF            ; EXFIL2 AND HBBS
  5991. ;
  5992. EX3FCB:     IF    EXFIL2 AND HBBS    AND RAMDSK
  5993.     DB    0,'BSAVE   COM'    ; Exit filename, must be 11 characters
  5994.     DB    0,'$S',0,0,0,0    ; 21 for rest of FCB
  5995.     DB    0,0,0,0,0,0,0
  5996.     DB    0,0,0,0,0,0,0
  5997.      ENDIF            ; EXFIL2 AND HBBS AND RAMDSK
  5998. ;
  5999. LCNAME:     IF    NO25TH OR MBBS
  6000.     DB    0,'LASTCALR???'    ; LASTCALR OR LASTCALR.DAT will be used
  6001.     DB    0
  6002.      ENDIF            ; NO25TH OR MBBS
  6003. ;
  6004. LCDATA:     IF    NO25TH OR MBBS
  6005.     DB    ' ',0
  6006.     DS    NO25BF-2    ; Size of buffer
  6007. LCFILL:    DB    '  L/C data N/A',0
  6008. LCHEAD:    DB    CR,0        ; Put your customized header here,
  6009.                 ; Terminate with a ,0
  6010.      ENDIF
  6011. ;
  6012.      IF    (NO25TH    OR MBBS) AND READLC
  6013. LCMSG1:    DB    'No L/C file',CR,LF,0
  6014.      ENDIF            ; NO25TH OR MBBS
  6015. ;
  6016.      IF    MBBS
  6017. MBBS1:    DB    CR,LF,'Loading for COMMENT before exiting...',CR,LF,LF,0
  6018. MBBS2:    DB    CR,LF,'[ Updating ]',CR,LF,0
  6019.      ENDIF            ; MBBS
  6020. ;
  6021. ;
  6022.      IF    DISKLOG
  6023. DSKLOG:    DB    0        ; Disk log open status
  6024. OPNMSG:    DB    CR,LF,'[Log on]',CR,LF,0 ; Function key message
  6025. CLSMSG:    DB    CR,LF,'[Log off]',CR,LF,0 ; Function key message
  6026. DSCMSG:    DB    '**DISCONNECT**',0 ; Log disconnect msg
  6027. CONMSG:    DB    '**CONNECT '    ; Connect message
  6028. CONMS1:    DB    '  on '
  6029. CDAY:    DS    8
  6030.     DB    '**',0
  6031.      ENDIF            ; DISKLOG
  6032. ;
  6033.      IF    DISKLOG    AND TIMEON
  6034. TLMMSG:    DB    '**TIME LIMIT**',0 ; Time limit message
  6035.      ENDIF            ; DISKLOG AND TIMEON
  6036. ;
  6037.      IF    DISKLOG
  6038. CARMSG:    DB    '**CARRIER LOST**',0 ; Carrier lost msg
  6039. TMOMSG:    DB    '**INPUT TIMEOUT**',0 ; Timout msg
  6040. DRPMSG:    DB    '**DROPPED**',0    ; Twit key message
  6041. VOCMSG:    DB    '**VOICE CALL**',0 ; Voice call msg
  6042. LOGFCB:    DB    LOGDRV-40H,'SYS     LOG' ; Log file fcb
  6043.     DS    24
  6044. WOFFSET:DB    0        ; Current write offset for log
  6045. OLDDMA:    DW    80H        ; Current DMA address
  6046. BDOSFL:    DB    0        ; BDOS call in progress flag
  6047. TIMSFL:    DB    0        ; Time stamp flag
  6048. LOGTOG:    DB    0        ; Log open toggle flag
  6049. OLDLUS:    DS    4        ; Old environment save area
  6050. RECORD:    DS    128        ; Log file buffer
  6051. HLSAVE:    DS    2        ; Temp HL save
  6052.     DS    40        ; Stack area for log routines
  6053. NEWSTK:    DS    0
  6054.      ENDIF            ; DISKLOG
  6055. ;.....
  6056. ;
  6057. ;
  6058. ;-----------------------------------------------------------------------
  6059. ;               ZCPR external paths
  6060. ;
  6061. ; ZCPR's external paths available.  (ZCPR will always do the current
  6062. ; drive/current user area)
  6063. ;
  6064. ; Command path available for SYSOP
  6065. ;
  6066.      IF    CHGPATH
  6067. SYSPATH:DB    1,0        ; Then do A0:
  6068.     DB    1,15        : THEN DO A15:
  6069.     DB    4,15        ; Then do D15:
  6070.     DB    0        ; End of path
  6071. ;
  6072. LSYSP    EQU    $-SYSPATH
  6073. ;
  6074. ;
  6075. ; Command path available for remote user
  6076. ;
  6077. REMPATH:DB    1,0        ; Then do A0: (don't do A15:)
  6078.     DB    0        ; End of path
  6079. LREMP    EQU    $-REMPATH
  6080.      ENDIF            ; CHGPATH
  6081. ;.....
  6082. ;
  6083. ;            end of ZCPR external paths
  6084. ;-----------------------------------------------------------------------
  6085. ;
  6086. ; These areas are not initialized
  6087. ;
  6088.      IF    NOT CPM3
  6089. PEND    EQU    $        ; The following area is not initialized
  6090.      ENDIF            ; NOT CPM3
  6091. ;
  6092.      IF    COMFILE    OR EXFILE
  6093. CURRFCB:DS    2
  6094.      ENDIF            ; COMFILE OR EXFILE
  6095. ;
  6096. TOCNTM:    DS    1
  6097. TOCNT:    DS    2
  6098. MSFLAG:    DS    1
  6099. ;
  6100. ;
  6101. ; Save the CP/M jump table here
  6102. ;
  6103. VCOLDBT:DS    3
  6104. VWARMBT:DS    3
  6105. VCONSTAT: DS    3
  6106. VCONIN:    DS    3
  6107. VCONOUT:DS    3
  6108. VLISTOUT: DS    3
  6109. VPUNCH:    DS    3
  6110. VREADER:DS    3
  6111. ;
  6112. ;
  6113. ; System addresses initialized at program startup
  6114. ;
  6115.      IF    CPM3
  6116. SCBBASE:DW    0        ; Base address of the CP/M Plus SCB
  6117. MEMBASE:DB    0        ; Base page of common memory
  6118. BDOSBASE: DB    0        ; Base page of BDOS
  6119.      ENDIF            ; CPM3
  6120. ;.....
  6121. ;
  6122. ;
  6123. ;----------------------------------------------------------------
  6124. ;
  6125. ; ASCII Equates
  6126. ;
  6127. CR    EQU    0DH        ; ASCII carriage return
  6128. LF    EQU    0AH        ; ASCII line feed
  6129. ;
  6130. LXID    EQU    11H        ; Define byte of LIX D,nnnn to fake loader
  6131. LXIH    EQU    21H        ; Define byte of LXI H,nnnn to fake loader
  6132. IOBYTE    EQU    0003H        ; Location of CP/M IOBYTE
  6133. FCB    EQU    005CH
  6134. FCBRNO    EQU    FCB+32
  6135. ;
  6136. ;
  6137. ; CP/M Plus system variable offsets
  6138. ;
  6139.      IF    CPM3
  6140. SCBDAT    EQU    00F4H        ; Offset of date into SCB
  6141. SCBTIM    EQU    00F6H        ; Offset of time into SCB
  6142. SCBCOM    EQU    00FAH        ; Offset of common memory base page in SCB
  6143. SCBBDOS    EQU    0099H        ; Offset of base page of BDOS in SCB
  6144.      ENDIF            ; CPM3
  6145. ;
  6146. ;
  6147. ; BDOS equates
  6148. ;
  6149.      IF    CPM3
  6150. BDOS    EQU    NEXT
  6151.      ENDIF            ; CPM3
  6152. ;
  6153.      IF    NOT CPM3
  6154. BDOS    EQU    0005H
  6155.      ENDIF            ; NOT CPM3
  6156. ;
  6157. CI    EQU    1
  6158. WRCON    EQU    2
  6159. DRECTIO    EQU    6
  6160. PRINTF    EQU    9
  6161. CSTS    EQU    11
  6162. SELDSK    EQU    14
  6163. OPEN    EQU    15
  6164. SEARCH    EQU    17
  6165. READ    EQU    20
  6166. STDMA    EQU    26
  6167. SETUSR    EQU    32
  6168. CHAINP    EQU    47
  6169. GTSCB    EQU    49
  6170. DEFPAS    EQU    106        ; Set default password BDOS function
  6171. ;
  6172.     DS    40
  6173. STACK    EQU    $        ; Local stack
  6174. ;
  6175.      IF    NOT CPM3
  6176. OBJEND    EQU    $
  6177.      ENDIF            ; NOT CPM3
  6178. ;.....
  6179. ;
  6180. ;
  6181.     END
  6182.