home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / cpm86 / c86xv9.a86 < prev    next >
Text File  |  2020-01-01  |  24KB  |  685 lines

  1. ; * * * * * * * * * * * * * * *  version 2.9  * * * * * * * * * * * * * * *
  2. ; [35] Modify the Rainbow 100 version to handle the Victor 9000/Sirius
  3. ; Eric Zurcher, Utah State University, Logan, Utah (REHABIV@USU.BITNET)
  4. ; 07/07/86
  5. ; * * * * * * * * * * * * * * *  version 2.8  * * * * * * * * * * * * * * *
  6. ; [34] Insert milli-second wait-loop for Break-timing - label MSWAIT:
  7. ; [33] Fix printer on hanging system problem by letting CP/M handle the
  8. ;       interrupts from the 7201 that we don't care about.  Thanks to
  9. ;       Paul Ford, U. of Chicago Graduate School of Business
  10. ; * * * * * * * * * * * * * * *  version 2.7  * * * * * * * * * * * * * * *
  11. ; [30d] Add SET PORT command, currently unimplemented.
  12. ; [30c] Isolate all machine dependencies in KERIO.
  13. ;       RonB, 04/18/84
  14. ; * * * * * * * * * * * * * * *  version 2.6  * * * * * * * * * * * * * * *
  15. ; [28e] Switch to local stack on interrupts.
  16. ;       RonB, 03/28/84
  17. ; * * * * * * * * * * * * * * *  version 2.4  * * * * * * * * * * * * * * *
  18. ; [20b] Add PRTBRK to send break & set correct clock rate for NEC.
  19. ; [20d] Add a pseudo time-out to PRTOUT so it doesn't loop forever.
  20. ;       RonB,03/02/84
  21. ; [19a] Add XON/XOFF type flow control
  22. ; [19b] Clear screen and beginning and end of program.
  23. ; [19e] Add PRTBRK to send break to port (Rainbow only)
  24. ; [19g] Put in EQU for clock rate for timing loops.
  25. ;       Rg, 2/84        <Oc.Garland%CU20B@Columbia-20>
  26. ; * * * * * * * * * * * * * * *  version 2.3  * * * * * * * * * * * * * * *
  27. ;  [par] Added calls to set parity, strip parity on input if
  28. ;       other than none parity is called for.
  29. ;        JD, 2/84
  30. ; * * * * * * * * * * * * * * *  version 2.2  * * * * * * * * * * * * * * *
  31. ;  [2]  Add a de-initialization routine for the serial port, to restore
  32. ;       changed interrupt vectors, etc.
  33. ;       RonB,12/23/83
  34. ;  [1]  Add I/O support for the NEC Advanced Personal Computer
  35. ;       RonB,12/23/83
  36. ; * * * * * * * * * * * * * * *  version 2.0  * * * * * * * * * * * * * * *
  37.  
  38. ; This module contains all the low level communications port I/O
  39. ; routines.
  40.  
  41. ; The following is the I/O code for the Victor 9000.
  42.  
  43.                 CSEG $
  44.  
  45. ; Clock rate *10 for timing loops       ;[19g]
  46. clckrt  equ     48              ;[19g]  4.8 Mhz
  47.  
  48. ;[35a] begin
  49. ; Offsets of memory-mapped Victor "ports" within segment 0E000H
  50. mdmseg  EQU     0E000H          ;Segement for memory-mapped 7201 of Victor
  51. mnstat  EQU     042H            ;Status port A.
  52. mndata  EQU     040H            ;Data port A.
  53. mnctl1  EQU     000H            ;Interrupt controller.
  54. mnctl2  EQU     001H            ;Interrupt controller.
  55. mnclk1  EQU     023H            ;For setting baud rate
  56. mnclk2  EQU     020H            ;      "
  57. ;[35a] end
  58.  
  59. ; Interrupt vector locations.  These are all in data segment 0.
  60.  
  61. mnoff   EQU     84H             ;Main data port interrupt routine offset.  [35]
  62. mnseg   EQU     86H             ;Main data port interrupt routine segment. [35]
  63.  
  64. output  EQU     04H             ;Bit for output ready.
  65. input   EQU     01H             ;Bit for input ready.
  66.  
  67. outlmt  EQU     1000H           ;Number of times to check output status
  68.                                 ; before giving up on send.             ;[20d]
  69.  
  70.  
  71. ; Input data from port.  Preserves all ACs and returns char in
  72. ; AL.  Gets the char from the ring buffer.  Assumes a char is
  73. ; already there.
  74.  
  75. inchr:  push    bx
  76.         cli                     ;Disable interrupts while were are playing.
  77.         dec     mnchrn          ;Decrement the number of chars in the buffer.
  78.         mov     bx, mnchop      ;Get the pointer into the buffer.
  79.         inc     bx              ;Increment to the next char.
  80.         cmp     bx, offset mnchrs+mnchnd ;Past the end?
  81.         jb      inchr2
  82.         mov     bx, offset mnchrs ;If so wrap around to the start.
  83. inchr2: mov     mnchop, bx      ;Save the updated pointer.
  84.         mov     al, [bx]        ;Get the character.
  85.         sti                     ;All done, we can restore interrupts.
  86.         pop     bx
  87.         cmp     parflg,parnon   ;[par] no parity?
  88.         je      inchr3          ;[par] yup, don't bother stripping
  89.         and     al,7fh          ;[par] checking parity, strip off
  90. inchr3: cmp     floctl, floxon  ; do flow control?              [19a] start
  91.         je      inchr4          ;If yes jump
  92.         ret
  93. inchr4: cmp     xofsnt, true    ;Have we sent an XOFF
  94.         je      inchr5          ;Jump if yes
  95.         ret
  96. inchr5: cmp     mnchrn, mntrg1  ;Under the low trigger point?
  97.         jb      inchr6          ;yes - jump
  98.         ret
  99. inchr6: push    ax              ;save current character
  100.         mov     al, xon
  101.         call    prtout          ;send an XON
  102.         mov     xofsnt, false   ;turn off the flag
  103.         pop     ax              ;get back character
  104.         ret                     ;                               [19a] end
  105.  
  106.  
  107. ; Output data to port. Trashes DX and prints char in AL.
  108.  
  109. ;[35b] begin
  110. outchr: push    es
  111.         push    si
  112.         mov     dx, mdmseg
  113.         mov     es, dx
  114.         mov     si, mndata
  115.         mov     es:[si], al
  116.         pop     si
  117.         pop     es
  118.         ret
  119.  ;[35b] end
  120.  
  121. ; Test if data is available from port.
  122.  
  123. instat: cmp     mnchrn, 0       ;Any chars in the buffer?
  124.         jnz     inst2
  125.          ret
  126. inst2:  jmp     rskp
  127.  
  128.  
  129. ; Test if port is ready to send next char.  Returns RETSKP if ready.
  130. ; Trashes dx.
  131.  
  132. outwt:  cmp     floctl, floxon  ;are we doing flow-control?     [19a] start
  133.         jne     outwta          ;no - go on
  134.         cmp     xofrcv, true    ;are we being held?
  135.         jne     outwta          ;no - ok go on
  136.         ret                     ;held - say we're busy. [19a] end
  137. outwta: push    ax
  138. ;[35c] begin
  139.         push    es
  140.         push    si
  141.         mov     dx, mdmseg
  142.         mov     es, dx
  143.         mov     si, mnstat
  144.         mov     al, es:[si]
  145.         test    al, output
  146.         pop     si
  147.         pop     es
  148. ;[35c] end
  149.         pop     ax
  150.         jnz     outwt2
  151.          ret
  152. outwt2: jmp     rskp
  153.  
  154.  
  155. ; Output the character, checking first to make sure the port is clear.
  156.  
  157. prtout: call    dopar           ;[par]
  158.         push    dx
  159.         push    cx                                              ;[20d] begin
  160.         mov     cx,outlmt
  161. prtou2: call    outwt           ;Wait until the port is ready
  162.          loop   prtou2          ; or too much time has passed.
  163.          nop
  164.         call    outchr          ;Output it.
  165.         pop     cx                                              ;[20d] end
  166.         pop     dx
  167.         ret
  168.  
  169.  
  170. mnax    dw      0               ;Storage in CSEG                ;[28e] begin
  171. mnsp    dw      0               ;  for use by interrupt handler
  172. mnsseg  dw      0
  173. mndseg  dw      0
  174.  
  175. ; This routine handles the interrupts on input.
  176.  
  177. mnint:  cli
  178.         mov     cs:mnax, ax     ;Save interrupt stack location.
  179.         mov     ax, sp
  180.         mov     cs:mnsp, ax
  181.         mov     ax, ss
  182.         mov     cs:mnsseg, ax
  183.         mov     ax, cs:mndseg   ;Switch to our internal stack.
  184.         mov     ss, ax
  185.         mov     sp, offset mnstk
  186.         push    ds              ;Save all registers.
  187.         push    es
  188.         push    bp
  189.         push    di
  190.         push    si
  191.         push    dx
  192.         push    cx
  193.         push    bx
  194.         mov     ds, ax
  195.         mov     dx, mdmseg      ;[35]
  196.         mov     es, dx          ;[35]
  197.         call    mnproc          ;Process the character.
  198. ;[35d] begin
  199.         mov     si, mnctl1      ;Point to the interrupt controller
  200.         mov     al, 061H
  201.         mov     es:[si], al     ;Re-enable interrupts
  202.         mov     si, mnstat      ;Get the status port.
  203.         mov     al, 38H
  204.         mov     es:[si], al     ;Tell the port we finished with the interrupt.
  205. ;[35d] end
  206.         pop     bx              ;Restore all registers.
  207.         pop     cx
  208.         pop     dx
  209.         pop     si
  210.         pop     di
  211.         pop     bp
  212.         pop     es
  213.         pop     ds
  214.         mov     ax, cs:mnsp     ;Restore the original stack.
  215.         mov     sp, ax
  216.         mov     ax, cs:mnsseg
  217.         mov     ss, ax
  218.         mov     ax, cs:mnax
  219.         iret                    ;Return from the interrupt.     ;[28e] end
  220.  
  221.  
  222. ; This routine (called by MNINT) gets a char from the main port
  223. ; and puts it in the infamous circular buffer.
  224.  
  225. mnproc: mov     si, mnstat      ;[35] Check port status
  226.         mov     al, es:[si]     ;[35]
  227.         test    al, input       ;Any there?
  228.         jnz     mnpro2          ;Yup, go take care of it.
  229.  
  230. ;[33] Begin addition
  231. ; If not a received character, simulate an interrupt transferring
  232. ; control to the CPM routine. Let it handle worrisome things like
  233. ; someone turning on the printer.
  234. ;[35e] begin
  235. ;Unlike the Rainbow, Victor CP/M does not normally handle these interrupts.
  236. ;Let's just return, lest we wreak havoc...
  237. ;        pushf                  ; Save flags, like an int.
  238. ;        callf dword ptr mnoldo ; Call CPM's routine.
  239. ;[35e] end
  240.          ret                    ; Now back to MNINT.
  241.  
  242. ;[33] End addition
  243.  
  244. ;[35f] begin
  245. mnpro2: mov     al, 1           ;Point to RR1.
  246.         mov     es:[si], al
  247.         mov     al, es:[si]     ;Read RR1.
  248.         mov     ah, al          ;Save it.
  249.         mov     al, 30H         ;Reset any errors.
  250.         mov     es:[si], al
  251.         mov     si, mndata
  252.         mov     al, es:[si]     ;Read the char.
  253. ;[35f] end
  254.         cmp     floctl, floxon  ;are we doing flow-control ?    [19a] start
  255.         jne     mnpr2b          ;no - go on
  256.         cmp     al, xoff        ;is it an XOFF?
  257.         jne     mnpr2a          ;no - go on
  258.         mov     xofrcv, true    ;set the flag
  259.         ret
  260. mnpr2a: cmp     al, xon         ;an XON?
  261.         jne     mnpr2b          ;no
  262.         mov     xofrcv, false   ;clear the flag
  263.         ret                     ;                               [19a] end
  264. mnpr2b: cmp     mnchrn, mnchnd  ;Is the buffer full?
  265.         je      mnperr          ;If so, take care of the error.
  266.         inc     mnchrn          ;Increment the character count.
  267.         mov     bx, mnchip      ;Get the buffer input pointer.
  268.         inc     bx              ;Increment it.
  269.         cmp     bx, offset mnchrs+mnchnd ;Past the end?
  270.         jb      mnpro3
  271.         mov     bx, offset mnchrs ;Yes, point to the start again.
  272. mnpro3: mov     mnchip, bx      ;Save the pointer.
  273.         mov     [bx], al        ;Put the character in the buffer.
  274.         cmp     floctl, floxon  ;do flow control?               [19a] start
  275.         je      mnpro4          ;If yes jump
  276.         ret
  277. mnpro4: cmp     xofsnt, true    ;Have we sent an XOFF
  278.         jnz     mnpro5
  279.         ret                     ;return if we have
  280. mnpro5: cmp     mnchrn, mntrg2  ;Past the High trigger point?
  281.         ja      mnpro6          ;yes - jump
  282.         ret
  283. mnpro6: mov     al, xoff
  284.         call    prtout          ;send an XOFF
  285.         mov     xofsnt, true    ;set the flag
  286.         ret                     ;                               [19a] End
  287.  
  288. mnperr: ret                     ;Just return on an error for now.
  289.  
  290.  
  291. ; prtbrk - send a break         ;                               [19e] start
  292.  
  293. prtbrk:                         ;
  294. ;[35g] begin
  295.         push    es              ;save registers
  296.         push    si
  297.         mov     dx, mdmseg      ;Point to "port" segment
  298.         mov     es, dx
  299.         mov     si, mnstat      ;status reg. address for port
  300.         mov     al, 15H         ;select reg. 5
  301.         mov     es:[si], al
  302.         mov     al, 0FAH        ;8 bits, TX, Break, RTS, & DTR
  303.         mov     es:[si], al     ;Turn Break on
  304.         mov     ax, 275         ;.. for 275 millisec's          [34]
  305.         call    mswait          ;                               [34]
  306.         mov     al, 15H         ;select reg. 5
  307.         mov     es:[si], al
  308.         mov     al, 0EAH        ;same as above without Break
  309.         mov     es:[si], al     ;turn it off
  310.         pop     si
  311.         pop     es
  312.         ret                     ;                                [19e] end
  313. ;[35g] end
  314. mswait:                         ;                               [34] start
  315.         mov     cx,5*clckrt     ; inner loop count for 1 millisec.
  316. mswai1:
  317.         sub     cx,1            ;** inner loop takes 20 clock cycles
  318.         jnz     mswai1          ;**
  319.         dec     ax              ; outer loop counter
  320.         jnz     mswait          ; wait another millisecond
  321.         ret                     ;                               [34] end
  322. ;
  323. ; Init the 7201 for 8 bits, no parity, and 1 stop bit.
  324.  
  325. serini:  ;call ansmod ;Switch from VT52 to ANSI mode ;[30c][35] removed
  326.  
  327.         cmp     mninit, 0FFH
  328.         je      serin2
  329.         mov     mninit, 0FFH
  330.         mov     ax, ds
  331.         mov     cs:mndseg, ax   ;Save the data segment somewhere in CSEG.
  332.         push    ds              ;Save the data segment.
  333.         mov     ax, 0
  334.         mov     ds, ax          ;We want DSEG = 0.
  335.         cli                     ;Turn off interrupts.
  336.         mov     bx, .mnoff      ;[33] Get original interrupt offset.
  337.         mov     es, .mnseg      ;[33] Get original interrupt segment.
  338.         mov     ax, offset mnint;Point to the interrupt routine offset.
  339.         mov     .mnoff, ax      ;Put in the main port interrupt offset addr.
  340.         mov     ax, cs          ;Get our code segment.
  341.         mov     .mnseg, ax      ;Put in the main port interrupt segment addr.
  342.         pop     ds              ;Restore data segment.
  343.  
  344.         mov     mnoldo, bx      ;[33] Stash original serial interrupt offset.
  345.         mov     mnolds, es      ;[33] Stash original segment.
  346.  
  347. ;[35h] begin
  348.         push    es              ;Save registers
  349.         push    si
  350.         mov     dx, mdmseg      ;Get "port" segment
  351.         mov     es, dx
  352.         mov     si, mnstat      ;Point to status port.
  353.         mov     al, 18H         ;Reset the port.
  354.         mov     es:[si], al
  355.         mov     al, 14H         ;Select register 4.
  356.         mov     es:[si], al
  357.         mov     al, 48H         ;16X clock, 1.5 stop bits, no parity.
  358.         mov     es:[si], al
  359.         mov     al, 13H         ;Select register 3.
  360.         mov     es:[si], al
  361.         mov     al, 0C1H        ;8 bits/char, RX enable.
  362.         mov     es:[si], al
  363.         mov     al, 15H         ;Select register 5.
  364.         mov     es:[si], al
  365.         mov     al, 0EAH        ;8 bits/char, TX enable, RTS and DTR.
  366.         mov     es:[si], al
  367.         mov     al, 11H         ;Select register 1.
  368.         mov     es:[si], al
  369.         mov     al, 18H         ;Enable interrupt processing on this port.
  370.         mov     es:[si], al
  371.         mov     si, mnctl2      ;point to 8259 interrput controller
  372.         mov     al,es:[si]
  373.         and     al, 0FDH        ;Enable interrupt processing
  374.         mov     es:[si], al
  375.         mov     si, mnctl1
  376.         mov     al, 061H
  377.         mov     es:[si], al     ;Clears outstanding requests
  378.         sti                     ;Restore interrupts.
  379.         pop     si
  380.         pop     es
  381.         call    stbaud
  382. serin2: ret
  383.  
  384. serfin:
  385.         call    clrscr          ;[19b] clear screen             ;[30c]
  386.         cmp     mninit, 0FFH
  387.         jne     serfn2
  388.         mov     mninit, 0
  389.         cli
  390.         push    es
  391.         push    si
  392.         mov     dx, mdmseg      ;Victor
  393.         mov     es, dx          ;Victor
  394.         mov     si, mnctl2      ;point to 8259 interrput controller
  395.         mov     al,es:[si]      ;Enable interrupt processing
  396.         or      al, 02H
  397.         mov     es:[si], al
  398.         mov     si, mnstat
  399.         mov     al, 01
  400.         mov     es:[si], al
  401.         mov     al, 00
  402.         mov     es:[si], al
  403.         mov     ax, mnoldo      ;[33] Get original interrupt offset.
  404.         mov     es, mnolds      ;[33] Get original interrupt segment.
  405.         push    ds              ;Save the data segment.
  406.         mov     dx, 0
  407.         mov     ds, dx          ;We want DSEG = 0.
  408.         mov     .mnoff, ax      ;Put in the main port interrupt offset addr.
  409.         mov     .mnseg, es      ;Put in the main port interrupt segment addr.
  410.         pop     ds              ;Restore data segment.
  411.         pop     si
  412.         pop     es
  413.         sti
  414.  
  415. serfn2: ret
  416. ;[35h] end
  417.  
  418. ; This routine clears the serial port input buffer.  It is called to
  419. ; clear out excess NAKs that can result from server mode operation.
  420.  
  421. cfibf:  mov     mnchrn, 0       ;Say no characters in the buffer.
  422.         mov     mnchip, offset mnchrs-1+mnchnd ;Reset input pointer.
  423.         mov     mnchop, offset mnchrs-1+mnchnd ;Reset output pointer.
  424.         ret
  425.  
  426.         DSEG $
  427.  
  428. mnchnd  equ     256             ;[19a] Size of circular buffer.
  429. mntrg1  equ     64              ;[19a] Low trigger point for Auto XON/XOFF
  430. mntrg2  equ     192             ;[19a] High trigger point for Auto XON/XOFF
  431.  
  432. floctl  db      1               ;[19a] If floctl=floxon do Auto XON/XOFF logic
  433. xofsnt  db      0               ;[19a] set if XOFF was sent
  434. xofrcv  db      0               ;[19a] set if XOFF was recieved
  435.  
  436. mnchrn  DW      0               ;[19a] Number of chars in the buffer.
  437. mnchrs  RB      mnchnd          ;Circular character buffer for input.
  438. mnchip  DW      mnchrs-1+mnchnd ;Input pointer into character buffer.
  439. mnchop  DW      mnchrs-1+mnchnd ;Output pointer into character buffer.
  440.  
  441. mnoldo  RW      1               ;[33] CPM's 7201 interrupt vector offset
  442. mnolds  RW      1               ;[33] and segment.
  443. mninit  DB      0               ;set to 0FFH if initialization has been done
  444.  
  445.         rw      32              ;Interrupt stack                ;[28e]
  446. mnstk   dw      0               ;bottom of stack                ;[28e]
  447.  
  448.  
  449.         CSEG $
  450.  
  451. ; The following routines do the SET and SHOW for the machine dependent
  452. ; features of Kermit.  At present there are only two:  baud rate setting
  453. ; and port selection.
  454.  
  455. ;[35i] begin
  456. ;       This is the SET BAUD rate subcommand
  457.  
  458. ; set the baud rate
  459.  
  460. stbaud: mov     al,mnbaud       ;get the baud rate information
  461.         cmp     al,15           ;check for valid range (0-15)
  462.         ja      stb02
  463.         mov     bx,offset baudtb;get address of baud rate table
  464.         add     al,al           ;compute word offset
  465.         mov     ah,0
  466.         add     bx,ax
  467.         push    es
  468.         push    si
  469.         mov     ax, mdmseg
  470.         mov     es, ax
  471.         mov     si, mnclk1
  472.         mov     al, 036H
  473.         mov     es:[si], al
  474.         mov     si, mnclk2
  475.         mov     ax, [bx]
  476.         mov     es:[si], al
  477.         mov     es:[si], ah
  478.         pop     si
  479.         pop     es
  480. stb02:  ret
  481.  
  482.         dseg $
  483.  
  484. ;       Serial port default parameters
  485.  
  486. mnbaud  db      13              ;9600 baud
  487.  
  488. ;       Interval Timer values (assumes 16x baud rate mode)
  489.  
  490. baudtb  dw      061Bh           ;50 baud        0
  491.         dw      0412h           ;75 baud        1
  492.         dw      02C6h           ;110 baud       2
  493.         dw      0245h           ;135 baud       3
  494.         dw      0209h           ;150 baud       4
  495.         dw      0104h           ;300 baud       5
  496.         dw      0082h           ;600 baud       6
  497.         dw      0041h           ;1200 baud      7
  498.         dw      002Bh           ;1800 baud      8
  499.         dw      0027h           ;2000 baud      9
  500.         dw      0021h           ;2400 baud      10
  501.         dw      0016h           ;3600 baud      11
  502.         dw      0010h           ;4800 baud      12
  503.         dw      0008h           ;9600 baud      13
  504.         dw      0004h           ;19200 baud     14
  505.         dw      0002h           ;38400 baud     15
  506.  
  507.         CSEG $
  508.  
  509. bdset:  mov     dx, offset bdtab
  510.         mov     bx, offset bdhlp
  511.         mov     ah, cmkey
  512.         call    comnd
  513.          jmp    r
  514.         mov     temp1, bx
  515.         mov     ah, cmcfm
  516.         call    comnd           ;Get a confirm.
  517.          jmp    r               ; Didn't get a confirm.
  518.         mov     bx, temp1
  519.         mov     mnbaud, bl      ;Set the baud rate table index.
  520.         call    stbaud
  521.         jmp     rskp
  522. ;[35i] end
  523.  
  524. ;This is the SET PORT subcommand (not implemented in Victor at this time)
  525.  
  526. prtset: mov     ah, cmcfm
  527.         call    comnd           ;Get a confirm.
  528.          jmp    $+3             ; Didn't get a confirm.
  529.         mov     dx, offset infms6 ;Tell user it's not implemented
  530.         call    tcrmsg
  531.         jmp     rskp
  532.  
  533.  
  534. ; The following procedures implement the SHOW command for the system
  535. ; dependent features of baud rate and port selection.
  536.  
  537. ;[35j] begin
  538. shobd:  mov     dx, offset bdst ;Baud rate string.
  539.         call    tcrmsg
  540.         mov     al, mnbaud      ;Print the keyword corresponding to the
  541.         mov     bx, offset bdtab ; current value of mnbaud.
  542.         call    tabprt
  543.         ret
  544.  
  545.         DSEG $
  546.  
  547. bdtab   db      16              ;Thirteen entries               ;[6] begin
  548.         db      3,'110$'
  549.         dw      0002H
  550.         db      4,'1200$'
  551.         dw      0007H
  552.         db      3,'135$'
  553.         dw      0003H
  554.         db      3,'150$'
  555.         dw      0004H
  556.         db      4,'1800$'
  557.         dw      0008H
  558.         db      5,'19200$'
  559.         dw      000EH
  560.         db      4,'2000$'
  561.         dw      0009H
  562.         db      4,'2400$'
  563.         dw      000AH
  564.         db      3,'300$'
  565.         dw      0005H
  566.         db      4,'3600$'
  567.         dw      000BH
  568.         db      5,'38400$'
  569.         dw      000FH
  570.         db      4,'4800$'
  571.         dw      000CH
  572.         db      2,'50$'
  573.         dw      0000H
  574.         db      3,'600$'
  575.         dw      0006H
  576.         db      2,'75$'
  577.         dw      0001H
  578.         db      4,'9600$'
  579.         dw      000DH                                           ;[6] end
  580.  
  581. bdhlp:
  582. db cr,lf,'      50      110     150     600     1800    2400    4800    19200'
  583. db cr,lf,'      75      135     300     1200    2000    3600    9600    38400$'
  584.  
  585.         CSEG $
  586. ;[35j] end
  587. shoprt: ret                     ;Port selection not implemented.
  588.  
  589.  
  590.  
  591.  
  592. ; The following routines do screen control.  These are isolated here because
  593. ; the screen control sequences are likely to vary from system to system, even
  594. ; though the Rainbow and APC (the only systems implemented to date) both use
  595. ; ANSI sequences for this purpose.
  596.  
  597.         CSEG $
  598.  
  599. ; POSCUR - positions cursor to row and col (each 1 byte) pointed to by dx.
  600.  
  601. ;[35k] begin
  602. poscur:
  603.         mov     si, dx
  604.         mov     dx, offset anspos ; move prefix string
  605.         mov     cl, prstr
  606.         int     bdos
  607.         xor     dx,dx
  608.         mov     dl, [si]
  609.         add     dl,01FH         ; this is the row
  610.         mov     cl,dconio       ; no checking please
  611.         int     bdos
  612.         mov     dl, 1[si]
  613.         add     dl,01FH         ; this is the column
  614.         mov     cl,dconio
  615.         int     bdos
  616.         ret
  617. ;[35k] end
  618.  
  619. ; CLRSCR - homes cursor and clears screen.
  620.  
  621. clrscr: mov     dx, offset anscls
  622.         call    tmsg
  623.         ret
  624.  
  625. ; CLRLIN - clears from cursor to end of line.
  626.  
  627. clrlin: mov     dl, cr          ;Go to beginning of line
  628.         call    bout
  629. clreol: mov     dx, offset ansclr ;Clear from cursor to end of line
  630.         call    tmsg
  631.         ret
  632.  
  633. ; REVON - turns on reverse video display
  634.  
  635. revon:  mov     dx, offset ansron
  636.         call    tmsg
  637.         ret
  638.  
  639. ; REVOFF - turns off reverse video display
  640.  
  641. revoff: mov     dx, offset ansrof
  642.         call    tmsg
  643.         ret
  644.  
  645. ; BLDON - turns on bold (highlighted) display
  646.  
  647. bldon:  mov     dx, offset ansbon
  648.         call    tmsg
  649.         ret
  650.  
  651. ; BLDOFF - turns off bold (highlighted) display
  652.  
  653. bldoff: mov     dx, offset ansbof
  654.         call    tmsg
  655.         ret
  656.  
  657. ; ANSMOD - enters ANSI mode from VT52 mode
  658.  
  659. ;[35l] begin    ; Just keep Victor in VT52 (actually Heath-19) mode
  660. ansmod: ;mov    dx, offset ansion
  661.         ;call   tmsg
  662.         ret
  663.  
  664.         DSEG $
  665.  
  666. anspos  db      esc,'Y$'                ;Position cursor to row and column
  667. anscls  db      esc,'H',esc,'J$'        ;Home cursor and clear screen
  668. ansclr  db      esc,'K$'                ;Clear from cursor to end of line
  669. ansron  db      esc,'p$'                ;Turn on reverse video
  670. ansrof  db      esc,'q$'                ;Turn off reverse video
  671. ansbon  db      esc,'($'                ;Turn on bold (highlight) display
  672. ansbof  db      esc,')$'                ;Turn off bold display
  673. ansion  db      '$'                     ;Enter ANSI mode
  674. ;[35l] end
  675.  
  676. ; Here tab expansion is done if necessary.  If not, just return retskp.
  677.  
  678.         CSEG $
  679. dotab:  jmp rskp
  680.  
  681.         DSEG $
  682. delstr  db      ' ',10O,10O,'$' ;Delete string.
  683.  
  684. system  db      '                  Victor 9000$' ;[35]
  685.