home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / RCPM / NBYE10.LBR / NBHAYES.IQC / NBHAYES.INC
Text File  |  2000-06-30  |  24KB  |  902 lines

  1. ;******************************************************************************
  2. ;
  3. ;    NBHAYES.INC        Gary Case
  4. ;    19 August 1984        585 Big Sky Court
  5. ;                Colorado Springs, CO
  6. ;                           80919
  7. ;                (303) 599-0744
  8. ;
  9. ;
  10. ; Hayes Smartmodem (or compatible) Insert for NBYE.MAC
  11. ;
  12. ; *** Must be renamed as NBYEMDM.INC before assembling NBYE.
  13. ;
  14. ;
  15. ;******************************************************************************
  16. ;
  17. ;
  18. ; This insert requires an additional insert with the actual port I/O routines
  19. ; that talk to the Smartmodem.  The required routines are:
  20. ;
  21. ;    MDMISTAT  --  Return zero status if no input character available,
  22. ;              non-zero status otherwise.  NOTE:  This routine must
  23. ;              also define the value of 'MISCYL' as follows:
  24. ;
  25. ;            MISCYL  EQU  nn  ;Nbr of machine cycles executed by
  26. ;                     ;this routine when no char ready
  27. ;
  28. ;
  29. ;    MDMOSTAT  --  Return zero status if port is not ready for output,
  30. ;              non-zero status otherwise.
  31. ;
  32. ;    MDMINP    --  Do an input from the modem port, waiting for the next
  33. ;              available character if necessary.  Return the character
  34. ;              in Acc.  If any USART errors were detected, clear the
  35. ;              errors and substitute a Null for the errored character.
  36. ;
  37. ;    MDMOUT    --  Send the character from Acc to the modem port.
  38. ;              (Wait until ready if necessary)
  39. ;
  40. ;    MDM110    --  Initialize the modem port to 110 baud.
  41. ;              Not required if OK110 is FALSE.
  42. ;              NOTE:  DTR must be on after initialization if DTRCTRL
  43. ;              is TRUE.
  44. ;
  45. ;    MDM300    --  Initialize the modem port to 300 baud.
  46. ;              NOTE:  DTR must be on after initialization if DTRCTRL
  47. ;              is TRUE.
  48. ;
  49. ;    MDM1200   --  Initialize the modem port to 1200 baud.
  50. ;              Not required if SM1200 is FALSE.
  51. ;              NOTE:  DTR must be on after initialization if DTRCTRL
  52. ;              is TRUE.
  53. ;
  54. ;    MDMDTRON  --  Turn modem port DTR on.
  55. ;              Only required if DTRCTRL is TRUE.
  56. ;
  57. ;    MDMDTROFF --  Turn modem port DTR off.
  58. ;              Only required if DTRCTRL is TRUE.
  59. ;
  60. ;    MDMDSR    --  Return Zero Flag = state of DSR from modem port.
  61. ;              (NZ ==> high, Z ==> low)
  62. ;              Only required if DCDDSR is TRUE.
  63. ;
  64. ;    
  65. ;    *** NOTE:  The above routines must SAVE ALL REGISTERS except Acc.
  66. ;
  67. ;
  68. ;        The following files provide the above inserts for the
  69. ;        Compupro Interfacer 3 (or 4) and North Star Horizon
  70. ;        right serial port, respectively:
  71. ;
  72. ;            NBCPRO.INC
  73. ;            NBNSRS.INC
  74. ;
  75. ;        The desired insert must be renamed NBYEIO.INC
  76. ;
  77. ;
  78. ;******************************************************************************
  79. ;
  80. ;    Customization Options  (see notes that follow)
  81. ;
  82. DTRCTRL    EQU    TRUE        ;CAN WE CONTROL THE SMARTMODEM DTR INPUT?
  83. ;
  84. DCDDSR    EQU    TRUE        ;SMARTMODEM DCD WIRED TO COMPUTER'S DSR INPUT?
  85. ;
  86. SM1200    EQU    TRUE        ;1200 BAUD SMARTMODEM?
  87. ;
  88. OK110    EQU    FALSE        ;WANT TO SUPPORT 110 BAUD?
  89. ;
  90. ;
  91. ;******************************************************************************
  92. ;
  93. ;
  94. ;  Configuration Notes:  This insert allows several different configurations
  95. ;             for the Smartmodem.  The recommended configuration is
  96. ;             to set DTRCTRL and DCDDSR both TRUE, and wire the
  97. ;             connector as shown below.  However, any combination
  98. ;             can be selected.  Note that if both DTRCTRL and DCDDSR
  99. ;             are FALSE, a simple 3-wire connection can be used to
  100. ;             connect the modem.  Several functions take longer to
  101. ;             perform in this mode, however, and loss of carrier
  102. ;             will only be detected while I/O is through NBYE; i.e.
  103. ;             it will not be detected during an XMODEM transfer
  104. ;             (although as long as NBYE is set to automatically
  105. ;             logout after a reasonable period of inactivity this
  106. ;             should not be a significant problem).
  107. ;             
  108. ;
  109. ;
  110. ; Recommended Computer to Smartmodem Cable Connections:
  111. ;
  112. ;   Pin Number if     Pin Number if      Smartmodem     When to Make the
  113. ;  Computer is DTE   Computer is DCE     Pin Number        Connection
  114. ;                                  
  115. ;         1                 1                 1              Always **
  116. ;         2                 3                 2              Always
  117. ;         3                 2                 3              Always
  118. ;         5                 4                 5              Always ***
  119. ;         6                20                 6        When DCDDSR is FALSE **
  120. ;         6                20                 8        When DCDDSR is TRUE
  121. ;         7                 7                 7              Always
  122. ;         8                 8                 8        When DCDDSR is FALSE ***
  123. ;        20                 6                20        When DTRCTRL is TRUE
  124. ;
  125. ;
  126. ;                                      ** ==> Not a required connection
  127. ;                                     *** ==> Only required if this line is not
  128. ;                                             pulled high by your computer when
  129. ;                                             no connection is made. 
  130. ;
  131. ;
  132. ; Smartmodem Switch Settings:
  133. ;
  134. ;     Switch Number    Position          When to Set This Way
  135. ;
  136. ;           1              UP            When DTRCTRL is TRUE
  137. ;           1            DOWN            When DTRCTRL is FALSE
  138. ;           2              UP                  Always
  139. ;           3            DOWN                  Always
  140. ;           4              UP                  Always
  141. ;           5            DOWN                  Always
  142. ;           6              UP            When DCDDSR is TRUE
  143. ;           6            DOWN            When DCDDSR is FALSE
  144. ;           7              UP        For single line installations
  145. ;           7            DOWN       For multiple line installations
  146. ;           8            DOWN                  Always
  147. ;
  148. ;
  149. ;******************************************************************************
  150. ;
  151. ;
  152.     IFT    DTRCTRL EQ FALSE  OR  DCDDSR EQ FALSE
  153. ESCCHR    EQU    28        ;SMARTMODEM ESCAPE CHARACTER
  154. NEWCR    EQU    '.'        ;SMARTMODEM 'CARRIAGE RETURN' CHARACTER
  155. NEWLF    EQU    '.'        ;SMARTMODEM 'LINE FEED' CHARACTER
  156.     ELSE
  157. NEWCR    EQU    CR
  158. NEWLF    EQU    LF
  159. ESCCHR    EQU    128
  160.     ENDIF    ;DTRCTRL EQ FALSE  OR  DCDDSR EQ FALSE
  161. ;
  162. ;
  163. MISTAT    EQU    MDMISTAT    ;Returns modem input status.
  164.                 ;
  165.                 ;     Z ==> No Character Ready
  166.                 ;    NZ ==> Character is Ready
  167.                 ;
  168. ;
  169. ;
  170. ;
  171. MOSTAT    EQU    MDMOSTAT    ;Returns modem output status.
  172.                 ;
  173.                 ;     Z ==> Not Ready for Output
  174.                 ;    NZ ==> Ready for Output
  175.                 ;
  176. ;
  177. ;
  178. ;
  179.     IFT    DCDDSR
  180. MINP    EQU    MDMINP        ;Get Next Input Character from Modem Port
  181.                 ;
  182.                 ;    ??? ==> Acc ==> Input Character
  183.                 ;
  184.     ELSE
  185. MINP:    CALL    MDMINP        ;GET CHARACTER FROM MODEM
  186.     PUSH    PSW        ;SAVE IT
  187.     PUSH    D        ;SAVE OTHER REGISTERS
  188.     PUSH    H
  189.     LHLD    SMCCHK        ;POINT TO NEXT CHARACTER IN DISCONNECT STRING
  190.     LXI    D,SMNOCR
  191.     XCHG
  192.     DAD    D
  193.     CMP    M        ;THIS CHARACTER PART OF THE STRING?
  194.     XCHG            ;(CURRENT INDEX TO HL JUST IN CASE)
  195.     JZ    MABEDC        ;...YES, MIGHT BE DISCONNECT STRING
  196. RSTIDX:    LXI    H,-1        ;...NO, RESET POINTER TO START OF STRING
  197. MABEDC:    INX    H        ;UPDATE COMPARISON INDEX
  198.     SHLD    SMCCHK
  199.     LXI    D,SMNOCR    ;END OF STRING?
  200.     DAD    D
  201.     MOV    A,M
  202.     ORA    A
  203.     JNZ    NOTDSC        ;...NO, DON'T HAVE POTENTIAL DISCONNECT
  204.     CALL    CARSTS        ;...YES, GET TRUE CARRIER STATUS
  205.     JMP    RSTIDX        ;RESET INDEX TO START OF DISCONNECT STRING
  206. ;
  207. NOTDSC:    POP    H        ;RESTORE REGISTERS AND THE NEW CHAR AND EXIT
  208.     POP    D
  209.     POP    PSW
  210.     RET
  211.     ENDIF    ;DCDDSR
  212. ;
  213. ;
  214. ;
  215. MOUT    EQU    MDMOUT        ;Send a Character to the Modem Port
  216.                 ;
  217.                 ;   Character to Send ==> Acc ==> Unchanged
  218.                 ;
  219. ;
  220. ;
  221. ;
  222. MINIT:        ;Routine to initialize the Smartmodem.
  223.         ;
  224.         ;Exit Status:    None
  225.         ;
  226. ;
  227.     IFT    DTRCTRL EQ FALSE  OR  DCDDSR EQ FALSE
  228. MFIRST    EQU    $+1
  229.     MVI    A,1        ;IS THIS THE FIRST TIME WE'VE BEEN CALLED?
  230.     DCR    A
  231.     JNZ    MBOKAY        ;...NO, WE KNOW THE MODEM PORT BAUD RATE
  232.     STA    MFIRST        ;...YES, SET FLAG SO WE DON'T DO THIS AGAIN AND
  233.     IFT    SM1200        ;     SET APPROPRIATE MODEM PORT BAUD RATE
  234.     CALL    MDM1200
  235.     ELSE
  236.     CALL    MDM300
  237.     ENDIF    ;SM1200
  238.     PUSH    H        ;SEND SMARTMODEM INIT SEQUENCE TO FORCE PROPER
  239.     LXI    H,SMCMD2    ;ESCAPE CODE RECOGNITION
  240.     CALL    SMSW2
  241.     POP    H
  242. MBOKAY    EQU    $
  243.     MVI    A,0FFH        ;SET 'HAVE CARRIER' FLAG VALUE
  244.     STA    CARFLG
  245.     ENDIF    ;DTRCTRL EQ FALSE  OR  DCDDSR EQ FALSE
  246.     PUSH    H        ;SAVE REGISTERS
  247.     LXI    H,SMCMD2    ;SET DESIRED INITIALIZATION SETUP STRING
  248.     JMP    MSET1        ;REST SAME AS EXIT ROUTINE
  249. ;
  250. ;
  251. ;
  252. MEXIT:        ;Routine to return the Smartmodem to a default state.
  253.         ;Called when NBYE is terminated by the system operator.
  254.         ;
  255.         ;Exit Status:    None
  256.         ;
  257. ;
  258.     PUSH    H        ;SAVE REGISTERS
  259.     LXI    H,SMCMD4    ;SET DESIRED EXIT SETUP STRING
  260. MSET1:    PUSH    H        ;SAVE SETUP STRING POINTER
  261. MSET2    EQU    $
  262.     IFT    DTRCTRL
  263.     CALL    MDMDTROFF    ;TURN OFF DTR TO ENSURE NO CARRIER
  264.     MVI    A,3        ;WAIT A BIT
  265.     CALL    ICDELAY
  266.     CALL    MDMDTRON    ;TURN DTR BACK ON
  267.     ELSE
  268.     CALL    SMESC        ;GET CONTROL OF THE SMARTMODEM
  269.     ENDIF    ;DTRCTRL
  270.     CALL    MDM300        ;ALWAYS DO SETUP AT 300 BAUD
  271.     LXI    H,SMCMD0    ;SEND RESET STRING TO SMARTMODEM
  272.     CALL    SMSW2
  273.     JNZ    MSET2        ;KEEP TRYING IF ANY PROBLEM
  274.     MVI    A,5        ;WAIT FOR EXTRA INTER-COMMAND DELAY FOR RESET
  275.     CALL    ICDELAY
  276.     LXI    H,SMCMD1    ;SEND DESIRED SWITCH POSITIONS
  277.     CALL    SMSW2
  278.     JNZ    MSET2        ;KEEP TRYING IF ANY PROBLEM
  279.     POP    H        ;FOLLOW WITH DESIRED SETUP PARAMETERS
  280.     CALL    SMSW2
  281.     JNZ    MSET1        ;AND TRY AGAIN IF ANY PROBLEM
  282.     POP    H        ;RESTORE REGISTERS AND EXIT
  283.     RET
  284. ;
  285. ;
  286. ;
  287. MRING:        ;Routine to return current ring status.  Uses the 'RING' result
  288.         ;code from the Smartmodem to determine ringing.
  289.         ;
  290.         ;Exit Status:    Z and NC ==> Not Ringing
  291.         ;           NZ and NC ==> Ringing
  292.         ;
  293. ;
  294.     CALL    SMCHK        ;KEEP CHECKING MODEM STATUS
  295. SMRPLY    EQU    $+1
  296.     MVI    A,0FFH        ;GET RING STATUS
  297.     PUSH    PSW        ;SAVE IT
  298.     MVI    A,0FFH        ;RESET REPLY FLAG REGARDLESS
  299.     STA    SMRPLY
  300.     POP    PSW        ;RESTORE RING STATUS
  301.     CPI    3        ;SET FLAGS BASED ON WHETHER WE HAD A RING
  302.     JZ    MR1
  303.     XRA    A        ;...NOT RINGING
  304.     RET
  305. ;
  306. MR1:    ORA    A        ;...RINGING
  307.     RET
  308. ;
  309. ;
  310. ;
  311. MANSWER:    ;Routine to answer the telephone.  Tells Smartmodem to answer
  312.         ;the telephone, then waits for the Smartmodem response code.
  313.         ;If the response is 'CONNECT' or 'CONNECT 1200' then a
  314.         ;connected status is returned.  If the response is anything
  315.         ;else, or if no response is received within 60 seconds, then
  316.         ;no carrier status is returned.  If a connection is
  317.         ;established, the modem polling at 'SMCHK' (invoked through
  318.         ;DELAY and KDELAY) is disabled.
  319.         ;
  320.         ;Exit Status:     Z ==> No Carrier
  321.         ;        NZ ==> Connected with a carrier
  322.         ;
  323. ;
  324.     PUSH    B        ;SAVE REGISTERS
  325.     PUSH    H
  326.     LXI    H,SMCMD3
  327.     CALL    SMSW60        ;SEND ANSWER COMMAND AND WAIT FOR RESPONSE
  328.     CPI    0FFH        ;CHECK FOR RESPONSE
  329.     JZ    MAEXIT        ;RETURN WITH ZERO STATUS IF NONE
  330.     CPI    4        ;HAVE A CONNECTION?
  331.     JZ    MANSWD        ;...YES, AT 110 OR 300 BAUD
  332.     ORA    A
  333.     JZ    MANSWD        ;...YES, AT 1200 BAUD
  334.     XRA    A        ;...NO, RETURN ZERO STATUS
  335.     JMP    MAEXIT
  336. ;
  337. MANSWD    EQU    $
  338.     IFT    SM1200
  339.     STA    MBRATE        ;STORE BAUD RATE FLAG FOR THE CONNECTION
  340.     ENDIF    ;SM1200
  341.     MVI    A,RET        ;DISABLE 'SMCHK' POLLING
  342.     STA    SMCRTN
  343.     ORA    A        ;FORCE NON-ZERO STATUS TO SHOW THE CONNECTION
  344. MAEXIT:    POP    H        ;RESTORE REGISTERS AND EXIT
  345.     POP    B
  346.     RET
  347. ;
  348. ;
  349. ;
  350. MBAUD:        ;Routine to determine the appropriate baud rate.
  351.         ;
  352.         ;    ??? ==> Acc ==> Baud Rate Indicator (if known)
  353.         ;                0 ==>  110
  354.         ;                1 ==>  300
  355.         ;                5 ==> 1200
  356.         ;
  357.         ;Exit Status:     C ==> Couldn't Determine Baud Rate
  358.         ;        NC ==> Baud Rate Indicator is Set
  359.         ;
  360. ;
  361.     IFT    SM1200
  362. MBRATE    EQU    $+1
  363.     MVI    A,0        ;WAS THE CONNECTION AT 1200 BAUD?
  364.     ORA    A
  365.     JNZ    LOBAUD        ;...NO, HAS TO BE 110 OR 300
  366.     CALL    MDM1200        ;...YES, SET CORRECT BAUD RATE AND EXIT
  367.     MVI    A,5        ;     WITH BAUD RATE INDICATOR AND NO CARRY
  368.     ORA    A
  369.     RET
  370. LOBAUD    EQU    $
  371.     ENDIF    ;SM1200
  372. ;
  373.     IFF    OK110        ;IF 110 BAUD NOT ALLOWED, THEN MUST BE 300
  374.     MVI    A,1        ;...SO SET INDICATOR AND EXIT WITH NO CARRY
  375.     RET
  376.     ELSE            ;ELSE NEED TO TRY BOTH 110 AND 300 BAUD
  377.     CALL    MDM300        ;TRY 300 BAUD
  378.     CALL    MCHRCK        ;WAIT FOR A CHARACTER (OR LOSS OF CARRIER)
  379.     RC            ;EXIT IF CARRIER LOST
  380.     MVI    A,1        ;...JUST IN CASE
  381.     RZ            ;DONE IF WE FOUND THE RIGHT SPEED
  382.     CALL    MDM110        ;ELSE NOW TRY 110
  383.     CALL    MCHRCK
  384.     RC            ;EXIT IF CARRIER LOST
  385.     MVI    A,0        ;...JUST IN CASE
  386.     RZ            ;DONE IF WE FOUND THE RIGHT SPEED
  387.     STC            ;ELSE RETURN WITH UNKNOWN STATUS
  388.     RET
  389.     ENDIF    ;OK110
  390. ;
  391. ;
  392. ;
  393. MCARRIER:    ;Routine to check current carrier status.
  394.         ;
  395.         ;Exit Status:    Z ==> No Carrier
  396.         ;           NZ ==> Carrier
  397.         ;
  398. ;
  399.     IFT    DCDDSR
  400.     JMP    MDMDSR        ;DCD TIED TO DSR -- JUST RETURN DSR STATUS
  401.     ELSE
  402. CARFLG    EQU    $+1
  403.     MVI    A,0FFH        ;GET CARRIER FLAG
  404.     ORA    A        ;SET APPROPRIATE STATUS AND EXIT
  405.     RET
  406.     ENDIF    ;DCDDSR
  407. ;
  408. ;
  409. ;
  410. DELAY:        ;Routine to delay .1 second.  Polls the modem as part of the
  411.         ;delay loop, and buffers any incoming data (if enabled).
  412.         ;
  413.         ;Exit Status:    None
  414.         ;
  415. ;
  416. USEC    EQU    (41+SMCCYL+MHZ/2)/MHZ    ;MICROSECONDS PER DELAY LOOP
  417. LOOPS    EQU    4*((25000+USEC/2)/USEC)    ;LOOPS NEEDED TO KILL .1 SECOND
  418. ;
  419.     PUSH    B        ;SAVE REGISTERS
  420.     LXI    B,LOOPS        ;SET NBR OF DELAY LOOPS FOR .1 SECOND
  421. DLAY1:    CALL    SMCHK        ;CHECK FOR SMARTMODEM INPUT AND BUFFER IF SO
  422.     DCX    B        ;DO ENOUGH TIMES TO TAKE APPROX .1 SECOND
  423.     MOV    A,B
  424.     ORA    C
  425.     JNZ    DLAY1
  426.     POP    B        ;RESTORE REGISTERS AND EXIT
  427.     RET
  428. ;
  429. ;
  430. ;
  431. KDELAY:        ;Routine to delay 1 millisecond.  Polls the modem as part of
  432.         ;the delay loop, and buffers any incoming data (if enabled).
  433.         ;
  434.         ;Exit Status:    None
  435.         ;
  436. ;
  437. KLOOPS    EQU    (1000+USEC/2)/USEC
  438. ;
  439.     PUSH    B
  440.     LXI    B,KLOOPS
  441.     JMP    DLAY1
  442. ;
  443. ;
  444. ;
  445. SMCHK:        ;Routine to check the Smartmodem for pending characters and
  446.         ;buffer any which may be available.  Used prior to establishing
  447.         ;a connection to receive the 'RING', 'CONNECT', 'OK', and
  448.         ;'CONNECT 1200' reply codes from the Smartmodem.
  449.         ;
  450.         ;Exit Status:    None
  451.         ;
  452. ;
  453. SMCCYL    EQU    28+MISCYL    ;CYCLES USED WHEN NO CHAR READY
  454. ;
  455.     CALL    MDMISTAT    ;ANY CHARACTERS READY FROM MODEM?
  456. SMCRTN:    RZ            ;...NO, NOTHING TO DO
  457.     CALL    MDMINP        ;...YES, GET THE CHARACTER
  458.     PUSH    D        ;SAVE REGISTERS
  459.     PUSH    H
  460. BFROFS    EQU    $+1
  461.     LXI    D,0        ;COMPUTE POSITION IN BUFFER FOR THIS CHARACTER
  462.     LXI    H,SMBUFR
  463.     DAD    D
  464.     MOV    M,A        ;AND STORE THE CHARACTER
  465.     SUI    LF        ;UPDATE OFFSET CIRCULARLY UNLESS A LINE FEED
  466.     JZ    NXTOFS        ;IN WHICH CASE USE THE START OF THE BUFFER
  467.     IFT    NEWLF NE LF
  468.     ADI    LF-NEWLF
  469.     JZ    NXTOFS
  470.     ENDIF    ;NEWLF NE LF
  471.     MOV    A,E
  472.     INR    A
  473.     ANI    00001111B
  474. NXTOFS:    STA    BFROFS
  475.     MOV    A,M        ;WAS CHARACTER A LINE FEED?
  476.     IFT    NEWLF NE LF
  477.     CPI    NEWLF
  478.     JZ    C4SMR
  479.     ENDIF    ;NEWLF NE LF
  480.     CPI    LF
  481.     JNZ    SMCXIT        ;...NO, WE'RE DONE
  482. C4SMR:    LXI    H,SMBUFR    ;...YES, CHECK FOR SMARTMODEM RESPONSE CODE
  483.     LXI    D,SMCODES
  484.     CALL    SEARCH
  485.     JNZ    SMCXIT        ;DONE IF NOT A SMARTMODEM RESPONSE CODE
  486.     STA    SMRPLY        ;ELSE FIRST FLAG THE RESPONSE WE JUST RECEIVED
  487. SMCXIT:    POP    H        ;RESTORE REGISTERS AND EXIT
  488.     POP    D
  489.     RET
  490. ;
  491. ;
  492. ;
  493.     IFF    DCDDSR
  494. ;
  495. CARSTS:        ;Routine to get the true carrier status from the Smartmodem
  496.         ;and store at 'CARFLG'.
  497.         ;
  498.         ;    Store 0 at CARFLG if no carrier, 0FFH otherwise.
  499.         ;
  500.         ;Exit Status:    None
  501.         ;
  502. ;
  503.     CALL    SMESC        ;GET CONTROL OF THE MODEM
  504.     PUSH    B        ;SAVE REGISTERS
  505.     PUSH    D
  506.     PUSH    H
  507.     LXI    H,SMCMD5    ;ASK FOR CURRENT VALUE OF STATUS REGISTER 15
  508.     CALL    SMSEND
  509.     MVI    A,RET        ;DISABLE 'SMCHK' POLLING
  510.     STA    SMCRTN
  511.     LXI    B,2000        ;WAIT 2 SECONDS FOR RESPONSE
  512.     MVI    D,0        ;SET INITIAL REGISTER VALUE
  513.     MVI    E,3        ;NUMBER OF EXPECTED DIGITS
  514. CSTS1:    CALL    MISTAT        ;WAIT FOR A CHARACTER
  515.     JZ    CSTS2
  516.     CALL    MINP        ;GET THE CHARACTER
  517.     SUI    '0'        ;DIGIT?
  518.     CPI    9+1
  519.     JNC    CSTS2        ;...NO
  520.     MOV    H,A        ;...YES, UPDATE REGISTER VALUE
  521.     MOV    A,D
  522.     ADD    A
  523.     MOV    D,A
  524.     ADD    A
  525.     ADD    A
  526.     ADD    D
  527.     ADD    H
  528.     MOV    D,A
  529.     DCR    E        ;DONE WITH THE REGISTER VALUE?
  530.     JZ    CSTS3        ;...YES
  531. CSTS2:    CALL    KDELAY        ;...NO, WAIT FOR NEXT CHARACTER
  532.     DCX    B
  533.     MOV    A,B
  534.     ORA    C
  535.     JNZ    CSTS1
  536.     POP    H        ;NO RESPONSE, SO START OVER
  537.     POP    D
  538.     POP    B
  539.     JMP    CARSTS
  540. ;
  541. CSTS3:    MVI    B,150        ;WAIT FOR .15 SECOND WITH NO INPUT
  542. CSTS4:    CALL    KDELAY        ;OR THE TERMINATING LINE FEED
  543.     CALL    MISTAT
  544.     JZ    CSTS5
  545.     CALL    MINP
  546.     CPI    LF
  547.     JZ    CSTS6
  548.     IFT    NEWLF NE LF
  549.     CPI    NEWLF
  550.     JZ    CSTS6
  551.     ENDIF    ;NEWLF NE LF
  552.     MVI    B,150+1
  553. CSTS5:    DCR    B
  554.     JNZ    CSTS4
  555. CSTS6:    MOV    A,D        ;GET REGISTER VALUE
  556.     ANI    01000000B    ;ISOLATE CARRIER STATUS
  557.     JZ    CSEXIT        ;DONE IF NO CARRIER
  558.     LXI    H,SMCMD6    ;ELSE FIRST GO BACK ON LINE
  559.     CALL    SMSW2
  560.     MVI    A,RET        ;DISABLE 'SMCHK' POLLING
  561.     STA    SMCRTN
  562.     MVI    A,0FFH        ;AND SET 'HAVE CARRIER' FLAG VALUE
  563. CSEXIT:    STA    CARFLG        ;STORE APPROPRIATE CARRIER FLAG AND EXIT
  564.     POP    H
  565.     POP    D
  566.     POP    B
  567.     RET
  568.     ENDIF    ;DCDDSR
  569. ;
  570. ;
  571. ;
  572.     IFT    DTRCTRL EQ FALSE  OR  DCDDSR EQ FALSE
  573. ;
  574. SMESC:        ;Routine to force the Smartmodem into command mode with the
  575.         ;Smartmodem escape sequence.  Waits for the 'OK' response from
  576.         ;the Smartmodem, and keeps trying if not received.
  577.         ;
  578.         ;Exit Status:    None
  579.         ;
  580. ;
  581.     MVI    A,4        ;DELAY .6 SECOND (.4 + .2 ADDED BY 'SMSEND')
  582.     CALL    ICDELAY
  583.     PUSH    H        ;SAVE REGISTERS
  584.     LXI    H,ESCSEQ    ;SEND THE ESCAPE CHARACTER SEQUENCE AND WAIT
  585.     CALL    SMSW2        ;FOR 'OK' STATUS
  586.     POP    H        ;RESTORE REGISTERS IN ANTICIPATION
  587.     RZ            ;AND EXIT IF WE'VE SUCCESSFULLY 'ESCAPED'
  588.     PUSH    H        ;ELSE TRY AN 'AT' IN CASE WE WEREN'T ON LINE
  589.     LXI    H,SMCMD4
  590.     CALL    SMSW2
  591.     POP    H
  592.     RZ
  593.     JMP    SMESC        ;KEEP TRYING UNTIL WE SUCCEED
  594. ;
  595.     ENDIF    ;DTRCTRL EQ FALSE  OR  DCDDSR EQ FALSE
  596. ;
  597. ;
  598. ;
  599. SEARCH:        ;Routine to search a table for a specified string.
  600.         ;If found returns zero status and a zero-based index number
  601.         ;for the matched string.  If not found returns non-zero status.
  602.         ;
  603.         ;           ??? => Acc => Index number of matched entry if
  604.         ;                 match found; else 0FFH
  605.         ;
  606.         ;  Ptr to table to =>  DE => ???
  607.         ;  search
  608.         ;
  609.         ;  Ptr to 1st char =>  HL => Pointer to char after last matched
  610.         ;  of string             char if matched; else unchanged
  611.         ;
  612.         ;
  613.         ;Exit Status:  Z ==> Match found
  614.         ;          NZ ==> No match in specified table
  615.         ;
  616.         ;Table Structure:    Consecutive strings with high-order bit
  617.         ;            of last char in each string set.  Zero
  618.         ;            byte as first (and only) byte of a 
  619.         ;            string terminates the table.
  620.         ;
  621.         ;            e.g.    DB  'STRING','1'+080H
  622.         ;                DB  'STRING','2'+080H
  623.         ;                DB  0   ;END OF THE TABLE
  624.         ;
  625. ;
  626.     PUSH    B        ;SAVE REGISTERS
  627.     PUSH    H        ;WITH STRING POINTER ON TOP
  628.     MVI    B,0        ;INIT TABLE INDEX
  629. CHKCHR:    LDAX    D        ;GET CHAR FROM TABLE
  630.     ANI    01111111B    ;DON'T INCLUDE END FLAG IN COMPARE
  631.     CMP    M        ;MATCH THE STRING?
  632.     JNZ    NOMTCH        ;...NO
  633.     LDAX    D        ;...YES, CHECK FOR END OF THE TABLE ENTRY
  634.     ANI    10000000B    ;     AND IF SO WE'VE FOUND A MATCH
  635.     INX    D        ;(BUMP POINTERS REGARDLESS)
  636.     INX    H
  637.     JNZ    MATCH
  638.     JMP    CHKCHR        ;ELSE KEEP CHECKING THE CURRENT STRING
  639. ;
  640. MATCH:    XRA    A        ;FOUND A MATCH -- SET ZERO FLAG
  641.     MOV    A,B        ;AND RETURN WITH INDEX IN ACC
  642.     POP    B        ;POP STRING POINTER OFF STACK
  643.     POP    B        ;AND RESTORE ONLY THE BC PAIR
  644.     RET
  645. ;
  646. NOMTCH:    LDAX    D        ;FIND END OF THE CURRENT TABLE ENTRY
  647.     ANI    10000000B    ;(AND BEGINNING OF THE NEXT)
  648.     INX    D
  649.     JZ    NOMTCH
  650.     POP    H        ;RESTORE POINTER TO STRING TO CHECK
  651.     PUSH    H        ;BUT KEEP ON STACK
  652.     INR    B        ;BUMP TABLE INDEX NUMBER
  653.     LDAX    D        ;SEE IF WE'VE EXHAUSTED THE TABLE
  654.     ORA    A
  655.     JNZ    CHKCHR        ;AND KEEP CHECKING IF NOT
  656.     DCR    A        ;ELSE FORCE NON-ZERO STATUS
  657.     POP    H        ;RESTORE REGISTERS AND EXIT
  658.     POP    B
  659.     RET
  660. ;
  661. ;
  662. ;
  663. MCHRCK:        ;Routine to wait for a character from the modem or a loss of
  664.         ;carrier.  Carrier must be lost for 2 seconds before it will
  665.         ;report lost carrier (so call waiting doesn't kill us).  If
  666.         ;a character is input, the status relative to the set of
  667.         ;characters CR, LF, and Ctrl-C  is returned.  The routine will
  668.         ;not wait longer than 5 seconds.
  669.         ;
  670.         ;Exit Status:     C ==> Carrier Lost
  671.         ;      Z and NC ==> Got one of the valid characters
  672.         ;     NZ and NC ==> No valid character received in 5 seconds
  673.         ;
  674. ;
  675.     PUSH    B
  676.     MVI    B,50        ;MAX TIME TO WAIT FOR A CHARACTER
  677. MCC1:    CALL    MDMISTAT    ;ANYTHING READY?
  678.     JNZ    MCC4        ;...YES, GET IT AND EXIT
  679.     MVI    C,20        ;(JUST IN CASE CARRIER'S LOST, SET TIMEOUT)
  680. MCC2:    CALL    MCARRIER    ;...NO, CHECK FOR CARRIER
  681.     JNZ    MCC3        ;    AND CONTINUE IF OKAY
  682.     CALL    DELAY        ;ELSE WAIT FOR CARRIER TO COME BACK
  683.     DCR    C
  684.     JNZ    MCC2
  685.     STC            ;AND ABORT IF IT DOESN'T
  686.     POP    B
  687.     RET
  688. ;
  689. MCC3:    CALL    DELAY
  690.     DCR    B
  691.     JNZ    MCC1
  692.     POP    B
  693.     IFF    DCDDSR
  694.     CALL    CARSTS        ;TIMED OUT -- GET TRUE CARRIER STATUS
  695.     ENDIF    ;DCDDSR
  696. NZNC:    MVI    A,0FFH        ;FORCE NON-ZERO STATUS AND NO CARRY
  697.     ORA    A
  698.     RET
  699. ;
  700. MCC4:    CALL    MDMINP        ;GET THE WAITING CHARACTER
  701.     POP    B        ;RESTORE REGISTERS BEFORE PENDING EXIT
  702.     CPI    CR        ;SEE IF IT'S ONE OF THE EXPECTED ONES
  703.     RZ            ;AND EXIT IF SO
  704.     CPI    LF
  705.     RZ
  706.     CPI    'C'-040H
  707.     RZ
  708.     JMP    NZNC        ;ELSE EXIT WITH NZ AND NC
  709. ;
  710. ;
  711. ;
  712. SMSW60:        ;Same as SMSW2, but maximum wait time is 60 seconds.
  713.         ;
  714. ;
  715.     PUSH    B        ;SAVE REGISTERS
  716.     PUSH    H
  717.     LXI    B,600        ;WAIT MAX OF 60 SECONDS FOR REPLY
  718.     JMP    SMSALT        ;REST IDENTICAL TO 'SMSOK2'
  719. ;
  720. ;
  721. ;
  722. SMSW2:        ;Routine to send a command to the Smartmodem and wait for the
  723.         ;response.  The maximum wait time is 2 seconds.
  724.         ;
  725.         ;        ??? ==> Acc ==> Smartmodem Reply Code (See SMCODES)
  726.         ;                or 0FFH if no reply in 2 seconds
  727.         ;
  728.         ; Ptr to String ==>  HL ==> Unchanged
  729.         ; (0 terminated)
  730.         ;
  731.         ;Exit Status:     Z ==> Reply was 'OK'
  732.         ;        NZ ==> Reply was other than 'OK'
  733.         ;        
  734. ;
  735.     PUSH    B        ;SAVE REGISTERS
  736.     PUSH    H
  737.     LXI    B,20        ;WAIT MAX OF 2 SECONDS FOR REPLY
  738. SMSALT:    MVI    A,RZ        ;ENABLE 'SMCHK' POLLING
  739.     STA    SMCRTN
  740.     CALL    SMSEND
  741. W4RPLY:    CALL    DELAY
  742.     LDA    SMRPLY        ;GET REPLY FLAG
  743.     PUSH    PSW        ;SAVE IT JUST IN CASE
  744.     CPI    0FFH        ;HAVE REPLY?
  745.     JNZ    HAVRPY        ;...YES
  746.     POP    PSW        ;...NO, BALANCE STACK AND KEEP WAITING
  747.     DCX    B
  748.     MOV    A,B
  749.     ORA    C
  750.     JNZ    W4RPLY
  751.     MVI    A,0FFH        ;NO REPLY IN MAX TIME -- RETURN 0FFH
  752.     PUSH    PSW        ;(RESULT EXPECTED ON STACK)
  753. HAVRPY:    MVI    A,0FFH        ;RESET REPLY FLAG
  754.     STA    SMRPLY
  755.     POP    PSW        ;RESTORE REPLY RESULT
  756.     CPI    5        ;SET STATUS BASED ON 'OK'
  757.     POP    H        ;RESTORE REGISTERS AND EXIT
  758.     POP    B
  759.     RET
  760. ;
  761. ;
  762. ;
  763. SMSEND:        ;Routine to send a null-terminated string to the Smartmodem.
  764.         ;
  765.         ;    Ptr to String ==> HL ==> Ptr to String Terminator
  766.         ;    (0 terminated)
  767.         ;
  768.         ;Exit Status:    None
  769.         ;
  770. ;
  771.     MVI    A,2        ;ALWAYS WAIT .2 SECONDS BEFORE SENDING COMMAND
  772.     CALL    ICDELAY        ;(TO PROVIDE INTER-COMMAND DELAY)
  773. SMS1:    MOV    A,M        ;GET NEXT CHARACTER OF STRING
  774.     ORA    A        ;END OF STRING?
  775.     RZ            ;...YES, EXIT
  776.     CALL    MDMOUT        ;...NO, SEND TO SMARTMODEM
  777.     INX    H        ;    AND CONTINUE WITH NEXT CHARACTER
  778.     JMP    SMS1
  779. ;
  780. ;
  781. ;
  782. ICDELAY:    ;Routine to wait a specified number of .1 second intervals.
  783.         ;Used to provide Smartmodem inter-command delays.
  784.         ;
  785.         ;    Nbr of Milliseconds to delay ==> Acc ==> ???
  786.         ;
  787. ;
  788.     PUSH    B        ;SAVE REGISTERS
  789.     MOV    B,A        ;SET LOOP COUNTER
  790. ICDLAY:    CALL    DELAY        ;DELAY A TENTH OF A SECOND
  791.     DCR    B        ;DONE?
  792.     JNZ    ICDLAY        ;...NO, CONTINUE
  793.     POP    B        ;...YES, RESTORE REGISTERS AND EXIT
  794.     RET
  795. ;
  796. ;
  797. ;
  798. ;******************************************************************************
  799. ;
  800. ;   Data Constants
  801. ;
  802. ;
  803. EC100    EQU    ESCCHR/100
  804. EC10    EQU    (ESCCHR-100*EC100)/10
  805. EC1    EQU    ESCCHR-100*EC100-10*EC10
  806. ;
  807. NCR100    EQU    NEWCR/100
  808. NCR10    EQU    (NEWCR-100*NCR100)/10
  809. NCR1    EQU    NEWCR-100*NCR100-10*NCR10
  810. ;
  811. NLF100    EQU    NEWLF/100
  812. NLF10    EQU    (NEWLF-100*NLF100)/10
  813. NLF1    EQU    NEWLF-100*NLF100-10*NLF10
  814. ;
  815. SMCMD0:    DB    'AT Z'
  816.     IFT    NEWCR NE CR
  817.     DB    NEWCR
  818.     ENDIF    ;NEWCR NE CR
  819.     DB    CR,0
  820. ;
  821. SMCMD1:    DB    'AT E0 M0 Q0 V1'
  822.     IFT    SM1200
  823.     DB    ' X1'
  824.     ENDIF    ;SM1200
  825.     IFT    NEWCR NE CR
  826.     DB    NEWCR
  827.     ENDIF    ;NEWCR NE CR
  828.     DB    CR,0
  829. ;
  830. SMCMD2:    DB    'AT'
  831.     DB    'S0=0'
  832.     DB    'S2=',EC100+'0',EC10+'0',EC1+'0'
  833.     DB    'S3=',NCR100+'0',NCR10+'0',NCR1+'0'
  834.     DB    'S4=',NLF100+'0',NLF10+'0',NLF1+'0'
  835.     DB    'S10=20'
  836.     DB    'S12=20'
  837.     IFT    NEWCR NE CR
  838.     DB    NEWCR
  839.     ENDIF    ;NEWCR NE CR
  840.     DB    CR,0
  841. ;
  842. SMCMD3:    DB    'AT A'
  843.     IFT    NEWCR NE CR
  844.     DB    NEWCR
  845.     ENDIF    ;NEWCR NE CR
  846.     DB    CR,0
  847. ;
  848. SMCMD4:    DB    'AT'
  849.     IFT    NEWCR NE CR
  850.     DB    NEWCR
  851.     ENDIF    ;NEWCR NE CR
  852.     DB    CR,0
  853. ;
  854. SMCMD5:    DB    'ATS15?'
  855.     IFT    NEWCR NE CR
  856.     DB    NEWCR
  857.     ENDIF    ;NEWCR NE CR
  858.     DB    CR,0
  859. ;
  860. SMCMD6:    DB    'ATO'
  861.     IFT    NEWCR NE CR
  862.     DB    NEWCR
  863.     ENDIF    ;NEWCR NE CR
  864.     DB    CR,0
  865. ;
  866. SMBUFR:    DS    16
  867. ;
  868. ESCSEQ:    DB    ESCCHR,ESCCHR,ESCCHR,0
  869. ;
  870. SMCCHK:    DW    0        ;OFFSET IN 'SMNOCR' STRING FOR NEXT INPUT CHAR
  871. ;
  872. SMNOCR:    DB    NEWCR,NEWLF    ;STRING TO LOOK FOR FROM SMARTMODEM
  873.     DB    'NO CARRIER'    ;IN CASE CARRIER LOST
  874.     DB    NEWCR,NEWLF,0
  875. ;
  876. ;
  877. HIBIT    EQU    10000000B
  878. ;
  879. SMCODES:    ;Table of Smartmodem Result Codes.  Order is reversed from that
  880.         ;listed in the Hayes book so 'CONNECT 1200' precedes 'CONNECT'.
  881.         ;Otherwise either result code would match 'CONNECT'.  Result
  882.         ;code indexes returned by 'SEARCH' are consequently as follows:
  883.         ;
  884.         ;    0  ==>  CONNECT 1200
  885.         ;    1  ==>  ERROR
  886.         ;    2  ==>  NO CARRIER
  887.         ;    3  ==>  RING
  888.         ;    4  ==>  CONNECT
  889.         ;    5  ==>  OK
  890. ;
  891.     DB    'CONNECT 120','0'+HIBIT
  892.     DB    'ERRO','R'+HIBIT
  893.     DB    'NO CARRIE','R'+HIBIT
  894.     DB    'RIN','G'+HIBIT
  895.     DB    'CONNEC','T'+HIBIT
  896.     DB    'O','K'+HIBIT
  897. ;
  898. ;
  899. ;               ***  End of Smartmodem Insert  ***
  900. ;
  901. ;******************************************************************************
  902.