home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / test / pdp11 / krtdia.mac < prev    next >
Text File  |  1996-10-17  |  43KB  |  1,284 lines

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