home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol065 / bye78.asm < prev    next >
Assembly Source File  |  1984-04-29  |  71KB  |  2,979 lines

  1. ;    TITLE    'BYE V7.8 AS OF 02/20/82'
  2. ;    PAGE    44
  3. ;
  4. ;        BYE V7.8 (revised 02/20/82)
  5. ;    REMOTE CONSOLE PROGRAM FOR CP/M AND MODEM
  6. ;
  7. ;This program allows modem callers to use your CP/M system
  8. ;just as if they were seated at the system console.  Special
  9. ;assembly-time options allow limiting the caller's access by
  10. ;password and/or access to only a message-service program.
  11. ;
  12. ;Based on an original program written by Dave Jaffe, January 1979
  13. ;Rewritten for PMMI modem by Ward Christensen, February 1979.
  14. ;This program now supports DC Hayes, PMMI, and external modems.
  15. ;The UARTS supported are the Intel 8251 and the Western Digital 8250.
  16. ;Be sure to set the equates for the modem you are using. 
  17. ;
  18. ;*************************************************************************
  19. ;DANGER: Pay close attention to the polarity of the jump instructions    *
  20. ;after any in from a uart when running under 8250/8251's,  I have tried  *
  21. ;to fix them for the most common logical setup, but your system may      *
  22. ;differ.                                 *
  23. ;*************************************************************************
  24. ;
  25. ;Thanks to Bill Precht for the "label + offset" idea allowing
  26. ;this program to relocate itself without using DDT to initially
  27. ;set it up.
  28. ;
  29. ;Modifications/fixes: (in reverse order to minimize reading time)
  30. ;
  31. ;02/03/82 Fixed the buggy conditional jumps in/after RINGWT.
  32. ;      Now there is conditional assembly depending on if you are
  33. ;      a WD8250/IN8251 or a "standard" system.
  34. ;      Fixed a few bugs in conditional assembly.
  35. ;      Improved LF code.
  36. ;                          -- Paul S Traina
  37. ;
  38. ;01/20/82 Add equates and routines for HEATH or IMS systems and any
  39. ;      other systems using External modems and the WD8250 UART.
  40. ;      Included assembly option for compatability with RBBS,
  41. ;      MINICBBS, and OXGATE implimentations. by Thom Quick
  42. ;
  43. ;01/09/82 Added WRTLOC flag for use with an RBBS program that sets
  44. ;      this flag during disk writes; avoids files out of synch
  45. ;      problem if caller hangs up during writes. Added MINICK
  46. ;      routines which do the same with MINICBBS. Added patch
  47. ;      to allow bye to run below the CCP with programs such as
  48. ;      TYPESQ. Separated Superb conditional assembly into Externl
  49. ;      and LOSER, this separates external modem operation from a
  50. ;      losing feature of a particular BIOS. (P. L. Kelley)
  51. ;        
  52. ;12/03/81 Implemented OxGate protocol,  fixed some bugs in conditional
  53. ;        equates.  Variables for UCLSW and NULLS moved up so that
  54. ;        programs can poke them too.    (Paul Traina)
  55. ;
  56. ;12/02/81 Make variables for MAXDRV, MAXUSR, and TOVALUE that
  57. ;         can be found via the warm boot BIOS vector at zero,
  58. ;      so that these values can be changed while BYE is
  59. ;      running to accomodate privileged users, either through
  60. ;      action of the BYE-run .COM file or some other password
  61. ;      program run later. Move MCBOOT and the USRLOG vector
  62. ;      to just after the START vector, for easier access
  63. ;      if desired.
  64. ;
  65. ;11/04/81 Print out BYE version number in PRNLOG, to allow
  66. ;      program to be identified easily when running. Call
  67. ;      USRCHK in all cases to print out version number on
  68. ;      local ctrl-C, then ask to resume BYE instead of
  69. ;      warm boot. Convert many msgs to upper/lower case.
  70. ;                    By Steve Bogolub
  71. ;
  72. ;10/24/81 Modified NOPASS so that COM files that look for
  73. ;      a second file on the command line (such as HELP18)
  74. ;      will find a 20H at FCB+1 for default purposes.  Also
  75. ;      added RUNCOM at the end of NOPASS and changed the
  76. ;      jumps to the TPA (100h) to a CALL so that a COM file
  77. ;      will return to BYE where a clean jump to warm boot
  78. ;      can be done instead of going off to never-never land.
  79. ;                    R. L. Plouffe
  80. ;
  81. ;10/11/81 Print password on local console with DUAL$IO. Allow
  82. ;      return from PRNLOG with USRLOG. Make <CR><LF> instead
  83. ;      of <LF><CR> in USRLOG reports. Print out BYE version
  84. ;      number for easy identification. Position PRNLOG after
  85. ;      cold boot routine, and change cold boot routine to
  86. ;      jump to MBOOT, thereby defining path to PRNLOG for
  87. ;      all BYE programs and allowing one trivial program
  88. ;      that can be run to get the BYE log. Make counters
  89. ;      16 bits for greater range. By Steve Bogolub
  90. ;
  91. ;10/01/81 Added CALL CHECK to MSTAT routine to eliminate
  92. ;      possibility of system crash when carrier lost while
  93. ;      performing repeated console status checks without
  94. ;      any console output.  This problem occurs during the
  95. ;      password input of USERPW.ASM, and potentially any other
  96. ;      program that does repeated direct console input, such
  97. ;      as MBASIC, etc.  
  98. ;      By Ron Fowler and Dave Hardy
  99. ;
  100. ;05/14/81 Added CCS disk support (to turn off disks when idle)
  101. ;      Added support for Godbout SS1 Real time clock.
  102. ;      Added Phone to Lister, Punch & Reader patch. (AAJ)
  103. ;
  104. ;03/20/81 Fixed MOUTPUT so parity bit is stripped before outputting
  105. ;      character to modem.  Corrected 3/18/81 null fix.  Added
  106. ;      additional description to heading of this file.  (KBP)
  107. ;
  108. ;03/18/81 Add first-ring debounce routine, change PMMI HANGUP
  109. ;      to do break for faster disconnect, fix error in P3TODTR
  110. ;      equate for PMMI, added end-of-program error message to
  111. ;      mark ending address (see note at label DEST). By KBP.
  112. ;      Fix bug that prevented nulls at end of line if DUAL$IO
  113. ;      was true.  By Hank Szyszka.
  114. ;
  115. ;02/23/81 Conditional assembly added for Intertec SuperBrain
  116. ;      with Racal-Vadic 3451 modem. Corrected lack of RET in
  117. ;      CONIN. In MOUTPUT, replaced CZ CHECK with JNZ SILENT,
  118. ;      CALL CHECK; this eliminates chance of looping in MOUTPUT
  119. ;      if modem doesn't empty USART after carrier lost.
  120. ;      Also had to write a routine to patch BIOS so that after
  121. ;      the warm boot disk read this program repatches the BIOS.
  122. ;      Apparently the SuperBrain warm boot overwrites a portion
  123. ;      of the BIOS. By P.L. Kelley
  124. ;
  125. ;02/17/81 Added check for extraneous control characters in
  126. ;      hardcopy log.  (Formfeed seems to be a common "hit").
  127. ;      Changed local startup test to directly test for carrier
  128. ;      instead of calling CARCK, to avoid 15 second delay.
  129. ;      <BRR>
  130. ;
  131. ;02/15/81 Removed dependance on DC Hayes hardware timer so that
  132. ;         DCHAYES conditional assembly is compatible with both
  133. ;         old-style 80-103A and new-style MM100 boards.
  134. ;         Rearranged patch list to "most recent first" order.
  135. ;      Added message for invalid-drive test.
  136. ;         Added ANI 7Fh to upper case conversion test so that
  137. ;         it's not fooled by bit 7 being set.
  138. ;         Added WELUSR equate for user # containing WELCOME file.
  139. ;         Removed PTRPORT equate and changed hardcopy logic to
  140. ;         work through the BIOS printer driver. <BRR>
  141. ;
  142. ;01/22/81 Changed carrier detect routine for DC Hayes to wait for
  143. ;      15 seconds after loss of carrier to return. <DAVID KOZINN>
  144. ;
  145. ;01/17/81 Changed timing loops to use DC Hayes hardware timer
  146. ;      if present.   <DAVID KOZINN>
  147. ;
  148. ;01/16/81 Added equates and code for the DC Hayes 
  149. ;      Micromodem 100.  <DAVID KOZINN>
  150. ;
  151. ;09/23/80 Fixed bugs that prevented "bye /a" and "bye /c" from
  152. ;      working properly.  Also repaired several errors in
  153. ;      conditional assembly nesting.  By Ron Fowler
  154. ;
  155. ;09/20/80 Modified status checking during ring-wait routine to
  156. ;      use cp/m BDOS call, as suggested by Keith Petersen.
  157. ;      This should make the program more portable.  Also
  158. ;      added Bruce Ratoff's update to DCHBYE program (5.5),
  159. ;      that allows the use of bye from non-zero user areas.
  160. ;      By Ron Fowler
  161. ;
  162. ;09/19/80 Modified COM file load routine to prevent BDOS
  163. ;      overwrite if the COM file won't fit in the TPA
  164. ;      By Ron Fowler
  165. ;
  166. ;09/19/80 Added new '/' option C, which has the same affect as
  167. ;      /A, except that /C loads the com file after answering
  168. ;      the phone, while /A boots CP/M.  By Ron Fowler
  169. ;
  170. ;09/19/80 Added conditional assembly to give the operator a
  171. ;      'twit' logout key. Added conditionals for 'message
  172. ;      from operator' and 'system down in 5 minutes' keys.
  173. ;      Added front-panel selection of hard-copy log, remote
  174. ;      'black-out', and password option.  Also, if cpm/2 is
  175. ;      used, a message is printed when an unsupported user
  176. ;      area is entered.  By Ron Fowler and Dave Hardy
  177. ;
  178. ;09/19/80 Modified to prevent re-load of the com file when
  179. ;      a voice call comes in.  Reset the DMA address back
  180. ;      to 80h after the com file is loaded.  By Ron Fowler
  181. ;
  182. ;09/16/80 Added conditional assembly to allow automatic
  183. ;      loading of a com file instead of cp/m boot. Also
  184. ;      added decimal usrlog counters as conditional
  185. ;      assembly.  By Ron Fowler
  186. ;
  187. ;09/15/80 Added conditional assembly for automatic timed
  188. ;      log-out, drive and user number masking, lower
  189. ;      case query at login, and cp/m 2.x.  Thanks to
  190. ;      Bruce Ratoff for the routines (lifted from his
  191. ;      'DCHBYE54.ASM') used to implement these functions
  192. ;      NOTE: in order to implement the timed log-out, it
  193. ;      was necessary to do timing in software loops.
  194. ;      Therefore, a new equate, FASTCLK, has been added
  195. ;      to allow for 4mhz clock speeds. Also added Bruce
  196. ;      Ratoff's overrun/framing error checking when read-
  197. ;      ing the modem port.  By Ron Fowler
  198. ;
  199. ;07/16/80 Added "/R" command option to allow USRLOG
  200. ;      counters to be reset upon entry.  By Dave Hardy
  201. ;
  202. ;07/11/80 Added conditional assembly for password and
  203. ;      user log routines, and routines to print USRLOG
  204. ;      information on console after program exit.
  205. ;      By Dave Hardy
  206. ;
  207. ;07/10/80 Added code to allow auto-answer after first
  208. ;      or second ring for more reliable auto-answer
  209. ;      when using "ringback" option.  By Dave Hardy
  210. ;
  211. ;06/29/80 Added USRLOG routines to keep track of number
  212. ;      of callers, and display on front panel
  213. ;      of IMSAI (i.e. output number to port FFH).
  214. ;      By Dave Hardy
  215. ;
  216. ;06/11/80 Added routines to allow conditional assembly for
  217. ;      Morrow's Discus 2D board (all Rev's) with memory
  218. ;      mapped I/O.  Added 710 Baud rate selection option
  219. ;      at sign-on.  By Dave Hardy and Bruce Levison.
  220. ;
  221. ;01/24/80 Added routines to preserve registers when calling
  222. ;      the user's CBIOS.  Added conditional assembly for
  223. ;      callback feature.  Increased stack space to 60.
  224. ;      By Keith Petersen.
  225. ;
  226. ;09/24/79 Added routines to allow automatic multiple baud
  227. ;      rate selection, exit to CP/M from local console,
  228. ;      echo nr. of nulls selected. By Keith Petersen,
  229. ;      with thanks to Bob Mathias for suggestions.
  230. ;
  231. ;05/06/79 Added routine to allow "callback" operation so modem
  232. ;      does not answer normal voice calls.  By Robbin Hough
  233. ;      and Keith Petersen, W8SDZ.
  234. ;
  235. ;------------------------------------------------
  236. ;
  237. ;This program runs up in high RAM.  It gets there
  238. ;by being moved there when 'BYE' is typed.
  239. ;
  240. ;The program in high RAM does the following:
  241. ;
  242. ;    1.    Hangs up the phone
  243. ;    2.    Awaits ring detect, allows exit
  244. ;        to CP/M if local KBD types CTL-C
  245. ;    3.    Outputs carrier (see callback routines)
  246. ;    4.    Awaits incoming carrier going to step 1
  247. ;        if none found in 15 seconds
  248. ;    5.    Asks number of nulls (0-9)
  249. ;    6.    Types the file "WELCOME" from
  250. ;        disk, allowing CTL-C to skip it
  251. ;    7.    Asks for a password, allowing
  252. ;        5 tries to get it right.
  253. ;    8.    When password entered, if used,
  254. ;        drops into CP/M.
  255. ;    9.    Caller can leave by hanging up,
  256. ;        (any time carrier is lost, it
  257. ;        waits 15 seconds, then goes
  258. ;        back to step 1), or the caller
  259. ;        may type the program name (BYE)
  260. ;
  261. ;------------------------------------------------
  262. ;
  263. ;System equates
  264. ;
  265. FALSE    EQU    0
  266. TRUE    EQU    NOT FALSE
  267. ;
  268. CR    EQU    0DH
  269. LF    EQU    0AH
  270. MINUTES    EQU    20*60    ;CONSTANT FOR 1 MIN TIME DELAY
  271. ;
  272. ;Change the following equate to an area in your
  273. ;high memory where this program may patch itself in.
  274. ;Approximate memory requirements: 2k bytes or more,
  275. ;depending upon the options selected.  A marker has
  276. ;been placed at the end to deliberately print an error
  277. ;message during assembly in order to determine the actual
  278. ;ending address of the program.  The error message will
  279. ;not affect the assembly.  Make sure you have memory
  280. ;available up to the address shown.
  281. ;
  282. DEST0    EQU    0F900H    ;RUNNING LOCATION OF CODE
  283. ;
  284. ;Change the following to specify either DCHAYES, PMMI or systems
  285. ;with EXTERNAL  modems. Be sure to change either TPORT for PMMI or
  286. ;DATA for DCHAYES if they are not at the standard locations.
  287. ;
  288. DCHAYES    EQU    TRUE     ;TRUE FOR DC HAYES MODEM
  289. PMMI    EQU    FALSE     ;TRUE FOR PMMI MODEM
  290. IN8251    EQU    FALSE    ;TRUE FOR EXTERNAL AND INTEL 8251
  291. WD8250  EQU    FALSE    ;TRUE FOR EXTERNAL AND WESTERN DIGITAL 8250 
  292. ;
  293. ;Change the following if you have a DC Hayes modem that is
  294. ;not based at 80H. All other port equates are based on this.
  295. ;
  296.     IF    DCHAYES
  297. DATA    EQU    80H    ;DC HAYES DATA PORT
  298.     ENDIF        ;DCHAYES
  299. ;
  300. ;Change the following if you have a PMMI modem that is not
  301. ;based at 0C0H.  All other port equates are based on this.
  302. ;
  303.     IF    PMMI
  304. TPORT    EQU    0C0H    ;UART CONTROL/STATUS PORT
  305.     ENDIF
  306. ;
  307.     IF    WD8250 
  308. BASE$PORT  EQU  20H
  309.     ENDIF
  310. ;
  311. ;You will likely also want to change the password,
  312. ;located below at label 'PASSWD', and the messages
  313. ;printed at label 'WELCOME' and just above label
  314. ;'HANGUP'. The names of the welcome and com files
  315. ;are at lables 'WELFIN' and 'COMFCB' respectively. 
  316. ;
  317. ;****************************************************
  318. ;*        Option configuration section        *
  319. ;****************************************************
  320. ;
  321. ;-----------------General Options------------------
  322. ;
  323. OXGATE    EQU    TRUE     ;WANT TO RUN AN OXGATE NODE?
  324. PRINTER EQU    TRUE     ;WANT TO RETAIN LIST DEVICE?
  325. DUAL$IO EQU    TRUE     ;WANT CONSOLE & MODEM?
  326. CALLBAK EQU    FALSE    ;WANT CALLBACK FEATURE?
  327. PWRQD    EQU    FALSE     ;WANT TO USE PASSWORD?
  328. BOOTMSG    EQU    FALSE    ;TRUE IF BOOT MESSAGE
  329. FKEYS    EQU    TRUE    ;WANT SPECIAL FUNCTION KEYS
  330. USRLOG    EQU    FALSE    ;WANT TO COUNT NUMBER OF USERS?
  331. HARDLOG EQU    TRUE     ;WANT TO ECHO REMOTE KBD TO PRINTER?
  332. TIMEOUT EQU    TRUE    ;WANT AUTO LOG-OFF FOR SLEEPY CALLERS?
  333. TOVALUE EQU    5    ;MINUTES TO AUTO LOGOFF
  334. COMFILE EQU    TRUE    ;WANT TO AUTOBOOT A COM FILE?
  335. DECIMAL EQU    TRUE    ;WANT DECIMAL VALUES FOR LOGS?
  336. TRAPLC    EQU    FALSE    ;WANT TO TRAP LOWER CASE?
  337. ALLDEV    EQU    FALSE    ;RETAIN PUNCH, READER, LISTER
  338. MINICK    EQU    FALSE    ;TRUE IF MINICBBS
  339. RBBSCK    EQU    FALSE    ;TRUE IF RBBS SETS/RESETS FLAG AT 'WRTLOC'
  340. IOBYTE    EQU    0003    ;LOCATION OF INTEL IOBYTE
  341. IOVAL    EQU    0    ;INITIAL VALUE TO STORE IN IOBYTE
  342. ;----------System and hardware dependent options--------------
  343. ;
  344. ZCPRT    EQU    TRUE     ;TRUE IF RUNNING NewZCPR (IN SECURE MODE)
  345. WHEEL    EQU    0FFFFH    ;LOCATION OF NZCPR'S WHEEL FLAG
  346. BYELOW    EQU    FALSE    ;TRUE IF BYE BELOW CCP
  347. LOSER    EQU    FALSE    ;TRUE IF WARM BOOT OVERWRITE PART OF THE BIOS
  348. NORING    EQU    FALSE    ;UART RING INDICATOR NOT AVAILABLE
  349. CPM2    EQU    TRUE    ;USING CP/M 2.X?
  350. MAXUSR    EQU    15    ;SET TO 0 FOR CP/M 1.4
  351. WELUSR    EQU    14    ;USER # OF WELCOME FILE, CPM2 TRUE
  352. COMUSR    EQU     14    ;USER # OF COM FILE, CPM2 TRUE
  353. FASTCLK    EQU     TRUE    ;SET TRUE FOR 4MHZ CLOCK
  354. MAXDRV    EQU    3    ;HIGHEST DRIVE SUPPORTED
  355. IMSAI    EQU    FALSE    ;ADDS VARIOUS OPTIONS W/SENSE SW'S
  356. TWITKEY EQU    'N'-40H ;KEYCODE TO LOG-OUT A CREEP
  357. MSGKEY    EQU    'Q'-40H ;KEYCODE TO PRINT 'MESG FROM OPER:'
  358. SYSDKEY EQU    'O'-40H ;KEYCODE TO PRINT SYS DOWN MSG
  359. SENSE    EQU    0FFH    ;SENSE SWITCH PORT NUMBER IMSAI TRUE
  360. BLKOUT    EQU    FALSE    ;SWITCH TO TURN OFF REMOTE SEND IMSAI TRUE
  361. SELPASS EQU    FALSE     ;SWITCH TO REQUIRE A PASSWORD IMSAI TRUE
  362. CCSDISK    EQU    FALSE     ;SET TRUE IF CCS DISK CONTROLLER   
  363. RTC    EQU    FALSE     ;SET TRUE IF GODBOUT SS1 BOARD
  364. ;
  365.     IF CCSDISK
  366. ;
  367. DISKON    EQU    071H    ;MOTORS ON, SELECT DISK A
  368. DISK    EQU    34H    ;DISK CONTROL PORT
  369. DISKOFF    EQU    051H    ;MOTORS OFF, SELECT DISK A;
  370.     ENDIF        ;CCSDISK
  371. ;
  372. ;Assignment of front-panel options to switches:
  373. ;
  374. LOGSW    EQU    01H    ;TURN ON FOR HARDCOPY
  375. PWDSW    EQU    02H    ;TURN ON FOR 'PASSWORD' MODE
  376. BLACKSW EQU    04H    ;TURN ON TO BLACK OUT REMOTE END
  377. ENABLF    EQU    08H    ;TURN ON TO ENABLE SPL FUNC KEYS
  378. ;
  379.     IF BYELOW
  380. DEST    EQU    DEST0+3    ;KEEP ON TARGET
  381. ;
  382. ;****WARNING *** WMLOC AND OLDBD ARE SYSTEM DEPENDENT****
  383. ;WMLOC can be found in the BIOS by tracing through the
  384. ;warm boot routine with DDT until you find:
  385. ;    LXI    H,OLDBD
  386. ;    SHLD    0006
  387. ;WMLOC is the address containing the LSB of OLDBD
  388. ;
  389. WMLOC    EQU    0E04DH
  390. OLDBD    EQU    0D006H
  391. ;
  392.     ENDIF        ;BYELOW 
  393. ;
  394.     IF    NOT BYELOW
  395. DEST    EQU    DEST0
  396.     ENDIF        ;NOT BYELOW
  397. ;
  398. ;There are some cases where warm boot overwrites the
  399. ;initial bios jump table. This problem was solved for
  400. ;the Superbrain 3.0 bios by finding a warmboot call
  401. ;to high in the bios. This call is then patched by
  402. ;BYE.  The form of the call is:
  403. ;    WBCALL  CALL    WMSTRT
  404. ;
  405.     IF    LOSER
  406. ;
  407. WBCALL    EQU    0DE48H    ;CHECK THIS IN YOUR BIOS     
  408. ;
  409. ;The following location is called
  410. ;
  411. WMSTRT    EQU    0EE48H    ;CHECK THIS IN YOUR BIOS
  412. ;
  413.     ENDIF        ;LOSER
  414. ;            
  415. ;****************************************************
  416. ;*     End of option configuration section        *
  417. ;****************************************************
  418. ;
  419. ;All modem I/O and control are here
  420. ;
  421. ;
  422. ;************ D.C. Hayes modem I/O area ************
  423. ;
  424.     IF    DCHAYES
  425. ;
  426. ;Port equates
  427. ;
  428. DPORT    EQU    DATA    ;DATA PORT
  429. STATUS    EQU    DATA+1
  430. RPORT    EQU    STATUS    ;MODEM STATUS PORT
  431. CR1    EQU    DATA+1
  432. CR2    EQU    DATA+2
  433. CR3    EQU    DATA+3
  434. ;
  435. ;Bit functions
  436. ;
  437. ;    Status register
  438. ;
  439. RRF    EQU    1    ;RECEIVE REGISTER FULL
  440. TRE    EQU    2    ;TRANSMITTER HOLDING REGISTER EMPTY
  441. PE    EQU    4    ;PARITY ERROR
  442. FE    EQU    8    ;FRAMING ERROR
  443. OE    EQU    10H    ;OVERRUN ERROR
  444. TMR    EQU    20H    ;TIMER STATUS (MM100 ONLY)
  445. CD    EQU    40H    ;CARRIER PRESENT
  446. RI    EQU    80H    ;NOT RING INDICATOR (LOW TRUE)
  447. P2RDET    EQU    RI    ;SAME AS ABOVE
  448. ;
  449. ;    Control register 1 (CR1)
  450. ;
  451. EPE    EQU    1    ;EVEN PARITY ENABLE
  452. LS1    EQU    2    ;WORD LENGTH SELECT BIT 1
  453. LS2    EQU    4    ;WORD LENGTH SELECT BIT 2
  454. SBS    EQU    8    ;STOP BITS
  455. PI    EQU    10H    ;PARITY INHIBIT
  456. TMIE    EQU    20H    ;TIMER INTERRUPTS ENABLE (MM100 ONLY)
  457. ;
  458. ;    Control register 2 (CR2)
  459. ;
  460. BRS    EQU    1    ;BAUD RATE CONTROL
  461. TXE    EQU    2    ;TRANSMIT CARRIER ENABLE
  462. MS    EQU    4    ;MODE (0=ANSWER 1=ORIGINATE)
  463. BRK    EQU    8    ;SEND BREAK
  464. ST    EQU    10H    ;SELF TEST
  465. TIE    EQU    20H    ;TRANSMITTER INTERRUPT ENABLE
  466. RIE    EQU    40H    ;RECEIVER INTERRUPT ENABLE (MM100 ONLY)
  467. OH    EQU    80H    ;OFF-HOOK
  468. ;
  469.     ENDIF        ;DCHAYES
  470. ;
  471. ;
  472. ;************ PMMI modem I/O area ************
  473. ;
  474.     IF    PMMI
  475. ;
  476. ;PMMI modem port equates (TPORT previously done)
  477. ;
  478. DPORT    EQU    TPORT+1 ;DATA PORT
  479. RPORT    EQU    TPORT+2 ;RATE GEN/MODEM STATUS
  480. CPORT    EQU    TPORT+3 ;MODEM CONTROL
  481. ;
  482. ;Switch hook and modem commands, output to TPORT (port 0)
  483. ;
  484. P0BYE    EQU    0    ;ON HOOK, OR DIALING BREAK
  485. P0ORIG    EQU    1    ;OFF HOOK, ORIG.
  486. P0ANSW    EQU    2    ;ANSWER PHONE
  487. P08BIT    EQU    0CH    ;8 DATA BITS
  488. P0NOPY    EQU    10H    ;NO PARITY
  489. P0EPS    EQU    20H    ;EVEN PARITY SELECT
  490. P0TSB    EQU    40H    ;2 STOP BITS
  491. P0EI    EQU    80H    ;ENABLE INTERRUPTS
  492. P0NORM    EQU    P08BIT+P0NOPY        ;NORMAL 8 BITS, NO PARITY
  493. P0110    EQU    P08BIT+P0NOPY+P0TSB ;SAME W/2 STOP BITS
  494. ;
  495. ;Modem status, input on RPORT (port 3)
  496. ;
  497. P2DTD    EQU    1    ;DIAL TONE DETECT
  498. P2RDET    EQU    2    ;RING DETECT
  499. P2CTS    EQU    4    ;CTS (CARRIER DETECT)
  500. P2RXBRK EQU    8    ;RECEIVE BREAK
  501. P2CONN    EQU    10H    ;CONNECTED? (0=YES, 1=MODEM CHIP HUNG UP)
  502. P2TMPUL EQU    80H    ;TIMER PULSES (40% UP CYCLE)
  503. ;
  504. ;Timer rate selection
  505. ;
  506. TRATE    EQU    250    ;VALUE FOR .1 SEC
  507. ;
  508. ;PMMI modem status masks
  509. ;
  510. P0TBMT    EQU    1    ;XMIT BUFF EMPTY
  511. P0DAV    EQU    2    ;DATA AVAILABLE
  512. P0TEOC    EQU    4    ;TEST END OF CHAR
  513. P0RPE    EQU    8    ;REC'D PARITY ERR
  514. P0ORUN    EQU    10H    ;OVERRUN
  515. P0FERR    EQU    20H    ;FRAMING ERROR
  516. ;
  517. ;Baud rate divisors
  518. ;
  519. B110    EQU    142    ;110 BAUD
  520. B300    EQU    52    ;300 BAUD
  521. B450    EQU    35    ;450 BAUD
  522. B600    EQU    26    ;600 BAUD
  523. B710    EQU    22    ;710 BAUD
  524. ;
  525.     ENDIF        ;PMMI
  526. ;
  527. ;************ EXTERNAL MODEM I/O AREA ************
  528. ;
  529.     IF    IN8251
  530. ;
  531. ;True if uart is Intel 8251 or equivalent
  532. ;
  533. DPORT    EQU    58H    ;DATA PORT
  534. CPORT    EQU    59H    ;CONTROL PORT
  535. SPORT    EQU    CPORT    ;STATUS PORT
  536. BPORT    EQU    60H    ;BAUD RATE PORT
  537. RPORT    EQU    69H    ;RING INDICATOR PORT
  538. ;
  539. ;The following are CPORT commands
  540. ;
  541. RSTINS    EQU    42H    ;RESET USART AND SEND DTR
  542. MODINS1    EQU    4EH    ;8 BITS, NO PARITY, 1 STOP BIT, 16X BAUD RATE
  543. MODINS2    EQU    0CEH    ;8 BITS, NO PARITY, 2 STOP BITS, 16X BAUD RATE
  544. ONINS    EQU    17H    ;RESET ERROR FLAGS, SEND DTR, ENABLE RECEIVE
  545.             ;AND TRANSMIT
  546. OFFINS    EQU    10H    ;DROP DTR, DISABLE RECEIVE AND TRANSMIT
  547. ;
  548. ;The following are SPORT status masks
  549. ;
  550. TRNRDY    EQU    01H    ;TRANSMITER EMPTY
  551. RCVRDY    EQU    02H    ;DATA AVAILABLE
  552. PERR    EQU    08H    ;PARITY ERROR
  553. ORERR    EQU    10H    ;OVERRUN ERROR
  554. FRERR    EQU    20H    ;FRAMING ERROR
  555. TOERR    EQU    ORERR + FRERR    ;OVERRUN PLUS FRAMING ERROR
  556. DSR    EQU    80H    ;DATA SET READY
  557. ;
  558. ;The following are baud rates for BPORT. The upper 4 bits are
  559. ;for the modem port while the lower four are for the auxiliary
  560. ;port.
  561. ;
  562. BD110    EQU    27H    ;110 BAUD
  563. BD300    EQU    57H    ;300 BAUD
  564. BD1200    EQU    77H    ;1200 BAUD
  565. ;
  566. ;Ring indicator port mask
  567. ;
  568. RI    EQU    40H    ;NOT RING INDICATOR (LOW TRUE)
  569. P2RDET    EQU    RI
  570. ;
  571.     ENDIF        ;IN8251
  572. ;
  573. ;****************WD8250  I/O AREAS*************************
  574. ;True if usar is Western Digital 8250 or equivilent.
  575. ;
  576.     IF    WD8250
  577. DPORT    EQU    BASE$PORT    ;DATA PORT
  578. LPORT    EQU    BASE$PORT+3    ;LINE CONTROL
  579. CPORT    EQU    BASE$PORT+4    ;MODEM CONTROL
  580. SPORT    EQU    BASE$PORT+5    ;LINE STATUS PORT
  581. MSPORT    EQU    BASE$PORT+6    ;MODEM STATUS PORT
  582. RPORT    EQU    BASE$PORT+6    ;RING INDICATOR PORT
  583. ;
  584. *****************LINE STATUS MASKS************************
  585. ;
  586. P0TBMT    EQU    20H    ;XMIT BUFFER EMPTY
  587. P0DAV    EQU    01H    ;DATA AVAILABLE
  588. P0RPE    EQU    04H    ;PARITY ERROR
  589. P0ORUN    EQU    02H    ;OVERRUN ERROR
  590. P0FERR    EQU    08H    ;FRAMING ERROR
  591. P0BRK    EQU    10H    ;BREAK DETECT
  592. ;
  593. ;****************MODEM STATUS MASKS***********************
  594. ;
  595. P2DSR    EQU    20H    ;DATA SET READY
  596. P2CTS    EQU    080H    ;CARRIER DETECT
  597. P2RDET    EQU    040H    ;RING DETECT
  598. ;
  599. ;******************BAUD RATE DIVISORS*********************
  600. ;
  601. BR300LS    EQU    000H    ;300 BAUD
  602. BR300MS    EQU    001H    
  603. BR450LS    EQU    0ABH    ;450 BAUD
  604. BR450MS    EQU    000H    
  605. BR600LS    EQU    080H    ;600 BAUD
  606. BR600MS    EQU    000H    
  607. BR120LS    EQU    040H    ;1200 BAUD
  608. BR120MS    EQU    000H
  609. ;
  610. ;*******************MODEM CONTROL****************************
  611. ;
  612. MCDTR    EQU    01H    ;
  613. MCRTS    EQU    02H
  614. MCOUT1    EQU    04H
  615. MCOUT2    EQU    08H
  616. ;
  617. ;*********************LINE CONTROL****************************
  618. ;
  619. LCWLS0    EQU    01H
  620. LCWLS1    EQU    02H
  621. LCSTB    EQU    04H
  622. LCPEN    EQU    08H
  623. LCPES    EQU    10H
  624. LCSPS    EQU    20H
  625. LCBRK    EQU    40H
  626. LCDLAB    EQU    80H
  627.     ENDIF        ;WD8250
  628. ;
  629. ;---------------------------------------------------------
  630. ;
  631.     ORG    100H
  632. ;
  633.     IF     BYELOW    
  634. ;This code allow running below ccp and using programs such as
  635. ;Mbasic or Typesq ect....
  636. ;
  637.     LXI    H,OLDBD    ;OLD LOCATION STORED IN 6 AND 7 FOR
  638.             ;JUMP FROM BDOS CALL
  639.     SHLD    DEST-2    ;STORE IT JUST ABOVE BYE
  640.     LXI    H,DEST-3 ;POINT TO THREE BYTE ABOVE 
  641.              ;NORMAL BYE
  642.     MVI    M,0C3H    ;PUT A JUMP THERE
  643.     SHLD    0006H    ;STORE DEST-3 FOR BDOS JUMP
  644.     SHLD    WMLOC    ;STORE DEST-3 IN YOUR BIOS
  645. ;
  646.     ENDIF        ;BYELOW
  647. ;
  648. ;Move modem interface program up to high RAM and jump to it
  649. ;
  650. MOVEUP    LXI    B,PEND-START+1        ;NUMBER OF BYTES TO MOVE
  651.     LXI    H,DEST+PEND-START+1 ;END OF MOVED CODE
  652.     LXI    D,SOURCE+PEND-START ;END OF SOURCE CODE
  653. ;
  654. MVLP    LDAX    D    ;GET BYTE
  655.     DCX    H    ;BUMP POINTERS
  656.     MOV    M,A    ;NEW HOME
  657.     DCX    D
  658.     DCX    B    ;BUMP BYTE COUNT
  659.     MOV    A,B    ;CHECK IF ZERO
  660.     ORA    C
  661.     JNZ    MVLP    ;IF NOT, DO SOME MORE
  662. ;
  663.     PUSH    H    ;SAVE FOR LATER JUMP
  664.     MVI    A,0C3H    ;CLEAR ANY TRAPS SO SYSOP..
  665.     STA    0    ;CAN USER "BYE /A"
  666.     XRA    A    ;NEXT WARMBOOT TO USR0/DRV A
  667.     STA    4
  668.     MVI    C,14    ;MAKE DRIVE A DEFAULT
  669.     MOV    E,A    ;LOG-IN DRIVE CP/M FUNCTION
  670.            CALL    BDOS                                     
  671. ;
  672.     IF    CPM2    ;SET USER 0
  673.     MVI    C,32    ;GET/SET USR CP/M FUNCTION
  674.     MVI    E,WELUSR
  675.     CALL    BDOS
  676.     ENDIF        ;CPM2
  677. ;
  678.     RET        ;TO ADRS PUSHED ABOVE
  679. ;
  680. ;
  681. SOURCE    EQU    $    ;BOUNDARY MEMORY MARKER
  682. ;
  683. OFFSET    EQU    DEST-SOURCE ;RELOC AMOUNT
  684. ;
  685. ;-----------------------------------------------;
  686. ;    The following code gets moved        ;
  687. ;    to high RAM located at "DEST",        ;
  688. ;        where it is executed.        ;
  689. ;-----------------------------------------------;
  690. ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  691. ;XX   C A U T I O N :  If modifying anything    XX
  692. ;XX    in this program from here on:        XX
  693. ;XX    A-L-L  labels must be of the form:    XX
  694. ;XX    LABEL    EQU    $+OFFSET        XX
  695. ;XX    in order that the relocation to high      XX
  696. ;XX    RAM work successfully.  Forgetting to    XX
  697. ;XX    specify '$+OFFSET' will cause the pro-    XX
  698. ;XX    gram to JMP into whatever is currently    XX
  699. ;XX    in low memory, with unpredictable    XX
  700. ;XX    results.  Be careful....        XX
  701. ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  702. ;
  703. START    EQU    $+OFFSET
  704.     JMP    START0    ;HOP OVER FIXED VECTORS
  705. ;
  706. ;Cold boot vector ends up here. Our cold boot routine
  707. ;consists of a jump to the warm boot routine. We are
  708. ;defined to consist of only this jump, with a jump
  709. ;to PRNLOG immediately after this jump, and other
  710. ;modifiable variables after that. By doing this,
  711. ;a trivial program can be written that calculates
  712. ;where PRNLOG is thru the warm boot vector at 0001H,
  713. ;then calls PRNLOG, allowing remote users to get the
  714. ;BYE log printed. Such a program, easily entered
  715. ;with DDT, is as follows:
  716. ;
  717. ;    LHLD    0001H    ;PT TO COLD BOOT VECTOR + 3
  718. ;    DCX    H    ;PT TO VECTOR HIGH BYTE
  719. ;    MOV    D,M    ;GET THAT IN D
  720. ;    DCX    H    ;PT TO VECTOR LOW BYTE
  721. ;    MOV    E,M    ;GET THAT IN E
  722. ;    LXI    H,3    ;CALC PRNLOG ADDRESS
  723. ;    DAD    D    ; BY ADDING TO COLD BOOT ADDRESS
  724. ;    PCHL        ;GO PRINT LOG INFO, THEN
  725. ;            ; RETURN TO CCP
  726. ;
  727. ;A similar calculation can be used to determine
  728. ;the locations of the MXUSR, MXDRV, and TOVAL
  729. ;variables to change them on the fly for special
  730. ;users. Since this will often be done by a
  731. ;BASIC signon program, the following sequence
  732. ;of code is recommended:
  733. ;
  734. ;  10 A=PEEK(2)*256+PEEK(1)-2 'Pt to cold boot address
  735. ;  20 A=PEEK(A+1)*256+PEEK(A)+6 'Get address of MXUSR
  736. ;  30 POKE A,8  'Set MXUSR to 8, allows 0-8
  737. ;  40 POKE A+1,4 'Set MXDRV to 4, allows A-D
  738. ;  50 POKE A+2,5 'Set TOVAL to 5, allows 5 min of inactivity
  739. ;
  740. ;The values POKE'ed will be reset to the assembly
  741. ;values of MAXUSR, MAXDRV and TOVALUE respectively
  742. ;the next time BYE answers the phone.
  743. ;
  744. ;The following will test whether bye is active and then set
  745. ;the flag at WRTLOC.
  746. ;
  747. ;  10 A=PEEK(2)*256+PEEK(1)-2
  748. ;  20 A=PEEK(A+1)*256+PEEK(A)+9 'Get Address of WRTLOC
  749. ;  30 IF CHR$(PEEK(A+1))+SHR$(PEEK(A+2))+CHR$(PEEK(A+3))<>"BYE" THEN
  750. ;  40 POKE A,&HFF 'SET FLAG FOR WRITE IN PROGRESS
  751. ;
  752. ;The routine on line 30 should be used in RBBS so that when RBBS is 
  753. ;running locally nothing will be poked into the bios.
  754. ;   
  755. MCBOOT    EQU    $+OFFSET
  756.     JMP    MBOOT    ;OFF TO WARM BOOT
  757.     JMP    PRNLOG    ;GO PRINT OUT ITEMS OF INTEREST
  758. ;
  759. ;Variables follow in a predefined order that can
  760. ;be manipulated by a passworded or other program
  761. ;to give special users different capabilities.
  762. ;
  763. MXUSR    EQU    $+OFFSET
  764.     DB    MAXUSR    ;RUNTIME MAX USER # (UNUSED
  765.             ; UNDER CP/M 1.4)
  766. ;
  767. MXDRV    EQU    $+OFFSET
  768.     DB    MAXDRV    ;RUNTIME # DRIVES ACCESSABLE
  769. ;
  770. TOVAL    EQU    $+OFFSET
  771.     DB    TOVALUE    ;RUNTIME # INACTIVE MINUTES
  772.             ; BEFORE AUTO LOGOFF
  773. NULLS    EQU    $+OFFSET
  774.     DB    5    ;INITIAL NUMBER OF NULLS
  775. ;
  776. ULCSW    EQU    $+OFFSET
  777.     DB    0    ;UPPER CASE ONLY SWITCH
  778. ;
  779. LFEEDS    EQU    $+OFFSET
  780.     DB    0    ;LINE FEED SWITCH
  781. ;    
  782. WRTLOC    EQU    $+OFFSET
  783.     DB    0    ;LOCATION OF FLAG FOR RBBS TO 
  784.             ;SET WHILE DOING DISK WRITES
  785.  
  786. ;Program version number message.
  787. ;
  788. VMSG    EQU    $+OFFSET
  789.     DB    'BYE version 7.8 as of 02/20/82',CR,LF,'$'
  790. ;
  791. ;----------------------------------------------
  792. ;This is the official start of the BYE program.
  793. ;----------------------------------------------
  794. ;
  795. ;If carrier lost, hang up, await ring.
  796. ;Otherwise, say goodbye, and hang up
  797. ;
  798. START0    EQU    $+OFFSET
  799. ;
  800.     XRA    A    ;GET 0
  801.     STA    LOSTFLG ;SHOW NO CARR. LOST
  802. ;
  803.     IF    MINICK
  804. ;
  805. ;Set MINICK to true if you use MINICBBS and want to take
  806. ;advantage of its feature which can prevent the modem
  807. ;from hanging up if the caller should happen to discon-
  808. ;nect during a file update. MINICBBS sets the high-order 
  809. ;bit of IOBYTE to (address 0003) to indicate a file update
  810. ;is in progress.
  811. ;
  812.     MVI    A,IOVAL
  813.     STA    IOBYTE
  814. ;
  815.     ENDIF        ;MINICK
  816. ;
  817. ;Don't allow a remote user to do 'BYE /A'
  818. ;
  819.     IF    DCHAYES
  820.     IN    STATUS
  821.     ANI    CD    ;CHECK CARRIER DETECT
  822.     JNZ    GOODBY    ;SAY GOODBYE IF REMOTE
  823.     ENDIF        ;DCHAYES
  824. ;
  825.     IF    PMMI
  826.     IN    RPORT    ;AS ABOVE, FOR PMMI MODEM
  827.     ANI    P2CTS    ;CD DEDUCED FROM CTS
  828.     JZ    GOODBY
  829.     ENDIF        ;PMMI
  830. ;
  831.     IF    IN8251
  832.     IN    SPORT
  833.     ANI    DSR    ;CHECK CARRIER DETECT
  834.     JNZ    GOODBY    ;GOODBYE IF REMOTE
  835.     ENDIF        ;IN8251
  836. ;
  837.     IF    WD8250 
  838.     IN    MSPORT
  839.     ANI    P2CTS
  840.     JNZ    GOODBY
  841.     ENDIF        ;WD8250
  842. ;
  843. ;Identify version of program
  844. ;
  845.     MVI    C,PRINTF
  846.     LXI    D,VMSG
  847.     CALL    BDOS
  848. ;
  849. ;Check for /A option on command - request to
  850. ;go immediately into answer mode
  851.     LXI    H,FCB+1 ;TO OPTION
  852.     MOV    A,M
  853.     CPI    '/'    ;OPTION?
  854.     JNZ    HANGUP
  855. ;Got an option - validate it
  856.     INX    H    ;TO OPTION BYTE
  857.     MOV    A,M    ;GET IT
  858.     STA    OPTION    ;MIGHT NEED LATER
  859.     CPI    'A'    ;ANSWER?
  860.     JZ    ANSWER
  861. ;
  862.     IF    COMFILE
  863.     CPI    'C'
  864.     JZ    ANSWER
  865.     ENDIF        ;COMFILE
  866. ;
  867.     IF    USRLOG    ;CHECK FOR RESET OF COUNTERS
  868.     CPI    'R'
  869.     CZ    RESET
  870.     ENDIF        ;USRLOG
  871. ;
  872.     JMP    HANGUP    ;WE KNOW IT'S LOCAL, SO SKIP CALL TO CARCK
  873. ;
  874. ;No option, or invalid one
  875. ;
  876. NOSLASH EQU    $+OFFSET
  877.     CALL    CARCK    ;SIGNED OFF W/THIS PROG?
  878.     JC    HANGUP    ;NOBODY THERE
  879. ;
  880. GOODBY    EQU    $+OFFSET
  881.     CALL    ILPRT    ;PRINT THIS MSG:
  882.     DB    CR,LF,'Good-bye, call again...'
  883.     IF     RTC
  884.     DB    CR,LF,CR,LF,'Off at ',0
  885.     CALL    TIME
  886.     CALL    ILPRT
  887.     ENDIF        ;RTC
  888. ;
  889.     DB    CR,LF,CR,LF,0
  890.     CALL    UNPATCH ;UNDO BIOS PATCHES
  891. ;
  892. ;Nobody there, or we are done, so hang up
  893. ;
  894. HANGUP    EQU    $+OFFSET
  895.     LXI    SP,STACK ;SET UP LOCAL STACK
  896.     XRA    A     ;FORCE NEXT WARMBOOT TO USER 0
  897.     STA    4     ;AND DRIVE A
  898. ;
  899.     IF CCSDISK
  900. ;
  901.     CALL DSKOFF    ;SHUT DOWN THE DRIVES
  902. ;
  903.     ENDIF    ;CCSDISK
  904. ;
  905.     MVI    C,14     ;MAKE DRIVE A DEFAULT
  906.     MOV    E,A
  907.     CALL    BDOS
  908.     MVI    A,' '     ;DON'T ALLOW OPTIONS..
  909.     STA    OPTION     ;..AFTER 1 "BYE / <ANYTHING>"
  910. ;
  911.     IF    CPM2 AND COMFILE
  912.     MVI    C,32     ;GET/SET USER CODE
  913.     MVI    E,COMUSR ;LOCATION OF OUR COMFILE
  914.     CALL    BDOS
  915.     ENDIF         ;CPM2 AND COMFILE
  916. ;
  917.     IF    COMFILE
  918.     CALL    LODCOM    ;LOAD THE COM FILE
  919.     ENDIF        ;COMFILE
  920. ;
  921. ;
  922. HANGUP2 EQU    $+OFFSET
  923. ;
  924. ;Clear DTR causing phone to hang up
  925. ;
  926.     IF    DCHAYES
  927.     XRA    A    ;GET A ZERO
  928.     OUT    CR2    ;WRITE TO CR2, CAUSING HANGUP
  929.     ENDIF        ;DCHAYES
  930. ;
  931.     IF    PMMI
  932.     XRA    A    ;GET DISCONNECT VALUE
  933.     OUT    TPORT    ;RESET ORIG/ANSW
  934.     OUT    CPORT    ;TURN OFF DTR, DO BREAK
  935.     ENDIF        ;PMMI
  936. ;
  937.     IF    IN8251
  938.     MVI    A,OFFINS    ;CLEAR DTR
  939.     OUT    CPORT    ;CAUSING HANGUP
  940.     PUSH    B    ;PRESERVE IN CASE WE NEED IT
  941.     MVI    B,150    ;15 SECOND DELAY
  942. ;
  943. OFFTI    EQU    $+OFFSET
  944.     CALL    DELAY    ;0.1 SECOND DELAY
  945.     DCR    B
  946.     JNZ    OFFTI    ;KEEP LOOPING UNTIL FINISHED
  947.     POP    B    ;RESTORE B
  948.     MVI    A,ONINS    ;TURN DTR ON ALLOWING MODEM TO ANSWER PHONE
  949.     OUT    CPORT
  950.     ENDIF        ;IN8251
  951. ;
  952.     IF    WD8250 
  953.     XRA    A    ;SHUT OFF DTR & RTS
  954.     OUT    CPORT    ;SHUT OFF MODEM
  955.     ENDIF        ;WD8250
  956. ;
  957.     IF    WD8250 AND NORING
  958. ;
  959.     PUSH    B    ;PRESERVE IT IF WE NEED IT
  960.     MVI    B,150    ;15 SEC DELAY
  961.  
  962. OFFTI    EQU    $+OFFSET
  963.     CALL    DELAY    ;0.1 SEC DELAY
  964.     DCR    B    
  965.     JNZ    OFFTI    ;KEEP LOOPING UNTIL DONE
  966.     POP    B    ;RESTORE B
  967.     MVI    A,MCDTR+MCRTS    ;TURN ON DTR/RTS 
  968.     OUT    CPORT
  969.     ENDIF        ;WD8250 
  970. ;
  971.     MVI    A,0C3H    ;CLEAR ANY TRAPS..
  972.     STA    0    ;..LEFT FROM COM FILE
  973. ;
  974. ;Await ringing
  975. ;
  976. RINGWT    EQU    $+OFFSET
  977. ;
  978. ;Check local keyboard for CTL-C exit request.
  979. ;NOTE: Must do input via BDOS because CBIOS patches
  980. ;are not done until call comes in.
  981. ;
  982.     CALL    UCSTS
  983.     ANI    7FH    ;STRIP PARITY BIT
  984.     CPI    'C'-40H ;CONTROL C?
  985.     CZ    USRCHK    ;Check for exit if so
  986. ;
  987.     IF    NORING
  988.     IN    MSPORT
  989.     ANI    P2CTS    ;GOT CARRIER
  990.     JNZ    ANSWER
  991.     JMP    RINGWT    ;KEEP CHECKING
  992.     ENDIF        ;NORING
  993. ;
  994. RINGW2    EQU    $+OFFSET
  995.     IN    RPORT    ;GET THE STATUS
  996.     ANI    P2RDET    ;RINGING?
  997. ;
  998.     IF    WD8250 OR IN8251
  999.     JZ    RINGWT    ;NO, WAIT
  1000.     ENDIF    ;WD8250 OR IN8251
  1001. ;
  1002.     IF    NOT (WD8250 OR IN8251)
  1003.     JNZ    RINGWT    ;NO, WAIT
  1004.     ENDIF    ;NOT (WD8250 OR IN8251)
  1005. ;
  1006. ;The phone may be ringing.  Wait .1 sec and look
  1007. ;again to make sure it isn't just relay bounce
  1008.     CALL    DELAY    ;.1 SEC DELAY FOR DEBOUNCE
  1009.     IN    RPORT    ;GET STATUS
  1010.     ANI    P2RDET    ;STILL RINGING?
  1011. ;
  1012.     IF    WD8250 OR IN8251
  1013.     JZ    RINGWT    ;NO, IT WAS RELAY BOUNCE
  1014.     ENDIF    ;WD8250 OR IN8251
  1015. ;
  1016.     IF    NOT (WD8250 OR IN8251)
  1017.     JNZ    RINGWT    ;NO, IT WAS A RELAY BOUNCE
  1018.     ENDIF    ;NOT (WD8250 OR IN8251)
  1019. ;
  1020. ;The phone is definitely ringing, now wait until ring is finished
  1021. ;
  1022. ENDRING EQU    $+OFFSET
  1023.     CALL    DELAY    ;.1 SEC DELAY FOR DEBOUNCE
  1024.     IN    RPORT    ;GET STATUS
  1025.     ANI    P2RDET    ;STILL RINGING?
  1026. ;
  1027.     IF    WD8250 OR IN8251
  1028.     JNZ    ENDRING ;WAIT UNTIL RING FINISHED
  1029.     ENDIF    ;WD8250 OR IN8251
  1030. ;
  1031.     IF    NOT (WD8250 OR IN8251)
  1032.     JZ    ENDRING    ;WAIT UNTIL RING FINISHED
  1033.     ENDIF    ;NOT (WD8250 OR IN8251)
  1034. ;
  1035.     IF    CALLBAK ;NEXT ROUTINES IMPLEMENT CALLBAK
  1036. ;
  1037. ;This routine minimizes the computer's interference
  1038. ;with normal household phone use by having computer
  1039. ;folk dial, let the phone ring once, hang up and 
  1040. ;then dial again.  When the phone rings only once it
  1041. ;alerts the computer which then waits for and answers
  1042. ;any ring which occurs within the next 40 seconds.
  1043. ;
  1044.     MVI    L,45    ;DELAY 4.5 SECONDS FOR NEXT RING
  1045. ;
  1046. WAITNX    EQU    $+OFFSET
  1047.     CALL    DELAY    ;WAIT .1 SECONDS
  1048.     DCR    L    ;MORE TO GO?
  1049.     JNZ    WAITNX    ;YES, LOOP
  1050.     IN    RPORT    ;GET THE STATUS
  1051.     ANI    P2RDET    ;RINGING AGAIN?
  1052.     ENDIF    ;CALLBAK
  1053. ;
  1054.     IF    CALLBAK AND (WD8250 OR IN8251)
  1055.     JZ    EXPECT    ;NO?...ITS FOR ME!
  1056.     ENDIF
  1057. ;
  1058.     IF    CALLBAK AND NOT (WD8250 OR IN8251)
  1059.     JNZ    EXPECT    ;NO?...ITS FOR ME!
  1060.     ENDIF
  1061. ;
  1062.     IF    CALLBAK
  1063. ;
  1064. ;If second ring, then check for third ring, in case
  1065. ;caller's phone exchange not synch'ed with computer's
  1066. ;
  1067. ENDRNG2 EQU    $+OFFSET
  1068.     IN    RPORT    ;GET THE STATUS
  1069.     ANI    P2RDET    ;STILL RINGING?
  1070.     ENDIF    ;CALLBAK
  1071. ;
  1072.     IF    CALLBAK AND (WD8250 OR IN8251)
  1073.     JZ    ENDRNG2 ;WAIT UNTIL RING FINISHED
  1074.     ENDIF
  1075. ;
  1076.     IF    CALLBAK AND NOT (WD8250 OR IN8251)
  1077.     JNZ    ENDRNG2    ;WAIT UNTIL RING FINISHED
  1078.     ENDIF
  1079. ;
  1080.     IF    CALLBAK
  1081.     MVI    L,45    ;DELAY 4.5 SECONDS FOR NEXT RING
  1082. ;
  1083. WAITNX2 EQU    $+OFFSET
  1084.     CALL    DELAY    ;WAIT .1 SECONDS
  1085.     DCR    L    ;MOE TO GO?
  1086.     JNZ    WAITNX2    ;YES, LOOP
  1087.     IN    RPORT    ;GET THE STATUS
  1088.     ANI    P2RDET    ;RINGING AGAIN?
  1089.     ENDIF    ;CALLBAK
  1090. ;
  1091.     IF    CALLBAK AND (WD8250 OR IN8251)
  1092.     JZ    EXPECT    ;NO?...ITS FOR ME!
  1093.     ENDIF
  1094. ;
  1095.     IF    CALLBAK AND NOT (WD8250 OR IN8251)
  1096.     JNZ    EXPECT    ;NO?...ITS FOR ME!
  1097.     ENDIF
  1098. ;
  1099.     IF    CALLBAK
  1100. ;
  1101. ;Call not for computer - wait until ringing done, then reset
  1102. ;
  1103. WAITNR    EQU    $+OFFSET
  1104.     MVI    L,100    ;WAIT FOR 10 SECS NO RINGING
  1105. ;
  1106. WAITNRL EQU    $+OFFSET
  1107.     CALL    DELAY    ;DELAY .1 SECONDS
  1108.     IN    RPORT    ;GET THE STATUS
  1109.     ANI    P2RDET    ;STILL RINGING?
  1110.     ENDIF    ;CALLBAK
  1111. ;
  1112.     IF    CALLBAK AND (WD8250 OR IN8251)
  1113.     JNZ    WAITNR    ;YES, WAIT 10 MORE SECONDS
  1114.     ENDIF
  1115. ;
  1116.     IF    CALLBAK AND NOT (WD8250 OR IN8251)
  1117.     JZ    WAITNR    ;YES, WAIT 10 MORE SECONDS
  1118.     ENDIF
  1119. ;
  1120.     IF    CALLBAK
  1121.     DCR    L    ;NO RING, MAYBE WE'RE DONE
  1122.     JNZ    WAITNRL ;NO, LOOP SOME MORE
  1123.     ENDIF
  1124. ;
  1125.     IF    CALLBAK AND USRLOG
  1126.     LXI    H,NONUSR ;RECORD AS VOICE CALL
  1127.     CALL    BOPLOG    ;CALL ROUTINE TO ADD ONE
  1128.     ENDIF        ;CALLBAK AND USRLOG
  1129. ;
  1130.     IF    CALLBAK ;CONTINUE WITH CALLBAK ROUTINES
  1131.     JMP    HANGUP2    ;GO WAIT FOR NEXT CALL
  1132. ;
  1133. EXPECT    EQU    $+OFFSET
  1134.     LXI    H,400    ;40 SECONDS TO WAIT FOR SECOND CALL
  1135. ;
  1136. RELOOK    EQU    $+OFFSET
  1137.     IN    RPORT    ;GET THE STATUS
  1138.     ANI    P2RDET    ;RINGING AGAIN?
  1139.     ENDIF    ;CALLBAK
  1140. ;
  1141.     IF    CALLBAK AND (WD8250 OR IN8251)
  1142.     JNZ    ANSWER    ;YES, GO ANSWER IT
  1143.     ENDIF
  1144. ;
  1145.     IF    CALLBAK AND NOT (WD8250 OR IN8251)
  1146.     JZ    ANSWER    ;YES, GO ANSWER IT
  1147.     ENDIF
  1148. ;
  1149.     IF    CALLBAK
  1150.     CALL    DELAY    ;WAIT .1 SECOND
  1151.     DCX    H    ;ONE LESS COUNT
  1152.     MOV    A,H
  1153.     ORA    L    ;IS COUNT ZERO?
  1154.     JNZ    RELOOK    ;NO, LOOK SOME MORE
  1155.     JMP    HANGUP2    ;COUNT DONE, WAIT FOR NEW CALL
  1156. ;
  1157.     ENDIF        ;END OF CALLBAK ROUTINES
  1158. ;
  1159. ;Setup modem
  1160. ;
  1161. ANSWER    EQU    $+OFFSET
  1162. ;
  1163.     IF    ZCPRT        ;RESET WHEEL STATUS
  1164.     XRA    A        ;WHEN RUNNING ZCPR-T## FOR YOUR CCP.
  1165.     STA    WHEEL
  1166.     ENDIF    ;ZCPRT
  1167. ;
  1168.     IF    USRLOG AND PWRQD ;COUNT # OF LOGON ATTEMPTS
  1169.     LXI    H,OLDUSR    ;GET # OF ATTEMPTS
  1170.     CALL    BOPLOG        CALL ROUTINE TO ADD ONE
  1171.     ENDIF    ;USRLOG AND PWRQD
  1172. ;
  1173.     IF    DCHAYES
  1174.     MVI    A,LS1+LS2+PI+SBS ;8 DATA BITS, NO PARITY, 2 STOP BITS
  1175.     OUT    CR1
  1176.     MVI    A,TXE+OH ;TURN ON CARRIER AND ANSWER PHONE
  1177.     OUT    CR2
  1178.     IN    DATA    ;CLEAR DATA INPUT PORT
  1179.     IN    DATA    ;MAKE SURE IT'S CLEAR
  1180.     CALL    CARCK    ;LOOK FOR CARRIER
  1181.     JC    HANGUP2    ;AWAIT ANOTHER CALLER
  1182. ;
  1183. ;Now test input for baud rate
  1184.     CALL    PATCH    ;PATCH JUMP TABLE
  1185.     CALL    TSTBAUD    ;SEE IF BAUD = 110
  1186.     JZ    WELCOME    ;YES, EXIT
  1187. ;
  1188.     MVI    A,LS1+LS2+PI    ;SET FOR 1 STOP BIT, 8 DATA, NO PARITY
  1189.     OUT    CR1
  1190.     MVI    A,TXE+OH+BRS    ;SET FOR 300 BAUD
  1191.     OUT    CR2
  1192.     CALL    TSTBAUD        ;SEE IF BAUD = 300
  1193.     JZ    WELCOME        ;YES,EXIT
  1194.     ENDIF            ;DCHAYES
  1195. ;
  1196.     IF    PMMI
  1197.     MVI    A,7FH    ;TURN ON DTR
  1198.     OUT    CPORT    ;.. AND SET FILTER VALUE FOR 300 BAUD
  1199.     CALL    DELAY    ;GIVE TIME TO TURN ON
  1200.     MVI    A,P0110+P0ANSW
  1201.     OUT    TPORT    ;ANSWER PHONE
  1202.     CALL    DELAY    ;GIVE TIME FOR ANSWER
  1203.     CALL    UCSTS
  1204.     IN    DPORT    ;CLEAR MODEM PORT
  1205.     IN    DPORT    ;MAKE SURE ITS CLEAR
  1206.     MVI    A,B110    ;SET DIVISOR
  1207.     OUT    RPORT    ;.. TO 110 BAUD RATE
  1208. ;Output value allowing modem to hang up on loss of carrier
  1209.     MVI    A,P0110 ;NORMAL MODE FOR 110 BAUD
  1210.     OUT    TPORT
  1211.     CALL    CARCK    ;LOOK FOR CARRIER
  1212.     JC    HANGUP2 ;AWAIT ANOTHER CALLER
  1213. ;Now test input for baud rate
  1214.     CALL    PATCH     ;PATCH JMP TABLE
  1215.     CALL    TSTBAUD  ;SEE IF BAUD = 110
  1216.     JZ    WELCOME  ;YES, EXIT
  1217. ;
  1218.     MVI    A,P0NORM ;SET FOR 1 STOP BIT, ETC.
  1219.     OUT    TPORT
  1220.     MVI    A,B300     ;SET DIVISOR
  1221.     OUT    RPORT     ;.. TO 300 RATE
  1222.     CALL    TSTBAUD  ;SEE IF BAUD = 300
  1223.     JZ    WELCOME  ;YES, EXIT
  1224. ;
  1225.     MVI    A,B450     ;SET DIVISOR
  1226.     OUT    RPORT     ;.. TO 450 RATE
  1227.     MVI    A,5FH     ;SET FILTER VALUE
  1228.     OUT    CPORT     ;.. FOR > 300
  1229.     CALL    TSTBAUD  ;SEE IF BAUD = 450
  1230.     JZ    WELCOME  ;YES, EXIT
  1231. ;
  1232.     MVI    A,B600     ;SET DIVISOR
  1233.     OUT    RPORT     ;.. TO 600 RATE
  1234.     CALL    TSTBAUD  ;SEE IF BAUD = 600
  1235.     JZ    WELCOME  ;YES, EXIT
  1236. ;
  1237.     MVI    A,B710     ;SET DIVISOR
  1238.     OUT    RPORT     ;.. TO 710 RATE
  1239.     CALL    TSTBAUD  ;SEE IF BAUD = 710
  1240.     JZ    WELCOME  ;YES, EXIT
  1241.     ENDIF         ;PMMI
  1242. ;
  1243.     IF    IN8251
  1244.     MVI    A,BD300     ;LOAD 300 BAUD
  1245.     OUT    BPORT
  1246.     IN    DPORT     ;CLEAR
  1247.     IN    DPORT     ;DATA PORT
  1248.     MVI    A,RSTINS ;RESET USART
  1249.     OUT    CPORT
  1250.     CALL    UDELAY     ;USART DELAY
  1251.     MVI    A,MODINS1 ;1 STOP BIT, ETC.
  1252.     OUT    CPORT
  1253.     CALL    UDELAY     ;USART DELAY
  1254.     MVI    A,ONINS     ;DSR, ETC.
  1255.     OUT    CPORT
  1256.     CALL    CARCK     ;SEE IF CARRIER IS PRESENT
  1257.     JC    HANGUP2
  1258. ;Test input for baud rate
  1259.     CALL    PATCH     ;PATCH JUMP TABLE
  1260.     CALL    TSTBAUD     ;SEE IF 300 BAUD
  1261.     JZ    WELCOME     ;YES, EXIT
  1262. ;
  1263.     MVI    A,BD1200 ;LOAD 1200 BAUD
  1264.     OUT    BPORT
  1265.     CALL    TSTBAUD     ;SEE IF 1200 BAUD
  1266.     JZ    WELCOME     ;YES,EXIT
  1267. ;
  1268.     MVI    A,RSTINS ;RESET USART
  1269.     OUT    CPORT
  1270.     CALL    UDELAY     ;DELAY FOR USART
  1271.     MVI    A,MODINS2 ;2 STOP BITS, ETC.
  1272.     OUT    CPORT
  1273.     CALL    UDELAY     ;DELAY FOR USART
  1274.     MVI    A,ONINS     ;DTR, ETC.
  1275.     OUT    CPORT
  1276.     MVI    A,BD110     ;LOAD 110 BAUD
  1277.     OUT    BPORT
  1278.     CALL    TSTBAUD     ;TEST FOR 110 BAUD
  1279.     JZ    WELCOME
  1280.     ENDIF         ;IN8251
  1281. ;
  1282.     IF    WD8250 AND NOT NORING
  1283. ;
  1284.     MVI    A,MCDTR+MCRTS    ;TURN ON DATA SET, ANSWER PHONE; 
  1285.     OUT    CPORT
  1286.     ENDIF          ;WD8250 AND NOT NORING
  1287. ;
  1288.     IF    WD8250 
  1289.     MVI    A,(LCWLS0+LCWLS1) AND 0FFH ;8 BIT DATA 1 STOP BIT NO PAR
  1290.     OUT    LPORT
  1291.     CALL    PATCH    ;PATCH DRIVERS
  1292. ;
  1293. ;    BAUD RATE SELECTOR
  1294. ;
  1295. TST300:    EQU    $+OFFSET
  1296.     PUSH    D    ;SAVE D/E
  1297.     MVI    D,BR300MS
  1298.     MVI    E,BR300LS
  1299.     CALL    SETBAUD
  1300.     POP    D
  1301.     CALL    TSTBAUD
  1302.     JNZ    TST450
  1303.     CALL    TSTBAUD
  1304.     JZ    WELCOME
  1305. TST450:    EQU    $+OFFSET
  1306.     PUSH    D
  1307.     MVI    D,BR450MS
  1308.     MVI    E,BR450LS
  1309.     CALL    SETBAUD
  1310.     POP    D
  1311.     CALL    TSTBAUD
  1312.     JNZ    TST600
  1313.     CALL    TSTBAUD
  1314.     JZ    WELCOME
  1315. TST600:    EQU    $+OFFSET
  1316.     PUSH    D
  1317.     MVI    D,BR600MS
  1318.     MVI    E,BR600LS
  1319.     CALL    SETBAUD
  1320.     POP    D
  1321.     CALL    TSTBAUD
  1322.     JNZ    TST120
  1323.     CALL    TSTBAUD
  1324.     JZ    WELCOME
  1325. TST120:    EQU    $+OFFSET
  1326.     PUSH    D
  1327.     MVI    D,BR120MS
  1328.     MVI    E,BR120LS
  1329.     CALL    SETBAUD
  1330.     POP     D
  1331.     CALL    TSTBAUD
  1332.     JNZ    BADDO
  1333.     CALL    TSTBAUD
  1334.     JZ    WELCOME
  1335.     ENDIF        ;WD8250 
  1336. ;
  1337. BADDO    EQU     $+OFFSET
  1338.     CALL    UNPATCH  ;RESTORE ORIG BIOS JMP TBL
  1339.     JMP    ANSWER     ;TEST MORE - INVALID BAUD RATE
  1340. ;
  1341.     IF    IN8251
  1342. UDELAY    EQU    $+OFFSET
  1343.     NOP ! NOP ! NOP !
  1344.     RET
  1345.     ENDIF        ;IN8251
  1346. ;
  1347. ;Get the console status when unpatched
  1348. ;
  1349. UCSTS    EQU    $+OFFSET
  1350. ;
  1351.     IF    CPM2
  1352.     MVI    C,DRECTIO ;DIRECT I/O CALL
  1353.     MVI    E,0FFH      ;ASK FOR INPUT
  1354.     CALL    BDOS      ;A=0 IF NO CHAR WAITING
  1355.     RET
  1356.     ENDIF          ;CPM2
  1357. ;
  1358.     IF    NOT CPM2
  1359.     MVI    C,CSTS      ;IN CPM 1.4, WE HAVE TO GET..
  1360.     CALL    BDOS      ;..THE STATUS FIRST
  1361.     ORA    A
  1362.     RZ
  1363.     MVI    C,CI      ;AND THEN THE CHARACTER
  1364.     CALL    BDOS
  1365.     RET
  1366.     ENDIF          ;NOT CPM2
  1367.  
  1368. ;
  1369. ;Following are the USRLOG routines
  1370. ;
  1371.     IF    USRLOG     ;INCLUDE RESET FUNCTIONS
  1372. RESET    EQU    $+OFFSET ;RESET ALL LOGON COUNTERS
  1373.     LXI    H,0    ;ZEROING 16 BIT COUNTERS
  1374.     ENDIF         ;USRLOG
  1375. ;
  1376.     IF    USRLOG AND PWRQD
  1377.     SHLD    OLDUSR    ;RESET ATTEMPT COUNTER
  1378.     ENDIF        ;USRLOG AND PWRQD
  1379. ;
  1380.     IF    USRLOG
  1381.     SHLD    NEWUSR    ;RESET LOGON COUNTER
  1382.     ENDIF        ;USRLOG
  1383. ;
  1384.     IF    USRLOG AND CALLBAK
  1385.     SHLD    NONUSR    ;RESET VOICE COUNTER
  1386.     ENDIF        ;USRLOG AND CALLBAK
  1387. ;
  1388.     IF    USRLOG AND IMSAI
  1389.     MVI    A,0FFH
  1390.     OUT    SENSE    ;RESET IMSAI PANEL DISPLAY
  1391.     ENDIF        ;USRLOG AND IMSAI
  1392. ;
  1393.     IF    USRLOG
  1394.     RET
  1395.     ENDIF        ;USRLOG
  1396. ;
  1397. ;  PRNLOG is called to print out the BYE version
  1398. ; # and USRLOG info. It can be called from
  1399. ; outside the program, using the vector after
  1400. ; MCBOOT.
  1401. ;
  1402. PRNLOG    EQU    $+OFFSET
  1403. ;
  1404.     MVI    C,PRINTF ;PRINT OUT PROG VERSION #
  1405.     LXI    D,VMSG
  1406.     CALL    BDOS
  1407. ;
  1408.     IF    USRLOG AND PWRQD ;PRINT # OF LOGON ATTEMPTS
  1409.     MVI    C,PRINTF
  1410.     LXI    D,ATMSG
  1411.     CALL    BDOS
  1412.     LXI    H,OLDUSR+1 ;PT TO HIGH BYTE
  1413.     CALL    HXOUT
  1414.     ENDIF        ;USRLOG AND PWRQD
  1415. ;
  1416.     IF    USRLOG    ;PRINT # OF LOGONS
  1417.     MVI    C,PRINTF
  1418.     LXI    D,SUMSG
  1419.     CALL    BDOS
  1420.     LXI    H,NEWUSR+1
  1421.     CALL    HXOUT
  1422.     ENDIF        ;USRLOG
  1423. ;
  1424.     IF    USRLOG AND CALLBAK    ;# OF VOICE CALLS
  1425.     MVI    C,PRINTF
  1426.     LXI    D,VCMSG
  1427.     CALL    BDOS
  1428.     LXI    H,NONUSR+1
  1429.     CALL    HXOUT
  1430.     ENDIF        ;USRLOG AND CALLBAK
  1431. ;
  1432.     RET        ;IF NO LOG, NULL PRNLOG ROUTINE
  1433. ;
  1434. USRCHK    EQU    $+OFFSET
  1435.     CALL    PRNLOG    ;GIVE INFO
  1436.     MVI    C,PRINTF
  1437.     LXI    D,RS1MSG
  1438.     CALL    BDOS    ;PROMPT FOR RESUME BYE
  1439. ;
  1440. PRNREL    EQU    $+OFFSET
  1441.     CALL    UCSTS    ;GET REPLY
  1442.     ORA    A
  1443.     JZ    PRNREL    ;WAIT UNTIL ANSWERED
  1444.     CPI    'R'    ;IS ANSWER "R", FOR RESUME?
  1445.     JZ    PRNRES    ;GO DO IT IF SO
  1446.     CPI    'R'+20H    ;TAKE LOWER CASE ALSO
  1447.     JNZ    EXCPM    ;IF NOT "R", WARM BOOT CP/M
  1448. ;
  1449. PRNRES    EQU    $+OFFSET
  1450.     MVI    C,PRINTF
  1451.     LXI    D,RS2MSG
  1452.     JMP    BDOS    ;RESUME VIA BDOS AFTER MSG
  1453. ;
  1454. RS1MSG    EQU    $+OFFSET
  1455.     DB    CR,LF,CR,LF,'Type "R" to resume,'
  1456.     DB    ' anything else to warm boot: $'
  1457. RS2MSG    EQU    $+OFFSET
  1458.     DB    'Resuming...',CR,LF,'$'
  1459. ;
  1460. ;  Here to exit to CP/M
  1461. ;
  1462. EXCPM    EQU    $+OFFSET
  1463. ;
  1464.     IF CCSDISK
  1465. ;
  1466.     CALL    DSKON    ;TURN ON THE DRIVES
  1467. ;
  1468.     ENDIF    ;CCSDISK
  1469. ;
  1470.     IF BYELOW
  1471. ;
  1472.     LXI    H,OLDBD    ;RESET THE OLD BDOS JUMP IN
  1473.     SHLD    WMLOC    ;THE BIOS WARM BOOT ROUTINE
  1474. ;
  1475.     ENDIF        ;BYELOW
  1476. ;    
  1477.     JMP    0000H    ;Warm boot CP/M
  1478. ;
  1479.     IF    USRLOG
  1480. ;
  1481. ;  BOPLOG INCREMENTS THE 16 BIT COUNTER PT'ED AT BY
  1482. ; HL. IF DECIMAL SWITCH IN USE, NUMBER IS KEPT AS
  1483. ; 4 BCD DIGITS.
  1484. ;
  1485. BOPLOG    EQU    $+OFFSET
  1486.     MOV    A,M    ;GET LOW BYTE
  1487.     INR    A    ;INCREMENT
  1488.     ENDIF        ;USRLOG
  1489. ;
  1490.     IF    USRLOG AND DECIMAL
  1491.     DAA        ;DECIMAL ADJUST
  1492.     ENDIF        ;USRLOG AND DECIMAL
  1493. ;
  1494.     IF    USRLOG
  1495.     MOV    M,A    ;REPLACE LOW ORDER
  1496.     RNC        ;IF NO CARRY, BOP DONE
  1497.     INX    H    ; ELSE CARRY TO HIGH ORDER
  1498.     MOV    A,M    ;GET HIGH ORDER
  1499.     INR    A    ; AND BOP IT
  1500.     ENDIF
  1501. ;
  1502.     IF    USRLOG AND DECIMAL
  1503.     DAA        ;DECIMAL ADJUST
  1504.     ENDIF        ;USRLOG AND DECIMAL
  1505. ;
  1506.     IF    USRLOG
  1507.     MOV    M,A    ;REPLACE HIGH ORDER
  1508.     RET        ;CARRY OUT OF HIGH DROPPED
  1509.     ENDIF        ;USRLOG
  1510. ;
  1511.     IF    USRLOG AND PWRQD
  1512. ATMSG    EQU    $+OFFSET
  1513.     DB    CR,LF,'Number of logon attempts: $'
  1514.     ENDIF        ;USRLOG AND PWRQD
  1515. ;
  1516.     IF    USRLOG
  1517. SUMSG    EQU    $+OFFSET
  1518.     DB    CR,LF,'Number of logons: $'
  1519.     ENDIF        ;USRLOG
  1520. ;
  1521.     IF    USRLOG AND CALLBAK
  1522. VCMSG    EQU    $+OFFSET
  1523.     DB    CR,LF,'Number of voice calls: $'
  1524.     ENDIF        ;USRLOG AND CALLBAK
  1525. ;
  1526.     IF    USRLOG
  1527. HXOUT    EQU    $+OFFSET
  1528.     PUSH    H    ;SAVE PTR
  1529.     CALL    HXHAF    ;DO HIGH ORDER HALF OF #
  1530.     POP    H    ;RESTORE PTR
  1531.     DCX    H    ;PT TO LOW, THEN DROP
  1532.             ; IN TO DO LOW HALF
  1533. ;
  1534. HXHAF    EQU    $+OFFSET
  1535.     MOV    A,M    ;GET HALF # IN ACC
  1536.     MOV    B,A    ;SAVE NUMBER
  1537.     RAR        ;ROTATE RIGHT 4 BITS
  1538.     RAR        ;TO MAKE AN ASCII DIGIT
  1539.     RAR
  1540.     RAR
  1541.     CALL    ONEOUT    ;OUTPUT MSH TO CONSOLE
  1542.     MOV    A,B    ;GET NUMBER BACK
  1543. ;
  1544. ONEOUT    EQU    $+OFFSET
  1545.     ANI    0FH    ;GET LSH FOR OUTPUT
  1546.     ADI    90H    ;CVT TO DECIMAL ASCII
  1547.     DAA
  1548.     ACI    40H
  1549.     DAA
  1550.     PUSH    B
  1551.     MVI    C,02H
  1552.     MOV    E,A    ;OUTPUT THE NUMBER
  1553.     CALL    BDOS
  1554.     POP    B
  1555.     RET
  1556.     ENDIF        ;USRLOG
  1557. ;
  1558. ;Welcome to the system
  1559. ;
  1560. WELCOME EQU    $+OFFSET
  1561. ;
  1562.     IF CCSDISK
  1563. ;
  1564.     CALL DSKON    ;TURN ON THE DRIVES
  1565. ;
  1566.     ENDIF    ;CCSDISK
  1567. ;
  1568.     IF    CPM2
  1569.     MVI    A,MAXUSR    ;RESET MAX USER #
  1570.     STA    MXUSR
  1571.     ENDIF    ;CPM2
  1572. ;
  1573.     MVI    A,MAXDRV    ;RESET MAX DRIVE #
  1574.     STA    MXDRV
  1575. ;
  1576.     IF    TIMEOUT
  1577.     MVI    A,TOVALUE    ;RESET TIMEOUT COUNT
  1578.     STA    TOVAL
  1579.     ENDIF    ;TIMEOUT
  1580. ;
  1581.     MVI    A,5    ;Assume this many nulls
  1582.     STA    NULLS    ; in case error
  1583. ;
  1584.     IF     NOT OXGATE
  1585. ;
  1586. GETNULL EQU    $+OFFSET
  1587. ;
  1588.     CALL    ILPRT    ;PRINT THIS MSG:
  1589.     DB    CR,LF
  1590.     DB    'HOW MANY NULLS (0-9) DO YOU NEED? ',0
  1591.     CALL    MINPUT    ;GET VALUE
  1592.     MOV    C,A    ;TO C FOR MOUTPUT
  1593.     CALL    MOUTPUT ;ECHO CHAR
  1594.     MOV    A,C    ;RESTORE VALUE
  1595.     CPI    '0'
  1596.     JC    GETNULL ;BAD, RETRY
  1597.     CPI    '9'+1
  1598.     JNC    GETNULL ;BAD
  1599.     SUI    '0'    ;MAKE BINARY
  1600.     STA    NULLS    ;SAVE COUNT
  1601. ;
  1602.     ENDIF        ;NOT OXGATE
  1603. ;
  1604.     IF    TRAPLC AND (NOT OXGATE)
  1605. GETULC    EQU    $+OFFSET
  1606.     CALL    ILPRT    ;PRINT THIS MSG:
  1607.     DB    CR,LF
  1608.     DB    'CAN YOUR TERMINAL DISPLAY LOWER CASE? ',0
  1609.     MVI    A,20H    ;FORCE CASE CONVERSION FOR NOW
  1610.     STA    ULCSW
  1611.     CALL    MINPUT    ;GET Y OR NO
  1612.     MOV    C,A
  1613.     CALL    MOUTPUT ;ECHO
  1614.     MOV    A,C
  1615.     CPI    'N'
  1616.     JZ    DONEOPT ;WE'RE ALREADY SET UP FOR NO LWR CASE
  1617.     CPI    'Y'
  1618.     JNZ    GETULC    ;WASN'T Y OR N...GO ASK AGAIN
  1619.     XRA    A
  1620.     STA    ULCSW    ;SET FLAG FOR NO CONVERSION
  1621. ;
  1622. DONEOPT EQU    $+OFFSET
  1623.     ENDIF        ;TRAPLC AND (NOT OXGATE)
  1624. ;
  1625.     CALL    ILPRT
  1626.     DB    CR,LF,0
  1627. ;Print the welcome file
  1628.     LXI    H,WELFILN ;SOURCE
  1629.     LXI    D,FCB    ;DESTINATION
  1630.     MVI    B,13    ;LENGTH
  1631.     CALL    MOVE    ;MOVE THE NAME
  1632. ;Set DMA address to 80h
  1633.     LXI    D,80H
  1634.     MVI    C,STDMA
  1635.     CALL    BDOS
  1636. ;
  1637.     IF    CPM2
  1638. ;Set user number for welcome file
  1639.     MVI    C,32
  1640.     MVI    E,WELUSR
  1641.     CALL    BDOS
  1642.     ENDIF        ;CPM2
  1643. ;
  1644. ;Open the welcome file
  1645.     LXI    D,FCB
  1646.     MVI    C,OPEN
  1647.     CALL    BDOS
  1648. ;Did it exist?
  1649.     INR    A    ;A=> 0 MEANS "NO"
  1650.     JZ    PASSINT ;NO WELCOME FILE
  1651. ;Got a file, type it
  1652.     XRA    A    ;GET 0
  1653.     STA    FCBRNO    ;ZERO RECORD #
  1654.     LXI    H,100H    ;GET INITIAL BUFF POINTER
  1655. ;
  1656. ;Type the welcome file
  1657. WELTYLP EQU    $+OFFSET
  1658.     CALL    RDBYTE    ;GET A BYTE
  1659.     CPI    1AH    ;EOF?
  1660.     JZ    PASSINT ;YES, DONE
  1661.     MOV    C,A    ;SETUP FOR TYPE
  1662.     CALL    MOUTPUT ;TYPE THE CHAR
  1663.     CALL    MSTAT    ;CHECK FOR..
  1664.     ORA    A    ;CHAR TYPED?
  1665.     JZ    WELTYLP ;..NO, LOOP
  1666.     CALL    MINPUT    ;..YES, GET CHAR
  1667.     CPI    'C'-40H ;CTL-C?
  1668.     JNZ    WELTYLP ;..NO, LOOP UNTIL EOF
  1669. ;
  1670. ;Get the password
  1671. ;
  1672. PASSINT EQU    $+OFFSET
  1673. ;
  1674.     IF    PWRQD AND IMSAI AND SELPASS 
  1675.     IN    SENSE    ;TURN THE SWITCH UP..
  1676.     ANI    PWDSW    ;..TO REQUIRE THE PASSWORD
  1677.     JZ    NOPASS
  1678.     ENDIF        ;PWRQD AND IMSAI AND SELPASS
  1679. ;
  1680.     IF    PWRQD
  1681.     MVI    D,5    ;5 TRIES AT PASSWORD
  1682. ;
  1683. PASSINP EQU    $+OFFSET
  1684.     CALL    ILPRT
  1685.     DB    CR,LF,'Enter password: ',0
  1686.     LXI    H,PASSWD ;POINT TO PASSWORD
  1687.     MVI    E,0    ;NO MISSED LETTERS
  1688.     IN    DPORT    ;CLEAR OUT GARBAGE
  1689. ;
  1690. PWMLP    EQU    $+OFFSET
  1691.     CALL    MINPUT    ;GET A CHAR
  1692.     CPI    60H    ;LOWER CASE?
  1693.     JC    NOTLC    ;NO,
  1694.     ANI    5FH    ;MAKE UPPER CASE ALPHA
  1695. ;
  1696. NOTLC    EQU    $+OFFSET
  1697.     ENDIF        ;PWRQD
  1698.  
  1699.     IF    DUAL$IO AND PWRQD
  1700.     PUSH    PSW    ;SAVE CHAR INPUT
  1701.     CPI    20H    ;IS CHAR CONTROL?
  1702.     JNC    PWDIS    ;PASS IF DISPLAYABLE
  1703.     MVI    C,'^'    ;IF CONTROL,
  1704.     CALL    CONOUT    ; MAP TO UP-ARROW,
  1705.     POP    PSW    ; THEN DISPLAYABLE
  1706.     PUSH    PSW
  1707.     ADI    40H
  1708. PWDIS    EQU    $+OFFSET
  1709.     MOV    C,A
  1710.     CALL    CONOUT    ;OUTPUT CHAR LOCALLY
  1711.     POP    PSW    ;RESTORE TO ACC
  1712.     ENDIF        ;DUAL$IO AND PWRQD
  1713.  
  1714.     IF    PWRQD
  1715.     CPI    'U'-40H ;CTL-U?
  1716.     JZ    PASSINP ;YES, RE-GET IT
  1717.     CMP    M    ;MATCH PASSWORD?
  1718.     JZ    PWMAT    ;..YES
  1719.     MVI    E,1    ;..NO, SHOW MISS
  1720.     CPI    CR    ;C/R?
  1721.     JNZ    PWMLP    ;..NO, WAIT FOR C/R
  1722. ;
  1723. ;Password didn't match
  1724. ;
  1725. PWNMAT    EQU    $+OFFSET
  1726.     CALL    ILPRT
  1727.     DB    'Incorrect',CR,LF,0
  1728.     DCR    D    ;MORE TRIES?
  1729.     JNZ    PASSINP ;YES
  1730.     JMP    BADPASS ;NO, GO HANG UP
  1731. ;
  1732. ;Character matched in password
  1733. ;
  1734. PWMAT    EQU    $+OFFSET
  1735.     INX    H    ;TO NEXT CHAR
  1736.     CPI    CR    ;END?
  1737.     JNZ    PWMLP    ;..NO, LOOP
  1738. ;End of password.  Any missed chars?
  1739.     MOV    A,E    ;GET FLAG
  1740.     ORA    A
  1741.     JNZ    PWNMAT    ;NOT RIGHT
  1742. ;Password correct
  1743.     ENDIF        ;PWRQD
  1744. ;
  1745. NOPASS    EQU    $+OFFSET
  1746. ;
  1747.     IF     RTC
  1748.     CALL    ILPRT
  1749.     DB    CR,LF,CR,LF,'On at ',0
  1750.     CALL    TIME
  1751.     CALL    ILPRT
  1752.     DB    CR,LF,0
  1753.     ENDIF        ;RTC
  1754. ;
  1755. ;
  1756.     IF    USRLOG    ;COUNT # OF SUCCESSFUL LOGONS
  1757.     LXI    H,NEWUSR ;GET LAST VALUE
  1758.     CALL    BOPLOG    ;CALL ROUTINE TO ADD ONE
  1759.     ENDIF        ;USRLOG
  1760. ;
  1761.     IF    IMSAI AND USRLOG
  1762.     LDA    NEWUSR    ;RE-GET LOW ORDER VALUE
  1763.     CMA        ;INVERT FOR LIGHTS
  1764.     OUT    SENSE    ;DISPLAY ON IMSAI FRONT PANEL
  1765.     ENDIF        ;IMSAI AND USRLOG
  1766. ;
  1767.     IF    BOOTMSG
  1768. ;
  1769.     CALL    ILPRT
  1770.     DB    CR,LF
  1771.     DB    'Please Wait... ' ;BOOT MSG HERE
  1772.     DB    0
  1773.     ENDIF        ;BOOTMSG
  1774. ;
  1775.     IF    COMFILE AND CPM2
  1776.     MVI    C,32
  1777.     MVI    E,COMUSR    ;SWITCH TO COM FILE USER #
  1778.     CALL    BDOS
  1779.     ENDIF        ;COMFILE AND CPM2
  1780. ;
  1781. ;
  1782.     IF    COMFILE
  1783.     MVI    A,20H    ;FOOL THE SYSTEM
  1784.     STA    FCB+1    ;SO THAT COM FILE WILL SEE
  1785.             ;20H AT FCB+1 FOR DEFAULT PURPOSES.
  1786.     LDA    OPTION
  1787.     CPI    'A'    ;SYSOP CAN BYPASS COM FILE BY..
  1788.     JZ    0    ;..TYPING "BYE /A"
  1789.     CPI    'C'    ;OPER CAN ALSO GO TO COM..
  1790.     JNZ    RUNCOM    ;..FILE LOAD WITH "BYE /C"
  1791.     CALL    ILPRT    ;PRINT THIS MESSAGE:'
  1792.     DB    'Loading system...',CR,LF,0
  1793.     CALL    LODCOM
  1794. RUNCOM    EQU    $+OFFSET ;EVERYONE ELSE GETS COM FILE
  1795.     CALL    100H
  1796.     ENDIF        ;COMFILE
  1797. ;
  1798.     JMP    0    ;WARM BOOT NOW FOR "NORMAL" CP/M USE
  1799. ;
  1800. ;TSTBAUD attempts to read a LF or CR, returns with
  1801. ;zero flag if the character read is one of these two.
  1802. ;
  1803. TSTBAUD EQU    $+OFFSET
  1804.     CALL    MINPUT    ;GET CHARACTER FROM MODEM
  1805.     CPI    CR    ;IF A CARRIAGE RETURN...
  1806.     RZ        ;.. RETURN
  1807.     CPI    LF    ;IF A LINEFEED...
  1808.     RZ
  1809.     CPI    'C'-40H    ;IF A CONTROL C
  1810.     RET        ;RET ZERO FLAG, ELSE NOT ZERO
  1811. ;
  1812. ;**************SET WD8250  BAUD RATE************************
  1813. ;
  1814.     IF    WD8250
  1815. ;
  1816. SETBAUD: EQU    $+OFFSET
  1817.     MVI    A,83H    ;SET DLAB
  1818.     OUT    LPORT
  1819.     MOV    A,E    ;GET LSB
  1820.     OUT    DPORT
  1821.     MOV    A,D    ;GET MSB
  1822.     OUT    DPORT+1
  1823.     CPI    04H    ;110?
  1824.     JNZ    ONESTOP    
  1825.     MVI    A,LCWLS0+LCWLS1+LCSTB    ;8 DATA 2 STOP BITS
  1826.     OUT     LPORT
  1827.     JMP    DLOOP
  1828. ONESTOP: EQU    $+OFFSET
  1829.     MVI    A,LCWLS0+LCWLS1
  1830.     OUT     LPORT
  1831. DLOOP:    EQU    $+OFFSET
  1832.     XCHG        ;PUT DIVISOR IN HL
  1833.     DAD H!DAD H!DAD H!DAD H    ;MULTIPLY BY 16
  1834.                 ;SO WE DELAY APPROX 2 CHARS TIMES
  1835. DLOOP1:    EQU    $+OFFSET
  1836.     DCX    H
  1837.     MOV    A,L
  1838.     ORA    H
  1839.     JNZ    DLOOP1
  1840.     XCHG
  1841.     IN    DPORT
  1842.     IN    DPORT
  1843.     RET
  1844. ;
  1845.     ENDIF        ;WD8250
  1846. ;
  1847. ;Loss of connection test
  1848. ;
  1849. CARCK    EQU    $+OFFSET
  1850. ;
  1851.     IF    DCHAYES
  1852. ;
  1853. ;The DC Hayes has a hardware hangup feature, but we won't use it.
  1854. ;Instead, if we detect that there is no carrier upon entry to
  1855. ;this routine, we'll keep checking for 15 seconds to see if the
  1856. ;carrier returns. If so, we'll just continue on. If not, we'll
  1857. ;signal this by setting the carry flag.
  1858. ;
  1859.     IN    STATUS    ;GET MODEM STATUS
  1860.     ANI    CD    ;GOT A CARRIER?
  1861.     JNZ    CARCK2    ;YES, GO ON WITH TESTS
  1862.     PUSH    B    ;PRESERVE SO WE CAN USE IT
  1863.     MVI    B,150    ;SET FOR 15 SECONDS
  1864. ;
  1865. CARLP    EQU    $+OFFSET
  1866.     CALL    DELAY    ;WAIT .1 SECONDS
  1867.     IN    STATUS    ;GET MODEM STATUS
  1868.     ANI    CD    ;HAS CARRIER RETURNED?
  1869.     MOV    A,B    ;PRESERVE COUNTDOWN VALUE
  1870.     POP    B    ;FIX STACK IN CASE ALL IS OK
  1871.     JNZ    CARCK2    ;GOT CARRIER, CONTINUE ON
  1872.     DCR    A    ;COUNT TIME DOWN
  1873.     STC        ;IN CASE THIS IS THE END OF TIME
  1874.     RZ        ;RETURN IF TIMED OUT
  1875.     PUSH    B    ;PRESERVE B
  1876.     MOV    B,A    ;GET COUNTER VALUE IN B
  1877.     JMP    CARLP    ;KEEP CHECKING
  1878.     ENDIF        ;DCHAYES
  1879. ;
  1880.     IF    PMMI
  1881. ;
  1882. ;The PMMI modem automatically hangs up the phone after
  1883. ;15 seconds of loss of carrier, providing you output to
  1884. ;port 0 to allow it (which this program does).
  1885. ;
  1886. ;..so, this routine first checks if the modem has hung up,
  1887. ;and if so, returns with carry set.  If not, it checks for
  1888. ;carrier and returns if carrier is on; otherwise waits for
  1889. ;carrier while still testing for disconnect.
  1890. ;
  1891. ;It tests the PMMI "CTS" (clear to send) bit
  1892. ;which is 0 when there is carrier
  1893. ;
  1894.     IN    RPORT    ;GET STATUS
  1895.     ANI    P2CONN    ;CONNECTED?
  1896.     STC        ;(IN CASE NOT)
  1897.     RNZ        ;HUNG UP.
  1898. ;Still connected, check for carrier
  1899.     IN    RPORT    ;LOOK AT STATUS
  1900.     ANI    P2CTS    ;GET CARRIER DETECT BIT
  1901.     JZ    CARCK2    ;CONTINUE W/TESTS
  1902. ;Loop until either connection lost, or carrier returns
  1903.     JMP    CARCK
  1904.     ENDIF        ;PMMI
  1905. ;
  1906.     IF    IN8251
  1907. ;
  1908. ;Racal-Vadic modem automatically hangs up phone 1 second
  1909. ;after carrier loss.
  1910. ;
  1911.     IN    SPORT    ;GET STATUS
  1912.     ANI    DSR    ;CHECK IF CARRIER ON
  1913.     JNZ    CARCK2    ;YES, CONTINUE ON
  1914.     STC        ;SET CARRY BIT FOR NO CARRIER
  1915.     RET
  1916.     ENDIF        ;IN8251
  1917. ;
  1918.     IF     WD8250
  1919. ;THE WD8250 HAS HARDWARE HANGUP. BUT WE WILL USE CARRIER DETECT
  1920. ;ROUTINE TO DETERMINE CARRIER LOSS AFTER 15 SECONDS.......
  1921.     IN    MSPORT    ;GET MODEM STATUS
  1922.     ANI    P2CTS    ;GOT A CARRIER
  1923.     JNZ    CARCK2    ;YES, GO ON WITH TESTS
  1924.     PUSH    B    ;PRESERVE SO WE CAN USE IT
  1925.     MVI    B,150    ;SET FOR 15 SECONDS
  1926. ;
  1927. CARLP    EQU    $+OFFSET
  1928. ;
  1929.     CALL    DELAY    ;WAIT .1 SECOND
  1930.     IN    MSPORT    ;GET MODEM STATUS
  1931.     ANI    P2CTS    ;HAS CARRIER RETURNED ?
  1932.     MOV    A,B    ;PRESERVE COUNT DOWN VALUE
  1933.     POP    B    ;FIX STACK IF ALL IS OK
  1934.     JNZ    CARCK2    ;HAVE CARRIER - CONTINUE
  1935.     DCR    A    ;COUNT DOWN TIME
  1936.     STC        ;IN CASE THIS IS THE END OF TIME
  1937.     RZ        ;RETURN IF TIMED OUT
  1938.     PUSH    B    ;PRESERVE B
  1939.     MOV    B,A    ;GET COUNTER VALUE IN B
  1940.     JMP    CARLP    ;CONTINUE - KEEP CHECKING
  1941.     ENDIF        ;WD8250
  1942.  
  1943. ;Now test drive #'s and (if CP/M 2.x) user #'s to
  1944. ;insure that maximums are not exceeded.
  1945. ;
  1946. CARCK2    EQU    $+OFFSET
  1947.     LDA    4    ;CHECK DISK/USER #
  1948.     ANI    0FH    ;ISOLATE DRIVE
  1949.     PUSH    H    ;SAVE HL
  1950.     LXI    H,MXDRV    ;PT TO ALLOWED # DRIVES
  1951.     CMP    M    ;VALID DRIVE?
  1952.     JC    CARCK3    ;YES, SKIP THIS JUNK
  1953.     LDA    4    ;GET WHOLE LOGIN BYTE
  1954.     ANI    0F0H    ;RETAIN USER # & FORCE DRIVE TO A
  1955.     STA    4    ;UPDATE LOGIN BYTE
  1956.     CALL    ILPRT    ;TELL USER WHAT HE DID
  1957.     DB    'A>',0
  1958.     JMP    0    ;WARM BOOT
  1959. ;
  1960. CARCK3    EQU    $+OFFSET
  1961. ;
  1962.     IF    CPM2
  1963.     LDA    4    ;GET LOGIN BYTE
  1964.     ANI    0F0H    ;ISOLATE USER #
  1965.     RRC        ;MOVE TO LOW BITS
  1966.     RRC
  1967.     RRC
  1968.     RRC
  1969.     LXI    H,MXUSR    ;PT TO MAX USER #
  1970.     CMP    M    ;VALID USER #?
  1971.     JC    CARCK4    ;YES, DON'T CHANGE
  1972.     JZ    CARCK4
  1973.     LDA    4    ;GET LOGIN BYTE AGAIN
  1974.     ANI    0FH    ;KEEP DRIVE, ZERO USER
  1975.     STA    4    ;UPDATE LOGIN BYTE
  1976.     CALL    ILPRT    ;TELL HIM WHAT HAPPENED
  1977.     DB    '> [Invalid user number, returning to 0]',0
  1978.     JMP    0    ;WARM BOOT
  1979.     ENDIF        ;CPM2
  1980. ;
  1981. CARCK4    EQU    $+OFFSET
  1982.     POP    H    ;RESTORE HL
  1983.     ORA    A
  1984.     RET
  1985. ;
  1986. ;.1 sec delay routine
  1987. ;
  1988. DELAY    EQU    $+OFFSET
  1989.     PUSH    B
  1990. ;
  1991.     IF    FASTCLK
  1992.     LXI    B,16667 ;4 MHZ TIMING CONSTANT
  1993.     ENDIF
  1994. ;
  1995.     IF    NOT FASTCLK
  1996.     LXI    B,8334    ;2 MHZ TIMING CONSTANT
  1997.     ENDIF
  1998. ;
  1999. DELAY1    EQU    $+OFFSET
  2000.     DCX    B
  2001.     MOV    A,B
  2002.     ORA    C
  2003.     JNZ    DELAY1
  2004.     POP    B
  2005.     RET
  2006. ;
  2007. ;50 ms delay routine
  2008. ;
  2009. KDELAY    EQU    $+OFFSET
  2010.     PUSH    B
  2011. ;
  2012.     IF    FASTCLK
  2013.     LXI    B,8334
  2014.     ENDIF
  2015. ;
  2016.     IF    NOT FASTCLK
  2017.     LXI    B,4167
  2018.     ENDIF
  2019. ;
  2020.     JMP    DELAY1
  2021. ;
  2022. ;Patch in the new JMP table (saving the old)
  2023. ;
  2024. PATCH    EQU    $+OFFSET
  2025.     CALL    TBLADDR        ;CALC HL= CP/M JMP TABLE
  2026.     LXI    D,VCOLDBT    ;POINT TO SAVE LOCATION
  2027.     MVI    B,24        ;SAVE ALL VECTORS
  2028.     CALL    MOVE        ;MOVE IT
  2029. ;Now move new JMP table to CP/M
  2030.     CALL    TBLADDR        ;CALC HL=CP/M'S JMP TABLE
  2031.     XCHG            ;MOVE TO DE
  2032.     LXI    H,NEWJTBL    ;POINT TO NEW
  2033.     CALL    MOVE        ;MOVE IT
  2034. ;
  2035.     IF    IN8251
  2036.     LXI    H,NWBCALL    ;POINT TO NEW CALL
  2037.     SHLD    WBCALL+1    ;MODIFY CALL IN BIOS
  2038.     ENDIF            ;IN8251
  2039. ;
  2040.     RET
  2041. ;
  2042. UNPATCH EQU    $+OFFSET
  2043.     CALL    TBLADDR        ;HL=CP/M'S JMP TABLE
  2044.     XCHG            ;MOVE TO DE
  2045.     LXI    H,VCOLDBT    ;GET SAVED TABLE
  2046.     CALL    MOVE        ;MOVE ORIG BACK
  2047. ;
  2048.     IF    LOSER
  2049.     LXI    H,WMSTRT    ;LOAD OLD CALL LOCATION
  2050.     SHLD    WBCALL+1    ;RESTORE OLD CALL
  2051.     ENDIF            ;LOSER
  2052. ;
  2053.     RET            
  2054. ;
  2055. ;Calculate HL=CP/M's jump table, B=length
  2056. ;
  2057. TBLADDR EQU    $+OFFSET
  2058.     LHLD    1    ;GET BIOS POINTER
  2059.     DCX    H    ;..SKIP
  2060.     DCX    H    ;..TO
  2061.     DCX    H    ;..COLD BOOT
  2062. ;
  2063.     IF    (NOT PRINTER) and (NOT ALLDEV)
  2064.     MVI    B,18    ;BYTES TO MOVE
  2065.     ENDIF        ;NOT PRINTER AND NOT ALLDEV
  2066. ;
  2067.     IF    PRINTER ;RETAIN LIST DEVICE?
  2068.     MVI    B,15    ;DON'T MOVE LISTER JUMP
  2069.     ENDIF        ;PRINTER
  2070. ;
  2071.     IF    ALLDEV    ;THIS PATCHES ALL DEVICES TO PHONE
  2072.     MVI    B,24    ;MOVE ALL JUMPS
  2073.     ENDIF        ;ALLDEV
  2074.  
  2075.     RET
  2076. ;
  2077. ;Move (HL) to (DE), length in (B)
  2078. ;
  2079. MOVE    EQU    $+OFFSET
  2080.     MOV    A,M    ;GET A BYTE
  2081.     STAX    D    ;PUT AT NEW HOME
  2082.     INX    D    ;BUMP POINTERS
  2083.     INX    H
  2084.     DCR    B    ;DEC BYTE COUNT
  2085.     JNZ    MOVE    ;IF MORE, DO IT
  2086.     RET        ;IF NOT,RETURN
  2087. ;
  2088.     IF    LOSER
  2089. NWBCALL    EQU    $+OFFSET
  2090.     CALL    WMSTRT    ;WARM BOOT DISK READ
  2091.     CALL    PATCH    ;FIX BIOS AGAIN AFTER WMSTRT
  2092.     RET
  2093.     ENDIF        ;LOSER
  2094. ;
  2095. ;Common routine to check for carrier lost, called from console out
  2096. ;
  2097. CHECK    EQU    $+OFFSET
  2098. ;
  2099.     IF    MINICK
  2100. ;
  2101.     LDA    IOBYTE    ;GET IOBYTE
  2102.     ANI    80H    ;TEST FOR DISK UPDATE
  2103.     RTN        ;BUSY WAIT UNTIL DONE
  2104. ;
  2105.     ENDIF        ;MINICK
  2106. ;
  2107.     IF    RBBSCK
  2108. ;
  2109.     LDA    WRTLOC    ;GET WRITE IN PROGRESS FLAG
  2110.     ORA    A
  2111.     RNZ        ;BUSY WAIT UNTIL DONE
  2112. ;
  2113.     ENDIF        ;RBBSCK
  2114. ;
  2115.     CALL    CARCK    ;SEE IF CARRIER STILL ON
  2116.     RNC        ;ALL OK
  2117. ;
  2118. ;Carrier is lost.  Type message so local console shows the reason
  2119. ;
  2120. BADPASS EQU    $+OFFSET ;COME HERE ON BAD PASSWORD
  2121.     MVI    A,1    ;SHOW CARRIER LOST SO
  2122.     STA    LOSTFLG ;..WE WON'T CK AGAIN
  2123.     LXI    SP,STACK ;ENSURE VALID STACK
  2124.     CALL    ILPRT
  2125.     DB    CR,LF
  2126.     DB    '[Carrier Lost]'
  2127.     DB    CR,LF,'   ',0
  2128.     CALL    UNPATCH ;RESTORE ORIG BIOS JMP TBL
  2129.     XRA    A    ;CLEAR OUT CARRIER..
  2130.     STA    LOSTFLG ;..LOST FLAG
  2131.     JMP    HANGUP
  2132. ;
  2133. ;Readbyte routine - used to read the welcome file
  2134. ;
  2135. RDBYTE    EQU    $+OFFSET
  2136.     MOV    A,H    ;TIME TO READ?
  2137.     ORA    A    ;..IF AT 100H
  2138.     JZ    NORD    ;NO READ REQ'D
  2139. ;Have to read a sector
  2140.     LXI    D,FCB
  2141.     MVI    C,READ
  2142.     CALL    BDOS
  2143.     ORA    A    ;OK?
  2144.     MVI    A,1AH    ;FAKE UP EOF
  2145.     RNZ        ;RET EOF IF BAD
  2146.     LXI    H,80H
  2147. ;
  2148. NORD    EQU    $+OFFSET
  2149.     MOV    A,M    ;GET CHAR
  2150.     INX    H    ;TO NEXT
  2151.     RET
  2152. ;
  2153. ;Keyboard/modem status test routine
  2154. ;
  2155. MSTAT    EQU    $+OFFSET
  2156. ;
  2157.     CALL    CHECK    ;CHECK FOR CARRIER LOST
  2158. ;
  2159.     IF    DUAL$IO ;WANT LOCAL CONSOLE?
  2160.     CALL    CONSTAT ;GET LOCAL STATUS
  2161.     ORA    A
  2162.     RNZ        ;RET IF LOCAL CHAR
  2163.     ENDIF        ;DUAL$IO
  2164. ;
  2165.     IF    DCHAYES
  2166.     IN    STATUS    ;GET MODEM STATUS
  2167.     ANI    RRF    ;GOT A CHARACTER?
  2168.     RZ        ;RETURN IF NOT
  2169.     IN    STATUS    ;GET MODEM STATUS
  2170.     ANI    FE+OE    ;CHECK FOR FRAMING AND OVERRUN ERROR
  2171.     JZ    MSTAT1    ;NO ERROR, CHARACTER IS VALID
  2172.     IN    DATA    ;SWALLOW CHARACTER (ALSO CLEAR OE & FE)
  2173.     XRA    A    ;RETURN FALSE
  2174.     RET
  2175.     ENDIF        ;DCHAYES
  2176. ;
  2177.     IF    PMMI
  2178.     IN    TPORT    ;GET STATUS
  2179.     ANI    P0DAV    ;DATA AVAILABLE?
  2180.     RZ        ;RETURN IF NOT READY
  2181.     IN    TPORT    ;GET STATUS
  2182.     ANI    30H    ;CHECK FRAMING AND OVERRUN BITS
  2183.     JZ    MSTAT1    ;NO ERRORS...LEGIT CHARACTER
  2184.     IN    DPORT    ;SWALLOW CHARACTER (CLEARS PODAV)
  2185.     XRA    A    ;RETURN FALSE
  2186.     RET
  2187.     ENDIF        ;PMMI
  2188. ;
  2189.     IF    IN8251
  2190.     IN    SPORT    ;GET STATUS
  2191.     ANI    RCVRDY    ;GOT A CHARACTER
  2192.     RZ        ;RETURN IF NOT
  2193.     IN    SPORT    ;GET STATUS
  2194.     ANI    TOERR    ;CHECK FOR PARITY, FRAMING AND OVERRUN ERRORS
  2195.     JZ    MSTAT1    ;NO ERRORS
  2196.     MVI    A,ONINS    ;RESET ERROR FLAGS
  2197.     OUT    CPORT
  2198.     XRA    A    ;RETURN    FALSE
  2199.     RET
  2200.     ENDIF        ;IN8251
  2201. ;
  2202.     IF    WD8250 
  2203.     IN    SPORT    ;GET STATUS
  2204.     ANI    P0DAV    ;DATA AVAILABLE
  2205.     RZ        ;RTN IF NOT RDY
  2206.     IN    SPORT    ;GET STATUS
  2207.     ANI    0EH    ;CHECK PAR, FRAM ERR AND OVRN BITS
  2208.     JZ    MSTAT1
  2209.     IN    DPORT
  2210.     XRA    A    ;RTN FALSE
  2211.     RET
  2212.     ENDIF        ;WD8250 
  2213. MSTAT1    EQU    $+OFFSET
  2214.     MVI    A,0FFH    ;SHOW READY
  2215.     ORA    A
  2216.     RET
  2217. ;
  2218. ;Modem input function, checks local console first
  2219. ;
  2220. MINPUT    EQU    $+OFFSET
  2221. ;
  2222.     IF    TIMEOUT
  2223.     LDA    TOVAL    ;GET # MINUTES BEFORE TIMEOUT
  2224. ;
  2225. MINPUT0    EQU    $+OFFSET
  2226.     STA    TOCNTM    ;SET MINUTES COUNTER
  2227.     PUSH    H
  2228.     LXI    H,MINUTES ;INIT ONE MINUTE TIMEOUT COUNTER
  2229.     SHLD    TOCNT
  2230.     POP    H
  2231.     ENDIF        ;TIMEOUT
  2232. ;
  2233. MINPUT1 EQU    $+OFFSET
  2234.     LDA    LOSTFLG ;KNOWN LOSS..
  2235.     ORA    A    ;..OF CARRIER?
  2236.     CZ    CHECK    ;CARRIER STILL ON?
  2237.     CALL    MSTAT    ;ANYTHING?
  2238.     ORA    A
  2239. ;
  2240.     IF    NOT TIMEOUT
  2241.     JZ    MINPUT    ;LOOP TILL CHAR RCD
  2242.     ENDIF        ;NOT TIMEOUT
  2243. ;
  2244.     IF    TIMEOUT
  2245.     JNZ    MINPUT2
  2246.     CALL    KDELAY    ;KILL 50 MS
  2247.     PUSH    H
  2248.     LHLD    TOCNT    ;KNOCK DOWN TIMEOUT COUNTER
  2249.     DCX    H
  2250.     SHLD    TOCNT
  2251.     MOV    A,H
  2252.     ORA    L
  2253.     POP    H
  2254.     JNZ    MINPUT1 ;STILL TIME LEFT..KEEP TRYING
  2255.     LDA    TOCNTM    ;COUNT OFF LAST MINUTE
  2256.     DCR    A
  2257.     JNZ    MINPUT0    ;GO BACK IF TIME LEFT
  2258.     CALL    ILPRT
  2259.     DB    '[Input timed out]',7,7,0
  2260.     JMP    NOSLASH
  2261.     ENDIF        ;TIMEOUT
  2262. ;
  2263. MINPUT2 EQU    $+OFFSET
  2264. ;
  2265.     IF    DUAL$IO ;BOTH LOCAL AND REMOTE
  2266.     CALL    CONSTAT ;CHECK LOCAL CONSOLE
  2267.     ORA    A    ;CHAR?
  2268.     JNZ    CONIN    ;..YES, READ IT, RET.
  2269.     ENDIF
  2270. ;
  2271. ;Local console wasn't ready, so read modem
  2272. ;
  2273.     IN    DPORT    ;GET DATA BYTE
  2274.     ANI    7FH    ;DELETE PARITY
  2275.     JZ    MINPUT    ;IGNORE NULLS
  2276. ;
  2277.     IF    IMSAI AND HARDLOG
  2278.     PUSH    B
  2279.     MOV    B,A
  2280.     IN    SENSE
  2281.     ANI    LOGSW
  2282.     MOV    A,B
  2283.     POP    B
  2284.     JZ    NOLOG
  2285.     ENDIF        ;IMSAI AND HARDLOG
  2286. ;
  2287.     IF    HARDLOG
  2288.     CPI    20H
  2289.     JNC    MINPUT3
  2290.     CPI    CR
  2291.     JNZ    NOLOG
  2292. ;
  2293. MINPUT3    EQU    $+OFFSET
  2294.     CALL    LISTOUT ;ECHO ON PRINTER
  2295.     CPI    CR
  2296.     JNZ    NOLOG    ;CR NEEDS LINEFEED
  2297.     MVI    A,LF
  2298.     CALL    LISTOUT ;SO SEND IT
  2299.     MVI    A,CR    ;GET BACK CR
  2300.     ENDIF        ;END OF HARDLOG
  2301. ;
  2302. NOLOG    EQU    $+OFFSET
  2303. ;
  2304.     CPI    3    ;IS IT CONTROL-C?
  2305.     RNZ        ;NO, PASS IT THRU
  2306.     LDA    0    ;SEE IF WARM BOOT DISABLED
  2307.     CPI    0C3H    ;JMP MEANS WARM BOOT OK
  2308.     MVI    A,3    ;SO RETURN CONTROL-C
  2309.     RZ
  2310.     XRA    A    ;ELSE CONVERT TO NULL
  2311.     RET
  2312. ;
  2313. ;Modem output function
  2314. ;
  2315. MOUTPUT EQU    $+OFFSET
  2316. ;
  2317. ;If we already know carrier is lost, don't check
  2318. ;for it again or loop trying to output.
  2319. ;
  2320.     LDA    LOSTFLG ;KNOWN LOSS OF CARRIER?
  2321.     ORA    A
  2322.     JNZ    SILENT    ;AVOID LOOP IN CASE CARRIER LOST
  2323.     CALL    CHECK    ;CARRIER STILL ON?
  2324. ;
  2325.     IF    DCHAYES
  2326.     IN    STATUS    ;GET MODEM STATUS
  2327.     ANI    TRE    ;TRANSMIT BUFFER EMPTY?
  2328.     ENDIF        ;DCHAYES
  2329. ;
  2330.     IF    PMMI
  2331.     IN    TPORT    ;GET MODEM STATUS
  2332.     ANI    P0TBMT    ;TRANSMIT BUFFER EMPTY?
  2333.     ENDIF        ;PMMI
  2334. ;
  2335.     IF    IN8251
  2336.     IN    SPORT    ;GET MODEM STATUS
  2337.     ANI    TRNRDY    ;TRANSMIT BUFFER EMPTY?
  2338.     ENDIF        ;IN8251
  2339. ;
  2340.     IF    WD8250 
  2341.     IN    SPORT
  2342.     ANI    P0TBMT
  2343.     ENDIF        ;WD8250 
  2344. ;
  2345.     JZ    MOUTPUT ;LOOP IF NOT READY
  2346. ;
  2347.     IF    IMSAI AND BLKOUT AND DUAL$IO
  2348.     IN    SENSE    ;FLIP SWITCH UP...
  2349.     ANI    BLACKSW ;..TO BLIND REMOTE USER
  2350.     JNZ    SILENT
  2351.     ENDIF        ;IMSAI AND BLKOUT AND DUAL$IO
  2352. ;
  2353.     MOV    A,C    ;GET CHAR
  2354.     ANI    7FH    ;STRIP PARITY BIT
  2355. ;
  2356.     IF    TRAPLC
  2357.     CPI    60H    ;CHECK FOR LOWER CASE
  2358.     JC    MOUTP2    ;SKIP IF NOT LC
  2359.     CPI    7FH    ;CHECK FOR RUBOUT
  2360.     JZ    MOUTP2
  2361.     PUSH    H
  2362.     LXI    H,ULCSW ;SUBTRACT EITHER 20H OR 0
  2363.     SUB    M
  2364.     POP    H
  2365.     MOV    C,A    ;FORCE ON LOCAL AS WELL AS REMOTE
  2366. ;
  2367. MOUTP2    EQU    $+OFFSET
  2368.     ENDIF        ;TRAPLC
  2369. ;
  2370.     OUT    DPORT    ;OUTPUT TO MODEM
  2371. ;
  2372. SILENT    EQU    $+OFFSET
  2373. ;
  2374.     IF    DUAL$IO ;TO LOCAL ALSO?
  2375.     PUSH    PSW    ;SAVE CHAR
  2376.     CALL    CONOUT    ;SEND TO REGULAR BIOS
  2377.     POP    PSW    ;GET CHAR AGAIN
  2378.     ENDIF        ;DUAL$IO
  2379. ;
  2380. ;Check for nulls
  2381.     CPI    LF    ;TIME FOR NULLS?
  2382.     RNZ        ;NO, RETURN
  2383. ;Send nulls if required
  2384.     LDA    NULLS    ;GET COUNT
  2385.     ORA    A    ;ANY?
  2386.     RZ        ;..NO
  2387.     PUSH    B
  2388.     MOV    B,A    ;SAVE COUNT
  2389.     MVI    C,0    ;0 IS A NULL
  2390. ;
  2391. NULLP    EQU    $+OFFSET
  2392.     CALL    MOUTPUT ;TYPE A NULL
  2393.     DCR    B    ;MORE?
  2394.     JNZ    NULLP    ;..YES, LOOP
  2395.     POP    B
  2396.     MVI    C,LF    ;RESTORE LF
  2397.     RET
  2398. ;
  2399. ;Boot trap - becomes disconnect if JMP at 0 has been altered
  2400. ;
  2401. MBOOT    EQU    $+OFFSET
  2402.     LDA    0    ;LOOK AT OPCODE
  2403.     CPI    0C3H    ;IS IT STILL JMP?
  2404.     JZ    VWARMBT ;YES, ALLOW IT
  2405.     JMP    NOSLASH ;NO, DISCONNECT
  2406. ;
  2407. ;Inline print routine
  2408. ;
  2409. ILPRT    EQU    $+OFFSET
  2410.     XTHL        ;SAVE HL, GET MSG
  2411.     PUSH    B    ;SAVE BC REGS
  2412. ;
  2413. ILPLP    EQU    $+OFFSET
  2414.     MOV    C,M    ;GET CHAR
  2415.     CALL    MOUTPUT ;OUTPUT IT
  2416.     INX    H    ;POINT TO NEXT
  2417.     MOV    A,M    ;TEST
  2418.     ORA    A    ;..FOR END
  2419.     JNZ    ILPLP
  2420.     POP    B    ;RESTORE BC REGS
  2421.     XTHL        ;RESTORE HL, RET ADDR
  2422.     RET        ;RET PAST MSG
  2423. ;
  2424.     IF    PWRQD    ;KEEP PASSWORD HERE
  2425. ;Access password (ends in carriage return)
  2426. ;
  2427. PASSWD    EQU    $+OFFSET
  2428.     DB    'TWIT'    ;THE PASSWORD ITSELF
  2429.     DB    CR    ;END OF PASSWORD
  2430. ;Allow room for bigger password to be patched in
  2431.     DB    0,0,0,0,0,0,0,0,0,0,0,0,0
  2432.     ENDIF        ;PWRQD
  2433. ;
  2434. ;Routine to load the COM file
  2435. ;
  2436.     IF    COMFILE
  2437. LODCOM    EQU    $+OFFSET
  2438.     XRA    A    ;INITIALIZE FCB
  2439.     STA    COMFCB
  2440.     LXI    H,COMFCB+12
  2441.     MVI    B,21
  2442. ;
  2443. ZLOOP    EQU    $+OFFSET
  2444.     MVI    M,0
  2445.     INX    H
  2446.     DCR    B
  2447.     JNZ    ZLOOP
  2448. ;
  2449.     MVI    C,OPEN    ;NOW OPEN THE FILE
  2450.     LXI    D,COMFCB
  2451.     CALL    BDOS
  2452.     INR    A    ;SHOULD BE NON-ZERO
  2453.     JZ    ABORT    ;NO FILE, ABORT
  2454. ;
  2455. ;Now load the file
  2456.     LHLD    6    ;GET TOP OF MEMORY
  2457.     LXI    D,-80H    ;RECORD LOADS CAN'T START..
  2458.     DAD    D    ;..ABOVE (BDOS) - 80H
  2459.     PUSH    H    ;SAVE ON STACK
  2460. ;
  2461.     LXI    D,80H    ;TPA-80H
  2462.     LXI    B,0    ;KEEP A RECORD COUNTER
  2463.     PUSH    B    ;SAVE COUNTER
  2464.     PUSH    D    ;AND LOAD ADDRESS
  2465. ;
  2466. GLOOP    EQU    $+OFFSET
  2467.     POP    D    ;GET TPA ADRS
  2468.     LXI    H,80H    ;POINT TO NXT ADRS TO READ TO
  2469.     DAD    D    ;HL HAS THE ADDRESS
  2470.     POP    B    ;INCREMENT THE COUNTER
  2471. ;Check for load past top-of-memory
  2472.     POP    D    ;GET (TOP-OF-MEMORY)
  2473.     PUSH    D    ;RE-SAVE FOR NEXT TIME
  2474.     MOV    A,E    ;SUBTRACT: (TOP) - (ADRS)
  2475.     SUB    L
  2476.     MOV    A,D    ;ONLY THE CARRY NEEDED
  2477.     SBB    H
  2478.     JNC    SIZEOK    ;CY= BETTER MOVCPM
  2479.     CALL    ERRXIT    ;SO TELL THE STORY
  2480.     DB    '[Program area too small]','$'
  2481. ;
  2482. SIZEOK    EQU    $+OFFSET
  2483.     INX    B
  2484.     PUSH    B
  2485.     PUSH    H    ;SAVE TPA ADRS
  2486.     XCHG        ;ALIGN REGISTERS
  2487.     MVI    C,STDMA ;TELL BDOS WHERE TO PUT RECORD
  2488.     CALL    BDOS
  2489.     LXI    D,COMFCB ;NOW READ THE RECORD
  2490.     MVI    C,READ
  2491.     CALL    BDOS
  2492.     ORA    A
  2493.     JZ    GLOOP    ;A=0 IF MORE TO READ
  2494.     POP    B    ;UNJUNK STACK
  2495.     POP    B    ;THIS IS OUR COUNTER
  2496.     POP    H    ;MORE JUNK ON STACK
  2497.     MOV    A,B    ;CHECK FOR ZERO
  2498.     ORA    C
  2499.     JZ    ABORT    ;WE SHOULD HAVE READ SOMETHING
  2500.     LXI    D,80H    ;WE DID, RESET DMA TO 80H
  2501.     MVI    C,STDMA
  2502.     CALL    BDOS
  2503.     CALL    LOADOK    ;PRINT THIS MSG TO CONSOLE:
  2504.     DB    'COM file loaded',CR,LF,'$'
  2505. ;
  2506. LOADOK    EQU    $+OFFSET
  2507.     POP    D
  2508.     LDA    OPTION    ;SEE IF THIS WAS "BYE /C"
  2509.     CPI    'C'    ;IF IT WAS THEN..
  2510.     RZ        ;..DON'T PRINT MESSAGE
  2511.     MVI    C,PRINTF
  2512.     CALL    BDOS
  2513.     RET
  2514. ;
  2515. ABORT    EQU    $+OFFSET
  2516.     CALL    ERRXIT
  2517.     DB    CR,LF
  2518.     DB    '[Cannot find COM file]','$'
  2519. ;
  2520. ERRXIT    EQU    $+OFFSET
  2521.     POP    D
  2522.     MVI    C,PRINTF
  2523.     CALL    BDOS    ;PRINT THE ABORT MSG
  2524.     JMP    EXCPM    ;WARM BOOT
  2525.     ENDIF        ;COMFILE
  2526. ;
  2527. ;This area is used for vectoring calls to the
  2528. ;user's CBIOS, but saving the registers first
  2529. ;in case they are destroyed.
  2530. ;
  2531. CONSTAT EQU    $+OFFSET
  2532.     PUSH    B
  2533.     PUSH    D
  2534.     PUSH    H
  2535.     CALL    VCONSTAT
  2536.     POP    H
  2537.     POP    D
  2538.     POP    B
  2539.     RET
  2540. ;
  2541. CONIN    EQU    $+OFFSET
  2542.     PUSH    B
  2543.     PUSH    D
  2544.     PUSH    H
  2545.     CALL    VCONIN
  2546. ;
  2547.     IF    FKEYS
  2548.     CALL    CKFUNC
  2549.     ENDIF        ;FKEYS
  2550. ;
  2551.     POP    H
  2552.     POP    D
  2553.     POP    B
  2554.     RET
  2555. ;
  2556. CKFUNC    EQU    $+OFFSET
  2557. ;
  2558.     IF    FKEYS AND IMSAI
  2559.     PUSH    B
  2560.     MOV    B,A    ;SAVE CHAR
  2561.     IN    SENSE    ;READ THE SWITCHES
  2562.     ANI    ENABLF    ;CHECK FKEY ENAB SW
  2563.     MOV    A,B    ;GET CHAR
  2564.     POP    B
  2565.     RZ        ;NO FUNCT IF SW OFF
  2566.     ENDIF        ;FKEYS AND IMSAI
  2567. ;
  2568.     IF    OXGATE
  2569.     CPI    LF    ;WE HAVE A TOGGLE FOR LINE FEEDS
  2570.     JNZ    MOUTP3    ;NOPE, NOT A LF
  2571.     LDA    LFEEDS    ;YES, SEE IF WE CAN SEND IT...
  2572.     ORA    A
  2573.     MVI    A,0
  2574.     RNZ        ;NOPE, DON'T!
  2575.     MVI    A,LF
  2576. MOUTP3    EQU    $+OFFSET
  2577.     ENDIF        ;OXGATE
  2578. ;
  2579.     IF    FKEYS
  2580.     CPI    SYSDKEY
  2581.     JZ    SYSDOWN ;TELL CALLER TO LEAVE
  2582.     CPI    TWITKEY
  2583.     JZ    GOODBY    ;MAKE CALLER LEAVE
  2584.     CPI    MSGKEY
  2585.     RNZ
  2586.     CALL    ILPRT    ;SEND CALLER A MESSAGE
  2587.     DB    'Message from Sysop:',0
  2588.     MVI    A,' '    ;SOMETHING TO RETURN WITH
  2589.     RET
  2590. ;
  2591. SYSDOWN EQU    $+OFFSET
  2592.     CALL    ILPRT
  2593.     DB    'System going down in'
  2594.     DB    ' 5 minutes...',0
  2595.     MVI    A,' '
  2596.     RET
  2597.     ENDIF        ;FKEYS
  2598. ;
  2599. CONOUT    EQU    $+OFFSET
  2600.     PUSH    B
  2601.     PUSH    D
  2602.     PUSH    H
  2603.     CALL    VCONOUT
  2604.     POP    H
  2605.     POP    D
  2606.     POP    B
  2607.     RET
  2608. ;
  2609. LISTOUT    EQU    $+OFFSET
  2610.     PUSH    B
  2611.     PUSH    D
  2612.     PUSH    H
  2613.     PUSH    PSW
  2614.     MOV    C,A
  2615.     CALL    VLISTOUT
  2616.     POP    PSW
  2617.     POP    H
  2618.     POP    D
  2619.     POP    B
  2620.     RET
  2621. ;
  2622. ;This is the JMP table which is copied on top
  2623. ;of the one pointed to by location 1 in CP/M
  2624. ;
  2625. NEWJTBL EQU    $+OFFSET
  2626.     JMP    MCBOOT    ;COLD BOOT
  2627.     JMP    MBOOT    ;WARM BOOT
  2628.     JMP    MSTAT    ;MODEM STATUS TEST
  2629.     JMP    MINPUT    ;MODEM INPUT ROUTINE
  2630.     JMP    MOUTPUT ;MODEM OUTPUT ROUTINE
  2631.     IF    NOT ALLDEV
  2632.     RET        ;DUMMY LIST DEVICE
  2633.     NOP
  2634.     NOP
  2635.     ENDIF        ;NOT ALLDEV
  2636. ;
  2637.     IF    ALLDEV
  2638.     JMP    MOUTPUT    ;MODEM LIST DEVICE
  2639.     JMP    MOUTPUT    ;MODEM PUNCH DEVICE
  2640.     JMP    MINPUT    ;MODEM READER DEVICE
  2641.     ENDIF        ;ALLDEV
  2642. ;
  2643.     IF CCSDISK
  2644. ;
  2645. DSKON    EQU    $+OFFSET
  2646.     PUSH PSW    ;SAVE THE A AND FLAGS
  2647.     MVI A,DISKON    ;VALUE TO TURN ON MOTORS
  2648.     OUT DISK    ;TO THE DISK CONTROLLER
  2649.     PUSH H        ;THIS IS TIMER
  2650.     LXI H,0000H    ;THIS LONG
  2651. DSKLP    EQU    $+OFFSET
  2652.     XTHL
  2653.     XTHL
  2654.     DCX H        ;COUNT LOOP
  2655.     MOV A,H        ;CHECK FOR DONE
  2656.     ORA L
  2657.     JNZ DSKLP
  2658.     POP H        ;RESTORE HL
  2659.     POP PSW        ;AND A & FLAGS
  2660.     RET
  2661. ;
  2662. DSKOFF    EQU    $+OFFSET
  2663.     PUSH PSW    ;SAVE A & FLAG
  2664.     MVI A,DISKOFF    ;VALUE TO TURN MOTORS OFF
  2665.     OUT DISK
  2666.     POP PSW
  2667.     RET
  2668. ;
  2669.     ENDIF        ;CCSDISK
  2670. ;
  2671. IF     RTC
  2672. CLKBASE    EQU    50H    ;BASE OF SYSTEM SUPPORT 1 CARD
  2673. CLKCTL    EQU CLKBASE+10    ;CLOCK CONTROL PORT
  2674. CLKDATA    EQU CLKBASE+11    ;CLOCK DATA PORT
  2675. CREAD    EQU    10H+40H    ;READ COMMAND + HOLD COUNT COMMAND
  2676. ;
  2677. TIME    EQU    $+OFFSET
  2678.     PUSH H
  2679.     PUSH D
  2680.     PUSH B
  2681.     PUSH PSW
  2682.     MVI D,CREAD+5    ;POINT TO 10S OF HOURS
  2683.     MVI B,3        ;3 LOOPS
  2684.     JMP TX        ;START W/ NO SEPARATOR
  2685. ;
  2686. T1    EQU    $+OFFSET
  2687.     MVI C,':'    ;SEPARATOR
  2688.     CALL MOUTPUT    ;TO THE PRINTER
  2689. TX    EQU    $+OFFSET
  2690.     MOV A,D        ;GET THE DIGIT ADDRESS
  2691.     CALL CLOCK    ;GET THE VALUE
  2692.     MOV C,A        ;SAVE IT
  2693.     MVI A,CREAD+5    ;TEST FOR FIRST LOOP
  2694.     CMP D        ;1ST LOOP?
  2695.     MOV A,C        ;RECOVER THE VALUE
  2696.     JNZ T2        ;JUMP IF NOT 1ST LOOP
  2697.     ANI 3        ;DROP PM INDICATOR
  2698. T2    EQU    $+OFFSET
  2699.     ADI '0'        ;ADD ASCII BIAS
  2700.     MOV C,A
  2701.     CALL MOUTPUT    ;AND PRINT IT
  2702.     DCR D        ;POINT TO NEXT DIGIT
  2703.     MOV A,D        ;GET THE DIGIT ADDRESS TO A
  2704.     CALL PCLOCK    ;GET & PRINT ASCII
  2705.     DCR D        ;BUMP DIGIT COUNTER
  2706.     DCR B
  2707.     JNZ T1        ;LOOP TILL ALL PRINTED
  2708. ;
  2709. ;
  2710.     CALL ILPRT    ;PRINT THE TIME ZONE
  2711.     DB ' CST  ',0 ;CENTRAL STANDARD TIME
  2712. ;
  2713. ; WE WILL NOW PRINT THE DAY OF THE WEEK, FOLLOWED
  2714. ; BY THE MONTH, DATE AND YEAR
  2715. ;
  2716. ;
  2717.     MVI A,CREAD+6    ;THIS IS DAY OF WEEK 
  2718.     CALL CLOCK    ;GET THE DAY NUMBER
  2719. ;
  2720. DAYDONE    EQU    $+OFFSET
  2721.     ADD A        ;DOUBLE DAY COUNT
  2722.     LXI H,DAYS    ;POINT TO TABLE
  2723.     MOV E,A        ;ADD OFFSET TO DE
  2724.     MVI D,0
  2725.     DAD D        ;NEW POINTER IN HL
  2726.     MOV A,M        ;GET LO BYTE OF WORD
  2727.     INX H        ;POINT TO HI BYTE
  2728.     MOV H,M        ;TO H
  2729.     MOV L,A        ;PLUS LO BYTE POINTS TO STRING
  2730.     CALL LINOUT    ;PRINT THE DAY
  2731. ;
  2732.     MVI A,CREAD+10    ;10S OF MONTHS
  2733.     CALL CLOCK
  2734.     ORA A        ;WE GOT 10'S OF MONTHS?
  2735.     JZ NOTENS    ;JUMP IF NOT
  2736.     MVI A,10    ;ADD 10S IF WE GOT EM
  2737. NOTENS    EQU    $+OFFSET
  2738.     MOV B,A        ;SAVE 10S IN B
  2739.     MVI A,CREAD+9    ;GET THE ONES
  2740.     CALL CLOCK
  2741.     ADD B        ;ADD TO THE 10S PLACE TO GET MONTH
  2742.     DCR A        ;CORRECT FOR JAN=1
  2743.     ADD A        ;DOUBLE MONTH NUMBER
  2744.     LXI H,MONTHS    ;POINT TO DISPATCH TABLE
  2745.     MOV E,A        ;OFF SET TO DE
  2746.     MVI D,0
  2747.     DAD D        ;POINTER TO STRING AT (HL)
  2748.     MOV A,M        ;GET LO BYTE TO A
  2749.     INX H        ;POINT TO NEXT
  2750.     MOV H,M        ;HI BYTE TO H
  2751.     MOV L,A        ;LO BYTE TO L POINTS TO STRING
  2752.     CALL LINOUT    ;PRINT THE MONTH
  2753. ;
  2754.     MVI A,CREAD+8    ;10S OF DAYS
  2755.     CALL CLOCK
  2756.     ANI 3        ;DROP LEAP YEAR INDICATOR
  2757.     JZ NTENS    ;JUMP IF NO TENS PLACE
  2758.     CALL PASC    ;PRINT IT
  2759. NTENS    EQU    $+OFFSET
  2760.     MVI A,CREAD+7    ;ONES OF DAYS
  2761.     CALL PCLOCK    ;PRINT THEM
  2762.     LXI H,YEAR    ;PLUS YEAR MESSAGE
  2763.     CALL LINOUT    ;TO LISTER
  2764.     MVI A,CREAD+12    ;TENS OF YEAR
  2765.     CALL PCLOCK    ;PRINT THEM
  2766.     MVI A,CREAD+11    ;ONES OF YEAR
  2767.     CALL PCLOCK
  2768.     CALL ILPRT    ;FINISH THE LINE
  2769.     DB CR,LF,CR,LF,0
  2770.     POP PSW
  2771.     POP B
  2772.     POP D
  2773.     POP H
  2774.     RET
  2775. ;
  2776. PCLOCK    EQU    $+OFFSET
  2777.     CALL CLOCK    ;GET THE DIGIT
  2778. PASC    EQU    $+OFFSET
  2779.     ADI '0'        ;ADD ASCII BIAS
  2780.     MOV C,A
  2781.     JMP MOUTPUT    ;AND PRINT
  2782. ;
  2783. CLOCK    EQU    $+OFFSET
  2784.     OUT CLKCTL    ;TELL IT ADDRESS
  2785.     IN CLKDATA    ;GET THE DATA NYBBLE
  2786.     PUSH PSW    ;SAVE THE DATA
  2787.     XRA A        ;GET 0
  2788.     OUT CLKCTL    ;RESET HOLD BIT
  2789.     POP PSW        ;RESTORE DATA
  2790.     RET
  2791. ;
  2792. LINOUT    EQU    $+OFFSET
  2793.     MOV A,M        ;GET THE CHARACTER
  2794.     CPI '$'        ;DONE?
  2795.     RZ        ;RETURN IF DONE
  2796.     MOV C,A        ;ELSE PRINT IT
  2797.     CALL MOUTPUT
  2798.     INX H        ;POINT TO NEXT CHARACTER
  2799.     JMP LINOUT    ;THEN LOOP TILL DONE
  2800. ;
  2801. ;
  2802. SUN    EQU    $+OFFSET
  2803.     DB 'Sunday, $'
  2804. MON    EQU    $+OFFSET
  2805.     DB 'Monday, $'
  2806. TUE    EQU    $+OFFSET
  2807.     DB 'Tuesday, $'
  2808. WED    EQU    $+OFFSET
  2809.     DB 'Wednesday, $'
  2810. THU    EQU    $+OFFSET
  2811.     DB 'Thursday, $'
  2812. FRI    EQU    $+OFFSET
  2813.     DB 'Friday, $'
  2814. SAT    EQU    $+OFFSET
  2815.     DB 'Saturday, $'
  2816. ;
  2817. JAN    EQU    $+OFFSET
  2818.     DB 'January $'
  2819. FEB    EQU    $+OFFSET
  2820.     DB 'February $'
  2821. MAR    EQU    $+OFFSET
  2822.     DB 'March $'
  2823. APR    EQU    $+OFFSET
  2824.     DB 'April $'
  2825. MAY    EQU    $+OFFSET
  2826.     DB 'May $'
  2827. JUN    EQU    $+OFFSET
  2828.     DB 'June $'
  2829. JUL    EQU    $+OFFSET
  2830.     DB 'July $'
  2831. AUG    EQU    $+OFFSET
  2832.     DB 'August $'
  2833. SEP    EQU    $+OFFSET
  2834.     DB 'September $'
  2835. OCT    EQU    $+OFFSET
  2836.     DB 'October $'
  2837. NOV    EQU    $+OFFSET
  2838.     DB 'November $'
  2839. DEC    EQU    $+OFFSET
  2840.     DB 'December $'
  2841. ;
  2842. YEAR    EQU    $+OFFSET
  2843.     DB ', 19$'
  2844. ;
  2845. ;#################################################
  2846. DAYS    EQU    $+OFFSET
  2847.     DW SUN
  2848.     DW MON
  2849.     DW TUE
  2850.     DW WED
  2851.     DW THU
  2852.     DW FRI
  2853.     DW SAT
  2854.     DW SUN
  2855. ;
  2856. MONTHS    EQU    $+OFFSET
  2857.     DW JAN
  2858.     DW FEB
  2859.     DW MAR
  2860.     DW APR
  2861.     DW MAY
  2862.     DW JUN
  2863.     DW JUL
  2864.     DW AUG
  2865.     DW SEP
  2866.     DW OCT
  2867.     DW NOV
  2868.     DW DEC
  2869. ;
  2870. ;
  2871.     ENDIF        ;RTC
  2872. ;
  2873. WELFILN EQU    $+OFFSET
  2874.     DB    0,'WELCOME    ',0
  2875. ;Welcome file name ^^^^^^^^^^^ (must be 11 characters)
  2876. ;
  2877. COMFCB    EQU    $+OFFSET
  2878. ;
  2879.     IF    NOT OXGATE
  2880.     DB    0,'RBBS    COM'
  2881. ;COM file name       ^^^^^^^^^^^ (must be 11 characters)
  2882.     ENDIF        ;NOT OXGATE
  2883. ;
  2884.     IF     OXGATE
  2885.     DB    0,'OXENTR  COM'
  2886. ;COM file name     ^^^^^^^^^^^ (must be 11 characters)
  2887.     ENDIF        ;OXGATE
  2888. ;
  2889. PEND    EQU    $+OFFSET ;END OF RELOCATED CODE
  2890. ;
  2891. ;These areas are not initialized
  2892. ;
  2893.     DS    21    ;REST OF COM FCB
  2894. ;
  2895. OPTION    EQU    $+OFFSET
  2896.     DS    1
  2897. ;
  2898. TOCNTM    EQU    $+OFFSET
  2899.     DS    1
  2900. ;
  2901. TOCNT    EQU    $+OFFSET
  2902.     DS    2
  2903. ;
  2904. ;Byte to keep track of lost carrier when
  2905. ;typing "[Carrier Lost]" so we don't loop
  2906. ;
  2907. LOSTFLG EQU    $+OFFSET
  2908.     DS    1
  2909. ;
  2910. ;Save the CP/M jump table here
  2911. ;
  2912. VCOLDBT EQU    $+OFFSET
  2913.     DS    3
  2914. ;
  2915. VWARMBT EQU    $+OFFSET
  2916.     DS    3
  2917. ;
  2918. VCONSTAT EQU    $+OFFSET
  2919.      DS    3
  2920. ;
  2921. VCONIN     EQU    $+OFFSET
  2922.      DS    3
  2923. ;
  2924. VCONOUT  EQU    $+OFFSET
  2925.      DS    3
  2926. ;
  2927. VLISTOUT EQU    $+OFFSET
  2928.      DS    3
  2929. ;
  2930. VPUNCH    EQU    $+OFFSET
  2931.     DS    3
  2932. ;
  2933. VREADER    EQU    $+OFFSET
  2934.     DS    3
  2935. ;
  2936. ;
  2937. ;
  2938. ;Since these areas are not initialized,
  2939. ;the following counters will not be changed
  2940. ;by subsequent loads of this program
  2941. ;
  2942.     IF    USRLOG
  2943. OLDUSR    EQU    $+OFFSET
  2944.     DS    2
  2945. ;
  2946. NEWUSR    EQU    $+OFFSET
  2947.     DS    2
  2948. ;
  2949. NONUSR    EQU    $+OFFSET
  2950.     DS    2
  2951.     ENDIF        ;USRLOG
  2952. ;
  2953. ;
  2954.     DS    60
  2955. STACK    EQU    $+OFFSET ;LOCAL STACK
  2956. ;
  2957. ENDMARK    EQU    $+OFFSET ;! IGNORE ERROR. THIS MARKS END OF PGM
  2958. ;
  2959. ;BDOS equates
  2960. ;
  2961. CI    EQU    1
  2962. WRCON    EQU    2
  2963. DRECTIO EQU    6
  2964. PRINTF    EQU    9
  2965. CSTS    EQU    11
  2966. OPEN    EQU    15
  2967. READ    EQU    20
  2968. STDMA    EQU    26
  2969. BDOS    EQU    5
  2970. FCB    EQU    5CH 
  2971. FCBRNO    EQU    FCB+32
  2972. ;
  2973.     END
  2974.  
  2975.  
  2976.