home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 5 / ctrom5b.zip / ctrom5b / PROGRAM / ASM / ALIB30B / MKEY16.ASM < prev    next >
Assembly Source File  |  1994-11-15  |  16KB  |  624 lines

  1.     page    66,132
  2. ;******************************** MKEY16.ASM *********************************
  3.  
  4. LIBSEG           segment byte public "LIB"
  5.         assume cs:LIBSEG , ds:nothing
  6.  
  7. ;----------------------------------------------------------------------------
  8. .xlist
  9.     include  mac.inc
  10.     include  common.inc
  11. .list
  12. ;----------------------------------------------------------------------------
  13.     extrn    key_if_ready:far
  14.     extrn    key_read:far
  15.     extrn    str_cleanl:far
  16.     extrn    HIDE_CURSOR:far
  17.     extrn    SHOW_CURSOR:far
  18.     extrn    is_digit:far
  19.     extrn    is_alpha:far
  20.     extrn    is_upper:far
  21.     extrn    to_upper:far
  22.     extrn    is_lower:far
  23.     extrn    to_lower:far
  24.     extrn    make_sound:far
  25.     extrn    display_string_fill:far
  26.     extrn    pick_color:byte
  27.     extrn    pick_select_color:byte
  28. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  29. ;---get_string-- database
  30.  
  31. input_color    db    0
  32. exit_color    db    0
  33.  
  34.     public    key_flags    ;used by window_edit also
  35. key_flags    db    0    ;01=numbers only 02=upper 04=lower 08=filename
  36.  
  37. starting_key_window_column db    0
  38. key_window_row         db    0
  39. key_window_length     db    0
  40. current_key_window_column db    0
  41. key_window_index      db    0
  42.  
  43. starting_key_buf_offset    dw    0
  44. key_buf_ptr        dw    0
  45. key_buf_seg        dw    0
  46. key_buf_length        dw    0
  47. key_buf_index        dw    0
  48.  
  49. last_cursor        db    0    ;column of current cursor posn
  50. comment 
  51. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -(MOUSE/KEY)
  52. GET_STRING - read string from the keyboard.
  53. ;
  54. ;inputs: es:di - point at buffer for string.  Buffer can be preloaded
  55. ;                with default display.  pad rest with zeros or spaces.
  56. ;           ah - color for edit line
  57. ;           al - color for edit line at exit time
  58. ;           ch - length of buffer
  59. ;           cl - length of window
  60. ;           dh - window row
  61. ;           dl - window column (starting)
  62. ;           bl - flag 01=numbers only 02h=upper case 04=lower case 08=filename
  63. ;             gs_numbers   equ  01h  ;get numbers only
  64. ;             gs_upper     equ  02h  ;get upper case characters
  65. ;             gs_lower     equ  04h  ;get lower case characters
  66. ;             gs_file      equ  08h  ;get filename characters only
  67. ;             gs_init      equ  10h  ;initialize (do once per string entry)
  68. ;             gs_key_wait  equ  20h  ;input keys till done or unknown key found
  69. ;             gs_key_check equ  40h  ;input key only if it is ready
  70. ;             gs_close     equ  80h  ;remove cursor and deselect string 
  71. ;
  72. ; output:   cx - size of string entered (-1=unknown key in -ax-)
  73. ;           ax - last key code if  cx=-1
  74. ;              - zero if gs_key_check and all keys processed ok
  75. ;
  76. ;  Note: The buffer length must be equal or greater than the window length
  77. ;
  78. ;        get_string is designed to operate in two modes.  The first mode
  79. ;        stays in get_string until the string is entered.  This mode requires
  80. ;        the flags: ( gs_init,gs_key_wait,gs_close) and all parameters.
  81. ;        The second mode allows get_string to poll the keyboard along with
  82. ;        other functions.  This mode can be used as follows:
  83. ;         1. call with gs_init flag and all parameters.
  84. ;         2. call with gs_key_check until string entered or abort key
  85. ;         3. call with gs_close to remove the cursor and delselect.
  86. ;        Steps 2&3 above only require the flag information in -bl- along
  87. ;        with the get_string call.
  88. ;* * * * * * * * * * * * * *
  89. 
  90.     PUBLIC    GET_STRING
  91. GET_STRING    PROC    FAR
  92.     apush    bx,dx,si,di,es
  93.     mov    key_flags,bl        ;save control flags
  94.     test    bl,gs_init
  95.     jz    gs_loop            ;jmp if init not needed
  96.          call    get_string_setup
  97. gs_loop:test    key_flags,gs_key_wait
  98.     jnz    gs_wait            ;jmp if wait for key mode
  99.     test    key_flags,gs_key_check
  100.     jz    gs_2            ;jmp if no check for key
  101.     call    KEY_IF_READY        ;get key if available
  102.     cmp    ax,0
  103.     jne    gs_1            ;jmp if key was found
  104.     mov    ah,input_color
  105.     call    key_display        ;update display
  106.     sub    ax,ax            ;clear ax
  107.     jmp    gs_2            ;go check if close    
  108. gs_wait:call    KEY_READ
  109. gs_1:    mov    si,offset decode_table
  110.     call    key_decode
  111.     cmp    cx,-1
  112.     je    gs_abort        ;jmp if illegal key press
  113.     call    key_processing
  114.     cmp    ah,-1
  115.     je    gs_abort        ;jmp if abort key
  116.     cmp    ah,2
  117.     je    gs_loop            ;jmp if error (ignore key)
  118.     cmp    ah,3
  119.     je    gs_exit            ;jmp if <Enter> key pressed
  120.     mov    ah,input_color
  121.     call    key_display
  122.     jmp    gs_loop
  123. ;
  124. ; scan string to determine length, remove trailing spaces at end of string.
  125. ;    
  126. gs_exit:
  127.     push    ds
  128.     mov    si,starting_key_buf_offset
  129.     mov    cx,key_buf_length
  130.     mov    ds,key_buf_seg
  131.     call    STR_CLEANL        ;returns trimed length in -cx-
  132.     pop    ds
  133. gs_2:
  134. gs_abort:
  135.     test    key_flags,gs_close
  136.     jz    gs_3            ;jmp if no close requested
  137.     apush    ax,cx
  138.     mov    ah,exit_color
  139.     call    key_display
  140.     call    HIDE_CURSOR
  141.     apop    cx,ax
  142. gs_3:    apop    es,di,si,dx,bx
  143.     retf        
  144. GET_STRING    ENDP
  145.  
  146. ;-----------------------------------------------------------------------------
  147. ;GET_STRING_SETUP: setup data, display window, cursor on, scan for existing
  148. ;                  string and pad end with zeros.
  149. ; inputs: es:di - point at buffer for string.  Buffer can be preloaded
  150. ;                 with default display.  pad rest with zeros or spaces.
  151. ;            ah - color for edit line
  152. ;            al - color for edit line at exit time
  153. ;            ch - length of buffer
  154. ;            cl - length of window
  155. ;            dh - window row
  156. ;            dl - window column (starting)
  157. ;            bl - flag 01=numbers only 02h=upper case 04=lower case 08=filename
  158.  
  159. GET_STRING_SETUP:
  160.     cld
  161.     mov    input_color,ah
  162.     mov    exit_color,al
  163.     
  164.     mov    key_buf_seg,es
  165.     mov    starting_key_buf_offset,di
  166.     mov    key_buf_ptr,di
  167.     mov    byte ptr key_buf_length,ch
  168.     mov    byte ptr key_buf_index,0
  169.     
  170.     mov    starting_key_window_column,dl
  171.     mov    key_window_row,dh
  172.     mov    key_window_length,cl
  173.     mov    current_key_window_column,dl
  174.     mov    key_window_index,0
  175.  
  176.     mov    al,0
  177.     mov    cx,key_buf_length
  178.     repne    scasb
  179.     mov    bx,cx            ;save count
  180.     jcxz    gss_skip1        ;jmp if buffer full without zeros
  181.     rep    stosb            ;fill remainder of buffer with zeros
  182. gss_skip1:
  183. ;
  184. ; compute length of string in buffer
  185. ;
  186.     mov    cx,key_buf_length
  187.     sub    cx,bx            ;cx=string length
  188.     dec    cx
  189.     mov    key_buf_index,cx
  190.     add    key_buf_ptr,cx
  191.     inc    cx
  192. ;
  193. ; check if we are overflowing window
  194. ;
  195.     cmp    cl,key_window_length
  196.     jb    no_window_overflow
  197.     mov    key_window_index,0
  198.     mov    key_buf_index,0
  199.     mov    di,starting_key_buf_offset
  200.     mov    key_buf_ptr,di
  201.     jmp    gss_display
  202. no_window_overflow:
  203.     dec    cl
  204.     mov    key_window_index,cl
  205.     add    current_key_window_column,cl
  206. ;
  207. ; display string
  208. ;
  209. gss_display:
  210.     mov    dl,current_key_window_column
  211.     call    SHOW_CURSOR
  212.     mov    ah,input_color
  213.     call    key_display
  214.     ret
  215. ;-----------------------------------------------------------------------------
  216. ; The following table is used by KEY_DECODE to scan for special keys
  217. ; and determine the processing needed.
  218. ;
  219. DECODE_TABLE    LABEL    BYTE
  220.     db    03h        ;ascii code - control-c
  221.     db    00h        ;extended flag
  222.     dw    abort_key    ;
  223.  
  224.     db    0dh
  225.     db    0
  226.     dw    enter_key
  227.  
  228.     db    1bh
  229.     db    0
  230.     dw    escape_key
  231.  
  232.     db    4dh
  233.     db    1
  234.     dw    right_arrow_key
  235.  
  236.     db    4bh
  237.     db    1
  238.     dw    left_arrow_key
  239.  
  240.     db    47h
  241.     db    1
  242.     dw    home_key
  243.  
  244.     db    4fh
  245.     db    1
  246.     dw    end_key
  247.  
  248.     db    53h
  249.     db    1
  250.     dw    delete_key
  251.  
  252.     db    08h
  253.     db    0
  254.     dw    backspace_key
  255.  
  256.     db    52h
  257.     db    1
  258.     dw    insert_key
  259.  
  260.     dw    -1        ;end of table
  261.     dw    normal_key    ; last entry is normal key processing
  262. comment 
  263. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -(MOUSE/KEY)
  264. KEY_DECODE - scan for special keys, determine key type and process flags.
  265. ;
  266. ; inputs: ah=key scan code
  267. ;         al=key ascii code
  268. ;      ds:si=pointer to decode table
  269. ;      key_flags - set to type of decode needed
  270. ;      
  271. ; output: if cx = 0 then,
  272. ;            al = key ascii code
  273. ;            ah = extended/nomal key flag
  274. ;            bx = processing offset (set to normal key if not in table and ah=0)
  275. ;         if cx=-1 then ax = illegal key
  276. ;
  277. ; note:   All keys not in table which have extended flag set are ignored.
  278. ;         Normal keys are processed using control flag supplied by user.
  279. ;* * * * * * * * * * * * * *
  280. 
  281.     public    key_decode
  282. KEY_DECODE    proc    far
  283.     xor    cx,cx            ;preload exit code (success)
  284. kd_loop:
  285.     cmp    word ptr cs:[si],-1
  286.     je    kd_srch_end
  287.     cmp    word ptr cs:[si],ax
  288.     je    kb_got_one
  289.     add    si,4            ;move to next entry
  290.     jmp    kd_loop
  291. ;
  292. ; found a key in the table.  cs:[si+2] contains the processing offset
  293. ;
  294. kb_got_one:
  295.     mov    bx,word ptr cs:[si+2]
  296.     jmp    kb_end1
  297. ;
  298. ; this key was not in the table. Check if it is legal
  299. ;
  300. kd_srch_end:
  301.     cmp    ah,0
  302.     jne    bad_key        ;jmp if bad key
  303.     mov    bx,word ptr cs:[si+2]
  304.     test    key_flags,01h    ;
  305.     jnz    numbers_only
  306.     test    key_flags,02h
  307.     jnz    upper_keys_only
  308.     test    key_flags,04h
  309.     jnz    lower_keys_only
  310.     test    key_flags,08h
  311.     jnz    file_keys_only
  312. ;
  313. ; this key needs to be returned as is.
  314. ;
  315.     jmp    kb_end1
  316. ;
  317. ; ah=0 al=ascii code 
  318. ;
  319. numbers_only:
  320.     call    IS_DIGIT
  321.     jnc    kb_end1            ;jmp if key is a number 0-9
  322.     jmp    bad_key
  323. ;
  324. ; ah=0 al=ascii code 
  325. ;
  326. upper_keys_only:
  327.     call    IS_ALPHA
  328.     jnc    kb_end1            ;jmp if not an alphabetic key
  329.     call    IS_UPPER
  330.     jnc    kb_end1            ;jmp if char is upper case
  331.     call    TO_UPPER
  332.     jmp    kb_end1
  333. ;
  334. ; ah=0 al=ascii code 
  335. ;
  336. lower_keys_only:
  337.     call    IS_ALPHA
  338.     jnc    kb_end1            ;jmp if not an allphabetic key
  339.     call    IS_LOWER
  340.     jnc    kb_end1            ;jmp if char is lower case
  341.     call    TO_LOWER
  342.     jmp    kb_end1
  343. ;
  344. ; ah=0 al=ascii code 
  345. ;
  346. file_keys_only:
  347.     jmp    kb_end1            ;allow all keys for now
  348.  
  349. bad_key:
  350. ;    mov    dx,3        ;duration
  351. ;    mov    bx,0a0h        ;tone
  352. ;    call    make_sound
  353.     mov    cx,-1
  354. ;;    mov    bx,offset normal_key
  355.     mov    bx,word ptr cs:[si+2]    ;get normal key processing routine
  356. kb_end1:
  357.     ret    
  358. key_decode    endp    
  359. ;-----------------------------------------------------------------------------
  360. ;KEY_PROCESSING: process non-exit keys, and retrun operation code
  361. ;  inputs: al = ascii code
  362. ;          ah = extended flag or -1 if bad key (bad key handled previously)
  363. ;          bx = processing offset
  364. ;  output: ah = flag 0-buffer key in -al- and adjust cursor as necessary
  365. ;                    1-cursor move only (see -bx-)
  366. ;                    2-error/ignore (sound bell if -al- has bell char)
  367. ;                    3-enter key pressed
  368. ;                  0ffh-abort key pressed -al- has key code
  369. ;          bl = 0-cursor unchanged  1-cursor right 0ffh-cursor left
  370. ;
  371. KEY_PROCESSING:
  372.     les    di,dword ptr key_buf_ptr
  373.     jmp    bx
  374. ;-----------------
  375. abort_key:
  376.     mov    ah,-1        ;flag abort state
  377.     jmp    kp_exit
  378. ;------------------
  379. enter_key:
  380.     mov    ah,3        ;flag enter key
  381.     jmp    kp_exit
  382. ;------------------
  383. escape_key:
  384.     mov    ah,-1
  385.     jmp    kp_exit
  386. ;------------------
  387. right_arrow_key:
  388.     mov    cx,key_buf_index    ;check
  389.     inc    cx
  390.     cmp    cx,key_buf_length    ; if at end of buffer
  391.     je    can_not_do        ;   jmp if at end already
  392.     cmp    byte ptr es:[di],0    ;check if at end of data
  393.     jne    rak1            ;jmp if valid ascii here
  394.         mov     byte ptr es:[di],' '    ;stuff space
  395. rak1:    inc    key_buf_ptr
  396.     inc    key_buf_index
  397.     mov    cl,key_window_index
  398.     inc    cl
  399.     cmp    cl,key_window_length
  400.     je    rak2            ;jmp if at right edge already
  401.     inc    key_window_index
  402.     inc    current_key_window_column
  403. rak2:
  404.     jmp    cursor_only_exit
  405. ;------------------
  406. left_arrow_key:
  407.     cmp    key_buf_index,0
  408.     je    can_not_do
  409.     mov    cl,key_window_index
  410.     cmp    cl,0
  411.     je    lak1            ;jmp if cursor at left edge already
  412. ;
  413. ; check if buffer index is ahead of window index and scrolling is needed
  414. ;
  415.     cmp    cl,byte ptr key_buf_index
  416.     jb    lak1            ;jmp if buffer is ahead still
  417.     dec    current_key_window_column
  418.     dec    key_window_index
  419. lak1:
  420.     dec    key_buf_index
  421.     dec    key_buf_ptr
  422.     jmp    cursor_only_exit
  423. ;-----------------
  424. home_key:
  425.     mov    key_buf_index,0
  426.     mov    cx,starting_key_buf_offset
  427.     mov    key_buf_ptr,cx
  428.  
  429.     mov    key_window_index,0
  430.     mov    cl,starting_key_window_column
  431.     mov    current_key_window_column,cl
  432.     jmp    cursor_only_exit
  433. ;-----------------
  434. end_key:
  435.     mov    cx,key_buf_length
  436.     dec    cx
  437.     mov    key_buf_index,cx
  438.     add    cx,starting_key_buf_offset
  439.     mov    key_buf_ptr,cx
  440.  
  441.     mov    cl,key_window_length
  442.     dec    cl
  443.     mov    key_window_index,cl
  444.     add    cl,starting_key_window_column
  445.     mov    current_key_window_column,cl
  446.  
  447. cursor_only_exit:
  448.     mov    ah,1        ;flag cursor move only
  449.     jmp    kp_exit
  450. ;-------------------
  451. delete_key:
  452.     cmp    byte ptr es:[di],0    ;check if char under cursor
  453.     je    can_not_do        ;jmp if no char here
  454. ;
  455. ; move end of string left 1 to cover deleted char. Fill zero at end
  456. ;
  457.     mov    cx,key_buf_length
  458.     sub    cx,key_buf_index
  459.     dec    cx
  460.     mov    si,di
  461. dk_move:
  462.     jcxz    dk_shift_done
  463.     inc    si
  464.     mov    ah,byte ptr es:[si]    ;get forward key
  465.     mov    byte ptr es:[di],ah    ;cover key to left
  466.     inc    di
  467.     loop    dk_move
  468. dk_shift_done:
  469.         mov     byte ptr es:[si],0      ;put zero at end
  470.     jmp    cursor_move_exit
  471. ;-------------------
  472. backspace_key:
  473.     call    left_arrow_key
  474.     cmp    ah,2
  475.     je    kp_exit
  476.     mov    di,key_buf_ptr        ;restore buffer ptr
  477.     call    delete_key
  478.     jmp    kp_exit
  479.  
  480. ;-------------------
  481. normal_key:
  482.     push    es
  483.     sub    cx,cx
  484.     mov    es,cx
  485.     test    byte ptr es:[417h],80h
  486.     pop    es
  487.     jnz    insert_mode
  488. ;
  489. ; keyboard is in overtype mode
  490. ;
  491.     mov    byte ptr es:[di],al    ;store char
  492.     mov    cx,key_buf_index
  493.     inc    cx
  494.     cmp    cx,key_buf_length
  495.     je    cursor_move_exit    ;jmp if at end of key buffer
  496.     call    right_arrow_key
  497.     jmp    norm_exit
  498. ;
  499. ; keyboard is in insert mode
  500. ;
  501. insert_mode:
  502.     mov    cx,key_buf_length
  503.     dec    cx
  504.     cmp    cx,key_buf_index    ;check if at end of buffer
  505.     je    im_stuff        ;go stuff char
  506. ;
  507. ; open a hole for our insert char.
  508. ;
  509.     sub    cx,key_buf_index    ;compute number of char's to right
  510.     mov    si,di
  511.     dec    si
  512.     add    si,cx
  513.     add    di,cx
  514. ;
  515. ; move from end of buffer to present position, then move our char 
  516. ;
  517. im_loop:
  518.     mov    ah,byte ptr es:[si]
  519.     mov    byte ptr es:[di],ah
  520.     dec    si
  521.     dec    di
  522.     loop    im_loop
  523.  
  524.     mov    byte ptr es:[di],al
  525.     call    right_arrow_key
  526.     jmp    norm_exit
  527.     
  528. im_stuff:
  529.     mov    byte ptr es:[di],al
  530.     
  531. norm_exit:
  532.     mov    ah,0
  533.     jmp    kp_exit
  534. ;-------------------
  535. can_not_do:
  536.     mov    dx,3        ;duration
  537.     mov    bx,0a0h        ;frequency
  538.     call    make_sound
  539.     mov    ah,2
  540.     jmp    kp_exit
  541. cursor_move_exit:
  542. insert_key:
  543.     mov    ah,1
  544. kp_exit:
  545.     ret
  546. ;-----------------------------------------------------------------------------
  547. ;KEY_DISPLAY: redisplay key input window.
  548. ;  inputs: ah = color
  549. ;  output: none
  550. ;
  551. KEY_DISPLAY:
  552.     mov    cl,key_window_index
  553.     inc    cl
  554.     cmp    cl,key_window_length    ;is cursor on left edge
  555.     jne    not_at_far_right
  556.     dec    cl
  557.     cmp    cl,byte ptr key_buf_index
  558.     je    not_at_far_right    ;jmp if normal display will work
  559. ;
  560. ; the windows is showing the right portion of the buffer and some characters
  561. ; on the left are not displayed.
  562. ; Next, determine where display should start from.
  563. ;
  564.     mov    cx,key_buf_index
  565.     sub    cl,key_window_index
  566.     mov    si,starting_key_buf_offset
  567.     add    si,cx
  568.     jmp    kd_display_out
  569.  
  570. not_at_far_right:
  571.     mov    si,starting_key_buf_offset
  572. kd_display_out:
  573.     mov    dx,word ptr starting_key_window_column
  574.     sub    ch,ch
  575.     mov    cl,key_window_length
  576.     push    ds
  577.     push    es
  578.     pop    ds
  579.     call    display_string_fill
  580.     pop    ds
  581.     add    dl,key_window_index
  582.     cmp    dl,last_cursor
  583.     je    no_change
  584.     mov    last_cursor,dl
  585. ;
  586. ; move cursor
  587. ;
  588.     mov    dh,key_window_row
  589.     mov    ah,2
  590.     mov    bh,0            ;page 0
  591.     int    10h    
  592. no_change:    
  593.     ret
  594. comment 
  595. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -(MOUSE/KEY)
  596. QGET_STRING - Quick call to get string & return when done
  597. ;
  598. ; inputs: cl = max string length (buffer length)
  599. ;         dx = display location (dh=row,dl=column)
  600. ;         es:di = pointer to buffer for data storage
  601. ;         
  602. ; output: cx = size of string entered, if -1 then illegal key (ax has key)
  603. ;         ax = if cx = -1 then cx=illegal key code
  604. ;              
  605. ; notes: This routine calls GET_STRING with some standard settings.
  606. ;        For full control use GET_STRING instead.         
  607. ;* * * * * * * * * * * * * *
  608. 
  609.     public    qget_string
  610. QGET_STRING    PROC    FAR
  611.     apush    bx,dx,si,di,ds,es
  612.     mov    ch,cl            ;set window length = string length
  613.     mov    ah,pick_select_color    ;set edit state color
  614.     mov    al,pick_color        ;set edit complete color
  615.     mov    bl,gs_init+gs_key_wait+gs_close    ;set edit flags
  616.     call    get_string
  617.     apop    es,ds,di,si,dx,bx
  618.     retf
  619. QGET_STRING    ENDP
  620. ;--------------------------------------------------------------------------
  621.  
  622. LIBSEG    ENDS
  623.     end
  624.