home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpmug / cpmug085.ark / BYE79.ASM < prev    next >
Encoding:
Assembly Source File  |  1984-04-29  |  77.7 KB  |  3,387 lines

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