home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / pdp11 / k11dia.mac < prev    next >
Text File  |  2020-01-01  |  44KB  |  1,619 lines

  1.     .title    K11DIA    dial command for kermit-11
  2.     .ident    /t2.40/
  3.  
  4. ;    18-Oct-85  20:06:09 Brian Nelson
  5. ;
  6. ;    04-Dec-85  11:22:32 BDN     Add optional linked list structure to
  7. ;                define modem responses, will be useful
  8. ;                when adding a SET DIAL command.
  9. ;    06-Dec-85  11:53:59 BDN     Added extra field in DEFINE macro and
  10. ;                support code to call external routines
  11. ;                for dialing, needed for PRO/TMS.
  12. ;    09-Jan-86  17:48:17 RTM  Added support for the RIXON Intelligent
  13. ;        (RTM01)        autodial modem (R212A).
  14. ;
  15. ;    13-Feb-86  10:10:08 BDN     Put the DF112 and DF224 responses into
  16. ;                linked lists.
  17. ;    23-Sep-86  14:10:30 BDN     Vadic 4224 modems
  18. ;    23-Sep-86  14:10:42 BDN     Added format effector %M for pulse/tone
  19. ;                if a SET PHONE PULSE/TONE was done. Also
  20. ;                added %B for 'blind' dialing, enabled if
  21. ;                SET PHONE BLIND
  22. ;    30-Sep-86  13:05:53 BDN     Added CTS2424, Also SHO DIAL
  23. ;    09-Feb-89  00:00:00 JCH  Complete definition of DF224 modem.
  24. ;
  25. ;    Copyright (C) 1985 1986 Change Software, Inc.
  26. ;
  27. ;
  28. ;     Its about time for a DIAL command. Would be really nice to use
  29. ;    on my PRO/350 and the XK: port. Of limitted utility  on the  44
  30. ;    as I  have to enter the GANDALF PACX to access the VADIC 212PAR
  31. ;    modems.
  32. ;
  33. ;     As noted in a number of comments, the timer support for RSTS/E
  34. ;    is abbysmal, the only thing you can do is SLEEP n, where 'n' is
  35. ;    in seconds.  Even worse is  the fact that various  asynchronous
  36. ;    events can prematurely cancel the sleep, like a delimiter typed
  37. ;    at a terminal allocated to the job. Also, you can NOT do a mark
  38. ;    time on RSTS/E, though version 9 does have the groundwork layed
  39. ;    for adding timer AST's in that v9 supports asych i/o,  thus the
  40. ;    needed executive data structures are mostly present.
  41. ;
  42. ;     I do not mean to knock RSTS/E really,  RSTS has a great number
  43. ;    of features that make interfacing with the terminal driver much
  44. ;    simpler than what one finds on RSX and RT11,  while at the same
  45. ;    time introducing its own peculiarities. RSX is by far the worst
  46. ;    as I often find grossly dissimiliar behavior between RSX sites.
  47. ;
  48. ;     As a final reflection, if I were to grade RSTS, RT and RSX  on
  49. ;    simplicity and stability of terminal driver interfacing,   RT11
  50. ;    would have to come first (both MT and XC/XL versions), followed
  51. ;    by RSTS and bringing up the rear, RSX (I've been burned on both
  52. ;    RSX and RSTS when new versions came out,  though being a RSTS/E
  53. ;    field test site tends to help).
  54.  
  55.  
  56.  
  57.  
  58.  
  59.     .if ndf, K11INC
  60.     .ift
  61.     .include    /IN:K11MAC.MAC/
  62.     .endc
  63.  
  64.     .enabl    lc
  65.     .nlist
  66.  
  67.  
  68. ;     It would be nice to be able to do this in a macro call but the
  69. ;    PDP-11 assembler does not allow continuation lines.  So what we
  70. ;    will instead do is define each arg as a word offset from a base
  71. ;    address of a list for that modem.
  72. ;    In many cases we could fit all the info on one line, but macros
  73. ;    dragged out that way are unreadable. It would be really nice to
  74. ;    be able to say:
  75. ;
  76. ;    moddef    type    = <VA212PAR> - ,
  77. ;        dial.time = 30. - ,
  78. ;        wake.string = .....      and so on.
  79. ;
  80. ;    .macro    moddef    dial.t,wake.s,wake.r,wake.p,dmod.s,dmod.p,dial.s,dial.r
  81. ;
  82. ;    Losely based on CKUDIAL.C
  83. ;
  84. ;    All times for delays are in TICKS (1/60 second intervals)
  85. ;
  86. ;    dial.time    Time the modem may use to dial a number
  87. ;    wake.string    Get modems attention, like in VADIC 212 ^E<CR>
  88. ;    wake.rate    Delay in milliseconds modem may need
  89. ;    wake.prompt    Modems command mode prompt
  90. ;    dmod.string    String needed to get it to dial a number
  91. ;    dmod.prompt    Dial mode prompt
  92. ;    dial.string    The string for dial, includes a %s for number position
  93. ;    dial.rate    delay between sending numbers over, in TICKS
  94. ;    wake.ack    as in va212, 'HELLO:I'M READY'
  95. ;    dial.ack    string to wait for to confirm number
  96. ;    dial.echo
  97. ;
  98. ;    WARNING: If any of these values are CHANGED, and there is absolutely
  99. ;    NO reason to do so,  you must check K11ST0.MAC  where a few of these
  100. ;    are also defined for the SET DIAL command. Anything new that's need-
  101. ;    ed in the modem database is  always added on to the END of the list.
  102. ;    While it is freely acknowledged that there are  now a couple of  ob-
  103. ;    solete fields, it doesn't cost that much. Leave the structure alone.
  104.  
  105.     mod.next    =:    0    ; next modem in list
  106.     mod.str        =:    2    ; address of name of modem
  107.     mod.val        =:    4    ; numeric value for dispatching
  108.     dial.time    =:    6    ; value of dial time
  109.     wake.string    =:    10    ; address of wakeup string
  110.     wake.rate    =:    12    ; value of delay
  111.     wake.prompt    =:    14    ; address of wakeup prompt
  112.     dmod.string    =:    16    ; address of dial dial string
  113.     dmod.prompt    =:    20    ; address of prompt returned for dial
  114.     dial.string    =:    22    ; address of formatting string for dial
  115.     dial.rate    =:    24    ; value of delay
  116.     wake.ack    =:    26    ; address of wakeup response
  117.     dial.ack    =:    30    ; 1st = waitfor, 2nd to confirm number
  118.     dial.online    =:    32    ; online ack string
  119.     dial.blind    =:    34    ; blind ack
  120.     dial.wait    =:    36    ; String for PAUSE characters
  121.     dial.confirm    =:    40    ; string to confirm number for dialing
  122.     dial.go        =:    42    ; ie, va212 returns "DIALING\n"
  123.     res.bin        =:    44    ; if <>, returns status with \n
  124.                     ; otherwise a binary response (DF03)
  125.     dial.echo    =:    46    ; if <>, numbers are echoed immediately
  126.     mod.comment    =:    50    ;
  127.     res.head    =:    52    ; 
  128.     ext.dial    =:    54    ; if ne, address of external dialer
  129.     dial.xabort    =:    56    ; /45/ To abort call from modem
  130.     dial.idle    =:    60    ; /45/ Place modem in IDLE state
  131.     dial.pulse    =:    62    ; /45/ Switch to pulse dialing
  132.     dial.nopulse    =:    64    ; /45/ Switch to tone dialing
  133.     def.guard    =:    66    ; /45/ last thing (unused)
  134.  
  135.  
  136.  
  137.  
  138.     .psect    modinf    ,ro,d,lcl,rel,con
  139.     .enabl    lc
  140.  
  141.     .macro    modval    val,offset
  142.     .save
  143.     .psect    modinf
  144.     . = $$current + offset
  145.     .word    val
  146.     .restore
  147.     .endm    modval
  148.  
  149.     .macro    modstr    s,offset
  150.     .save
  151.     .psect    string
  152.     $$addr    =    .
  153.     $$ = 0
  154.     .irpc    ch,<s>
  155.      ch1 = ''ch
  156.      .if eq, ch1 - '^
  157.      .ift
  158.        $$ = 100
  159.      .iff
  160.        .if ne    ,$$
  161.        .if ge    , <ch1!40> - <'a!40>
  162.         .iif le, <ch1!40> - <'z!40>, ch1 = ch1&137
  163.        .endc
  164.        .endc
  165.      .byte    ch1-$$
  166.      $$ = 0
  167.      .endc
  168.     .endr
  169.     .byte    0
  170.     .restore
  171.     .save
  172.     .psect    modinf
  173.     . = $$current + offset
  174.     .word    $$addr
  175.     .restore
  176.     .endm    modstr
  177.     
  178.  
  179.     .sbttl    inialize subfields of modem info structure
  180.  
  181.  
  182.     .macro    dial$time    val
  183.     modval    val,dial.time
  184.     .endm    dial$time
  185.  
  186.     .macro    wake$rate    val
  187.     modval    val,wake.rate
  188.     .endm    wake$rate
  189.  
  190.     .macro    dial$rate    val
  191.     modval    val,dial.rate
  192.     .endm    dial$rate
  193.  
  194.     .macro    wake$string    s
  195.     modstr    <s>,wake.string
  196.     .endm    wake$string
  197.  
  198.     .macro    wake$prompt    s
  199.     modstr    <s>,wake.prompt
  200.     .endm    wake$prompt
  201.  
  202.     .macro    dmod$string    s
  203.     modstr    <s>,dmod.string
  204.     .endm    dmod$string
  205.  
  206.     .macro    dmod$prompt    s
  207.     modstr    <s>,dmod.prompt
  208.     .endm    dmod$prompt
  209.  
  210.     .macro    dial$string    s
  211.     modstr    <s>,dial.string
  212.     .endm    dial$string
  213.  
  214.     .macro    mod$comment    s
  215.     modstr    <s>,mod.com
  216.     .endm    mod$comment
  217.  
  218.     .macro    dial$ack    s
  219.     modstr    <s>,dial.ack
  220.     .endm    dial$ack
  221.  
  222.     .macro    dial$confirm    s
  223.     modstr    <s>,dial.confirm
  224.     .endm    dial$confirm
  225.  
  226.     .macro    dial$online    s
  227.     modstr    <s>,dial.online
  228.     .endm    dial$online
  229.  
  230.     .macro    dial$blind    s
  231.     modstr    <s>,dial.blind
  232.     .endm    dial$blind
  233.  
  234.     .macro    dial$wait    s
  235.     modstr    <s>,dial.wait
  236.     .endm    dial$wait
  237.  
  238.     .macro    dial$go        s
  239.     modstr    <s>,dial.go
  240.     .endm    dial$go
  241.  
  242.     .macro    dial$echo    v
  243.     modval    v,dial.echo
  244.     .endm    dial$echo
  245.  
  246.     .macro    dial$pulse    s    ; /45/ String to force PULSE dialing
  247.     modstr    <s>,dial.pulse        ; /45/ ...
  248.     .endm    dial$pulse        ; /45/ ...
  249.  
  250.     .macro    dial$nopulse    s    ; /45/ String to force tone dialing
  251.     modstr    <s>,dial.nopulse    ; /45/ ...
  252.     .endm    dial$nopulse        ; /45/ ...
  253.  
  254.     .macro    dial$xabort    s    ; /45/ Use this field if we detect
  255.     modstr    <s>,dial.xabort        ; /45/ a control C abort and need
  256.     .endm    dial$xabort        ; /45/ to get the modem to stop dialing
  257.  
  258.     .macro    dial$idle    s    ; /45/ Switch from command mode to
  259.     modstr    <s>,dial.idle        ; /45/ to IDLE mode
  260.     .endm    dial$idle        ; /45/
  261.  
  262.  
  263.     .macro    ext$dial    v
  264.     modval    v,ext.dial
  265.     .endm    ext$dial
  266.  
  267.     .macro    res$bin    v
  268.     modval    v,res.bin
  269.     .endm    res$bin
  270.  
  271.     .macro    wake$ack    s
  272.     modstr    <s>,wake.ack
  273.     .endm    wake$ack
  274.  
  275.  
  276.     $$prev    =    modinf
  277.     $$seq    =    1
  278.  
  279.     .save
  280.     .psect    usermd    ,rw,d,gbl,rel,con
  281. null2:    .byte    0
  282. null:    .byte    0
  283.     .psect    string    ,ro,d,lcl,rel,con
  284.     .psect    rwdata    ,rw,d,lcl,rel,con
  285. bell:    .byte    'G&37,'G&37,0
  286.     .even
  287. modtyp:    .word    0
  288. buffer:    .blkb    200
  289. ttbuff:    .blkb    200
  290.     .restore    
  291.  
  292.  
  293.     .macro    define    lab    ,s    ,user
  294.  
  295.     .if nb    ,user            ; if we are defining the 'user'
  296.     .ift                ; modem we need to be in a global
  297.     .save                ; psect to be located in the root
  298.     .psect    usermd    ,rw,d,gbl,rel,con ; put a reference to this psect
  299.     .iff                ; in k11dat
  300.     $modtail==    .        ; to manually set link to 'usermd'
  301.     .endc                ; 
  302.     .iif    ndf, $$prev    ,$$prev = modinf
  303.     $$current    =    .    ; save current pc
  304.     $res    =    0
  305.     $reslast=    0
  306. lab:    .word    0            ; link to next please
  307.     .iif nb, user, .globl lab    ; must be global if USER mode
  308.     .save                ; save current psect
  309.     .psect    string            ; switch to string psect
  310.     $$ = .                ; save it's current PC
  311.     .asciz    /s/            ; insert the modem type string
  312.     .even                ; always useful for word addressing
  313.     .restore            ; pop the previous psect (modinf)
  314.     .word    $$            ; and insert address of the string
  315.     $'lab    =    $$seq        ; define sequence value
  316.     .word    $$seq            ; store value in structure
  317.     $$seq    =    $$seq + 1    ; sequence number
  318.     .word    30.            ; default for dial time
  319.     .word    null            ; default for wakeup
  320.     .word    0            ; default for delay
  321.     .word    null            ; default for command mode prompt
  322.     .word    null            ; default for dial command
  323.     .word    null            ; default for dial prompt
  324.     .word    null            ; default for dial formatting
  325.     .word    0            ; default for dial delay
  326.     .word    null            ; default for wakeup ack
  327.     .word    null2            ; default for ack string
  328.     .word    null            ; default for dial.online
  329.     .word    null            ; default for dial.blind
  330.     .word    null            ; default for dial.wait
  331.     .word    null            ; default for dial.confirm
  332.     .word    null            ; default for dial.go
  333.     .word    0            ; 0 normal, else 1 for binary (res.bin)
  334.     .word    0            ; default for dial.echo
  335.     .word    null            ; default for MOD$COMMENT
  336.     .word    0            ; res.head
  337.     .word    0            ; possible external dialer address
  338.     .word    null            ; /45/ Default for XABORT string
  339.     .word    null            ; /45/ Default for IDLE string
  340.     .word    null            ; /45/ Default for PULSE dialing
  341.     .word    null            ; /45/ Default for TONE dialing
  342.     .word    0            ; guard word
  343.     $$end    =    .
  344.  
  345.     $$size    =    $$end - $$current
  346.     .assume    $$size  eq <def.guard+2>
  347.  
  348.     .if b    ,user            ; we don't want psect errors from
  349.     .ift                ; MAC for the USER modem type.
  350.     .    =    $$prev
  351.     .word    lab
  352.     .    =    $$end
  353.     $$prev    =    lab
  354.     .iff
  355.     .restore            ; for USER type, return to old psect
  356.     .endc                ; Also, the USER modem MUST be last
  357.     .endm    define
  358.  
  359.  
  360.     .sbttl    create a linked list, header in res.head
  361.  
  362. ;    Added edit /39/ Brian Nelson  4-DEC-1985 09:46
  363. ;
  364. ;     Create a linked  list  of  possible  modem  responses.  The
  365. ;    advantages  of  this is that we could use a SET DIAL command
  366. ;    to create a modem data  structure  at  run  time,  and  that
  367. ;    defining  modems  is  simplified.  As  a  note,  there is no
  368. ;    requirement to use this structure. It will be used  for  the
  369. ;    DEFAULT entry in the 'GETSTS' routine. 
  370. ;
  371. ;
  372. ;    Format is:    res.head(current_modem) --> first entry
  373. ;
  374. ;
  375. ;    Entry format:    .word    next    (or zero for tail)
  376. ;            .word    class    (-1 fail, 0 info, 1 sucess)
  377. ;            .asciz    /response_string/
  378.  
  379.     CONNECT    =    1
  380.     INFO    =    0
  381.     FAILED    =    -1
  382.  
  383.  
  384.     .save
  385.     .psect    resdat    ,rw,d,lcl,rel,con
  386. resdat:
  387.     .restore
  388.  
  389.     .macro    mod$res    s,class
  390.  
  391.     .save                ; save current psect context
  392.     .psect    resdat    ,rw,d,lcl,rel,con
  393.     $res1    =    .        ; save current pc in 'resdat'
  394.     .word    0            ; link to next is zero
  395.     .if b, class            ; if class not specified, then
  396.     .word    0            ; make it zero
  397.     .iff                ; else insert it
  398.     .word    class            ; response class
  399.     .endc                ; if b, class
  400.     .asciz    /s/            ; the actual text
  401.     .even                ; must do
  402.     .restore            ; get last psect
  403.     .if eq    ,$res            ; is this first time for new
  404.     .ift                ; type ?
  405.     modval    $res1,res.head        ; yes, stuff the link header
  406.     .iff                ; not the first time
  407.     .save                ; save current psect context
  408.     .psect    resdat            ; and a new one
  409.     $respc = .            ; save the current pc
  410.     . = $reslast            ; backup to link word from previous
  411.     .word    $res1            ; insert address of new entry
  412.     . = $respc            ; restore correct pc
  413.     .restore            ; restore old psect context
  414.     .endc                ; end
  415.     $reslast = $res1        ; lastlink = current_entry
  416.     $res    =    1        ; not the first time anymore
  417.  
  418.     .endm                ; thats it
  419.  
  420.     .list
  421.  
  422.  
  423.     .sbttl    finally, we can define the modem
  424.     .psect    modinf    ,ro,d,lcl,rel,con
  425.  
  426.  
  427. ;    All xxxx$rate values are in TICKS (1/60 second)
  428. ;    WARNING: The definition for USER_DEFINED MUST be last !!!!!!!
  429. ;    WARNING: Before accessing any data here  from outside of this
  430. ;    module (overlay), insure the overlay is loaded, as in calling
  431. ;    FINDMODEM with the modem type string .asciz pointed to by R5.
  432.  
  433. modinf::
  434.     define    v2pa    ,<VA212PA>    ; stand alone VA212PA
  435.     dial$time    35.
  436.     wake$string    <^E^M>
  437.     wake$rate    10        ; wait 8 ticks (8/60 second)
  438.     wake$ack    <HELLO:I'M READY>
  439.     wake$prompt    <*>
  440.     dmod$string    <D^M>
  441.     dmod$prompt    <?>
  442.     dial$string    <%s^M>
  443.     dial$rate    10
  444.     dial$ack    <^M>
  445.     dial$confirm    <^M>
  446.     dial$go        <DIALING>
  447.     dial$echo    1
  448.     dial$xabort    <^M>
  449.     dial$idle    <I^M>
  450.     dial$wait    <K>
  451.     mod$comment    <Stand alone VADIC VA212>
  452.     mod$res        <ON LINE>    ,CONNECT
  453.     mod$res        <ONLINE>    ,CONNECT
  454.     mod$res        <BUSY>        ,FAILED
  455.     mod$res        <FAILED CALL>    ,FAILED
  456.     mod$res        <NO DIAL>    ,FAILED
  457.     mod$res        <VOICE>        ,FAILED
  458.     mod$res        <TIME OUT>    ,FAILED
  459.     mod$res        <RINGING>    ,INFO
  460.  
  461.     define    v2par    ,<VA212PAR>    ; rack mounted VA212PAR
  462.     dial$time    35.
  463.     wake$string    <^E^M>
  464.     wake$rate    10
  465.     wake$ack    <HELLO:I'M READY>
  466.     wake$prompt    <*>
  467.     dmod$string    <D^M>
  468.     dmod$prompt    <?>
  469.     dial$string    <%s^M>
  470.     dial$rate    10
  471.     dial$go        <DIALING>
  472.     dial$echo    1
  473.     dial$xabort    <^M>
  474.     dial$idle    <I^M>
  475.     dial$wait    <K>
  476.     mod$comment    <Rack mounted VADIC VA212PAR>
  477.     mod$res        <ON LINE>    ,CONNECT
  478.     mod$res        <ONLINE>    ,CONNECT
  479.     mod$res        <BUSY>        ,FAILED
  480.     mod$res        <FAILED CALL>    ,FAILED
  481.     mod$res        <NO DIAL>    ,FAILED
  482.     mod$res        <VOICE>        ,FAILED
  483.     mod$res        <TIME OUT>    ,FAILED
  484.     mod$res        <RINGING>    ,INFO
  485.  
  486.     define    vadic    ,<VADIC>    ; stand alone VA212PA
  487.     dial$time    35.
  488.     wake$string    <^E^M>
  489.     wake$rate    10
  490.     wake$ack    <HELLO:I'M READY>
  491.     wake$prompt    <*>
  492.     dmod$string    <D^M>
  493.     dmod$prompt    <?>
  494.     dial$string    <%s^M>
  495.     dial$rate    10
  496.     dial$ack    <^M>
  497.     dial$confirm    <^M>
  498.     dial$go        <DIALING>
  499.     dial$echo    1
  500.     dial$xabort    <^M>
  501.     dial$idle    <I^M>
  502.     dial$wait    <K>
  503.     mod$comment    <Generic VADIC with autodial>
  504.     mod$res        <ON LINE>    ,CONNECT
  505.     mod$res        <ONLINE>    ,CONNECT
  506.     mod$res        <BUSY>        ,FAILED
  507.     mod$res        <FAILED CALL>    ,FAILED
  508.     mod$res        <NO DIAL>    ,FAILED
  509.     mod$res        <VOICE>        ,FAILED
  510.     mod$res        <TIME OUT>    ,FAILED
  511.     mod$res        <RINGING>    ,INFO
  512.  
  513.  
  514.     define    cts24    ,<CTS2424>    ; CTS (Fabritek) 2424 autodial
  515.     dial$time    35.
  516.     wake$string    <^T^WAT^Q^M>    ; Just in case add ^Q<cr> in also
  517.     wake$rate    10
  518.     wake$ack    <Modem Ready>
  519.     dial$string    <D%M%B%S^M>
  520.     dial$rate    10
  521.     dial$xabort    <^T^W>
  522.     dial$idle    <^T^W>
  523.     dial$wait    <+>
  524.     dial$pulse    <P>
  525.     dial$nopulse    <T>
  526.     dial$blind    <&>
  527.     dial$echo    1
  528.     mod$comment    <CTS/Fabri-Tek 2424AD V.22bis Autodialier>
  529.     mod$res        <Ring>        ,INFO
  530.     mod$res        <Busy>        ,FAILED
  531.     mod$res        <Dead Line>    ,FAILED
  532.     mod$res        <Disconnect>    ,FAILED
  533.     mod$res        <Modem Ready>    ,INFO
  534.     mod$res        <No Answer>    ,FAILED
  535.     mod$res        <No Dialtone>    ,FAILED
  536.     mod$res        <No Tone>    ,FAILED
  537.     mod$res        <On Line>    ,CONNECT
  538.     mod$res        <On Line Originate>,CONNECT
  539.     mod$res        <Redialing>    ,INFO
  540.  
  541.  
  542.     define    va42    ,<VA4224>    ; Rack mount 2400 baud
  543.     dial$time    35.
  544.     wake$string    <^E^M>
  545.     wake$rate    10
  546.     wake$ack    <HELLO:I'M READY>
  547.     wake$prompt    <*>
  548.     dial$string    <D%M%S%B^M>
  549.     dial$rate    10
  550.     dial$go        <DIALING>
  551.     dial$echo    1
  552.     dial$xabort    <^M>
  553.     dial$idle    <I^M>
  554.     dial$wait    <K>
  555.     dial$pulse    <P>
  556.     dial$nopulse    <T>
  557.     dial$blind    <B>
  558.     mod$comment    <Vadic 4224 CCITT V.22bis autodial>
  559.     mod$res        <ON LINE>    ,CONNECT
  560.     mod$res        <ONLINE>    ,CONNECT
  561.     mod$res        <BUSY>        ,FAILED
  562.     mod$res        <FAILED CALL>    ,FAILED
  563.     mod$res        <NO DIAL>    ,FAILED
  564.     mod$res        <VOICE>        ,FAILED
  565.     mod$res        <TIME OUT>    ,FAILED
  566.     mod$res        <RINGING>    ,INFO
  567.     mod$res        <ON LINE 300>    ,CONNECT
  568.     mod$res        <ON LINE 1200>    ,CONNECT
  569.     mod$res        <ON LINE 2400>    ,CONNECT
  570.     mod$res        <ERROR CONTROL>    ,INFO
  571.     mod$res        <NO ERROR CONTROL>,INFO
  572.  
  573.     define    df03    ,<DF03>        ; dec DF03
  574.     dial$time    30.
  575.     wake$string    <^A^B>
  576.     dial$string    <%s>
  577.     dial$echo    1
  578.     res$bin        1        ; responds in binary (no crlf)
  579.     mod$comment    <DEC DF03AC Autodial modem>
  580.  
  581.     define    df100    ,<DF100>    ; a DF112
  582.     dial$time    30.
  583.     wake$string    <^B>
  584.     wake$rate    0
  585.     wake$ack    <Ready>
  586.     wake$prompt    <Ready>
  587.     dial$string    <%s#>        ; /45/
  588.     dial$rate    10
  589.     dial$xabort    <^M>
  590.     dial$echo    1
  591.     mod$comment    <DEC Standalone DF112>
  592.     mod$res        <Attached>    ,CONNECT
  593.     mod$res        <Busy>        ,FAILED
  594.     mod$res        <Disconnected>    ,FAILED
  595.     mod$res        <Error>        ,FAILED
  596.     mod$res        <No answer>    ,FAILED
  597.     mod$res        <No dial tone>    ,FAILED
  598.     mod$res        <Speed:>    ,FAILED
  599.  
  600.     define    df200    ,<DF200>    ; a DF2xx ?
  601.     dial$time    30.
  602.     wake$string    <^B>
  603.     wake$rate    0
  604.     wake$ack    <Ready>
  605.     wake$prompt    <Ready>
  606.     dial$string    <%b%m%s!>        ; /60/
  607.     dial$rate    0
  608.     dial$xabort    <^B>            ; /60/
  609.     dial$echo    1
  610.     dial$pulse    <P>            ; /60/
  611.     dial$nopulse    <T>            ; /60/
  612.     dial$blind    <^A>            ; /60/
  613.     mod$comment    <DEC Standalone DF224>
  614.     mod$res        <Attached>    ,CONNECT
  615.     mod$res        <Busy>        ,FAILED
  616.     mod$res        <Disconnected>    ,FAILED
  617.     mod$res        <Error>        ,FAILED
  618.     mod$res        <No answer>    ,FAILED
  619.     mod$res        <No dial tone>    ,FAILED
  620.     mod$res        <Speed:>    ,FAILED
  621.  
  622.  
  623.     define    hayes    ,<HAYES>    ; actually, its a VOLKSMODEM 12
  624.     dial$time    35.        ; that we are testing with. It's
  625.     wake$string    <ATZ V1^M>    ; supposed to be compatible.
  626.     wake$rate    0
  627.     wake$ack    <OK>
  628.     wake$prompt    <OK>
  629.     dmod$string    <>
  630.     dmod$prompt    <>
  631.     dial$string    <AT D %s^M>
  632.     dial$rate    0
  633.     dial$echo    1
  634.  
  635.  
  636.     define    microcom,<MICROCOM>    ; 
  637.     dial$time    35.
  638.     wake$string    <4445^MSE2^MS1C0^MSCE ON^M>
  639.     wake$rate    10
  640.     wake$ack    <!>
  641.     wake$prompt    <!>
  642.     dial$string    <D%s^M>
  643.     dial$rate    10
  644.     dial$echo    1
  645.     mod$res        <CONNECT>    ,CONNECT
  646.     mod$res        <NO CONNECT>    ,FAILED
  647.     mod$res        <!>        ,FAILED
  648.     mod$comment    <MicroCom SX1200>
  649.  
  650. ;    The following entry was added by edit (RTM01).
  651.  
  652.     define    r212a    ,<R212A>    ; RIXON R212A Intelligent modem.
  653.     dial$time    60.        ; Long timeout for overseas.
  654.     wake$string    <^M^M>
  655.     wake$rate    10        ; wait 8 ticks (8/60 second)
  656.     wake$ack    <RIXON R212A INTELLIGENT MODEM>
  657.     wake$prompt    <$>
  658.     dmod$string    <K>
  659.     dmod$prompt    <NUMBER:>
  660.     dial$string    <%s^M>
  661.     dial$rate    10
  662. ;    dial$ack    <^M>
  663. ;    dial$confirm    <^M>
  664.     dial$go        <DIALING:>
  665.     dial$echo    1
  666.     mod$comment    <RIXON R212A Intelligent Modem>
  667.     mod$res        <ON LINE>    ,CONNECT
  668.     mod$res        <ON-LINE>    ,CONNECT
  669.     mod$res        <NO ANSWER>    ,FAILED
  670.     mod$res        <DEAD LINE>    ,FAILED
  671.     mod$res        <BUSY>        ,FAILED
  672.     mod$res        <END D>        ,INFO
  673.     mod$res        <RINGING>    ,INFO
  674.  
  675.     define    protms    ,<PROTMS>    ; this one has to use QIOS for dial
  676.     ext$dial    tmsdial        ; we will have to catch this one in
  677.                     ; a not so clean manner. Waiting for
  678.                     ; Steve Kovey's code for support.
  679.  
  680.  
  681.  
  682.     .sbttl    define user defined modem structure
  683.  
  684. ;     This one <USER_DEFINED> MUST be the last one in the list. The link
  685. ;    must  be inserted  at run time via a call to FINDMODEM with a known
  686. ;    type, like CALLS FINDMO,<#vadid>.
  687. ;     NONE of the field macros used above  will work for this since  the
  688. ;    psect it's in is global.
  689. ;     Setting up the fields is fairly simple,  for example,  setting the
  690. ;    wakeup string would be:
  691. ;
  692. ;    mov    #usermd    ,r4
  693. ;    strcpy    #udiawake,argbuf
  694. ;    mov    #udiawake,wake.string(r4)    ; stuff wakeup string addr
  695. ;
  696. ;    And setting a reponse string, assuming CONNECT is success
  697. ;
  698. ;    mov    #usermd    ,r4        ; address of data structure
  699. ;    mov    #contxt    ,res.header(r4)    ; and stuff the list in
  700. ;
  701. ;    contxt:    .word    faitxt        ; link to next
  702. ;        .word    1        ; > 0 for indicating connect
  703. ;        .asciz    /CONNECT/    ; the string itself
  704. ;        .even            ; please
  705. ;    faitxt:    .word    0        ; no link to next
  706. ;        .word    -1        ; flag call failed
  707. ;        .asciz    /NOCONNECT/    ; the text if it fails
  708. ;        .even            ; please
  709. ;
  710. ;    Where udiawake was a area in the root,  defined in  K11DAT.MAC
  711. ;    Keep in mind that the code which looks for a response will NOT
  712. ;    exit until (1) nothing happens for 30 seconds or  (2) it finds
  713. ;    a match in the list with a non-zero status.
  714.  
  715.  
  716.     define    usermd    ,<USER_DEFINED>,GLOBAL ; This MUST be the last one
  717.  
  718.  
  719. ;    No more definitions allowed past here
  720.  
  721.  
  722.  
  723.  
  724.     .sbttl    local macros to make life simpler
  725.  
  726.     .macro    lowcase    s
  727.     mov    s    ,r0
  728.     call    lowcas
  729.     .endm    lowcase
  730.  
  731.     .macro    sleep    time
  732.     calls    suspend    ,<time,#0>
  733.     .endm    sleep
  734.  
  735.     .macro    tsleep    ticks
  736.     calls    suspend    ,<#0,ticks>
  737.     .endm    tsleep
  738.  
  739.     .macro    ttputstr    s
  740.     mov    r1    ,-(sp)
  741.     mov    s    ,r1
  742.     call    doput
  743.     mov    (sp)+    ,r1
  744.     .endm    ttputstr
  745.  
  746.     .macro    ttputc    c
  747.     clr    -(sp)
  748.     bisb    c    ,(sp)
  749.     mov    sp    ,r0
  750.     calls    binwri    ,<r0,#1,#lun.ti>
  751.     tst    (sp)+
  752.     .endm    ttputc
  753.  
  754.     .macro    ttgetc    wait
  755.  
  756. ;    lun.ti is the remote lun
  757.  
  758.     .if b    ,wait
  759.     .ift
  760.     calls    xbinread,<#lun.ti,#0>
  761.     .iff
  762.     calls    xbinread,<#lun.ti,wait>
  763.     .endc
  764.     
  765.     .endm    ttgetc
  766.  
  767.  
  768.     .macro    waitfor    s    ,time,fail
  769.     .if    b    ,time
  770.     .ift
  771.     clr    -(sp)
  772.     .iff
  773.     mov    time    ,-(sp)
  774.     .endc
  775.     mov    s    ,-(sp)
  776.     call    waitfor
  777.     .if nb, fail
  778.     tst    r0
  779.     beq    fail
  780.     .endc
  781.     .endm    waitfor
  782.  
  783.     .macro    waitc    c    ,time
  784.     clr    -(sp)
  785.     mov    sp    ,r0
  786.     movb    c    ,(r0)
  787.     .if    b    ,time
  788.     .ift
  789.     clr    -(sp)
  790.     .iff
  791.     mov    time    ,-(sp)
  792.     .endc
  793.     mov    r0    ,-(sp)
  794.     call    waitfor
  795.     tst    (sp)+
  796.     .endm    waitc
  797.  
  798.     .macro    didweget    s,pat,status,ret,?b
  799.     .save
  800.     .psect    string
  801.     $$     = .
  802.     .asciz    /pat/
  803.     .restore
  804.     mov    #$$    ,-(sp)
  805.     mov    s    ,-(sp)
  806.     call    didweget
  807.     tst    r0
  808.     beq    b
  809.     mov    status    ,ret
  810. b:
  811.     .endm    didweget
  812.  
  813.     remmod    =    ter$cc
  814.  
  815.  
  816.     .sbttl    REDIAL command
  817.  
  818.     .psect    $code
  819.     .enabl    lsb
  820.  
  821. c$redi::mov    argbuf    ,r3        ; /40/ argbuf address
  822.     mov    phnum    ,r2        ; /40/ address of phone number
  823.     mov    #1    ,r4        ; /40/ default repeat count
  824.     tstb    @r3            ; /40/ Any repeat count passed ?
  825.     beq    5$            ; /40/ No
  826.     calls    l$val    ,<r3>        ; /40/ retry count
  827.     mov    r1    ,r4        ; /40/ save repeat count
  828.     tst    r0            ; /40/ success ?
  829.     beq    5$            ; /40/ yes
  830.     message    <Invalid number!>,cr
  831.     br    90$            ; /40/ exit
  832. 5$:    tstb    @r2            ; /40/ Any real phone number today?
  833.     bne    10$            ; /40/ yes
  834.     message    <No previous number!>,cr
  835.     br    90$            ; /40/ exit if no DIAL command
  836. 10$:    message    <Using: >        ; /40/ echo the number we will use
  837.     print    r2            ; /40/
  838.     message                ; /40/ crlf
  839.     strcpy    r3    ,r2        ; /40/ copy old phone num to 'argbuf'
  840.  
  841. 20$:    tst    cccnt            ; /40/ control C abort ?
  842.     bne    90$            ; /40/ Yes, exit this loop NOW
  843.     mov    r4    ,-(sp)        ; /40/ save looping counter
  844.     call    c$dial            ; /40/ no, try dialing
  845.     mov    (sp)+    ,r4        ; /40/ restore looping counter
  846.     tst    r0            ; /40/ success ?
  847.     beq    100$            ; /40/ yes
  848.     sob    r4    ,20$        ; /40/ No, try again please
  849.  
  850. 90$:    mov    #-1    ,r0        ; /40/ failure
  851.     inc    status            ; /45/ Set global flag also
  852. 100$:    return
  853.  
  854.     .dsabl    lsb
  855.  
  856.  
  857. set$mo::strcpy    #modem    ,argbuf
  858.     call    findmodem
  859.     tst    r0
  860.     bne    100$
  861.     mov    #-1    ,r0
  862.     inc    status            ; /45/ Global flag also
  863.     return
  864. 100$:    clr    r0
  865.     return
  866.  
  867.  
  868.  
  869.     
  870.  
  871.     .sbttl    the DIAL command
  872.  
  873.     .psect    $code
  874.     .enabl    lsb
  875.  
  876. c$dial::strcpy    phnum    ,argbuf        ; /40/ save the phone number
  877.     tstb    ttdial            ; check for a real terminal name
  878.     bne    10$            ; ok
  879.     message    <Please use the SET LINE command first>,cr
  880.     br    90$            ; exit
  881. 10$:    tstb    modem            ; check for a SET MODEM command
  882.     bne    20$            ; ok
  883.     tst    proflg            ; /39/ is this a pro/350 ?
  884.     beq    15$            ; /39/ no, fatal error
  885.     cmpb    ttdial    ,#'X&137    ; /39/ check for XTn:
  886.     bne    15$            ; /39/ no
  887.     cmpb    ttdial+1,#'T&137    ; /39/ if so, must be TMS on P/OS
  888.     bne    15$            ; /39/ no, so no modem type fatal
  889.     strcpy    #modem    ,protms+mod.str    ; /39/ stuff 'PROTMS' in please
  890.     br    20$            ; /39/ lookup the modem now
  891. 15$:    message    <Please use the SET MODEM command first>,cr
  892.     br    90$
  893. 20$:    call    findnumber        ; /45/ Perhaps a SET PHO NUM ?
  894.     bcs    90$            ; /51/
  895.     call    findmodem        ; do we know about this modem ?
  896.     mov    r0    ,modtype    ; save the address of descriptor
  897.     beq    90$            ; no luck, exit with failure
  898.     mov    ext.dial(r0),r1        ; /39/ need external routine to dial?
  899.     beq    30$            ; /39/ no
  900.     jsr    pc    ,@r1        ; /39/ yes, call it then
  901.     br    120$            ; /39/ and exit
  902. 30$:    mov    dial.string(r0),r0    ; /39/ get dial formatting string addr
  903.     tstb    @r0            ; /39/ anything there ?
  904.     bne    40$            ; /39/ yes
  905.     message    <A dial formatting string has not been defined>,cr
  906.     br    90$            ; /39/ exit
  907. 40$:    calls    ttyini    ,<#ttname,#lun.ti,#remmod>
  908.     tst    r0            ; did we get a successful open on line?
  909.     bne    80$            ; no, emit some sort of error message
  910.     call    tidias            ; /45/ Set characteristics (TC.DLU)
  911.     call    getatn            ; try to get modems attention
  912.     tst    r0            ; did getting modems attn succeed?
  913.     beq    90$            ; no
  914.     call    dodial            ; actually try to dial the number now
  915.     mov    r0    ,-(sp)        ; /45/ Save status return
  916.     call    tidiar            ; /45/ Reset characteristics
  917.     mov    (sp)+    ,r0        ; /45/ Restore status return
  918.     tst    r0            ; returns 1 for success, zero else
  919.     beq    90$            ; failure
  920.     br    100$            ; success, return(0) re normal k11
  921.  
  922.  
  923. 80$:    direrr    r0            ; emit an error message and exit
  924. 90$:    mov    #-1    ,r0
  925.     br    110$
  926. 100$:    clr    r0
  927. 110$:    call    200$
  928. 120$:    tst    r0            ; /45/ Errors ?
  929.     beq    130$            ; /45/ No
  930.     inc    status            ; /45/ Yes, set into global flag
  931. 130$:    return
  932.  
  933.  
  934. 200$:    mov    r0    ,-(sp)
  935.     calls    ttyfin    ,<#ttname,#lun.ti> ; close the terminal up now
  936.     mov    (sp)+    ,r0
  937.     return
  938.  
  939.     .dsabl    lsb
  940.  
  941.  
  942.  
  943.     .sbttl    match type of modem
  944.     .enabl    lsb
  945.  
  946. ;    FINDMODEM
  947. ;
  948. ;    Passed:    nothing, assumes MODEM name is in global modem::
  949. ;
  950. ;    Return:    r0    address of structure for the modem
  951. ;        r0 = 0    if the modem type could not be found
  952. ;
  953. ;    Remark:     It might be better to call PRINTM to display messages
  954. ;        to better control the case if we got spawned under RSX
  955. ;        or RSTS so we  could avoid I/O and instead return some
  956. ;        status info.
  957.  
  958.  
  959. findmo::tst    $modtail        ; /39/ Is the usre mode defined?
  960.     bne    5$            ; /39/ Yes
  961.     mov    #usermd    ,$modtail    ; /39/ no, insert it please
  962. 5$:    mov    #modinf    ,r3        ; get address of head of list
  963. 10$:    strcmp    #modem    ,mod.str(r3)    ; check for a match please
  964.     tst    r0            ; a match
  965.     beq    80$            ; yes
  966.     mov    mod.next(r3),r3        ; no, try the next one please
  967.     bne    10$            ; keep going
  968.     message    <This modem type is unknown. The known modem types>,cr
  969.     message    <are:>,cr
  970.     message
  971.     mov    #modinf    ,r3        ; now print the list of modems
  972. 20$:    print    mod.str(r3)        ; first one
  973.     strlen    mod.str(r3)        ; /39/ length of modem type
  974.     sub    #40    ,r0        ; /39/ tab over please
  975.     neg    r0            ; /39/ make it > 0
  976. 30$:    print    #200$            ; /39/ a space
  977.     sob    r0    ,30$        ; /39/ next please
  978.     print    mod.com(r3)        ; /39/ dump comment string
  979.     message                ; cr/lf
  980.     mov    mod.next(r3),r3        ; next one in list
  981.     bne    20$            ; ok
  982.     br    90$            ; exit with failure
  983. 80$:    mov    r3    ,r0        ; return address of structure
  984.     br    100$            ; bye
  985. 90$:    clr    r0            ; failure
  986. 100$:    return                ; bye
  987.  
  988.     .save
  989.     .psect    $Pdata    ,d
  990. 200$:    .byte    40,0
  991.     .restore
  992.  
  993.     global    <modem>
  994.  
  995.  
  996.  
  997.     .dsabl    lsb
  998.  
  999.  
  1000.     .sbttl    Look for defined phone numbers
  1001.     .enabl    lsb
  1002.  
  1003. ;    Added /45/ 20-Feb-86  13:00:50 BDN
  1004. ;
  1005. ;    Check through linked list for phone number definitions
  1006.  
  1007.  
  1008. findnu:    mov    r3    ,-(sp)        ; Save this 
  1009.     mov    r2    ,-(sp)        ; Save this one also
  1010.     cmpb    @argbuf    ,#'0        ; Only if not number in first pos
  1011.     blo    5$            ; Ok
  1012.     cmpb    @argbuf    ,#'9        ; Well ?
  1013.     bhi    5$            ; No
  1014.     clc                ; Success, exit
  1015.     jmp    100$            ; A number, exit please
  1016. 5$:    mov    #pnhead    ,r2        ; Get listhead
  1017. ;-    calls    tlog    ,<argbuf>    ; /47/ Check for logical names
  1018.                     ; Loop a little
  1019. 10$:    mov    (r2)    ,r2        ; Get next entry
  1020.     beq    90$            ; Nothing there
  1021.     mov    r2    ,r3        ; Get address of text
  1022.     add    #2    ,r3        ; +2 for data
  1023.     mov    #ntemp    ,r0        ; Store temp here
  1024. 20$:    cmpb    (r3)    ,#40        ; All done looking ?
  1025.     beq    30$            ; Yes
  1026.     movb    (r3)+    ,(r0)+        ; No, copy more of the NAME
  1027.     bne    20$            ; All done
  1028. 30$:    clrb    (r0)            ; Insure .asciz please
  1029.     strcmp    #ntemp    ,argbuf        ; Check for a match please
  1030.     tst    r0            ; Find a match ?
  1031.     bne    10$            ; No, check the next one
  1032.                     ;
  1033. 40$:    inc    r3            ; Point to number field
  1034.     tstb    (r3)            ; Anything really there?
  1035.     beq    100$            ; No, exit please
  1036.     message    <Using: >        ; Print the translation out
  1037.     strcpy    argbuf    ,r3        ; Copy it over
  1038.     print    argbuf            ; ...
  1039.     message                ; ....
  1040.     clc                ; Success
  1041.     br    100$            ; Exit
  1042.     
  1043. 90$:    print    #npr            ; /51/ Dump a prompt
  1044.     mov    #ttbuff    ,r2        ; /51/ Set address up
  1045.     calls    kbread    ,<r2>        ; /51/ Read the response
  1046.     bicb    #40    ,r2        ; /51/ Cvt to lower case
  1047.     cmpb    @r2    ,#15        ; /51/ A CR
  1048.     beq    95$            ; /51/ Ok
  1049.     tstb    @r2            ; /51/ Null ?
  1050.     beq    95$            ; /51/ Yes, success
  1051.     cmpb    @r2    ,#'Y&137    ; /51/ A 'YES'
  1052.     beq    95$            ; /51/ Y, success
  1053.     sec                ; /51/ No, failure
  1054.     br    100$            ; /51/ Exit
  1055. 95$:    clc                ; /51/ Success
  1056. 100$:    mov    (sp)+    ,r2        ; Pop and
  1057.     mov    (sp)+    ,r3        ; pop again, then...
  1058.     return                ; Exit
  1059.  
  1060.     .dsabl    lsb
  1061.     .save
  1062.     .psect    string
  1063.     .even
  1064. ntemp:    .blkb    200
  1065. npr:    .asciz    /No translation found for number. Continue <Yes> ? /
  1066.     .even
  1067.     .restore
  1068.  
  1069.     global    <pnhead>
  1070.  
  1071.  
  1072.  
  1073.     .sbttl    GETATN    wake the modem up
  1074.     .enabl    lsb
  1075.  
  1076. ;    Input:    MODTYPE    address of modem descriptor
  1077. ;    Return:    R0    zero on failure, else success
  1078. ;
  1079. ;    In case the modem is already awake (at command prompt mode)
  1080. ;    we will dump the string,  wait for the  ackknowledgment and
  1081. ;    then loop until we are sure there is no more data.  For ex-
  1082. ;    ample, the VA212 will send back a INVALID COMMAND\n* string
  1083. ;    for the ^E and one also for the <CR>. We could,  of course,
  1084. ;    first send the modem it's IDLE command, but there are times
  1085. ;    when that may be undesirable,  like when the modem is being
  1086. ;    accessed via some sort of LAN or PABX.
  1087.  
  1088.  
  1089. getatn::save    <r1,r2,r3,r4>        ; perhaps save something
  1090.     mov    modtype    ,r4        ; get address of structure
  1091.     call    eatjunk            ; trash stuff that may be waiting
  1092.     mov    #3    ,r3        ; loop a little to get modem going
  1093.     mov    wake.string(r4),r2    ; Get address of wakeup string
  1094.  
  1095. 10$:    ttputc    (r2)+            ; We may need to insert delays
  1096.     tstb    @r2            ; for the faster modems.
  1097.     beq    15$            ; All done?
  1098.     tsleep    wake.rate(r4)        ; Not done, pause if need be
  1099.     br    10$            ; And do some more
  1100.  
  1101. 15$:    waitfor    wake.prompt(r4),#3,20$    ; now wait for an ack
  1102.     br    25$            ; success
  1103. 20$:    call    eatjunk            ; trash stuff that may be waiting
  1104.     mov    wake.string(r4),r2    ; reset wakeup string
  1105.     sob    r3    ,10$        ; next please
  1106.     br    90$            ; a complete failure, exit
  1107.  
  1108. 25$:    message    <Modem in command mode>,cr
  1109. 30$:    call    eatjunk
  1110.     mov    #1    ,r0        ; return(success)
  1111.     br    100$            ; and exit
  1112. 90$:    message    <Failed to get modems attention>,cr
  1113.     clr    r0
  1114. 100$:    unsave    <r4,r3,r2,r1>
  1115.     return
  1116.  
  1117.     .dsabl    lsb
  1118.  
  1119.  
  1120.     .sbttl    actually dial the number
  1121.     .enabl    lsb
  1122.  
  1123. ;     Note that the waitfor routine, called by macro of same name will
  1124. ;    exit immediatly if the string to compare against is NULL, thus it
  1125. ;    won't hurt anything to call it for modems that may not respond.
  1126. ;     One other problem is in inserting delays into dumping strings to
  1127. ;    the  modem in that the smallest  interval RSTS/E can delay is one
  1128. ;    second. As always in Kermit-11,  we must try to allow for code to
  1129. ;    function under all execs, not just RT or just RSTS or .....
  1130.  
  1131.  
  1132. dodial:    save    <r2,r3,r4,r5>        ; save registers that we might zap
  1133.     mov    #buffer    ,r3        ; and a pointer to it also
  1134.     mov    modtype    ,r4        ; get address of modem descriptor
  1135.     mov    #1    ,r2        ; since RSTSE can't sleep < 1 second
  1136.     mov    #cccnt    ,r5        ; control C int flag
  1137.     call    fmtstr            ; format the dialing string
  1138.     tst    dialmode        ; /45/ Should we force PULSE or TONE?
  1139.     beq    5$            ; /45/ Nothing
  1140.     bmi    4$            ; /45/ Tone
  1141.     ttputs    dial.pulse(r4)        ; /45/ See if user selected PULSE
  1142.     br    5$            ; /45/ Now get the thing to dial
  1143. 4$:    ttputs    dial.nopulse(r4)    ; /45/ Force TONE dialing
  1144. 5$:    ttputs    dmod.string(r4)        ; dump the prompt for dialing out
  1145.     waitfor    dmod.prompt(r4),#4,80$    ; wait for a response
  1146.     call    eatjunk            ; let things settle a bit
  1147. 10$:    tstb    (r3)            ; end of it all ?
  1148.     beq    40$            ; yes
  1149.     tst    @r5            ; user interupt happen ?
  1150.     bne    90$            ; yes, exit now
  1151.     ttputc    (r3)+            ; no, dump one character out
  1152.     tst    dial.echo(r4)        ; does it echo characters after each
  1153.     beq    20$            ; character ?
  1154.     ttgetc    #1            ; yes, just wait a second for the echo
  1155. 20$:    dec    r2            ; time to take a short nap ?
  1156.     bne    10$            ; no
  1157.     tst    dial.rate(r4)        ; do we REALLY need to suspend ?
  1158.     beq    30$            ; no
  1159.     tsleep    dial.rate(r4)        ; yes, do it (RSTS of course, can't
  1160. 30$:    mov    #1    ,r2        ; sleep < 1 but RSX & RT can).
  1161.     br    10$            ; may want to insert delays here
  1162. 40$:    mov    #buffer    ,r3        ; restore buffer pointer
  1163.     waitfor    dial.ack(r4),#4        ; wait for number being echoed perhaps
  1164.     sleep    #1            ; another kludge (mostly RSTS again)
  1165.     tst    @r5            ; control C or other abort?
  1166.     bne    90$            ; yes
  1167.     ttputs    dial.conf(r4)        ; stuff a confirm (ok if null)
  1168.     waitfor    dial.go(r4),#5,100$    ; maybe wait for any confirm that its
  1169.     message    <Modem dialing>,cr    ; dialing the number?
  1170.     call    getsts            ; get final result of the call please
  1171.     tst    r0            ; success ?
  1172.     bne    110$            ; yes
  1173.     br    100$            ; no, dump failure message
  1174.  
  1175. 80$:    strcpy    #buffer,#nodprompt    ; copy message for no dial prompt
  1176.     br    100$            ; and dump message
  1177.  
  1178. 90$:    strcpy    #buffer,#abort        ; user interupt message
  1179.  
  1180. 100$:    tst    cccnt            ; /45/ Did this die from a control C
  1181.     beq    105$            ; /45/ No
  1182.     ttputs    dial.xabort(r4)        ; /45/ Yes, get the modem to STOP
  1183. 105$:    ttputs    dial.idle(r4)        ; /45/ Reset into IDLE state
  1184.     message    <Call failed >        ; oops
  1185.     print    #buffer            ; why it did
  1186.     message                ; <CR><LF>
  1187.     clr    r0            ; failure
  1188.     br    120$            ; exit
  1189.  
  1190. 110$:    message    <Connection made, use the CONNECT command to access remote>
  1191.     print    #bell            ; /50/ Beep
  1192.     call    getsys            ; /48/ Don't wait unless rsx flavor
  1193.     cmpb    r0    ,#SY$MPL    ; /48/ M+ ?
  1194.     beq    115$            ; /48/ Yes, wait a moment
  1195.     cmpb    r0    ,#SY$11M    ; /48/ RSX11M 4.x ?
  1196.     bne    116$            ; /48/ No, don't suspend
  1197. 115$:    sleep    #2            ; /45/ Wait a moment
  1198. 116$:    message                ; successful call
  1199.     mov    #1    ,r0        ; exit
  1200. 120$:    unsave    <r5,r4,r3,r2>        ; and registers
  1201.     return                ; and exit
  1202.  
  1203.  
  1204.     .dsabl    lsb
  1205.  
  1206.     
  1207.  
  1208.     .sbttl    GETSTS    Get final result of dial
  1209.  
  1210. ;    Passed:    R4    --> structure describing modem
  1211. ;
  1212. ;    Return:    R0    1 for success, else zero
  1213. ;
  1214. ;     This is the messy part as we have to anticipate response from
  1215. ;    whatever modem type we are trying to use.
  1216. ;     Much of the attempts to do timeouts is made very difficult by
  1217. ;    the fact that out of P/OS, RT11, RSX11M/m+ and RSTS/E,  !ONLY!
  1218. ;    RSTS is unable to schedule time based AST's (mrkt$s and so on)
  1219. ;     Timer AST's would greatly help out here.
  1220. ;
  1221. ;    Define dispatch table to take special actions for each modem type
  1222.  
  1223.  
  1224.     dispatch    basedsp=moddsp,baseval=modlst,default=.default
  1225.  
  1226. ;- /39/    dispatch    $V2PA    ,.v2pa        ; standalone VA212PA
  1227. ;- /39/    dispatch    $V2PAR    ,.v2par        ; rack mount VA212PAR
  1228. ;- /39/    dispatch    $VADIC    ,.vadic        ; most vadics (same as 212PA)
  1229.     dispatch    $HAYES    ,.hayes        ; HAYES (really volksmodem12)
  1230. ;- /45/    dispatch    $DF100    ,.df100        ; DEC DF112
  1231. ;- /45/    dispatch    $DF200    ,.df200        ; DEC DF2xx series
  1232.     dispatch    $DF03    ,.df03        ; DEC DF03
  1233.     dispatch
  1234.  
  1235.     .save
  1236.     .psect
  1237.     .psect    string
  1238. defmsg:    .asciz    / No connection/
  1239. exring:    .asciz    / Excessive RINGING... messages returned/
  1240. abort:    .asciz    / Operation aborted under user interupt/
  1241. nodpro:    .asciz    / No response or invalid response to dial command/
  1242.     .restore
  1243.  
  1244.     CONNECT    =    1
  1245.     FAILED    =    -1
  1246.     status    =    0
  1247.     nrings    =    2
  1248.     temp    =    4
  1249.     locsiz    =    10
  1250.  
  1251.  
  1252. getsts::tst    diatmo            ; /46/ Timeout set?
  1253.     bne    5$            ; /46/ Yes
  1254. ..diat    ==    . + 2            ; /46/ Patchable
  1255.     mov    #30.    ,diatmo        ; /46/ No, set it up
  1256. 5$:    sub    #locsiz    ,sp        ; allocate local r/w data
  1257.     mov    sp    ,r5        ; and a pointer
  1258.     mov    #10    ,nrings(r5)    ; for VA212 PA, excessive ringing
  1259.     clr    temp(r5)        ; temp
  1260.     clr    (r5)            ; status = 0
  1261.     .assume    status eq 0        ; assertion
  1262.     mov    #buffer    ,r3        ; a buffer pointer
  1263.     strcpy    r3    ,#defmsg    ; copy a message over
  1264.  
  1265. 10$:    tst    (r5)            ; while ( status == 0 )
  1266.     bne    90$            ; exit with result
  1267.     mov    #buffer    ,r3        ; a buffer pointer
  1268.  
  1269. 20$:    ttgetc    diatmo            ; wait for a status return
  1270.     tst    r0            ; successful ?
  1271.     beq    30$            ; yes
  1272.     mov    #FAILED    ,(r5)        ; no
  1273.     br    70$            ; exit loop
  1274. 30$:    tstb    r1            ; /51/ Never suffer imbedded NULLS
  1275.     beq    20$            ; /51/ Ignore if such
  1276.     bicb    #^C177    ,r1        ; insure a real seven bit character
  1277.     movb    r1    ,(r3)+        ; copy the byte over
  1278.     clrb    (r3)            ; insure we stay .asciz
  1279.     tst    res.bin(r4)        ; exit loop on single character I/O?
  1280.     bne    40$            ; yes
  1281.     cmpb    r1    ,#CR        ; carriage return finally found ?
  1282.     beq    40$            ; yes
  1283.     cmpb    r1    ,#LF        ; no, but a line feed will do nicely
  1284.     bne    20$            ; not a <LF>, try some more input then
  1285.  
  1286. 40$:    scan    mod.val(r4),#modlst    ; do a crude case statement
  1287.     asl    r0            ; word indexing
  1288.     jsr    pc    ,@moddsp(r0)    ; simple
  1289. 70$:    br    10$            ; next please
  1290.  
  1291. 90$:    mov    #1    ,r0        ; assume success
  1292.     tst    (r5)            ; failure ?
  1293.     bpl    100$            ; no
  1294.     clr    r0            ; return(0) for failure
  1295. 100$:    add    #locsiz    ,sp        ; pop temps and exit
  1296.     return                ; exit
  1297.  
  1298.     global    <diatmo>        ; /46/
  1299.  
  1300.  
  1301.     .sbttl    dispatch routines for specific modem (vadic, hayes)
  1302.  
  1303.     .enabl    lsb
  1304.  
  1305. ;     The DEFAULT entry will read possible responses, and their
  1306. ;    message classes, from a linked list whose first address  is
  1307. ;    in RES.HEADER(modem_address). Each list entry has a link to
  1308. ;    the next one (or a zero), a message class (lt zero if fail,
  1309. ;    == zero for ringing  message, and gt zero for SUCCESS ). If
  1310. ;    a modem  has no entries at all,  the routine will  return a
  1311. ;    failed call. While this method can tend to add size to this
  1312. ;    module as similiar modems must have separate list,  it is a
  1313. ;    bit more general,  while allowing us at some future time to
  1314. ;    provide a SET DIAL command to dynamically create the  modem 
  1315. ;    data structure for a previously undefined modem type. Added
  1316. ;    edit 2.39, 04-DEC-1985 10:17, Brian Nelson.
  1317. ;
  1318. ;     We do not need a real definition for modem type DEFAULT as
  1319. ;    it  is not possible to ever get this far if the type is un-
  1320. ;    defined.
  1321. ;
  1322. ;    Default:
  1323.  
  1324. .default:
  1325.     save    <r3>            ; /39/ save temp register
  1326.     mov    res.head(r4),r3        ; /39/ get listhead of responses
  1327.     beq    90$            ; /39/ No responses defined ?
  1328. 10$:    mov    r3    ,-(sp)        ; /39/ get address of ascii text
  1329.     add    #4    ,(sp)        ; /39/ 4 byte offset for text
  1330.     mov    #buffer    ,-(sp)        ; /39/ Stuff address of response
  1331.     call    didweget        ; /39/ check for the response
  1332.     tst    r0            ; /39/ find the text in the list?
  1333.     bne    20$            ; /39/ yes, get the response class
  1334.     mov    (r3)    ,r3        ; /39/ no, get the next in the list
  1335.     bne    10$            ; /39/ something is left
  1336.     br    100$            ; /39/ nothing is left, continue...
  1337. 20$:    mov    2(r3)    ,(r5)        ; /39/ response class
  1338.     bne    100$            ; /39/ either success or failure
  1339.     PRINT    #buffer            ; /54/
  1340.     MESSAGE                ; /54/
  1341.     dec    nrings(r5)        ; /39/ Choose a point to cut it off
  1342.     bne    100$            ; /39/ after a lot of ringing messages.
  1343.     strcpy    #buffer,#exrings    ; /39/ copy an informative message. Stop
  1344.     ttputs    wake.string(r4)        ; /39/ the modem from trying too hard
  1345.     waitfor    wake.prompt(r4),#2    ; /39/ eat any possible response please
  1346. 90$:    mov    #FAILED    ,(r5)        ; /39/ exit
  1347. 100$:    unsave    <r3>            ; /39/ pop r3 and exit
  1348.     return                ; /39/ bye
  1349.  
  1350.     .dsabl    lsb
  1351.     
  1352.  
  1353.     .sbttl    Special cases
  1354.  
  1355.     .enabl    lsb
  1356.  
  1357. ;    Case HAYES:
  1358.  
  1359. .hayes:    didweget #buffer,<CONNECT>,#CONNECTED,(r5)
  1360.     didweget #buffer,<NO CARRIER>,#FAILED,(r5)
  1361.     didweget #buffer,<BUSY>,#FAILED,(r5)
  1362.     didweget #buffer,<ERROR>,#FAILED,(r5)
  1363.     didweget #buffer,<RING>,#1,r0    ; macro clears r0 if string not found
  1364.     tst    r0            ;
  1365.     beq    10$            ; and ring and ring and ring forever it
  1366.     message    <Remote phone is ringing>,cr
  1367.     dec    nrings(r5)        ; would seem. so chose a point to cut
  1368.     bne    10$            ; it off at some point
  1369.     strcpy    #buffer,#exrings    ; copy an informative message and stop
  1370.     ttputs    wake.string(r4)        ; the modem from trying too hard
  1371.     waitfor    wake.prompt(r4),#2    ; eat the OK please
  1372.     mov    #FAILED    ,(r5)        ; exit
  1373. 10$:    return
  1374.  
  1375.     .dsabl    lsb
  1376.  
  1377.  
  1378.  
  1379. ;    Case DF03:
  1380.  
  1381. .df03:    didweget #buffer,<A>,#CONNECTED,(r5)
  1382.     didweget #buffer,<B>,#FAILED,(r5)
  1383.     return
  1384.  
  1385.  
  1386.  
  1387.  
  1388.  
  1389.     .sbttl    format dial string (sprintf works a lot better)
  1390.  
  1391. ;    Passed:    R3    address of buffer to place result
  1392. ;        ARGBUF    the number to insert
  1393.  
  1394.  
  1395. fmtstr:    mov    r3    ,-(sp)
  1396.     mov    dial.string(r4),r2    ; point to the dial formatting string
  1397. 10$:    tstb    (r2)            ; done ?
  1398.     beq    50$            ; yes
  1399.     cmpb    (r2)    ,#'%        ; look for a format effector
  1400.     bne    30$            ; no
  1401.     mov    argbuf    ,r0        ; Assume phone number insertion
  1402.     cmpb    1(r2)    ,#'s!40        ; %s formatting ?
  1403.     beq    20$            ; no
  1404.     cmpb    1(r2)    ,#'s&137    ; %S formatting ?
  1405.     beq    20$            ; Yes
  1406.     mov    dial.wait(r4),r0    ; No, assume pause string formatting
  1407.     cmpb    1(r2)    ,#'p!40        ; %P for pause string?
  1408.     beq    20$            ; Yes
  1409.     cmpb    1(r2)    ,#'p&137    ; check both cases
  1410.     beq    20$            ; No
  1411.                     ;
  1412.     cmpb    1(r2)    ,#'M&137    ; /54/ Mode (ie PULSE, TONE)
  1413.     beq    15$            ; /54/ Found it
  1414.     cmpb    1(r2)    ,#'m!40        ; /54/ ...
  1415.     bne    16$            ; /54/ Nope
  1416. 15$:    mov    dial.pulse(r4),r0    ; /54/ Assume PULSE dialing
  1417.     tst    pulse            ; /54/ Ever SET PHONE PULSE/TONE?
  1418.     beq    25$            ; /54/ No, ignore string
  1419.     bmi    20$            ; /54/ SET PHONE PULSE
  1420.     mov    dial.nopulse(r4),r0    ; /54/ SET PHONE TONE
  1421.     br    20$            ;
  1422. 16$:    cmpb    1(r2)    ,#'B&137    ; /54/ SET PHONE BLIND?
  1423.     beq    17$            ; /54/ Is this the formatting char?
  1424.     cmpb    1(r2)    ,#'b!40        ; /54/ No, perhaps lower case?
  1425.     bne    30$            ; /54/ No, copy data then
  1426. 17$:    tst    blind            ; /54/ Ever do the SET PHONE BLIND?
  1427.     beq    25$            ; /54/ No, ignore string
  1428.     mov    dial.blind(r4),r0    ; /54/ Yes, insert the data then.
  1429.                     ;
  1430. 20$:    movb    (r0)+    ,(r3)+        ; copy a byte please
  1431.     bne    20$            ; not a null, next please
  1432.     dec    r3            ; fix current pointer up
  1433. 25$:    inc    r2            ; skip over the '%' please
  1434.     br    40$            ; next please
  1435. 30$:    movb    (r2)    ,(r3)+        ; not formatting, copy character
  1436. 40$:    inc    r2            ; skip over current character now
  1437.     br    10$            ; next
  1438.  
  1439. 50$:    clrb    (r3)            ; insure dial string is .asciz
  1440.     mov    (sp)+    ,r3        ; restore pointer and exit
  1441.     return
  1442.  
  1443.  
  1444.  
  1445.     .sbttl    misc util routines
  1446.     .enabl    lsb
  1447.  
  1448. ;    WAITFOR(s,timeout)
  1449. ;
  1450. ;    Wait for the character string in S
  1451. ;
  1452. ;    Passed:    2(sp)    string
  1453. ;        4(sp)    timeout
  1454. ;    Return:    1    success
  1455. ;        0    timeout
  1456.  
  1457. waitfor:save    <r2,r3,r4>
  1458.     mov    2+6(sp)    ,r4        ; string we are looking to get
  1459.     mov    2+10(sp),r3        ; timeout in seconds
  1460. 10$:    movb    (r4)+    ,r2        ; next character to await
  1461.     beq    30$            ; success, we can leave now
  1462. 20$:    ttgetc    r3            ; wait at most r3 seconds please
  1463.     tst    r0            ; success ?
  1464.     bne    90$            ; no (i/o routines use r0 for err code)
  1465.     bicb    #^C177    ,r1        ; remove parity always
  1466.     tstb    r1            ; /51/ Ignore imbedded NULLS
  1467.     beq    20$            ; /51/ ....
  1468.     cmpb    r1    ,r2        ; did we get the correct character?
  1469.     bne    20$            ; no, keep waiting then
  1470.     br    10$            ; found it, check for next character
  1471. 30$:    mov    #1    ,r0        ; success
  1472.     br    100$            ; exit
  1473. 90$:    clr    r0            ; failure, return(0)
  1474. 100$:    unsave    <r4,r3,r2>
  1475.     mov    (sp)    ,4(sp)        ; move return address up and exit
  1476.     cmp    (sp)+    ,(sp)+        ; fix stack
  1477.     return                ; exit
  1478.  
  1479.     .dsabl    lsb
  1480.  
  1481.  
  1482. didwege:save    <r1,r2,r3>
  1483.     mov    2+10(sp),r3        ; string to look for
  1484.     mov    2+6(sp)    ,r2        ; string to find it in
  1485.     lowcase    r3            ; /45/ Lowercase it in buffer
  1486.     strlen    r3            ; string length of pattern
  1487.     mov    r0    ,r1        ; save it
  1488.     lowcase    r2            ; /45/ Lowercase it in buffer
  1489.     strlen    r2            ; length of source string
  1490.     calls    instr    ,<r2,r0,r3,r1>    ; simple (use funct we already have)
  1491.     unsave    <r3,r2,r1>        ; pop temps and exit
  1492.     mov    (sp)    ,4(sp)        ; move return address up and exit
  1493.     cmp    (sp)+    ,(sp)+        ; fix stack
  1494.     return                ; exit
  1495.  
  1496. eatjunk:save    <r0,r1>
  1497. 10$:    ttgetc    #1
  1498.     tst    r0
  1499.     beq    10$
  1500.     unsave    <r1,r0>
  1501.     return
  1502.  
  1503.  
  1504. ;    Added /45/
  1505.  
  1506. lowcas:    mov    r0    ,-(sp)        ; Save starting address
  1507. 10$:    tstb    (r0)            ; End of the line yet?
  1508.     beq    100$            ; Yes, exit then
  1509.     cmpb    (r0)    ,#'A&137    ; A big letter?
  1510.     blo    20$            ; No
  1511.     cmpb    (r0)    ,#'Z&137    ; A big letter?
  1512.     bhi    20$            ; No
  1513.     bisb    #40    ,(r0)        ; Yes, make it lower
  1514. 20$:    inc    r0            ; Next please
  1515.     br    10$            ; and check it
  1516. 100$:    mov    (sp)+    ,r0        ; Return starting address
  1517.     return                ; Exit
  1518.  
  1519. doput:    strlen    r1
  1520.     tst    r0
  1521.     beq    10$
  1522.     calls    binwri    ,<r1,r0,#lun.ti>
  1523. 10$:    return
  1524.  
  1525.  
  1526.     .sbttl    Show Modem/Dial
  1527.  
  1528.     .enabl    lsb
  1529.  
  1530. shomod::
  1531. shodia::call    findmodem        ; Do we know about this modem ?
  1532.     mov    r0    ,r4        ; Save the address of descriptor
  1533.     bne    5$            ; No luck, exit with failure
  1534.     MESSAGE    <No modem type has been SET>,CR
  1535.     return                ;
  1536. 5$:    mov    #slist    ,r3        ; Info list start
  1537.     tst    ext.dial(r4)        ; Is this a built-in, like PRO/TMS?
  1538.     beq    10$            ; No
  1539.     MESSAGE    <This is an internal modem>,CR
  1540.     jmp    100$            ; Exit
  1541.                     ;
  1542. 10$:    movb    (r3)+    ,r1        ; Type of data (1=String,0=Number)
  1543.     movb    (r3)+    ,r2        ; Offset, zero implies end.
  1544.     beq    60$            ; All done
  1545.     add    r4    ,r2        ; Move to the correct offset
  1546.     PRINT    r3            ; Dump the header
  1547. 20$:    tstb    (r3)+            ; Now look for the end of it
  1548.     bne    20$            ; Not yet
  1549.     tstb    r1            ; Data type, zero is numeric
  1550.     bne    30$            ; Ascii
  1551.     DECOUT    (r2)            ; Dump the data
  1552.     br    50$            ; Next please
  1553. 30$:    mov    (r2)    ,r0        ; Get the string data address
  1554.     beq    40$            ; Nothing there
  1555.     tstb    @r0            ; Again
  1556.     beq    40$            ; Nothing has been set
  1557.     call    unfmts            ; Convert and print it
  1558.     PRINT    r0            ; Do it
  1559.     br    50$            ; Next
  1560. 40$:    MESSAGE    <The option has not been SET>
  1561. 50$:    MESSAGE                ;
  1562.     br    10$            ; Next
  1563.                     ;
  1564. 60$:    mov    res.head(r4),r3        ; Response header
  1565.     beq    100$            ; Nothing present
  1566.     MESSAGE                ;
  1567.     MESSAGE    <Modem message            Message Class>,CR
  1568.     MESSAGE              ;
  1569. 65$:    mov    r3    ,r2        ; Get the response address
  1570.     beq    100$            ; All done
  1571.     add    #4    ,r2        ; Offset is four
  1572.     STRCPY    #buffer    ,r2        ; Copy it
  1573.     STRLEN    #buffer            ; Length
  1574.     sub    #24.    ,r0        ; Amount to stuff in
  1575.     neg    r0            ; Make it positive
  1576.     mov    r0    ,r5        ; Save it in a safe place
  1577.     ble    75$            ; Avoid this please
  1578. 70$:    STRCAT    #buffer    ,#200$        ; Do it
  1579.     sob    r5    ,70$        ; A few times
  1580. 75$:    PRINT    #buffer            ; Dump the text
  1581.     tst    2(r3)            ; What is the message class?
  1582.     bmi    85$            ; If < 0, failure to connect
  1583.     beq    80$            ; If == 0 just informative
  1584.     MESSAGE    <Successfull connect>,CR;
  1585.     br    90$            ; Next please
  1586. 80$:    MESSAGE    <Informative message>,CR;
  1587.     br    90$            ; Next please
  1588. 85$:    MESSAGE    <Failure to  connect>,CR;
  1589. 90$:    mov    (r3)    ,r3        ; Pick up link to next
  1590.     br    65$            ; Next please
  1591.                     ;    
  1592. 100$:    return
  1593.  
  1594.     .Save
  1595.     .psect    $Pdata,d
  1596.  
  1597. 200$:    .asciz    / /
  1598.  
  1599.     .macro    DES    Type,Offset,Title
  1600.     .if B, Type
  1601.     .byte    0,0
  1602.     .iff
  1603.     .byte    Type,Offset
  1604.     .asciz    @Title@
  1605.     .endc
  1606.     .endm    DES
  1607.  
  1608. slist:    DES    1,mod.comment,<Modem type:         >
  1609.     DES    1,wake.string,<Wakeup string:      >
  1610.     DES    1,wake.ack   ,<Response to wakeup: >
  1611.     DES    1,dial.string,<Format for dialing: >
  1612.     DES    0,dial.rate,  <Delay  for dialing: >
  1613.     DES
  1614.  
  1615.     .Even
  1616.     .Restore
  1617.  
  1618.     .end
  1619.