home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progasm / supervdu.arj / SUPERVDU.ASM
Encoding:
Assembly Source File  |  1990-09-14  |  35.6 KB  |  1,911 lines

  1. ;
  2. ;Version 2.0 - 11th December 1987
  3. ;
  4. ;SUPERVDU.SYS (IBM) Version 2.1
  5. ;
  6. ;This program may be freely copied and altered subject only to a credit for
  7. ;the author remaining in the source.
  8. ;
  9. ;(C) M. F. Winiberg, 5 Parc Villas, Newlyn, Penzance, Cornwall TR18 5EA
  10. ;
  11. ;A terminal device, designed to replace ANSI.SYS as distributed by IBM et al,
  12. ;this software contains both ANSI (corrected and extended from IBMs) and VT52
  13. ;terminal support.  In addition, interfaces to a Marconi Trackerball or
  14. ;Microsoft serial mouse are included.
  15. ;
  16. ;06/01/87
  17. ;
  18. ;Spurious VT52 codes are now ignored, not echoed - makes things designed for
  19. ;ACT machines run more smoothly!
  20. ;
  21. ;26/04/87
  22. ;
  23. ;Colour selection via sgr ansi command now uses high intensity colours - this
  24. ;gives a brighter display on EGA cards or where CGA with intensity is
  25. ;available
  26. ;
  27. ;04/09/87
  28. ;
  29. ;Maximum column/row addresses extended to 132 by 66 to allow for 132 column
  30. ;EGA cards etc
  31. ;
  32. ;11/12/87
  33. ;
  34. ;Mouse and Trackerball support made optional via an equate.
  35. ;
  36. ;Maximum column/row addresses reset by finding current display mode
  37. ;with  int 10H, ah = 0fH and then looking up the screen sizes in
  38. ;a table.  The 132 column modes etc produced by the ATI VIP and
  39. ;EGA WONDER cards are also included.
  40. ;
  41. ;14/12/87
  42. ;
  43. ;The above (11/12) mod didn't work because the VIP ROM BIOS does not
  44. ;return the exepcted info - it always returns mode 3 for the high res modes!
  45. ;
  46. ;I have now added some extra controls that allow the user to set the resolution
  47. ;of the display by sending pseudo ansi sequences.
  48. ;
  49. ;
  50. codeseg    SEGMENT PARA PUBLIC
  51.     ASSUME CS:codeseg,DS:codeseg,ES:codeseg
  52. ;
  53. true        EQU    0FFFFH
  54. false        EQU    0
  55. ;
  56. ; Set the next equate to true if you want the mouse/trackerball code
  57. ; included.
  58. ;
  59. tracker        EQU    false
  60. ;
  61. rkadr        EQU    6CH
  62. CR        EQU    0DH
  63. LF        EQU    0AH
  64. ;
  65. ;Version definitions
  66. ;
  67. ;
  68. MAJOR        EQU    '2'
  69. MINOR        EQU    '1'
  70. ;
  71. BUFFER_HEAD    EQU    041AH        ; IBM ROM keyboard variable
  72. ;
  73. ; Maximum length of buffer used to store key definitions and incoming
  74. ; parameter data.
  75. ;
  76. max_pbuf    EQU    500
  77. ;
  78.     org    0
  79. ;
  80. ;    CONSOLE DEVICE HEADER
  81. ;
  82. condev    DW    0ffffh
  83.     DW    0ffffh
  84.     DW    8013h
  85.     DW    strategy
  86.     DW    entry
  87.     DB    'CON     '
  88. ;
  89. ;device command switch table
  90. ;
  91. contbl    DW    con$init
  92.     DW    exit
  93.     DW    exit
  94.     DW    cmderr
  95.     DW    con$read
  96.     DW    con$rdnd
  97.     DW    exit
  98.     DW    con$flsh
  99.     DW    con$writ
  100.     DW    con$writ
  101.     DW    exit
  102.     DW    exit
  103. ;
  104. ;VT52 command lookup table
  105. ;
  106. ;
  107. vt52_tab LABEL BYTE
  108. ;
  109.     db    '('
  110.     dw    bright            ; high intensity foreground
  111.     db    ')'
  112.     dw    dim            ; normal intensity
  113.     db    'A'
  114.     dw    cuu            ; cursor up
  115.     db    'B'
  116.     dw    vcud            ; cursor down
  117.     db    'C'
  118.     dw    cuf            ; cursor forward
  119.     db    'D'
  120.     dw    cub            ; cursor back
  121.     db    'E'
  122.     dw    vcls            ; clear top 24 lines only - leave cursor
  123.     db    'H'
  124.     dw    cuh            ; cursor position
  125.     db    'J'
  126.     dw    ved            ; erase display
  127.     db    'K'
  128.     dw    el            ; erase line
  129.     db    'Y'
  130.     dw    vcup            ; cursor position
  131.     db    'j'
  132.     dw    scp            ; save cursor position
  133.     db    'k'
  134.     dw    rcp            ; restore cursor position
  135.     db    'p'
  136.     dw    revon            ; reverse video on
  137.     db    'q'
  138.     dw    revoff            ; reverse video off
  139.     db    'y'
  140.     dw    vrm            ; reset mode
  141.     db    'x'
  142.     dw    vsm            ; set mode
  143.     db    00
  144. ;
  145. ;ANSI sequence command lookup table
  146. ;
  147. cmdtab    DB    'A'
  148.     DW    cuu
  149.     DB    'B'
  150.     DW    cud
  151.     DB    'C'
  152.     DW    cuf
  153.     DB    'D'
  154.     DW    cub
  155.     DB    'H'
  156.     DW    cup
  157.     DB    'J'
  158.     DW    ed
  159.     DB    'K'
  160.     DW    el
  161.     DB    'R'
  162.     DW    cpr
  163.     DB    'f'
  164.     DW    cup
  165.     DB    'h'
  166.     DW    sm
  167.     DB    'l'
  168.     DW    rm
  169.     DB    'm'
  170.     DW    sgr
  171.     DB    'n'
  172.     DW    dsr
  173.     DB    'p'
  174.     DW    kkr
  175.     DB    's'
  176.     DW    scp
  177.     DB    'u'
  178.     DW    rcp
  179. ;
  180. if    tracker
  181. ;
  182. ;input device controls - not ANSI!
  183. ;
  184.     DB    '['
  185.     DW    devon
  186.     DB    ']'
  187.     DW    devoff
  188. ;
  189. endif
  190. ;
  191. ; Screen resolution setting control - not ansi
  192. ;
  193.     DB    '#'
  194.     DW    set_res
  195. ;
  196.     DB    0            ; end of table
  197. ;
  198. ptrsav    DW    0
  199. ptrsav2    DW    0
  200. ;
  201. ;
  202. ;Note - reversed order so word fetches get row,col into rH,rL
  203. ;
  204. win_col        DB    24        ; physical start of window
  205. win_row        DB    17
  206. win_col_max    DB    79        ; maximum size of window
  207. win_row_max    DB    24
  208. ;
  209. strategy     PROC    FAR
  210. ;
  211.     mov    cs:ptrsav,bx
  212.     mov    cs:ptrsav2,es
  213.     ret
  214. ;
  215. strategy    ENDP
  216.  
  217. entry:
  218.     push    si
  219.     push    ax
  220.     push    cx
  221.     push    dx
  222.     push    di
  223.     push    bp
  224.     push    ds
  225.     push    es
  226.     push    bx
  227.     lds    bx,cs:DWORD PTR    ptrsav
  228.     mov    cx,18[bx]
  229.     mov    al,2[bx]
  230.     cbw
  231.     mov    si,OFFSET contbl    ; 12h
  232.     add    si,ax
  233.     add    si,ax
  234.     cmp    al,0bh            ; Number of entries in table
  235.     ja    cmderr
  236.     les    di,DWORD PTR 14[bx]
  237.     push    cs
  238.     pop    ds
  239.     jmp    WORD PTR [si]
  240.  
  241. bus$exit:
  242.     mov    ah,3
  243.     jmp    SHORT err1
  244.  
  245. cmderr:
  246.     mov    al,3
  247.     mov    ah,81h
  248.     jmp    SHORT err1
  249.  
  250. exitp    PROC    FAR
  251. ;
  252. exit:
  253.     mov    ah,1
  254. err1:
  255.     lds    bx,cs:DWORD PTR    ptrsav
  256.     mov    3[bx],ax
  257.     pop    bx
  258.     pop    es
  259.     pop    ds
  260.     pop    bp
  261.     pop    di
  262.     pop    dx
  263.     pop    cx
  264.     pop    ax
  265.     pop    si
  266.     ret
  267. ;
  268. exitp    ENDP
  269. ;
  270. break:
  271.     mov    cs:altah,3
  272. intret:
  273.     iret
  274.  
  275. ;
  276. ;NOTE - we must keep a separate idea of our cursor position in case the ROM is
  277. ;called to alter it without our knowledge, also if we use the same ones, they
  278. ;risk causing double scrolling because of double updating of the row values.
  279. ;
  280. ;See note dated 16/05/86 above - to avoid the problem of programs that cursor
  281. ;address via the ROM but then continue via the OS - tricky one - calls to the
  282. ;rom routines to cursor address also alter our local copy!
  283. ;
  284. chrout:
  285.     cmp    al,CR
  286.     jnz    trylf
  287.     mov    col,0
  288.     jmp    setit
  289.  
  290. trylf:
  291.     cmp    al,LF
  292.     jz    islf
  293.     cmp    al,7
  294.     jnz    tryback
  295. ;
  296. ;BEEPS
  297. ;
  298. torom:
  299.     mov    bx,WORD PTR attr
  300.     and    bl,7
  301.     mov    ah,0eh
  302.     int    10h
  303. ret5:
  304.     ret
  305.     
  306. tryback:
  307.     cmp    al,8
  308.     jnz    outchr
  309.     cmp    col,0
  310.     jz    ret5
  311.     dec    col
  312.     jmp    SHORT setit
  313.  
  314. outchr:
  315.     mov    bx,WORD PTR attr
  316.     mov    cx,1
  317.     mov    ah,9
  318.     int    10h
  319.     inc    col
  320.     mov    al,win_col_max        ; applies in all cases regardless
  321.     cmp    col,al
  322.     jbe    setit
  323.     cmp    wrap,0
  324.     jz    outchr1
  325.     dec    col
  326.     ret
  327.  
  328. outchr1:
  329.     mov    col,0
  330. islf:
  331.     inc    row
  332.     mov    al,win_row_max
  333.     cmp    row,al
  334.     jbe    setit
  335.     mov    row,al
  336.     call    scroll
  337. setit:
  338.     mov    dh,row
  339.     mov    dl,col
  340.     mov    bh,dis_page
  341.     mov    ah,2
  342.     int    10h
  343.     ret
  344. scroll:
  345.     mov    ax,601H            ; scroll up one line
  346.     xor    cx,cx            ; top left is 0,0
  347.     mov    bh,attr
  348.     mov    dx,WORD PTR win_col_max    ; bottom right
  349.     int    10H            ; scroll it
  350.     ret
  351.  
  352. ;    mov    al,0ah
  353. ;    jmp    torom
  354.  
  355. con$read:
  356.     jcxz    con$exit
  357. con$loop:
  358.     push    cx
  359.     call    chrin
  360.     pop    cx
  361.     stosb
  362.     loop    con$loop
  363. con$exit:
  364.     jmp    exit
  365.  
  366. chrin:
  367.     xor    ax,ax
  368.     xchg    al,altah
  369.     or    al,al
  370.     jnz    keyret
  371. no_key:
  372.     cmp    bufcnt,0
  373.     jnz    read_buf        ; get chars from buffer
  374. ;
  375. if    tracker
  376. ;
  377.     xor    ax,ax            ; get next key from input device
  378.     call    inp_key
  379.     jz    no_inpk            ; none found
  380.     jmp    SHORT    lkup
  381. no_inpk:
  382. ;
  383. endif
  384. ;
  385.     xor    ah,ah            ; see if key available
  386.     int    16h
  387. lkup:
  388.     call    lookup            ; see if a key definition to be used
  389.     jnz    no_def
  390.     dec    cx            ; cx has length of definition
  391.     dec    cx
  392.     inc    bx
  393.     inc    bx
  394.     or    al,al            ; if extended key, need to skip a byte    
  395.     jnz    ord_key            ; in the definition.
  396.     dec    cx
  397.     inc    bx
  398. ord_key:
  399.     mov    bufcnt,cl
  400.     mov    bufpos,bx
  401.     call    read_buf
  402. no_def:
  403.     or    ax,ax
  404.     jz    no_key
  405.     or    al,al
  406.     jnz    keyret
  407.     mov    altah,ah        ; save station code?
  408. keyret:
  409.     ret
  410.  
  411. read_buf:
  412.     mov    bx,bufpos
  413.     mov    ax,[bx]
  414.     dec    bufcnt
  415.     inc    bx
  416.     or    al,al
  417.     jnz    key_ord            ; special keys are words not bytes
  418.     inc    bx
  419.     dec    bufcnt
  420. key_ord:
  421.     mov    bufpos,bx
  422.     ret
  423.  
  424. ;
  425. ;Keyboard key reassignment lookup.
  426. ;
  427. ;This routine looks through a linked list of key redefinitions to see if the
  428. ;current key has to be translated.
  429. ;
  430. ;On entry:
  431. ;
  432. ;    AX - has key code as returned by ROM BIOS
  433. ;
  434. ;On exit:
  435. ;
  436. ;    Z flag unset if no definition found
  437. ;
  438. ;    Z flag set if definition found,
  439. ;    BX points to start of definition data made up as follows:
  440. ;
  441. ;        length of entry        byte
  442. ;        BIOS key code        byte ( or word for extended keys)
  443. ;        New definition        bytes to make up length
  444. ;
  445. ;    CX has length of entry
  446. ;
  447. lookup:
  448.     mov    bx,OFFSET keybuf
  449. look_2:
  450.     mov    cl,[bx]            ; get definition length
  451.     xor    ch,ch
  452.     or    cx,cx
  453.     jz    no_trans        ; no defn - cannot translate
  454.     or    al,al
  455.     jnz    not_ext
  456.     cmp    ax,1[bx]        ; extended key stored as word
  457.     jmp    SHORT is_key
  458.  
  459. not_ext:
  460.     cmp    al,1[bx]        ; ordinary - this is key val
  461. is_key:    jz    found_key
  462.     add    bx,cx            ; point to next defn
  463.     jmp    SHORT look_2        ; keep looking
  464.  
  465. no_trans:
  466.     or    bx,bx            ; set flags
  467. found_key:
  468.     ret
  469.  
  470. con$rdnd:
  471.     mov    al,altah
  472.     or    al,al
  473.     jnz    rdexit
  474.     cmp    bufcnt,0
  475.     jz    rd1
  476.     mov    bx,bufpos
  477.     mov    al,[bx]
  478.     jmp    SHORT rdexit
  479.  
  480. rd1:
  481. ;
  482. if    tracker
  483. ;
  484.     mov    ah,1            ; any keys waiting in input device
  485.     call    inp_key
  486.     jz    chk_kbd            ; no - check the system keyboard
  487.     jmp    SHORT kkr_chk        ; otherwise go translate if reqd
  488. ;
  489. endif
  490. ;
  491. chk_kbd:
  492.     mov    ah,1            ; non-des read
  493.     int    16h
  494.     jz    con_mt            ; nothing there
  495.     or    ax,ax
  496.     jnz    kkr_chk            ; check key value in case kkr in force
  497.     mov    ah,0            ; remove any null chars from the buffer
  498.     int    16h
  499.     jmp    SHORT con$rdnd
  500.  
  501. kkr_chk:
  502.     call    lookup
  503.     jnz    rdexit
  504.     mov    al,2[bx]
  505.     cmp    BYTE PTR 1[bx],0    ; true if extended key definition
  506.     jnz    rdexit
  507.     mov    al,3[bx]        ; first byte of defn
  508. rdexit:
  509.     lds    bx,DWORD PTR ptrsav
  510.     mov    13[bx],al        ; pass back to caller
  511. exvec:
  512.     jmp    exit
  513.  
  514. con_mt:
  515.     jmp    bus$exit
  516.  
  517. con$flsh:
  518. ;
  519. if    tracker
  520. ;
  521.     mov    ah,2            ; clear pending input dev keys
  522.     call    inp_key
  523. ;
  524. endif
  525. ;
  526.     mov    altah,0
  527.     mov    bufcnt,0        ; clear internal buffer
  528.     push    ds
  529.     xor    bp,bp
  530.     mov    ds,bp
  531.     mov    bp,BUFFER_HEAD        ; IBM keyboard buffer
  532.     mov    ds:WORD PTR [bp],1eh    ; clear IBM ROM keyboard buffer
  533.     mov    ds:WORD PTR 2[bp],1eh
  534.     pop    ds
  535.     jmp    SHORT exvec
  536. ;
  537. if    tracker
  538. ;
  539. ;inp_key
  540. ;
  541. ;function that manipulates the keystrokes generated by an input device (eg
  542. ;mouse) in a way similar to the ROM BIOS kbd handler.
  543. ;
  544. ;On entry:
  545. ;
  546. ;    AH    0    Fetch next key from device - return with null if none
  547. ;    AH    1    return Z if no keys waiting, NZ if there are some
  548. ;    AH    2    clear any pending key returns
  549. ;
  550. ;On exit:
  551. ;
  552. ;    AX        has key value where relevant
  553. ;    Z        flag set if no key available
  554. ;
  555. ; In addition, this function attempts to return movement keys in a sensible
  556. ;fashion so that diagonal movements come out naturally, not as x,y steps.
  557. ;
  558. inp_key    PROC    NEAR
  559. ;
  560.     push    ax            ; save passed command while we scan
  561.     mov    al,devflg        ; if device off, then do nothing
  562.     or    al,al
  563.     jnz    dev_active
  564.     jmp    no_butt
  565. dev_active:
  566.     call    device            ; the device
  567.     push    ax            ; save any button info
  568.     mov    ax,bx
  569.     add    ax,xrem            ; get any current x remainder
  570.     cwd
  571.     idiv    speed            ; divide by the selected speed
  572.     mov    xrem,dx            ; keep any remainder for next time
  573.     mov    bx,ax
  574.     or    bx,bx            ; set flags
  575.     jz    no_inpx
  576.     jns    inp_px
  577.     neg    bx
  578.     mov    ax,4B00H        ; (left) station code
  579.     jmp    SHORT inp_xset
  580. inp_px:
  581.     mov    ax,4D00H        ; (right)
  582. inp_xset:
  583.     push    cx
  584.     mov    cx,bx
  585. px_lp:
  586.     call    add_inp            ; add ax to the buffer if pos
  587.     loop    px_lp
  588.     pop    cx
  589. no_inpx:
  590.     mov    ax,cx
  591.     add    ax,yrem            ; get any y remainder
  592.     cwd
  593.     idiv    speed
  594.     mov    yrem,dx            ; keep this remainder
  595.     mov    cx,ax
  596.     or    cx,cx
  597.     jz    no_inpy
  598.     jns    inp_py
  599.     neg    cx
  600.     mov    ax,5000H        ; (down) station code
  601.     jmp    SHORT inp_yset
  602. inp_py:
  603.     mov    ax,4800H        ; (up)
  604. inp_yset:
  605.     call    add_inp            ; add ax to the buffer if pos
  606.     loop    inp_yset
  607. no_inpy:
  608.     pop    ax
  609.     or    al,al            ; any buttons?
  610.     jz    no_butt
  611.     mov    di,6800H        ; ALT-F1 (we use F1-8)
  612.     mov    cx,8            ; 8 bits to examine
  613. butt_lp:
  614.     ror    al,1            ; see if button down
  615.     jnc    butt_up            ; no, so don't add to buffer
  616.     push    ax
  617.     mov    ax,di            ; get key value
  618.     call    add_inp
  619.     pop    ax
  620. butt_up:
  621.     add    di,100H            ; move to next F key value
  622.     loop    butt_lp
  623. no_butt:
  624.     pop    ax            ; get back passed command
  625.     cmp    ah,2
  626.     jz    inp_clr            ; clear any pending data
  627.     cmp    ah,1            ; read any waiting key
  628.     jz    inp_ndrd
  629.     or    ah,ah
  630.     jz    inp_rd            ; read next value
  631. clr_ex:
  632.     xor    ax,ax
  633.     ret                ; otherwise give up
  634. ;
  635. inp_clr:
  636.     xor    ax,ax
  637.     mov    in_rd,ax        ; reset read pointer into buffer
  638.     mov    in_wr,ax        ; reset write pointer
  639.     mov    in_cnt,ax        ; reset current char count
  640.     jmp    SHORT clr_ex
  641. ;
  642. inp_ndrd:                ; return any pending value
  643.     mov    ax,in_cnt        ; any in buffer
  644.     or    ax,ax
  645.     jz    clr_ex            ; no - give up
  646.     mov    bx,OFFSET inp_buf
  647.     mov    si,in_rd
  648.     mov    ax,[bx+si]        ; get key value without moving pointer
  649.     or    ax,ax            ; set flags
  650.     ret
  651. ;
  652. inp_rd:
  653.     mov    ax,in_cnt
  654.     or    ax,ax
  655.     jz    clr_ex            ; none in, so give up
  656.     mov    bx,OFFSET inp_buf
  657.     mov    si,in_rd        ; current offset into buffer
  658.     mov    ax,[bx+si]        ; get current key
  659.     dec    WORD PTR in_cnt        ; knock one off contents
  660.     add    si,2
  661.     cmp    si,256            ; see if we have wrapped around
  662.     jb    no_rdwp
  663.     xor    si,si            ; reset to beginning of buffer
  664. no_rdwp:
  665.     mov    in_rd,si
  666.     or    ax,ax
  667.     ret                ; return char to kbd routine
  668. ;
  669. inp_key    ENDP
  670. ;
  671. ;
  672. ;add_inp    adds AX to the circular buffer
  673. ;
  674. add_inp    PROC    NEAR
  675. ;
  676.     push    bx
  677.     push    dx
  678.     push    si
  679.     mov    dx,in_cnt        ; see if any room
  680.     cmp    dx,256
  681.     jae    no_add
  682.     mov    bx,OFFSET inp_buf
  683.     mov    si,in_wr        ; get current write position
  684.     mov    [bx+si],ax        ; store key value
  685.     inc    WORD PTR in_cnt
  686.     add    si,2
  687.     cmp    si,256
  688.     jb    no_wrwp
  689.     xor    si,si            ; wrap back to beginning of buffer
  690. no_wrwp:
  691.     mov    in_wr,si
  692. no_add:
  693.     pop    si
  694.     pop    dx
  695.     pop    bx
  696.     ret
  697. ;
  698. add_inp    ENDP
  699. ;
  700. ;
  701. endif
  702. ;
  703. ;
  704. con$writ:
  705.     or    cx,cx
  706.     jnz    get_lp
  707.     jmp    exvec
  708. get_lp:
  709.     mov    al,es:[di]
  710.     inc    di
  711.     call    outc
  712.     loop    get_lp
  713.     jmp    exvec
  714.  
  715. cout:
  716.     sti
  717.     push    ds
  718.     push    cs
  719.     pop    ds
  720.     call    outc
  721.     pop    ds
  722.     iret
  723.  
  724. ;
  725. outc:
  726.     push    ax
  727.     push    bx
  728.     push    cx
  729.     push    dx
  730.     push    si
  731.     push    di
  732.     push    es
  733.     push    bp
  734.     push    ax
  735.     push    bx
  736.     push    cx
  737.     push    dx
  738.     mov    cx,ds            ; IBM rom as ROM BIOS seems to cause
  739.     mov    dx,40H            ; problems
  740.     mov    ds,dx            ; point to ROM BIOS data area
  741.     mov    bl,ds:BYTE PTR 62H    ; find current active display page
  742.     xor    bh,bh
  743.     mov    dx,80[bx]        ; get current cursor pos
  744.     mov    ds,cx
  745.     mov    WORD PTR cs:col,dx
  746.     pop    dx
  747.     pop    cx
  748.     pop    bx
  749.     pop    ax
  750.     call    video
  751.     pop    bp
  752.     pop    es
  753.     pop    di
  754.     pop    si
  755.     pop    dx
  756.     pop    cx
  757.     pop    bx
  758.     pop    ax
  759.     ret
  760.  
  761. video:
  762.     mov    si,OFFSET state        ; Starts by jumping to s1
  763.     jmp    WORD PTR [si]
  764.  
  765. ansi_chk:
  766.     cmp    al,'['
  767.     jz    ansi_comes
  768. ;
  769. ;Now check for VT52 codes
  770. ;
  771.     mov    bx,OFFSET vt52_tab - 3
  772. vs7a:
  773.     add    bx,3
  774.     cmp    BYTE PTR [bx],0
  775.     jnz    vs7b
  776.     jmp    s1a            ; was no_cmd, but I now want to ignore
  777. vs7b:
  778.     cmp    BYTE PTR [bx],al
  779.     jnz    vs7a
  780.     mov    cx,1            ; only one thing to do for all VT52s
  781.     jmp    WORD PTR 1[bx]
  782. ;
  783. ansi_comes:
  784.     mov    state,OFFSET scan_params
  785.     xor    bx,bx
  786.     mov    WORD PTR delim,bx
  787.     jmp    SHORT t_p_buff
  788.  
  789. scan_params:
  790.     cmp    al,';'            ; separator
  791.     jnz    chk_dig
  792. nxt_pbyte:
  793.     inc    parm_len        ; ensure at least 1
  794. t_p_buff:                ; terminate current param area end
  795.     call    np_byte
  796.     xor    ax,ax
  797.     mov    [bx],ax
  798.     ret
  799.  
  800. chk_dig:
  801.     cmp    al,'0'            ; 30h
  802.     jb    chk_delim
  803.     cmp    al,'9'            ; 39h
  804.     ja    chk_delim
  805.     call    np_byte
  806.     sub    al,'0'            ; 30h
  807.     xchg    al,[bx]
  808.     mov    ah,0ah
  809.     mul    ah
  810.     add    [bx],al
  811.     ret
  812.  
  813. chk_delim:
  814.     cmp    al,'='            ; These are lead-in/separators used
  815.     jz    sep_fnd            ; by some commands
  816.     cmp    al,'?'
  817.     jz    sep_fnd
  818.     cmp    al,'"'            ; String delimiter for kkr
  819.     jz    str_fnd
  820.     cmp    al,27h            ; ' - alternate string delimiter
  821.     jnz    scan_cmd
  822. str_fnd:
  823.     mov    state,OFFSET read_parm
  824.     mov    delim,al
  825. sep_fnd:
  826.     ret
  827.  
  828. read_parm:
  829.     cmp    al,delim
  830.     jnz    still_str        ; still receiving a string
  831.     dec    parm_len
  832.     mov    state,OFFSET scan_params
  833.     ret
  834.  
  835. still_str:
  836.     call    np_byte
  837.     mov    [bx],al
  838.     mov    state,OFFSET read_parm ; 398h
  839.     jmp    SHORT nxt_pbyte
  840.  
  841. scan_cmd:
  842.     mov    bx,OFFSET cmdtab - 3
  843. scmd_2:
  844.     add    bx,3
  845.     cmp    BYTE PTR [bx],0
  846.     jz    no_cmd
  847.     cmp    [bx],al
  848.     jnz    scmd_2
  849.     mov    ax,1[bx]
  850.     mov    bx,OFFSET keybuf
  851.     inc    bx
  852.     add    bx,kbuf_end
  853.     mov    dl,[bx]            ; get first parameter (should always be
  854.     xor    dh,dh            ; a number
  855.     mov    cx,dx
  856.     or    cx,cx
  857.     jnz    gotoit
  858.     inc    cx            ; set default of 1 for param 1 value
  859. gotoit:
  860.     jmp    ax
  861.  
  862. s1:
  863.     cmp    al,1bh
  864.     jnz    no_cmd
  865.     mov    state,OFFSET ansi_chk
  866.     ret
  867.  
  868. no_cmd:
  869.     call    chrout            ; print char if not in table
  870. s1a:
  871.     mov    state,OFFSET s1
  872.     ret
  873.  
  874. movcur:
  875.     cmp    [bx],ah
  876.     jz    setcur
  877.     add    [bx],al
  878.     loop    movcur
  879. setcur:
  880.     mov    dh,row
  881.     mov    dl,col
  882.     mov    bh,dis_page
  883.     mov    ah,2
  884.     int    10h
  885.     jmp    SHORT s1a
  886.  
  887. cuh:
  888.     mov    WORD PTR col,0
  889.     jmp    SHORT setcur
  890.  
  891. cup:
  892.     mov    al,win_row_max
  893.     inc    al
  894.     cmp    cl,al            ; Check ROW is in range (parm 1)
  895.     jbe    cup2
  896.     jmp    setcur            ; no - reset cursor to previous value
  897. cup2:
  898.     mov    al,win_col_max
  899.     inc    al
  900.     mov    ch,1[bx]        ; get column (parm 2)
  901.     or    ch,ch
  902.     jz    zer_col
  903.     dec    ch
  904. zer_col:
  905.     cmp    al,ch            ; limit it to current max value
  906.     ja    col_ok
  907.     mov    ch,al
  908. col_ok:
  909.     xchg    cl,ch            ; get into correct place for writing
  910.     dec    ch            ; row is always at least 1
  911.     mov    WORD PTR col,cx        ; enter new value and then set it
  912.     jmp    setcur
  913.  
  914. vcup:
  915.     mov    state,OFFSET vcup1
  916.     ret
  917. vcup1:
  918.     sub    al,32
  919.     mov    BYTE PTR rowtemp,al
  920.     mov    state,OFFSET vcup2
  921.     ret
  922. vcup2:
  923.     sub    al,32
  924.     mov    BYTE PTR col,al
  925.     mov    al,BYTE PTR rowtemp
  926.     mov    BYTE PTR row,al
  927.     jmp    setcur
  928.  
  929. ;
  930. ;reverse video is done like this so that it works the way you would expect
  931. ;on a colour display, ie it swaps background and foreground as far as possible.
  932. ;
  933. ;NOTE- for MVD11 reverse video is obtained by writing ASCII + 128 byte, thus
  934. ;we need to select the method depending on the current display selected.
  935. ;
  936. ;
  937. revon:
  938.     mov    BYTE PTR revflg,80H
  939.     jmp    SHORT set_rev
  940.  
  941. revoff:
  942.     mov    BYTE PTR revflg,0
  943.  
  944. set_rev:
  945.     mov    al,attr
  946.     and    al,77H
  947.     mov    cl,4            ; swap the attribute settings
  948.     ror    al,cl
  949.     and    BYTE PTR attr,88H    ; keep B and I as before
  950.     or    BYTE PTR attr,al
  951.     jmp    s1a
  952.  
  953. bright:
  954.     or    BYTE PTR attr,08H    ; set intensity bit
  955.     jmp    s1a
  956.  
  957. dim:
  958.     and    BYTE PTR attr,0F7H    ; remove intensity bit
  959.     jmp    s1a
  960.  
  961. cuf:
  962.     mov    ah,win_col_max
  963.     mov    al,1
  964. cuf1:
  965.     mov    bx,OFFSET col
  966.     jmp    movcur
  967.  
  968. cub:
  969.     mov    ax,0FFH
  970.     jmp    SHORT cuf1
  971.  
  972. cuu:
  973.     mov    ax,0FFH
  974. cuu1:
  975.     mov    bx,OFFSET row
  976.     jmp    movcur
  977.  
  978. cud:
  979.     mov    ah,win_row_max
  980.     mov    al,1
  981.     jmp    SHORT cuu1
  982.  
  983. scp:
  984.     mov    ax,word    ptr col
  985.     mov    savcr,ax
  986.     jmp    setcur
  987.  
  988. rcp:
  989.     mov    ax,savcr
  990.     mov    WORD PTR col,ax
  991.     jmp    setcur
  992.  
  993. vcud:    mov    ah,win_col_max
  994.     mov    al,1
  995.     jmp    SHORT cuu1
  996.  
  997. sgr:
  998.     xor    cx,cx
  999.     xchg    cl,BYTE PTR parm_len
  1000.     call    np_byte
  1001.     inc    cx
  1002. att_loop:
  1003.     mov    al,[bx]            ; get an attribute command from param
  1004.     push    bx            ; area
  1005.     mov    bx,OFFSET att_tab    ; look it up in the table
  1006. att_next:
  1007.     mov    ah,[bx]
  1008.     add    bx,3
  1009.     cmp    ah,0ffh            ; end of table ?
  1010.     jz    att_done
  1011.     cmp    ah,al            ; found requested attribute?
  1012.     jnz    att_next        ; no, look at next entry in table
  1013.     mov    ax,-2[bx]        ; yes, get mask and bits needed to
  1014.     and    attr,al            ; establish the attribute requested
  1015.     or    attr,ah
  1016. att_done:
  1017.     pop    bx
  1018.     inc    bx
  1019.     loop    att_loop
  1020.     jmp    setcur
  1021.  
  1022. ved:
  1023.     mov    al,win_row_max        ; last line is special in VT52
  1024.     dec    al
  1025.     cmp    BYTE PTR row,al
  1026.     jb    ved_j
  1027.     jmp    vel1
  1028. ved_j:                    ; BLOODY INTEL!
  1029.     mov    dh,al
  1030. ;
  1031. ;Clear to end of screen - because of way ROM BIOS works, we must clear
  1032. ;the current line from cursor to end, and clear the remainder of the screen
  1033. ;window at full width
  1034. ;
  1035. ved2:
  1036.     mov    cx,WORD PTR col
  1037.     inc    ch            ; up row to clear remainder
  1038.     xor    cl,cl
  1039.     mov    dl,win_col_max
  1040.     mov    bh,attr
  1041.     mov    ax,600H
  1042.     int    10H            ; clear it
  1043.     jmp    SHORT el        ; now erase to end of current line
  1044.  
  1045. vcls:                    ; clear whole display, leave cursor
  1046.     xor    cx,cx            ; and line 25
  1047.     mov    dh,win_row_max
  1048.     dec    dh
  1049.     jmp    SHORT erase
  1050.  
  1051. ed:
  1052.     xor    cl,cl            ; examine the passed param (if any)
  1053.     xchg    cl,BYTE PTR parm_len
  1054.     call    np_byte
  1055.     mov    al,[bx]            ; get it
  1056.     or    al,al            ; 0 - clear from cursor to end of screen
  1057.     mov    dh,win_row_max
  1058.     jz    ved2
  1059.     cmp    al,2
  1060.     jz    clr
  1061.     mov    dx,WORD PTR col
  1062.     xor    cx,cx            ; al = 1 clear up to cursor
  1063.     dec    dh            ; do area above cursor line
  1064.     mov    dl,win_col_max
  1065.     mov    bh,attr
  1066.     mov    ax,600H
  1067.     int    10H
  1068.     mov    dx,WORD PTR col        ; now clear up to cursor
  1069.     mov    ch,dh
  1070.     xor    cl,cl
  1071.     jmp    SHORT erase2
  1072. clr:
  1073.     xor    cx,cx            ; clear the lot!
  1074.     mov    WORD PTR col,cx
  1075. erase:
  1076.     mov    dl,win_col_max
  1077. erase2:
  1078.     mov    bh,attr
  1079.     mov    ax,600h
  1080.     int    10h
  1081.     jmp    setcur
  1082.  
  1083. vel1:
  1084.     mov    BYTE PTR col,0
  1085.  
  1086. el:
  1087.     mov    cx,word    ptr col
  1088. el2:
  1089.     mov    dh,ch
  1090.     jmp    SHORT erase
  1091.  
  1092. byte_to_dec:
  1093.     mov    dl,0ah
  1094.     inc    al
  1095.     xor    ah,ah
  1096.     div    dl
  1097.     add    ax,3030h
  1098.     ret
  1099.  
  1100. dsr:
  1101.     mov    al,row
  1102.     call    byte_to_dec
  1103.     mov    rowval,ax
  1104.     mov    al,col
  1105.     call    byte_to_dec
  1106.     mov    colval,ax
  1107.     mov    bufcnt,9
  1108.     mov    bufpos,OFFSET cprbuf
  1109. cpr:
  1110.     jmp    s1a
  1111.  
  1112. vrm:
  1113.     mov    state,OFFSET vrm1
  1114.     ret
  1115.  
  1116. vrm1:
  1117.     xor    cx,cx
  1118.     mov    ch,24
  1119.     jmp    SHORT el2
  1120.  
  1121. rm:
  1122.     mov    cl,1
  1123.     jmp    SHORT setmode
  1124.  
  1125. vsm:
  1126.     mov    state,OFFSET s1a
  1127.     ret
  1128. sm:
  1129.     xor    cx,cx
  1130. setmode:
  1131.     mov    al,dl
  1132.     cmp    al,7
  1133.     ja    cpr
  1134.     jb    set_it
  1135.     mov    wrap,cl
  1136.     jmp    SHORT cpr
  1137.  
  1138. set_it:
  1139.     mov    ah,0
  1140.     int    10h
  1141.     jmp    SHORT cpr
  1142.  
  1143. ;
  1144. if    tracker
  1145. ;
  1146. ;
  1147. ;devon - enable (in software) the input device - also init the buffers etc
  1148. ;
  1149. devon:
  1150.     mov    speed,cx        ; first param (def 1) sets speed
  1151.     mov     ax,2
  1152.     call    inp_key            ; clear any pending keys
  1153.     mov    ax,io_port        ; if Z then cannot use device
  1154.     or    ax,ax
  1155.     jz    not_on
  1156.     mov    BYTE PTR devflg,1    ; tell console device is active
  1157.     call    devinit            ; tell device to init
  1158. not_on:
  1159.     jmp    setcur
  1160. ;
  1161. ;
  1162. ;devoff - disable input device, hence freeing any ports etc it was using
  1163. ;
  1164. devoff:
  1165.     mov    BYTE PTR devflg,0
  1166.     call    devterm
  1167.     jmp    setcur
  1168. ;
  1169. endif
  1170. ;
  1171. ; Screen resolution setting command
  1172. ;
  1173. set_res:
  1174.     mov    ch,cl            ; get rows to ch
  1175.     mov    cl,1[bx]        ; and columns to cl
  1176.     dec    cl            ; adjust to max address
  1177.     dec    ch
  1178.     mov    WORD PTR win_col_max,cx    ; set it
  1179.     jmp    setcur
  1180. ;
  1181. ;Keyboard Key Reassignment
  1182. ;
  1183. kkr:
  1184.     xor    dx,dx
  1185.     xchg    dl,BYTE PTR parm_len
  1186.     inc    dx
  1187.     inc    dx
  1188.     call    np_byte            ; bx points to start of param area
  1189.     mov    ax,[bx]            ; get key value required
  1190.     call    lookup            ; is it already defined?
  1191.     jnz    isn_defd        ; no
  1192.     mov    di,bx            ; yes - remove existing definition
  1193.     sub    kbuf_end,cx        ; cx has length of definition
  1194.     mov    bufcnt,0
  1195.     mov    si,di            ; di points to start of defn
  1196.     add    si,cx            ; si to end
  1197.     add    cx,OFFSET enk_buf
  1198.     sub    cx,si            ; shift rest of table up
  1199.     cld
  1200.     push    es
  1201.     push    cs
  1202.     pop    es
  1203.     rep    movsb
  1204.     pop    es
  1205. isn_defd:
  1206.     call    np_byte
  1207.     cmp    BYTE PTR [bx],0        ; extended key?
  1208.     jnz    kk_nsp
  1209.     cmp    dl,4            ; minimum length for a definition
  1210.     jb    is_room
  1211.     jmp    SHORT kk_isdef
  1212. kk_nsp:
  1213.     cmp    dl,3            ; minimum length for a definition
  1214.     jb    is_room            ; no - just terminate table here
  1215. kk_isdef:
  1216.     mov    -1[bx],dl
  1217.     add    kbuf_end,dx
  1218.     add    bx,dx            ; point to new end to key table
  1219.     cmp    kbuf_end,max_pbuf - 8    ; leave some room for more commands
  1220.     jb    is_room
  1221.     sub    bx,dx            ; no room in buffer - give up
  1222.     sub    ds:WORD PTR kbuf_end,dx
  1223. is_room:
  1224.     mov    BYTE PTR -1[bx],0    ; make last byte in table a 0
  1225.     mov    state,OFFSET s1
  1226.     ret
  1227.  
  1228. ;
  1229. ;This routine returns the address in BX of the next byte to be used for storing
  1230. ;incoming parameters (including strings) to be used by the ANSI commands
  1231. ;
  1232. ;This data is stored on the end of the keyboard translate buffer.
  1233. ;
  1234. np_byte:
  1235.     mov    bx,ds:kbuf_end
  1236.     inc    bx
  1237.     add    bx,parm_len
  1238.     cmp    bx,max_pbuf
  1239.     jb    pbuf_ok
  1240.     dec    parm_len
  1241.     jmp    SHORT np_byte
  1242.  
  1243. pbuf_ok:
  1244.     add    bx,OFFSET keybuf    ; 555h
  1245.     ret
  1246. ;
  1247. if    tracker
  1248. ;
  1249. ;
  1250. ;device hooks temporarily set here
  1251. ;
  1252. device:
  1253.     jmp    mouse            ; filled in when device loaded
  1254. devinit:
  1255.     jmp    minit
  1256. devterm:
  1257.     jmp    mterm
  1258. ;
  1259. ;space for device code
  1260. ;
  1261.     db    512 DUP (0C3H)        ; ret instructions!
  1262. ;
  1263. ;General purpose button, loop counters for use by device
  1264. ;
  1265. ;
  1266. last_b    DB    0
  1267. key    DB    0
  1268. count    DW    0
  1269. ;
  1270. ;
  1271. ;input device data area.
  1272. ;
  1273. ;Here I implement a circular (FIFO) buffer to hold the data returned by the
  1274. ;input device.  Only the untranslated keycodes are stored.
  1275. ;
  1276. ;
  1277. in_rd        DW    0        ; current read key value
  1278. in_wr        DW    0        ; next location to store key
  1279. in_cnt        DW    0        ; number of entries in buffer
  1280. inp_buf        DW    256 DUP (0)    ; buffer 256 keys at a time
  1281. devflg        DB    0        ; flags that input device is enabled
  1282. speed        DW    1        ; divisor to control device speed
  1283. xrem        DW    0        ; remainders carried over to next
  1284. yrem        DW    0        ; call of device
  1285. io_chan        DW    0        ; set to 0 for COM1
  1286. io_port        DW    0        ; contains I/O address base for driver
  1287.                     ; the last two are set by INIT
  1288. ;
  1289. endif
  1290. ;
  1291. ;
  1292. ;
  1293. ;Data used by the device driver - some of this is position dependant
  1294. ;so be very careful when adding/deleting new bits!
  1295. ;
  1296. text_ok        DB    0        ; set by init
  1297. keys_ok        DB    0        ; set by init
  1298. ibm_cur        DW    0
  1299. ibm_atr        DW    0
  1300. rowtemp        DB    0
  1301. revflg        DB    0
  1302. wrap        DB    0
  1303. kbuf_end    DW    4
  1304. state        DW    s1
  1305. mode        DB    3
  1306. col        DB    0
  1307. row        DB    0
  1308. savcr        DW    0
  1309. delim        DB    0
  1310. parm_len    DW    0        ; length of parameter area in buffer
  1311. bufcnt        DB    0
  1312. bufpos        DW    keybuf        ; location to get next key value from!
  1313. cprbuf        DB    1bh,'['
  1314. rowval        DW    3030h
  1315.         DB    ';'
  1316. colval        DW    3030h
  1317.         DB    'R',0dh
  1318. altah        DB    0
  1319. attr        DB    7
  1320. dis_page    DB    0
  1321. base        DW    0b800h
  1322. scr_seg        DW    0
  1323. ;
  1324. ;Table used by SGR for modifying the current attributes associated with
  1325. ;characters written to the screen.
  1326. ;
  1327. ;Made up as follows:
  1328. ;
  1329. ;    attr cmd val    mask    attribute bits to be set
  1330. ;
  1331. ;
  1332. att_tab    LABEL    BYTE
  1333.  
  1334.     DB       0,       0,   7
  1335.     DB       1,    0FFH,   8
  1336.     DB       4,    0F8H,   1
  1337.     DB       5,    0FFH, 80H
  1338.     DB       7,    0F8H, 70H
  1339.     DB       8,     88H,   0
  1340.     DB     1EH,    0F8H,   0
  1341.     DB     1FH,    0F8H,   4+8    ; Use high intensity colours -
  1342.     DB     20H,    0F8H,   2+8    ; looks better on EGA etc
  1343.     DB     21H,    0F8H,   6+8
  1344.     DB     22H,    0F8H,   1+8
  1345.     DB     23H,    0F8H,   5+8
  1346.     DB     24H,    0F8H,   3+8
  1347.     DB     25H,    0F8H,   7+8
  1348.     DB     28H,     8FH,   0
  1349.     DB     29H,     8FH, 40H
  1350.     DB     2AH,     8FH, 20H
  1351.     DB     2BH,     8FH, 60H
  1352.     DB     2CH,     8FH, 10H
  1353.     DB     2DH,     8FH, 50H
  1354.     DB     2EH,     8FH, 30H
  1355.     DB     2FH,     8FH, 70H
  1356.     DB    0FFH
  1357. ;
  1358. ;
  1359. keybuf    DB    4,   0,    72h, 10h    ; Print screen key
  1360.     DB    (max_pbuf - 4) DUP (0)
  1361. enk_buf    LABEL    BYTE
  1362. ;
  1363. ;init code can be thrown away after use
  1364. ;
  1365. con$init:
  1366. ;
  1367.     sti
  1368.     int    11H            ; equipment check
  1369.     and    al,30H            ; get display info
  1370.     cmp    al,30H            ; Z if BW card
  1371.     jz    con$crt
  1372.     mov    ax,3            ; set 80 x 25 colour mode
  1373.     int    10H
  1374.     jmp    SHORT con$set
  1375. con$crt:
  1376.     mov    ax,7            ; set CRT mode
  1377.     int    10H
  1378. con$set:
  1379.     mov    WORD PTR col,0
  1380.     xor    ax,ax            ; IBM window always set to 0,0
  1381.     mov    WORD PTR win_col,ax
  1382.     mov    WORD PTR col,ax
  1383. ;
  1384. if    tracker
  1385. ;
  1386. ;
  1387. ;set up the required input device driver code
  1388. ;
  1389.     lds    bx,cs:DWORD PTR ptrsav    ; examine the invocation line
  1390.     lds    si,DWORD PTR 18[bx]       ; get pointer to string
  1391. ;
  1392. ;first find the end of the line
  1393. ;
  1394. scloop:
  1395.     mov    al,[si]
  1396.     cmp    al,0DH                 ; Carriage Return
  1397.     jz    en_lin                  ; found the end
  1398.     cmp    al,0AH                 ; might be a line feed
  1399.     jz    en_lin
  1400.     inc    si
  1401.     jmp    SHORT scloop
  1402. en_lin:                          ; line end is guaranteed!
  1403. ;
  1404. ;now go back until we find a char - should be a digit!
  1405. ;
  1406. b1_lp:
  1407.     dec    si
  1408.     cmp    BYTE PTR [si],' '         ; ignore any trailing spaces
  1409.     jz    b1_lp
  1410. ;
  1411.     cmp    BYTE PTR [si],'0'
  1412.     jb    no_dig
  1413.     cmp    BYTE PTR [si],'9'
  1414.     ja    no_dig
  1415.     mov    al,[si]                  ; get the digit - 0 or 1?
  1416.     sub    al,'1'
  1417.     and    ax,1                  ; force into range 0 - 1
  1418.     mov    cs:io_chan,ax              ; save for later setup
  1419. ;
  1420. ;now go back until we hit another character
  1421. ;
  1422. b2_lp:
  1423.     dec    si
  1424.     cmp    BYTE PTR [si],' '
  1425.     jz    b2_lp    
  1426. no_dig:
  1427. ;
  1428. ;now we fetch the two characters that should indicate the device to use
  1429. ;
  1430.     dec    si
  1431.     mov    ax,[si]                  ; get the chars
  1432.     and    ax,5f5fH              ; force into upper case
  1433.     cmp    ax,'SM'                  ; intel reverses word bytes
  1434.     jnz    st_tb                  ; not mouse, so set trackball
  1435. ;
  1436. ;serial mouse setup
  1437. ;
  1438.     mov    ax,40H                  ; point to PC data area
  1439.     mov    ds,ax
  1440.     mov    bx,cs:io_chan
  1441.     add    bx,bx                  ; point into RS232_BASE
  1442.     mov    ax,[bx]
  1443.     push    cs
  1444.     pop    ds
  1445.     mov    io_port,ax              ; set up device data area
  1446.     or    ax,ax                  ; Z if port not available
  1447.     jz    no_com
  1448.     mov    ax,OFFSET ld_ok              ; set up display messages
  1449.     jmp    SHORT dev_mst
  1450. no_com:
  1451.     mov    ax,OFFSET ld_bad
  1452. dev_mst:
  1453.     mov    dv_ms2,ax
  1454.     or    bx,bx                  ; which port?
  1455.     jnz    dev_2
  1456.     mov    ax,OFFSET c1_mess
  1457.     jmp    SHORT dev_ms2
  1458. dev_2:
  1459.     mov    ax,OFFSET c2_mess
  1460. dev_ms2:
  1461.     mov    dv_ms3,ax
  1462.     mov    ax,OFFSET sm_mess    ; and actual device name
  1463.     mov    dv_ms1,ax
  1464.     mov    cx,(OFFSET sm_end) - (OFFSET sm_start)
  1465.     mov    di,OFFSET device
  1466.     mov    si,OFFSET sm_start
  1467.     jmp    ld_dev
  1468. ;
  1469. ;come here if trackerball is to be used!
  1470. ;
  1471. st_tb:
  1472.     mov    ax,40H                  ; point to PC data area
  1473.     mov    ds,ax
  1474.     mov    bx,cs:io_chan
  1475.     add    bx,bx                  ; point into PRINTER_BASE
  1476.     add    bx,8            ; offset to PRINTER_BASE
  1477.     mov    ax,[bx]
  1478.     push    cs
  1479.     pop    ds
  1480.     mov    io_port,ax              ; set up device data area
  1481.     or    ax,ax                  ; Z if port not available
  1482.     jz    no_lst
  1483.     mov    ax,OFFSET ld_ok
  1484.     jmp    SHORT dev_tb
  1485. no_lst:
  1486.     mov    ax,OFFSET ld_bad
  1487. dev_tb:
  1488.     mov    dv_ms2,ax
  1489.     test    WORD PTR io_chan,0FFFH
  1490.     jnz    p_dev2
  1491.     mov    ax,OFFSET p1_mess
  1492.     jmp    SHORT dev_tb2
  1493. p_dev2:
  1494.     mov    ax,OFFSET p2_mess
  1495. dev_tb2:
  1496.     mov    dv_ms3,ax
  1497.     mov    ax,OFFSET mb_mess
  1498.     mov    dv_ms1,ax
  1499.     mov    cx,(OFFSET tb_end) - (OFFSET tb_start)
  1500.     mov    si,OFFSET tb_start
  1501.     mov    di,OFFSET device
  1502. ld_dev:
  1503.     push    cs
  1504.     pop    es
  1505.     cld
  1506.     rep    movsb
  1507. ;
  1508. endif
  1509. ;
  1510. setbrk:
  1511.     xor    bx,bx
  1512.     mov    ds,bx
  1513.     mov    bx,6ch            ; set up MSDOS int vectors
  1514.     mov    WORD PTR [bx],OFFSET break
  1515.     mov    2[bx],cs
  1516.     mov    bx,0a4h            ; 29 - conout
  1517.     mov    WORD PTR [bx],OFFSET cout
  1518.     mov    2[bx],cs
  1519.     push    dx
  1520.     push    cs
  1521.     pop    ds
  1522.     mov    dx,OFFSET signon
  1523.     mov    ah,9
  1524.     int    21H
  1525. ;
  1526. if    tracker
  1527. ;
  1528.     mov    dx,dv_ms1
  1529.     mov    ah,9
  1530.     int    21H
  1531.     mov    dx,dv_ms2
  1532.     mov    ah,9
  1533.     int    21H
  1534.     mov    dx,dv_ms3
  1535.     mov    ah,9
  1536.     int    21H
  1537. ;
  1538. endif
  1539. ;
  1540.     pop    dx
  1541.     sti
  1542.     lds    bx,cs:DWORD PTR    ptrsav
  1543.     mov    WORD PTR 14[bx],OFFSET con$init    ; yes
  1544.     mov    16[bx],cs
  1545.     jmp    exit
  1546. ;
  1547. signon    DB    27,'[2J'
  1548.     DB    27,'[1;20H',27,'p'
  1549.     DB    '                               '
  1550.     DB    27,'[2;20H'
  1551.       DB    '      CHARTER SOFTWARE LTD     '
  1552.     DB    27,'[3;20H'
  1553.     DB    '                               '
  1554.     DB    27,'q',27,'[5;17H'
  1555.     DB    'ANSI/VT52 Terminal V 2.1: 12th DEC 1987'
  1556.     DB    27,'[7;17H'
  1557.     DB    '  For PC, XT, AT and compatibles only'
  1558.     DB    27,'[8;17H'
  1559.     DB    '$'    
  1560. ;
  1561. if    tracker
  1562. ;
  1563. ;
  1564. mb_mess    DB    'RB2 Trackerball $'
  1565. sm_mess    DB    'Microsoft Mouse $'
  1566. ;
  1567. ld_ok    DB    'installed, using $'
  1568. ld_bad    DB    27,'punable to access',27,'q $'
  1569. ;
  1570. c1_mess    DB    'COM1',13,10,10,'$'
  1571. c2_mess    DB    'COM2',13,10,10,'$'
  1572. p1_mess    DB    'LPT1',13,10,10,'$'
  1573. p2_mess    DB    'LPT2',13,10,10,'$'
  1574. ;
  1575. dv_ms1    DW    0
  1576. dv_ms2    DW    0
  1577. dv_ms3    DW    0
  1578. ;
  1579. ;
  1580. sm_start:
  1581. ;
  1582. ;Hooks into device code
  1583. ;
  1584.     jmp    mouse
  1585.     jmp    minit
  1586.     jmp    mterm
  1587. ;
  1588. ;Simple interface to the Microsoft Serial Mouse, via the IBM ROM BIOS RS232
  1589. ;controls.  This returns data to the caller using a method that can be adapted
  1590. ;to other input devices:
  1591. ;
  1592. ;When called it returns:
  1593. ;
  1594. ;    AL    - 8 bits set to 0 or 1 depending on the state of buttons
  1595. ;          1 - 8 (bits 0 - 7). A one indicated the button is down
  1596. ;
  1597. ;    BX    - Count of x steps received
  1598. ;    CX    - Count of y steps received
  1599. ;
  1600. ;
  1601. mouse    PROC    NEAR
  1602. ;
  1603.     xor    bx,bx            ; prepare return registers
  1604.     xor    cx,cx
  1605.     call    status            ; get COM1 status
  1606.     and    al,1            ; any bytes waiting
  1607.     jnz    got_one
  1608.     jmp    no_mouse        ; nothing received, go back to caller
  1609. got_one:
  1610.     call    c1_dat            ; read a byte
  1611.     test    al,40H            ; true if this is start of the sequence
  1612.     jnz    rd_mouse        ; yes, get the mouse data
  1613.     jmp    no_mouse
  1614. rd_mouse:
  1615.     push    ax            ; save for later
  1616.     call    c1_dat            ; two more chars should be coming
  1617.     mov    bl,al            ; x movement
  1618.     call    c1_dat
  1619.     mov    cl,al            ; y
  1620. ;
  1621. ;now see which buttons are pressed - give the left one priority
  1622. ;
  1623.     pop    dx            ; get first byte into dl
  1624.     mov    al,dl            ; take copy to check for button release
  1625.     and    dl,30H            ; don't xor it if none there, else we
  1626.     jz    not_lst            ; will get the last one pressed again!
  1627.     xor    dl,last_b        ; previous button settings
  1628. not_lst:
  1629.     mov    last_b,al        ; save for next time
  1630.     xor    dh,dh            ; keep button byte in here
  1631.     test    dl,20H            ; true if left button (1)
  1632.     jz    no_left
  1633.     or    dh,1            ; set first button bit
  1634. no_left:
  1635.     test    dl,10H            ; right button (3): tball compatability
  1636.     jz    no_right
  1637.     or    dh,4
  1638. no_right:
  1639.     mov    dl,al            ; get original flag byte back
  1640.     test    dl,03H            ; negative x movement
  1641.     jz    xv_ok
  1642.     mov    ax,40H            ; numbers are 7 bit twos complement
  1643.     sub    ax,bx
  1644.     xor    bx,bx
  1645.     sub    bx,ax            ; make into a 16 bit twos comp number
  1646. xv_ok:
  1647.     test    dl,0CH            ; negative y (= + y in cartesian terms)
  1648.     jz    yv_pos
  1649.     mov    ax,40H
  1650.     sub    ax,cx
  1651.     jmp    SHORT yv_ok
  1652. yv_pos:
  1653.     xor    ax,ax
  1654.     sub    ax,cx
  1655. yv_ok:
  1656.     mov    cx,ax
  1657.     mov    al,dh
  1658.     xor    ah,ah
  1659.     jmp    SHORT all_done
  1660. no_mouse:
  1661.     xor    ax,ax
  1662. all_done:
  1663.     ret
  1664. ;
  1665. status    PROC    NEAR
  1666. ;
  1667.     mov    dx,io_port        ; read COM? status
  1668.     add    dx,5
  1669.     in    al,dx
  1670.     ret
  1671. ;
  1672. status    ENDP
  1673. ;
  1674. c1_dat    PROC    NEAR
  1675. ;
  1676.     push    cx            ; time out if nothing received
  1677.     xor    cx,cx            ; to avoid lockup
  1678. wt_dat:
  1679.     dec    cx
  1680.     jcxz    no_dat
  1681.     call    status            ; call it a few times to give
  1682.     call    status            ; reasonable loop
  1683.     call    status
  1684.     call    status
  1685.     and    al,1
  1686.     jz    wt_dat
  1687.     mov    dx,io_port        ; COM? data
  1688.     in    al,dx
  1689.     jmp    SHORT dat_in
  1690. no_dat:
  1691.     xor    ax,ax
  1692. dat_in:
  1693.     pop    cx
  1694.     ret
  1695. ;
  1696. c1_dat    ENDP
  1697. ;
  1698. mouse    ENDP
  1699. ;
  1700. minit    PROC    NEAR
  1701. ;
  1702. ;
  1703. ;Set COM1 baud rate etc for the mouse
  1704. ;
  1705.     mov    ax,82H            ; 1200 baud, 7 bits, 1 stop, no parity
  1706.     mov    dx,io_chan        ; contains 0 for COM1, 1 for COM2
  1707.     int    14H
  1708. ;
  1709. ;mouse needs RTS and DTR on, so we have to program those directly using data
  1710. ;from the ROM BIOS area
  1711. ;
  1712.     push    ds
  1713.     push    dx
  1714.     mov    dx,40H            ; IBM data segment
  1715.     mov    ds,dx
  1716.     mov    dx,cs:io_port        ; word holding port address selected
  1717.     or    dx,dx            ; Z if no serial card there
  1718.     jz    m_nogo
  1719.     add    dx,4            ; point to modem control register
  1720.     mov    al,3            ; enable RTS and CTS
  1721.     out    dx,al
  1722. m_nogo:
  1723.     pop    dx
  1724.     pop    ds
  1725.     ret
  1726. ;
  1727. minit    ENDP
  1728. ;
  1729. mterm    PROC    NEAR
  1730. ;
  1731.     ret                ; restore any initial host state
  1732. ;
  1733. mterm    ENDP
  1734. ;
  1735. sm_end:
  1736. ;
  1737. tb_start:
  1738. ;
  1739. ;Hooks into trackerball driver
  1740. ;
  1741.     jmp    tball
  1742.     jmp    tbinit
  1743.     jmp    tbterm
  1744. ;
  1745. ;
  1746. ;It is possible to use all the status I/O lines on the IBM standard printer
  1747. ;port as inputs, by setting them all to 0 and then just reading them back.
  1748. ;
  1749. ;This allows us to obtain the seven lines needed to poll the trackerball.
  1750. ;
  1751. ;The connections and ports are as follows:
  1752. ;
  1753. ;    Port Pin    Signal        Trackball signal    Port bit
  1754. ;
  1755. ;       1        /strobe            X1        3BE/37A    0
  1756. ;       14        /AutoFeed        X2        3BE/37A 1
  1757. ;       16*        /init            Y1        3BE/37A    2
  1758. ;       17        /select            Y2        3BE/37A 3
  1759. ;       15*        /error            L        3BD/379 3
  1760. ;       13*        select            M        3BD/379 4
  1761. ;       12*        P.End            R        3BD/379 5
  1762. ;
  1763. ; The pins marked * are presented in the read port in the same sense as the
  1764. ; actual signals, the others are inverted, hence these bits need to be turned
  1765. ; around as necessary to get the actual data.
  1766. ;
  1767. ;
  1768. ;
  1769. ;This function takes no parameters and returns no value, it simply
  1770. ;programs the IBM status lines to be a inputs
  1771. ;
  1772. tbinit    PROC    NEAR
  1773. ;
  1774.                 ;NOTE other pins are already inputs
  1775.     mov    dx,io_port    ;assume mono/printer adapter for now
  1776.     add    dx,2
  1777.     mov    al,04H        ;set all pins as inputs (16 is not inverted)
  1778.     out    dx,al
  1779.     ret
  1780. ;
  1781. tbinit    ENDP
  1782. ;
  1783. ;
  1784. ;Restore the parallel port to normal use
  1785. ;
  1786. tbterm    PROC    NEAR
  1787. ;
  1788.     mov    dx,io_port        ;reset port to power up defaults
  1789.     add    dx,2
  1790.     mov    al,0BH
  1791.     out    dx,al
  1792.     ret
  1793. ;
  1794. tbterm    ENDP
  1795. ;
  1796. ;
  1797. ;This routine performs two functions, it first scans the trackerball keys.
  1798. ;If any are pressed, it waits for them to be released and then returns with
  1799. ;the pattern (active high). The trackerball itself is then examined, the
  1800. ;program determines the direction of rotation and returns this as an x,y
  1801. ;movement.  The speed sensing used in the direct driver is not used here,
  1802. ;otherwise a quick spin might produce 256 movement codes in one go!
  1803. ;
  1804. ;Returns the same data as the mouse driver above
  1805. ;
  1806. tball    PROC    NEAR
  1807. ;
  1808. timval    equ    020H
  1809. ;
  1810. ;
  1811.     xor    si,si
  1812.     xor    di,di
  1813.     xor    bx,bx        ;clear ball directions
  1814. retry:
  1815.     or    si,si        ;any movement yet recorded?
  1816.     jz    tst_di
  1817.     jmp    goback        ;yes!
  1818. tst_di:
  1819.     or    di,di
  1820.     jnz    goback
  1821. nokeys:
  1822.     mov    dx,io_port    ;input port address
  1823.     inc    dx
  1824.     in    al,dx        ;get current settings
  1825.     and     al,38H    
  1826.     xor    al,38H        ;non - zero if any keys pressed
  1827.     mov    cl,3
  1828.     shr    al,cl        ;get into correct bit positions
  1829.     or    al,al        ;see if any pressed
  1830.     mov    dl,al
  1831.     jz    non_pr        ;don't xor with last val if none pressed
  1832.     xor    dl,last_b    ;make code wait for release on next passes
  1833. non_pr:
  1834.     mov    last_b,al    ;save value
  1835.     mov    key,dl        ;save button value for end
  1836. balls:                ;scan tracker ball
  1837. ;
  1838.     mov    dx,io_port
  1839.     inc    dx
  1840.     inc    dx
  1841.     in    al,dx        ;fetch ball status
  1842.     xor    al,0BH        ;get all bits into the same sense (see above)
  1843.     and    al,5        ;examine x1 and y1
  1844.     mov    ah,al        ;save current x1 and y1
  1845.     mov    count,timval    ;used to give time for a transition to occur
  1846. ballp:
  1847.     dec    count
  1848.     jz    goback        ;fed up with waiting
  1849.     in    al,dx
  1850.     xor    al,0BH
  1851.     mov    cl,al        ;save result
  1852.     and     al,5
  1853.     cmp    ah,al        ;wait for a transition
  1854.     jz    ballp
  1855. ;
  1856. ;we have now scanned a transition, so we can find out the direction the ball
  1857. ;was moving in from the quadrature square waves
  1858. ;
  1859.     xor    al,ah        ;zero if both same
  1860.     push    ax        ;save for later
  1861.     and    al,1        ;check x1 first
  1862.     jz    testy1        ;no change in x1
  1863.     test    cl,1        ;low to high transition on x1?
  1864.     jz    xhtol        ;no
  1865.     test    cl,2        ;if x2 high we are moving left
  1866.     jnz    xleft1
  1867. xleft2:
  1868.     inc    si
  1869.     jmp    SHORT testy1
  1870. xhtol:
  1871.     test    cl,2        ;if x2 high we are moving right
  1872.     jnz    xleft2
  1873. xleft1:
  1874.     dec    si
  1875. testy1:
  1876.     pop    ax
  1877.     and    al,4        ;see if y1 changed
  1878.     jz    goback    
  1879.     test    cl,4        ;low to high transition on y1?
  1880.     jz    yhtol        ;no
  1881.     test    cl,8        ;if y2 high we are moving up
  1882.     jz    yup2
  1883. yup1:
  1884.     inc    di
  1885.     jmp    SHORT goback
  1886. yhtol:
  1887.     test    cl,8        ;if y2 high we are going down
  1888.     jz    yup1
  1889. yup2:
  1890.     dec    di
  1891. goback:                ;something somewhere may have been read
  1892.     mov    bx,si        ;x movement
  1893.     mov    cx,di        ;y
  1894.     mov    al,key        ;get buttons
  1895.     xor    ah,ah
  1896.     ret
  1897. ;
  1898. ;
  1899. tball    ENDP
  1900. ;
  1901. ;
  1902. tb_end:
  1903. ;
  1904. ;
  1905. endif
  1906. ;
  1907. ;
  1908. codeseg    ENDS
  1909.     END
  1910. ;
  1911.