home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / sigmv066.ark / APBYE.ASM < prev    next >
Assembly Source File  |  1984-04-29  |  36KB  |  1,563 lines

  1. ;        APBYE    V6.9 (revised 3/30/81)
  2. ;    REMOTE CONSOLE PROGRAM FOR CP/M AND MODEM
  3. ;
  4. ;This program allows modem callers to use your CP/M system
  5. ;just as if they were seated at the system console.  Special
  6. ;assembly-time options allow limiting the caller's access by
  7. ;password and/or access to only a message-service program.
  8. ;
  9. ;Based on an original program written by Dave Jaffe, January 1979
  10. ;Rewritten for PMMI modem by Ward Christensen, February 1979.
  11. ;
  12. ;MODIFIED FOR DCH MMII
  13. ;BY DAVID MORITZ, MARCH 1981
  14. ;
  15. ;
  16. ;PLEASE NOTIFY ME OF ANY MOD-
  17. ;IFICATIONS:
  18. ;
  19. ;        DAVID MORITZ
  20. ;         2228 N. SAWYER
  21. ;         CGO.,IL. 60647
  22. ;
  23. ;        312 384-4762
  24. ;         (24 HR. MODEM)
  25. ;
  26. ;Thanks to Bill Precht for the "label + offset" idea allowing
  27. ;this program to relocate itself without using DDT to initially
  28. ;set it up.
  29. ;
  30. ;Modifications/fixes: (in reverse order to minimize reading time)
  31. ;
  32. ;03/30/81 COMBINED APBYE12 WITH
  33. ;MODIFIED VERSION OF BYE69.
  34. ;
  35. ;THANKS TO GORDON BANKS FOR THE
  36. ;ADDITION OF 'HIMEM' ROUTINES
  37. ;TO PREVENT TRANSIENT PROGRAMS
  38. ;FROM OVERWRITING BYE BY CHANGING
  39. ;THE JUMP VECTOR IN 6,7 TO BDOS
  40. ;TO ALLOW JUMPING AROUND THE
  41. ;PROGRAM.
  42. ;
  43. ;03/20/81 Fixed MOUTPUT so parity bit is stripped before outputting
  44. ;      character to modem.  Corrected 3/18/81 null fix.  Added
  45. ;      additional description to heading of this file.  (KBP)
  46. ;
  47. ;03/18/81 Add first-ring debounce routine, change PMMI HANGUP
  48. ;      to do break for faster disconnect, fix error in P3TODTR
  49. ;      equate for PMMI, added end-of-program error message to
  50. ;      mark ending address (see note at label DEST). By KBP.
  51. ;      Fix bug that prevented nulls at end of line if DUAL$IO
  52. ;      was true.  By Hank Szyszka.
  53. ;
  54. ;
  55. ;02/17/81 Added check for extraneous control characters in
  56. ;      hardcopy log.  (Formfeed seems to be a common "hit").
  57. ;      Changed local startup test to directly test for carrier
  58. ;      instead of calling CARCK, to avoid 15 second delay.
  59. ;      <BRR>
  60. ;
  61. ;         Rearranged patch list to "most recent first" order.
  62. ;      Added message for invalid-drive test.
  63. ;         Added ANI 7Fh to upper case conversion test so that
  64. ;         it's not fooled by bit 7 being set.
  65. ;         Added WELUSR equate for user # containing WELCOME file.
  66. ;         Removed PTRPORT equate and changed hardcopy logic to
  67. ;         work through the BIOS printer driver. <BRR>
  68. ;
  69. ;01/22/81 Changed carrier detect routine for DC Hayes to wait for
  70. ;      15 seconds after loss of carrier to return. <DAVID KOZINN>
  71. ;
  72. ;      if present.   <DAVID KOZINN>
  73. ;
  74. ;
  75. ;09/23/80 Fixed bugs that prevented "bye /a" and "bye /c" from
  76. ;      working properly.  Also repaired several errors in
  77. ;      conditional assembly nesting.  By Ron Fowler
  78. ;
  79. ;09/20/80 Modified status checking during ring-wait routine to
  80. ;      use cp/m BDOS call, as suggested by Keith Petersen.
  81. ;      This should make the program more portable.  Also
  82. ;      added Bruce Ratoff's update to DCHBYE program (5.5),
  83. ;      that allows the use of bye from non-zero user areas.
  84. ;      By Ron Fowler
  85. ;
  86. ;09/19/80 Modified COM file load routine to prevent BDOS
  87. ;      overwrite if the COM file won't fit in the TPA
  88. ;      By Ron Fowler
  89. ;
  90. ;09/19/80 Added new '/' option C, which has the same affect as
  91. ;      /A, except that /C loads the com file after answering
  92. ;      the phone, while /A boots cp/m.  By Ron Fowler
  93. ;
  94. ;09/19/80 Added conditional assembly to give the operator a
  95. ;      'twit' logout key. Added conditionals for 'message
  96. ;      from operator' and 'system down in 5 minutes' keys.
  97. ;      Added front-panel selection of hard-copy log, remote
  98. ;      'black-out', and password option.  Also, if cpm/2 is
  99. ;      used, a message is printed when an unsupported user
  100. ;      area is entered.  By Ron Fowler and Dave Hardy
  101. ;
  102. ;09/19/80 Modified to prevent re-load of the com file when
  103. ;      a voice call comes in.  Reset the DMA address back
  104. ;      to 80h after the com file is loaded.  By Ron Fowler
  105. ;
  106. ;09/16/80 Added conditional assembly to allow automatic
  107. ;      loading of a com file instead of cp/m boot. Also
  108. ;      added decimal usrlog counters as conditional
  109. ;      assembly.  By Ron Fowler
  110. ;
  111. ;09/15/80 Added conditional assembly for automatic timed
  112. ;      log-out, drive and user number masking, lower
  113. ;      case query at login, and cp/m 2.x.  Thanks to
  114. ;      Bruce Ratoff for the routines (lifted from his
  115. ;      'DCHBYE54.ASM') used to implement these functions
  116. ;      NOTE: in order to implement the timed log-out, it
  117. ;      was necessary to do timing in software loops.
  118. ;      Therefore, a new equate, FASTCLK, has been added
  119. ;      to allow for 4mhz clock speeds. Also added Bruce
  120. ;      Ratoff's overrun/framing error checking when read-
  121. ;      ing the modem port.  By Ron Fowler
  122. ;
  123. ;07/16/80 Added "/R" command option to allow USRLOG
  124. ;      counters to be reset upon entry.  By Dave Hardy
  125. ;
  126. ;07/11/80 Added conditional assembly for password and
  127. ;      user log routines, and routines to print USRLOG
  128. ;      information on console after program exit.
  129. ;      By Dave Hardy
  130. ;
  131. ;07/10/80 Added code to allow auto-answer after first
  132. ;      or second ring for more reliable auto-answer
  133. ;      when using "ringback" option.  By Dave Hardy
  134. ;
  135. ;06/29/80 Added USRLOG routines to keep track of number
  136. ;         OF CALLERS.
  137. ;      By Dave Hardy
  138. ;
  139. ;
  140. ;01/24/80 Added routines to preserve registers when calling
  141. ;      the user's CBIOS.  Added conditional assembly for
  142. ;      callback feature.  Increased stack space to 60.
  143. ;      By Keith Petersen.
  144. ;
  145. ;09/24/79 Added routines to allow automatic multiple baud
  146. ;      rate selection, exit to CP/M from local console,
  147. ;      echo nr. of nulls selected. By Keith Petersen,
  148. ;      with thanks to Bob Mathias for suggestions.
  149. ;
  150. ;05/06/79 Added routine to allow "callback" operation so modem
  151. ;      does not answer normal voice calls.  By Robbin Hough
  152. ;      and Keith Petersen, W8SDZ.
  153. ;
  154. ;------------------------------------------------
  155. ;
  156. ;This program runs up in high RAM.  It gets there
  157. ;by being moved there when 'BYE' is typed.
  158. ;
  159. ;The program in high RAM does the following:
  160. ;
  161. ;    1.    Hangs up the phone
  162. ;    2.    Awaits ring detect, allows exit
  163. ;        to CP/M if local KBD types CTL-C
  164. ;    3.    Outputs carrier (see callback routines)
  165. ;    4.    Awaits incoming carrier going to step 1
  166. ;        if none found in 15 seconds
  167. ;    5.    Asks number of nulls (0-9)
  168. ;    6.    Types the file "WELCOME" from
  169. ;        disk, allowing CTL-C to skip it
  170. ;    7.    Asks for a password, allowing
  171. ;        5 tried to get it right.
  172. ;    8.    When password entered, if used,
  173. ;        drops into CP/M.
  174. ;    9.    Caller can leave by hanging up,
  175. ;        (any time carrier is lost, it
  176. ;        waits 15 seconds, then goes
  177. ;        back to step 1), or the caller
  178. ;        may type the program name (BYE)
  179. ;
  180. ;------------------------------------------------
  181. ;
  182. ;System equates
  183. ;
  184. FALSE    EQU    0
  185. TRUE    EQU    NOT FALSE
  186. CR    EQU    0DH
  187. LF    EQU    0AH
  188. MINUTES    EQU    20*60    ;CONSTANT FOR 1 MIN TIME DELAY
  189. ;
  190. ;Change the following equate to an area in your
  191. ;high memory where this program may patch itself in.
  192. ;Approximate memory requirements: 2k bytes or more,
  193. ;depending upon the options selected.  A marker has
  194. ;been placed at the end to deliberately print an error
  195. ;message during assembly in order to determine the actual
  196. ;ending address of the program.  The error message will
  197. ;not affect the assembly.  Make sure you have memory
  198. ;available up to the address shown.
  199. ;
  200. DEST    EQU    0BE00H    ;RUNNING LOCATION OF CODE
  201. RSET    EQU     0DAF0H  ;WHERE CP/MLOADS THE BDOS ADDRESS
  202. JUMP    EQU     0C3H  ;OP-CODE FOR A JMP
  203. ;
  204. CONDATA EQU     0E000H
  205. ;
  206. ;
  207. ;You will likely also want to change the password,
  208. ;located below at label 'PASSWD', and the messages
  209. ;printed at label 'WELCOME' and just above label
  210. ;'HANGUP'.
  211. ;
  212. ;****************************************************
  213. ;*        Option configuration section        *
  214. ;****************************************************
  215. ;
  216. PRINTER EQU    FALSE    ;WANT TO RETAIN LIST DEVICE?
  217. DUAL$IO EQU    TRUE     ;WANT CONSOLE & MODEM?
  218. CALLBAK EQU    FALSE    ;WANT CALLBACK FEATURE?
  219. PWRQD    EQU    FALSE    ;WANT TO USE PASSWORD?
  220. USRLOG    EQU    TRUE    ;WANT TO COUNT NUMBER OF USERS?
  221. HARDLOG EQU    FALSE    ;WANT TO ECHO REMOTE KBD TO PRINTER?
  222. CPM2    EQU    TRUE    ;USING CP/M 2.x?
  223. MAXUSR    EQU    3    ;SET TO 0 FOR CP/M 1.4
  224. MAXDRV    EQU    3    ;HIGHEST DRIVE SUPPORTED
  225. FASTCLK EQU    FALSE    ;SET TRUE FOR 4 MHZ CLOCK
  226. TIMEOUT EQU    TRUE    ;WANT AUTO LOG-OFF FOR SLEEPY CALLERS?
  227. TOVALUE EQU    3    ;THIS IS 3 MINUTES TO AUTO LOGOUT
  228. WELUSR    EQU    0    ;USER # THAT WELCOME FILE IS KEPT IN
  229. COMFILE EQU    TRUE     ;WANT TO AUTOBOOT A COM FILE?
  230. COMUSR    EQU    0    ;USER # THAT COMFILE IS KEPT IN
  231. DECIMAL EQU    TRUE    ;WANT DECIMAL VALUES FOR LOGS?
  232. TRAPLC    EQU    FALSE    ;WANT TO TRAP LOWER CASE?
  233. ;
  234. ;Special keys for special functions
  235. ;
  236. FKEYS    EQU    TRUE    ;WANT SPECIAL FUNCTION KEYS?
  237. ;
  238. ;Assign function keys to the following control codes (if used):
  239. ;
  240. TWITKEY EQU    'N'-40H ;KEYCODE TO LOG-OUT A CREEP
  241. MSGKEY    EQU    'Q'-40H ;KEYCODE TO PRINT 'MESG FROM OPER:'
  242. SYSDKEY EQU    'O'-40H ;KEYCODE TO PRINT SYS DOWN MSG
  243. ;
  244. ;
  245. ;****************************************************
  246. ;*     End of option configuration section        *
  247. ;****************************************************
  248. ;
  249. ;
  250. ;
  251. ;MMII MODEM ADDRESS EQUATES
  252. ;
  253. TPORT   EQU     0E0A6H ;CONTROL/STATUS PORT
  254. DPORT    EQU    0E0A7H ;DATA PORT
  255. RPORT    EQU    0E0A5H ;RATE GEN/MODEM STATUS
  256. CPORT    EQU    0E0A5H ;MODEM CONTROL
  257. RPORT1  EQU     0E0A6H  ;STATUS
  258. ;
  259. ;Switch hook and modem commands, output to TPORT (port 0)
  260. ;
  261. P0BYE    EQU    0    ;ON HOOK, OR DIALING BREAK
  262. P0ORIG    EQU    8EH    ;OFF HOOK, ORIG.
  263. P0ANSW    EQU    8AH    ;ANSWER PHONE
  264. P0TSB    EQU    08H    ;2 STOP BITS
  265. P0EI    EQU    20H    ;ENABLE INTERRUPTS
  266. P0NORM  EQU     15H     ;NORMAL 8 BITS, NO PARITY
  267. P0110   EQU     11H     ;SAME W/2 STOP BITS
  268. ;
  269. ;Modem status, input on RPORT (port 3)
  270. ;
  271. P2RDET  EQU     80H     ;RING DETECT
  272. P2CTS    EQU    04H    ;CTS (CARRIER DETECT)
  273. ;
  274. ;MMII modem status masks
  275. ;
  276. P0TBMT    EQU    2    ;XMIT BUFF EMPTY
  277. P0DAV    EQU    1    ;DATA AVAILABLE
  278. P0RPE    EQU    40H    ;REC'D PARITY ERR
  279. P0ORUN    EQU    20H    ;OVERRUN
  280. P0FERR    EQU    10H    ;FRAMING ERROR
  281. ;
  282. ;Baud rate divisors
  283. ;
  284. B110    EQU    0    ;110 BAUD
  285. B300    EQU    1    ;300 BAUD
  286. ;
  287. ;
  288. ;
  289. ;
  290. ;---------------------------------------------------------
  291. ;
  292.     ORG    100H
  293. ;
  294. ;Move modem interface program up to high RAM and jump to it
  295. ;
  296. ;BUT FIRST, PROTECT BYE BY RESETTING BDOS JUMPS
  297. ;
  298. HIMEM   LDA     BDOS+2  ;HAS HIMEM ALREADY BEEN SET?
  299.         CPI     0CCH  ;THIS IS WHAT IS NORMALLY THERE
  300.         JZ      CONT  ;STILL CC, SO CONTINUE
  301.         JMP     MOVEUP  ;ELSE SKIP NEXT BIT
  302. CONT    LHLD    BDOS+1  ;LOAD CURRENT BDOS JUMP
  303.         SHLD    DEST-2  ;PUT IN FRONT OF BYE
  304.         MVI     A,JUMP  ;WRITE A JMP OP-CODE IN FRONT OF THAT
  305.         STA     DEST-3
  306.         LXI     H,DEST-3 ;MOVE THE NEW JUMP-TO ADDRESS..
  307.         SHLD    RSET+1  ;..TO THE RESET VECTOR SETTER
  308.         SHLD    BDOS+1  ;AND TO BDOS JUMP ADDRESS
  309. MOVEUP    LXI    B,PEND-START+1        ;NUMBER OF BYTES TO MOVE
  310.     LXI    H,DEST+PEND-START+1 ;END OF MOVED CODE
  311.     LXI    D,SOURCE+PEND-START ;END OF SOURCE CODE
  312. ;
  313. MVLP    LDAX    D    ;GET BYTE
  314.     DCX    H    ;BUMP POINTERS
  315.     MOV    M,A    ;NEW HOME
  316.     DCX    D
  317.     DCX    B    ;BUMP BYTE COUNT
  318.     MOV    A,B    ;CHECK IF ZERO
  319.     ORA    C
  320.     JNZ    MVLP    ;IF NOT, DO SOME MORE
  321. ;
  322.     PUSH    H    ;SAVE FOR LATER JUMP
  323.     MVI    A,0C3H    ;CLEAR ANY TRAPS SO SYSOP..
  324.     STA    0    ;CAN USER "BYE /A"
  325.     XRA    A    ;NEXT WARMBOOT TO USR0/DRV A
  326.     STA    4
  327.     MVI    C,14    ;MAKE DRIVE A DEFAULT
  328.     MOV    E,A    ;LOG-IN DRIVE CP/M FUNCTION
  329.     CALL    BDOS
  330. ;
  331.     IF    CPM2    ;SET USER 0
  332.     MVI    C,32    ;GET/SET USR CP/M FUNCTION
  333.     MVI    E,WELUSR
  334.     CALL    BDOS
  335.     ENDIF        ;CPM2
  336. ;
  337.     RET        ;TO ADRS PUSHED ABOVE
  338. ;
  339. ;
  340. SOURCE    EQU    $    ;BOUNDARY MEMORY MARKER
  341. ;
  342. OFFSET    EQU    DEST-SOURCE ;RELOC AMOUNT
  343. ;
  344. ;-----------------------------------------------;
  345. ;    The following code gets moved        ;
  346. ;    to high RAM located at "DEST",        ;
  347. ;        where it is executed.        ;
  348. ;-----------------------------------------------;
  349. ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  350. ;XX   C A U T I O N :  If modifying anything    XX
  351. ;XX    in this program from here on:        XX
  352. ;XX    A-L-L  labels must be of the form:    XX
  353. ;XX    LABEL    EQU    $+OFFSET        XX
  354. ;XX    in order that the relocation to high      XX
  355. ;XX    RAM work successfully.  Forgetting to    XX
  356. ;XX    specify '$+OFFSET' will cause the pro-    XX
  357. ;XX    gram to JMP into whatever is currently    XX
  358. ;XX    in low memory, with unpredictable    XX
  359. ;XX    results.  Be careful....        XX
  360. ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  361. ;
  362. ;If carrier lost, hang up, await ring.
  363. ;Otherwise, say goodbye, and hang up
  364. ;
  365. START    EQU    $+OFFSET
  366. ;
  367.     XRA    A    ;GET 0
  368.     STA    LOSTFLG ;SHOW NO CARR. LOST
  369. ;
  370. ;Don't allow a remote user to do 'BYE /A'
  371. ;
  372. ;
  373.     LDA    RPORT1    ;AS ABOVE, FOR PMMI MODEM
  374.     ANI    P2CTS    ;CD DEDUCED FROM CTS
  375.     JZ    GOODBY
  376. ;
  377. ;
  378. ;Check for /A option on command - request to
  379. ;go immediately into answer mode
  380.     LXI    H,FCB+1 ;TO OPTION
  381.     MOV    A,M
  382.     CPI    '/'    ;OPTION?
  383.     JNZ    HANGUP
  384. ;Got an option - validate it
  385.     INX    H    ;TO OPTION BYTE
  386.     MOV    A,M    ;GET IT
  387.     STA    OPTION    ;MIGHT NEED LATER
  388.     CPI    'A'    ;ANSWER?
  389.     JZ    ANSWER
  390. ;
  391.     IF    COMFILE
  392.     CPI    'C'
  393.     JZ    ANSWER
  394.     ENDIF        ;COMFILE
  395. ;
  396.     IF    USRLOG    ;CHECK FOR RESET OF COUNTERS
  397.     CPI    'R'
  398.     CZ    RESET
  399.     ENDIF        ;USRLOG
  400. ;
  401.     JMP    HANGUP    ;WE KNOW IT'S LOCAL, SO SKIP CALL TO CARCK
  402. ;
  403. ;No option, or invalid one
  404. ;
  405. NOSLASH EQU    $+OFFSET
  406.     CALL    CARCK    ;SIGNED OFF W/THIS PROG?
  407.     JC    HANGUP    ;NOBODY THERE
  408. ;
  409. GOODBY    EQU    $+OFFSET
  410.     CALL    ILPRT    ;PRINT THIS MSG:
  411.     DB    CR,LF,'GOOD BYE, CALL AGAIN'
  412.     DB    CR,LF,CR,LF,0
  413.     CALL    UNPATCH ;UNDO BIOS PATCHES
  414. ;
  415. ;Nobody there, or we are done, so hang up
  416. ;
  417. HANGUP    EQU    $+OFFSET
  418.     LXI    SP,STACK ;SET UP LOCAL STACK
  419.     XRA    A     ;FORCE NEXT WARMBOOT TO USER 0
  420.     STA    4     ;AND DRIVE A
  421.     MVI    C,14     ;MAKE DRIVE A DEFAULT
  422.     MOV    E,A
  423.     CALL    BDOS
  424.     MVI    A,' '     ;DON'T ALLOW OPTIONS..
  425.     STA    OPTION     ;..AFTER 1 "BYE / <ANYTHING>"
  426. ;
  427.     IF    CPM2 AND COMFILE
  428.     MVI    C,32     ;GET/SET USER CODE
  429.     MVI    E,COMUSR ;LOCATION OF OUR COMFILE
  430.     CALL    BDOS
  431.     ENDIF         ;CPM2 AND COMFILE
  432. ;
  433.     IF    COMFILE
  434.     CALL    LODCOM    ;LOAD THE COM FILE
  435.     ENDIF        ;COMFILE
  436. ;
  437. ;
  438. HANGUP2 EQU    $+OFFSET
  439. ;
  440. ;Clear DTR causing phone to hang up
  441. ;
  442. ;
  443.     XRA    A    ;GET DISCONNECT VALUE
  444.     STA    TPORT    ;RESET ORIG/ANSW
  445.     STA    CPORT    ;TURN OFF DTR, DO BREAK
  446. ;
  447. ;
  448. ;
  449.     MVI    A,0C3H    ;CLEAR ANY TRAPS..
  450.     STA    0    ;..LEFT FROM COM FILE
  451. ;
  452. ;Await ringing
  453. ;
  454. RINGWT    EQU    $+OFFSET
  455. ;
  456. ;Check local keyboard for CTL-C exit request.
  457. ;NOTE: Must do input via BDOS because CBIOS patches
  458. ;are not done until call comes in.
  459.         LDA     CONDATA
  460.     ANI    7FH    ;STRIP PARITY BIT
  461.     CPI    'C'-40H ;CONTROL C?
  462. ;
  463.     IF    NOT USRLOG
  464.     JZ    0    ;YES, --EXIT-- TO CP/M
  465.     ENDIF        ;NOT USRLOG
  466. ;
  467.     IF    USRLOG    ;PRINT OUT USER INFO
  468.     JZ    PRNLOG
  469.     ENDIF        ;USRLOG
  470. ;
  471. RINGW2    EQU    $+OFFSET
  472.     LDA    RPORT    ;GET THE STATUS
  473.     ANI    P2RDET    ;RINGING?
  474.     JNZ    RINGWT    ;NO, WAIT
  475. ;
  476. ;The phone may be ringing.  Wait .1 sec and look
  477. ;again to make sure it isn't just relay bounce
  478.     CALL    DELAY    ;.1 SEC DELAY FOR DEBOUNCE
  479.     LDA    RPORT    ;GET STATUS
  480.     ANI    P2RDET    ;STILL RINGING?
  481.     JNZ    RINGWT    ;NO, IT WAS RELAY BOUNCE
  482. ;
  483. ;The phone is definitely ringing, now wait until ring is finished
  484. ;
  485. ENDRING EQU    $+OFFSET
  486.     CALL    DELAY    ;.1 SEC DELAY FOR DEBOUNCE
  487.     LDA    RPORT    ;GET STATUS
  488.     ANI    P2RDET    ;STILL RINGING?
  489.     JZ    ENDRING ;WAIT UNTIL RING FINISHED
  490. ;
  491.     IF    CALLBAK ;NEXT ROUTINES IMPLEMENT CALLBACK
  492. ;
  493. ;This routine minimizes the computer's interference
  494. ;with normal househole phone use by having computer
  495. ;folk dial, let the phone ring once, hang up and 
  496. ;then dial again.  When the phone rings only once it
  497. ;alerts the computer which then waits for and answers
  498. ;any ring which occurs within the next 40 seconds.
  499. ;
  500.     MVI    L,45    ;DELAY 4.5 SECONDS FOR NEXT RING
  501. ;
  502. WAITNX    EQU    $+OFFSET
  503.     CALL    DELAY    ;WAIT .1 SECONDS
  504.     DCR    L    ;MORE TO GO?
  505.     JNZ    WAITNX    ;YES, LOOP
  506.     LDA    RPORT    ;GET THE STATUS
  507.     ANI    P2RDET    ;RINGING AGAIN?
  508.     JNZ    EXPECT    ;NO?...ITS FOR ME!
  509. ;
  510. ;If second ring, then check for third ring, in case
  511. ;caller's phone exchange not synch'ed with computer's
  512. ;
  513. ENDRNG2 EQU    $+OFFSET
  514.     LDA    RPORT    ;GET THE STATUS
  515.     ANI    P2RDET    ;STILL RINGING?
  516.     JZ    ENDRNG2 ;WAIT UNTIL RING FINISHED
  517.     MVI    L,45    ;DELAY 4.5 SECONDS FOR NEXT RING
  518. ;
  519. WAITNX2 EQU    $+OFFSET
  520.     CALL    DELAY    ;WAIT .1 SECONDS
  521.     DCR    L    ;MOE TO GO?
  522.     JNZ    WAITNX2    ;YES, LOOP
  523.     LDA    RPORT    ;GET THE STATUS
  524.     ANI    P2RDET    ;RINGING AGAIN?
  525.     JNZ    EXPECT    ;NO?...ITS FOR ME!
  526. ;
  527. ;Call not for computer - wait until ringing done, then reset
  528. ;
  529. WAITNR    EQU    $+OFFSET
  530.     MVI    L,100    ;WAIT FOR 10 SECS NO RINGING
  531. ;
  532. WAITNRL EQU    $+OFFSET
  533.     CALL    DELAY    ;DELAY .1 SECONDS
  534.     LDA    RPORT    ;GET THE STATUS
  535.     ANI    P2RDET    ;STILL RINGING?
  536.     JZ    WAITNR    ;YES, WAIT 10 MORE SECONDS
  537.     DCR    L    ;NO RING, MAYBE WE'RE DONE
  538.     JNZ    WAITNRL ;NO, LOOP SOME MORE
  539.     ENDIF
  540. ;
  541.     IF    CALLBAK AND USRLOG
  542.     LDA    NONUSR    ;RECORD AS VOICE CALL
  543.     INR    A    ;ADD ONE TO COUNT
  544.     ENDIF        ;CALLBAK AND USRLOG
  545. ;
  546.     IF    CALLBAK AND USRLOG AND DECIMAL
  547.     DAA        ;MAKE DECIMAL
  548.     ENDIF        ;CALLBK AND USRLOG AND DECIMAL
  549. ;
  550.     IF    CALLBAK AND USRLOG
  551.     STA    NONUSR    ;SAVE NEW COUNT
  552.     ENDIF        ;CALLBK AND USRLOG
  553. ;
  554.     IF    CALLBAK ;CONTINUE WITH CALLBAK ROUTINES
  555.     JMP    HANGUP2    ;GO WAIT FOR NEXT CALL
  556. ;
  557. EXPECT    EQU    $+OFFSET
  558.     LXI    H,400    ;40 SECONDS TO WAIT FOR SECOND CALL
  559. ;
  560. RELOOK    EQU    $+OFFSET
  561.     LDA    RPORT    ;GET THE STATUS
  562.     ANI    P2RDET    ;RINGING AGAIN?
  563.     JZ    ANSWER    ;YES, GO ANSWER IT
  564.     CALL    DELAY    ;WAIT .1 SECOND
  565.     DCX    H    ;ONE LESS COUNT
  566.     MOV    A,H
  567.     ORA    L    ;IS COUNT ZERO?
  568.     JNZ    RELOOK    ;NO, LOOK SOME MORE
  569.     JMP    HANGUP2    ;COUNT DONE, WAIT FOR NEW CALL
  570. ;
  571.     ENDIF        ;END OF CALLBACK ROUTINES
  572. ;
  573. ;Setup modem
  574. ;
  575. ANSWER    EQU    $+OFFSET
  576. ;
  577.     IF    USRLOG    ;COUNT # OF LOGON ATTEMPTS
  578.     LDA    OLDUSR    ;GET # OF ATTEPMTS
  579.     INR    A    ;ADD THIS CALL
  580.     ENDIF        ;USRLOG
  581. ;
  582.     IF    USRLOG AND DECIMAL
  583.     DAA        ;MAKE IT DECIMAL
  584.     ENDIF        ;USRLOG AND DECIMAL
  585. ;
  586.     IF    USRLOG
  587.     STA    OLDUSR    ;SAVE NEW COUNT
  588.     ENDIF        ;USRLOG
  589. ;
  590. ;
  591.         MVI     A,P0ANSW  ;TURN ON DTR
  592.     STA    CPORT    ;.. AND SET FILTER VALUE FOR 300 BAUD
  593.         MVI     E,20
  594. ANSWR1  EQU     $+OFFSET
  595.     CALL    DELAY    ;GIVE TIME TO TURN ON
  596.         DCR     E
  597.         JNZ     ANSWR1
  598.         MVI     A,P0110
  599.     STA    TPORT    ;ANSWER PHONE
  600.     CALL    DELAY    ;GIVE TIME FOR ANSWER
  601.         LDA     CONDATA
  602.     LDA    DPORT    ;CLEAR MODEM PORT
  603.     LDA    DPORT    ;MAKE SURE ITS CLEAR
  604. ;Output value allowing modem to hang up on loss of carrier
  605.         CALL    CARCK0
  606.         JC      HANGUP
  607. ;Now test input for baud rate
  608.     CALL    PATCH     ;PATCH JMP TABLE
  609.     CALL    TSTBAUD  ;SEE IF BAUD = 110
  610.     JZ    WELCOME  ;YES, EXIT
  611.     MVI    A,P0NORM ;SET FOR 1 STOP BIT, ETC.
  612.     STA    TPORT
  613.         MVI     A,B300+P0ANSW ;SET DIVISOR
  614.         STA     CPORT    ;.. TO 300 RATE
  615.     CALL    TSTBAUD  ;SEE IF BAUD = 300
  616.     JZ    WELCOME  ;YES, EXIT
  617.     CALL    UNPATCH  ;RESTORE ORIG BIOS JMP TBL
  618.     JMP    ANSWER     ;TEST MORE - INVALID BAUD RATE
  619. ;
  620. ;
  621. ;Following are the USRLOG routines
  622. ;
  623.     IF    USRLOG     ;INCLUDE RESET FUNCTIONS
  624. RESET    EQU    $+OFFSET ;RESET ALL LOGON COUNTERS
  625.     XRA    A
  626.     ENDIF         ;USRLOG
  627. ;
  628.     IF    USRLOG AND PWRQD
  629.     STA    OLDUSR    ;RESET ATTEMPT COUNTER
  630.     ENDIF        ;USRLOG AND PWRQD
  631. ;
  632.     IF    USRLOG
  633.     STA    NEWUSR    ;RESET LOGON COUNTER
  634.     ENDIF        ;USRLOG
  635. ;
  636.     IF    USRLOG AND CALLBAK
  637.     STA    NONUSR    ;RESET VOICE COUNTER
  638.     ENDIF        ;USRLOG AND CALLBAK
  639. ;
  640. ;
  641.     IF    USRLOG
  642.     RET
  643.     ENDIF        ;USRLOG
  644. ;
  645. PRNLOG    EQU    $+OFFSET
  646. ;
  647.     IF    USRLOG AND PWRQD ;PRINT # OF LOGON ATTEMPTS
  648.     MVI    C,PRINTF
  649.     LXI    D,ATMSG
  650.     CALL    BDOS
  651.     LDA    OLDUSR
  652.     CALL    HXOUT
  653.     ENDIF        ;USRLOG AND PWRQD
  654. ;
  655.     IF    USRLOG    ;PRINT # OF LOGONS
  656.     MVI    C,PRINTF
  657.     LXI    D,SUMSG
  658.     CALL    BDOS
  659.     LDA    NEWUSR
  660.     CALL    HXOUT
  661.     ENDIF        ;USRLOG
  662. ;
  663.     IF    USRLOG AND CALLBAK    ;# OF VOICE CALLS
  664.     MVI    C,PRINTF
  665.     LXI    D,VCMSG
  666.     CALL    BDOS
  667.     LDA    NONUSR
  668.     CALL    HXOUT
  669.     ENDIF        ;USRLOG AND CALLBAK
  670. ;
  671.     IF    USRLOG
  672.     JMP    0    ;WARM-BOOT BACK TO CP/M
  673.     ENDIF        ;USRLOG
  674. ;
  675.     IF    USRLOG AND PWRQD
  676. ATMSG    EQU    $+OFFSET
  677.     DB    LF,CR,'NUMBER OF LOGON ATTEMPTS: $'
  678.     ENDIF        ;USRLOG AND PWRQD
  679. ;
  680.     IF    USRLOG
  681. SUMSG    EQU    $+OFFSET
  682.     DB    LF,CR,'NUMBER OF LOGONS: $'
  683.     ENDIF        ;USRLOG
  684. ;
  685.     IF    USRLOG AND CALLBAK
  686. VCMSG    EQU    $+OFFSET
  687.     DB    LF,CR,'NUMBER OF VOICE CALLS: $'
  688.     ENDIF        ;USRLOG AND CALLBAK
  689. ;
  690.     IF    USRLOG
  691. HXOUT    EQU    $+OFFSET
  692.     MOV    B,A    ;SAVE NUMBER
  693.     RAR        ;ROTATE RIGHT 4 BITS
  694.     RAR        ;TO MAKE AN ASCII DIGIT
  695.     RAR
  696.     RAR
  697.     CALL    ONEOUT    ;OUTPUT MSH TO CONSOLE
  698.     MOV    A,B    ;GET NUMBER BACK
  699. ;
  700. ONEOUT    EQU    $+OFFSET
  701.     ANI    0FH    ;GET LSH FOR OUTPUT
  702.     CPI    0AH    ;CHECK IF ALPHA
  703.     JC    NOTAL2
  704.     ADI    07H
  705. ;
  706. NOTAL2    EQU    $+OFFSET
  707.     ADI    30H
  708.     PUSH    B
  709.     MVI    C,02H
  710.     MOV    E,A    ;OUTPUT THE NUMBER
  711.     CALL    BDOS
  712.     POP    B
  713.     RET
  714.     ENDIF        ;USRLOG
  715. ;
  716. ;Welcome to the system
  717. ;
  718. WELCOME EQU    $+OFFSET
  719. ;
  720. GETNULL EQU    $+OFFSET
  721.     CALL    ILPRT    ;PRINT THIS MSG:
  722.     DB    CR,LF
  723.     DB    'HOW MANY NULLS (0-9) DO YOU NEED? ',0
  724.     CALL    MINPUT    ;GET VALUE
  725.     MOV    C,A    ;TO C FOR MOUTPUT
  726.     CALL    MOUTPUT ;ECHO CHAR
  727.     MOV    A,C    ;RESTORE VALUE
  728.     CPI    '0'
  729.     JC    GETNULL ;BAD, RETRY
  730.     CPI    '9'+1
  731.     JNC    GETNULL ;BAD
  732.     SUI    '0'    ;MAKE BINARY
  733.     STA    NULLS    ;SAVE COUNT
  734. ;
  735.     IF    TRAPLC
  736. GETULC    EQU    $+OFFSET
  737.     CALL    ILPRT    ;PRINT THIS MSG:
  738.     DB    CR,LF
  739.     DB    'CAN YOUR TERMINAL DISPLAY LOWER CASE? ',0
  740.     MVI    A,20H    ;FORCE CASE CONVERSION FOR NOW
  741.     STA    ULCSW
  742.     CALL    MINPUT    ;GET Y OR NO
  743.     MOV    C,A
  744.     CALL    MOUTPUT ;ECHO
  745.     MOV    A,C
  746.     CPI    'N'
  747.     JZ    DONEOPT ;WE'RE ALREADY SET UP FOR NO LWR CASE
  748.     CPI    'Y'
  749.     JNZ    GETULC    ;WASN'T Y OR N...GO ASK AGAIN
  750.     XRA    A
  751.     STA    ULCSW    ;SET FLAG FOR NO CONVERSION
  752. ;
  753. DONEOPT EQU    $+OFFSET
  754.     ENDIF        ;TRAPLC
  755. ;
  756.     CALL    ILPRT
  757.     DB    CR,LF,0
  758. ;Print the welcome file
  759.     LXI    H,WELFILN ;SOURCE
  760.     LXI    D,FCB    ;DESTINATION
  761.     MVI    B,13    ;LENGTH
  762.     CALL    MOVE    ;MOVE THE NAME
  763. ;Set DMA address to 80h
  764.     LXI    D,80H
  765.     MVI    C,STDMA
  766.     CALL    BDOS
  767. ;
  768.     IF    CPM2
  769. ;Set user number for welcome file
  770.     MVI    C,32
  771.     MVI    E,WELUSR
  772.     CALL    BDOS
  773.     ENDIF        ;CPM2
  774. ;
  775. ;Open the welcome file
  776.     LXI    D,FCB
  777.     MVI    C,OPEN
  778.     CALL    BDOS
  779. ;Did it exist?
  780.     INR    A    ;A=> 0 MEANS "NO"
  781.     JZ    PASSINT ;NO WELCOME FILE
  782. ;Got a file, type it
  783.     XRA    A    ;GET 0
  784.     STA    FCBRNO    ;ZERO RECORD #
  785.     LXI    H,100H    ;GET INITIAL BUFF POINTER
  786. ;
  787. ;Type the welcome file
  788. WELTYLP EQU    $+OFFSET
  789.     CALL    RDBYTE    ;GET A BYTE
  790.     CPI    1AH    ;EOF?
  791.     JZ    PASSINT ;YES, DONE
  792.     MOV    C,A    ;SETUP FOR TYPE
  793.     CALL    MOUTPUT ;TYPE THE CHAR
  794.     CALL    MSTAT    ;CHECK FOR..
  795.     ORA    A    ;CHAR TYPED?
  796.     JZ    WELTYLP ;..NO, LOOP
  797.     CALL    MINPUT    ;..YES, GET CHAR
  798.     CPI    'C'-40H ;CTL-C?
  799.     JNZ    WELTYLP ;..NO, LOOP UNTIL EOF
  800. ;
  801. ;Get the password
  802. ;
  803. PASSINT EQU    $+OFFSET
  804. ;
  805. ;
  806.     IF    PWRQD
  807.     MVI    D,5    ;5 TRIES AT PASSWORD
  808. ;
  809. PASSINP EQU    $+OFFSET
  810.     CALL    ILPRT
  811.     DB    CR,LF,'ENTER PASSWORD: ',0
  812.     LXI    H,PASSWD ;POINT TO PASSWORD
  813.     MVI    E,0    ;NO MISSED LETTERS
  814.     LDA    DPORT    ;CLEAR OUT GARBAGE
  815. ;
  816. PWMLP    EQU    $+OFFSET
  817.     CALL    MINPUT    ;GET A CHAR
  818.     CPI    'U'-40H ;CTL-U?
  819.     JZ    PASSINP ;YES, RE-GET IT
  820.     CPI    60H    ;LOWER CASE?
  821.     JC    NOTLC    ;NO,
  822.     ANI    5FH    ;MAKE UPPER CASE ALPHA
  823. ;
  824. NOTLC    EQU    $+OFFSET
  825.     CMP    M    ;MATCH PASSWORD?
  826.     JZ    PWMAT    ;..YES
  827.     MVI    E,1    ;..NO, SHOW MISS
  828.     CPI    CR    ;C/R?
  829.     JNZ    PWMLP    ;..NO, WAIT FOR C/R
  830. ;
  831. ;Password didn't match
  832. ;
  833. PWNMAT    EQU    $+OFFSET
  834.     CALL    ILPRT
  835.     DB    '++INCORRECT++',CR,LF,0
  836.     DCR    D    ;MORE TRIES?
  837.     JNZ    PASSINP ;YES
  838.     JMP    BADPASS ;NO, GO HANG UP
  839. ;
  840. ;Character matched in password
  841. ;
  842. PWMAT    EQU    $+OFFSET
  843.     INX    H    ;TO NEXT CHAR
  844.     CPI    CR    ;END?
  845.     JNZ    PWMLP    ;..NO, LOOP
  846. ;End of password.  Any missed chars?
  847.     MOV    A,E    ;GET FLAG
  848.     ORA    A
  849.     JNZ    PWNMAT    ;NOT RIGHT
  850. ;Password correct
  851.     ENDIF        ;PWRQD
  852. ;
  853. NOPASS    EQU    $+OFFSET
  854. ;
  855.     IF    USRLOG    ;COUNT # OF SUCCESSFUL LOGONS
  856.     LDA    NEWUSR    ;GET LAST VALUE
  857.     INR    A    ;INCREMENT IT
  858.     ENDIF        ;USRLOG
  859. ;
  860.     IF    USRLOG AND DECIMAL
  861.     DAA        ;MAKE IT DECIMAL
  862.     ENDIF        ;USRLOG AND DECIMAL
  863. ;
  864.     IF    USRLOG
  865.     STA    NEWUSR    ;SAVE NEW VALUE
  866.         ENDIF           ;USRLOG
  867. ;
  868.     CALL    ILPRT
  869.     DB    CR,LF,' ',0    ;PUT BOOT-UP MSG HERE
  870. ;
  871.     IF    COMFILE AND CPM2
  872.     MVI    C,32
  873.     MVI    E,COMUSR    ;SWITCH TO COM FILE USER #
  874.     CALL    BDOS
  875.     ENDIF        ;COMFILE AND CPM2
  876. ;
  877.     IF    COMFILE
  878.     LDA    OPTION
  879.     CPI    'A'    ;SYSOP CAN BYPASS COM FILE BY..
  880.     JZ    0    ;..TYPING "BYE /A"
  881.     CPI    'C'    ;OPER CAN ALSO GO TO COM..
  882.     JNZ    100H    ;..FILE LOAD WITH "BYE /C"
  883.     CALL    ILPRT    ;PRINT THIS MESSAGE:'
  884.     DB    'Loading system...',CR,LF,0
  885.     CALL    LODCOM
  886.     JMP    100H    ;EVERYONE ELSE GETS COM FILE
  887.     ENDIF        ;COMFILE
  888. ;
  889.     IF    NOT COMFILE
  890.     JMP    0
  891.     ENDIF        ;NOT COMFILE
  892. ;
  893. ;TSTBAUD attempts to read a LF or CR, returns with
  894. ;zero flag if the character read is one of these two.
  895. ;
  896. TSTBAUD EQU    $+OFFSET
  897.     CALL    MINPUT    ;GET CHARACTER FROM MODEM
  898.     CPI    CR    ;IF A CARRIAGE RETURN...
  899.     RZ        ;.. RETURN
  900.     CPI    LF    ;IF A LINEFEED...
  901.     RET        ;RET ZERO FLAG, ELSE NOT ZERO
  902. ;
  903. ;Loss of connection test
  904. ;
  905. CARCK0  EQU     $+OFFSET;INITIAL
  906.         PUSH    D       ;CARRIER
  907.         MVI     E,150   ;DETECT
  908.         JMP     CARCK5  ;ROUTINE
  909. CARCK    EQU    $+OFFSET
  910.         PUSH    D
  911.         MVI     E,150
  912. CARCK1  EQU     $+OFFSET
  913.         LDA     RPORT1
  914.     ANI    P2CTS    ;GOT A CARRIER?
  915.     JZ    CARCK2    ;YES, GO ON WITH TESTS
  916.     CALL    DELAY    ;WAIT .1 SECONDS
  917.         DCR     E       ;COUNT DOWN TIME
  918.         JNZ     CARCK1
  919.         STC
  920.         POP     D
  921.         RET
  922. ;
  923. ;NOW TEST DRIVE #'S AND (IF CP/M 2.X) USER #'S TO
  924. ;insure that maximums are not exceeded.
  925. ;
  926. CARCK2    EQU    $+OFFSET
  927.     LDA    4    ;CHECK DISK/USER #
  928.     ANI    0FH    ;ISOLATE DRIVE
  929.     CPI    MAXDRV    ;VALID DRIVE?
  930.     JC    CARCK3    ;YES, SKIP THIS JUNK
  931.     LDA    4    ;GET WHOLE LOGIN BYTE
  932.     ANI    0F0H    ;RETAIN USER # & FORCE DRIVE TO A
  933.     STA    4    ;UPDATE LOGIN BYTE
  934.     CALL    ILPRT    ;TELL USER WHAT HE DID
  935.     DB    'INVALID DRIVE - RETURNING TO A:',0
  936.     JMP    0    ;WARM BOOT
  937. ;
  938. CARCK3    EQU    $+OFFSET
  939. ;
  940.     IF    CPM2
  941.     LDA    4    ;GET LOGIN BYTE
  942.     ANI    0F0H    ;ISOLATE USER #
  943.     CPI    MAXUSR*16+1 ;VALID USER #?
  944.     JC    CARCK4    ;YES, DON'T CHANGE
  945.     LDA    4    ;GET LOGIN BYTE AGAIN
  946.     ANI    0FH    ;KEEP DRIVE, ZERO USER
  947.     STA    4    ;UPDATE LOGIN BYTE
  948.     CALL    ILPRT    ;TELL HIM WHAT HAPPENED
  949.     DB    '++INVALID USER NUMBER - RETURNING TO 0++',0
  950.     JMP    0    ;WARM BOOT
  951.     ENDIF        ;CPM2
  952. ;
  953. CARCK4    EQU    $+OFFSET
  954.     ORA    A
  955.         POP     D
  956.     RET
  957. ;
  958. CARCK5  EQU     $+OFFSET
  959.         LDA     DPORT
  960.         LDA     DPORT
  961.         LDA     RPORT1
  962.         LDA     RPORT1
  963.         ANI     P2CTS
  964.         JZ      CARCK2
  965.         CALL    DELAY
  966.         DCR     E
  967.         JNZ     CARCK5
  968.         STC
  969.         POP     D
  970.         RET
  971. ;
  972. ;.1 sec delay routine
  973. ;
  974. DELAY    EQU    $+OFFSET
  975.     PUSH    B
  976. ;
  977.     IF    FASTCLK
  978.     LXI    B,16667 ;4 MHZ TIMING CONSTANT
  979.     ENDIF
  980. ;
  981.     IF    NOT FASTCLK
  982.     LXI    B,8334    ;2 MHZ TIMING CONSTANT
  983.     ENDIF
  984. ;
  985. DELAY1    EQU    $+OFFSET
  986.     DCX    B
  987.     MOV    A,B
  988.     ORA    C
  989.     JNZ    DELAY1
  990.     POP    B
  991.     RET
  992. ;
  993. ;50 ms delay routine
  994. ;
  995. KDELAY    EQU    $+OFFSET
  996.     PUSH    B
  997. ;
  998.     IF    FASTCLK
  999.     LXI    B,8334
  1000.     ENDIF
  1001. ;
  1002.     IF    NOT FASTCLK
  1003.     LXI    B,4167
  1004.     ENDIF
  1005. ;
  1006.     JMP    DELAY1
  1007. ;
  1008. ;Patch in the new JMP table (saving the old)
  1009. ;
  1010. PATCH    EQU    $+OFFSET
  1011.     CALL    TBLADDR        ;CALC HL= CP/M JMP TABLE
  1012.     LXI    D,VCOLDBT    ;POINT TO SAVE LOCATION
  1013.     MVI    B,18        ;ALWAYS SAVE PRINTER VECTOR
  1014.     CALL    MOVE        ;MOVE IT
  1015. ;Now move new JMP table to CP/M
  1016.     CALL    TBLADDR        ;CALC HL=CP/M'S JMP TABLE
  1017.     XCHG            ;MOVE TO DE
  1018.     LXI    H,NEWJTBL    ;POINT TO NEW
  1019.     CALL    MOVE        ;MOVE IT
  1020.     RET
  1021. ;
  1022. UNPATCH EQU    $+OFFSET
  1023.     CALL    TBLADDR        ;HL=CP/M'S JMP TABLE
  1024.     XCHG            ;MOVE TO DE
  1025.     LXI    H,VCOLDBT    ;GET SAVED TABLE
  1026.     CALL    MOVE        ;MOVE ORIG BACK
  1027.     RET            
  1028. ;
  1029. ;Calculate HL=CP/M's jump table, B=length
  1030. ;
  1031. TBLADDR EQU    $+OFFSET
  1032.     LHLD    1    ;GET BIOS POINTER
  1033.     DCX    H    ;..SKIP
  1034.     DCX    H    ;..TO
  1035.     DCX    H    ;..COLD BOOT
  1036. ;
  1037.     IF    NOT PRINTER
  1038.     MVI    B,18    ;BYTES TO MOVE
  1039.     ENDIF
  1040. ;
  1041.     IF    PRINTER ;RETAIN LIST DEVICE?
  1042.     MVI    B,15    ;DON'T MOVE LISTER JUMP
  1043.     ENDIF
  1044. ;
  1045.     RET
  1046. ;
  1047. ;Move (HL) to (DE), length in (B)
  1048. ;
  1049. MOVE    EQU    $+OFFSET
  1050.     MOV    A,M    ;GET A BYTE
  1051.     STAX    D    ;PUT AT NEW HOME
  1052.     INX    D    ;BUMP POINTERS
  1053.     INX    H
  1054.     DCR    B    ;DEC BYTE COUNT
  1055.     JNZ    MOVE    ;IF MORE, DO IT
  1056.     RET        ;IF NOT,RETURN
  1057. ;
  1058. ;
  1059. ;Common routine to check for carrier lost, called from console out
  1060. ;
  1061. CHECK    EQU    $+OFFSET
  1062.     CALL    CARCK    ;SEE IF CARRIER STILL ON
  1063.     RNC        ;ALL OK
  1064. ;
  1065. ;Carrier is lost.  Type message so local console shows the reason
  1066. ;
  1067. BADPASS EQU    $+OFFSET ;COME HERE ON BAD PASSWORD
  1068.     MVI    A,1    ;SHOW CARRIER LOST SO
  1069.     STA    LOSTFLG ;..WE WON'T CK AGAIN
  1070.     LXI    SP,STACK ;ENSURE VALID STACK
  1071.     CALL    ILPRT
  1072.     DB    CR,LF
  1073.     DB    '++CARRIER LOST++'
  1074.     DB    CR,LF,'   ',0
  1075.     CALL    UNPATCH ;RESTORE ORIG BIOS JMP TBL
  1076.     XRA    A    ;CLEAR OUT CARRIER..
  1077.     STA    LOSTFLG ;..LOST FLAG
  1078.     JMP    HANGUP
  1079. ;
  1080. ;Readbyte routine - used to read the welcome file
  1081. ;
  1082. RDBYTE    EQU    $+OFFSET
  1083.     MOV    A,H    ;TIME TO READ?
  1084.     ORA    A    ;..IF AT 100H
  1085.     JZ    NORD    ;NO READ REQ'D
  1086. ;Have to read a sector
  1087.     LXI    D,FCB
  1088.     MVI    C,READ
  1089.     CALL    BDOS
  1090.     ORA    A    ;OK?
  1091.     MVI    A,1AH    ;FAKE UP EOF
  1092.     RNZ        ;RET EOF IF BAD
  1093.     LXI    H,80H
  1094. ;
  1095. NORD    EQU    $+OFFSET
  1096.     MOV    A,M    ;GET CHAR
  1097.     INX    H    ;TO NEXT
  1098.     RET
  1099. ;
  1100. ;Keyboard/modem status test routine
  1101. ;
  1102. MSTAT    EQU    $+OFFSET
  1103. ;
  1104.     IF    DUAL$IO ;WANT LOCAL CONSOLE?
  1105.     CALL    CONSTAT ;GET LOCAL STATUS
  1106.     ORA    A
  1107.     RNZ        ;RET IF LOCAL CHAR
  1108.     ENDIF        ;DUAL$IO
  1109. ;
  1110.     LDA    TPORT    ;GET STATUS
  1111.     ANI    P0DAV    ;DATA AVAILABLE?
  1112.     RZ        ;RETURN IF NOT READY
  1113.     LDA    TPORT    ;GET STATUS
  1114.     ANI    30H    ;CHECK FRAMING AND OVERRUN BITS
  1115.     JZ    MSTAT1    ;NO ERRORS...LEGIT CHARACTER
  1116.     LDA    DPORT    ;SWALLOW CHARACTER (CLEARS PODAV)
  1117.     SUB    A    ;RETURN FALSE
  1118.     RET
  1119. MSTAT1    EQU    $+OFFSET
  1120.     MVI    A,0FFH    ;SHOW READY
  1121.     ORA    A
  1122.     RET
  1123. ;
  1124. ;Modem input function, checks local console first
  1125. ;
  1126. MINPUT    EQU    $+OFFSET
  1127. ;
  1128.     IF    TIMEOUT
  1129.     PUSH    H
  1130.     LXI    H,TOVALUE*MINUTES ;INITIALIZE TIMEOUT COUNTER
  1131.     SHLD    TOCNT
  1132.     POP    H
  1133.     ENDIF        ;TIMEOUT
  1134. ;
  1135. MINPUT1 EQU    $+OFFSET
  1136.     LDA    LOSTFLG ;KNOWN LOSS..
  1137.     ORA    A    ;..OF CARRIER?
  1138.     CZ    CHECK    ;CARRIER STILL ON?
  1139.     CALL    MSTAT    ;ANYTHING?
  1140.     ORA    A
  1141. ;
  1142.     IF    NOT TIMEOUT
  1143.     JZ    MINPUT    ;LOOP TILL CHAR RCD
  1144.     ENDIF        ;NOT TIMEOUT
  1145. ;
  1146.     IF    TIMEOUT
  1147.     JNZ    MINPUT2
  1148.     CALL    KDELAY    ;KILL 50 MS
  1149.     PUSH    H
  1150.     LHLD    TOCNT    ;KNOCK DOWN TIMEOUT COUNTER
  1151.     DCX    H
  1152.     SHLD    TOCNT
  1153.     MOV    A,H
  1154.     ORA    L
  1155.     POP    H
  1156.     JNZ    MINPUT1 ;STILL TIME LEFT..KEEP TRYING
  1157.     CALL    ILPRT
  1158.     DB    '++INPUT TIMED OUT++',7,7,0
  1159.     JMP    NOSLASH
  1160.     ENDIF        ;TIMEOUT
  1161. ;
  1162. MINPUT2 EQU    $+OFFSET
  1163. ;
  1164.     IF    DUAL$IO ;BOTH LOCAL AND REMOTE
  1165.     CALL    CONSTAT ;CHECK LOCAL CONSOLE
  1166.     ORA    A    ;CHAR?
  1167.     JNZ    CONIN    ;..YES, READ IT, RET.
  1168.     ENDIF
  1169. ;
  1170. ;Local console wasn't ready, so read modem
  1171. ;
  1172.     LDA    DPORT    ;GET DATA BYTE
  1173.     ANI    7FH    ;DELETE PARITY
  1174.     JZ    MINPUT    ;IGNORE NULLS
  1175.     IF    HARDLOG
  1176.     CPI    20H
  1177.     JNC    MINPUT3
  1178.     CPI    CR
  1179.     JNZ    NOLOG
  1180. ;
  1181. MINPUT3    EQU    $+OFFSET
  1182.     CALL    LISTOUT ;ECHO ON PRINTER
  1183.     CPI    CR
  1184.     JNZ    NOLOG    ;CR NEEDS LINEFEED
  1185.     MVI    A,LF
  1186.     CALL    LISTOUT ;SO SEND IT
  1187.     MVI    A,CR    ;GET BACK CR
  1188.     ENDIF        ;END OF HARDLOG
  1189. ;
  1190. NOLOG    EQU    $+OFFSET
  1191. ;
  1192.     CPI    3    ;IS IT CONTROL-C?
  1193.     RNZ        ;NO, PASS IT THRU
  1194.     LDA    0    ;SEE IF WARM BOOT DISABLED
  1195.     CPI    0C3H    ;JMP MEANS WARM BOOT OK
  1196.     MVI    A,3    ;SO RETURN CONTROL-C
  1197.     RZ
  1198.     XRA    A    ;ELSE CONVERT TO NULL
  1199.     RET
  1200. ;
  1201. ;Modem output function
  1202. ;
  1203. MOUTPUT EQU    $+OFFSET
  1204. ;
  1205. ;If we already know carrier is lost, don't check
  1206. ;for it again or loop trying to output.
  1207.     LDA    LOSTFLG ;KNOWN LOSS OF CARRIER?
  1208.     ORA    A
  1209.     JNZ    SILENT    ;AVOID LOOP IN CASE CARRIER LOST
  1210.     CALL    CHECK    ;CARRIER STILL ON?
  1211.     LDA    TPORT    ;GET MODEM STATUS
  1212.     ANI    P0TBMT    ;TRANSMIT BUFFER EMPTY?
  1213.     JZ    MOUTPUT ;LOOP IF NOT READY
  1214.     MOV    A,C    ;GET CHAR
  1215.     ANI    7FH    ;STRIP PARITY BIT
  1216.     IF    TRAPLC
  1217.     CPI    60H    ;CHECK FOR LOWER CASE
  1218.     JC    MOUTP2    ;SKIP IF NOT LC
  1219.     CPI    7FH    ;CHECK FOR RUBOUT
  1220.     JZ    MOUTP2
  1221.     PUSH    H
  1222.     LXI    H,ULCSW ;SUBTRACT EITHER 20H OR 0
  1223.     SUB    M
  1224.     POP    H
  1225.     MOV    C,A    ;FORCE ON LOCAL AS WELL AS REMOTE
  1226. ;
  1227. MOUTP2    EQU    $+OFFSET
  1228.     ENDIF        ;TRAPLC
  1229. ;
  1230.     STA    DPORT    ;OUTPUT TO MODEM
  1231. ;
  1232. SILENT    EQU    $+OFFSET
  1233. ;
  1234.     IF    DUAL$IO ;TO LOCAL ALSO?
  1235.     PUSH    PSW    ;SAVE CHAR
  1236.     CALL    CONOUT    ;SEND TO REGULAR BIOS
  1237.     POP    PSW    ;GET CHAR AGAIN
  1238.     ENDIF        ;DUAL$IO
  1239. ;
  1240. ;Check for nulls
  1241.     CPI    LF    ;TIME FOR NULLS?
  1242.     RNZ        ;NO, RETURN
  1243. ;Send nulls if required
  1244.     LDA    NULLS    ;GET COUNT
  1245.     ORA    A    ;ANY?
  1246.     RZ        ;..NO
  1247.     PUSH    B
  1248.     MOV    B,A    ;SAVE COUNT
  1249.     MVI    C,0    ;0 IS A NULL
  1250. ;
  1251. NULLP    EQU    $+OFFSET
  1252.     CALL    MOUTPUT ;TYPE A NULL
  1253.     DCR    B    ;MORE?
  1254.     JNZ    NULLP    ;..YES, LOOP
  1255.     POP    B
  1256.     MVI    C,LF    ;RESTORE LF
  1257.     RET
  1258. ;
  1259. ;Boot trap - becomes disconnect if JMP at 0 has been altered
  1260. ;
  1261. MBOOT    EQU    $+OFFSET
  1262.     LDA    0    ;LOOK AT OPCODE
  1263.     CPI    0C3H    ;IS IT STILL JMP?
  1264.     JZ    VWARMBT ;YES, ALLOW IT
  1265.     JMP    NOSLASH ;NO, DISCONNECT
  1266. ;
  1267. ;Inline print routine
  1268. ;
  1269. ILPRT    EQU    $+OFFSET
  1270.     XTHL        ;SAVE HL, GET MSG
  1271.     PUSH    B    ;SAVE BC REGS
  1272. ;
  1273. ILPLP    EQU    $+OFFSET
  1274.     MOV    C,M    ;GET CHAR
  1275.     CALL    MOUTPUT ;OUTPUT IT
  1276.     INX    H    ;POINT TO NEXT
  1277.     MOV    A,M    ;TEST
  1278.     ORA    A    ;..FOR END
  1279.     JNZ    ILPLP
  1280.     POP    B    ;RESTORE BC REGS
  1281.     XTHL        ;RESTORE HL, RET ADDR
  1282.     RET        ;RET PAST MSG
  1283. ;
  1284.     IF    PWRQD    ;KEEP PASSWORD HERE
  1285. ;Access password (ends in carriage return)
  1286. ;
  1287. PASSWD    EQU    $+OFFSET
  1288.     DB    'HELLO' ;THE PASSWORD ITSELF
  1289.     DB    CR    ;END OF PASSWORD
  1290. ;Allow room for bigger password to be patched in
  1291.     DB    0,0,0,0,0,0,0,0,0,0,0,0,0
  1292.     ENDIF        ;PWRQD
  1293. ;
  1294. ;Routine to load the COM file
  1295. ;
  1296.     IF    COMFILE
  1297. LODCOM    EQU    $+OFFSET
  1298.     XRA    A    ;INITIALIZE FCB
  1299.     STA    COMFCB
  1300.     LXI    H,COMFCB+12
  1301.     MVI    B,21
  1302. ;
  1303. ZLOOP    EQU    $+OFFSET
  1304.     MVI    M,0
  1305.     INX    H
  1306.     DCR    B
  1307.     JNZ    ZLOOP
  1308. ;
  1309.     MVI    C,OPEN    ;NOW OPEN THE FILE
  1310.     LXI    D,COMFCB
  1311.     CALL    BDOS
  1312.     INR    A    ;SHOULD BE NON-ZERO
  1313.     JZ    ABORT    ;NO FILE, ABORT
  1314. ;
  1315. ;Now load the file
  1316.     LHLD    6    ;GET TOP OF MEMORY
  1317.     LXI    D,-80H    ;RECORD LOADS CAN'T START..
  1318.     DAD    D    ;..ABOVE (BDOS) - 80H
  1319.     PUSH    H    ;SAVE ON STACK
  1320. ;
  1321.     LXI    D,80H    ;TPA-80H
  1322.     LXI    B,0    ;KEEP A RECORD COUNTER
  1323.     PUSH    B    ;SAVE COUNTER
  1324.     PUSH    D    ;AND LOAD ADDRESS
  1325. ;
  1326. GLOOP    EQU    $+OFFSET
  1327.     POP    D    ;GET TPA ADRS
  1328.     LXI    H,80H    ;POINT TO NXT ADRS TO READ TO
  1329.     DAD    D    ;HL HAS THE ADDRESS
  1330.     POP    B    ;INCREMENT THE COUNTER
  1331. ;Check for load past top-of-memory
  1332.     POP    D    ;GET (TOP-OF-MEMORY)
  1333.     PUSH    D    ;RE-SAVE FOR NEXT TIME
  1334.     MOV    A,E    ;SUBTRACT: (TOP) - (ADRS)
  1335.     SUB    L
  1336.     MOV    A,D    ;ONLY THE CARRY NEEDED
  1337.     SBB    H
  1338.     JNC    SIZEOK    ;CY= BETTER MOVCPM
  1339.     CALL    ERRXIT    ;SO TELL THE STORY
  1340.     DB    '++PROGRAM AREA TOO SMALL++','$'
  1341. ;
  1342. SIZEOK    EQU    $+OFFSET
  1343.     INX    B
  1344.     PUSH    B
  1345.     PUSH    H    ;SAVE TPA ADRS
  1346.     XCHG        ;ALIGN REGISTERS
  1347.     MVI    C,STDMA ;TELL BDOS WHERE TO PUT RECORD
  1348.     CALL    BDOS
  1349.     LXI    D,COMFCB ;NOW READ THE RECORD
  1350.     MVI    C,READ
  1351.     CALL    BDOS
  1352.     ORA    A
  1353.     JZ    GLOOP    ;A=0 IF MORE TO READ
  1354.     POP    B    ;UNJUNK STACK
  1355.     POP    B    ;THIS IS OUR COUNTER
  1356.     POP    H    ;MORE JUNK ON STACK
  1357.     MOV    A,B    ;CHECK FOR ZERO
  1358.     ORA    C
  1359.     JZ    ABORT    ;WE SHOULD HAVE READ SOMETHING
  1360.     LXI    D,80H    ;WE DID, RESET DMA TO 80H
  1361.     MVI    C,STDMA
  1362.     CALL    BDOS
  1363.     CALL    LOADOK    ;PRINT THIS MSG TO CONSOLE:
  1364.     DB    '++COM FILE LOADED++',CR,LF,'$'
  1365. ;
  1366. LOADOK    EQU    $+OFFSET
  1367.     POP    D
  1368.     LDA    OPTION    ;SEE IF THIS WAS "BYE /C"
  1369.     CPI    'C'    ;IF IT WAS THEN..
  1370.     RZ        ;..DON'T PRINT MESSAGE
  1371.     MVI    C,PRINTF
  1372.     CALL    BDOS
  1373.     RET
  1374. ;
  1375. ABORT    EQU    $+OFFSET
  1376.     CALL    ERRXIT
  1377.     DB    CR,LF
  1378.     DB    '++CANNOT FIND COM FILE++','$'
  1379. ;
  1380. ERRXIT    EQU    $+OFFSET
  1381.     POP    D
  1382.     MVI    C,PRINTF
  1383.     CALL    BDOS    ;PRINT THE ABORT MSG
  1384.     JMP    0    ;WARM BOOT
  1385.     ENDIF        ;COMFILE
  1386. ;
  1387. ;This area is used for vectoring calls to the
  1388. ;user's CBIOS, but saving the registers first
  1389. ;in case they are destroyed.
  1390. ;
  1391. CONSTAT EQU    $+OFFSET
  1392.     PUSH    B
  1393.     PUSH    D
  1394.     PUSH    H
  1395.     CALL    VCONSTAT
  1396.     POP    H
  1397.     POP    D
  1398.     POP    B
  1399.     RET
  1400. ;
  1401. CONIN    EQU    $+OFFSET
  1402.     PUSH    B
  1403.     PUSH    D
  1404.     PUSH    H
  1405.     CALL    VCONIN
  1406. ;
  1407.     IF    FKEYS
  1408.     CALL    CKFUNC
  1409.     ENDIF        ;FKEYS
  1410. ;
  1411.     POP    H
  1412.     POP    D
  1413.     POP    B
  1414.     RET
  1415. ;
  1416. CKFUNC    EQU    $+OFFSET
  1417. ;
  1418. ;
  1419.     IF    FKEYS
  1420.     CPI    SYSDKEY
  1421.     JZ    SYSDOWN ;TELL CALLER TO LEAVE
  1422.     CPI    TWITKEY
  1423.     JZ    GOODBY    ;MAKE CALLER LEAVE
  1424.     CPI    MSGKEY
  1425.     RNZ
  1426.     CALL    ILPRT    ;SEND CALLER A MESSAGE
  1427.     DB    'MESSAGE FROM OPERATOR:',0
  1428.     MVI    A,' '    ;SOMETHING TO RETURN WITH
  1429.     RET
  1430. ;
  1431. SYSDOWN EQU    $+OFFSET
  1432.     CALL    ILPRT
  1433.     DB    'SYSTEM DOWN IN'
  1434.     DB    ' 5 MINUTES....',0
  1435.     MVI    A,' '
  1436.     RET
  1437.     ENDIF        ;FKEYS
  1438. ;
  1439. CONOUT    EQU    $+OFFSET
  1440.     PUSH    B
  1441.     PUSH    D
  1442.     PUSH    H
  1443.     CALL    VCONOUT
  1444.     POP    H
  1445.     POP    D
  1446.     POP    B
  1447.     RET
  1448. ;
  1449. LISTOUT    EQU    $+OFFSET
  1450.     PUSH    B
  1451.     PUSH    D
  1452.     PUSH    H
  1453.     PUSH    PSW
  1454.     MOV    C,A
  1455.     CALL    VLISTOUT
  1456.     POP    PSW
  1457.     POP    H
  1458.     POP    D
  1459.     POP    B
  1460.     RET
  1461. ;
  1462. ;This is the JMP table which is copied on top
  1463. ;of the one pointed to by location 1 in CP/M
  1464. ;
  1465. NEWJTBL EQU    $+OFFSET
  1466.     JMP    MBOOT    ;COLD BOOT
  1467.     JMP    MBOOT    ;WARM BOOT
  1468.     JMP    MSTAT    ;MODEM STATUS TEST
  1469.     JMP    MINPUT    ;MODEM INPUT ROUTINE
  1470.     JMP    MOUTPUT ;MODEM OUTPUT ROUTINE
  1471.     RET        ;DUMMY LIST DEVICE
  1472.     NOP
  1473.     NOP
  1474. ;
  1475. WELFILN EQU    $+OFFSET
  1476.     DB    0,'WELCOME    ',0
  1477. ;Welcome file name ^^^^^^^^^^^ (must be 11 characters)
  1478. ;
  1479. NULLS    EQU    $+OFFSET
  1480.     DB    5
  1481. ;
  1482. COMFCB    EQU    $+OFFSET
  1483.     DB    0,'RBBS    COM'
  1484. ;COM file name       ^^^^^^^^^^^ (must be 11 characters)
  1485. ;
  1486. PEND    EQU    $+OFFSET ;END OF RELOCATED CODE
  1487. ;
  1488. ;These areas are not initialized
  1489. ;
  1490.     DS    21    ;REST OF COM FCB
  1491. ;
  1492. ULCSW    EQU    $+OFFSET
  1493.     DS    1
  1494. ;
  1495. OPTION    EQU    $+OFFSET
  1496.     DS    1
  1497. ;
  1498. TOCNT    EQU    $+OFFSET
  1499.     DS    2
  1500. ;
  1501. ;Byte to keep track of lost carrier when
  1502. ;typing "++CARRIER LOST++" so we don't loop
  1503. ;
  1504. LOSTFLG EQU    $+OFFSET
  1505.     DS    1
  1506. ;
  1507. ;Save the CP/M jump table here
  1508. ;
  1509. VCOLDBT EQU    $+OFFSET
  1510.     DS    3
  1511. ;
  1512. VWARMBT EQU    $+OFFSET
  1513.     DS    3
  1514. ;
  1515. VCONSTAT EQU    $+OFFSET
  1516.      DS    3
  1517. ;
  1518. VCONIN     EQU    $+OFFSET
  1519.      DS    3
  1520. ;
  1521. VCONOUT  EQU    $+OFFSET
  1522.      DS    3
  1523. ;
  1524. VLISTOUT EQU    $+OFFSET
  1525.      DS    3
  1526. ;
  1527. ;Since these areas are not initialized,
  1528. ;the following counters will not be changed
  1529. ;by subsequent loads of this program
  1530. ;
  1531.     IF    USRLOG
  1532. OLDUSR    EQU    $+OFFSET
  1533.     DS    1
  1534. ;
  1535. NEWUSR    EQU    $+OFFSET
  1536.     DS    1
  1537. ;
  1538. NONUSR    EQU    $+OFFSET
  1539.     DS    1
  1540.     ENDIF        ;USRLOG
  1541. ;
  1542. ;
  1543.     DS    60
  1544. STACK    EQU    $+OFFSET ;LOCAL STACK
  1545. ;
  1546. ENDMARK    EQU    $+OFFSET ;! IGNORE ERROR. THIS MARKS END OF PGM
  1547. ;
  1548. ;BDOS equates
  1549. ;
  1550. CI    EQU    1
  1551. WRCON    EQU    2
  1552. DRECTIO EQU    6
  1553. PRINTF    EQU    9
  1554. CSTS    EQU    11
  1555. OPEN    EQU    15
  1556. READ    EQU    20
  1557. STDMA    EQU    26
  1558. BDOS    EQU    5
  1559. FCB    EQU    5CH 
  1560. FCBRNO    EQU    FCB+32
  1561. ;
  1562.     END
  1563.