home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / b / krtdia.mac < prev    next >
Text File  |  2020-01-01  |  42KB  |  1,275 lines

  1.     .title    KRTDIA    Dial command and related items
  2.     .ident    "V03.63"
  3.  
  4. ; /63/  27-Sep-97  Billy Youdelman  V03.63
  5. ;
  6. ;    use opentt in place of ttyini to set linksts flag
  7. ;    move the modem definitions to a separate module KRTMDM.MAC
  8. ;    SET$DTR and SET$MODEM back here from KRTDSP
  9.  
  10. ; /62/    27-Jul-93  Billy Youdelman  V03.62
  11. ;
  12. ;    add support for call back modems, SET DIAL/PHONE [NO]ANSWER
  13. ;
  14. ;    add a one-tick pacing delay in DODIAL's loop at 50$ (when the modem
  15. ;    doesn't echo commands) to match what was done for echoing modems
  16. ;
  17. ;    fix SHO MODEM for changes to SET DIAL [NO]ECHO and [NO]INIT-ONCE
  18. ;    add initiate-prompt, dial-ack, confirm-ack, [no]binary-response
  19. ;
  20. ;    added x.result (default "Hayes" xmode) and time.settle defaults,
  21. ;    and in "Hayes" and Telebit modem definitions
  22. ;
  23. ;    if DCD is high when exiting program, hang up modem
  24. ;    add support for 38.4kb
  25. ;    add Telebit T3000 modem def, needs KM handler and SET FLOW-CONTROL RTS
  26. ;
  27. ;    double the settle-time value for the wait after dropping DTR,
  28. ;    as some modems (like the T3000) need more time to recover
  29.  
  30. ; /BBS/     1-Dec-91  Billy Youdelman  V03.61
  31. ;
  32. ;    set$mo now won't write bad modem name into modem:
  33. ;    if DIAL/REDIAL succeeds jump to CONNECT automatically
  34. ;    set linksts when dialing so ^C abort will catch correct ttname
  35. ;    findmodem now does not try to process an empty string in modem:
  36. ;    added c$idle, call to reset modem to idle (answer) mode
  37. ;    findmodem/findnumber will match on partial input string
  38. ;    added %X format effector for setting Hayes extended response mode
  39. ;    added Telebit T2500 modem definitions
  40. ;
  41. ;    redial loop moved to c$dial, runs faster without initializing
  42. ;    the modem's lun every pass thru the loop, reduces cpu usage too
  43. ;
  44. ;    load buffer with defmsg after displaying RING, to not overwrite
  45. ;    the default message with call status stuff
  46. ;
  47. ;    if DIAL can't translate an alias, say so then die (instead of
  48. ;    prompting to continue with an empty number buffer)
  49. ;
  50. ;    added xredial flag word, for keeping return path straight when
  51. ;    connecting after a successful REDIAL. speed up redial process for
  52. ;    modems which define init.once by not initting before every retry.
  53. ;    init.once and mready (status flag) were added to support all this..
  54. ;
  55. ;    while waiting for a response after dialing modem, check for
  56. ;    input from keyboard, allowing an easy abort
  57. ;
  58. ;    .default patched to get/set handler speed from modem response,
  59. ;    old speed is saved and restored, unless set different after..
  60. ;    Hayes definition completed and moved to it.  this also renders
  61. ;    Hayes responses displayable via SHO MODEM.
  62. ;
  63. ;    diatmo from SET DIAL TIME-OUT gets written into dial.time(r4)
  64. ;    when either c$dial or sho$dial is called.  it's now usable with
  65. ;    any modem type (not just user-defined) by setting the modem's
  66. ;    internal timer to the max (ATS7=255 etc) then letting Kermit's
  67. ;    timer take action first.
  68. ;
  69. ;    modified waitfor to test for keyboard input, allowing a "strike
  70. ;    any char" abort during dialing, now including the init string.
  71. ;    DTR is dropped to ensure the modem will actually abort the call.
  72. ;
  73. ;    SHO MODEM expanded to display everything
  74. ;    result message must match from 1st byte to avoid embedded strings
  75. ;    save modem init status to drop unnecessary inits
  76. ;    SET MODEM now inits same, if a line (and speed) have been set
  77. ;    echo everything from modem (if it echoes) during DIAL
  78. ;    add CONNECT/nnnn for Hayes to alter DTE speed w/TSX and CL
  79. ;    add Concord Data Systems 224 Auto-dial modem
  80. ;
  81. ;    moved SET DTR code here, and reinit modem after DTR drop if one
  82. ;    was on-line before it
  83.  
  84. ;    Copyright 1985,1986 Change Software, Inc.
  85. ;
  86. ;    18-Oct-85  20:06:09 Brian Nelson
  87. ;
  88. ;    04-Dec-85  11:22:32 BDN     Add optional linked list structure to
  89. ;                 define modem responses, will be useful
  90. ;                 when adding a SET DIAL command
  91. ;    09-Jan-86  17:48:17 RTM  Added support for the RIXON Intelligent
  92. ;                 auto-dial modem (R212A) (edit RTM01)
  93. ;    13-Feb-86  10:10:08 BDN     Put the DF112 and DF224 responses into
  94. ;                 linked lists
  95. ;    23-Sep-86  14:10:30 BDN     Vadic 4224 modems
  96. ;    23-Sep-86  14:10:42 BDN     Added format effector %M for pulse/tone
  97. ;                 if a SET PHONE PULSE/TONE was done
  98. ;                 Added %B for "blind" dialing, enabled if
  99. ;                 SET PHONE BLIND
  100. ;    30-Sep-86  13:05:53 BDN     Added CTS2424, Also SHO DIAL
  101. ;    09-Feb-89  00:00:00 JCH  Complete definition of DF224 modem
  102.  
  103.  
  104.     .include "IN:KRTMAC.MAC"
  105.     .iif ndf  KRTINC  .error    <; .include for IN:KRTMAC.MAC failed>
  106.  
  107.  
  108. ; /BBS/    This is used by SHOW MODEM to format the display of response messages
  109. ; and actions to them.  It's the column at which the actions begin and may be
  110. ; increased if longer response strings must accommodated.
  111.  
  112.     COL.ACT      =    18.
  113.  
  114.  
  115.     .sbttl    Local macros
  116.  
  117.     $$TRIP    = 0            ; /63/ init trip counter
  118.  
  119.     .macro    des  type ,offset ,title
  120.     .save                ; /63/
  121.     .psect    $pdata            ; /63/
  122.     .if  b    <type>
  123.     .byte    0    ,0
  124.     .even                ; /63/ do this here, once is enough..
  125.     $$trip=0            ; /63/ reset for possible future use
  126.     .iff
  127.       .if eq $$trip            ; /63/ if at the first list entry
  128. deslist:                ; /63/ insert the label for the list
  129.       .endc
  130.       $$trip=1            ; /63/ not the first entry any more
  131.     .byte    type    ,offset        ; type_0=integer, type_1=string
  132.     .asciz    @title@            ; /62/ type_2=on/off
  133.     .endc
  134.     .restore            ; /63/
  135.     .endm    des
  136.  
  137.     .macro    ttgetc    wait        ; get one char from the link device
  138.     .if  b    <wait>            ; wait value is in seconds
  139.     calls    xbinread,<#1>        ; /62/ this waits up to one second
  140.     .iff
  141.     calls    xbinread,<wait>
  142.     .endc
  143.     .endm    ttgetc
  144.  
  145.     .macro    ttputc    c        ; send one char to the link device
  146.     clr    -(sp)            ; create a one word buffer
  147.     bisb    c    ,(sp)        ; stuff in byte sans sign extension
  148.     mov    sp    ,r0        ; point to buffer
  149.     calls    binwri    ,<r0,#1>    ; send it
  150.     tst    (sp)+            ; pop buffer
  151.     .endm    ttputc
  152.  
  153.     .macro    ttputs    s        ; send a string to the link device
  154.     mov    r1    ,-(sp)        ; a one word buffer
  155.     mov    s    ,r1        ; pass string location to do.put
  156.     call    do.put            ; /63/ send it
  157.     mov    (sp)+    ,r1        ; pop buffer
  158.     .endm    ttputstr
  159.  
  160.     .macro    waitfor  s ,time ,fail    ; wait for a response from modem
  161.     .if  b    <time>            ; time value is in seconds
  162.     clr    -(sp)            ; time buffer
  163.     inc    @sp            ; /BBS/ default wait is one second
  164.     .iff
  165.     mov    time    ,-(sp)        ; pass time to wait
  166.     .endc
  167.     mov    s    ,-(sp)        ; and address of expected string
  168.     call    waitfor            ; go look for it
  169.     .if nb    <fail>            ; if given a failure routine address
  170.     tst    r0            ; check to see if it worked..
  171.     beq    fail            ; it did not
  172.     .endc
  173.     .endm    waitfor
  174.  
  175.  
  176.     .sbttl    Local data
  177.  
  178.     .psect    $pdata            ; /63/ consolidate all data here
  179. abort:    .asciz    "% Aborted from keyboard"
  180. bells:    .byte    bell ,bell ,0        ; two bells when CONNECTing
  181. defmsg:    .asciz    "% Timed out"
  182. dia.01:    .asciz    "Toggling DTR.."    ; /63/ moved message macro data here
  183. dia.02:    .asciz    "Re-initting modem.."
  184. dia.03:    .asciz    " modem is on-line"<cr><lf>
  185. dia.04:    .asciz    "Try #"
  186. dia.05:    .asciz    ":"<cr><lf>
  187. dia.06:    .asciz    "The known modem types are:"<cr><lf>
  188. dia.07:    .asciz    "% No answer"<cr><lf>
  189. dia.08:    .asciz    "Yes"
  190. dia.09:    .asciz    "No"
  191. dia.10:    .asciz    "Dial time-out secs: "
  192. dia.11:    .asciz    "Settle-time ticks:  "
  193. dia.12:    .asciz    '%X = "X'
  194. dia.13:    .asciz    "Binary-responses:   "
  195. dia.14:    .asciz    "Result strings:"<cr><lf>
  196. dia.15:    .asciz    "Success"
  197. dia.16:    .asciz    "Rings+1"<cr><lf>
  198. dia.17:    .asciz    "Failure"<cr><lf>
  199. dia.18:    .asciz    "Link "
  200. dia.19:    .asciz    " disconnected"<cr><lf>
  201. msg$dte:.asciz    ",  DTE is forced to "    ; /63/ tag messages that alter speed
  202. msg$fmt:.asciz    "Format effectors:   "    ; /62/
  203. nodpro:    .asciz    "% No dial$prompt"
  204. nod.go:    .asciz    "% No dial$go"
  205. nod.ack:.asciz    "% No dial$ack"
  206. prefix:    .asciz    \ = "\            ; /62/ prefix for format effector data
  207. tripsp:    .asciz    \"   \            ; /62/ a " followed by three blanks
  208.     .even
  209.  
  210.     .psect    $rwdata    ,rw,d,lcl,rel,con
  211. buffer:    .blkb    84.            ; /BBS/ general purpose buffer
  212. mute:    .word    0            ; /BBS/ use to mute output to TT
  213. retries:.word    0            ; /BBS/ redial this many times..
  214.  
  215.  
  216.     .psect    $code
  217.     .sbttl    SET MODEM-TYPE        ; /BBS/ almost 100% new..
  218.  
  219. set$mo::strcpy    #spare1    ,#modem        ; save copy of what's there now
  220.     mov    modtype    ,r4        ; address of its structure
  221.     mov    mready    ,r3        ; and its status
  222.     upcase    argbuf            ; upper case the argument
  223.     copyz    argbuf    ,#modem ,#40    ; copy new modem name over
  224.     call    findmodem        ; and look for it in the list
  225.     tst    r0            ; did it work?
  226.     bne    10$            ; ya
  227.  
  228.     strcpy    #modem    ,#spare1    ; no, restore the old modem type
  229.     mov    r3    ,mready        ; its status
  230.     mov    r4    ,modtype    ; and its structure's address
  231.     call    incsts            ; flag error, so r0 can be cleared
  232.     clr    r0            ; strcpy, just above, trashes this reg
  233.     return                ; error already handled by findmodem
  234.  
  235. 10$:    clr    blind            ; reset this
  236. ;    clr    pulse            ; commented out, phone line is same..
  237.     mov    dial.time(r0),diatmo    ; /62/ start with default time-out
  238.     mov    time.set(r0) ,settle    ; /62/ and settle-time
  239.     mov    #xresult     ,r1    ; /62/ where to put new extended mode
  240.     mov    x.result(r0) ,r0    ; /62/ default supplied?
  241.     bmi    20$            ; /62/ no, let null say it's nothing..
  242.     call    L10012            ; /62/ ya, write it as ascii number(s)
  243. 20$:    clrb    (r1)            ; /62/ null terminate the string
  244.     clr    r0            ; preset to no error
  245.     tstb    ttname            ; is line to modem set yet?
  246.     beq    30$            ; no
  247.     call    ttyhang            ; ya, assert DTR on PRO, reset modem
  248.     tst    r0            ; did it work?
  249.     bne    30$            ; no, ttyini handles its own error
  250.     mov    settle    ,r0        ; /62/ double the wait here because
  251.     asl    r0            ; /62/ some modems are just too slow!
  252.     calls    suspend    ,<#0,r0>    ; /62/ let modem recover from DTR drop
  253.     call    set.mo            ; shared code
  254. 30$:    tst    r0            ; did all this work?
  255.     bne    dia.er            ; /63/ no, goto error handler
  256.     return
  257.  
  258.  
  259.     .sbttl    SET DTR and HANGUP
  260.  
  261. set$dt::call    set.dtr            ; toggle DTR
  262.     tst    r0            ; did it work?
  263.     bne    dia.er            ; /63/ no
  264.     .newline
  265.     return
  266.  
  267. c$hang::call    set.dtr            ; toggle DTR
  268.     tst    r0            ; did it work?
  269.     bne    dia.er            ; /63/ no
  270.     wrtall    #dia.18            ; "Link "
  271.     wrtall    #ttname            ; include the device name
  272.     wrtall    #dia.19            ; " disconnected"<cr><lf>
  273.     return
  274.  
  275. dia.er:    direrr    r0            ; /63/ dump error message
  276.     call    incsts            ; flag error, so r0 can be cleared
  277.     clr    r0            ; only do error message once
  278.     return
  279.  
  280.  
  281.     .sbttl    The real work of SET MODEM
  282.  
  283. set.mo:    mov    linksts    ,r2        ; save link open/closed status
  284.     bne    10$            ; it's open now
  285.     call    opentt            ; /63/ open link device
  286.     tst    r0            ; successful open on line?
  287.     bne    20$            ; no, give up
  288.  
  289. 10$:    call    fixspeed        ; restore set speed if need be
  290.     mov    sp    ,mute        ; turn off echo
  291.     call    getatn            ; try to get modems attention
  292.     clr    mute            ; turn echo back on
  293.     tst    r0            ; success?
  294.     bne    20$            ; no
  295.     tst    sy.ini            ; come here while executing KRT.INI?
  296.     bne    20$            ; ya, don't echo modem I/O
  297.     tst    infomsg            ; SET TT QUIET?
  298.     beq    20$            ; ya..
  299.     wrtall    #modem            ; no, display name of modem
  300.     wrtall    #dia.03            ; /63/ " modem is on-line"<cr><lf>
  301.                     ; note r0 still =0 here, from above..
  302. 20$:    mov    r0    ,-(sp)        ; save error
  303.     mov    r2    ,linksts    ; restore link status
  304.     bne    30$            ; it was open, leave it that way
  305.     call    ttyfin            ; close the link
  306. 30$:    mov    (sp)+    ,r0        ; restore error
  307.     return
  308.  
  309.  
  310.     .sbttl    The real work of SET DTR
  311.     .enabl    lsb
  312.  
  313. set.dtr:wrtall    #dia.01            ; /63/ "Toggling DTR.."
  314.     call    l$nolf            ; just a return, unless TT is NOSCOPE
  315.     call    ttyhang            ; drop DTR for 0.5sec
  316.     tst    r0            ; did it work?
  317.     bne    10$            ; no
  318.     tst    modtype            ; was a modem on-line?
  319.     beq    10$            ; no
  320.     mov    settle    ,r0        ; /62/ double the wait here because
  321.     asl    r0            ; /62/ some modems are just too slow!
  322.     calls    suspend    ,<#0,r0>    ; /62/ let modem recover from DTR drop
  323.     .br    reinit            ; /63/
  324.  
  325. reinit::wrtall    #dia.02            ; /63/ "Re-initting modem.."
  326.     call    l$nolf            ; just a return
  327.     mov    infomsg    ,-(sp)        ; save state of SET TT [NO]QUIET
  328.     clr    infomsg            ; temporarily off display
  329.     call    set.mo            ; go re-init the modem
  330.     mov    (sp)+    ,infomsg    ; restore SET TT [NO]QUIET
  331. 10$:    return
  332.  
  333.     .dsabl    lsb
  334.  
  335.  
  336.     .sbttl    The REDIAL command    ; /BBS/ slightly modified..
  337.  
  338. c$redi::mov    argbuf    ,r3        ; argbuf address
  339.     mov    phnum    ,r2        ; address of phone number
  340.     mov    #-1    ,r4        ; default repeat count = 65535.
  341.     tstb    @r3            ; any repeat count passed?
  342.     beq    20$            ; no
  343.     calls    l$val    ,<r3>        ; convert ascii to integer
  344.     tst    r0            ; success?
  345.     bne    10$            ; no
  346.     mov    r1    ,r4        ; save repeat count
  347.     bne    20$            ; disallow 0, it would really = 65536.
  348. 10$:    mov    #er$inr    ,r0        ; invalid number of retires
  349.     br    40$            ; go handle error
  350. 20$:    tstb    @r2            ; anything to dial?
  351.     bne    30$            ; yes
  352.     mov    #er$npn    ,r0        ; no previous number dialed
  353.     br    40$            ; bail out
  354. 30$:    strcpy    r3    ,r2        ; copy old phone num to argbuf
  355.     mov    sp    ,xredial    ; flag c$dial was called by c$redial
  356.     clr    retries            ; init number of tries counter
  357.     call    c$dial            ; redial loop moved to c$dial
  358.     br    50$            ; c$dial handles its own errors
  359.  
  360. 40$:    direrr    r0            ; for local errors
  361.     call    incsts            ; set global flag also
  362. 50$:    clr    r0            ; error was just handled
  363.     return
  364.  
  365.  
  366.     .sbttl    The DIAL command    ; /BBS/ substantially changed..
  367.     .enabl    lsb
  368.  
  369. c$dial::tst    signon            ; if coming here from init file
  370.     bne    10$            ; dump sign-on stuff before dial
  371.     call    sho$line
  372.  
  373. 10$:    tstb    ttname            ; check for a real terminal name
  374.     bne    20$            ; ok
  375.     mov    #er$pls    ,r0        ; please SET LINE first
  376.     br    70$            ; goto error handler
  377.  
  378. 20$:    call    inqcd            ; /62/ check to see if already talking
  379.     tst    r0            ; /62/ or prior session not dead yet
  380.     ble    30$            ; /62/ no data carrier is now present
  381.     mov    #er$dcd    ,r0        ; /62/ can't DIAL whilst DCD asserted
  382.     br    70$            ; goto error handler
  383.  
  384. 30$:    call    findnumber        ; perhaps a SET PHONE NUMBER?
  385.     bcs    100$            ; findnu handles its own error
  386.     call    loamdm            ; /63/ ensure modem data are loaded
  387.     mov    modtype    ,r0        ; recover the address of descriptor
  388.     bne    40$            ; ok
  389.     mov    #er$mdm    ,r0        ; please SET MODEM first
  390.     br    70$            ; goto error handler
  391.  
  392. 40$:    clr    mute            ; turn echo back on just in case
  393.     mov    dial.string(r0),r0    ; get dial format string address
  394.     tstb    @r0            ; anything there?
  395.     bne    50$            ; yes
  396.     mov    #er$ndf    ,r0        ; no dial format string defined
  397.     br    70$            ; goto error handler
  398.  
  399. 50$:    call    opentt            ; /63/ open the link device
  400.     tst    r0            ; successful?
  401.     bne    100$            ; no, ttyini does the error message
  402.     call    fixspeed        ; restore set speed if need be
  403.     call    eatjunk            ; /63/ flush any late redial response
  404.     mov    modtype    ,r0        ; recover top of list
  405.     tst    init.once(r0)        ; need to re-init modem?
  406.     beq    60$            ; evidently..
  407.     tst    mready            ; is the modem now on-line?
  408.     bne    80$            ; ya
  409. 60$:    call    getatn            ; try to get modems attention
  410.     tst    r0            ; did getting modems attn succeed?
  411.     beq    80$            ; ya
  412. 70$:    direrr    r0            ; no, emit error msg
  413.     br    100$            ; /62/ and exit
  414.  
  415. 80$:    tst    cccnt            ; abort?
  416.     bne    100$            ; ya..
  417.     tst    xredial            ; redialing?
  418.     beq    90$            ; no
  419.     inc    retries            ; ya, bump retries count
  420.     wrtall    #dia.04            ; /63/ "Try #"
  421.     mov    retries    ,r0        ; copy for integer to ascii conv
  422.     call    L10266            ; print integer as decimal numb
  423.     wrtall    #dia.05            ; /63/ ":"<cr><lf>
  424.  
  425. 90$:    call    dodial            ; actually try to dial the number now
  426.     tst    r0            ; returns 1 for success, 0 if failed
  427.     bne    130$            ; success, go CONNECT
  428.     tst    xredial            ; redialing this?
  429.     beq    100$            ; no, die..
  430.     sob    r4    ,80$        ; ya, try again?
  431.  
  432. 100$:    call    incsts            ; set global error flag
  433.  
  434. 110$:    call    ttyfin            ; close the handler
  435.     clr    linksts            ; flag for ccast
  436. 120$:    clr    r0            ; /62/ error already handled
  437.     return
  438.  
  439. 130$:    tst    xredial            ; come here from c$redial?
  440.     beq    140$            ; nope
  441.     tst    (sp)+            ; ya, pop its return address
  442. 140$:    jmp    c$conn            ; and CONNECT automatically..
  443.  
  444.  
  445.     .sbttl    Reset the modem        ; /BBS/ all new
  446.  
  447. c$idle::call    loamdm            ; /63/ ensure modem data are loaded
  448.     mov    modtype    ,r4        ; get modem type
  449.     beq    120$            ; no modem is on-line
  450.     tst    r50dev            ; is there a line set?
  451.     beq    120$            ; no, thus can't talk to modem
  452.     call    inqcd            ; /62/ ya, is the modem active?
  453.     tst    r0            ; /62/ well..
  454.     ble    150$            ; /62/ probably not, do the init
  455.     call    ttyhang            ; /62/ ya, try to hang it up!
  456.     calls    suspend    ,<#0,settle>    ; /62/ let modem recover from DTR drop
  457. 150$:    clr    mready            ; no longer ready no matter what
  458.     call    opentt            ; /63/ init handler, etc..
  459.     tst    r0            ; get a successful open on line?
  460.     beq    160$            ; ya
  461.     mov    #er$idl    ,r0        ; can't release modem
  462.     br    70$            ; and off to common code..
  463.  
  464. 160$:    call    fixspeed        ; restore set speed if need be
  465.     ttputs    dial.idle(r4)        ; send idle command string to modem
  466.     br    110$            ; and off to common code..
  467.  
  468.     .dsabl    lsb
  469.  
  470.  
  471.     .sbttl    Restore last set speed    ; /BBS/ added..
  472.  
  473. fixspeed:tst    b4speed            ; did last call alter speed?
  474.     beq    10$            ; nope
  475.     calls    setspd    ,<b4speed>    ; restore speed before that happened
  476.     clr    b4speed            ; once iz enuff..
  477. 10$:    return
  478.  
  479.  
  480.     .sbttl    Find location of a modem's data structure
  481.  
  482. ;    F I N D M O D E M        ; /BBS/ substantially revised..
  483. ;
  484. ;    assumes:  modem    = name of the desired modem
  485. ;    returns:    r0    = address of modem data structure or 0 if not found
  486.  
  487. findmo:    save    <r3>
  488.     tstb    modem            ; did caller supply a modem name?
  489.     beq    80$            ; nope..
  490.     call    loamdm            ; /63/ load predefined modems' data
  491.     mov    r0    ,r3        ; /63/ get address of head of list
  492.     cmpb    #'?    ,modem        ; come here for help?
  493.     beq    40$            ; ya, format display accordingly
  494.  
  495. 10$:    mov    mod.string(r3),r0    ; allow match if ok up to end of
  496.     mov    #modem    ,r1        ; argbuf so partial string works
  497. 20$:    cmpb    (r0)+    ,(r1)+        ; are they the same
  498.     bne    30$            ; no
  499.     tstb    (r1)            ; end of argbuf?
  500.     bne    20$            ; no, continue
  501.     mov    r3    ,modtype    ; save address of the structure
  502.     copyz    mod.string(r3),#modem    ; be sure whole name is there
  503.     br    70$            ; done
  504.  
  505. 30$:    mov    mod.next(r3),r3        ; no, try the next one please
  506.     bne    10$            ; keep going
  507.     direrr    #er$unm            ; modem type is unknown
  508.     tst    infomsg            ; SET TT QUIET?
  509.     beq    80$            ; ya, skip list of possibilities
  510.  
  511. 40$:    wrtall    #dia.06            ; /63/ "..known modem types.."<cr><lf>
  512.     call    loamdm            ; /63/ load predefined modems' data
  513.     mov    r0    ,r3        ; /63/ get address of head of list
  514. 50$:    wrtall    mod.string(r3)        ; now print the list of modems
  515.     strlen    mod.string(r3)        ; length of modem type
  516.     sub    #20    ,r0        ; cut to 16. for tighter display
  517.     neg    r0            ; make it a positive number
  518.     mov    r0    ,r1        ; stash a copy for the loop
  519.     mov    #space    ,r0        ; load up a space
  520. 60$:    call    writ1ch            ; write it to TT
  521.     sob    r1    ,60$        ; loop until properly padded
  522.     wrtall    mod.com(r3)        ; dump comment string
  523.     .newline
  524.     mov    mod.next(r3),r3        ; next one in list
  525.     bne    50$            ; ok
  526.     br    80$            ; exit with failure
  527.  
  528. 70$:    mov    r3    ,r0        ; return address of structure
  529.     br    90$
  530. 80$:    clr    r0            ; failure
  531. 90$:    unsave    <r3>
  532.     return
  533.  
  534.  
  535.     .sbttl    Find a defined phone number
  536.  
  537. findnu:    save    <r3,r2>            ; /45/ Added 20-Feb-86 13:00:50 BDN
  538.     strcpy    #errtxt    ,argbuf        ; /63/ save a copy of input string
  539.     cmpb    @argbuf    ,#'0        ; only if not number in first position
  540.     blo    10$            ; ok
  541.     cmpb    @argbuf    ,#'9        ; well?
  542.     blos    70$            ; /BBS/ it's a number
  543. 10$:    mov    #pnhead    ,r2        ; get listhead
  544.  
  545. 20$:    mov    (r2)    ,r2        ; loop a little, get next entry
  546.     beq    60$            ; nothing there
  547.     mov    r2    ,r3        ; get address of text
  548.     add    #2    ,r3        ; +2 is offset for the data
  549.  
  550.     strcpy    #errtxt    ,r3        ; /63/ save a copy of input string
  551.     mov    #errtxt    ,r1        ; /63/ save un-upper-cased name here
  552.     mov    #buffer    ,r0        ; store temp copy here
  553. 30$:    cmpb    (r3)    ,#space        ; all done looking?
  554.     beq    40$            ; yes
  555.     movb    (r3)    ,(r1)+        ; /63/ copy for "last # dialed"
  556.     movb    (r3)+    ,(r0)+        ; no, copy more of the name
  557.     bne    30$            ; and continue
  558. 40$:    clrb    (r0)            ; ensure .asciz please
  559.     clrb    (r1)            ; /63/ ditto
  560.  
  561.     ; /BBS/ checking for end of argbuf matches on any partial string
  562.     upcase    argbuf            ; also leaves r0 -> argbuf
  563.     mov    r0    ,r1        ; save pointer
  564.     upcase    #buffer            ; /62/ temp buff allows upcasing name
  565. 50$:    cmpb    (r0)+    ,(r1)+        ; are they the same?
  566.     bne    20$            ; no
  567.     tstb    (r1)            ; ya, hit end of argbuf yet?
  568.     bne    50$            ; no, continue
  569.     inc    r3            ; point to number field
  570.     tstb    (r3)            ; anything really there?
  571.     beq    60$            ; /BBS/ no, go print error message
  572.     strcpy    argbuf    ,r3        ; copy into the real argument buffer
  573.     br    70$            ; /BBS/ go clear carry and exit
  574.  
  575. 60$:    direrr    #er$nnf            ; /BBS/ say why it's gonna die
  576.     sec                ; /51/ failure
  577.     br    80$
  578. 70$:    copyz    #errtxt    ,phnum,#60    ; /63/ stash copy for "last # dialed"
  579.     clc                ; /51/ success
  580. 80$:    unsave    <r2,r3>
  581.     return
  582.  
  583.  
  584.     .sbttl    Wake up (init) modem    ; /BBS/ almost 100% new..
  585.  
  586. ;    G E T A T N
  587. ;
  588. ;    In case the modem is already awake (at command prompt mode)
  589. ;    we will dump the string,  wait for the  acknowledgment  and
  590. ;    loop until we are sure there are no more data.  For example
  591. ;    the VA212 will send back an  INVALID  COMMAND\n* string for
  592. ;    for the ^E and one also for the <CR>.  We could, of course,
  593. ;    first send the modem its idle command,  but there are times
  594. ;    when that may be undesirable,  like when the modem is being
  595. ;    accessed via some sort of LAN or PABX.
  596. ;
  597. ;    input:    modtyp    = address of modem descriptor
  598. ;    return:      r0    = if <>, the error code
  599.  
  600. getatn:    save    <r1,r2,r3,r4>
  601.     clr    -(sp)            ; init "msg rec'd" flag
  602.     mov    #buffer    ,r2        ; write init string here
  603.     call    loamdm            ; /63/ ensure modem data are loaded
  604.     mov    modtype    ,r4        ; get address of structure
  605.     clr    mready            ; modem is no longer ready
  606.     mov    wake.string(r4),r3    ; point to the init string
  607.     tstb    (r3)            ; is there one to send?
  608.     bne    10$            ; ya
  609.     mov    #er$wks    ,r0        ; nope..
  610.     jmp    200$            ; handle the error
  611.  
  612. 10$:    tstb    (r3)            ; done?
  613.     beq    70$            ; yes
  614.     cmpb    (r3)    ,#'%        ; look for a format effector
  615.     bne    50$            ; ya, not no..
  616.     cmpb    1(r3)    ,#'x!40        ; "%X" to set Hayes extended mode?
  617.     beq    20$            ; yes
  618.     cmpb    1(r3)    ,#'X&137    ; check both cases
  619.     bne    50$            ; not formatting, copy char over
  620. 20$:    tstb    xresult            ; is there an extended mode set?
  621.     beq    40$            ; no, kill leading space here
  622.     movb    #'X&137    ,(r2)+        ; ya, insert an "X"
  623.     mov    #xresult,r1        ; make copy to auto-increment
  624. 30$:    movb    (r1)+    ,(r2)+        ; then insert the mode, ala "X4"
  625.     bne    30$            ; stop on the first null
  626. 40$:    dec    r2            ; then back up over it
  627.     inc    r3            ; skip over the "%" please
  628.     br    60$            ; next please
  629. 50$:    movb    (r3)    ,(r2)+        ; not formatting, copy character
  630. 60$:    inc    r3            ; skip over current char now
  631.     br    10$            ; next
  632. 70$:    clrb    (r2)            ; .asciz
  633.  
  634.     mov    #3    ,r3        ; loop a little to get modem going
  635. 80$:    call    eatjunk            ; trash stuff that may be waiting
  636.     mov    #buffer    ,r2        ; get address of wakeup string
  637.     br    100$            ; for display format on abort
  638.  
  639. 90$:    tstb    (r2)+            ; /62/ next byte..
  640.     beq    140$            ; /62/ that's all there is
  641.     tst    mute            ; allow strike any key abort?
  642.     bne    100$            ; no, not this time
  643.     call    chkabo            ; strike any key to abort
  644.     tst    r0            ; get anything?
  645.     beq    100$            ; nope
  646.     inc    cccnt            ; fake abort so modem is stopped
  647.     call    clrcns            ; eat LF after a CR, etc..
  648.     tst    (sp)            ; /62/ anything typed out yet?
  649.     beq    180$            ; /62/ no
  650.     .newline            ; ya, ensure abort message is on \n
  651.     br    180$            ; and bail out..
  652.  
  653. 100$:    ttputc    (r2)            ; /62/ put a char to the modem
  654.     tst    dial.echo(r4)        ; /62/ does it echo?
  655.     beq    110$            ; /62/ no
  656.     ttgetc    #-1            ; then look for its echo
  657.     tst    r0            ; anything there?
  658.     bne    130$            ; no
  659.     bicb    #^c<177>,r1        ; remove parity always
  660.     cmpb    r1    ,#cr        ; is it a return?
  661.     beq    130$            ; ya, don't echo it
  662.     cmpb    r1    ,#lf        ; is it a line feed?
  663.     beq    130$            ; ya, don't echo it
  664.     movb    r1    ,r0        ; get a copy of it
  665.     br    120$            ; /62/ and go dump same to the screen
  666. 110$:    calls    suspend    ,<#0,#1>    ; /62/ match above ttgetc 1 tick lag
  667.     movb    (r3)    ,r0        ; cop char just sent
  668. 120$:    tst    mute            ; echo this to TT?
  669.     bne    130$            ; no, don't echo modem I/O
  670.     mov    r0    ,@sp        ; set "msg rec'd" flag
  671.     call    writ1char        ; and echo to TT
  672. 130$:    calls    suspend    ,<#0,wake.rate(r4)> ; no, pause if need be
  673.     br    90$            ; and do some more
  674.  
  675. 140$:    tst    (sp)            ; was anything echo'd to TT?
  676.     beq    150$            ; no, skip the newline
  677.     .newline            ; ya, tag it
  678. 150$:    waitfor    wake.prompt(r4),#2,160$    ; now wait 2 secs for a response
  679.     br    170$            ; success
  680. 160$:    tst    cccnt            ; abort?
  681.     bne    180$            ; ya..
  682.     dec    r3            ; decrement loop counter
  683.     beq    190$            ; a complete failure, exit
  684.     jmp    80$            ; next please
  685.  
  686. 170$:    mov    r4    ,mready        ; flag that modem is initialized
  687.     clr    r0            ; return(success)
  688.     br    210$
  689.  
  690. 180$:    mov    #er$abk    ,r0        ; say it's a keyboard abort
  691.     br    200$
  692. 190$:    mov    #er$wke    ,r0        ; can't get wake$pmpt from modem
  693. 200$:    clr    mready            ; modem is not now ready
  694. 210$:    call    eatjunk            ; just to be sure..
  695.     tst    (sp)+            ; pop "msg rec'd" flag buffer
  696.     unsave    <r4,r3,r2,r1>
  697.     return
  698.  
  699.  
  700.     .sbttl    Dial the number        ; /BBS/ moderately modified..
  701.  
  702. ;    Note that the waitfor routine,  called by macro of same name, will
  703. ;    exit immediately if the string to compare against is NULL, thus it
  704. ;    won't hurt anything to call it for modems that may not respond, as
  705. ;    long dmod.* aren't defined for such a modem, that is..
  706.  
  707. dodial:    save    <r2,r3,r4>
  708.     clr    -(sp)            ; /62/ init "msg rec'd" flag
  709.     mov    #buffer    ,r3        ; pointer to a handy buffer
  710.     mov    modtype    ,r4        ; get address of modem descriptor
  711.     call    fmtstr            ; format the dialing string
  712.  
  713.     ttputs    dmod.string(r4)        ; dump the prompt for dialing out
  714.     waitfor    dmod.prompt(r4),#4,70$    ; wait for a response
  715.     call    eatjunk            ; let things settle a bit
  716.     br    30$            ; display format on abort kludge
  717.  
  718. 10$:    tstb    (r3)+            ; next byte..
  719.     beq    80$            ; that's all there is
  720.  
  721.     call    chkabo            ; strike any key to abort
  722.     tst    r0            ; get anything?
  723.     beq    30$            ; nope
  724.     inc    cccnt            ; fake abort so modem is stopped
  725.     call    clrcns            ; eat LF after a CR, etc..
  726.     tst    (sp)            ; /62/ was anything echo'd to TT?
  727.     beq    20$            ; /62/ no, skip the newline
  728.     .newline            ; /62/ ya, tag it
  729. 20$:    jmp    150$            ; /62/ go clean up
  730.  
  731. 30$:    ttputc    (r3)            ; send a char to the modem
  732.     tst    dial.echo(r4)        ; does it echo?
  733.     beq    40$            ; no
  734.     ttgetc    #-1            ; ya, wait one tick for echo
  735.     tst    r0            ; get anything?
  736.     bne    60$            ; no
  737.     bicb    #^c<177>,r1        ; remove parity always
  738.     movb    r1    ,r0        ; copy the char
  739.     br    50$            ; and go dump same to the screen
  740. 40$:    calls    suspend    ,<#0,#1>    ; /62/ match above ttgetc 1 tick lag
  741.     movb    (r3)    ,r0        ; cop char just sent
  742. 50$:    mov    r0    ,@sp        ; /62/ set "msg rec'd" flag
  743.     call    writ1char        ; and echo it to TT
  744. 60$:    calls    suspend    ,<#0,dial.rate(r4)> ; pace chars if dial.rate is not 0
  745.     br    10$            ; loop
  746.  
  747. 70$:    mov    #nodprompt,r0        ; no dial prompt
  748.     br    130$
  749.  
  750. 80$:    tst    (sp)            ; /62/ ever type anything to TT?
  751.     beq    90$            ; /62/ no, thus a newline isn't needed
  752.     .newline            ; for dial string above
  753. 90$:    mov    #buffer    ,r3        ; restore buffer pointer
  754.     waitfor    dial.ack(r4),#4,110$    ; wait for numb to echo perhaps
  755.     ttputs    dial.conf(r4)        ; stuff a confirm (ok if null)
  756.     waitfor    dial.go(r4),#5,120$    ; maybe wait for any confirming string
  757.     call    getsts            ; get final result of the call please
  758.     tst    cccnt            ; did this die from a keyboard abort?
  759.     bne    140$            ; ya
  760.     inc    r0            ; success?
  761.     bgt    180$            ; yes
  762.     beq    100$            ; no, but modem stopped itself
  763.     ttputs    dial.xabort(r4)        ; get the modem to stop
  764.     calls    suspend    ,<#0,settle>    ; let modem recover from abort!
  765. 100$:    tstb    buffer            ; anything in the buffer?
  766.     bne    170$            ; ya, message already displayed..
  767.     mov    #defmsg    ,r0        ; no, must have timed out, say so
  768.     br    130$            ; go dump failure message
  769.  
  770. 110$:    mov    #nod.ack,r0        ; no dial ack
  771.     br    130$
  772. 120$:    mov    #nod.go    ,r0        ; no dial.go confirmation
  773. 130$:    tst    cccnt            ; was ^C typed?
  774.     beq    160$            ; no
  775.  
  776. 140$:    tstb    buffer            ; anything in the buffer?
  777.     beq    150$            ; no, don't need a newline
  778.     .newline            ; ya, goto a clean line
  779. 150$:    ttputs    dial.xabort(r4)        ; get the modem to stop
  780.     calls    suspend    ,<#0,settle>    ; let modem recover from abort!
  781.     mov    cccnt    ,-(sp)        ; save number of times ^C typed
  782.     clr    cccnt            ; do this so set.dtr can call getatn
  783.     call    set.dtr            ; drop DTR and re-init modem
  784.     direrr    r0            ; /62/ if set.dtr failed, say why
  785.     mov    (sp)+    ,cccnt        ; restore ^C count
  786.     mov    #abort    ,r0        ; user interrupt message
  787.  
  788. 160$:    wrtall    r0            ; say why we are here..
  789.     .newline
  790. 170$:    clr    r0            ; failure
  791.     br    190$
  792.  
  793. 180$:    wrtall    #bells            ; beep just before CONNECTing
  794.     mov    #1    ,r0        ; success
  795. 190$:    tst    (sp)+            ; /62/ pop "msg rec'd" flag buffer
  796.     unsave    <r4,r3,r2>
  797.     return
  798.  
  799.  
  800.     .sbttl    Get final result of dialing    ; /BBS/ somewhat modified
  801.  
  802.     NOREPLY    =    7        ; /62/ fail call after this many rings
  803.  
  804.     ; offsets to local data on stack
  805.     STATUS    =    0        ; current status
  806.     NRINGS    =    2        ; number of rings
  807.     LOCSIZ    =    4        ; size of the above
  808.  
  809. ;    passed:      r4    = pointer to modem's data structure
  810. ;    return:      r0    = if <>, the error code
  811.  
  812. getsts:    save    <r5>
  813.     mov    diatmo    ,r3        ; /62/ # secs to wait for response
  814.     mul    clkflg    ,r3        ; convert to ticks per second
  815.     mov    r3    ,r2        ; save 16-bit product here
  816.     sub    #locsiz    ,sp        ; allocate a local data buffer
  817.     mov    sp    ,r5        ; and a pointer to it
  818.     clr    -(sp)            ; init "msg rec'd" flag
  819.     mov    #noreply,nrings(r5)    ; after this many rings, give up..
  820.     clr    (r5)            ; status = 0
  821.  
  822. 10$:    tst    (r5)            ; while (status == 0)
  823.     bne    90$            ; exit with result
  824.     mov    #buffer    ,r3        ; a buffer pointer
  825.     clrb    (r3)            ; init buffer
  826.  
  827. 20$:    call    chkabo            ; strike any key to abort
  828.     tst    r0            ; get anything?
  829.     beq    30$            ; nope
  830.     inc    cccnt            ; fake abort so modem is stopped
  831.     call    clrcns            ; eat LF after a CR, etc..
  832.     br    40$            ; and bail out
  833.  
  834. 30$:    calls    xbinrea    ,<#-1>        ; this actually waits one tick
  835.     tst    r0            ; did that work?
  836.     beq    50$            ; ya
  837.     sob    r2    ,20$        ; no, try it all again
  838.  
  839. 40$:    mov    #aborted,(r5)        ; flag modem needs to be killed
  840.     br    90$            ; exit loop
  841.  
  842. 50$:    tstb    r1            ; never suffer embedded nulls
  843.     beq    20$            ; a null, skip it
  844.     bicb    #^c<177>,r1        ; ensure a real seven bit character
  845.     movb    r1    ,(r3)+        ; copy the byte over
  846.     clrb    (r3)            ; ensure we stay .asciz
  847.     tst    res.bin(r4)        ; exit loop on single character I/O?
  848.     bne    70$            ; yes
  849.     cmpb    r1    ,#cr        ; carriage return finally found?
  850.     beq    60$            ; yes
  851.     cmpb    r1    ,#lf        ; no, but
  852.     beq    60$            ; a line feed will do nicely
  853.     mov    r1    ,@sp        ; it's neither, set "msg rec'd" flag
  854.     mov    r1    ,r0        ; pass char to writ1char
  855.     call    writ1char        ; echo to TT
  856.     br    20$            ; then go back for more input
  857.  
  858. 60$:    cmpb    buffer    ,#cr        ; leading return?
  859.     beq    10$            ; can't be a valid response
  860.     cmpb    buffer    ,#lf        ; leading line feed?
  861.     beq    10$            ; ditto..
  862.  
  863. 70$:    tst    (sp)            ; was anything echo'd to TT?
  864.     beq    80$            ; no, cursor is already on column one
  865.     .newline            ; ya, tag it
  866. 80$:    jsr    pc,.default        ; go check result message
  867.     br    10$            ; next please
  868.  
  869. 90$:    mov    (r5)    ,r0        ; recover error
  870.     tst    (sp)+            ; pop "msg rec'd" flag buffer
  871.     add    #locsiz    ,sp        ; pop temp buffer
  872.     unsave    <r5>
  873.     return
  874.  
  875.  
  876.     .sbttl    Check modem's response    ; /39/ 4-DEC-1985, Brian Nelson
  877.  
  878. ;    Read possible responses and their message classes from a linked
  879. ;    list whose first address is in res.header(modem_address).  If a
  880. ;    modem has no mod$res entries this routine will fail any call.
  881.  
  882. .default:save    <r3>            ; /BBS/ about 50% new..
  883.     mov    res.head(r4),r3        ; get listhead of responses
  884.     beq    90$            ; nothing defined..
  885. 10$:    save    <r1,r2,r3>
  886.     add    #4    ,r3        ; 4 byte offset for text
  887.     mov    #buffer    ,r2        ; address of response to find text in
  888. 20$:    cmpb    (r2)    ,#space        ; is this a space or below?
  889.     bgt    30$            ; no, continue
  890.     inc    r2            ; ya, skip past leading blanks and non
  891.     br    20$            ; printing stuff before checking match
  892. 30$:    upcase    r3            ; uppercase text
  893.     strlen    r3            ; get its length
  894.     mov    r0    ,r1        ; save it
  895.     upcase    r2            ; uppercase response from modem
  896.     strlen    r2            ; get its length
  897.     calls    instr    ,<r2,r0,r3,r1>    ; see if desired text is in response
  898.     unsave    <r3,r2,r1>
  899.     dec    r0            ; match must begin from the top of
  900.     beq    40$            ; the response string, else ignore it
  901.     mov    (r3)    ,r3        ; get the next in the list
  902.     bne    10$            ; something is left to try
  903.     br    100$            ; tried 'em all..
  904. 40$:    mov    2(r3)    ,(r5)        ; response class
  905.     blt    50$            ; /62/ < is 38.4kb or a failed call
  906.     bgt    60$            ; 1 = ring, >1 = connect..
  907.     br    100$            ; 0 = info only, display but no action
  908. 50$:    cmp    (r5)    ,#con38400    ; /62/ is it 38.4kb?
  909.     bne    90$            ; /62/ no, it's a failed call..
  910.  
  911. 60$:    cmp    (r5)    ,#2        ; what to do ??
  912.     blo    80$            ; it wuz ring /62/ fix for 38.4kb
  913.     beq    100$            ; connect without speed check
  914.     call    ttspeed            ; speed supplied, get handler's speed
  915.     tst    r0            ; is it settable?
  916.     beq    70$            ; /62/ nope..
  917.     cmp    r0    ,(r5)        ; does modem speed = handler speed?
  918.     beq    70$            ; ya..
  919.     mov    r0    ,b4speed    ; no, save speed before fallback..
  920.     calls    setspd    ,<@r5>        ; set it now
  921. 70$:    mov    #connect,@r5        ; say it's time to connect
  922.     br    100$
  923.  
  924. 80$:    clr    @r5            ; turn ring into an info message
  925.     dec    nrings(r5)        ; if more than number in nrings
  926.     bne    100$            ; then give up
  927.     wrtall    #dia.07            ; /63/ "% No answer"<cr><lf>
  928.     mov    #aborted,(r5)        ; flag need to make modem stop
  929.     br    100$
  930. 90$:    mov    #failed    ,(r5)        ; come here if modem stopped itself
  931. 100$:    unsave    <r3>
  932.     return
  933.  
  934.  
  935.     .sbttl    Format dial string
  936.  
  937. ;    passed:      r3    = address of buffer to place result
  938. ;        argbuf    = the phone number to insert via %S
  939.  
  940. fmtstr:    save    <r3>
  941.     mov    dial.string(r4),r2    ; point to the dial format string
  942. 10$:    tstb    (r2)            ; done?
  943.     beq    140$            ; yes
  944.     cmpb    (r2)    ,#'%        ; look for a format effector
  945.     bne    120$            ; no
  946.  
  947.     mov    argbuf    ,r0        ; assume phone number insertion
  948.     cmpb    1(r2)    ,#'s!40        ; %S formatting?
  949.     beq    100$            ; yes
  950.     cmpb    1(r2)    ,#'S&137    ; check both cases
  951.     beq    100$            ; yes
  952.  
  953.     mov    dial.wait(r4),r0    ; no, assume pause string formatting
  954.     cmpb    1(r2)    ,#'p!40        ; %P for pause string?
  955.     beq    100$            ; yes
  956.     cmpb    1(r2)    ,#'P&137    ; check both cases
  957.     beq    100$            ; yes
  958.  
  959.     cmpb    1(r2)    ,#'x!40        ; /BBS/ "%X" for Hayes extended mode?
  960.     beq    20$            ; /BBS/ yes
  961.     cmpb    1(r2)    ,#'X&137    ; /BBS/ check both cases
  962.     bne    40$            ; /BBS/ no
  963. 20$:    tstb    xresult            ; /BBS/ is there an xmode set?
  964.     beq    30$            ; /BBS/ no, kill leading space here
  965.     movb    #'X&137    ,(r3)+        ; /BBS/ ya, insert an "X"
  966.     movb    xresult    ,(r3)+        ; /BBS/ then the mode, ala "X4"
  967.     movb    xresult+1,(r3)+        ; /BBS/ one char or two?
  968.     bne    110$            ; /BBS/ it was two this time..
  969. 30$:    dec    r3            ; /BBS/ it was one, fix pointer
  970.     br    110$            ; /BBS/ and continue
  971.  
  972. 40$:    cmpb    1(r2)    ,#'M&137    ; /54/ mode (ie PULSE, TONE)?
  973.     beq    50$            ; /54/ found it
  974.     cmpb    1(r2)    ,#'m!40        ; /54/ try lower case also..
  975.     bne    60$            ; /54/ nope
  976. 50$:    mov    dial.pulse(r4),r0    ; /54/ assume PULSE dialing
  977.     tst    pulse            ; /54/ ever SET PHONE PULSE or TONE?
  978.     beq    110$            ; /54/ no, ignore string
  979.     bmi    100$            ; /54/ ya, it's PULSE
  980.     mov    dial.nopulse(r4),r0    ; /54/ it's TONE
  981.     br    100$
  982.  
  983. 60$:    cmpb    1(r2)    ,#'B&137    ; /54/ SET PHONE BLIND?
  984.     beq    70$            ; /54/ ya..
  985.     cmpb    1(r2)    ,#'b!40        ; /54/ no, perhaps lower case?
  986.     bne    80$            ; /62/ nope
  987. 70$:    tst    blind            ; /54/ ever do the SET PHONE BLIND?
  988.     beq    110$            ; /54/ no, ignore string
  989.     mov    dial.blind(r4),r0    ; /54/ yes, insert the data then
  990.     br    100$
  991.  
  992. 80$:    cmpb    1(r2)    ,#'A&137    ; /62/ auto-answer format effector?
  993.     beq    90$            ; /62/ ya
  994.     cmpb    1(r2)    ,#'a!40        ; /62/ try lower case also..
  995.     bne    120$            ; /62/ no, copy data then
  996. 90$:    mov    ph.noanswer(r4),r0    ; /62/ default to not answering phone
  997.     tst    answer            ; /62/ did user SET PHONE ANSWER?
  998.     beq    100$            ; /62/ no
  999.     mov    ph.answer(r4),r0    ; /62/ ya, insert answer command
  1000.  
  1001. 100$:    movb    (r0)+    ,(r3)+        ; copy a byte please
  1002.     bne    100$            ; not a null, next please
  1003.     dec    r3            ; fix current pointer up
  1004. 110$:    inc    r2            ; skip over the "%" please
  1005.     br    130$            ; next please
  1006. 120$:    movb    (r2)    ,(r3)+        ; not formatting, copy character
  1007. 130$:    inc    r2            ; skip over current character now
  1008.     br    10$            ; next
  1009.  
  1010. 140$:    clrb    (r3)            ; ensure dial string is .asciz
  1011.     unsave    <r3>
  1012.     return
  1013.  
  1014.  
  1015.     .sbttl    Wait for a response    ; /BBS/ moderately revised..
  1016.  
  1017. ;    passed:     2(sp)    = string
  1018. ;         4(sp)    = time-out
  1019. ;    return:       r0    = <> for success, 0 for time out
  1020.  
  1021. waitfor:save    <r2,r3,r4>        ; this decrements stack pointer 6
  1022.     mov    2+6(sp)    ,r4        ; string we are expecting
  1023.     mov    4+6(sp)    ,r3        ; time-out in seconds
  1024.     mul    clkflg    ,r3        ; make it ticks
  1025.     clr    -(sp)            ; init data rec'd flag
  1026. 10$:    movb    (r4)+    ,r2        ; next character to await
  1027.     beq    50$            ; success, we can leave now
  1028.  
  1029. 20$:    tst    mute            ; allow strike any key abort?
  1030.     bne    30$            ; no
  1031.     call    chkabo            ; strike any key to abort
  1032.     tst    r0            ; get anything?
  1033.     beq    30$            ; nope
  1034.     inc    cccnt            ; fake abort so modem is stopped
  1035.     call    clrcns            ; eat LF after a CR, etc..
  1036.     br    60$            ; and bail out
  1037.  
  1038. 30$:    dec    r3            ; one less tick to wait
  1039.     beq    60$            ; no more ticks left
  1040.     calls    xbinrea    ,<#-1>        ; this actually waits one tick
  1041.     tst    r0            ; success?
  1042.     bne    20$            ; no
  1043.     bicb    #^c<177>,r1        ; remove parity always
  1044.     cmpb    r1    ,#cr        ; is it a return?
  1045.     beq    40$            ; ya, don't echo it
  1046.     cmpb    r1    ,#lf        ; is it a line feed?
  1047.     beq    40$            ; ya, don't echo it
  1048.     movb    r1    ,r0        ; get a copy of it
  1049.     beq    20$            ; dump nulls
  1050.     tst    mute            ; echo to TT this time?
  1051.     bne    40$            ; no, don't echo modem I/O
  1052.     mov    r0    ,@sp        ; set "msg rec'd" flag
  1053.     call    writ1char        ; keep user informed of what's up..
  1054. 40$:    cmpb    r1    ,r2        ; did we get the correct character?
  1055.     bne    20$            ; no, keep waiting then
  1056.     br    10$            ; found it, check for next character
  1057.  
  1058. 50$:    mov    sp    ,r0        ; success
  1059.     br    70$
  1060. 60$:    clr    r0            ; failure
  1061. 70$:    tst    (sp)+            ; was anything dumped to TT?
  1062.     beq    80$            ; nope
  1063.     .newline            ; ya, tag it with a newline
  1064. 80$:    unsave    <r4,r3,r2>
  1065.     mov    (sp)    ,4(sp)        ; move return address up and fix stack
  1066.     cmp    (sp)+    ,(sp)+        ; here instead of in calling macro
  1067.     return
  1068.  
  1069.  
  1070.     .sbttl    Eat junk from modem
  1071.  
  1072. eatjunk:save    <r0,r1>
  1073. 10$:    ttgetc    #-1            ; /BBS/ speed up junk consumption
  1074.     tst    r0            ; /BBS/ and thus redial faster..
  1075.     beq    10$            ; loop until nothing remains
  1076.     unsave    <r1,r0>
  1077.     return
  1078.  
  1079.  
  1080.     .sbttl    Send a string to the modem
  1081.  
  1082. do.put:    strlen    r1            ; /63/ get length
  1083.     tst    r0            ; anything to send?
  1084.     beq    10$            ; no
  1085.     calls    binwri    ,<r1,r0>    ; ya, length is in r0
  1086. 10$:    return
  1087.  
  1088.  
  1089.     .sbttl    SHOW MODEM, SHOW DIAL    ; /BBS/ heavily hacked
  1090.  
  1091. shodia::call    loamdm            ; /63/ ensure correct overlay loaded
  1092.     mov    modtype    ,r4        ; get address of descriptor
  1093.     bne    10$            ; got it
  1094.     direrr    #er$mdm            ; no modem type has been set
  1095.     return
  1096.  
  1097. 10$:    mov    #deslist,r3        ; /63/ info list start
  1098. 20$:    movb    (r3)+    ,r1        ; /62/ type 2=on/off,1=string,0=number
  1099.     movb    (r3)+    ,r2        ; /62/ offset, zero implies end
  1100.     beq    100$            ; all done
  1101.     add    r4    ,r2        ; move to the correct offset
  1102.     mov    r3    ,-(sp)        ; /62/ save the header address
  1103. 30$:    tstb    (r3)+            ; now look for the end of it
  1104.     bne    30$            ; not yet
  1105.     decb    r1            ; /62/ determine data type
  1106.     bgt    70$            ; /62/ it's "2"  goto on/off displayer
  1107.     beq    40$            ; /62/ it's "1"  goto string handler
  1108.     wrtall    (sp)+            ; /62/ dump the header
  1109.     mov    @r2    ,r0        ; it is "0"  copy number to display
  1110.     call    L10266            ; write it to terminal
  1111.     br    90$            ; next please
  1112.  
  1113. 40$:    mov    (r2)    ,r0        ; get the string address
  1114.     beq    50$            ; /62/ nothing there
  1115.     tstb    @r0            ; again
  1116.     bne    60$            ; /62/ there is something to see
  1117. 50$:    tst    (sp)+            ; /62/ nothing, dump unused header
  1118.     br    20$            ; /62/ skip newline, try next one
  1119. 60$:    wrtall    (sp)+            ; /62/ dump the header
  1120.     call    unfmts            ; convert and print it
  1121.     wrtall    r0            ; do it
  1122.     br    90$            ; next
  1123.  
  1124. 70$:    wrtall    (sp)+            ; /62/ dump the header
  1125.     mov    (r2)    ,r0        ; /62/ get the data
  1126.     beq    80$            ; /62/ 0 = no
  1127.     wrtall    #dia.08            ; /63/ anything_else = "Yes"
  1128.  
  1129.     br    90$            ; /62/
  1130. 80$:    wrtall    #dia.09            ; /63/ "No"
  1131. 90$:    .newline
  1132.     br    20$            ; next
  1133.  
  1134. 100$:    wrtall    #dia.10            ; /63/ "Dial time-out secs: "
  1135.     mov    diatmo    ,r0        ; /62/ get time-out time
  1136.     call    L10266            ; /62/ display it
  1137.     .newline            ; /62/
  1138.  
  1139.     wrtall    #dia.11            ; /63/ "Settle-time ticks:  "
  1140.     mov    settle    ,r0        ; get settle time
  1141.     call    L10266            ; display it
  1142.     .newline            ; /62/
  1143.  
  1144.     clr    -(sp)            ; a flag, if <> something found
  1145.  
  1146.     mov    ph.noanswer(r4),r1    ; /62/ default to not answering phone
  1147.     tst    answer            ; /62/ did user SET PHONE ANSWER?
  1148.     beq    110$            ; /62/ no
  1149.     mov    ph.answer(r4),r1    ; /62/ ya, insert answer command
  1150. 110$:    tstb    @r1            ; /62/ if there is any..
  1151.     beq    120$            ; /62/ there isn't
  1152.     movb    #'A&137    ,r2        ; /62/ there is, and it's this type
  1153.     call    foreff            ; /62/ go display it
  1154.  
  1155. 120$:    tst    blind            ; ever SET PHONE BLIND?
  1156.     beq    130$            ; no, ignore string
  1157.     mov    dial.blind(r4),r1    ; yes, insert the data then
  1158.     tstb    @r1            ; if there is any..
  1159.     beq    130$            ; there isn't
  1160.     movb    #'B&137    ,r2        ; /62/ there is, and it's this type
  1161.     call    foreff            ; go display it
  1162.  
  1163. 130$:    mov    dial.pulse(r4),r1    ; assume PULSE dialing
  1164.     tst    pulse            ; ever SET PHONE PULSE or TONE?
  1165.     beq    150$            ; no, ignore string
  1166.     bmi    140$            ; ya, it's PULSE
  1167.     mov    dial.nopulse(r4),r1    ; it's TONE
  1168. 140$:    tstb    @r1            ; anything defined?
  1169.     beq    150$            ; nope
  1170.     movb    #'M&137    ,r2        ; /62/ there is, and it's this type
  1171.     call    foreff            ; go display it
  1172.  
  1173. 150$:    tstb    xresult            ; anything set here?
  1174.     beq    170$            ; nope..
  1175.     tst    (sp)            ; /62/ has this stuff been identified?
  1176.     bne    160$            ; /62 ya
  1177.     wrtall    #msg$fmt        ; /62/ no, do that now
  1178.     mov    sp    ,(sp)        ; /62/ and set flag it has been done
  1179. 160$:    wrtall    #dia.12            ; /63/ ya, dump a header: '%X = "X'
  1180.     wrtall    #xresult        ; and the actual number
  1181.     mov    #'"    ,r0        ; /62/
  1182.     call    writ1char        ; /62/
  1183.  
  1184. 170$:    tst    (sp)+            ; /62/ dump formatter flag buffer
  1185.     beq    180$            ; /62/ no newline needed..
  1186.     .newline            ; done with format effectors
  1187.  
  1188. 180$:    wrtall    #dia.13            ; /63/ "Binary-responses:   "
  1189.     tst    res.bin(r4)        ; /62/ on or off?
  1190.     beq    190$            ; /62/ 0 = no
  1191.     wrtall    #dia.08            ; /63/ anything_else = "Yes"
  1192.     br    200$            ; /62/
  1193. 190$:    wrtall    #dia.09            ; /63/ "No"
  1194. 200$:    .newline            ; /62/
  1195.  
  1196.     mov    res.head(r4),r3        ; response header
  1197.     beq    290$            ; nothing present
  1198.     wrtall    #dia.14            ; /63/ "Result strings:"<cr><lf>
  1199. 210$:    mov    r3    ,r0        ; /62/ get the response address
  1200.     beq    290$            ; all done
  1201.     add    #4    ,r0        ; /62/ offset to text
  1202.     call    unfmts            ; /62/ convert it
  1203.     wrtall    r0            ; /62/ and print it
  1204.     strlen    r0            ; /62/ ..more efficient
  1205.     sub    #col.act,r0        ; number of blanks needed to pad
  1206.     neg    r0            ; make it positive
  1207.     mov    r0    ,r5        ; save it in a safe place
  1208.     ble    230$            ; avoid this please
  1209.     mov    #space    ,r0        ; load up a space
  1210. 220$:    call    writ1ch            ; this way is more efficient
  1211.     sob    r5    ,220$        ; loop until done
  1212.  
  1213. 230$:    mov    2(r3)    ,r0        ; what is the message class?
  1214.     bmi    270$            ; if < it's failure to connect
  1215. 240$:    dec    r0            ; if = 1 it's ringing
  1216.     beq    260$            ; it was one, because now it's 0
  1217.     wrtall    #dia.15            ; /63/ "Success"
  1218.     dec    r0            ; if = 2 connect w/o speed check
  1219.     beq    250$            ; it wuz 2
  1220.     inc    r0            ; restore
  1221.     inc    r0            ; r0
  1222.     wrtall    #msg$dte        ; "  DTE is forced to "
  1223.     call    L10266            ; tag above with speed
  1224. 250$:    .newline
  1225.     br    280$
  1226. 260$:    wrtall    #dia.16            ; /63/ "Rings+1"<cr><lf>
  1227.     br    280$
  1228. 270$:    cmp    r0    ,#con38400    ; /62/ kludge to see if it's 38.4kb
  1229.     beq    240$            ; /62/ it is..
  1230.     wrtall    #dia.17            ; /63/ "Failure"<cr><lf>
  1231. 280$:    mov    (r3)    ,r3        ; pick up link to..
  1232.     br    210$            ; ..next please
  1233.  
  1234. 290$:    clr    r0            ; /62/
  1235.     return
  1236.  
  1237. foreff:    tst    2(sp)            ; /62/ need to print header?
  1238.     bne    10$            ; /62/ nope..
  1239.     wrtall    #msg$fmt        ; /62/ ya
  1240.     mov    sp    ,2(sp)        ; /62/ but not anymore
  1241. 10$:    mov    #'%    ,r0        ; /62/ a percent sign char
  1242.     call    writ1char        ; /62/ dump it to the terminal
  1243.     movb    r2    ,r0        ; /62/ the format effector character
  1244.     call    writ1char        ; /62/ now dump it to tt
  1245.     wrtall    #prefix            ; /62/ do some display formatting
  1246.     wrtall    r1            ; /62/ now display what is inserted
  1247.     wrtall    #tripsp            ; /62/ format display
  1248.     return
  1249.  
  1250.     des    1 ,mod.string    ,<Modem name:         >
  1251.     des    1 ,mod.comment    ,<Modem type:         >
  1252.     des    1 ,wake.string    ,<Wakeup string:      >
  1253.     des    0 ,wake.rate    ,<Wake-rate in ticks: >
  1254.     des    1 ,wake.prompt    ,<Response to wakeup: >
  1255.     des    1 ,dial.string    ,<Dial FORMAT string: >
  1256.     des    0 ,dial.rate    ,<Dial-rate in ticks: >
  1257.     des    1 ,dial.wait    ,<Pause character(s): >
  1258.     des    1 ,dial.ack    ,<Dial-acknowledge:   >
  1259.     des    1 ,dmod.string    ,<"Initiate" string:  >
  1260.     des    1 ,dmod.prompt    ,<"Initiate" prompt:  >
  1261.     des    1 ,dial.confirm    ,<"Confirm" string:   >
  1262.     des    1 ,dial.go    ,<"Confirm" ack:      >
  1263.     des    2 ,dial.echo    ,<Echoes dial string: >
  1264.     des    2 ,init.once    ,<Redial w/o reinit:  >
  1265.     des    1 ,dial.blind    ,<Blind dial string:  >
  1266.     des    1 ,dial.pulse    ,<Pulse dial string:  >
  1267.     des    1 ,dial.nopulse    ,<Tone dial string:   >
  1268.     des    1 ,dial.xabort    ,<Dial abort string:  >
  1269.     des    1 ,dial.idle    ,<Reset/idle string:  >
  1270.     des    1 ,ph.answer    ,<Enable autoanswer:  >
  1271.     des    1 ,ph.noasnwer    ,<Disable autoanswer: >
  1272.     des
  1273.  
  1274.     .end
  1275.