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 / CPM / BYE5 / BYE520.LBR / BYE520.AZM / BYE520.ASM
Assembly Source File  |  2000-06-30  |  162KB  |  6,622 lines

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