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

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