home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / ka9q / nan24hyc.zip / NANSI_F.ASM < prev    next >
Assembly Source File  |  1990-10-30  |  22KB  |  834 lines

  1.     page    66, 132
  2. ;----- nansi_f.asm ---------------------------------------------
  3. ; The ANSI control subroutines.
  4. ; (C) 1986 Daniel Kegel, Pasadena, CA
  5. ; May be distributed for educational and personal use only
  6. ; Each routine is called with the following register usage:
  7. ;  AX = max(1, value of first parameter)
  8. ;  Z flag is set if first parameter is zero.
  9. ;  CX = number of paramters
  10. ;  SI = offset of second parameter from CS
  11. ;  DS = CS
  12. ;  ES:DI points to the current location on the memory-mapped screen.
  13. ;  DX is number of characters remaining on the current screen line.
  14. ; The control routine is free to trash AX, BX, CX, SI, and DS.
  15. ; It must preserve ES, and can alter DX and DI if it wants to move the
  16. ; cursor.
  17. ;
  18. ; Revisions:
  19. ;  19 Aug 85: Fixed horrible bug in insert/delete line.
  20. ;  26 Aug 85: Fixed simple limit-to-one-too-few-lines bug in ins/del line;
  21. ;  anyway, it inserts 24 lines when on line 2 now.  Whether it's fixed...
  22. ;  4 Sept 85: Fixed bug created on 26 Aug 85; when limiting ins/del line
  23. ;  count, we are clearing, not scrolling; fixed BIOS call to reflect this.
  24. ;  30 Jan 86: Added EGA cursor patch
  25. ;  31 Jan 86: Disabled insert/delete char in graphics modes
  26. ;          Implemented keyboard redefinition reset
  27. ;  1 Feb 86: added video_mode and max_x test after mode set
  28. ;  8 Jul 86: got rid of code that screwed up palette
  29. ;  9 Aug 86: added set/reset mode call for snow_flag, no pseudocursor mode,
  30. ;         reset for 43 line mode, 50 line mode for ATT 6300
  31. ;  10 Aug 86: added set display page in Set Mode
  32. ;  11 Aug 86: added snow mode support for ins/del char
  33. ; c.r. henderson
  34. ;  3 mar 90: added a response to ESC[c.     Response is now 'nansi' followed
  35. ;         by a carriage return
  36. ;  30 Oct 90: crh mods merged into 2.4 by Howard Chu
  37. ;----------------------------------------------------------------
  38.  
  39.     include nansi_d.asm
  40.  
  41.     ; To nansi_p.asm
  42.     public    ansi_fn_table
  43.  
  44.     ; From nansi.asm
  45.     extrn    snow_flag:byte, pseudo_flag:byte
  46.     extrn    port_6845:word
  47.     extrn    cur_coords:word, saved_coords:word
  48.     extrn    cur_x:byte, max_x:byte
  49.     extrn    cur_y:byte, max_y:byte
  50.     extrn    sr_min_y:byte, sr_max_y:byte
  51.     extrn    cur_attrib:byte, wrap_flag:byte
  52.     extrn    xy_to_regs:near
  53.     extrn    get_blank_attrib:near
  54.     extrn    xlate_tab_ptr:word
  55.     extrn    cpr_esc:byte, cprseq:word
  56.     extrn    id_str:byte, id_end:byte, idseq:word
  57.     extrn    video_mode:byte
  58.     extrn    lookup:near
  59.     extrn    in_g_mode:near
  60.     extrn    snow_stosw:near, snow_movsw:near
  61.  
  62.     ; from nansi_p.asm
  63.     extrn    param_buffer:word    ; used in keyboard programming
  64.     extrn    param_end:word
  65.     extrn    redef_end:word
  66.  
  67. keybuf    struc                ; used in making cpr sequence
  68. len    dw    ?
  69. adr    dw    ?
  70. keybuf    ends
  71.  
  72.  
  73. ABS40    segment at 40h
  74.     org    1ah
  75. buffer_head    dw    ?    ; Used in 'flush input buffer' dos call.
  76. buffer_tail    dw    ?
  77.  
  78.     org    49h
  79. crt_mode    db    ?
  80. crt_cols    dw    ?
  81. crt_len        dw    ?
  82. crt_start    dw    ?
  83. cursor_posn    dw    8 dup (?)
  84. cursor_mode    dw    ?
  85. active_page    db    ?
  86. addr_6845    dw    ?
  87. crt_mode_set    db    ?
  88. crt_palette    db    ?
  89.  
  90. ABS40    ends
  91.  
  92. code    segment byte public 'CODE'
  93.     assume cs:code, ds:code
  94.  
  95. ;----- byteout ---------------------------------------------------
  96. ; Converts al to a decimal ASCII string (in 0..99),
  97. ; stores it at ES:DI++.     Returns DI pointing at byte after last digit.
  98. ; Destroys DL.
  99.  
  100. byteout proc    near
  101.     aam
  102.     add    ax, 3030h
  103.     xchg    ah, al
  104.     stosb
  105.     xchg    ah, al
  106.     stosb
  107.     ret
  108. byteout endp
  109.  
  110. ;----- ansi_fn_table -----------------------------------
  111. ; Table of offsets of terminal control subroutines in order of
  112. ; the character that invokes them, @..Z, a..z.    Exactly 53 entries.
  113. ; All the subroutines are defined below in this module.
  114. ansi_fn_table    label    word
  115.     dw    ic,  cup, cdn, cfw, cbk        ; @, A, B, C, D
  116.     dw    nul, nul, nul, hvp, nul        ; E, F, G, H, I
  117.     dw    eid, eil, il,  d_l, nul        ; J, K, L, M, N
  118.     dw    nul, dc,  nul, nul, nul        ; O, P, Q, R, S
  119.     dw    nul, nul, nul, nul, nul        ; T, U, V, W, X
  120.     dw    nul, nul            ; Y, Z
  121.     dw    nul, nul, id,  nul, nul        ; a, b, c, d, e     CRH 3-9-90
  122.     dw    hvp, nul, sm,  nul, nul        ; f, g, h, i, j
  123.     dw    nul, rm,  sgr, dsr, nul        ; k, l, m, n, o
  124.     dw    key, nul, ssr, scp, nul        ; p, q, r, s, t
  125.     dw    rcp, nul, nul, nul, xoc        ; u, v, w, x, y
  126.     dw    nul                ; z
  127.  
  128. ansi_functions    proc    near        ; set return type to NEAR
  129.  
  130. ;----- nul ---------------------------------------------
  131. ; No-action ansi sequence; called when unknown command given.
  132. nul:    ret
  133.  
  134. ;----- Cursor Motion -----------------------------------------------
  135.  
  136. ;-- cursor to y,x
  137. hvp:    or    al, al        ; First parameter is desired Y coordinate.
  138.     jz    hvp_yok
  139.     dec    ax        ; Convert to zero-based coordinates.
  140. hvp_yok:mov    cur_y, al
  141.     ; Get second parameter, if it is there, and set X with it.
  142.     xor    ax, ax
  143.     cmp    cx, 2        ; was there a second parameter?
  144.     jb    hvp_xok
  145.     lodsb            ; yes.
  146.     or    al, al
  147.     jz    hvp_xok
  148.     dec    ax        ; convert to zero-based coordinates.
  149. hvp_xok:mov    cur_x, al
  150.  
  151.     ; Clip to maximum coordinates.
  152. hvp_set:
  153.     mov    ax, cur_coords        ; al = x, ah = y
  154.     cmp    al, max_x
  155.     jbe    hvp_sxok
  156.         mov    al, max_x
  157.         mov    cur_x, al
  158. hvp_sxok:
  159.     cmp    ah, max_y
  160.     jbe    hvp_syok
  161.         mov    al, max_y
  162.         mov    cur_y, al
  163. hvp_syok:
  164.     ; Set values of DX and DI accordingly.
  165.     call    xy_to_regs
  166.     ret
  167.  
  168. ;-- cursor forward --
  169. cfw:    add    cur_x, al
  170.     jmp    hvp_set
  171.  
  172. ;-- cursor back -----
  173. cbk:    sub    cur_x, al
  174.     jae    cbk_ok
  175.         mov    cur_x, 0
  176. cbk_ok: jmp    hvp_set
  177.  
  178. ;-- cursor down -----
  179. cdn:    add    cur_y, al
  180.     jmp    hvp_set
  181.  
  182. ;-- cursor up -------
  183. cup:    sub    cur_y, al
  184.     jae    cup_ok
  185.         mov    cur_y, 0
  186. cup_ok: jmp    hvp_set
  187.  
  188. ;-- save cursor position --------------------------------------
  189. scp:    mov    ax, cur_coords
  190.     mov    saved_coords, ax
  191.     ret
  192.  
  193. ;-- restore cursor position -----------------------------------
  194. rcp:    mov    ax, saved_coords
  195.     mov    cur_coords, ax
  196.     jmp    hvp_set        ; Clip in case we have switched video modes.
  197.  
  198. ;-- set scolling region ----------------------------------------
  199. ; top;bottom
  200. ; default for top is 1
  201. ; default for bottom is max_y+1
  202. ; Funny things happen when cursor is outside the scrolling region.
  203. ; Need to find out what real terminals do.
  204.  
  205. ssr:    ; Set top.  Clip to 0, max_y.
  206.     or    al, al
  207.     jnz    ssr_min_nz
  208.         dec    ax        ; one-based to zero-based
  209. ssr_min_nz:
  210.     cmp    al, max_y
  211.     jb    ssr_min_ok
  212.         mov    al, sr_max_y
  213. ssr_min_ok:
  214.     mov    sr_min_y, al
  215.  
  216.     ; Set bottom.  Clip to sr_min_y, max_y.
  217.     mov    al, max_y
  218.     cmp    cx, 2        ; is 2nd parameter present?
  219.     jb    ssr_max_ok
  220.         lodsb
  221.         or    al, al
  222.         jz    ssr_max_nz    ; if already zero, don't go lower...
  223.         dec    ax        ; 1-based to 0-based
  224.         ; Clip to sr_min_y
  225. ssr_max_nz:    cmp    al, sr_min_y
  226.         ja    ssr_max_nottoosmall
  227.             mov    al, sr_min_y
  228. ssr_max_nottoosmall:
  229.         ; Clip to max_y
  230.         cmp    al, max_y
  231.         jb    ssr_max_ok
  232.             mov    al, max_y
  233. ssr_max_ok:
  234.     mov    sr_max_y, al
  235.     ret
  236.  
  237.  
  238. ;-- set graphics rendition ------------------------------------
  239. ; Modifies the color in which new characters are written.
  240.  
  241. sgr:    dec    si        ; get back pointer to first parameter
  242.     or    cx, cx        ; Did he give any parameters?
  243.     jnz    sgr_loop
  244.         mov    byte ptr [si], 0    ; no parameters, so fake
  245.         inc    cx            ; one with the default value.
  246.     ; For each parameter
  247. sgr_loop:
  248.         lodsb                ; al = next parameter
  249.         ; Search color table
  250.         push    cx
  251.         mov    cx, colors
  252.         mov    bx, offset color_table-3
  253. sgr_search:
  254.             add    bx, 3
  255.             cmp    al, byte ptr [bx]
  256.             loopnz    sgr_search    ; until match found or done
  257.         jnz    sgr_loopx
  258.     
  259.         ; If parameter named a known color, set the current
  260.         ; color variable.
  261.         mov    ax, [bx+1]
  262.         and    cur_attrib, al
  263.         or    cur_attrib, ah
  264. sgr_loopx:
  265.         pop    cx
  266.         loop    sgr_loop        ; until no more parameters.
  267.  
  268.     ; DRK 7/7/86 Removed horrible bug caused by test code being
  269.     ; left in the distribution file...
  270.     ;;--------------
  271.     ;; DRK 2/25/86    
  272.     ;; Set background color in case we enter a graphics mode
  273.     ;mov    ah, 11                ; color palette
  274.     ;mov    bh, 0                ; background color
  275.     ;mov    bl, cur_attrib
  276.     ;mov    cl, 4
  277.     ;shr    bl, cl                ; get background bits
  278.     ;int    10h                ; call video bios
  279.     ;;--------------
  280.     ret
  281.  
  282. ;-- erase in line ----------------------------------------
  283. ; Uses BIOS to scroll away a one-line rectangle
  284. eil:    push    dx
  285.     mov    cx, cur_coords
  286.     mov    dh, ch
  287.     jmp    short scrollem
  288.  
  289. ;-- erase in display -------------------------------------
  290. ; Uses BIOS to scroll away all of display
  291. eid:    jz    eid0    ; If param was originally zero, z flag is set...
  292. ;    
  293.     cmp    al, 2    ; Home and then clear to eop
  294.     je    eid2
  295. ;
  296.     cmp    al, 1    ; Clear from top of page?
  297.     jnz    eid_ignore
  298. ;
  299. eid1:    push    dx
  300.     mov    dx, cur_coords; current is lower right of this line
  301.     mov    cx, 0    ;    clear square above left of cur_coords
  302.     or    dl, dl    ;    at first char position on this line?
  303.     jz    eid1a    ;    yes, so ignore this line
  304.     sub    dl, 1    ;    blank chars b4 but not including curs lcn
  305.     call    get_blank_attrib
  306.     mov    bh, ah
  307.     mov    ax, 600h
  308.     int    10h
  309. eid1a:    cmp    dh, 0    ; On top row, if so, simply exit
  310.     jz    eidx
  311. ;
  312. ; Not on top row, must clear all above line to right of cursor psn
  313. ;
  314.     sub    dh, 1
  315.     mov    dl, max_x
  316.     call    get_blank_attrib
  317.     mov    bh, ah
  318.     jmp    eidi    ; Call int 10 to perform scroll
  319. ;
  320. ; '0' param
  321. ;
  322. eid0:    call    eil    ; Yes, clr-eop by first clearing rest of current line
  323.     mov    cx, cur_coords
  324.     cmp    ch, max_y
  325.     jz    eid_ignore    ; Just exit if last line now.
  326. ;
  327.     push    dx    ; then clearing to end of page
  328.     mov    cl, 0    ;    upper left column
  329.     add    ch, 1    ;  at next row from current
  330.     mov    dh, max_y; to bottom right row
  331.     jmp    scrollem;   then rest of page
  332. eid2:    if    cls_homes_too
  333.         mov    cur_coords, 0
  334.         call    xy_to_regs
  335.     endif
  336.     push    dx
  337.     xor    cx, cx
  338.     mov    ch, sr_min_y
  339.     mov    dh, sr_max_y
  340. scrollem:
  341.     call    get_blank_attrib
  342.     mov    bh, ah
  343.     mov    dl, max_x
  344. eidi:    mov    ax, 600h
  345.     int    10h
  346. eidx:    pop    dx
  347. eid_ignore:
  348.     ret
  349.  
  350. ;-- device status report --------------------------------
  351. ; Stuffs an escape, a left bracket, current Y, semicolon, current X,
  352. ; a capital R, and a carriage return into input stream.
  353. ; The coordinates are 1 to 3 decimal digits each.
  354.  
  355. dsr:    push    di
  356.     push    dx
  357.     push    es
  358.     mov    ax, cs
  359.     mov    es, ax
  360.     std            ; Store string in reversed order for fun
  361.     mov    di, offset cpr_esc - 2
  362.     mov    al, cur_y
  363.     inc    al        ; convert to one-based coords
  364.     call    byteout        ; row
  365.     mov    al, ';'        ; ;
  366.     stosb
  367.     mov    al, cur_x
  368.     inc    al        ; convert to one-based coords
  369.     call    byteout        ; column
  370.     mov    al, 'R'        ; R ANSI function 'Cursor Position Report'
  371.     stosb
  372.     mov    al, 13
  373.     mov    word ptr cprseq.adr, di ; save pointer to last char in string
  374.     stosb                ; send a carriage return, too
  375.     mov    ax, offset cpr_esc
  376.     sub    ax, di            ; ax is # of characters in string
  377.     mov    word ptr cprseq.len, ax ; pass info to the getchar routine
  378.     cld
  379.     pop    es
  380.     pop    dx
  381.     pop    di
  382.     ret
  383.  
  384. ;-- keyboard reassignment -------------------------------
  385. ; Key reassignment buffer is between param_end and redef_end+2, exclusive.
  386. ; When it shrinks or grows, param_end is moved.
  387. ; Format of an entry is as follows:
  388. ;   highest address -> length:word (may be 0)
  389. ;               key to replace:word     (either hi or low byte is zero)
  390. ;               .
  391. ;               .    new key value, "length" bytes long
  392. ;               .
  393. ;   lowest address  -> next entry, or free space.
  394. ; If no arguments are given, keyboard is reset to default condition.
  395. ; Otherwise, first parameter (or first two, if first is zero) defines
  396. ; the key whose value is to be changed, and the following parameters
  397. ; define the key's new, possibly zero-length, value.
  398.  
  399. key:
  400.     ; Is this a reset?
  401.     or    cx, cx
  402.     jz    key_init
  403.     ; Get the first (or first two) parameters
  404.     cld
  405.     dec    si    ; point to first param
  406.     dec    cx    ; Assume it's a fn key, get two params
  407.     dec    cx
  408.     lodsw
  409.     or    al, al    ; Is it a function key?
  410.     jz    key_fnkey
  411.         ; It's not a function key- put second param back
  412.         inc    cx
  413.         dec    si
  414. key_fnkey:
  415.     ; Key to redefine now in AX.  If it's already redefined,
  416.     ; lookup will set Z, point SI to redef string, set CX to its length.
  417.     push    di
  418.     push    es
  419.     push    cx
  420.     push    si
  421.  
  422.     std            ; moving up, must move from top down
  423.     push    ds
  424.     pop    es        ; string move must have ES=DS
  425.     call    lookup        ; rets Z if redefined...
  426.     jnz    key_newkey
  427.     ; It's already defined.     Erase its old definition- i.e., move
  428.     ; region param_end+1..SI-1 upwards CX+4 bytes, add CX+4 to param_end.
  429.     add    cx, 4
  430.     mov    bp, param_end    ; save old value in bp...
  431.     add    param_end, cx
  432.     dec    si        ; start at (SI-1)
  433.     mov    di, si
  434.     add    di, cx        ; move to (start + CX+4)
  435.     mov    cx, si
  436.     sub    cx, bp        ; length of region old_param_end+1..start
  437.     rep    movsb
  438. key_newkey:
  439.     ; Key not redefined.  See if there's enough room to redefine it.
  440.     pop    si        ; get back pointer to redef string
  441.     pop    cx        ; get back number of bytes in redef string
  442.     mov    di, param_end    ; hi byte of new redef record, hi byte of len
  443.     sub    di, 4        ; hi byte of new data field
  444.     mov    bx, di
  445.     sub    bx, cx        ; hi byte of remaining buffer space
  446.     sub    bx, 16        ; better be at least 16 bytes room
  447.     cmp    bx, param_buffer
  448.     jb    key_popem    ; nope- forget it.
  449.     ; Nothing in the way now!
  450.     mov    [di+3], cx    ; save length field
  451.     mov    [di+1], ax    ; save name field
  452.     jcxz    key_nullstring
  453. key_saveloop:            ; save data field
  454.     movsb
  455.     add    si, 2        ; input string ascending, output descending
  456.     loop    key_saveloop
  457. key_nullstring:
  458.     mov    param_end, di    ; save adr of new hi byte of free area
  459. key_popem:
  460.     pop    es
  461.     pop    di
  462.  
  463. key_exit:
  464.     cld
  465.     ret
  466.  
  467. key_init:
  468.     ; Build the default redefinition table:
  469.     ;    control-printscreen -> control-P
  470.     push    es
  471.     push    ds
  472.     pop    es
  473.     std
  474.     mov    di, redef_end
  475.     mov    ax, 1
  476.     stosw
  477.     mov    ax, 7200h    ; control-printscreen
  478.     stosw
  479.     mov    al, 16        ; control P
  480.     stosb
  481.     mov    param_end, di    ; save new bottom of redef table
  482.     pop    es
  483.     jmp    key_exit
  484.  
  485. ;---- Delete/Insert Lines -------------------------------
  486. ; AL is number of lines to delete/insert.
  487. ; Preserves DX, DI; does not move cursor.
  488.  
  489. d_l:    ; Delete lines.
  490.     mov    ah, 6            ; BIOS: scroll up
  491.     jmp    short il_open
  492.  
  493. il:    ; Insert lines.
  494.     mov    ah, 7            ; BIOS: scroll down
  495.  
  496. il_open:
  497.     ; Whether inserting or deleting, limit him to (max_y - cur_y) lines;
  498.     ; if above that, we're just clearing; set AL=0 so BIOS doesn't burp.
  499.     mov    bh, sr_max_y
  500.     sub    bh, cur_y
  501.     cmp    al, bh
  502.     jbe    il_ok            ; DRK 9/4...
  503.         mov    al, 0        ; he tried to move too far
  504. il_ok:
  505.     push    ax
  506.     call    get_blank_attrib
  507.     mov    bh, ah            ; color to use on new blank areas
  508.     pop    ax            ; AL is number of lines to scroll.
  509.  
  510.     mov    cl, 0            ; upper-left-x of data to scroll
  511.     mov    ch, cur_y        ; upper-left-y of data to scroll
  512.     push    dx
  513.     mov    dl, max_x        ; lower-rite-x
  514.     mov    dh, sr_max_y        ; lower-rite-y (zero based)
  515.     int    10h            ; call BIOS to scroll a rectangle.
  516.     pop    dx
  517.     ret                ; done.
  518.  
  519. ;-- Insert / Delete Characters ----------------------------
  520. ; AL is number of characters to insert or delete.
  521. ; Preserves DX, DI; does not move cursor.
  522. ; 8/11/86: now use snow_stosw and snow_movsw; these trash BP.
  523.  
  524. ic:    mov    ch, 1            ; 1 => swap dest & source below
  525.     jmp    short dc_ch
  526.  
  527. dc:    mov    ch, 0
  528.  
  529. dc_ch:
  530.     call    in_g_mode
  531.     jnc    dc_ret            ; | if in graphics mode, ignore.
  532.  
  533.     ; AL = number of chars to ins or del (guarenteed nonzero).
  534.     ; Limit him to # of chars left on line.
  535.     cmp    al, dl
  536.     jbe    dc_cok
  537.         mov    al, dl
  538. dc_cok:
  539.     push    di            ; DI is current address of cursor
  540.     xchg    ax, cx            ; CX gets # of chars to ins/del
  541.     push    cx            ; Stack gets # of columns to clear.
  542.  
  543.     ; Set up source = destination + cx*2, count = dx - cx
  544.     mov    ch, 0            ; make it a word
  545.     mov    si, di
  546.     add    si, cx
  547.     add    si, cx
  548.     neg    cl
  549.     add    cl, dl
  550.     mov    ch, 0            ; CX = # of words to transfer
  551.     cld                ; REP increments si & di
  552.  
  553.     ; If this is an insert, then flip transfer around in both ways.
  554.     test    ah, 1
  555.     jz    dc_noswap
  556.         xchg    di, si        ; source <-> dest
  557.         std            ; up <-> down
  558.         mov    ax, cx        ; make move over same range
  559.         dec    ax
  560.         add    ax, ax        ; AX=dist from 1st to last byte.
  561.         add    di, ax        ; Start transfer at high end of block
  562.         add    si, ax        ;  instead of low end.
  563. dc_noswap:
  564.     ; Move those characters.
  565.     push    es
  566.     pop    ds
  567.     call    snow_movsw        ; Trashes BP.
  568.     pop    cx
  569.     ; Figure out what color to make the new blanks.
  570.     call    get_blank_attrib
  571.     mov    al, ' '
  572.     ; Blank out vacated region.
  573.     call    snow_stosw
  574.  
  575.     ; All done.
  576.     cld                ; restore normal REP state and
  577.     pop    di            ;  cursor address.
  578. dc_ret: ret
  579.  
  580. ;---- identify terminal as nansi --------------- added by:  CRH on 3-9-90
  581. id:    push    di
  582.     push    dx
  583.     push    es
  584.     mov    ax, cs
  585.     mov    es, ax
  586.     mov    di, offset id_str
  587.     mov    ax, offset id_end
  588.     sub    ax, di
  589.     inc    ax
  590.     mov    word ptr idseq.len, ax ; # chars in string 'nansi-cr-'
  591.     mov    word ptr idseq.adr, di ; pass address of string to getchar
  592.  
  593. ;
  594. ; return, our work's done
  595. ;
  596.     pop    es
  597.     pop    dx
  598.     pop    di
  599.     ret
  600.  
  601. ;---- set / reset mode ---------------------------------------
  602. ; Sets graphics/text mode; also sets/resets "no wrap at eol" mode.
  603. ; 8/9/86 drk: Cleaned up, added snow flag, added reset 43 line mode,
  604. ;          ATT 6300 support, pseudocursor on/off.
  605.  
  606. sm:    mov    ah, 0ffh    ; set
  607.     jmp    short sm_rs
  608.  
  609. rm:    mov    ah, 0        ; reset
  610.  
  611. sm_rs:    cmp    al, 7        ; Wrap/nowrap?
  612.     lea    bx, wrap_flag
  613.     jz    sm_flag
  614.     cmp    al, 44        ; Snow/nosnow?
  615.     lea    bx, snow_flag
  616.     jz    sm_flag
  617.     cmp    al, 45        ; Graphics cursor or not?
  618.     lea    bx, pseudo_flag
  619.     jz    sm_flag
  620.     cmp    al, 46        ; Set display page?
  621.     jz    sm_page
  622.     cmp    al, 50        ; Set/reset 50 line mode?
  623.     jz    sm_50lines
  624.     cmp    al, 43        ; Set/reset 43 line mode?
  625.     jz    sm_43lines
  626.     jmp    sm_video    ; If none of the above, must be a screen mode.
  627.  
  628.     ;--- Set or reset simple flag ---
  629. sm_flag:
  630.     mov    byte ptr [bx], ah
  631.     ret
  632.  
  633.     ;--- Set Display Page ---
  634. sm_page:
  635.     cmp    cl, 2            ; must have 2nd arg
  636.     jb    sm_pdone
  637.  
  638.     ; Set old page cursor coordinates.
  639.     push    ds
  640.     mov    ax, abs40
  641.     mov    ds, ax
  642.     assume    ds:abs40
  643.     mov    al,active_page
  644.     cbw    
  645.     add    ax,ax
  646.     xchg    bx,ax
  647.     mov    ax,cs:cur_coords
  648.     mov    cursor_posn[bx],ax
  649.  
  650.     ; Set active page.
  651.     lods    byte ptr cs:[si]    ; Second arg = page number
  652.     mov    ah, 5
  653.     int    10h
  654.  
  655.     ; Find new page cursor coordinates.
  656.     mov    al,active_page
  657.     cbw    
  658.     add    ax,ax
  659.     xchg    bx,ax
  660.     mov    ax,cursor_posn[bx]
  661.     pop    ds
  662.     assume    ds:code
  663.     mov    cur_coords,AX
  664.  
  665. sm_pdone:
  666.     ret
  667.  
  668.     ;--- Set or Reset Lots 'O Lines mode for ATT 6300 ---
  669. sm_50lines:
  670.     test    ah, 1            ; Was it a Set command?
  671.     mov    al, video_mode
  672.     jz    sm_video        ; no- reset 50 line mode
  673.                     ; by reentering base mode.
  674.     mov    ah, 0
  675.     mov    al, 72
  676.     int    10h            ; ATT Video Bios call
  677.     mov    max_y, 49        ; assume it gets us 50 lines
  678.     jmp    short sm_home
  679.  
  680.     ;--- Set or Reset Lots 'O Lines mode for EGA ---
  681. sm_43lines:
  682.     test    ah, 1            ; Was it a Set command?
  683.     mov    al, video_mode
  684.     jz    sm_video        ; no- reset 43 line mode
  685.                     ; by reentering base mode.
  686.  
  687.     ; Only valid for the Enhanced Graphics Adaptor on
  688.     ; a monochrome display or an enhanced color display.
  689.     ; Test presence of EGA by calling BIOS fn 12h.10h.
  690.     mov    ah, 12h
  691.     mov    bx, 0ff10h
  692.     int    10h            ; bh=0-1, bl=0-3 if EGA
  693.     test    bx, 0FEFCH
  694.     jnz    sm_done            ; sorry, charlie
  695.  
  696.     ; 43 line mode only allowed in text modes, for now.
  697.     call    in_g_mode
  698.     jnc    sm_done
  699.  
  700.     mov    ah, 0            ; "Set video mode"
  701.     mov    al, video_mode        ; Re-init current mode
  702.     int    10h
  703.  
  704.     mov    ax,1112h        ; Load 8x8 font
  705.     mov    bl,0            ; (instead of 8x14)
  706.     int    10h
  707.  
  708.     mov    ax, 1200h        ; Load new printscreen
  709.     mov    bl, 20h
  710.     int    10h
  711.  
  712.     mov    ah,1
  713.     mov    cx,0707h        ; (Load cursor scan lines)
  714.     int    10h
  715.     ; | Patch; this gotten by painful observation of
  716.     ; | IBM's professional editor.    I think there's a
  717.     ; | documented bug in Video Bios's "load cursor scan line"
  718.     ; | call; try looking in latter 1985 PC Tech Journal.
  719.     mov    dx, port_6845        ; '6845' command reg
  720.     mov    al, 10
  721.     out    dx, al
  722.     jmp    $+2
  723.     inc    dx
  724.     mov    al, 7
  725.     out    dx, al            ; set cursor start line
  726.     ; Assume that gets us 43 lines.
  727.     mov    max_y, 42
  728.     mov    sr_max_y, 42
  729.     jmp    short sm_home
  730.  
  731.     ;--- Set Video Mode ---
  732. sm_video:
  733.     ; It must be a video mode.  Call BIOS.
  734.     mov    ah, 0        ; "set video mode"
  735.     int    10h
  736.     ; Assume that gets us 25 lines.
  737.     mov    max_y, 24
  738.     mov    sr_max_y, 24
  739. sm_home:
  740.     mov    sr_min_y, 0        ; setting mode clears scrolling region
  741.  
  742.     ; Read the BIOS buffer address/cursor position variables.
  743.     mov    ax, abs40
  744.     push    ds
  745.     mov    ds, ax
  746.     assume    ds:abs40
  747.     ; Find current video mode and screen size.
  748.     mov    ax,word ptr crt_mode    ; al = crt mode; ah = # of columns
  749.     pop    ds
  750.     mov    video_mode, al
  751.     dec    ah            ; ah = max column
  752.     mov    max_x, ah
  753.  
  754.     ; Since cursor may end up in illegal position, it's best to
  755.     ; just go home after switching video modes.
  756.     mov    cur_coords, 0
  757.     call    xy_to_regs
  758. sm_done:
  759.     ret
  760.  
  761. ;------- Output Character Translation ----------------------
  762. ; A decidedly nonstandard function, possibly useful for editing files
  763. ; intended to be printed by daisywheel printers with strange wheels.
  764. ; (The letter 'y' was chosen to conflict with the VT100 self-test command.)
  765. ; Usage: ESC [ #1;#2 y
  766. ; where #1 is the character to redefine
  767. ;    #2 is the new display value
  768. ; If only ESC [ #1 y is sent, character #1 is reset to its default value.
  769. ; If only ESC [ y is sent, the entire table is reset to the default value.
  770. ; (If only ESC [ #1; y is sent, character #1 is set to zero... sigh.)
  771.  
  772. xoc:    ; Xlate output character
  773.     mov    bx, xlate_tab_ptr
  774.     jcxz    xoc_reset    ; if no parameters, reset table to 1:1
  775.     dec    si        ; point to first parameter
  776.     lodsw            ; first parameter to AL, second to AH
  777.     dec    cx        ; is parameter count 1?
  778.     jnz    xoc_bothparams
  779.         mov    ah, al    ; if only one param, reset that char.
  780. xoc_bothparams:
  781.     add    bl, al
  782.     adc    bh, 0        ; bx points to entry for char AL
  783.     mov    byte ptr [bx], ah    ; change that entry
  784. xoc_done:
  785.     ret
  786.  
  787. xoc_reset:
  788.     ; Fill table with default values- i.e. 0, 1, 2, ... 255.
  789.     xor    ax, ax
  790. xoc_loop:
  791.     mov    byte ptr [bx], al
  792.     inc    bx
  793.     inc    al
  794.     jnz    xoc_loop
  795.     jmp    xoc_done
  796.  
  797. ansi_functions    endp    ; end dummy procedure block
  798.  
  799.  
  800.  
  801. ;-------- Color table -----------------------------------------
  802. ; Used in "set graphics rendition"
  803. colors    equ    22            ; number of colors in table
  804. color_table:
  805.     db    0, 000h,07h        ; all attribs off; normal.
  806.     db    1, 0ffh,08h        ; bold
  807.     db    4, 0f8h,01h        ; underline
  808.     db    5, 0ffh,80h        ; blink
  809.     db    7, 0f8h,70h        ; reverse
  810.     db    8, 088h,00h        ; invisible
  811.  
  812.     db    30,0f8h,00h        ; black foreground
  813.     db    31,0f8h,04h        ; red
  814.     db    32,0f8h,02h        ; green
  815.     db    33,0f8h,06h        ; yellow
  816.     db    34,0f8h,01h        ; blue
  817.     db    35,0f8h,05h        ; magenta
  818.     db    36,0f8h,03h        ; cyan
  819.     db    37,0f8h,07h        ; white
  820.  
  821.     db    40,08fh,00h        ; black background
  822.     db    41,08fh,40h        ; red
  823.     db    42,08fh,20h        ; green
  824.     db    43,08fh,60h        ; yellow
  825.     db    44,08fh,10h        ; blue
  826.     db    45,08fh,50h        ; magenta
  827.     db    46,08fh,30h        ; cyan
  828.     db    47,08fh,70h        ; white
  829.  
  830.  
  831. code    ends
  832.     end                ; of nansi_f.asm
  833.  
  834.