home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / mex / mxm-rv16.asm < prev    next >
Encoding:
Assembly Source File  |  1994-07-13  |  15.1 KB  |  494 lines

  1.     TITLE    'MEX RACAL-VADIC VA212 OVERLAY V1.6'
  2. ;
  3. ; (DELETE ABOVE TITLE LINE IF ASSEMBLING WITH ASM)
  4. ;
  5. ; MXM-RV16.ASM  Current version 6 Sep 85
  6. ;
  7. ; Racal Vadic VA212 overlay for MEX: revision 1.0
  8. ;  Written 20 May 1984 by Dave Mabry
  9. ;  Adapted using information and excerpts from Ron Fowler's
  10. ;   overlay for the PMMI modem.
  11. ;
  12. ; Please leave any bug reports or requests on TCBBS in Dearborn,
  13. ;  Michigan (313-846-6127) or Royal Oak RCPM (313-759-6569)
  14. ;  or call me at 313-956-5703 (voice).        mabry
  15. ;
  16. ; Updates:
  17. ;  MXO-RV10.ASM
  18. ;   5/20/84...Original release.
  19. ;  MXO-RV11.ASM
  20. ;   5/21/84...Fixed bug in Busy handler that left modem in
  21. ;    "terminal" mode.  This caused no problems but it
  22. ;    wasn't "clean".
  23. ;  MXO-RV12.ASM
  24. ;   5/22/84...Added code to ensure the modem is left in
  25. ;    "idle" state after busy signal returned.
  26. ;    Major rewrite with debugging done using a data line
  27. ;    monitor.  This version should work without problems
  28. ;    on all systems.
  29. ;  MXM-RV14.ASM
  30. ;   11/18/84...Modified to take advantage of the two new return
  31. ;    codes available on MEX V1.1x (no-ring and no-dialtone).
  32. ;    Also used MXM rather than MXO as suggested by Ron F.
  33. ;    Version skipped 1.3 since someone already released one
  34. ;    that I chose not to incorporate.  It supported the
  35. ;    Racal-Vadic 3451 Auto Dial with an assembly-time equate,
  36. ;    but there is another overlay that I wrote (MXO-RT12.ASM)
  37. ;    that supports it better.
  38. ;  MXM-RV15.ASM
  39. ;   6/29/85...Modified to work with MEX PLUS (V1.3)
  40. ;  MXM-RV16.ASM
  41. ;   9/6/85...Made generic to work with MEX and MEX Plus.
  42. ;    Use MXPLUS equate to get different version.
  43. ;
  44. ; Note that unlike the Hayes modem, the Racal Vadic does not
  45. ;  have an ascii command that will cause a disconnect.  Therefore
  46. ;  for that feature of MEX to work properly, your normal overlay
  47. ;  for your machine must be able to toggle DTR in the DISCV routine.
  48. ;
  49. ; This overlay will work with any other overlay that terminates
  50. ; prior to 0B00H.
  51. ;
  52. VERS    EQU    16        ; Version number
  53. FALSE    EQU    0
  54. TRUE    EQU    0FFH
  55. MXPLUS    EQU    FALSE        ; True -> Mex Plus, false -> MEX
  56. ;
  57. ;
  58. ; SYSTEM CONSTANTS
  59. ;
  60. NDISCV    EQU    015FH        ; Modem disconnect routine
  61. DIALV    EQU    0162H        ;LOCATION OF DIAL VECTOR IN OVERLAY
  62. DISCV    EQU    0165H        ;LOCATION OF DISCONNECT VECTOR IN OVERLAY
  63. DIALOC    EQU    0B00H        ;DIALING CODE GOES HERE
  64. SMTABL    EQU    0D55H        ; Smart modem INIT, SSET, De-INIT routines
  65. ;
  66. ;
  67. ; MEX service processor stuff ... MEX supports an overlay service
  68. ; processor, located at 0D00H (and maintained at this address from
  69. ; version to version).  If your overlay needs to call BDOS for any
  70. ; reason, it should call MEX instead; function calls below about
  71. ; 240 are simply passed on to the BDOS (console and list I/O calls
  72. ; are specially handled to allow modem port queueing, which is why
  73. ; you should call MEX instead of BDOS).  MEX uses function calls
  74. ; above about 244 for special overlay services (described below).
  75. ;
  76. ; Some sophisticated overlays may need to do file I/O; if so, use
  77. ; the PARSFN MEX call with a pointer to the FCB in DE to parse out
  78. ; the name.  This FCB should support a spare byte immediately pre-
  79. ; ceeding the actual FCB (to contain user # information).  If you've
  80. ; used MEX-10 for input instead of BDOS-10 (or you're parsing part
  81. ; of a SET command line that's already been input), then MEX will
  82. ; take care of DU specs, and set up the FCB accordingly.  There-
  83. ; after all file I/O calls done through the MEX service processor
  84. ; will handle drive and user with no further effort necessary on
  85. ; the part of the programmer.
  86. ;
  87. MEX    EQU    0D00H        ;address of the service processor
  88. INMDM    EQU    255        ;get char from port to A, CY=no more in 100 ms
  89. TIMER    EQU    254        ;delay 100ms * reg B
  90. TMDINP    EQU    253        ;B=# secs to wait for char, cy=no char
  91. CHEKCC    EQU    252        ;check for ^C from KBD, Z=present
  92. SNDRDY    EQU    251        ;test for modem-send ready
  93. RCVRDY    EQU    250        ;test for modem-receive ready
  94. SNDCHR    EQU    249        ;send a character to the modem (after sndrdy)
  95. RCVCHR    EQU    248        ;recv a char from modem (after rcvrdy)
  96. LOOKUP    EQU    247        ;table search: see CMDTBL comments for info
  97. PARSFN    EQU    246        ;parse filename from input stream
  98. BDPARS    EQU    245        ;parse baud-rate from input stream
  99. SBLANK    EQU    244        ;scan input stream to next non-blank
  100. EVALA    EQU    243        ;evaluate numeric from input stream
  101. LKAHED    EQU    242        ;get nxt char w/o removing from input
  102. GNC    EQU    241        ;get char from input, cy=1 if none
  103. ILP    EQU    240        ;inline print
  104. DECOUT    EQU    239        ;decimal output
  105. PRBAUD    EQU    238        ;print baud rate
  106. PRNTBL    EQU    237        ;print MEX format table (HL)
  107. PRID    EQU    236        ;print MEX ID string on console
  108. ONOFF    EQU    235        ;parse on/offfrom input stream (a=0 or 1,
  109.                 ; cy=error)
  110. ;
  111. ;
  112. CONOUT    EQU    2        ;simulated BDOS function 2: console char out
  113. PRINT    EQU    9        ;simulated BDOS function 9: print string
  114. INBUF    EQU    10        ;input buffer, same structure as BDOS 10
  115. ;
  116. ;
  117. CR    EQU    0DH
  118. LF    EQU    0AH
  119. ;
  120. ;
  121. IF    MXPLUS            ; For Mex Plus overlay format
  122.  
  123.     ORG    100H
  124.     DB    0C3H        ; Identify 8080 overlay
  125.  
  126.     ORG    NDISCV
  127.     RET
  128.  
  129. ENDIF
  130.  
  131.     ORG    DIALV        ;OVERLAY THE DIALING VECTOR
  132.     JMP    DIAL
  133. ;    
  134. ;
  135. ; This is the DIAL routine called by MEX to dial a digit. The digit
  136. ; to be dialed is passed in the A register.  Note that two special
  137. ; codes must be intercepted as non-digits: 254 (start dial sequence)
  138. ; and 255 (end-dial sequence).  Mex will always call DIAL with 254
  139. ; in the accumulator prior to dialing a number.  Mex will also call
  140. ; dial with 255 in A as an indication that dialing is complete. Thus,
  141. ; the overlay may use these values to "block" the number, holding it
  142. ; in a buffer until it is completely assembled (in fact, that's the
  143. ; scheme employed here for the Racal Vadic).
  144. ;
  145. ; After the 254-start-dial sequence, MEX will call the overlay with
  146. ; digits, one-at-a-time.  MEX will make no assumptions about the dig-
  147. ; its, and will send each to the DIAL routine un-inspected (some modems,
  148. ; like the Smartmodem, allow special non-numeric characters in the
  149. ; phone number, and MEX may make no assumptions about these).
  150. ;
  151. ; After receiving the end-dial sequence (255) the overlay must take
  152. ; whatever end-of-dial actions are necessary *including* waiting for
  153. ; carrier at the distant end.  The overlay should monitor the keyboard
  154. ; during this wait (using the MEX keystat service call), and return
  155. ; an exit code to MEX in the A register, as follows:
  156. ;
  157. ;    0 - Carrier detected, connection established
  158. ;    1 - Far end busy (only for modems that can detect this condition)
  159. ;    2 - No answer (or timed out waiting for modem response)
  160. ;    3 - Keyboard abort (^C only: all others should be ignored)
  161. ;    4 - Error reported by modem
  162. ;    5 - No ring reported by modem
  163. ;    6 - No dial tone reported by modem
  164. ;
  165. ; <No other codes should be returned after an end-dial sequence>
  166. ;
  167. ; The overlay should not loop forever in the carrier-wait routine, but
  168. ; instead use either the overlay timer vector, or the INMDMV (timed 100
  169. ; ms character wait) service call routine.
  170. ;
  171. ; The DIAL routine is free to use any of the registers, but must return
  172. ; the above code after an end-dial sequence
  173. ;
  174.     ORG    DIALOC
  175. ;
  176. DIAL:    LHLD    DIALPT        ;FETCH POINTER
  177.     CPI    254        ;START DIAL?
  178.     JZ    STDIAL        ;JUMP IF SO
  179.     CPI    255        ;END DIAL?
  180.     JZ    ENDIAL        ;JUMP IF SO
  181. ;
  182. ; Not start or end sequence, must be a digit to be sent to the modem
  183. ;
  184.     MOV    M,A        ;PUT CHAR IN BUFFER
  185.     INX    H        ;ADVANCE POINTER
  186.     SHLD    DIALPT        ;STUFF PNTR
  187.     RET            ;ALL DONE
  188. ;
  189. ; Here on a start-dial sequence
  190. ;
  191. STDIAL:    LXI    H,DIALBF    ;SET UP BUFFER POINTER
  192.     SHLD    DIALPT
  193.     RET
  194. ;
  195. ; Here on an end-dial sequence
  196. ;
  197. ENDIAL:
  198.     MVI    M,0        ; Terminate phone number string
  199. CLEAR:
  200.     MVI    C,INMDM        ; Clean out the data buffer in usart
  201.     CALL    MEX
  202.     JNC    CLEAR        ; Get all available
  203.     LXI    H,WAKEUP    ; Get modem's attention
  204.     CALL    RVSEND
  205.     CALL    LFWAIT        ; First thing after ^E,<cr>
  206.     RNZ            ; Return if time out
  207.     CALL    LFWAIT        ; After "HELLO..."
  208.     RNZ            ; Return if time out
  209.     LXI    H,DCMD        ; Send "dial" command to modem
  210.     CALL    RVSEND
  211.     CALL    SENDCR        ; Terminate dial command
  212.     CALL    LFWAIT        ; Wait for "NUMBER?" prompt
  213.     RNZ            ; Return if not normal return from LFWAIT
  214.     LXI    H,DIALBF    ; Point to number
  215.     CALL    RVSEND        ; Send it to modem
  216.     CALL    SENDCR        ; Send <cr> to terminate phone number
  217.     CALL    SENDCR        ; Send second <cr> to initiate dialing
  218.     RNZ
  219. ;
  220. ; Here starts the main loop waiting for messages from the modem
  221. ;  and interpreting them.  Some are just passed to the console
  222. ;  and others trigger a specific action.
  223. ;
  224. DLOOP:
  225.     LXI    H,RESPBF    ; Point to response buffer
  226.     MVI    C,255        ; Long wait here
  227.     CALL    CATCHR        ; Catch response from modem
  228.     ORA    A        ; Zero return code ?
  229.     JNZ    IDLE        ; No, disconnect and return error code
  230.     MOV    A,B        ; Get character count from CATCHR
  231.     ORA    A        ; Hope it isn't zero
  232.     JZ    DLOOP        ; If it is, then ignore this response
  233.     LXI    H,RESPBF    ; Point to string from modem
  234.     LXI    D,RSPTBL    ; Point to valid response table
  235.     CALL    COMPR        ; Find out which response we got
  236.     MOV    A,B        ; Get return value
  237.     CPI    255        ; No response match
  238.     JNZ    DIAL05
  239. ERRET:
  240.     MVI    A,4        ; Error return to MEX
  241.     JMP    IDLE        ; Disconnect and return error code
  242. DIAL05:
  243.     CPI    3        ; Failed call ?
  244.     JZ    ERRET        ; Error return
  245.     CPI    1        ; Dialing message ?
  246.     JNZ    DIAL10
  247.     MVI    C,ILP
  248.     CALL    MEX
  249.     DB    'Dial, ',0
  250.     JMP    DLOOP
  251. DIAL10:
  252.     CPI    2        ; Ringing ?
  253.     JNZ    DIAL15
  254.     MVI    C,ILP
  255.     CALL    MEX
  256.     DB    'ring, ',0
  257.     JMP    DLOOP
  258. DIAL15:
  259.     CPI    4        ; Answer tone ?
  260.     JNZ    DIAL20
  261.     MVI    C,ILP
  262.     CALL    MEX
  263.     DB    'answer, ',0
  264.     JMP    DLOOP
  265. DIAL20:
  266.     CPI    5        ; On line ?
  267.     JNZ    DIAL25
  268.     XRA    A        ; Return on line code to MEX
  269.     RET
  270. DIAL25:
  271.     CPI    7        ; Busy ?
  272.     JNZ    DIAL35
  273.     CALL    LFWAIT        ; Busy message has 2 <lf>'s
  274.     RNZ            ; If timeout or user abort
  275. DIAL30:
  276.     MVI    A,1        ; Return busy code to MEX
  277.     JMP    IDLE        ; Disconnect and return error code
  278. DIAL35:
  279.     CPI    8        ; Voice ?
  280.     JNZ    DIAL40        ; No, try the next thing
  281. ;
  282. ; Handle "VOICE" here
  283. ;
  284. ; We treat "VOICE" like "BUSY" since most of the time the modem
  285. ;  detects "VOICE" it is a loud or unusual busy signal.
  286. ;
  287.     CALL    SENDCR        ; <cr> ends the "voice" mode
  288.     JMP    DIAL30        ; Abort and return busy code to MEX
  289. DIAL40:
  290.     CPI    6        ; No dial tone ?
  291.     JNZ    ERRET        ; Not one of the above, return MODEM ERROR
  292. ;
  293. ; Otherwise fall through with 6 in accumulator.  This indicates NO DIAL TONE
  294. ;  to MEX.
  295. ;
  296. IDLE:
  297. ;
  298. ; Forces modem into idle state by sending "idle" command and
  299. ;  then toggling DTR using the user's DISCV entry.
  300. ; Preserves any return code that may be in register A.
  301. ;
  302.     PUSH    PSW        ; Preserve any return code
  303.     CALL    SENDCR        ; Abort any dialing taking place
  304.     LXI    H,IDLCMD    ; Send idle message to modem
  305.     CALL    RVSEND
  306.     CALL    DISCV        ; Make sure modem disconnects
  307.     POP    PSW        ; Retrieve return code
  308.     RET
  309.  
  310. SENDCR:
  311. ;
  312. ; Sends a carriage return character to the modem and waits for a
  313. ;  line feed character to be returned.
  314. ;
  315.     LXI    H,CRMSG        ; Send <cr> to modem
  316.     CALL    RVSEND
  317.  
  318. ; Note: execution falls through to LFWAIT
  319. ;
  320. ; Waits til the character from the modem is a line feed
  321. ; Returns the same codes as CATCHR.
  322. ;
  323. LFWAIT:
  324.     MVI    C,10        ; Up to one second for <lf>
  325.     LXI    H,RESPBF
  326.     JMP    CATCHR        ; Use CATCHR to wait for <lf>
  327.  
  328.  
  329.  
  330. ; Table of valid responses from modem
  331. RSPTBL:
  332.     DB    'HE',0        ; "hello..."
  333.     DB    'DI',0        ; "dialing..."
  334.     DB    'RI',0        ; "ringing..."
  335.     DB    'FA',0        ; "failed call"
  336.     DB    'AN',0        ; "answer tone"
  337.     DB    'ON',0        ; "on line"
  338.     DB    'NO',0        ; "no dial tone"
  339.     DB    'BU',0        ; "busy"
  340.     DB    'VO',0        ; "voice"
  341.     DB    0        ; Table terminator
  342.  
  343.  
  344. COMPR:
  345. ; Compares a string of characters in memory to a table of
  346. ;  strings.  Each entry of the table must be terminated by
  347. ;  a zero byte, and the table must be terminated by another
  348. ;  zero byte.
  349. ; Inputs:  HL points to the string to look for
  350. ;       DE points to the table
  351. ; Output:  B contains the number of the table entry that
  352. ;         matches the string, and a 255 if no entry matched.
  353. ;
  354.     MVI    B,0        ; Init index
  355. CMPR05:
  356.     MVI    C,2        ; Number of characters to try to match
  357. CMPR10:
  358.     LDAX    D        ; Fetch char from table
  359.     CMP    M        ; Same as char in string ?
  360.     JNZ    CMPR15        ; Jump if not this entry in table
  361.     INX    H        ; Else, point to next char in string
  362.     INX    D        ;  and next char in table entry
  363.     DCR    C        ; Decrement counter of characters
  364.     JNZ    CMPR10        ; Go check next char
  365.     RET            ; B contains the index of match
  366. CMPR15:
  367.     INR    B        ; Increment index
  368. CMPR20:
  369.     INX    D        ; Next char in table
  370.     LDAX    D        ; Get next char from table
  371.     ORA    A        ; Is it last char in that entry ?
  372.     JNZ    CMPR20        ; No, keep looking
  373.     INX    D        ; Yes, then point to first char of next one
  374.     LDAX    D        ; Now check for end of table
  375.     ORA    A        ; Zero delimits table
  376.     JNZ    CMPR05        ; Go check this table entry
  377.     MVI    B,255        ; No match return code
  378.     RET
  379.  
  380.  
  381. CATCHR:
  382. ;
  383. ; Catch response from modem.
  384. ; Input:  HL pointing to buffer for characters from modem
  385. ;      C  delay allowed before timeout (multiples of 100ms)
  386. ; Output: Buffer contains the string received from modem with
  387. ;       any control characters filtered out.
  388. ;      C  count of characters received before <cr>
  389. ;      A  error code:  0 ==> normal return
  390. ;              2 ==> time out occurred
  391. ;              3 ==> user typed ^C
  392. ;
  393.     MVI    B,0        ; Character counter
  394. CRLOOP:
  395.     MOV    D,C        ; Initialize count down timer
  396. CRL05:
  397.     PUSH    B        ; Save character counter
  398.     PUSH    D        ; Save time out count down
  399.     PUSH    H        ; Save buffer pointer
  400.     MVI    C,CHEKCC    ; See if user typed ^C
  401.     CALL    MEX
  402.     JZ    UABORT        ; If yes, jump to user abort code
  403.     MVI    C,INMDM        ; Else, continue
  404.     CALL    MEX        ; Get char in 100ms if available
  405.     POP    H        ; Restore working registers
  406.     POP    D
  407.     POP    B
  408.     JC    NOCHAR        ; If no char in 1ms, handle it
  409.     ANI    7FH        ; Mask any parity bit
  410.     CPI    LF        ; End of line from modem ?
  411.     JZ    EOL        ; If <lf> then end of line
  412.     CPI    ' '        ; Filter unwanted characters
  413.     JC    CRLOOP        ; Ignore control characters
  414.     CPI    'z'+1        ; Nothing above lower case alpha's
  415.     JNC    CRLOOP
  416.     MOV    M,A        ; Here we have a valid character
  417.     INX    H        ;  so save it and bump pointer
  418.     INR    B        ; Increment character counter also
  419.     JMP    CRLOOP        ; Go get the next one
  420.  
  421. ;
  422. ; Handle no character from modem in 100ms
  423. ;
  424. NOCHAR:
  425.     DCR    D        ; Decrement time out counter
  426.     JNZ    CRL05        ; If not to zero, wait some more
  427.     MOV    C,B        ; Else, return with what we have now
  428.     MVI    A,2        ; Time-out error code
  429.     RET
  430. ;
  431. ; End of line from modem
  432. ;
  433. EOL:
  434.     MOV    C,B        ; Character count
  435.     XRA    A        ; Return zero
  436.     RET
  437. ;
  438. ; User abort from ^C
  439. ;
  440. UABORT:
  441.     CALL    IDLE        ; Force disconnect
  442.     POP    H        ; Since these are still on the stack
  443.     POP    D
  444.     POP    B
  445.     MOV    C,B        ; Count of characters up to now
  446.     MVI    A,3        ; User abort code
  447.     RET
  448.  
  449. ;
  450. ; Sends a string of characters pointed to by HL terminated by zero
  451. ;
  452. RVSEND:
  453.     MVI    C,SNDRDY    ; Get modem send status
  454.     CALL    MEX
  455.     JNZ    RVSEND        ; Wait for modem ready
  456.     MOV    A,M        ; Get character
  457.     INX    H        ; Point to next character
  458.     ORA    A        ; Is this the terminator ?
  459.     RZ            ; If yes, done
  460.     MOV    B,A        ; Pass character in B
  461.     MVI    C,SNDCHR    ; Let MEX send to modem
  462.     CALL    MEX
  463.     JMP    RVSEND
  464.  
  465. NOTIMP:
  466.     MVI    C,ILP
  467.     CALL    MEX
  468.     DB    'Not implemented'
  469.     DB    ' (Racal-Vadic 212 v'
  470.     DB    (VERS / 10) + '0', '.', (VERS MOD 10) + '0'
  471.     DB    ')',CR,LF,0
  472. JUSTRT:
  473.     RET
  474.  
  475. ;
  476. ; DATA AREA
  477. ;
  478. WAKEUP:    DB    'E'-40H,CR,0    ; String to wake up modem
  479. IDLCMD:    DB    'I',CR,0    ; Idle command
  480. DCMD:    DB    'D',0        ; Dial command to modem
  481. CRMSG:    DB    CR,0        ; Note, this is end of DCMD
  482. RESPBF:    DS    20        ; Response from modem
  483. DIALBF:    DS    30        ; Phone number buffer
  484. DIALPT:    DS    2        ;DIAL POSITION POINTER
  485. ;
  486.  
  487.     ORG    SMTABL
  488.  
  489.     DW    JUSTRT        ; Init
  490.     DW    NOTIMP        ; SSET
  491.     DW    JUSTRT        ; De-init
  492.  
  493.     END
  494.