home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / mex / mxo-mw10.asm < prev    next >
Assembly Source File  |  1994-07-13  |  14KB  |  449 lines

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