home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / bye3 / bye339.lbr / BYE339.AQM / BYE339.ASM
Assembly Source File  |  1985-12-02  |  90KB  |  3,447 lines

  1. ; BYE339 - REMOTE CONSOLE PROGRAM FOR CP/M 2 AND MODEM - 10/21/85
  2. ;        Not for CP/M 3--use BYE+3nn
  3. ;
  4.     ASEG        ; Needed for M80, disregard error if using MAC.
  5. ;
  6. ; This program allows modem callers to use a CP/M system just as if they
  7. ; were seated at the system console.  Special assembly-time options al-
  8. ; low limiting the caller's access by password and/or access to only a
  9. ; message-service program.  A number of external inserts are available
  10. ; to adapt this program to various computers, clocks and  modems.  It
  11. ; may be assembled with ASM, LASM, MAC or M80.    If the ZCPR3 equate is
  12. ; set YES, a macro assembler such as MAC or M80 will be required.  If
  13. ; the program will not assemble correctly with M80, check the insert
  14. ; that was added, it likely is not configured properly.
  15. ;
  16. ; There are spinoffs of the BYE program (notably MBYE and BYE5), we've
  17. ; tried to incorporate any "features" of these programs so that users need
  18. ; not use a spinoff but instead use the real BYE program.
  19. ;
  20. ; BYE3 is placed in the public domain.    It may be updated or altered for
  21. ; your personal use.  I'd like to try and consolodate any new releases, so
  22. ; we can avoid another MODEM7 fiasco.  If you have changes that you feel
  23. ; should be included in future releases, please forward them to:
  24. ;    Saratoga OxGate            - 408/354-5934 (pst)
  25. ;
  26. ;=======================================================================
  27. ; (Put only the current update comments here, move the previous one down
  28. ; with the others.  Will assist those who want to see "what is new".)
  29. ;
  30. ; -----------------------------------------------------------------------
  31. ;
  32. ; v339        Added my improved BIN2BCD and BCD2BIN routines.
  33. ; 10/21/85  Added Mike DeWeese's call-back routines (note: to use call-back,
  34. ;          you must have a Hayes compatible modem that can handle "ATA".)
  35. ;        Printer was not working when going through BDOS calls.
  36. ;        Now the MDRING stuff should work properly.
  37. ;        Changed time routines so system only checks time-on after ever CR.
  38. ;          (Will speed things up for slow clock users).
  39. ;        Added "ULTIME" key to give a user "unlimited time" on the system.
  40. ;        Modded RSX handler very slightly so multiple RSX's are trackable
  41. ;          using CBF's RSX handling routines.
  42. ;                            pst
  43. ;
  44. ;=======================================================================
  45. ;
  46. ; BYE uses a special loader that is built into the program to automatically
  47. ; move itself below CCP. This does not require any alteration in the location
  48. ; of CP/M by using MOVCPM.  In this case, all you need to do is: (1) choose
  49. ; the desired options, (2) patch in the insert for your computer in the special
  50. ; area near the start marked "+++ Install your I/O port insert here +++", (3)
  51. ; patch in the insert for your clock at label TIME (if RTC is YES) and
  52. ; (4) then finish editing, assemble, load and use.
  53. ;
  54. ; This program does the following:
  55. ;
  56. ;       If you type BYE E, BYE will load and execute as though it has
  57. ;       a valid carrier or caller.  Handy for debug--otherwise bye will:
  58. ;
  59. ;    1) Hangs up the phone
  60. ;    2) Awaits ring if B3IM is YES, (or carrier detect if B3IM is NO),
  61. ;       allows exit to CP/M if local KEYB types CTL-C
  62. ;    3) Answers the phone and outputs carrier
  63. ;    4) Awaits incoming carrier. If none found in 30 seconds, hangs
  64. ;       up the phone and goes to step 1
  65. ;    5) Detects the speed of caller and sets local cpu to that speed
  66. ;    6) Asks number of nulls (0-9)
  67. ;    7) Sets the log-in time (if TIMEON is YES)
  68. ;    8) Types the "WELCOME" file from disk, (optional) allowing
  69. ;        CTL-C to skip it
  70. ;    9) Asks for a password (optional), allowing 3 tries to get
  71. ;        it right.  When entered drops into CP/M
  72. ;      10) Caller can leave by hanging up, (any time carrier is
  73. ;        lost, it waits then goes back to step 1) or the caller
  74. ;        may type the program name (BYE).
  75. ;
  76. ;=======================================================================
  77. ;
  78. ; v338        Re-installed code for modems that require ring signals (such as
  79. ; 08/08/85  PMMI, Hayes MM100 & MM][, AppleCat][), which was brutally removed
  80. ;        by the author of Bye335.  Changed documentation which had some
  81. ;        BYEBDOS calls backwards.  Changed format of two BYEBDOS calls.
  82. ;        Bye was loading in ~256 bytes lower than necessary-- fixed it.
  83. ;        Shortened stack space from 60 to 40 bytes.
  84. ;        Added "ASKNULL" equate to disable asking for nulls.
  85. ;        Added "MDMRNG"  equate for PMMI type modems that need ring/answer.
  86. ;        Fixed bug introduced in v335 re: COM files on other drives.
  87. ;        Fixed bug introduced in v337 re: NO25TH / lastcaller reading.
  88. ;                            pst
  89. ;
  90. ; v337a     Added additional conditionals to take more assembly time
  91. ; 07/27/85  advantage of HS300, HS1200, HS2400, B3IM & IMODEM.  Moved the
  92. ;           end marker for the B3IM routine to just above IMHANG so to avoid
  93. ;           the inadvertant deletion of some lines of code that belong with
  94. ;           BYE instead of with the B3IM routines.  Included BYE337.FIX.
  95. ;                            -- Don Brown
  96. ;
  97. ; v337       *All BYE dependant routines may be accessed through BDOS calls
  98. ; 07/24/85  now.  BYE intercepted the BDOS vector anyway, so I figured we
  99. ;        might as well do something with it.  BYEBDOS calls start at
  100. ;        80 decimal.  See BYE337.DOC for more information.
  101. ;       *Striped out many comments, because I've written and included
  102. ;        a comprehensive BYE manual.
  103. ;       *Added fixes for: Anchor modems, MBBS disconnect, and
  104. ;        function keys generating nulls.
  105. ;       *Removed BYELOW equate...you MUST to run BYE low now.  Sorry.
  106. ;       *If you're not using the NO25TH option, the LCDATA buffer will
  107. ;        be a single entry (a 0) so your BBS can sense you're not using
  108. ;        the NO25TH deal and not overrwrite BYE.
  109. ;       *Removed manditory NO25TH when using OxGate, as OxGate's now
  110. ;        smart enough to sense that you don't have the buffer (see above).
  111. ;       *Added NEEDLC.  If yes, then will include code to read lastcaller.
  112. ;       *If you have your own modem overlay, please remove the "ANI 7FH"
  113. ;        or "ANI 127"'s that are in it.  This will allow 8-bit I/O for
  114. ;        programs like XMODEM.
  115. ;       *Removed low-memory bytes LHOUR/LMIN-- XModem and BBS can
  116. ;        access them by looking at RTCBUF+7 and RTCBUF+8
  117. ;       *Made the two subroutines: BCDBIN and BINBCD deleteable.  If you
  118. ;        need them, then set BIN2BCD and/or BCD2BIN to "YES", otherwise
  119. ;        they won't be assembled into the code.
  120. ;       *If TIMEON is yes, you should make sure your clock insert pokes
  121. ;        not only CHOUR and CMIN with the binary hour/min, but that it
  122. ;        pokes the RTCbuf with the BCD values.  This way BBSs and XMODEM
  123. ;        can get the time and date from BYE.
  124. ;       *No longer uses STATUS byte in low-memory.
  125. ;       *No longer patches punch and reader devices to modem.
  126. ;                                pst
  127. ;
  128. ;=======================================================================
  129. ;
  130. MAIN    EQU    3
  131. VERS    EQU    39
  132. MONTH    EQU    10
  133. DAY    EQU    21
  134. YEAR    EQU    85
  135. ;
  136. ; System equates
  137. ;
  138. NO    EQU    0
  139. YES    EQU    NOT NO        ; For conditional assembly
  140. ;
  141. ; You will likely also want to change the password, located below at
  142. ; label 'PASSWD', and the messages printed at label 'WELCOME' and just
  143. ; above label 'HANGUP'.  The names of the WELCOME and .COM files are at
  144. ; labels 'WELFIN' and 'COMFCB' respectively.
  145. ;
  146. ;***********************************************************************
  147. ;
  148. ;           OPTION CONFIGURATION SECTION
  149. ;
  150. ;***********************************************************************
  151. ;
  152. ;          BYE3 Operating System Configuration
  153. ;
  154. CCPL    EQU    8        ; Number of sectors for CCP size (norm=8)
  155. ;
  156. LOCMD    EQU    61        ; Start of BYERSX commands
  157. HICMD    EQU    LOCMD+22    ; End   of BYERSX commands
  158. ;
  159. ;           Modem type
  160. ;
  161. MDMRNG    EQU    NO        ; Yes, for board-modem requiring ring signal
  162. IMODEM    EQU    NO        ; Yes, for intelligent modem, including Hayes
  163. B3IM    EQU    NO        ; Yes, your modem uses AT protocol, like Hayes
  164. ;
  165. ; Set one (and only one) of the following HS equates to YES
  166. ;
  167. HS2400    EQU    NO        ; Yes if your modem's high speed is 2400 baud.
  168. HS1200    EQU    NO         ; Yes if your modem's high speed is 1200 baud.
  169. HS300    EQU    NO        ; Yes if your modem's high speed is 300  baud.
  170. ;
  171. ;    The next 4 equates are only used if B3IM is YES
  172. ;
  173. ECHO    EQU    YES        ; Yes, if modem echos commads
  174. CALBAK    EQU    NO        ; Yes, if you want to use call-back feature
  175. ANCHOR    EQU    NO        ; Yes, if you have a Mark XII
  176. NODTR    EQU    NO        ; Yes, modem or computer does not support DTR
  177. NOATA    EQU    NO        ; Yes, if you have an older Password, or S100
  178. ;
  179. ;            BBS type
  180. ;
  181. ;    Set only one, or none of the following BBS equates to YES.
  182. ;
  183. OXGATE    EQU    NO        ; Yes, running OxGate BBS system
  184. MBBS    EQU    NO        ; Yes, running MBBS BBS system
  185. MINICK    EQU    NO        ; Yes, running MINICBBS
  186. METAL    EQU    NO        ; Yes, running METAL BBS system.  Note:  METAL
  187.                 ; Requires a patch to use the NO25TH feature.
  188.                 ; See the METAL.FIX file in this LBR.
  189. RBBSCK    EQU    NO        ; Yes, running RBBS, sets/resets 'WRTLOC' flag
  190. IOVAL    EQU    0        ; Initial value for IOBYTE (if MINICK YES)
  191. ;
  192. ;        Clock/Time equates
  193. ;
  194. ;    RTC - tells BYE that you have a real-time clock that pokes
  195. ;          CHOUR and CMIN with binary hour/minutes, and pokes
  196. ;          RTCBUF with the BCD time and date.  See the RTC reader
  197. ;          code for more info.
  198. ;
  199. ;      TIMEON - if RTC = yes, will bump users if they are online longer
  200. ;           then MAXMIN minutes (default=60).
  201. ;       TOSWB - if RTC = yes and TIMEON = yes, will print time on system
  202. ;           on every warm-boot.
  203. ;
  204. ;      RSPEED - if RTC = yes, will not allow low-speed (300 baud) users
  205. ;           online during prime-time hours.
  206. ;       HOUR1 - start of prime time (default = 7pm)
  207. ;       HOUR2 - end of prime time   (default = 11pm)
  208. ;       OKSPD - anything this fast, or faster is ok (default = 1200 baud)
  209. ;
  210. ;      BCD2BIN- your reader routine needs our BCD -> BINary converter
  211. ;      BIN2BCD- your reader routine needs our BINary -> BCD converter
  212. ;
  213. RTC    EQU    NO        ; YES = we have RTC reader
  214. TIMEON    EQU    NO        ; YES = keep track of time-on-system
  215. TOSWB    EQU    NO        ; YES = print TOS on warm-boot
  216. RSPEED    EQU    NO        ; YES = restrict baud rates
  217. ;
  218. BCD2BIN    EQU    NO        ; YES = include BCD->BIN routine "BCDBIN"
  219. BIN2BCD    EQU    NO        ; YES = include BIN->BCD routine "BINBCD"
  220. ;
  221.      IF    RTC AND TIMEON
  222. MAXMIN    EQU    60        ; 0= no restrictions
  223.      ENDIF            ; RTC AND TIMEON
  224. ;
  225.      IF    RTC AND RSPEED    ; Restrict low speed people
  226. HOUR1    EQU    19        ; Start of prime-time
  227. HOUR2    EQU    23        ; End of prime-time
  228. OKSPD    EQU    5        ; Minimum speed accepted (5=1200 baud)
  229.                 ; See OFFMSG to match your time & baud rate
  230.      ENDIF            ; RTC AND RSPEED
  231. ;
  232. ;         General Equates
  233. ;
  234. HARDLOG    EQU    NO        ; Yes, echo remote input to printer
  235. PRINTER    EQU    YES        ; Yes, printer available & online
  236. ;
  237. COMFILE    EQU    NO        ; Yes, chain to a .COM file on carrier detect
  238. COMDRV    EQU    'A'        ; Drive to look for .COM file on
  239. COMUSR    EQU    14        ; User# of .COM file to be called after answer
  240. ;
  241. EXFILE    EQU    NO        ; Yes, chain a .COM file upon loss of carrier
  242. EXDRV    EQU    'A'        ; Drive to look for exit .COM file on
  243. EXUSR    EQU    14        ; User # of .COM file to be called upon exit
  244. ;
  245. NO25TH    EQU    NO        ; Yes, you wish to display lastcalr data (^W)
  246. NEEDLC    EQU    NO        ; Yes, read the name from lastcalr file
  247. LCDRV    EQU    'A'        ; Drive to find last-caller file
  248. LCUSR    EQU    14        ; User # of last-caller file
  249. ;
  250. WELFILE    EQU    NO        ; Yes, to send a welcome file
  251. WELDRV    EQU    'A'        ; Drive to look for welcome file
  252. WELUSR    EQU    14        ; User number of welcome file
  253. ;
  254. CLRSCR    EQU    NO        ; Yes, to auto-clear local crt screen between
  255. CLRB4    EQU    NO        ; Clear before printing user-log summary
  256. ;
  257. CLRCH1    EQU    1BH        ; Set these for your clear screen sequence
  258. CLRCH2    EQU    '*'        ; 1B is escape and ESC : clears my screen
  259. CLRCH3    EQU    0        ; (Byte 3 if you need it).
  260. CLRCH4    EQU    0        ; Six bytes allowed for clear screen sequence
  261. CLRCH5    EQU    0        ; And you can also clear
  262. CLRCH6    EQU    0        ; Your 25th line if desired.
  263. ;
  264. ASKNULL    EQU    YES        ; Yes, ask the "Nulls" question
  265. MNULLS    EQU    6        ; Max times to ask "Nulls, if needed" question
  266. PRGRSS    EQU    YES        ; Yes, for helpful progress reports on crt
  267. PRNTGB    EQU    YES        ; Yes, print "Goodbye..." message
  268. PRNTWB    EQU    NO        ; Yes, print a string for each warm boot
  269. PWRQD    EQU    NO        ; Yes, password needed for CP/M access
  270. TOVALUE    EQU    5        ; Minutes of no-activity allowed.  255 max.
  271. WBRTN    EQU    NO        ; Yes, do function each time system warm boots
  272. ;
  273. ;        System and Hardware dependent options
  274. ;
  275. CLOSS    EQU    1        ; If carrier dies, wait 1 sec. then hang up
  276. CFRST    EQU    25        ; Wait 25 seconds for carrier (IF MDMRNG)
  277. CTRLC    EQU    'K'-'@'        ; Map ^C to this character
  278. DOWNMIN    EQU    2        ; Number of min after Sysop types ^^O to logout
  279. LOSER    EQU    NO        ; Yes, warm boot overwrites part of the BIOS
  280. MHZ    EQU    4        ; Processor clock in MHz
  281. ;
  282. ;          Function Keys
  283. ;
  284. ATTNCH    EQU    '^'-'@'        ; Attention character to type first (^^ now)
  285. BLNKKEY    EQU    'B'        ; Key to toggle remote terminal on/off
  286. SYSDKEY    EQU    'O'        ; Char. to print "System going down in n min.."
  287. TWITKEY    EQU    'N'        ; Keycode to hangup modem manually
  288. MSGKEY    EQU    'Q'        ; Keycode to print "Message from SYSOP: "
  289. BELLKEY    EQU    'G'        ; Key to toggle bells on console
  290. TIMEKEY    EQU    'T'        ; Key for sysop to display time (if TIMEON)
  291. ULTMKEY    EQU    'U'        ; Key to grant unlimited time (if TIMEON)
  292. WHOKEY    EQU    'W'        ; Key to display LASTCALR if NO25TH is YES.
  293. ZCREEN    EQU    'Z'        ; Key to manually clear your screen b/t calls.
  294. ;
  295. ;           CCP options
  296. ;
  297. ZCPR2    EQU    NO        ; Yes, if running ZCPR2, ZCMD1/2 or NZCPR
  298. ZCPR3    EQU    NO        ; Yes, if running ZCPR3 (set ZCPR2 = no)
  299. ;
  300. ; NOTE: requires MAC.COM to assemble if ZCPR3 set YES
  301. ;
  302.      IF    ZCPR3
  303.     MACLIB    Z3BASE        ; Requires MAC to assemble...otherwise enter
  304.                 ; Constants directly..see label DOZ3 for
  305.                 ; For required EQU's
  306.      ENDIF            ; ZCPR3
  307. ;
  308. USEZCPR    EQU    NO        ; Yes, if using ZCPR/NZCPR/ZCMD to set bytes
  309. MAXDRIV    EQU    003DH        ; ZCPR lolcation of MAXDRIV byte
  310. WHEEL    EQU    003EH        ; Location of ZCPR's wheel flag
  311. MAXUSER    EQU    003FH        ; ZCPR location of MAXUSR byte
  312. MAXDRV    EQU    'D'-'@'        ; Highest drive supported
  313. MAXUSR    EQU    9        ; Highest user area
  314. SYSDRV    EQU    'F'-'@'        ; Highest local drive supported
  315. SYSUSR    EQU    15        ; Highest local user area (0-15)
  316. ;
  317. CHGPATH    EQU    NO        ; Yes, if changing ZCPR's external path
  318. EXTPATH    EQU    0040H        ; ZCPR external path default location
  319. ;
  320. ;          MSPEED values
  321. ;
  322. MSPEED    EQU    003CH        ; Baud rate pointer
  323. BP110    EQU    0        ; 110 baud - baud rate pointers for MSPEED
  324. BP300    EQU    1        ; 300 baud
  325. BP450    EQU    2        ; 450 baud
  326. BP600    EQU    3        ; 600 baud
  327. BP710    EQU    4        ; 710 baud
  328. BP1200    EQU    5        ; 1200 baud
  329. BP2400    EQU    6        ; 2400 baud
  330. BP4800    EQU    7        ; 4800 baud
  331. BP9600    EQU    8        ; 9600 baud
  332. BP19200    EQU    9        ; 19200 baud
  333. ;
  334. ;          If using LOSER
  335. ;
  336. ; There are some cases where warm boot overwrites the initial BIOS jump
  337. ; table.  This problem was solved for the Superbrain 3.0 bios by find-
  338. ; ing a warmboot call to HIGH in the BIOS.  This call is then patched by
  339. ; BYE.    The form of the call is:     WBCALL   CALL  WMSTRT
  340. ;
  341.      IF    LOSER
  342. WBCALL    EQU    0E260H        ; Check this in your BIOS
  343. ;
  344. ; The following location is called
  345. ;
  346. WMSTRT    EQU    0E566H        ; Check this in your BIOS
  347.      ENDIF            ; LOSER
  348. ;
  349. ;-----------------------------------------------------------------------
  350. ;
  351. ;         END OF OPTION CONFIGURATION SECTION FOR BYE3
  352. ;
  353. ;-----------------------------------------------------------------------
  354. ;
  355.     ORG    100H
  356. ;
  357. ;-------------------- Special Loader Routine ---------------------------
  358. ;
  359. START:    LXI    SP,ISTACK    ; Set stack for initialization routine
  360.     LHLD    0000H+1        ; Point to warm boot
  361.     DCX    H        ; If BYE is active,
  362.     MOV    D,M        ; Pick up pointer to BYE variables
  363.     DCX    H
  364.     MOV    E,M
  365.     LXI    H,HDROFF    ; Calculate address of BYE tag
  366.     DAD    D
  367.     MOV    A,M        ; Get letter
  368.     CPI    'B'        ; Try to match 'BYE' (or 'Bye')
  369.     JNZ    STARTA        ; Relocate if BYE not active
  370.     INX    H
  371.     MOV    A,M
  372.     CPI    'Y'        ; Relocate if BYE not active
  373.     JNZ    STARTA
  374.     INX    H
  375.     MOV    A,M
  376.     CPI    'E'        ; Relocate if BYE not active
  377.     JNZ    STARTA
  378. ;
  379. ; Ok, we're sure that BYE's already there
  380. ;
  381.     LHLD    BDOS+1        ; Load BDOS vector
  382.     INX    H        ; Compute start of BYE3
  383.     INX    H
  384.     INX    H
  385.     PCHL            ; Go execute already loaded code
  386. ;
  387. STARTA:    LHLD    BDOS+1        ; Load BDOS vector
  388.     LXI    D,-(CCPL*256)-8    ; 2k bytes in CCP plus offset
  389.     DAD    D        ; Make room for the CCP
  390. ;
  391. ; HL now contains the destination address of BYE3
  392. ;
  393.     LXI    D,OBJEND-1    ; Set up the source pointer
  394.     LXI    B,OBJEND-BEGOBJ    ; Set up byte counter
  395. ;
  396. BLOCK:    LDAX    D        ; Get program byte
  397.     MOV    M,A        ; Move program byte
  398.     MOV    A,B        ; Get byte count
  399.     ORA    C        ; Finished block transfer?
  400.     JZ    UPDATE        ; Yes, check on the opcode values
  401.     DCX    D        ; No, set source pointer
  402.     DCX    H        ; Set destination pointer
  403.     DCX    B        ; Set byte counter
  404.     JMP    BLOCK        ; Continue block transfer until finished
  405. ;
  406. UPDATE:    XCHG            ; Move the source addrress into 'HL'
  407.     CALL    NEGHL        ; Prepare value for subtraction
  408.     DAD    D        ; Form the program offset
  409.     SHLD    OFFSET        ; Save the program offset
  410.     XCHG            ; Set up the offset register
  411.     LXI    H,ENDOBJ    ; Get  the ending addr of the prgm code
  412.     DAD    D        ; Form new ending addr (new location)
  413.     SHLD    ENDRNG        ; Save the ending addr of the prgm code
  414.     LXI    H,BEGOBJ    ; Get  the start address of program code
  415.     DAD    D        ; Form new beginning addr (new location)
  416. ;
  417. ; The following code determines whether or not an address is within the
  418. ; BYE prgm and sets it to the new address if it is - otherwise it will
  419. ; not disturb the code.
  420. ;
  421.     DCX    H        ; Set up the source pointer for the
  422.                 ; Modification routine entry
  423. MODIFY:    INX    H        ; Point to the next (hopefully) instr.
  424.     DB    LXID        ; Get the address of the end of BYE3
  425. ;
  426. ENDRNG:    DW    0
  427.     MOV    A,E
  428.     SUB    L
  429.     MOV    A,D
  430.     SBB    H        ; Have we finished moving this block?
  431.     JC    BEGIN        ; Yes, we can begin now.
  432. ;
  433. ; Here is where we test for the 3-byte opcodes
  434. ;
  435.     MVI    B,INST3E-INST3    ; Get number of elements in the table
  436.     LXI    D,INST3        ; Set up the 3-byte opcodes table ptr
  437. ;
  438. THRBYT:    LDAX    D        ; Get opcode byte from table
  439.     CMP    M        ; Is this byte a 3-byte opcode?
  440.     JZ    CHANGE        ; Change the 2nd and 3rd bytes if needed
  441.     INX    D        ; No, advance table pointer
  442.     DCR    B        ; End of 3-byte table?
  443.     JNZ    THRBYT        ; No, keep looking
  444. ;
  445. ; Skip all the 2-byte opcodes - this keeps the transfer program from
  446. ; trying to figure out what the second byte is.
  447. ;
  448.     MVI    B,INST2E-INST2    ; Get the number of table elements
  449.     LXI    D,INST2        ; Set up the 2-byte-opcodes-table ptr
  450. ;
  451. TWOBYT:    LDAX    D        ; Get opcode byte from table
  452.     CMP    M        ; Is this byte a 2-byte opcode?
  453.     JZ    SKIP        ; Yes, skip it and continue
  454.     DCR    B        ; No, end of 2-byte table?
  455.     INX    D        ; Advance table pointer
  456.     JNZ    TWOBYT        ; No, keep looking
  457.     JMP    MODIFY        ; Yes, a one-byte opcode, keep going
  458. ;
  459. SKIP:    INX    H        ; Advance object code pointera
  460.     JMP    MODIFY        ; Continue search
  461. ;
  462. CHANGE:    LXI    D,OBJEND    ; Set up end of range pointer
  463.     LXI    B,BEGOBJ    ; Set up beginning of range pointer
  464. ;
  465. ; See if the address is above the range
  466. ;
  467.     INX    H        ; Advance pointer to the LSB of the addr
  468.     MOV    A,E
  469.     SUB    M
  470.     INX    H        ; Advance pointer to the MSB of the addr
  471.     MOV    A,D
  472.     SBB    M
  473.     JC    MODIFY
  474. ;
  475. ; See if the address is below the range
  476. ;
  477.     DCX    H        ; Set ptr back to the LSB of the addr
  478.     MOV    A,M
  479.     SUB    C
  480.     INX    H        ; Advance pointer to the MSB of the addr
  481.     MOV    A,M
  482.     SBB    B
  483.     JC    MODIFY
  484. ;
  485. ; Update the value of this address by adding the offset to it
  486. ;
  487.     DCX    H        ; Set ptra back to LSB of the address
  488.     DB    LXID        ; Load DE with the offset value
  489. ;
  490. OFFSET:    DW    0
  491.     MOV    A,M        ; Get base address
  492.     ADD    E        ; Change LSB to new address
  493.     MOV    M,A        ; Update memory
  494.     INX    H        ; Advance pointer to the MSB of the addr
  495.     MOV    A,M        ; Get the MSB of the base addr
  496.     ADC    D        ; Change LSB to new address
  497.     MOV    M,A        ; Update memory
  498.     JMP    MODIFY        ; Take care of the next instruction
  499. ;
  500. ; Small subroutine to negate the contents of HL
  501. ;
  502. NEGHL:    MOV    A,H
  503.     CMA
  504.     MOV    H,A        ; Get the complement of the MSB
  505.     MOV    A,L
  506.     CMA
  507.     MOV    L,A        ; Get the complement of the LSBb
  508.     INX    H        ; Make 'HL' totally negative
  509.     RET
  510. ;
  511. ; Prepare to branch to the BYE3 program
  512. ;
  513. BEGIN:    LHLD    BDOS+1
  514.     PUSH    H
  515.     LXI    D,BEGOBJ
  516.     LHLD    OFFSET        ; Get prgram offset
  517.     DAD    D        ; Form address of new BDOS address
  518.     SHLD    BDOS+1        ; Update BDOS vector
  519.     INX    H
  520.     POP    D
  521.     MOV    M,E
  522.     INX    H
  523.     MOV    M,D
  524.     INX    H
  525.     PCHL            ; Jump to relocated BYE3 program
  526. ;
  527. ; The following table defines the 3-byte load instructions used in the
  528. ; 8080 instruction set.
  529. ;
  530. INST3:    DB    001H,011H,021H,022H,02AH,031H,032H,03AH,0C2H
  531.     DB    0C3H,0C4H,0CAH,0CCH,0CDH,0D2H,0D4H,0DAH,0DCH
  532.     DB    0E2H,0E4H,0EAH,0ECH,0F2H,0F4H,0FAH,0FCH
  533. INST3E    EQU    $        ; End of 3 byte op codes
  534. ;
  535. ;
  536. ; The following table is the listing of the 2-byte opcodes used in the
  537. ; 8080 instruction code set.
  538. ;
  539. INST2:    DB    006H,00EH,016H,01EH,026H,02EH,036H,03EH,0C6H
  540.     DB    0CEH,0D3H,0D6H,0DBH,0DEH,0E6H,0EEH,0F6H,0FEH
  541. INST2E    EQU    $        ; End of 2 byte op codes
  542. ;
  543. ; Set aside space for the stack region
  544. ;
  545.     DS    40
  546. ISTACK:    DW    0        ; Top of stack
  547. ;
  548. ;
  549. ;-----------------------------------------------------------------------
  550. ;
  551. ;           THE FOLLOWING CODE GETS MOVED
  552. ;             TO HIGH RAM BY THE LOADER
  553. ;           PROGRAM, WHERE IT IS EXECUTED.
  554. ;
  555. ;-----------------------------------------------------------------------
  556. ;
  557. BEGOBJ:    JMP    0        ; Filled by BEGIN
  558. BGOBJ2:    JMP    START0        ; Hop over fixed vectors
  559. ;
  560. MCBOOT:    JMP    MBOOT        ; Off to warm boot
  561.     JMP    PRNLOG        ; Go print out items of interest
  562. ;
  563. ; Variables follow in a predefined order that can be manipulated by a
  564. ; passworded or other program to give special users different capabili-
  565. ; ties.
  566. ;
  567. ;-----------------------------------------------------------------------
  568. ;
  569. ; Here is a quickie handy reference table to use so we do not get mixed
  570. ; up.  Please do not change the order of it in any future changes.
  571. ;
  572. ; |mxusr |mxdrv |toval |nulls |ulcsw |lfeeds|wrtloc|hardon|mdmoff|covect |
  573. ; |1 byte|1 byte|1 byte|1 byte|1 byte|1 byte|1 byte|1 byte|1 byte|2 bytes|
  574. ;
  575. ; |hdroff |bellon|lcptr |lcdata |mxtme |rtcbuf |
  576. ; |3 bytes|1 byte|1 byte|2 bytes|1 byte|2 bytes|
  577. ;-----------------------------------------------------------------------
  578. ;
  579. MXUSR:    DB    MAXUSR        ; Runtime maximum user area available
  580. MXDRV:    DB    MAXDRV        ; Runtime maximum drive available
  581. TOVAL:    DB    TOVALUE        ; Number of mins. to wait before timeout
  582. NULLS:    DB    0        ; Number of nulls after <cr>
  583. ULCSW:    DB    0        ; Upper case only switch (32=upper case)
  584. LFEEDS:    DB    0        ; Line feed mask (0=don't mask)
  585. WRTLOC:    DB    0        ; Location RBBS pokes so BYE won't hang
  586. HARDON:    DB    0FFH        ; If 0, hardlog is deactivated
  587. MDMOFF:    DB    0        ; If 0FFH, do not output to console
  588. COVECT:    DW    0        ; Console output vector for XMODEM
  589. HDROFF    EQU    $-MCBOOT    ; Offset to 'BYE' that follows
  590.     DB    'BYE'        ; Tells XMODEM that BYE is being used
  591. BELLON:    DB    0FFH        ; If 0FFH, ^G ok to send to console
  592. LCPTR:    JMP    LCDATA        ; First byte is user access data for MBBS
  593.                 ; Next 2 bytes point to lastcalr data buffer
  594. MXTIME:    JMP    RTCBUF        ; First bye holds maximum time allowed
  595.                 ; Next 2 bytes point at clock buffer
  596. ;
  597. ;***********************************************************************
  598. ;
  599. ;      THIS IS THE OFFICIAL START OF THE BYE PROGRAM
  600. ;
  601. ;***********************************************************************
  602. ;
  603. ;        +++ Insert your serial port driver here +++
  604. ;
  605. ;***********************************************************************
  606. ;
  607. ;                         (IF IMODEM AND (NOT B3IM)
  608. ;        +++ Insert your intelligent modem driver here +++
  609. ;            (not necessary if B3IM is YES)
  610. ;
  611. ;***********************************************************************
  612. ;
  613. ;
  614. ; If you have a clock please replace this code with your clock read code.
  615. ; Use as many instructions as you need but make sure you store binary-not
  616. ; BCD values in CCHOUR and CCMIN.
  617. ;
  618. ; Two subroutines are availble if you set the "xxx2yyy" equates:
  619. ;    BINBCD - converts binary to BCD     -- set BIN2BCD = YES
  620. ;    BCDBIN - converts BCD to binary        -- set BCD2BIN = YES
  621. ;
  622. ; Make sure you also store the full time and date in RTCBUF so your BBS
  623. ; and XMODEM can get the time and date.
  624. ;
  625. ;        (IF RTC)
  626. ;        +++ Insert your clock reader here +++
  627. ;
  628. ;*************************************************************************
  629. ;
  630. ;    This code is for programming the "Hayes Compatible" intelligent
  631. ;    modems.  If you have a "dumb" modem, then it doesn't apply to you.
  632. ;    If you have an intelligent modem that is not "Hayes Compatible" then
  633. ;    You should have inserted your own modem-driver above.
  634. ;        Example: Cermetek I212A = B3CM+1.INS
  635. ;
  636.      IF    B3IM
  637. IMRING:    CALL    MDINST        ; Character ready from modem?
  638.     RZ            ; No
  639.     CALL    MDINP        ; Get the modem response code
  640.     ANI    7FH        ; Strip parity
  641.      ENDIF            ; B3IM
  642. ;
  643.      IF    B3IM AND PRGRSS
  644.     CALL    RCDISP        ; Display RC for local sysop
  645.     PUSH    PSW
  646.     LXI    H,LFMSG
  647.     CALL    PRINTL        ; Turn up a line on crt
  648.     POP    PSW
  649.      ENDIF            ; B3IM AND PRGRSS
  650. ;
  651.      IF    B3IM
  652.     CPI    CR
  653.     RZ
  654.     CPI    LF
  655.     RZ
  656.     CPI    '2'        ; Ring?
  657.     JNZ    REDOIT        ; No, something wrong, start over
  658.      ENDIF            ; B3IM
  659. ;
  660.      IF    B3IM AND CALBAK AND PRGRSS
  661.     LXI    H,CALMSG1
  662.     CALL    PRINTL        ; Print "Waiting for 2nd ring..."
  663.      ENDIF
  664. ;
  665.      IF    B3IM AND CALBAK
  666.     LXI    B,8000        ; Look for 8 seconds for 2nd ring
  667. RCLOOP:    CALL    MDINST        ; Anything available?
  668.     JNZ    RING2        ; Yes, check it out
  669.     CALL    KDELAY        ; Wait 1ms
  670.     DCX    B        ; Decrement counter
  671.     MOV    A,B
  672.     ORA    C
  673.     JNZ    RCLOOP
  674.     JMP    CALL2        ; Now check for second call
  675. ;
  676. RING2:    CALL    MDINP        ; Get character
  677.     ANI    127
  678.     CALL    RCDISP        ; Show it on screen
  679.     CPI    '2'
  680.     JNZ    RCLOOP        ; Not another ring, so we're OK for now
  681.      ENDIF
  682. ;
  683.      IF    B3IM AND CALBAK    AND PRGRSS
  684.     LXI    H,CALMSG3    ; Print "Timing out from voice call..."
  685.     CALL    PRINTL
  686.      ENDIF
  687. ;
  688.      IF    B3IM AND CALBAK
  689.     LXI    B,20        ; Voice call -- wait 20 secs to timeout
  690. TOTLP:    CALL    DELAY        ; Time-out loop
  691.     DCX    B
  692.     MOV    A,B
  693.     ORA    C
  694.     JNZ    TOTLP
  695.     JMP    REDOIT        ; Re-init modem
  696.      ENDIF
  697. ;
  698. CALL2    EQU    $        ; Wait for second call
  699. ;
  700.      IF    B3IM AND CALBAK AND PRGRSS
  701.     LXI    H,CALMSG2    ; Print "Waiting 45 seconds for call"
  702.     CALL    PRINTL
  703.      ENDIF
  704. ;
  705.      IF    B3IM AND CALBAK
  706.     CALL    EATALL        ; Eat anything in the buffer
  707.     LXI    B,45000        ; Wait up to 45 seconds for call back
  708. C2LOOP:    CALL    MDINST
  709.     JNZ    ISRING
  710.     CALL    KDELAY        ; Wait 1ms
  711.     DCX    B
  712.     MOV    A,B
  713.     ORA    C
  714.     JNZ    C2LOOP
  715.     JMP    REDOIT        ; All timed out -- no 2nd ring, re-init
  716. ;
  717. ISRING:    CALL    MDINP        ; Do we have second ring?
  718.     ANI    127
  719.     CALL    RCDISP        ; Display result code
  720.     CPI    '2'
  721.     CZ    IMINT2        ; Print CRLF and set zero flag
  722.     JNZ    REDOIT        ; Not a ring, so re-init, else answer phone
  723.      ENDIF    ;B3IM AND CALBAK
  724. ;
  725.      IF    B3IM AND (NOT NOATA)
  726. IMRIN1:    MVI    B,22        ; Must let the phone quit ringing first
  727.     CALL    DLP1        ; Usually takes from 1.4 to 3.7 seconds
  728.     CALL    EATALL        ; Swallow c/r or lf from result code
  729.     LXI    H,B3ATA
  730.     CALL    IMSEND        ; Send ATA to modem
  731.      ENDIF            ; B3IM AND (NOT NOATA)
  732. ;
  733.      IF    B3IM
  734.     LXI    B,30000        ; We will check for RC every 1 ms for 30 secs
  735. ;
  736. MDR1:    CALL    MDINST
  737.     JZ    RCHEK        ; And wait for response
  738.     CALL    MDINP        ; Then fetch it
  739.     ANI    07FH        ; And strip parity
  740.      ENDIF            ; B3IM
  741. ;
  742.      IF    B3IM AND PRGRSS
  743.     CALL    RCDISP        ; And show results code (RC)
  744.      ENDIF            ; B3IM AND PRGRSS
  745. ;
  746.      IF    B3IM
  747.     CPI    CR
  748.     JZ    MDR1
  749.     CPI    LF
  750.     JZ    MDR1
  751.     CPI    '3'        ; Carrier wait timeout?
  752.     JZ    REDOIT        ; Yep, timeout (voice call maybe)
  753.     CPI    '4'        ; Error?
  754.     JZ    REDOIT        ; Start over
  755.      ENDIF            ; B3IM
  756. ;
  757.      IF    B3IM AND (HS1200 OR HS2400)
  758.     CPI    '1'        ; 300 baud or 2400 bps?
  759.     JNZ    MDR2        ; No, check for 1200 bps
  760.      ENDIF            ; B3IM AND (HS1200 OR HS2400)
  761. ;
  762. ; Get next character if first was a '1' (and HS2400 is YES)
  763. ;
  764.      IF    B3IM AND HS2400
  765.     CALL    CHECK1        ; Let's see if it's a 1, 10 or 11
  766.      ENDIF            ; B3IM AND HS2400
  767. ;
  768.      IF    B3IM AND PRGRSS
  769.     CALL    RCDISP        ; Show RC to local terminal
  770.      ENDIF            ; B3IM AND PRGRSS
  771. ;
  772.      IF    B3IM AND HS2400
  773.     CPI    '0'
  774.     JZ    SET24        ; For Vadic and Hayes, 10 means 2400 bps
  775.     CPI    '1'        ; For some, 11 means 2400 bps
  776.     JZ    SET24
  777.      ENDIF            ; B3IM AND HS2400
  778. ;
  779.      IF    B3IM
  780.     JMP    SET3        ; Was 1 (300 baud)
  781.      ENDIF            ; B3IM
  782. ;
  783.      IF    B3IM AND (HS1200 OR HS2400)
  784. MDR2:    CPI    '5'        ; 1200 bps?
  785.     JZ    SET12        ; Yes
  786.      ENDIF            ; B3IM AND (HS1200 OR HS2400)
  787. ;
  788.      IF    B3IM AND HS2400
  789.     CPI    '6'        ; 2400 bps? (preproduction only)
  790.     JZ    SET24
  791.      ENDIF            ; B3IM AND HS2400
  792. ;
  793.      IF    B3IM AND ANCHOR
  794.     JMP    SET3        ; If it wasn't a 3 or 5 it means the Anchor
  795.                 ; Connected at 300 but sent RC at wrong speed
  796.      ENDIF            ; B3IM AND ANCHOR
  797. ;
  798.      IF    B3IM
  799.     JMP    MDR1        ; Wait 30 seconds for valid response
  800. ;
  801. RCHEK:    CALL    KDELAY        ; Wait 1 millisecond
  802.     DCX    B
  803.     MOV    A,C
  804.     ORA    B        ; Time up?
  805.     JNZ    MDR1        ; No, Keep trying
  806. ;
  807. REDOIT:    POP    H        ; Go reset if none of these responses
  808.     LXI    H,VCNUM        ; Update the voice call
  809.     INR    M        ; Counter
  810.     LXI    H,LFMSG
  811.     CALL    PRINTL        ; Turn up a line on crt
  812.     JMP    HANGUP1
  813.      ENDIF            ; B3IM
  814. ;
  815.      IF    B3IM AND PRGRSS
  816. RCDISP:    PUSH    B
  817.     PUSH    H
  818.     PUSH    PSW        ; Save A
  819.     STA    RCSHOW
  820.     LXI    H,RCSHOW    ; And show results code (RC)
  821.     CALL    PRINTL
  822.     POP    PSW
  823.     PUSH    PSW
  824.     CPI    CR
  825.     JNZ    RCDIS1
  826.     MVI    A,LF
  827.     STA    RCSHOW        ; Force a LF after a CR
  828.     LXI    H,RCSHOW
  829.     CALL    PRINTL
  830. RCDIS1:    POP    PSW
  831.     POP    H
  832.     POP    B
  833.     RET
  834.      ENDIF            ; B3IM AND PRGRSS
  835. ;
  836. ;
  837.      IF    B3IM
  838. CHECK1:    LXI    B,500        ; Try for 500 ms
  839. CHECK2:    CALL    KDELAY
  840.     DCX    B
  841.     MOV    A,B
  842.     ORA    C
  843.     JZ    CHECK3        ; 500 ms is up
  844.     CALL    MDINST        ; Character ready?
  845.     JZ    CHECK2        ; No, keep waiting
  846.     CALL    MDINP        ; Yes, fetch it
  847.     ANI    07FH        ; And strip parity
  848.     RET            ; And return
  849. ;
  850. CHECK3:    MVI    A,0FFH        ; Set error code
  851.     RET            ; And return
  852.      ENDIF            ; B3IM
  853. ;
  854.      IF    B3IM AND HS2400
  855. SET24:    CALL    SET2400        ; Set port to 2400 bps
  856.     MVI    A,BP2400
  857.     STA    MSPEED        ; Set speed indicator
  858.     JMP    FINISH
  859.      ENDIF            ; B3IM AND HS2400
  860. ;
  861.      IF    B3IM
  862. SET3:    CALL    SET300        ; Set port to 300 baud
  863.     MVI    A,BP300
  864.     STA    MSPEED        ; Set speed indicator
  865.     JMP    FINISH
  866.      ENDIF            ; B3IM
  867. ;
  868.      IF    B3IM AND (HS1200 OR HS2400)
  869. SET12:    CALL    SET1200        ; Set port to 1200 bps
  870.     MVI    A,BP1200
  871.     STA    MSPEED        ; And speed indicator
  872.      ENDIF            ; B3IM AND (HS1200 OR HS2400)
  873. ;
  874.      IF    B3IM
  875. FINISH:    POP    H        ; Reset CALL on the stack
  876.     CALL    PATCH        ; Patch the jump table
  877.     MVI    B,15
  878.     CALL    DLP1        ; Wait 1.5 sec for user to enter terminal mode
  879.     CALL    EATALL        ; Clear input port and
  880.     JMP    ANSW        ; Greet the user at his speed
  881. ;
  882. ;
  883. ; Initialize the modem.  First, disable the auto-answer to prevent any
  884. ; problems if somebody phones while you are resetting the registers.
  885. ; Then reset the registers for normal unattended operation.
  886. ;
  887. IMINIT:    CALL    DLP
  888.     CALL    EATALL
  889. ;
  890.     LXI    H,B3ATZ        ; Reset the modem
  891.     CALL    IMSEND
  892.     CALL    DLP
  893.     CALL    EATALL        ; Swallow the response
  894. ;
  895.     LXI    H,B3INIT
  896.     CALL    IMSEND        ; Go initialize the modem
  897.      ENDIF            ; B3IM
  898. ;
  899.      IF    B3IM AND PRGRSS
  900. IMINT1:    CALL    CHECK1
  901.     CPI    255        ; Didn't come back in 500ms?
  902.     JZ    IMERRX
  903.     CPI    '0'
  904.     CZ    RCDISP        ; Display result code
  905.     JZ    IMINT2
  906.     CPI    '4'
  907.     CZ    RCDISP
  908.     JNZ    IMINT1        ; Wait for a zero or four
  909. IMERRX:    LXI    H,CMDERR
  910.     CALL    PRINTL        ; Inform sysop of problem
  911.     RET
  912.      ENDIF            ; B3IM AND PRGRSS
  913. ;
  914.      IF    B3IM
  915. IMINT2:    LXI    H,LFMSG
  916.     CALL    PRINTL        ; Turn up a line on crt
  917.     CALL    DLP
  918.     CALL    EATALL        ; Get any garble from the modem
  919.     RET
  920. ;
  921. ;
  922. ; Delay about one second to let modem get stabilized before or after a
  923. ; command string.
  924. ;
  925. DLP:    MVI    B,10
  926. ;
  927. DLP1:    CALL    DELAY
  928.     DCR    B
  929.     JNZ    DLP1
  930.     RET
  931. ;
  932. EATALL:    CALL    CHECK1
  933.     CPI    0FFH        ; All characters eaten?
  934.     JNZ    EATALL        ; No, keep eating
  935.     RET
  936. ;
  937. ; De-initiaize the modem.  When the operator uses CTL-C followed by any-
  938. ; thing but "R", this call will return the modem to default settings.
  939. ;
  940. IMQUIT:    LXI    H,LFMSG
  941.     CALL    PRINTL        ; Turn up a line on crt
  942.     LXI    H,B3ATZ
  943.     CALL    IMSEND        ; Send ATZ message to modem
  944.     CALL    DLP
  945.     CALL    EATALL
  946.     LXI    H,B3USR
  947.     CALL    IMSEND        ; Send ATS0=0 to modem
  948.     CALL    EATALL        ; Clear mdm input
  949.     RET
  950. ;
  951. ;
  952. ; Send a command string to the modem. (If ECHO) Verify, reset the modem
  953. ; and resend string if echo fails.
  954. ;
  955. IMSEND:    PUSH    B        ; Save 'BC' registers
  956.     SHLD    ADDSTR        ; Save start of command string
  957. ;
  958. IMSEN1:    CALL    MDOUTST        ; Modem ready for character?
  959.     JZ    IMSEN1        ; No, go check again
  960.     MOV    A,M        ; Get the character
  961.     CALL    MDOUTP        ; Send the character
  962.      ENDIF            ; B3IM
  963. ;
  964.      IF    B3IM AND PRGRSS
  965.     CALL    RCDISP        ; Display the command string
  966.      ENDIF            ; B3IM AND PRGRSS
  967. ;
  968.      IF    B3IM AND ECHO    ; Hayes needs echo checking
  969.     CALL    CHECK1        ; Get the echo character
  970.     CMP    M        ; Same?
  971.     JNZ    NOECHO        ; No, let's resend entire command string
  972.      ENDIF            ; B3IM AND ECHO
  973. ;
  974.      IF    B3IM
  975.     INX    H        ; Point to next
  976.     MOV    A,M        ; Get next character
  977.     ORA    A        ; Has all been sent
  978.     JNZ    IMSEN1        ; No, go send another character
  979.     POP    B        ; Restore the BC registers
  980.     RET            ; Return past end of message
  981.      ENDIF            ; B3IM
  982. ;
  983. NOECHO:     IF    B3IM AND ECHO AND PRGRSS
  984.     LXI    H,NOEMSG
  985.     CALL    PRINTL        ; Inform sysop of echo error
  986.      ENDIF            ; B3IM AND ECHO AND PRGRSS
  987. ;
  988.      IF    B3IM AND ECHO
  989.     CALL    MDOUTST        ; Wait for modem ready
  990.     JZ    NOECHO
  991.     MVI    A,CR
  992.     CALL    MDOUTP        ; Force a c/r to end command string
  993.     CALL    DLP        ; Let modem settle
  994.     CALL    EATALL        ; Make sure input is clear
  995.     LHLD    ADDSTR        ; Restore address of command string
  996.     JMP    IMSEN1        ; And send it again
  997.      ENDIF            ; B3IM AND ECHO
  998. ;
  999. ;    A hangup routine for those people who don't have DTR control
  1000. ;    over their modems.
  1001. ;
  1002.      IF    B3IM AND NODTR
  1003. IMDROP:    CALL    EATALL
  1004.     MVI    B,15
  1005.     CALL    DLP1        ; This routine will hang up the phone
  1006.     LXI    H,B3ESC        ; Using +++ATH
  1007.     CALL    IMSEND
  1008.     CALL    EATALL
  1009.     MVI    B,15
  1010.     CALL    DLP1
  1011.     LXI    H,B3ATH
  1012.     CALL    IMSEND        ; For modems without DTR support
  1013.     CALL    DLP
  1014.     RET
  1015.      ENDIF            ; B3IM AND NODTR
  1016. ;
  1017. ;              End of B3IM
  1018. ;***********************************************************************
  1019. ;
  1020. IMHANG:    CALL    MDCARCK        ; Carrier?
  1021.     RZ            ; Carrier gone, return
  1022. ;
  1023.      IF    B3IM AND NODTR
  1024.     CALL    IMDROP        ; Send +++ATH
  1025.      ENDIF            ; B3IM AND NODTR
  1026. ;
  1027.      IF    NOT NODTR
  1028.     CALL    MDSTOP        ; Drop DTR-***This is a new label just after
  1029.                 ; MDQUIT that drops dtr and returns.
  1030.      ENDIF            ; NOT NODTR  (see BYE3-INS.LBR for new insert)
  1031. ;
  1032.     JMP    IMHANG        ; Keep looping
  1033.     RET
  1034. ;
  1035. ;-----------------------------------------------------------------------------
  1036. ;
  1037. ; If the carrier is lost - hang up, await ring.  Otherwise, say goodbye,
  1038. ; and hang-up.
  1039. ;
  1040. START0:    LHLD    BDOS+1        ; Get beginning address of BYE3 program
  1041.     SHLD    BDADDR        ; Save address of BYE3 start
  1042. ;
  1043. ;    Patch in BYE interceptor
  1044. ;
  1045.     LHLD    BEGOBJ+1    ; Get real bdos call
  1046.     MOV    A,H        ; Get high address byte
  1047.     LXI    D,BYERSX    ; Have to do it this way to fool relocator
  1048.     CMP    D        ; Already pointed to BYERSX?
  1049.     JZ    NORPTC        ; then don't patch again
  1050. ;
  1051.     SHLD    REALBD+1    ; Save it in the interceptor routine
  1052.     LXI    H,BYERSX    ; Get address of interceptor routine
  1053.     SHLD    BEGOBJ+1    ; Save it so it thinks RSX = BDOS
  1054. ;
  1055. NORPTC:    XRA    A        ; A=0
  1056.     STA    ULCSW        ; Reset upper/lower case flag
  1057.     STA    LFEEDS        ; And line feed flag
  1058.     STA    WRTLOC        ; And write-in-progress flag
  1059. ;
  1060.      IF    RTC AND TIMEON
  1061.     STA    MXTIME        ; Show clock hasn't been read yet
  1062.      ENDIF            ; RTC AND TIMEON
  1063. ;
  1064.     LHLD    VCONOUT+1
  1065.     SHLD    COVECT        ; So xmodem can make direct BIOS calls
  1066. ;
  1067. ; Set MINICK to 'YES' if you use MINICBBS and want to take advantage of
  1068. ; its feature which can prevent the modem from hanging up if the caller
  1069. ; should happen to disconnect during a file update.  MINICBBS sets the
  1070. ; high-order bit of IOBYTE (address 0003H) to indicate a file update is
  1071. ; in progress.
  1072. ;
  1073.      IF    MINICK
  1074.     MVI    A,IOVAL        ; Get proper initial value
  1075.     STA    IOBYTE        ; Set it in IOBYTE
  1076.      ENDIF            ; MINICK
  1077. ;
  1078.      IF    MBBS
  1079.     LXI    SP,STACK
  1080.     CALL    MDCARCK
  1081.     JZ    START1        ; No carrier, skip this
  1082.     LDA    LCDATA
  1083.     CPI    ' '        ; User logged in?
  1084.     JZ    GOODBY        ; No, carry on
  1085.     XRA    A
  1086.     STA    0        ; Prep mbbs
  1087.     MVI    A,0FFH
  1088.     STA    WRTLOC        ; To prevent hangup
  1089.     LDA    FCB+1
  1090.     CPI    'C'        ; Comments requested?
  1091.     JZ    MBBSC        ; Yes, do comments
  1092.      ENDIF            ; MBBS
  1093. ;
  1094.      IF    MBBS AND PRNTGB
  1095.     LXI    H,GBMSG
  1096.     CALL    PRINTB        ; Say goodbye to user
  1097.      ENDIF            ; MBBS AND PRNTGB
  1098. ;
  1099.      IF    MBBS
  1100. MBBS01:    CALL    MDHANG        ; Drop carrier and fix so phone won't answer
  1101.     CALL    LODCOM        ; Load mbbs for logoff
  1102.     JMP    MBBSNC        ; And tell sysop
  1103. ;
  1104. MBBSC:    LXI    H,MBBS1
  1105.     CALL    PRINTB        ; Wait for mbbs to load
  1106.     CALL    LODCOM        ; Load mbbs
  1107.     CALL    MDCARCK        ; Did user wait for all this?
  1108.     JZ    MBBSNC        ; No, tell mbbs
  1109.     MVI    A,0CDH
  1110.     STA    0        ; So mbbs will ask for comments
  1111.     CALL    100H        ; Now do it
  1112. ;
  1113. MBBSNC:    LXI    H,MBBS2
  1114.     CALL    PRINTL        ; Tell sysop about log off
  1115.     MVI    A,0FFH
  1116.     STA    MDMOFF        ; So bye will handle rest of this
  1117.     MVI    A,'E'
  1118.     STA    OPTION        ; So bye will trap mbbs return
  1119.     CALL    100H        ; Let mbbs finish user stats
  1120.      ENDIF            ; MBBS
  1121. ;
  1122.     CALL    MDCARCK        ; Call modem carrier check routine
  1123.     JNZ    GOODBY        ; We have carrier, so say bye bye...
  1124. ;
  1125. START1:     IF    COMFILE
  1126.     LDA    FCB+1
  1127.     STA    OPTION        ; So remote cannot type BYE E
  1128.     MVI    A,' '
  1129.     STA    FCB+1
  1130.      ENDIF            ; COMFILE
  1131. ;
  1132. ; Identify version of program
  1133. ;
  1134.     CALL    PATCH        ; Copies vectors for PRINTL
  1135.     CALL    UNPATCH
  1136.     LXI    H,VMSG        ; Signon message
  1137.     CALL    PRINTL
  1138.     JMP    HANGUP        ; We know it is local, so skip call to
  1139.                 ; Carrier check
  1140. ;
  1141. NOSLASH:CALL    CARCK        ; Signed off with this program?
  1142.     JC    HANGUP        ; Nobody there
  1143. ;
  1144. GOODBY:     IF    PRNTGB
  1145.     LXI    H,GBMSG        ; Goodbye message
  1146.     CALL    PRINTB        ; Print this message
  1147.      ENDIF            ; PRNTGB
  1148. ;
  1149.     CALL    IMHANG        ; Hang up the phone before doing this
  1150.     CALL    UNPATCH        ; Undo BIOS patches
  1151. ;
  1152. ; Nobody there, or we are done.
  1153. ;
  1154. HANGUP:    LXI    SP,STACK    ; Set up local stack
  1155.     CALL    IMHANG        ; Hangup phone (from twitdrop)
  1156.     XRA    A        ; Force next warmboot to user 0
  1157.     STA    0004H        ; And drive a:
  1158. ;
  1159.      IF    COMFILE
  1160.     CALL    LODCOM        ; Load the .COM file
  1161.      ENDIF
  1162. ;
  1163. ;
  1164. ; Give summary and initialize for next call
  1165. ;
  1166. HANGUP1: IF    CLRSCR AND CLRB4
  1167.     LXI    H,CLRSEQ
  1168.     CALL    PRINTL        ; Clear local crt screen
  1169.      ENDIF
  1170. ;
  1171.      IF    NO25TH OR MBBS
  1172.     LXI    H,LFMSG
  1173.     CALL    PRINTL
  1174.     LXI    H,LCDATA
  1175.     CALL    PRINTL        ; Show sysop who was just on
  1176.     LXI    H,LCFILL
  1177.     LXI    D,LCDATA
  1178.     MVI    B,78
  1179.     CALL    MOVE        ; Put filler msg into lastcalr for now
  1180.      ENDIF
  1181. ;
  1182.      IF    TIMEON AND RTC AND NO25TH
  1183.     LXI    H,TONMSG
  1184.     CALL    PRINTL        ; Show him how long last guy was on
  1185.     MVI    A,' '
  1186.     STA    TONMSD
  1187.     STA    TONMSD+1
  1188.     STA    TONMSD+2    ; Reset time buffer to spaces
  1189.      ENDIF
  1190. ;
  1191.     CALL    CALSUM        ; Give sysop call summary
  1192. ;
  1193.      IF    CLRSCR AND (NOT CLRB4)
  1194.     LXI    H,CLRSEQ
  1195.     CALL    PRINTL
  1196.      ENDIF
  1197. ;
  1198.      IF    B3IM AND HS2400
  1199.     CALL    SET2400        ; Talk to the modem at its highest speed
  1200.      ENDIF
  1201. ;
  1202.      IF    B3IM AND HS1200
  1203.     CALL    SET1200
  1204.      ENDIF
  1205. ;
  1206.      IF    B3IM AND HS300
  1207.     CALL    SET300
  1208.      ENDIF
  1209. ;
  1210.     CALL    MDINIT        ; Call modem initialization routine
  1211. ;
  1212.     MVI    A,0C3H        ; Clear any traps left from .COM file
  1213.     STA    0
  1214.     XRA    A        ; Clear any emulation modes
  1215.     STA    MDMOFF        ; Turn modem on
  1216.     STA    WRTLOC        ; Turn write flag off
  1217. ;
  1218.      IF    COMFILE
  1219.     LDA    OPTION
  1220.     CPI    'E'        ; Execute comfile locally?
  1221.     JNZ    RINGWT        ; No, continue
  1222.     CALL    MDQUIT        ; Fix modem so won't answer phone
  1223.     MVI    A,0FFH
  1224.     STA    MDMOFF        ; Turn modem off
  1225.     STA    WRTLOC        ; And write flag
  1226.     JMP    ANSW        ; Skip this
  1227.      ENDIF
  1228. ;
  1229. ; Await ringing - check local keyboard for CTL-C exit request.    Note:
  1230. ; Must do input via BDOS because CBIOS patches are not done until the
  1231. ; call comes in.
  1232. ;
  1233. RINGWT:    CALL    UCSTS
  1234.     ANI    7FH        ; Strip parity bit
  1235.     CPI    'C'-40H        ; CTL-C?
  1236.     CZ    USRCHK        ; Check for exit
  1237.     CALL    CKFUNC        ; Check for function keys
  1238. ;
  1239.      IF    MDMRNG AND NOT B3IM
  1240.     CALL    MDRING        ; Have a modem that MUST have ring signal
  1241.     JZ    RINGWT
  1242.     CALL    MDANSW        ; Answer phone
  1243. ;
  1244.     MVI    B,CFRST*10    ; Set for 'CFRST' seconds
  1245. WTCLP:    CALL    DELAY        ; Wait .1 second
  1246.     CALL    MDCARCK        ; Check for carrier
  1247.     JNZ    GOTCR        ; We got carrier
  1248.     DCR    B
  1249.     JNZ    WTCLP        ; Is our time up? (no..wait)
  1250.     JMP    HANGUP        ; Yes, time is up..go wait for another ring
  1251. ;
  1252. GOTCR    EQU    $        ; Carrier present
  1253.      ENDIF
  1254. ;
  1255.      IF    B3IM
  1256.     CALL    IMRING        ; Check for ring, answer phone, etc.
  1257.     JZ    RINGWT
  1258.      ENDIF
  1259. ;
  1260.      IF    NOT (B3IM OR MDMRNG)
  1261.     CALL    MDCARCK        ; Modem has no ring signal, check for carrier
  1262.     JZ    RINGWT        ; Nope, loop
  1263.      ENDIF
  1264. ;
  1265. ;-----------------------------------------------------------------------
  1266. ;
  1267. ;    Answer routine
  1268. ;
  1269. ANSW:    CALL    BDCHEK
  1270. ;
  1271.      IF    ZCPR2 OR ZCPR3    ; Only when using ZCPR w/secure mode
  1272.     XRA    A        ; When running ZCPR for your CCP.
  1273.     STA    WHEEL        ; Answer the phone in non-wheel mode
  1274.      ENDIF            ; ZCPR OR ZCPR3
  1275. ;
  1276.      IF    (NOT USEZCPR) AND (ZCPR2 OR ZCPR3)
  1277.     MVI    A,MAXUSR    ; Reset maximum user area
  1278.     STA    MXUSR        ; Set it in bye
  1279.     INR    A        ; Bump it
  1280.     STA    MAXUSER        ; Set it in ZCPR
  1281.     MVI    A,MAXDRV    ; Reset maximum drive
  1282.     STA    MXDRV
  1283.     DCR    A
  1284.     STA    MAXDRIV
  1285.      ENDIF            ; (NOT USEZCPR) AND (ZCPR2 OR ZCPR3)
  1286. ;
  1287.      IF    CHGPATH        ; If external ZCPR path
  1288.     LXI    H,REMPATH    ; Source=remote path
  1289.     LXI    D,EXTPATH    ; Dest=external path at 0040H
  1290.     MVI    B,LREMP        ; Length of remote path
  1291.     CALL    MOVE
  1292.      ENDIF            ; CHGPATH
  1293. ;
  1294.     XRA    A        ; Make sure line feeds are on again
  1295.     STA    LFEEDS
  1296.     STA    NULLS        ; Set nulls to 0 before asking question
  1297.     STA    MXTIME        ; Turn off time check
  1298.     STA    NULTRY        ; Reset Nulls question counter
  1299.     STA    CDOFF        ; Limit for waiting for c/r
  1300.     STA    FKATTN        ; Reset attention character
  1301. ;
  1302.     MVI    A,TOVALUE    ; Reset timeout count
  1303.     STA    TOVAL
  1304. ;
  1305.      IF    NO25TH OR MBBS
  1306.     MVI    A,' '        ; Clear the LC buffer
  1307.     STA    LCDATA
  1308.      ENDIF
  1309. ;
  1310.      IF    NOT (NO25TH OR MBBS)
  1311.     XRA    A        ; Tell the system there's no LC buffer
  1312.     STA    LCDATA
  1313.      ENDIF
  1314. ;
  1315.      IF    COMFILE
  1316.     LDA    OPTION
  1317.     CPI    'E'
  1318.     JZ    WELCOME        ; Skip this if running local
  1319.      ENDIF
  1320. ;
  1321.     LXI    H,CWCAR        ; Get # of attempts
  1322.     INR    M        ; And add one
  1323. ;
  1324.      IF    B3IM
  1325.     JMP    WELCOME        ; Skip the old fashion CR detect method
  1326.      ENDIF
  1327. ;
  1328.      IF    NOT B3IM
  1329. ANSWA:    CALL    SET300
  1330.     MVI    A,BP300        ; Poke in MSPEED value
  1331.     STA    MSPEED
  1332.     CALL    MDINP        ; Clear garbage characters
  1333.     CALL    MDINP
  1334. ;
  1335. ; Now test input for baud rate - FIRST, check for 300 baud
  1336. ;
  1337. ANSWB:    CALL    PATCH        ; Patch jump table
  1338.      ENDIF
  1339. ;
  1340.      IF    PRGRSS AND (NOT    B3IM)
  1341.     LXI    H,MSG30
  1342.     CALL    PRINTL        ; Print locally
  1343.      ENDIF
  1344. ;
  1345.      IF    NOT B3IM
  1346.     CALL    TSTBAUD        ; See if 300 baud
  1347.     JZ    WELCOME        ; Yes, exit
  1348.      ENDIF
  1349. ;
  1350. ;
  1351. ; Now check for 1200 bps
  1352. ;
  1353.      IF    PRGRSS AND (NOT    B3IM) AND (HS1200 OR HS2400)
  1354.     LXI    H,MSG12
  1355.     CALL    PRINTL        ; Print locally
  1356.      ENDIF
  1357. ;
  1358.      IF    (NOT B3IM) AND (HS1200 OR HS2400)
  1359.     CALL    SET1200        ; Now check 1200 bps
  1360.     JNZ    ANS0
  1361.     MVI    A,BP1200    ; Set the MSPEED pointer
  1362.     STA    MSPEED
  1363.     CALL    MDINP        ; Clear garbage
  1364.     CALL    TSTBAUD        ; Check baud rate
  1365.     JZ    WELCOME
  1366.      ENDIF
  1367. ;
  1368. ANS0:     IF    PRGRSS AND (NOT    B3IM) AND HS2400
  1369.     LXI    H,MSG24
  1370.     CALL    PRINTL        ; Print locally
  1371.      ENDIF
  1372. ;
  1373.      IF    (NOT B3IM) AND HS2400
  1374.     CALL    SET2400        ; Check for 2400 baud
  1375.     JNZ    BADDO        ; Start over
  1376.     MVI    A,BP2400    ; Set speed indicator
  1377.     STA    MSPEED
  1378.     CALL    MDINP        ; Clear garbage
  1379.     CALL    TSTBAUD        ; Check it
  1380.     JZ    WELCOME
  1381.      ENDIF
  1382. ;
  1383.      IF    (NOT B3IM)
  1384. BADDO:    CALL    UNPATCH        ; Restore original jump table
  1385.     JMP    ANSWA        ; Test more - invalid baud rate
  1386.      ENDIF
  1387. ;
  1388. ;              end of answer routine
  1389. ;-----------------------------------------------------------------------
  1390. ;
  1391. ;    Fix BDOS vector to point to BYE
  1392. ;
  1393. BDCHEK:    PUSH    H        ; To make truly universal, this
  1394.     DB    LXIH        ; Program always re-stores the BDOS
  1395. ;
  1396. BDADDR:    DW    0000H        ; Pointer at 6 and 7 set up location for
  1397.     SHLD    6        ; Beginning address of BYE
  1398.     POP    H        ; At every chance.
  1399.     RET
  1400. ;
  1401. ;-----------------------------------------------------------------------
  1402. ;
  1403. ; Common routine to check for carrier lost - called from console out
  1404. ;
  1405. CHECK:     IF    MINICK
  1406.     LDA    IOBYTE        ; Get IOBYTE
  1407.     ANI    80H        ; Test for disk update
  1408.     RNZ            ; Busy, wait until done
  1409.      ENDIF
  1410. ;
  1411.      IF    RBBSCK OR MBBS
  1412.     LDA    WRTLOC        ; Get write in progress flag
  1413.     ORA    A
  1414.     RNZ            ; Busy, wait until done
  1415.      ENDIF
  1416. ;
  1417.     LDA    MDMOFF
  1418.     ORA    A        ; Know modem off?
  1419.     RNZ            ; Yes, skip this
  1420.     CALL    CARCK        ; See if carrier still on
  1421.     RNC            ; All ok
  1422. ;
  1423. ; Carrier is lost.  Type message so local console shows the reason.
  1424. ; Come here on bad password.
  1425. ;
  1426. BADPASS:LXI    SP,STACK    ; Ensure valid stack
  1427.     MVI    A,0FFH        ; Turn off modem I/O
  1428.     STA    MDMOFF
  1429.     LXI    H,CLMSG        ; Carrier lost message
  1430.     CALL    PRINTL        ; Send this Message
  1431. ;
  1432. DROPCAR:LXI    SP,STACK
  1433.     CALL    UNPATCH        ; Restore original BIOS jump table
  1434.     XRA    A        ; Clear out carrier lost flag
  1435.     STA    MDMOFF
  1436.     STA    MXTIME        ; Reset time
  1437. ;
  1438.      IF    EXFILE
  1439.     MVI    C,SETUSR    ; Select user area for EXITFILE
  1440.     MVI    E,EXUSR
  1441.     CALL    BDOS
  1442.     MVI    C,SELDSK    ; Select default drive for EXITFILE
  1443.     MVI    E,EXDRV-'A'
  1444.     CALL    BDOS
  1445.     CALL    LODEX
  1446.     CPI    '*'        ; Test that file was really loaded
  1447.     JNZ    100H        ; EXITFIL was't loaded, so run it
  1448.      ENDIF
  1449. ;
  1450.     CALL    UNPATCH
  1451.     JMP    HANGUP
  1452. ;
  1453. ;
  1454. ;-----------------------------------------------------------------------
  1455. ;
  1456. ;      Function key routines
  1457. ;
  1458. CKFUNC:    PUSH    PSW
  1459.     XRA    A
  1460.     STA    FKATTN        ; We're doing the function key now...
  1461.     POP    PSW
  1462.     CPI    ATTNCH        ; Is it attention character?
  1463.     RZ            ; Return with it in buffer
  1464.     ANI    01FH        ; Make key control-code
  1465.     ORI    040H        ; Make key upper case letter
  1466. ;
  1467.      IF    NO25TH OR MBBS
  1468.     CPI    WHOKEY
  1469.     JZ    WHOSIT        ; Display last caller data
  1470.      ENDIF
  1471. ;
  1472.      IF    TIMEON AND RTC
  1473.     CPI    TIMEKEY
  1474.     JZ    DTIME        ; Case running local, allow debug
  1475.     CPI    ULTMKEY        ; Set unlimited time-on system
  1476.     JZ    UTIME
  1477.      ENDIF
  1478. ;
  1479.     CPI    ZCREEN
  1480.     JZ    CLEARIT        ; Sysop wants to clear his screen
  1481. ;
  1482.     CPI    BELLKEY
  1483.     JZ    BELLTOG        ; Toggle bell on/off
  1484. ;
  1485.     MOV    B,A
  1486.     PUSH    B
  1487.     CALL    MDCARCK        ; See if carrier is on, because
  1488.     POP    B
  1489.     MOV    A,B
  1490.     RZ            ; The following keys are useless without it.
  1491. ;
  1492.     CPI    BLNKKEY        ; Turn off caller's output for a moment?
  1493.     JZ    BLNKTOG        ; (this is a toggle)
  1494.     CPI    SYSDKEY
  1495.     JZ    SYSDOWN        ; Tell caller system is going down
  1496.     CPI    TWITKEY
  1497.     JZ    DROPCAR        ; Hang up on the twit
  1498.     CPI    MSGKEY
  1499.     RNZ
  1500. ;
  1501. ; Message from Sysop
  1502. ;
  1503.     LXI    H,MFSMSG    ; SYSOP message
  1504.     CALL    PRINTB        ; Tell caller you want to say something
  1505. ;
  1506. SYSML:    CALL    VCONIN        ; Get key from sysop
  1507.     CPI    'C'-'@'        ; If ^C, exit loop
  1508.     JZ    SYSMX
  1509.     MOV    C,A        ; Else echo to console and modem
  1510.     PUSH    PSW
  1511.     CALL    MOUTPUT
  1512.     POP    PSW
  1513.     CPI    'H'-'@'        ; If BS, do BS/SP/BS
  1514.     JZ    SYSMBS
  1515.     CPI    CR        ; If CR, do CRLF
  1516.     JZ    SYSMCR
  1517.     JMP    SYSML
  1518. ;
  1519. SYSMCR:    MVI    C,LF        ; Do linefeed after CR
  1520.     JMP    SYSECH
  1521. ;
  1522. SYSMBS:    MVI    C,' '
  1523.     CALL    MOUTPUT
  1524.     MVI    C,'H'-'@'
  1525. ;
  1526. SYSECH:    CALL    MOUTPUT
  1527.     JMP    SYSML
  1528. ;
  1529. SYSMX:    MVI    C,CR        ; Do crlf
  1530.     CALL    MOUTPUT
  1531.     MVI    C,LF
  1532.     CALL    MOUTPUT
  1533.     MVI    A,'H'-'@'    ; Return with bs for buffer
  1534.     RET
  1535. ;
  1536. ; System Going down
  1537. ;
  1538. SYSDOWN:LXI    H,SGDMSG    ; System going down message
  1539.     CALL    PRINTB        ; Send this message
  1540. ;
  1541.      IF    TIMEON AND RTC
  1542.     CALL    TCHECK        ; Calculate current time-on-system
  1543.     LDA    TON        ; Fetch it
  1544.     ADI    DOWNMIN        ; Give him this much longer
  1545.     STA    MXTIME        ; And BYE will log him off
  1546.      ENDIF            ; TIMEON AND RTC
  1547. ;
  1548.     MVI    A,'H'-'@'    ; Return with bs for buffer
  1549.     RET
  1550. ;
  1551. ; Toggle bell
  1552. ;
  1553. BELLTOG:LDA    BELLON        ; Get bell status
  1554.     ORA    A
  1555.     MVI    A,0FFH        ; Prepare for on
  1556.     LXI    H,BELMON
  1557.     JZ    BELT1        ; Go turn bell on
  1558.     XRA    A        ; Else turn bell off
  1559.     LXI    H,BELMOFF
  1560. ;
  1561. BELT1:    STA    BELLON
  1562.     CALL    PRINTL        ; Print status message locally
  1563.     MVI    A,'H'-'@'    ; Return with bs for buffer
  1564.     RET
  1565. ;
  1566. ; Toggle blankout
  1567. ;
  1568. BLNKTOG:LDA    MDMOFF
  1569.     ORA    A        ; If zero, make 0FFH
  1570.     MVI    A,0FFH        ; (we do not use CMA, because MDMOFF
  1571.     LXI    H,SCRMOFF
  1572.     JZ    BLNKT1        ; Could equal a different value like 1)
  1573.     XRA    A        ; If not zero, make it zero
  1574.     LXI    H,SCRMON
  1575. BLNKT1:    STA    MDMOFF
  1576.     CALL    PRINTL
  1577.     MVI    A,'H'-'@'    ; Return with bs for buffer
  1578.     RET
  1579. ;
  1580. ;    Who's on the system?
  1581. ;
  1582.      IF    NO25TH OR MBBS
  1583. WHOSIT:    LXI    H,CRMSG        ; Turn up a fresh line
  1584.     CALL    PRINTL
  1585.     LXI    H,LCDATA
  1586.     CALL    PRINTL        ; Show sysop lastcaller data
  1587.     LXI    H,CRMSG
  1588.     CALL    PRINTL        ; New line for neatness
  1589.     MVI    A,'H'-'@'    ; Return with bs for buffer
  1590.     RET
  1591.      ENDIF
  1592. ;
  1593. ;    Display time
  1594. ;
  1595.      IF    TIMEON AND RTC
  1596. DTIME:    CALL    TCHECK
  1597.     LXI    H,LFMSG
  1598.     CALL    PRINTL
  1599.     LXI    H,TONMSG
  1600.     CALL    PRINTL        ; Print time on
  1601.     LXI    H,LFMSG
  1602.     CALL    PRINTL
  1603.     MVI    A,'H'-'@'    ; Return with bs for buffer
  1604.     RET
  1605. ;
  1606. ;    Set unlimited time on system
  1607. ;
  1608. UTIME:    XRA    A        ; Set MAXTIME to 0
  1609.     STA    MXTIME
  1610.     LXI    H,UTIMEM    ; Print message
  1611.     CALL    PRINTL
  1612.     MVI    A,'H'-'@'
  1613.     RET
  1614.      ENDIF
  1615. ;
  1616. ;    Clear local screen
  1617. ;
  1618. CLEARIT:LXI    H,CLRSEQ
  1619.     CALL    PRINTL        ; Clear local screen
  1620.     MVI    A,'H'-'@'
  1621.     RET            ; BS for buffer
  1622. ;
  1623. ;-----------------------------------------------------------------------
  1624. ;
  1625. ;    BYE RSX interceptor
  1626. ;
  1627. REALBD:    JMP    0        ; Will be filled in to point to REAL bdos
  1628. ;
  1629. BYERSX:    MVI    A,HICMD        ; [trackable by CBF RSX handler]
  1630.     CMP    C        ; > than HICMD?
  1631.     JC    REALBD        ; Yes, go to real-BDOS
  1632.     MVI    A,SETUSR    ; BDOS user code?
  1633.     CMP    C
  1634.     JZ    TSTUSR        ; Yes, so do our special thing
  1635.     MVI    A,LOCMD-1    ; Less than lowest RSX command?
  1636.     CMP    C
  1637.     JNC    REALBD        ; Go do standard BDOS call
  1638. ;
  1639. ;    Ok, it's one of our commands, sigh let's get to work
  1640. ;
  1641.     MOV    A,C
  1642.     SUI    LOCMD        ;commands now range from 0..hicmd-locmd
  1643.     PUSH    D
  1644.     MOV    E,A        ;save copy of command in A
  1645.     ADD    A        ;A=2*A
  1646.     ADD    E        ;A=3*A    3x offset for each vector
  1647.     MOV    E,A        ;make command offset 16-bits
  1648.     MVI    D,0        ;DE = offset into table
  1649. ;
  1650.     LXI    H,RSXTBL
  1651.     DAD    D        ;HL points to entry in RSXTBL now
  1652.     POP    D
  1653.     MOV    A,E        ;Generalized movement of input data
  1654.     PCHL            ;Jump to entry in rsx table
  1655. ;
  1656. RSXTBL:    JMP    MDINST        ;modem input status            61
  1657.     JMP    MDOUTST        ;modem output status            62
  1658.     JMP    MDOUTP        ;modem output character (raw)        63
  1659.     JMP    MDINP        ;modem input character (raw)        64
  1660.     JMP    MDCARCK        ;modem carrier check            65
  1661.     JMP    VCONSTAT    ;console input status            66
  1662.     JMP    CONIN        ;console input character (loop)        67
  1663.     JMP    RCONOT        ;console output character (loop)    68
  1664.     JMP    RMXDRV        ;set maximum drive            69
  1665.     JMP    RMXUSR        ;set maximum user area            70
  1666.     JMP    RMTOUT        ;set timeout value            71
  1667.     JMP    RMNULL        ;set nulls                72
  1668.     JMP    RMULC        ;set upper/lower case flag        73
  1669.     JMP    RMLFM        ;set line feed mask            74
  1670.     JMP    RMWRT        ;set writeloc                75
  1671.     JMP    RMHDR        ;set hardlog copy flag            76
  1672.     JMP    RMOFF        ;set modemoff flag            77
  1673.     JMP    RMBELL        ;set console bell flag            78
  1674.     JMP    RMRTC        ;return RTC buffer area            79
  1675.     JMP    RMLCBF        ;return LC buffer area            80
  1676.     JMP    RMMXT        ;set maxmimum time on system        81
  1677.     JMP    RMLTIM        ;set login time                82
  1678.     JMP    RMTOS        ;print tos message (on both consoles)    83
  1679. ;
  1680. ;    BYE existance test
  1681. ;
  1682. TSTUSR:    MOV    A,E        ;Get E register value
  1683.     CPI    241        ;Was E = 241?
  1684.     JNZ    REALBD        ;nope, was for BDOS
  1685.     MVI    A,77        ;was for us, say we're alive
  1686.     RET
  1687. ;
  1688. RCONOT:    MOV    C,E        ;Get byte to send
  1689.     JMP    VCONOUT
  1690. ;
  1691. RMXDRV:    LXI    H,MXDRV        ;Set/get maximum drive
  1692.     JMP    SETGET1
  1693. ;
  1694. RMXUSR:    LXI    H,MXUSR        ;Set/get maximum user area
  1695.     JMP    SETGET1
  1696. ;
  1697. RMNULL:    LXI    H,NULLS        ;Set/get nulls
  1698.     JMP    SETGET1
  1699. ;
  1700. RMTOUT:    LXI    H,TOVAL        ;Set/get timeout value
  1701.     JMP    SETGET1
  1702. ;
  1703. RMULC:    LXI    H,ULCSW        ;Set/get upper-lowercase flag
  1704.     JMP    SETGET1
  1705. ;
  1706. RMLFM:    LXI    H,LFEEDS    ;Set/get line-feed mask
  1707.     JMP    SETGET2
  1708. ;
  1709. RMHDR:    LXI    H,HARDON    ;Set/get hard-log
  1710.     JMP    SETGET2
  1711. ;
  1712. RMWRT:    LXI    H,WRTLOC    ;Set/get RBBS WRTLOC flag
  1713.     JMP    SETGET2
  1714. ;
  1715. RMOFF:    LXI    H,MDMOFF    ;Set/get modem-off flag
  1716.     JMP    SETGET2
  1717. ;
  1718. RMBELL:    LXI    H,BELLON    ;Set/get console-bell flag
  1719.     JMP    SETGET2
  1720. ;
  1721. RMRTC:     IF    TIMEON AND RTC
  1722.     CALL    TCHECK           ; Set time on system & rtc buffer
  1723.      ENDIF
  1724. ;
  1725.      IF    RTC AND NOT TIMEON ; Set rtc buffer
  1726.     CALL    TIME
  1727.      ENDIF
  1728. ;
  1729.     LXI    H,RTCBUF    ;return address of RTC buffer
  1730.     LDA    TON        ;and time on system in A
  1731.     RET
  1732. ;
  1733. RMLCBF:    LXI    H,LCDATA    ;return address of LC data buffer
  1734.     RET
  1735. ;
  1736. RMMXT:    LXI    H,MXTIME    ;Set/get maximum time online
  1737.     JMP    SETGET1
  1738. ;
  1739. RMLTIM:    STA    LMIN        ;Set login time
  1740.     MOV    A,D
  1741.     STA    LHOUR
  1742.     RET
  1743. ;
  1744. RMTOS:     IF    TIMEON AND RTC    ;Only do this if we can..otherwise RET
  1745.     CALL    TCHECK        ;Set time in message
  1746.     LXI    H,TONMSG
  1747.     CALL    PRINTB        ;Print it
  1748.      ENDIF            ; TIMEON AND RTC
  1749.     RET
  1750. ;
  1751. ;    SETGET1 - if A=0..254 then poke value with A
  1752. ;            - if A=255    then return with current value
  1753. ;
  1754. SETGET1:INR    A        ;if A was 255, Z flag will now be set
  1755.     JZ    SGET1        ;we want to get current value
  1756.     DCR    A
  1757.     MOV    M,A        ;no, set current value
  1758.     RET
  1759. ;
  1760. SGET1:    MOV    A,M        ;return with current value in A
  1761.     RET
  1762. ;
  1763. ;    SETGET2 - if A=0      then poke value with 0
  1764. ;        - if A=1      then poke value with 255
  1765. ;        - if A=255    then return with current value
  1766. ;
  1767. SETGET2:INR    A        ;if A was 255, Z flag will now be set
  1768.     JZ    SGET2        ;we want to get current value
  1769.     DCR    A        ;if it's zero, then poke a zero
  1770.     JZ    SGET2W
  1771.     MVI    A,255        ;else poke a 255
  1772. SGET2W:    MOV    M,A
  1773.     RET
  1774. ;
  1775. SGET2:    MOV    A,M        ;return with current value in A
  1776.     RET
  1777. ;
  1778. ;-----------------------------------------------------------------------
  1779. ;
  1780. CONIN:    PUSH    B
  1781.     PUSH    D
  1782.     PUSH    H
  1783.     CALL    VCONIN
  1784. ;
  1785.     CPI    ATTNCH
  1786.     JNZ    CON1        ; If not attention character
  1787.     LDA    FKATTN
  1788.     ORA    A
  1789.     MVI    A,ATTNCH
  1790.     JNZ    CON2
  1791. ;
  1792.     MVI    A,0FFH        ; Set special flag
  1793.     STA    FKATTN
  1794.     MVI    A,'H'-'@'    ; Return a ^H
  1795.     JMP    CON2
  1796. ;
  1797. CON1:    MOV    B,A        ; Save character in B
  1798.     LDA    FKATTN        ; If special key last sent, then check fkeys
  1799.     ORA    A
  1800.     MOV    A,B        ; restore character
  1801.     CNZ    CKFUNC
  1802. ;
  1803. CON2:    POP    H
  1804.     POP    D
  1805.     POP    B
  1806.     RET
  1807. ;
  1808. ;-----------------------------------------------------------------------
  1809. ;
  1810. CONOUT:    PUSH    B
  1811.     PUSH    D
  1812.     PUSH    H
  1813.     CALL    VCONOUT
  1814.     POP    H
  1815.     POP    D
  1816.     POP    B
  1817.     RET
  1818. ;
  1819. ;-----------------------------------------------------------------------
  1820. ;
  1821. CONSTAT:PUSH    B
  1822.     PUSH    D
  1823.     PUSH    H
  1824.     CALL    VCONSTAT
  1825.     POP    H
  1826.     POP    D
  1827.     POP    B
  1828.     RET
  1829. ;
  1830. ;-----------------------------------------------------------------------
  1831. ;
  1832. ; .1 sec delay routine
  1833. ;
  1834. DELAY:    PUSH    B
  1835.     LXI    B,4167*MHZ    ; Timing constant * clock MHz
  1836. ;
  1837. DELAY1:    DCX    B
  1838.     MOV    A,B
  1839.     ORA    C
  1840.     JNZ    DELAY1
  1841.     POP    B
  1842.     RET
  1843. ;
  1844. ; 1 millisecond delay routine
  1845. ;
  1846. KDELAY:    PUSH    B
  1847.     LXI    B,42*MHZ    ; Timing constant * clock MHz
  1848.     JMP    DELAY1
  1849. ;
  1850. ;-----------------------------------------------------------------------
  1851. ;
  1852. ; Here to exit to CP/M, first reset the Port/Modem to default status
  1853. ;
  1854. EXCPM:    CALL    MDQUIT        ; Return Port/Modem to default settings
  1855. ;
  1856.     LHLD    REALBD+1    ; Get real bdos vector
  1857.     SHLD    6        ; Save it so CP/M doen't crash
  1858. ;
  1859.      IF    ZCPR2 OR ZCPR3
  1860.     MVI    A,0FFH
  1861.     STA    WHEEL        ; Restore wheel byte for SYSOP
  1862.     MVI    A,SYSUSR+1
  1863.     STA    MAXUSER        ; And MAXUSR
  1864.     MVI    A,SYSDRV-1
  1865.     STA    MAXDRIV        ; And MAXDRIV
  1866.      ENDIF            ; ZCPR2 OR ZCPR3
  1867. ;
  1868.      IF    CHGPATH        ; If external zcpr path
  1869.     LXI    H,SYSPATH    ; Source=SYSOP's path
  1870.     LXI    D,EXTPATH    ; Dest=external path at 0040H
  1871.     MVI    B,LSYSP        ; Length of new path
  1872.     CALL    MOVE
  1873.      ENDIF            ; CHGPATH
  1874. ;
  1875.      IF    ZCPR3
  1876.     CALL    DOZ3        ; ZCPR3 re-initialization
  1877.      ENDIF            ; ZCPR3
  1878. ;
  1879.     LHLD    BEGOBJ+1
  1880.     SHLD    BDOS+1        ; Some systems do not restore this on warmboot
  1881.     JMP    0000H        ; Warm boot CP/M
  1882. ;
  1883. ; ZCPR3 command line buffer, shell stack, TCAP stuff
  1884. ;
  1885.      IF    ZCPR3
  1886. DOZ3:    LHLD    Z3CL        ; Z3CL is the address of the MCLB
  1887.     MVI    M,0
  1888. ;
  1889. ; Command line done, now do shell stack
  1890. ;
  1891.     LXI    H,SHSTK        ; SHSTK is the addr of the Shell Stack
  1892.     CALL    ZERO128
  1893. ;
  1894. ; Now initialize  TCAP
  1895. ;
  1896. ;    LXI    H,Z3ENV+128    ; Z3ENV is the address of the Environ-
  1897. ;    CALL    ZERO128        ; Ment Descriptor...the TCAP is the
  1898.                 ; Second 128 bytes
  1899. ;
  1900. ; Also clean up message buffers
  1901. ;
  1902.     LXI    H,Z3MSG        ; Z3MSG is the addr of the msg buffers
  1903.     MVI    B,80
  1904.     CALL    ZEROM
  1905.     RET
  1906. ;
  1907. ; Routine to zero memory blocks
  1908. ;
  1909. ZERO128:MVI    B,128
  1910. ;
  1911. ZEROM:    MVI    M,0
  1912.     INX    H
  1913.     DCR    B
  1914.     JNZ    ZEROM
  1915.     RET
  1916.      ENDIF            ; ZCPR3
  1917. ;
  1918. ;-----------------------------------------------------------------------
  1919. ;
  1920. ; Loss of carrier test and drive/user validation
  1921. ;
  1922. CARCK:    LDA    MDMOFF
  1923.     ORA    A        ; Known loss?
  1924.     JNZ    CARCK2        ; Yes, allow d/u check locally
  1925.     CALL    MDCARCK        ; Carrier there?
  1926.     JNZ    CARCK2        ; Yep, go onto other checks...
  1927.     PUSH    B        ; Preserve so we can use it
  1928.     MVI    B,CLOSS*10    ; Set for 'CLOSS' seconds
  1929. ;
  1930. CARLP:    CALL    DELAY        ; Wait .1 seconds
  1931.     CALL    MDCARCK        ; Check for carrier
  1932.     MOV    A,B        ; Get count back in a
  1933.     POP    B        ; Fix stack in case all is ok
  1934.     JNZ    CARCK2        ; Got carrier, continue on
  1935.     DCR    A        ; Count time down
  1936.     STC            ; In case this is the end of 'time'
  1937.     RZ            ; Return if timed out
  1938.     PUSH    B        ; Preserve 'BC'
  1939.     MOV    B,A        ; Get counter value in 'B'
  1940.     JMP    CARLP        ; Keep checking
  1941. ;
  1942. ; Now test drive #'s and (if CP/M 2.x) user #'s to insure that maximums
  1943. ; are not exceeded.
  1944. ;
  1945. CARCK2:     IF    USEZCPR    AND (ZCPR2 OR ZCPR3)
  1946.     LDA    MAXDRIV
  1947.     INR    A
  1948.     STA    MXDRV
  1949.     LDA    MAXUSER        ; Get it from ZCPR/ZCMD
  1950.     DCR    A        ; Drop it one
  1951.     STA    MXUSR        ; Save it in bye
  1952.      ENDIF            ; USEZCPR AND (ZCPR2 OR ZCPR3)
  1953. ;
  1954.      IF    (NOT USEZCPR) AND (ZCPR2 OR ZCPR3)
  1955.     LDA    MXDRV        ; Older versions did not do this if
  1956.     DCR    A        ; Wheel was set -- BAD KARMA
  1957.     STA    MAXDRIV
  1958.     LDA    MXUSR        ; Get it from BYE
  1959.     INR    A        ; Bump it
  1960.     STA    MAXUSER        ; Save it in ZCPR
  1961.      ENDIF            ; (NOT USEZCPR) AND (ZCPR2 OR ZCPR3)
  1962. ;
  1963.     LDA    0004H        ; Check disk/user #
  1964.     ANI    0FH        ; Isolate drive
  1965.     PUSH    H        ; Save 'HL'
  1966.     LXI    H,MXDRV        ; Point to allowed # of drives
  1967.     CMP    M        ; Valid drive?
  1968.     JC    CARCK3        ; Yes, skip this junk
  1969.     LDA    0004H        ; Get whole login byte
  1970.     ANI    0F0H        ; Retain user # & force drive to A:
  1971.     STA    0004H        ; Update login byte
  1972.     LXI    H,IDMSG        ; Incorrect Drive Message
  1973.     CALL    PRINTB        ; Tell user what he did
  1974.     JMP    0000H        ; Warm boot
  1975. ;
  1976. ;    Drives were ok, check user areas
  1977. ;
  1978. CARCK3:    LDA    0004H        ; Get login byte
  1979.     ANI    0F0H        ; Isolate user #
  1980.     RRC            ; Move to low bits
  1981.     RRC
  1982.     RRC
  1983.     RRC
  1984.     LXI    H,MXUSR        ; Point to maximum user number
  1985.     CMP    M        ; Valid user #?
  1986.     JC    CARCK4        ; Yes, don't change
  1987.     JZ    CARCK4
  1988.     LDA    0004H        ; Get login byte again
  1989.     ANI    0FH        ; Keep drive, zero user area
  1990.     STA    0004H        ; Update login byte
  1991.     LXI    H,IUMSG        ; Invalid User message
  1992.     CALL    PRINTB        ; Tell him what happened
  1993.     JMP    0000H        ; Warm boot
  1994. ;
  1995. CARCK4:    POP    H        ; Restore 'HL'
  1996.     ORA    A
  1997.     RET
  1998. ;
  1999. ;-----------------------------------------------------------------------
  2000. ;
  2001. ;             print routines
  2002. ;
  2003. ; The following code has been modified to accomodate the automatic
  2004. ; loader.  (The loader may modify a constant, so all messages have been
  2005. ; place been placed at the end of the program and just moved to high
  2006. ; memory.)
  2007. ;
  2008. ; Print on both consoles ** USE ONLY IF IN PATCHED MODE **
  2009. ;
  2010. PRINTB:    PUSH    B        ; Save BC
  2011.     PUSH    PSW        ; And status regs
  2012. PRBL:    MOV    C,M        ; Get character
  2013.     CALL    MOUTPUT        ; Output it
  2014.     INX    H        ; Point to next character
  2015.     MOV    A,M        ; Test for end of message
  2016.     ORA    A
  2017.     JNZ    PRBL
  2018.     POP    PSW        ; Restore status regs
  2019.     POP    B        ; Restore BC
  2020.     RET
  2021. ;
  2022. ; Print locally only
  2023. ;
  2024. PRINTL:    PUSH    B        ; Save BC
  2025.     PUSH    PSW        ; And status regs
  2026. PRLL:    MOV    C,M        ; Get character
  2027.     CALL    CONOUT        ; Output it
  2028.     INX    H        ; Point to next character
  2029.     MOV    A,M        ; Test for end of message
  2030.     ORA    A
  2031.     JNZ    PRLL
  2032.     POP    PSW        ; Restore status regs
  2033.     POP    B        ; Restore BC
  2034.     RET
  2035. ;
  2036. ;-----------------------------------------------------------------------
  2037. ;
  2038. LISTOUT:PUSH    B
  2039.     PUSH    D
  2040.     PUSH    H
  2041.     PUSH    PSW
  2042.     CALL    VLISTOUT
  2043.     POP    PSW
  2044.     POP    H
  2045.     POP    D
  2046.     POP    B
  2047.     RET
  2048. ;
  2049. ;-----------------------------------------------------------------------
  2050. ;        .COM file routine
  2051. ;
  2052. ; Routine to load the .COM file
  2053. ;
  2054. LODCOM:     IF    COMFILE
  2055.     MVI    C,SELDSK
  2056.     MVI    E,COMDRV-'A'    ; Select drive with .COM file on
  2057.     CALL    BDOS
  2058.     MVI    C,SETUSR    ; Set CP/M user area function
  2059.     MVI    E,COMUSR    ; Location of our COMFILE
  2060.     CALL    BDOS
  2061.     LXI    H,COMFCB
  2062.     SHLD    CURRFCB
  2063.     XRA    A        ; Initialize FCB
  2064.     STA    COMFCB
  2065.     LXI    H,COMFCB+12
  2066.     MVI    B,21
  2067.     CALL    ZLOOP
  2068.     LXI    D,COMFCB
  2069.     CALL    OPENFIL
  2070.     JZ    ABORT
  2071.     JMP    LOADFIL
  2072.      ENDIF            ; COMFILE
  2073. ;
  2074. LODEX:     IF    EXFILE
  2075.     LXI    H,EXITFCB
  2076.     SHLD    CURRFCB
  2077.     LXI    H,EXITFCB+12
  2078.     MVI    B,21
  2079.     CALL    ZLOOP
  2080.     LXI    D,EXITFCB
  2081.     CALL    OPENFIL
  2082.     MVI    A,'*'        ; Do not try to run unloaded file
  2083.     RZ            ; Cannot open file, finish BYE hangup
  2084.      ENDIF            ; EXFILE
  2085. ;
  2086. ; Now load the file
  2087. ;
  2088.      IF    COMFILE    OR EXFILE
  2089. LOADFIL:
  2090.     LHLD    6        ; Get top of memory
  2091.     LXI    D,-80H
  2092.     DAD    D
  2093.     PUSH    H        ; Save on stack
  2094.     LXI    D,80H        ; TPA-80H
  2095.     LXI    B,0        ; Keep a record counter
  2096.     PUSH    B        ; Save counter
  2097.     PUSH    D        ; And load address
  2098. ;
  2099. GLOOP:    POP    D        ; Get TPA address
  2100.     LXI    H,80H        ; Point to next address to read to
  2101.     DAD    D        ; HL has the address
  2102.     POP    B        ; Increment the counter
  2103. ;
  2104. ; Check for load past top-of-memory
  2105. ;
  2106.     POP    D        ; Get (top-of-memory)
  2107.     PUSH    D        ; Resave for next time
  2108.     MOV    A,E        ; Subtract: (top) - (address)
  2109.     SUB    L
  2110.     MOV    A,D        ; Only the carry needed
  2111.     SBB    H
  2112.     JNC    SIZEOK        ; CY=better MOVCPM
  2113.     LXI    H,PTSMSG
  2114.     JMP    ERRXIT
  2115. ;
  2116. SIZEOK:    INX    B
  2117.     PUSH    B
  2118.     PUSH    H        ; Save TPA address
  2119.     XCHG            ; Align registers
  2120.     MVI    C,STDMA        ; Tell BDOS where to put record
  2121.     CALL    BDOS
  2122.     LHLD    CURRFCB        ; Point to aprropriate FCB
  2123.     XCHG
  2124.     MVI    C,READ
  2125.     CALL    BDOS
  2126.     ORA    A
  2127.     JZ    GLOOP        ; A=0 if more to read
  2128.     POP    B        ; Unjunk stack
  2129.     POP    B        ; This is our counter
  2130.     POP    H        ; More junk on stack
  2131.     MOV    A,B        ; Check for zero
  2132.     ORA    C
  2133.     JZ    ABORT        ; We should have read something
  2134.     LXI    D,80H        ; We did, reset DMA to 80H
  2135.     MVI    C,STDMA
  2136.     CALL    BDOS
  2137.     LXI    H,CFLMSG
  2138.     CALL    PRINTL
  2139.     RET
  2140. ;
  2141. ZLOOP:    MVI    M,0
  2142.     INX    H
  2143.     DCR    B
  2144.     JNZ    ZLOOP
  2145.     RET
  2146. ;
  2147. OPENFIL:MVI    C,OPEN        ; Open file pointed to by 'DE'
  2148.     CALL    BDOS
  2149.     INR    A
  2150.     RET
  2151. ;
  2152. ABORT:    LXI    H,CNFMSG
  2153. ;
  2154. ERRXIT:    CALL    PRINTL
  2155.     JMP    EXCPM        ; Warm boot
  2156.      ENDIF            ; COMFILE OR EXFILE
  2157. ;
  2158. ;            end of .COM file routine
  2159. ;-----------------------------------------------------------------------
  2160. ;
  2161. ; Boot trap - becomes disconnect if JMP at 0 has been altered
  2162. ;
  2163. MBOOT:     IF    COMFILE
  2164.     LDA    OPTION
  2165.     CPI    'E'        ; Return from local test?
  2166.     JNZ    MBOOT1        ; No, continue
  2167.     MVI    A,' '
  2168.     STA    FCB+1        ; Fool system
  2169.     CALL    UNPATCH        ; Yes, restore
  2170.     JMP    START0        ; And start fresh
  2171. MBOOT1:     ENDIF            ; COMFILE
  2172. ;
  2173.     LDA    0        ; Look at opcode
  2174.     CPI    0C3H        ; Is it still a jmp?
  2175.     JNZ    NOSLASH        ; No, so say bye bye...
  2176.     CALL    BDCHEK
  2177. ;
  2178.      IF    (NO25TH OR MBBS) AND NEEDLC
  2179.     LDA    LCDATA        ; See if lastcalr has been read
  2180.     CPI    ' '        ; Or data poked by a BBS, like MBBS
  2181.     JNZ    NO25EX        ; Yes, skip this
  2182.     XRA    A        ; Else, let's pick up the lastcalr file
  2183.     STA    FCBRNO        ; Prepare FCB for lastcalr
  2184.     LXI    H,LCNAME
  2185.     LXI    D,FCB
  2186.     MVI    B,13
  2187.     CALL    MOVE        ; Move rest of FCB
  2188.     MVI    C,0DH        ; Reset disk and
  2189.     CALL    BDOS        ; Set for default buffer
  2190.     MVI    C,SELDSK
  2191.     MVI    E,LCDRV-'A'
  2192.     CALL    BDOS        ; Set drive
  2193.     MVI    C,SETUSR
  2194.     MVI    E,LCUSR
  2195.     CALL    BDOS        ; And user
  2196.     LXI    D,FCB
  2197.     CALL    OPENFIL        ; Open it
  2198.     LXI    H,LCMSG1
  2199.     CZ    PRINTL        ; Error msg
  2200.     JZ    NO25EX        ; No file available, exit
  2201.     LXI    D,FCB
  2202.     MVI    C,READ
  2203.     CALL    BDOS        ; Read 1 record max
  2204.     LXI    H,LCMSG1
  2205.     ORA    A
  2206.     CNZ    PRINTL        ; Say error
  2207.     LXI    H,80H
  2208.     LXI    D,LCDATA
  2209.     MVI    B,78
  2210.     CALL    MOVE        ; Move data into bye's internal buffer
  2211.     MVI    B,78        ; We will display 78 chars max
  2212.     LXI    H,LCDATA
  2213. NO25RD:    MOV    A,M
  2214.     CPI    'Z'-'@'        ; EOF?
  2215.     JZ    NO25ZD
  2216.     CPI    ','
  2217.     CZ    NO25SP        ; Convert commas and semicolons to spaces
  2218.     CPI    ';'
  2219.     CZ    NO25SP
  2220.     CPI    CR
  2221.     CZ    NO25SP        ; CRLF's become spaces too.
  2222.     CPI    LF
  2223.     CZ    NO25SP
  2224.     DCR    B
  2225.     INX    H        ; Get next byte
  2226.     JMP    NO25RD
  2227. NO25ZD:    XRA    A
  2228.     MOV    M,A        ; Set terminator for print routine
  2229.     STA    0004H        ; Reset drive/user area to 0
  2230.      ENDIF            ; (NO25TH OR MBBS) AND NEEDLC
  2231. ;
  2232.      IF    NO25TH OR MBBS
  2233. NO25EX:    CALL    WHOSIT        ; Some BBSs will always poke the buffer
  2234.      ENDIF
  2235. ;
  2236. ; Special warm-boot routine - print a message or something - even run a
  2237. ; program if you want to!!!
  2238. ;
  2239. WMBMSGPRT:
  2240.      IF    WBRTN
  2241.     PUSH    B
  2242.     PUSH    D
  2243.     PUSH    H
  2244.      ENDIF
  2245. ;
  2246.      IF    PRNTWB
  2247.     LXI    H,WBMSG
  2248.     CALL    PRINTB        ; Print the following message:
  2249.      ENDIF
  2250. ;
  2251.      IF    WBRTN
  2252.     POP    H
  2253.     POP    D
  2254.     POP    B
  2255.      ENDIF
  2256. ;
  2257.      IF    RTC AND TIMEON AND TOSWB AND (ZCPR2 OR ZCPR3)
  2258.     LDA    WHEEL        ; Don't print message if guy is wheel
  2259.     ORA    A
  2260.     JNZ    VWARMBT        ; No, go do warm boot
  2261.      ENDIF
  2262. ;
  2263.      IF    RTC AND TIMEON AND TOSWB
  2264.     CALL    TCHECK
  2265.     LXI    H,TONMSG
  2266.     CALL    PRINTB        ; Display timeon
  2267.      ENDIF
  2268. ;
  2269.     JMP    VWARMBT        ; Go do a warm boot
  2270. ;
  2271. ;    Reset lastcaller buffer to nil
  2272. ;
  2273.      IF    NO25TH OR MBBS
  2274. NO25SP:    MVI    A,' '        ; Space
  2275.     MOV    M,A        ; To lcdata
  2276.     RET
  2277.      ENDIF
  2278. ;
  2279. ;-----------------------------------------------------------------------
  2280. ;
  2281. ; Modem input function, checks local console first
  2282. ;
  2283. MINPUT:    CALL    BDCHEK
  2284.     LDA    TOVAL        ; Get # of minutes before timeout
  2285. ;
  2286. MINP0:    STA    TOCNTM        ; Set minutes counter
  2287.     PUSH    H
  2288.     LXI    H,42000        ; Initialize one minute timeout counter
  2289.     SHLD    TOCNT
  2290.     POP    H
  2291. ;
  2292. MINP1:    CALL    MSTAT        ; Anything?
  2293.     ORA    A
  2294.     JNZ    MINP2
  2295.     CALL    KDELAY        ; Wait 1 ms
  2296.     PUSH    H
  2297.     LHLD    TOCNT        ; Knock down timeout counter
  2298.     DCX    H
  2299.     SHLD    TOCNT
  2300.     MOV    A,H
  2301.     ORA    L
  2302.     POP    H
  2303.     JNZ    MINP1        ; Still time left, keep trying
  2304.     LDA    TOCNTM        ; Count off last minute
  2305.     DCR    A
  2306.     JNZ    MINP0        ; Go back if time left
  2307. ;
  2308. TMOUT:    LXI    H,ITOMSG
  2309.     CALL    PRINTB
  2310.     JMP    NOSLASH
  2311. ;
  2312. MINP2:    CALL    CONSTAT        ; Check local console
  2313.     ORA    A        ; Character?
  2314.     JNZ    CONIN        ; Yes, read it & return
  2315. ;
  2316. ; Local console wasn't ready, so read modem
  2317. ;
  2318.     CALL    MDINP
  2319.     ANI    07Fh        ; Delete parity
  2320. ;
  2321.     MOV    B,A        ; Save it
  2322.     LDA    MDMOFF
  2323.     ORA    A        ; Is remote blanked?
  2324.     MVI    A,0        ; Null, just in case
  2325.     RNZ
  2326.     MOV    A,B        ; Restore character
  2327. ;
  2328.      IF    ZCPR2 OR ZCPR3
  2329.     MOV    B,A        ; Save byte in B
  2330.     LDA    WHEEL
  2331.     ORA    A
  2332.     MOV    A,B        ; Get character back
  2333.     JNZ    MINP2A        ; It's a wheel, don't trap ^P
  2334.      ENDIF            ; ZCPR2 OR ZCPR3
  2335. ;
  2336.     CPI    'P'-'@'        ; Is it a ^P?
  2337.     JNZ    MINP2A        ; No, don't do anything
  2338.     MVI    A,'H'-'@'    ; Make it a bs
  2339. ;
  2340. MINP2A:     IF    HARDLOG
  2341.     PUSH    B
  2342.     MOV    B,A        ; Put a copy of the character in B
  2343.     LDA    HARDON        ; If HARDON=0 then turn HARDLOG off (so
  2344.     ORA    A        ; SYSOP does not waste paper while he
  2345.     MOV    A,B        ; Playing ZORK from work.)
  2346.     POP    B
  2347.     JZ    NOLOG
  2348.     CPI    20H
  2349.     JNC    MINP3
  2350.     CPI    CR
  2351.     JNZ    NOLOG
  2352. ;
  2353. MINP3:    MOV    C,A        ; Move to reg "C"
  2354.     CALL    LISTOUT        ; Echo on printer
  2355.     CPI    CR
  2356.     JNZ    NOLOG        ; Return needs linefeed
  2357.     MVI    C,LF
  2358.     CALL    LISTOUT        ; So send it
  2359.     MVI    A,CR        ; Get back CR
  2360.      ENDIF            ; HARDLOG
  2361. ;
  2362. NOLOG:    CPI    'C'-'@'        ; Is it ^C?
  2363.     RNZ            ; No, pass it through
  2364.     LDA    0        ; See if warm boot disabled
  2365.     CPI    0C3H        ; Jump means warm boot ok
  2366.     MVI    A,3        ; So return with a ^C
  2367.     RZ
  2368.     MVI    A,CTRLC        ; Else convert to different character
  2369.     RET
  2370. ;
  2371. ;-----------------------------------------------------------------------
  2372. ;
  2373. ; Modem output function
  2374. ;
  2375. MOUTPUT:CALL    BDCHEK
  2376. ;
  2377.      IF    RTC
  2378.     MOV    A,C        ; Only update time buffer when we send a CR.
  2379.     CPI    CR        ; so it speeds things up.
  2380.     JNZ    NOTCHK
  2381.      ENDIF
  2382. ;
  2383.      IF    RTC AND (NOT TIMEON)
  2384.     CALL    TIME        ; Just update time buffer if no autologout
  2385.      ENDIF            ; RTC AND (NOT TIMEON)
  2386. ;
  2387.      IF    TIMEON AND RTC
  2388.     CALL    TCHECK        ; Update/check clock and timeon
  2389.      ENDIF            ; TIMEON AND RTC
  2390. ;
  2391. ; If we already know carrier is lost, do not check for it again or loop
  2392. ; trying to output.
  2393. ;
  2394. NOTCHK:    LDA    MDMOFF        ; Known loss of carrier?
  2395.     ORA    A
  2396.     PUSH    PSW
  2397.     CNZ    CONOUT        ; Output to local only
  2398.     POP    PSW
  2399.     RNZ            ; Then exit
  2400. ;
  2401. MOUTA:    CALL    CHECK        ; Carrier still on?
  2402.     CALL    MDOUTST        ; Check modem output status
  2403.     JZ    MOUTA
  2404.     MOV    A,C        ; Get character
  2405.     ANI    7FH        ; Strip parity bit
  2406. ;
  2407.     CPI    60H        ; Check for lower case
  2408.     JC    MOUTP2        ; Skip if not lower case
  2409.     CPI    7FH        ; Check for rubout
  2410.     JZ    MOUTP2
  2411.     PUSH    H
  2412.     LXI    H,ULCSW        ; Subtract either 20H or nothing
  2413.     SUB    M
  2414.     POP    H
  2415.     MOV    C,A        ; Force on local as well as remote
  2416. ;
  2417. MOUTP2:    CPI    LF        ; We have a toggle for line feeds
  2418.     JNZ    MOUTP3        ; Nope, not a LF
  2419.     LDA    LFEEDS        ; Yes, see if we can send it...
  2420.     ORA    A        ; Set flags
  2421.     MVI    A,0        ; Prepare with a null
  2422.     JNZ    MOUTP3        ; Nope, don't (instead, send a null)
  2423.     MVI    A,LF        ; Yes, it's ok to send the line feed
  2424. ;
  2425. MOUTP3:    CALL    MDOUTP        ; Output character to modem
  2426.     PUSH    PSW        ; Save character
  2427.     CPI    'G'-'@'        ; Is it a bell?
  2428.     JNZ    NOTBEL
  2429.     LDA    BELLON        ; Get flag
  2430.     ORA    A
  2431.     JZ    ISBELL
  2432. ;
  2433. NOTBEL:    CALL    CONOUT        ; Send to regular BIOS
  2434. ISBELL:    POP    PSW        ; Get character again
  2435. ;
  2436. ; Check for nulls
  2437. ;
  2438.     CPI    LF        ; Time for nulls?
  2439.     RNZ            ; No, return
  2440. ;
  2441. ; Send nulls if requested
  2442. ;
  2443.     LDA    NULLS        ; Get count
  2444.     ORA    A        ; Any?
  2445.     RZ            ; No
  2446.     PUSH    B
  2447.     MOV    B,A        ; Save count
  2448. ;
  2449. NULLP:    CALL    MDOUTST        ; Modem ready?
  2450.     JZ    NULLP
  2451.     XRA    A        ; 0 is a null
  2452.     CALL    MDOUTP        ; Type a null
  2453.     DCR    B        ; Another?
  2454.     JNZ    NULLP        ; Yes, loop
  2455.     POP    B
  2456.     RET
  2457. ;
  2458. ;-----------------------------------------------------------------------
  2459. ;
  2460. ; Move (HL) to (DE), length in (B)
  2461. ;
  2462. MOVE:    MOV    A,M        ; Get a byte
  2463.     STAX    D        ; Put at new home
  2464.     INX    D        ; Bump pointers
  2465.     INX    H
  2466.     DCR    B        ; Decrement byte count
  2467.     JNZ    MOVE        ; If more, do it
  2468.     RET            ; If not, return
  2469. ;
  2470. ;-----------------------------------------------------------------------
  2471. ;
  2472. ; Keyboard/modem status test routine
  2473. ;
  2474. MSTAT:    CALL    BDCHEK        ; Set 6 to safety
  2475.     CALL    CHECK        ; Check for carrier lost
  2476.     CALL    CONSTAT        ; Get local status
  2477.     ORA    A
  2478.     RNZ            ; Return if local character
  2479.     CALL    MDINST        ; Get modem input status
  2480.     RET
  2481. ;
  2482. ;-----------------------------------------------------------------------
  2483. ;
  2484. ; This is the jmp table which is copied on top of the one pointed to by
  2485. ; location 1 in CP/M.
  2486. ;
  2487. NEWJTBL:JMP    MCBOOT        ; Cold boot
  2488.     JMP    MBOOT        ; Warm boot
  2489.     JMP    MSTAT        ; Modem status test
  2490.     JMP    MINPUT        ; Modem input routine
  2491.     JMP    MOUTPUT        ; Modem output routine
  2492. ;
  2493.      IF    NOT (HARDLOG OR PRINTER)
  2494.     JMP    MOUTPUT        ; Modem = list device
  2495.      ENDIF            ; NOT (HARDLOG OR PRINTER)
  2496. ;
  2497.      IF    HARDLOG OR PRINTER
  2498.     JMP    LISTOUT        ; Jump to list output routine
  2499.      ENDIF            ; HARDLOG OR PRINTER
  2500. ;
  2501. ;-----------------------------------------------------------------------
  2502. ;
  2503. NWBCALL: IF    LOSER
  2504.     CALL    WMSTRT        ; Warm boot disk read
  2505.     CALL    PATCH        ; Fix BIOS again after WMSTRT
  2506.      ENDIF            ; LOSER
  2507. ;
  2508.     CALL    BDCHEK
  2509.     RET
  2510. ;
  2511. ;-----------------------------------------------------------------------
  2512. ;
  2513. ; Patch in the new JMP table (saving the old)
  2514. ;
  2515. PATCH:    LDA    PTFLAG
  2516.     ORA    A
  2517.     JNZ    SKPTH        ; Save the original jump table only once
  2518.     CALL    TBLADDR        ; HL= CP/M BIOS jump table
  2519.     LXI    D,VCOLDBT    ; Point to save location
  2520.     CALL    MOVE        ; Move it
  2521.     LHLD    VCONOUT+1    ; Get the original CONOUT address
  2522.     SHLD    COVECT        ; Store for use with XMODEM programs
  2523. ;
  2524. ; Now move the new JMP table to CP/M
  2525. ;
  2526. SKPTH:    CALL    TBLADDR        ; HL= CP/M BIOS jump table
  2527.     XCHG            ; Move it to 'DE'
  2528.     LXI    H,NEWJTBL    ; Point to new jump table
  2529.     CALL    MOVE        ; Move it
  2530.     MVI    A,255
  2531.     STA    PTFLAG
  2532. ;
  2533.      IF    LOSER
  2534.     LXI    H,NWBCALL    ; Set new warm boot call
  2535.     SHLD    WBCALL+1    ; Store the new address
  2536.      ENDIF            ; LOSER
  2537. ;
  2538.     RET
  2539. ;
  2540. ; Calculate HL=CP/M's jump table, B=length
  2541. ;
  2542. TBLADDR:LHLD    1        ; Get BIOS pointer
  2543.     DCX    H        ; Skip to cold boot
  2544.     DCX    H
  2545.     DCX    H
  2546.     MVI    B,18        ; Move all jumps
  2547.     RET
  2548. ;
  2549. ;-----------------------------------------------------------------------
  2550. ;
  2551. ; PRNLOG is called to print out the BYE version # and USRLOG info.  It
  2552. ; can be called from outside the program, using the vector after MCBOOT.
  2553. ;
  2554. PRNLOG:    LXI    H,VMSG
  2555.     CALL    PRINTL
  2556.     CALL    CALSUM
  2557.     RET
  2558. ;
  2559. CALSUM:    LDA    CWCAR        ; Get 8 bit number
  2560.     LXI    H,ATMSN        ; Address to store ascii
  2561.     CALL    DEC8        ; And convert to ascii
  2562.     CALL    MDCARCK        ; If carrier is on, wheel byte (sysop) calling
  2563.     LXI    H,ATMSG        ; Print Callers with carrier detected
  2564.     CNZ    PRINTB        ; To both if sysop is on other end
  2565.     CZ    PRINTL        ; Or just local if between calls
  2566. ;
  2567.      IF    B3IM        ; Print # of voice calls
  2568.     LDA    VCNUM
  2569.     LXI    H,VCMSN        ; Put ascii here
  2570.     CALL    DEC8
  2571.     CALL    MDCARCK
  2572.     LXI    H,VCMSG
  2573.     CNZ    PRINTB
  2574.     CZ    PRINTL
  2575.      ENDIF            ; B3IM
  2576. ;
  2577.      IF    PWRQD
  2578.     LDA    NWPWD        ; 8 bit counter
  2579.     LXI    H,NWMSD        ; Put ascii here
  2580.     CALL    DEC8
  2581.     CALL    MDCARCK
  2582.     LXI    H,NWMSG        ; Print callers who knew password
  2583.     CNZ    PRINTB
  2584.     CZ    PRINTL
  2585.      ENDIF            ; PWRQD
  2586. ;
  2587.     LXI    H,LFMSG
  2588.     CALL    PRINTL        ; Turn up a line
  2589.     RET            ; End of call summary
  2590. ;
  2591. ;-----------------------------------------------------------------------
  2592. ;
  2593. ; Readbyte routine - used to read the welcome file
  2594. ;
  2595.      IF    WELFILE
  2596. RDBYTE:    MOV    A,H        ; Time to read?
  2597.     ORA    A        ; If at 100H, no read required
  2598.     JZ    NORD
  2599. ;
  2600. ; Have to read a sector
  2601. ;
  2602.     LXI    D,FCB
  2603.     MVI    C,READ
  2604.     CALL    BDOS
  2605.     ORA    A        ; Ok?
  2606.     MVI    A,1AH        ; Fake up EOF
  2607.     RNZ            ; Return EOF if bad
  2608.     LXI    H,80H
  2609. ;
  2610. NORD:    MOV    A,M        ; Get character
  2611.     INX    H        ; Point to next byte
  2612.     RET
  2613.      ENDIF            ; WELFILE
  2614. ;
  2615. ;-----------------------------------------------------------------------
  2616. ;
  2617. ; TSTBAUD attempts to read a CR, LF or CTL-C and returns with zero flag
  2618. ; if the character read is one of these three.
  2619. ;
  2620.      IF    NOT B3IM
  2621. TSTBAUD:CALL    MDCARCK        ; Check carrier first
  2622.     JZ    BADPASS        ; Carrier is gone, start over
  2623.     LDA    CDOFF
  2624.     INR    A
  2625.     STA    CDOFF
  2626.     CPI    60        ; Allow 1 minute for c/r detect
  2627.     JZ    TMOUT        ; Log him off
  2628.     MVI    D,20        ; Check for 2 sec for current baud rate
  2629. ;
  2630. TSTB1:    MVI    B,1        ; At .1 sec intervals
  2631.     PUSH    D
  2632.     CALL    DELAY
  2633.     CALL    MDINST        ; See if character available
  2634.     ORA    A
  2635.     JZ    TSTB2        ; None yet
  2636.     CALL    MDINP        ; Yes, read the character
  2637.     ANI    7FH
  2638.     POP    D        ; Restore the stack
  2639.     JMP    TSTB3        ; And see if it is right character
  2640. ;
  2641. TSTB2:    POP    D        ; Restore DE
  2642.     DCR    D        ; And decrement the count
  2643.     MOV    A,D
  2644.     ORA    A        ; 2 sec's up??
  2645.     JNZ    TSTB1        ; No, try again
  2646.     MVI    A,0FFH        ; Dummy character
  2647. ;
  2648. TSTB3:    CPI    CR        ; If a CR
  2649.     RZ
  2650.     CPI    LF        ; If a LF
  2651.     RZ
  2652.     CPI    'C'-40H        ; If a CTL-C
  2653.     RET            ; Return with proper flags set
  2654.      ENDIF            ; NOT B3IM
  2655. ;
  2656. ;-----------------------------------------------------------------------
  2657. ;
  2658. ; Get the console status when unpatched
  2659. ;
  2660. UCSTS:    MVI    C,DRECTIO    ; Direct I/O call
  2661.     MVI    E,255        ; Ask for input
  2662.     CALL    BDOS        ; A=0 if no character waiting
  2663.     RET
  2664. ;
  2665. ;-----------------------------------------------------------------------
  2666. ;
  2667. UNPATCH:CALL    TBLADDR        ; HL= CP/M BIOS jump table
  2668.     XCHG            ; Move to DE
  2669.     LXI    H,VCOLDBT    ; Get saved table
  2670.     CALL    MOVE        ; Move original table back
  2671. ;
  2672.      IF    LOSER
  2673.     LXI    H,WMSTRT    ; Load old call location
  2674.     SHLD    WBCALL+1    ; Restore old call
  2675.      ENDIF            ; LOSER
  2676. ;
  2677.     RET
  2678. ;
  2679. ;-----------------------------------------------------------------------
  2680. ;
  2681. USRCHK:    CALL    PRNLOG        ; Give info
  2682.     LXI    H,RS1MSG
  2683.     CALL    PRINTL        ; Prompt to resume waiting for ring
  2684. ;
  2685. PRNREL:    CALL    UCSTS        ; Get reply
  2686.     ORA    A
  2687.     JZ    PRNREL        ; Wait until answered
  2688.     ANI    05FH        ; Make uppercase
  2689.     CPI    'E'        ; Execute com file?
  2690.     JZ    USRUN        ; Yes
  2691.     CPI    'R'        ; Is answer "r", for resume?
  2692.     JZ    PRNRES        ; Go do it if so
  2693.     JMP    EXCPM
  2694. ;
  2695. PRNRES:    LXI    H,RS2MSG
  2696.     JMP    PRINTL        ; Resume via BDOS after message
  2697. ;
  2698. USRUN:    MVI    A,'E'
  2699.     STA    FCB+1        ; Fake it
  2700.     JMP    START0        ; For sysop
  2701. ;
  2702. ;-----------------------------------------------------------------------
  2703. ;        WELCOME routine (note no extent used)
  2704. ;
  2705. ; Welcome to the system
  2706. ;
  2707. WELCOME:
  2708.      IF    ASKNULL AND NOT OXGATE
  2709.     LDA    NULTRY        ; How many times have we tried this?
  2710.     INR    A
  2711.     STA    NULTRY
  2712.     DCR    A
  2713.     CPI    MNULLS        ; Exceeded his limit?
  2714.     JZ    NULOFF        ; Yes, log the turkey off
  2715.     LXI    H,NULMSG    ; Nulls message
  2716.     CALL    PRINTB        ; Send this message
  2717.     CALL    MINPUT        ; Get value
  2718.     MOV    C,A        ; To 'C' for output
  2719.     CALL    MOUTPUT        ; Echo character
  2720.     MOV    A,C        ; Restore value
  2721.     CPI    '0'
  2722.     JC    WELCOME        ; Bad, retry
  2723.     CPI    '9'+1
  2724.     JNC    WELCOME        ; Bad, retry
  2725.     SUI    '0'        ; Make binary
  2726.     STA    NULLS        ; Save count
  2727.      ENDIF
  2728. ;
  2729. GETULC:    LXI    H,CRMSG        ; Carriage Return, Line Feed
  2730.     CALL    PRINTB        ; Send this message
  2731. ;
  2732.      IF    RTC AND RSPEED
  2733.     XRA    A        ; Clear status
  2734.     LDA    MSPEED        ; See what speed the user is at
  2735.     SUI    OKSPD        ; Is it acceptable?
  2736.     JNC    SPDOK        ; Yes, continue
  2737.     CALL    TIME        ; Get current time
  2738.     MVI    A,HOUR1        ; Start of prime-time
  2739. ;
  2740. SPD01:    LXI    H,CCHOUR    ; Point at current hour
  2741.     CMP    M        ; Equal?
  2742.     JZ    LOGOFF        ; Yes, dump him
  2743.     INR    A        ; Check for
  2744.     CPI    HOUR2        ; End of prime-time
  2745.     JZ    SPDOK        ; Not prime-time so let him on
  2746.     CPI    24        ; Past midnight?
  2747.     JNZ    SPD01        ; No, continue
  2748.     XRA    A        ; Yes set to 00 hour
  2749.     JMP    SPD01        ; And continue
  2750. ;
  2751. LOGOFF:    LXI    H,OFFMSG    ; Point at logoff message
  2752.     CALL    PRINTB        ; And tell him why
  2753.     CALL    DELAY        ; Let message finish
  2754.     CALL    DELAY        ; Before dumping him
  2755.     JMP    NOSLASH        ; Then dump him off
  2756. SPDOK:     ENDIF
  2757. ;
  2758.      IF    RTC
  2759.     CALL    TIME        ; Read current time
  2760.      ENDIF
  2761. ;
  2762.      IF    RTC AND TIMEON
  2763.     LDA    CCHOUR        ; And set
  2764.     STA    LHOUR        ; The users
  2765.     LDA    CCMIN        ; Login
  2766.     STA    LMIN        ; Time for later use
  2767.     MVI    A,MAXMIN    ; Set number of minutes
  2768.     STA    MXTIME        ; So we know it's ok to check time
  2769.      ENDIF
  2770. ;
  2771. ; Print the welcome file
  2772. ;
  2773.      IF    WELFILE
  2774.     LXI    H,WELFILN    ; Source
  2775.     LXI    D,FCB        ; Destination
  2776.     MVI    B,13        ; Length
  2777.     CALL    MOVE        ; Move the name
  2778.     LXI    D,80H        ; Set DMA address to 80H
  2779.     MVI    C,STDMA
  2780.     CALL    BDOS
  2781.     MVI    C,SETUSR    ; Set user number for WELCOME file
  2782.     MVI    E,WELUSR
  2783.     CALL    BDOS
  2784. ;
  2785. ; Open the WELCOME file
  2786. ;
  2787.     MVI    C,SELDSK    ; Select default drive for WELCOME file
  2788.     MVI    E,WELDRV-'A'
  2789.     CALL    BDOS
  2790.     LXI    D,FCB
  2791.     MVI    C,OPEN        ; Open file
  2792.     CALL    BDOS
  2793. ;
  2794. ; Did it exist?
  2795. ;
  2796.     INR    A        ; A=> 0 means "no"
  2797.     JZ    PASSINT        ; No WELCOME file
  2798. ;
  2799. ; Got a file, type it
  2800. ;
  2801.     XRA    A        ; A=0
  2802.     STA    FCBRNO        ; Zero record number
  2803.     LXI    H,100H        ; Get initial buffer pointer
  2804. ;
  2805. ;
  2806. ; Type the WELCOME file
  2807. ;
  2808. WELTYPE:CALL    RDBYTE        ; Get a byte
  2809.     CPI    'Z'-'@'        ; EOF?
  2810.     JZ    PASSINT        ; Yes, done
  2811.     MOV    C,A        ; Setup for type
  2812.     CALL    MOUTPUT        ; Type the character
  2813.     CALL    MSTAT        ; Check for character typed
  2814.     ORA    A
  2815.     JZ    WELTYPE        ; No, loop
  2816.     CALL    MINPUT        ; Yes, get character
  2817.     ANI    01FH        ; Make it a control character
  2818.     CPI    'C'-'@'        ; Did user type a CTL-C to end listing?
  2819.     JZ    PASSINT
  2820.     CPI    'K'-'@'        ; CTL-K to end listing?
  2821.     JZ    PASSINT
  2822.     CPI    'S'-'@'        ; CTL-S to delay listing?
  2823.     JNZ    WELTYPE        ; No, loop until EOF
  2824. ;
  2825. WAIT:    CALL    MSTAT
  2826.     ORA    A        ; Has another char been typed?
  2827.     JZ    WAIT        ; No, wait
  2828.     CALL    MINPUT        ; Yes, check character
  2829.     ANI    01FH        ; Make it a control character
  2830.     CPI    'C'-'@'        ; Did user type a CTL-C to end listing?
  2831.     JZ    PASSINT
  2832.     CPI    'K'-'@'        ; CTL-K to end listing?
  2833.     JNZ    WELTYPE        ; None of these, loop until EOF
  2834.      ENDIF            ; WELFILE
  2835. ;
  2836. ; Get the password
  2837. ;
  2838. PASSINT: IF    PWRQD
  2839.     MVI    D,3        ; 3 tries at password
  2840. PASSINP:LXI    H,PWMSG        ; Password message
  2841.     CALL    PRINTB        ; Send this message
  2842.     LXI    H,PASSWD    ; Point to password
  2843.     MVI    E,0        ; No missed letters
  2844. ;
  2845. PWMLP:    CALL    MINPUT        ; Get a character
  2846.     CPI    60H        ; Lower case?
  2847.     JC    NOTLC        ; No,
  2848.     ANI    5FH        ; Make upper case alpha
  2849. ;
  2850. NOTLC:    PUSH    PSW        ; Save character input
  2851.     CPI    20H        ; Is character a control code?
  2852.     JNC    PWDIS        ; Pass if displayable
  2853.     MVI    C,'^'        ; If control map to up arrow then display
  2854.     CALL    CONOUT
  2855.     POP    PSW
  2856.     PUSH    PSW
  2857.     ADI    40H
  2858. ;
  2859. PWDIS:    MOV    C,A
  2860.     CALL    CONOUT        ; Output character locally
  2861.     POP    PSW        ; Restore 'A' reg.
  2862.     CPI    'U'-40H        ; CTL-U?
  2863.     JZ    PASSINP        ; Yes, abort, and retry
  2864.     CMP    M        ; Match password?
  2865.     JZ    PWMAT
  2866.     MVI    E,1        ; No, show miss
  2867.     CPI    CR        ; CR?
  2868.     JNZ    PWMLP        ; No, wait for CR
  2869. ;
  2870. ; Password did not match
  2871. ;
  2872. PWNMAT:    LXI    H,WRGMSG    ; Wrong password message
  2873.     CALL    PRINTB        ; Send this message
  2874.     DCR    D        ; More tries?
  2875.     JNZ    PASSINP        ; Yes
  2876.     JMP    NOSLASH        ; No, go hang up
  2877. ;
  2878. ; Character matched in password
  2879. ;
  2880. PWMAT:    INX    H        ; To next character
  2881.     CPI    CR        ; End?
  2882.     JNZ    PWMLP        ; No, loop
  2883. ;
  2884. ; End of password, any missed characters?
  2885. ;
  2886.     MOV    A,E        ; Get flag
  2887.     ORA    A
  2888.     JNZ    PWNMAT        ; Not right
  2889. ;
  2890.     LXI    H,NWPWD        ; Get last value
  2891.     INR    M        ; And add one
  2892.      ENDIF            ; PWRQD
  2893. ;
  2894.      IF    COMFILE
  2895.     MVI    C,SELDSK    ; Switch to .COM file drive
  2896.     MVI    E,COMDRV-'A'
  2897.     CALL    BDOS
  2898.     MVI    C,SETUSR
  2899.     MVI    E,COMUSR    ; Switch to .COM file user area
  2900.     CALL    BDOS
  2901.     MVI    A,' '        ; Fool the system so that the .COM file
  2902.     STA    FCB+1        ; Will see a space at FCB+1 for default
  2903.     JMP    RUNCOM        ; Execute the COM file
  2904.      ENDIF
  2905. ;
  2906. ; Everyone else gets .COM file
  2907. ;
  2908. RUNCOM:     IF    ZCPR3 AND COMFILE
  2909.     CALL    DOZ3        ; ZCPR3 re-initialization
  2910.      ENDIF            ; ZCPR3 and COMFILE
  2911. ;
  2912.      IF    COMFILE
  2913.     LDA    OPTION
  2914.     CPI    'E'        ; Executing locally?
  2915.     CNZ    100H        ; No, skip this
  2916.     CALL    PATCH        ; So we run under bye
  2917.     CALL    100H        ; Execute com file
  2918.      ENDIF            ; COMFILE
  2919. ;
  2920.     JMP    0000H        ; Warm boot now for "normal" CP/M use
  2921. ;
  2922. NULOFF:    LXI    H,NOMSG        ; Tell the turkey he failed
  2923.     CALL    PRINTB
  2924.     JMP    NOSLASH        ; And log him off
  2925. ;
  2926. ;              end of WELCOME routine
  2927. ;-----------------------------------------------------------------------
  2928. ;           calculate user's elapsed time
  2929. ;
  2930. ; Calculate time on system.  Log him off if =>MAXMIN unless WHEEL is on,
  2931. ; or MXTIME=0.
  2932. ;
  2933.      IF    RTC AND TIMEON
  2934. TCHECK:    PUSH    B
  2935.     PUSH    D
  2936.     PUSH    H
  2937.     CALL    TIME        ; Get current time
  2938.     LDA    LHOUR        ; (LHOUR)=log-in hour 0-23
  2939.     CALL    TCX60        ; Convert to minutes, results in (HL)
  2940.     LDA    LMIN        ; (LMIN)=log-in minutes, 0-59
  2941.     LXI    D,0        ; Clear (DE)
  2942.     MOV    E,A        ; (LMIN) to (DE)
  2943.     DAD    D        ; (HL)+(DE)=(HL)
  2944.     PUSH    H        ; Save log-in minutes on stack
  2945.     LDA    CCHOUR        ; (CCHOUR)=current hour, 0-23
  2946.     LXI    H,LHOUR        ; Let's see if we crossed midnight
  2947.     SUB    M
  2948.     JNC    TCOK        ; No, we're ok
  2949.     LDA    CCHOUR        ; Yes, let's add 24
  2950.     ADI    24
  2951.     STA    CCHOUR        ; Now we're ok
  2952. TCOK:    LDA    CCHOUR        ; (CCHOUR) is now bigger than (LHOUR)
  2953.     CALL    TCX60        ; Convert it to minutes
  2954.     LDA    CCMIN        ; Current minutes, 0-59
  2955.     LXI    D,0        ; Clear (DE)
  2956.     MOV    E,A        ; CCMIN to (DE)
  2957.     DAD    D        ; (HL) now has current time in minutes
  2958.     POP    D        ; (DE) now has log-in time
  2959.     CALL    TCDIF        ; Get the difference, (HL)-(DE)=(HL)
  2960.     MVI    A,' '        ; Clear out time buffer
  2961.     STA    TONMSD
  2962.     STA    TONMSD+1
  2963.     STA    TONMSD+2
  2964.     MOV    A,L        ; Only save LSB, 0-255 is plenty
  2965.     STA    TON        ; And save it
  2966. ;
  2967.     LXI    H,TONMSD    ; (A)=TON, (HL)=address to store ascii
  2968.     CALL    DEC8        ; Convert timeon to ascii
  2969.     POP    H
  2970.     POP    D
  2971.     POP    B
  2972.     LDA    WHEEL
  2973.     ORA    A        ; Maybe he typed his password for user
  2974.     RNZ
  2975.     LDA    MXTIME        ; Get maximum time allowed
  2976.     ORA    A        ; If zero, MBBS says it's ok
  2977.     RZ            ; For unlimited time on
  2978.     PUSH    B
  2979.     MOV    B,A        ; Move it to 'B'
  2980.     LDA    TON
  2981.     SUB    B        ; Subtract max time allowed
  2982.     POP    B
  2983.     RC            ; Still time left
  2984.     XRA    A
  2985.     STA    MXTIME        ; Reset time flag
  2986.     LXI    H,TIMEUP    ; Time is up, inform user
  2987.     CALL    PRINTB
  2988.     CALL    DELAY        ; Wait for msg to finish
  2989.     CALL    DELAY
  2990.     JMP    NOSLASH        ; And log him off
  2991. ;
  2992. ; TCX60 will multiply (A)x60, results in (HL).
  2993. ;
  2994. TCX60:    LXI    H,0        ; (HL)=0
  2995.     ORA    A
  2996.     RZ            ; If (A)=0, no x60 needed
  2997.     LXI    D,60        ; Multiplier
  2998. TCX61:    DAD    D        ; X60
  2999.     DCR    A        ; Done?
  3000.     JNZ    TCX61        ; No
  3001.     RET
  3002. ;
  3003. ; TCDIF will subtract (DE) from (HL), results in (HL).
  3004. ; (HL) normally has the larger number
  3005. ;
  3006. TCDIF:    MOV    A,L        ; LSB of (HL)
  3007.     SUB    E        ; LSB of (DE)
  3008.     MOV    L,A        ; Back to L
  3009.     MOV    A,H        ; MSB of (HL)
  3010.     SBB    D        ; MSB of (DE) and carry flag
  3011.     MOV    H,A        ; (HL) now has difference
  3012.     RET
  3013.      ENDIF            ; RTC AND TIMEON
  3014. ;
  3015. ;    BCDBIN - convert BCD number to binary number
  3016. ;    Entry:   A = BCD number
  3017. ;    Exit:    A = binary number
  3018. ;    Destroys: nothing
  3019. ;
  3020.      IF    RTC AND BCD2BIN
  3021. BCDBIN:    PUSH    D
  3022.     MOV    E,A        ; Save original byte
  3023.     ANI    15
  3024.     MOV    D,A        ; Save low nibble
  3025.     MOV    A,E
  3026.     ANI    240        ; Mask LSN
  3027.     RRC            ; x2
  3028.     MOV    E,A
  3029.     RRC            ; x4
  3030.     RRC            ; x8
  3031.     ADD    E        ; x10
  3032.     ADD    D        ; low nibble
  3033.     POP    D
  3034.     RET
  3035.      ENDIF
  3036. ;
  3037. ;    BINBCD - convert binary number to BCD
  3038. ;    Entry:     A = binary number
  3039. ;    Exit:     A = BCD number
  3040. ;    Destroys: nothing
  3041. ;
  3042.      IF    RTC AND BIN2BCD
  3043. BINBCD:    PUSH    D
  3044.     MVI    E,255        ; -1
  3045. BLP:    INR    E        ; Increment tens counter
  3046.     SUI    10        ; Subtract 10 each pass
  3047.     JNC    BLP
  3048.     ADI    10        ; Get back number
  3049.     MOV    D,A
  3050.     MOV    A,E
  3051.     RLC            ; Shift over to MSN
  3052.     RLC
  3053.     RLC
  3054.     RLC
  3055.     ADD    D        ; Add in ones position
  3056.     POP    D
  3057.     RET
  3058.      ENDIF
  3059. ;
  3060. ;-----------------------------------------------------------------------
  3061. ;
  3062. ; DEC8 will convert an 8 bit binary number in A to 3 ASCII bytes.
  3063. ; HL points to the MSB location where the ASCII bytes will be stored.
  3064. ; Leading zeros are suppressed, so store spaces in your buffer before calling.
  3065. ;
  3066. DEC8:    PUSH    B
  3067.     PUSH    D
  3068.     MVI    E,0        ; Leading zero flag
  3069.     MVI    D,100
  3070. DEC81:    MVI    C,'0'-1
  3071. DEC82:    INR    C
  3072.     SUB    D        ; 100 or 10
  3073.     JNC    DEC82        ; Still +
  3074.     ADD    D        ; Now add it back
  3075.     MOV    B,A        ; Remainder
  3076.     MOV    A,C        ; Get 100/10
  3077.     CPI    '1'        ; Zero?
  3078.     JNC    DEC84        ; Yes
  3079.     MOV    A,E        ; Check flag
  3080.     ORA    A        ; Reset?
  3081.     MOV    A,C        ; Restore byte
  3082.     JZ    DEC85        ; Leading zeros are skipped
  3083. DEC84:    MOV    M,A        ; Store it in buffer pointed at by HL
  3084.     INX    H        ; Increment storage location
  3085.     MVI    E,0FFH        ; Set zero flag
  3086. DEC85:    MOV    A,D
  3087.     SUI    90        ; 100 to 10
  3088.     MOV    D,A
  3089.     MOV    A,B        ; Remainder
  3090.     JNC    DEC81        ; Do it again
  3091.     ADI    '0'        ; Make ascii
  3092.     MOV    M,A        ; And store it
  3093.     POP    D
  3094.     POP    B
  3095.     RET
  3096. ;
  3097. ENDOBJ    EQU    $
  3098. ;           end of main body of program
  3099. ;-----------------------------------------------------------------------
  3100. ;
  3101. ;  ------------------------------------------------
  3102. ;  START B3IM COMMANDS    (Set B3IM EQU YES to use this)
  3103. ;  ------------------------------------------------
  3104. ;
  3105.      IF    B3IM
  3106. B3ATA:    DB    'ATA',CR,0    ; Answer the phone
  3107. B3ATZ:    DB    'ATZ',CR,0    ; Reset modem
  3108. B3ESC:    DB    '+++',0        ; Escape sequence for command mode
  3109. B3ATH:    DB    'ATH',CR,0    ; Hangup phone
  3110. ;
  3111. ADDSTR:    DW    0        ; Address of command string
  3112. VCMSG:    DB    CR,LF,'Voice or no carrier calls: '
  3113. VCMSN:    DB    '   ',0
  3114. VCNUM:    DB    0        ; Counter for voice calls
  3115.      ENDIF            ; B3IM
  3116. ;
  3117.      IF    B3IM AND PRGRSS
  3118. RCSHOW:    DB    '_',0        ; Will be stored by PRGRSS
  3119. NOEMSG:    DB    CR,LF,'Echo error--will try again...',CR,LF,0
  3120. CMDERR:    DB    '--ERROR--your modem cannot execute the above command string-'
  3121.     DB    '--Find out why..',CR,LF,0
  3122.      ENDIF            ; B3IM AND PRGRSS
  3123. ;
  3124.      IF    B3IM AND PRGRSS AND CALBAK
  3125. CALMSG1:DB    'Now checking for voice or computer call...',0
  3126. CALMSG2:DB    'Waiting for call-back...',CR,LF,0
  3127. CALMSG3:DB    CR,LF,'Timing out from voice call...',CR,LF,0
  3128.      ENDIF
  3129. ;
  3130.      IF    B3IM
  3131. B3INIT:    DB    'AT'        ; Attention
  3132.      ENDIF
  3133. ;
  3134.      IF    B3IM AND ECHO
  3135.     DB    'E1'        ; Echo back characters sent to modem
  3136.      ENDIF
  3137. ;
  3138.      IF    B3IM AND (NOT ECHO)
  3139.     DB    'E0'        ; Only Hayes needs echo verification
  3140.      ENDIF
  3141. ;
  3142.      IF    B3IM
  3143.     DB    'Q0'        ; Send result codes
  3144.     DB    'V0'        ; Terse mode
  3145.      ENDIF
  3146. ;
  3147.      IF    B3IM AND (NOT NOATA)
  3148.     DB    'S0=0'        ; No auto-answer (we will use 'ATA')
  3149.      ENDIF
  3150. ;
  3151.      IF    B3IM AND NOATA
  3152.     DB    'S0=1'        ; Will answer on first ring
  3153.      ENDIF
  3154. ;
  3155.      IF    B3IM AND (NOT ANCHOR) OR (NOT NODTR)
  3156.     DB    'S2=128'    ; Non-printing ASCII vs "+++"
  3157.      ENDIF
  3158. ;
  3159.      IF    B3IM AND (NOT ANCHOR)
  3160.     DB    'M0'        ; Speaker off
  3161.     DB    'S10=25'    ; 2 1/2 sec wait after carrier loss to hang up
  3162.      ENDIF
  3163. ;
  3164.      IF    B3IM AND (NOT HS300) AND (NOT ANCHOR)
  3165.     DB    'X1'        ; Extended response codes beyond '4'
  3166.      ENDIF
  3167. ;
  3168.      IF    B3IM
  3169.     DB    CR,0        ; CR finishes command string
  3170. B3USR:    DB    'ATS0=0',CR,0    ; This helps the Password and S-100
  3171.      ENDIF
  3172. ;
  3173. ;    End of B3IM command strings
  3174. ;    ---------------------------
  3175. ;
  3176. ;                messages
  3177. ;
  3178.      IF    PRGRSS AND (NOT    B3IM)
  3179. MSG30:    DB    '300 baud test',CR,LF,0
  3180. MSG12:    DB    '1200 baud test',CR,LF,0
  3181. MSG24:    DB    '2400 baud test',CR,LF,0
  3182.      ENDIF
  3183. ;
  3184. ;
  3185. ; Program version number message
  3186. ;
  3187. VMSG:    DB    CR,LF,'BYE',MAIN+'0'
  3188.     DB    VERS/10+'0',VERS MOD 10+'0',' - '
  3189.     DB    MONTH/10+'0',MONTH MOD 10+'0','/'
  3190.     DB    DAY/10+'0',DAY MOD 10+'0','/'
  3191.     DB    YEAR/10+'0',YEAR MOD 10+'0',CR,LF,0
  3192. ;
  3193. CLRSEQ:    DB    CLRCH1,CLRCH2,CLRCH3,CLRCH4,CLRCH5,CLRCH6,0
  3194. ;
  3195. CDOFF:    DB    0
  3196. OPTION:    DB    0
  3197. ;
  3198.      IF    RTC AND RSPEED
  3199. OFFMSG:    DB    CR,LF,'Sorry!   1200 or 2400 baud only allowed 7PM-11PM'
  3200.     DB    CR,LF,CR,LF,' Call back before/after 7-11PM Pacific'
  3201.     DB    CR,LF,0
  3202.      ENDIF
  3203. ;
  3204.      IF    RTC AND TIMEON
  3205. TIMEUP:    DB    7,7,CR,LF,CR,LF
  3206.     DB    ' Your time is up - wait 24 hours to call back',CR,LF,0
  3207. TONMSG:    DB    CR,LF,'Time on system is '
  3208. TONMSD:    DB    '   minutes',CR,LF,0
  3209.      ENDIF
  3210. ;
  3211. ; Real-Time clock buffer.
  3212. ; Store BCD values into this area if RTC is YES.
  3213. ;
  3214. ; (NOTE: 99:99:99 INDICATES CLOCK IS NOT RUNNING OR NOT AVAILABLE)
  3215. ;
  3216. RTCBUF:    DB    99H,99H,99H    ; HH:MM:SS (BCD 24hr time) 00:00:00-23:59:59
  3217.     DB    19H,85H,02H,31H    ; YYYY/MM/DD (BCD ISO date)
  3218. TON:    DB    0        ; Time on system
  3219.     DB    0        ; Reserved for use with MBBS only
  3220. CCHOUR:    DB    0        ; Current hour (binary)
  3221. CCMIN:    DB    0        ; Current minute (binary)
  3222. LHOUR:    DB    0        ; Login hour
  3223. LMIN:    DB    0        ; Login minute
  3224. ;
  3225. ;    Other Messages
  3226. ;
  3227.      IF    ASKNULL AND NOT OXGATE
  3228. NULMSG:    DB    CR,LF,CR,CR,CR,CR,'Nulls, if needed, (0-9)? ',0
  3229.      ENDIF
  3230. ;
  3231. CRMSG:    DB    CR,LF,CR,LF,0
  3232. NULTRY:    DB    0
  3233. NOMSG:    DB    CR,LF,LF,'You have flunked the 0-9 IQ test...',CR,LF,LF
  3234.     DB    0
  3235. PTFLAG:    DB    0
  3236. ;
  3237.      IF    PRNTGB
  3238. GBMSG:    DB    CR,LF,CR,CR,'Goodbye, call again...',CR,LF,CR,LF,0
  3239.      ENDIF
  3240. ;
  3241. RS1MSG:     IF    COMFILE
  3242.     DB    CR,LF,'Type "E" to execute COM file locally,'
  3243.      ENDIF
  3244. ;
  3245.     DB    CR,LF,'Type "R" to resume, anything else to warm boot: '
  3246.     DB    0
  3247. ;
  3248. RS2MSG:    DB    '  Resuming...',CR,LF,0
  3249. ;
  3250. ATMSG:    DB    CR,LF,'Total calls with carrier:  '
  3251. ATMSN:    DB    '   ',0
  3252. CWCAR:    DB    0        ; Counter for carrier detected calls
  3253. ;
  3254. ; Access password (ends in carriage return) - keep password here
  3255. ;
  3256.      IF    PWRQD
  3257. PASSWD:    DB    'DDT'        ; The password itself
  3258.     DB    CR        ; End of password, CR-only to erase it
  3259. ;
  3260. ;
  3261. ; (Allow room for larger password to be entered, up to 10 characters)
  3262. ;
  3263.     DB    0,0,0,0,0,0,0
  3264. ;
  3265. PWMSG:    DB    CR,LF,'Enter Password: ',0
  3266. WRGMSG:    DB    'Incorrect password',CR,LF,0
  3267. NWMSG:    DB    CR,LF,'Callers with correct password: '
  3268. NWMSD:    DB    '   ',0
  3269. NWPWD:    DB    0        ; Counter for correct password callers
  3270.      ENDIF
  3271. ;
  3272.      IF    COMFILE
  3273. LSMSG:    DB    'Loading system...',CR,LF,0
  3274.      ENDIF
  3275. ;
  3276. IDMSG:    DB    '> [Invalid drive, returning to A:]',0
  3277. IUMSG:    DB    '> [Invalid user number, returning to 0]',0
  3278. CLMSG:    DB    CR,LF,'[Carrier lost]',CR,LF,0
  3279. ITOMSG:    DB    '[Input timed out]',7,0
  3280. SCRMON:    DB    '[Remote screen enabled]',CR,LF,0
  3281. SCRMOFF:DB    '[Remote screen disabled]',CR,LF,0
  3282. BELMON:    DB    '[Console bell enabled]',CR,LF,0
  3283. BELMOFF:DB    '[Console bell disabled]',CR,LF,0
  3284. MFSMSG:    DB    'Message from Sysop: ',0
  3285. SGDMSG:    DB    'System is going down, you have ',DOWNMIN+'0'
  3286.     DB    ' minute(s) to logout.',0
  3287. ;
  3288.      IF    TIMEON AND RTC
  3289. UTIMEM:    DB    '[Unlimited time on system granted]',CR,LF,0
  3290.      ENDIF
  3291. ;
  3292. LFMSG:    DB    CR,LF,0
  3293. ;
  3294.      IF    PRNTWB
  3295. WBMSG:    DB    CR,LF,'Booting CP/M...',CR,LF
  3296.     DB    0
  3297.      ENDIF
  3298. ;
  3299.      IF    COMFILE    OR EXFILE
  3300. PTSMSG:    DB    '++ Program area too small ++',0
  3301. CNFMSG:    DB    CR,LF,'++ Cannot find .COM file ++',0
  3302. CFLMSG:    DB    CR,LF,'[.COM file loaded]',CR,LF,0
  3303.      ENDIF
  3304. ;
  3305.      IF    WELFILE
  3306. WELFILN:DB    0,'WELCOME ???'    ; WELCOME file name, must be 11 chars.
  3307.     DB    0        ; WELCOME or WELCOME.TXT will work
  3308.      ENDIF
  3309. ;
  3310. COMFCB:
  3311.      IF    COMFILE    AND (NOT OXGATE) AND (NOT METAL) AND (NOT MBBS)
  3312.     DB    0,'RBBS    COM'    ; COM file name, must be 11 characters
  3313.     DS    21        ; Rest of .COM FCB
  3314.      ENDIF
  3315. ;
  3316.      IF    COMFILE    AND OXGATE
  3317.     DB    0,'OXENTR  COM'    ; OxGate entry module
  3318.     DS    21        ; Rest of FCB
  3319.      ENDIF
  3320. ;
  3321.      IF    COMFILE    AND METAL
  3322.     DB    0,'MENTR   COM'    ; Metal entry file
  3323.     DS    21        ; Rest of FCB
  3324.      ENDIF
  3325. ;
  3326.      IF    COMFILE    AND MBBS
  3327.     DB    0,'MBBS    COM'    ; Mbbs entry file
  3328.     DS    21        ; Rest of FCB
  3329.      ENDIF
  3330. ;
  3331. EXITFCB:
  3332.      IF    EXFILE AND (NOT    OXGATE)    AND (NOT METAL)
  3333.     DB    0,'        COM'    ; Exit filename, must be 11 characters
  3334.     DS    21        ; Rest of exit FCB
  3335.      ENDIF
  3336. ;
  3337.      IF    EXFILE AND OXGATE
  3338.     DB    0,'OXEXIT  COM'    ; Exit filename, must be 11 characters
  3339.     DS    21        ; Rest of exit FCB
  3340.      ENDIF
  3341. ;
  3342.      IF    EXFILE AND METAL
  3343.     DB    0,'MEXIT   COM'    ; Exit filename, must be 11 characters
  3344.     DS    21        ; Rest of exit FCB
  3345.      ENDIF
  3346. ;
  3347. LCNAME:     IF    NO25TH OR MBBS
  3348.     DB    0,'LASTCALR???'    ; LASTCALR OR LASTCALR.DAT will be used
  3349.     DB    0
  3350.      ENDIF
  3351. ;
  3352.      IF    NO25TH OR MBBS
  3353. LCDATA:    DB    ' ',0
  3354.     DS    78
  3355. LCFILL:    DB    '  Last caller data has not been loaded, wait for first W/B'
  3356.     DB    ' to CP/M',0,0,0,0,0,0,0
  3357. LCMSG1:    DB    '*** ERROR *** No last-caller data found',CR,LF,0
  3358.      ENDIF
  3359. ;
  3360.      IF    NOT (NO25TH OR MBBS)
  3361. LCDATA:    DB    0        ; If BBS sees a null here, it won't overwrite
  3362.                 ; a non-existant buffer.
  3363.      ENDIF
  3364. ;
  3365.      IF    MBBS
  3366. MBBS1:    DB    CR,LF,'Loading MBBS for logoff...please wait...',CR,LF,LF,0
  3367. MBBS2:    DB    CR,LF,'[Logging off user]',CR,LF,0
  3368.      ENDIF
  3369. ;
  3370. ;-----------------------------------------------------------------------
  3371. ;              ZCPR external paths
  3372. ;
  3373. ; ZCPR's external paths available.  (ZCPR will always do the current
  3374. ; drive/current user area)
  3375. ;
  3376. ; Command path available for SYSOP
  3377. ;
  3378.      IF    CHGPATH
  3379. SYSPATH:DB    1,0        ; A0:
  3380.     DB    1,15        ; A15:
  3381.     DB    0        ; End of path
  3382. LSYSP    EQU    $-SYSPATH
  3383. ;
  3384. ; Command path available for remote user
  3385. ;
  3386. REMPATH:DB    1,0        ; A0:
  3387.     DB    0        ; End of path
  3388. LREMP    EQU    $-REMPATH
  3389.      ENDIF
  3390. ;
  3391. ;            end of ZCPR external paths
  3392. ;-----------------------------------------------------------------------
  3393. ;
  3394. ; These areas are not initialized
  3395. ;
  3396. PEND    EQU    $        ; The following area is not initialized
  3397. ;
  3398.      IF    COMFILE    OR EXFILE
  3399. CURRFCB:DS    2
  3400.      ENDIF
  3401. ;
  3402. TOCNTM:    DS    1
  3403. TOCNT:    DS    2
  3404. FKATTN:    DS    1
  3405. ;
  3406. ; Save the CP/M jump table here
  3407. ;
  3408. VCOLDBT:  DS    3
  3409. VWARMBT:  DS    3
  3410. VCONSTAT: DS    3
  3411. VCONIN:      DS    3
  3412. VCONOUT:  DS    3
  3413. VLISTOUT: DS    3
  3414. ;
  3415. ;----------------------------------------------------------------
  3416. ;
  3417. ; ASCII Equates
  3418. ;
  3419. CR    EQU    0DH        ; ASCII carriage return
  3420. LF    EQU    0AH        ; ASCII line feed
  3421. ;
  3422. LXID    EQU    11H        ; Define byte of LIX D,nnnn to fake loader
  3423. LXIH    EQU    21H        ; Define byte of LXI H,nnnn to fake loader
  3424. IOBYTE    EQU    0003H        ; Location of CP/M IOBYTE
  3425. FCB    EQU    005CH
  3426. FCBRNO    EQU    FCB+32
  3427. ;
  3428. ; BDOS equates
  3429. ;
  3430. BDOS    EQU    0005H
  3431. CI    EQU    1
  3432. WRCON    EQU    2
  3433. DRECTIO    EQU    6
  3434. PRINTF    EQU    9
  3435. CSTS    EQU    11
  3436. SELDSK    EQU    14
  3437. OPEN    EQU    15
  3438. READ    EQU    20
  3439. STDMA    EQU    26
  3440. SETUSR    EQU    32
  3441. ;
  3442.     DS    40
  3443. STACK    EQU    $        ; Local stack
  3444. OBJEND    EQU    $
  3445. ;
  3446.     END
  3447.