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 / BYE510.LBR / BYE510.AQM / BYE510.ASM
Assembly Source File  |  2000-06-30  |  143KB  |  5,757 lines

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