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

  1.     page    66,132
  2. ;******************************** MKEY17.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    box_shrink:far
  14.     extrn    key_read:far
  15.     extrn    key_decode:far
  16.     extrn    make_sound:far
  17.     extrn    is_alpha:far
  18.     extrn    get_string:far
  19.     extrn    DEC_STR_TO_WORD:far
  20.     extrn    message:far
  21.     extrn    posn_to_adr:near
  22.     extrn    adr_to_posn:near
  23.     extrn    $vertical_repeat_chr:near
  24.     extrn    lib_info:byte
  25.     extrn    msg_text_color:byte
  26.     extrn    msg_hyper_color:byte
  27.     extrn    bar_select_color:byte
  28.     extrn    bar_text_color:byte
  29.     extrn    key_flags:byte
  30. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  31. ;---window__edit-- database
  32.  
  33. buffer_end    dw    0    ;offset of last legal char
  34.  
  35. hr_text1    db    ' This word can not be selected because it has one of'
  36.         db    ' the following problems: 1)word does no start with a'
  37.         db    ' space 2)word does not end with a space 3)illegal'
  38.         db    ' character appears in this word.',0
  39.  
  40. hr_text2    db    'What record number should be triggered here',0
  41.  
  42. hr_text3    db    'This is an existing hyper word.',0dh,0ah
  43.         db    'Enter new record# or zero to delete this trigger',0
  44.  
  45. hr_text4    db    'Hyper record# out of range.  Legal range is 1-221',0
  46.  
  47. hr_buf        db    8 dup (0)            
  48. hr_rec        db    0        ;record # for hyper entry 1-221
  49. dirty_flag    db    0        ;set if changes made
  50. comment 
  51. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -(MOUSE/KEY)
  52. WINDOW_EDIT - edit text within window
  53. ;
  54. ;  inputs:  bx = window frame size (bh-rows bl=columns)
  55. ;           dx = window position (dh=row dl=column)
  56. ;        ds:si = data for window
  57. ;           cx = size of data buffer (must be larger than window by 20%)
  58. ;           
  59. ;  outputs:    ah = -1 (abort key pressed)
  60. ;               al = last key press if normal exit
  61. ;               carry set = changes make to buffer
  62. ;              
  63. ;  processing:  1. display window data with cursor, then respond
  64. ;                  to edit keys:  ctrl-c  = abort
  65. ;                                 Enter   = break this line
  66. ;                                 ESC     = exit edit mode
  67. ;                                 right   = cursor right
  68. ;                                 left    = cursor left
  69. ;                                 up      = cursor up
  70. ;                                 down    = cursor down
  71. ;                                 home    = cursor to left edge
  72. ;                                 end     = cursor to right edge
  73. ;                                 del     = delete char. under cursor
  74. ;                                 back    = delete & move back
  75. ;                                 F1      = hyper word select
  76. ;
  77. ; note:  Normal ascii characters are entered into the buffer and
  78. ;        the buffer updated.  The state of INS key determines
  79. ;        if characters are inserted or overtype occurs.  Illegal
  80. ;        key cause a beep and are ignored.
  81. ;* * * * * * * * * * * * * *
  82. 
  83.     public    window_edit
  84. window_edit    proc    far
  85.     apush    bx,cx,dx,si,di,es    
  86.     call    box_shrink        ;compute
  87.  
  88.     dec    cx
  89.     mov    cs:buffer_end,cx    ;compute
  90.     add    cs:buffer_end,si    ;  end of buffer offset
  91.     mov    di,si
  92.     mov    cs:key_flags,0        ;clear flags in key_decode
  93. ;
  94. ; bx=box size dx=box location  ds=buffer segment
  95. ;    
  96. we_loop:
  97.     call    window_cstring
  98.     call    key_read
  99.     apush    bx,si
  100.     mov    si,offset decode_table
  101.     call    key_decode
  102.     mov    bp,bx            ;get processing ptr
  103.     apop    si,bx
  104.     cmp    cx,-1
  105.     jne    do_process
  106.     jmp    can_not_do        ;jmp if illegal key press
  107. do_process:    
  108.     mov    cs:cursor_buf_ptr,di
  109.     jmp    bp            ;go to correct processing
  110. ;
  111. ; remove cursor from box
  112. ;    
  113. we_exit:push    ax
  114.     add    dx,word ptr cs:cursor_column    ;compute cursor location
  115.     call    posn_to_adr
  116.     mov    al,cs:msg_text_color
  117.     inc    di
  118.     mov    byte ptr es:[di],al    ;remove cursor
  119.     pop    ax
  120.     apop    es,di,si,dx,cx,bx
  121.     rcl    cs:dirty_flag,1        ;set carry if changes were make
  122.     ret        
  123.     
  124. window_edit    endp
  125.  
  126. ;-----------------------------------------------------------------------------
  127. ; The following table is used by KEY_DECODE to scan for special keys
  128. ; and determine the processing needed.
  129. ;
  130. DECODE_TABLE    LABEL    BYTE
  131.     db    03h        ;ascii code - control-c
  132.     db    00h        ;extended flag
  133.     dw    abort_key    ;
  134.  
  135.     db    0dh
  136.     db    0
  137.     dw    enter_key
  138.  
  139.     db    1bh
  140.     db    0
  141.     dw    escape_key
  142.  
  143.     db    4dh
  144.     db    1
  145.     dw    right_arrow_key
  146.  
  147.     db    4bh
  148.     db    1
  149.     dw    left_arrow_key
  150.  
  151.     db    48h
  152.     db    1
  153.     dw    up_arrow_key
  154.  
  155.     db    50h
  156.     db    1
  157.     dw    down_arrow_key
  158.     
  159.     db    47h
  160.     db    1
  161.     dw    home_key
  162.  
  163.     db    4fh
  164.     db    1
  165.     dw    end_key
  166.  
  167.     db    53h
  168.     db    1
  169.     dw    delete_key
  170.  
  171.     db    08h
  172.     db    0
  173.     dw    backspace_key
  174.  
  175.     db    49h            ;PGDN
  176.     db    1
  177.     dw    page_key
  178.  
  179.     db    51h            ;PGUP
  180.     db    1
  181.     dw    page_key
  182.  
  183.     db    52h
  184.     db    1
  185.     dw    we_loop            ;ignore the insert key
  186.  
  187.     db    3bh
  188.     db    1
  189.     dw    hyper_request
  190.  
  191.     dw    -1        ;end of table
  192.     dw    normal_key    ; last entry is normal key processing
  193.     
  194. ;-----------------------------------------------------------------------------
  195. ;KEY_PROCESSING: process key press as decoded using DECODE_TABLE
  196. ;  inputs: al = ascii code
  197. ;          ah = extended flag or -1 if bad key (bad key handled previously)
  198. ;          DS:SI = buffer top
  199. ;          ds:di = cursor posn
  200. ;          bx=box size
  201. ;          dx=box location
  202. ;-----------------
  203. abort_key:
  204.     mov    ah,-1        ;flag abort state
  205. page_key:
  206.     jmp    we_exit
  207. ;------------------
  208. enter_key:
  209.     mov    ah,cs:cursor_row
  210.     inc    ah
  211.     cmp    ah,bh            ;check if curosr at bottom of window
  212.     jne    enter_key2        ;  jmp if cr/lf ok
  213. ;
  214. ; simulate a cr/lf by clearing to end of buffer
  215. ;
  216.     push    di
  217.     push    ds
  218.     pop    es
  219.     mov    al,0
  220. ek_loop:    
  221.     stosb
  222.     cmp    di,cs:buffer_end
  223.     jne    ek_loop
  224.     call    insert_char
  225.     pop    di
  226.     jmp    we_loop
  227. enter_key2:
  228.     push    di
  229.     call    insert_char
  230.     pop    di
  231.     inc    di
  232.     mov    al,0ah
  233.     call    insert_char
  234.     jmp    we_loop
  235. ;------------------
  236. escape_key:
  237.     mov    ah,-1
  238.     jmp    we_exit
  239. ;------------------
  240. right_arrow_key:
  241.     call    cursor_right
  242.     jmp    we_loop
  243. ;------------------
  244. left_arrow_key:
  245.     call    cursor_left
  246.     jmp    we_loop
  247. ;-----------------
  248. up_arrow_key:
  249.     cmp    cs:cursor_row,0
  250.     je    can_not_do        ;jmp if at top already
  251.  
  252.     mov    bp,cs:cursor_line_tbl
  253.     sub    bp,size line_struc    ;move up one line
  254.     jmp    up_down_common
  255. ;-----------------
  256. down_arrow_key:
  257.     mov    ah,cs:cursor_row
  258.     inc    ah
  259.     cmp    ah,bh            ;check if this is last line
  260.     je    can_not_do        ;  jmp if on last line
  261. ;
  262. ; check if the next line exists
  263. ;
  264.     mov    bp,cs:cursor_line_tbl
  265.     mov    ax,cs:[bp.line_start]    ;get cursor line start
  266.     add    bp,size line_struc    ;move to previous entry
  267.     cmp    ax,cs:[bp.line_end]
  268.     je    can_not_do        ;jmp if no next line avail
  269. up_down_common:
  270.     mov    di,cs:[bp.line_start]
  271.     mov    al,cs:cursor_column
  272.     mov    ah,0
  273.     add    di,ax
  274. uak_adjust:    
  275.     cmp    di,cs:[bp.line_end]
  276.     jbe    uak_exit        ;jmp if new cursor posn ok
  277.     dec    di
  278.     jmp    uak_adjust
  279. uak_exit:    
  280.     jmp    we_loop
  281. ;-----------------
  282. home_key:
  283.     mov    di,si
  284.     jmp    we_loop
  285. ;-----------------
  286. end_key:
  287.     mov    al,bh            ;get rows in display
  288.     dec    al
  289.     mov    ah,(size line_struc)
  290.     mul    ah
  291.     add    ax,offset line_table
  292.     mov    di,ax
  293.     mov    di,cs:[di.line_end]
  294. ek_done:jmp    we_loop
  295. ;-------------------
  296. delete_key:
  297.     cmp    byte ptr ds:[di],0    ;check if char under cursor
  298.     je    can_not_do        ;jmp if no char here
  299.     cmp    byte ptr ds:[di],0dh
  300.     jne    dk_cont            ;jmp if not a cr/lf
  301.     call    fill_hole
  302. dk_cont:    
  303.     call    fill_hole
  304.     jmp    we_loop
  305. ;
  306. ; move end of string left 1 to cover deleted char. Fill zero at end
  307. ;
  308. fill_hole:
  309.     apush    si,di
  310.     mov    si,ds
  311.     mov    es,si
  312.     
  313.     mov    si,di
  314.     inc    si
  315.     mov    cx,cs:buffer_end
  316.     sub    cx,di
  317.     inc    cx
  318.     cld
  319.     rep    movsb
  320.     mov    byte ptr [di],0        ;put zero at end
  321.     mov    cs:dirty_flag,80h    ;set changes make flag
  322.     apop    di,si
  323.     ret
  324. ;-------------------
  325. backspace_key:
  326.     cmp    di,si
  327.     je    can_not_do        ;jmp if at top left edge
  328.     call    cursor_left
  329.     jmp    delete_key
  330.  
  331. ;-------------------
  332. normal_key:
  333.     push    es
  334.     sub    cx,cx
  335.     mov    es,cx
  336.     test    byte ptr es:[417h],80h
  337.     pop    es
  338.     jnz    insert_mode
  339. ;
  340. ; keyboard is in overtype mode
  341. ;
  342.     mov    byte ptr ds:[di],al    ;store char
  343.     mov    cs:dirty_flag,80h    ;set changes make flag
  344.     jmp    right_arrow_key
  345. ;
  346. ; keyboard is in insert mode
  347. ;
  348. insert_mode:
  349.     call    insert_char
  350.     cmp    al,0dh
  351.     jne    im_exit
  352.     mov    al,0ah
  353.     call    insert_char
  354.     dec    di
  355. im_exit:jmp    we_loop
  356. ;-------------------
  357. ;
  358. ; The F1 key was pressed, check if:
  359. ;   1. the cursor presently points at a hyper entry.
  360. ;   2. the cursor word is not a possible hyper entry.
  361. ;   3. if not 1 or 2 ask for record # and insert hyper
  362. ;
  363. ;  inputs: al = ascii code
  364. ;          ah = extended flag or -1 if bad key (bad key handled previously)
  365. ;          DS:SI = buffer top
  366. ;          ds:di = cursor posn
  367. ;          bx=box size
  368. ;          dx=box location
  369. ;
  370. hyper_request:
  371.     push    di
  372.     mov    ah,0            ;force normal char. state
  373.     mov    al,byte ptr ds:[di]    ;get char under the cursor
  374.     call    is_alpha        ;check if pointing at alpha
  375.     jnc    hr_scan            ; jmp if alpha
  376.     cmp    byte ptr [di],'-'
  377.     je    hr_scan
  378.     jmp    hr_msg            ;jmp if illegal hyper word
  379. ;
  380. ; scan the word to verify it starts and ends with a space
  381. ;    
  382. hr_scan:
  383.     inc    di
  384.     mov    al,byte ptr [di]
  385.     call    is_alpha
  386.     jnc    hr_scan            ;loop if normal alpha
  387.     cmp    al,'-'
  388.     je    hr_scan            ;loop if legal char
  389.     cmp    al,' '
  390.     jne    hr_msg            ;jmp if illegal hyper word
  391. ;
  392. ; now scan back to see if word starts with a space
  393. ;
  394. hr_scan2:
  395.     dec    di
  396.     mov    al,byte ptr [di]
  397.     call    is_alpha
  398.     jnc    hr_scan2        ;loop if normal alpha
  399.     cmp    al,'-'
  400.     je    hr_scan3        ;loop if legal char
  401.     cmp    byte ptr [di-1],1fh
  402.     je    hr_hyper         ;jmp if existing hyper word
  403.     cmp    al,' '
  404.     jne    hr_msg            ;jmp if illegal hyper word
  405. ;
  406. ; we have scanned this word and it is a possible hyper word, ask for record#
  407. ;
  408. hr_scan3:
  409.     inc    di
  410.     push    si
  411.     mov    si,offset hr_text2
  412.     call    get_hyper_num        ;get rec# to -ax- and to hr_rec
  413.     pop    si
  414.     cmp    ax,0
  415.     je    hr_msg2            ;jmp if illegal rec#
  416.     cmp    ax,221
  417.     ja    hr_msg2
  418. ;
  419. ; we now have the hyper record# in -ax- and also stored at hr_rec
  420. ;
  421.     mov    al,1fh
  422.     call    insert_char        ;put trigger char in message
  423.     mov    al,cs:hr_rec
  424.     add    al,21h            ;21h=record# 1
  425.     call    insert_char
  426.     pop    di
  427.     add    di,2
  428.     jmp    hr_exit2
  429. ;
  430. ; this word appears to be an existing hyper word, ask if delete or modify
  431. ;
  432. hr_hyper:
  433.     push    si
  434.     mov    si,offset hr_text3
  435.     call    get_hyper_num
  436.     pop    si
  437.     cmp    al,0
  438.     jne    hr_modify
  439. ;
  440. ; delete this hyper trigger
  441. ;
  442. hr_delete:
  443.     dec    di
  444.     call    fill_hole
  445.     call    fill_hole
  446.     pop    di
  447.     sub    di,2
  448.     jmp    hr_exit2
  449. ;
  450. ; modify this hyper trigger
  451. ;
  452. hr_modify:
  453.     cmp    ax,221
  454.     ja    hr_msg2
  455.     add    al,21h
  456.     mov    byte ptr ds:[di],al    ;stuff new hyper trigger
  457.     mov    cs:dirty_flag,80h    ;signal changes make
  458.     jmp    hr_exit    
  459. ;
  460. ; the entered record# is out of range
  461. ;
  462. hr_msg2:push    si
  463.     mov    si,offset hr_text4
  464.     call    hr_warning
  465.     pop    si
  466.     jmp    hr_exit
  467. ;
  468. ; this word can not be a hyper word because:
  469. ;         1. it does not start and end with a space
  470. ;         2. it contains an illegal alpha character
  471. ;
  472. hr_msg:    push    si
  473.     mov    si,offset hr_text1
  474.     call    hr_warning
  475.     pop    si
  476.     
  477. hr_exit:
  478.     pop    di
  479. hr_exit2:    
  480.     jmp    we_loop    
  481. ;-------------------
  482. can_not_do:
  483.     apush    ax,bx,dx
  484.     mov    dx,3        ;duration
  485.     mov    bx,0a0h        ;frequency
  486.     call    make_sound
  487.     apop    dx,bx,ax
  488.     jmp    we_loop
  489. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  490. ; insert_char - place one key in buffer
  491. ;  inputs: al = ascii code
  492. ;          ah = extended flag or -1 if bad key (bad key handled previously)
  493. ;          DS:SI = buffer top
  494. ;          ds:di = cursor posn
  495. ;          bx=box size
  496. ;          dx=box location
  497. ;  outputs: di = updated cursor position
  498. ;
  499. insert_char:
  500.     apush    cx,si,di,es
  501.     mov    cx,ds
  502.     mov    es,cx
  503.     
  504.     mov    cx,cs:buffer_end
  505.     sub    cx,di
  506.  
  507.     mov    di,cs:buffer_end
  508.     mov    si,di
  509.     dec    si
  510.     jcxz    ik_done
  511.     std
  512.     rep    movsb
  513.     cld
  514. ik_done:
  515.     apop    es,di,si,cx
  516.     mov    byte ptr [di],al    ;insert new key
  517.     mov    cs:dirty_flag,80h    ;signal changes made
  518.     call    cursor_right
  519.     ret
  520.       
  521. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  522. ; cursor_right - move cursor right
  523. ;  inputs: al = ascii code
  524. ;          ah = extended flag or -1 if bad key (bad key handled previously)
  525. ;          DS:SI = buffer top
  526. ;          ds:di = cursor posn
  527. ;          bx=box size
  528. ;          dx=box location
  529. ;  outputs: di = updated cursor position
  530. ;
  531. cursor_right:
  532.     mov    al,bh            ;get rows in display
  533.     dec    al
  534.     mov    ah,(size line_struc)
  535.     mul    ah
  536.     add    ax,offset line_table
  537.     mov    bp,ax
  538. ;
  539. ; bp now points to last line_table entry for our window. check
  540. ; if cursor is at end
  541. ;
  542.     cmp    bp,cs:cursor_line_tbl
  543.     jne    cr_x                ;jmp if not on last line
  544.     mov    al,cs:cursor_column
  545.     inc    al
  546.     cmp    al,bl
  547.     je    cr_exit                ;jmp if at end of window
  548. cr_x:    cmp    di,si
  549.     jne    cr_2                ;jmp if not at buffer start
  550.     cmp    byte ptr [di],0
  551.     je    cr_exit                ;jmp if at buffer start & no data
  552.     jmp    cr_1
  553. cr_2:    cmp    byte ptr [di],0            ;only allow cursor to stray
  554.     je    cr_exit                ; one position past valid data
  555.     
  556. cr_1:    cmp    byte ptr [di],0dh
  557.     jne    cr_bump
  558.     inc    di
  559. cr_bump:
  560.     inc    di    
  561. ;
  562. ; check if moving into a hyper word
  563. ;
  564.     cmp    byte ptr [di],1fh
  565.     jne    skip_hyper            ;jmp if no hyper word
  566.     add    di,2    
  567. skip_hyper:    
  568.  
  569. cr_exit:ret    
  570. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  571. ; cursor_left - move cursor right
  572. ;  inputs: al = ascii code
  573. ;          ah = extended flag or -1 if bad key (bad key handled previously)
  574. ;          DS:SI = buffer top
  575. ;          ds:di = cursor posn
  576. ;          bx=box size
  577. ;          dx=box location
  578. ;  outputs: di = updated cursor position
  579. ;
  580. cursor_left:
  581.     cmp    di,si
  582.     je    cl_exit
  583.     dec    di
  584.     cmp    byte ptr [di],0dh
  585.     je    single_skip
  586.     cmp    byte ptr [di],0ah
  587.     jne    cl_ckhyper
  588. single_skip:
  589.     dec    di    
  590. cl_ckhyper:
  591.         cmp     byte ptr [di-1],1fh
  592.     jne    cl_exit
  593.     mov    al,byte ptr [di]
  594.     sub    di,2    
  595. cl_exit:ret    
  596. ;-------------------------------------------------------------------------
  597. ; get_hyper_num - request hyper record number
  598. ;  inputs:  cs:si = message
  599. ;  output: ax = record number
  600. ;
  601. get_hyper_num:    
  602.     apush    bx,cx,dx,di,ds,es
  603.     push    cs
  604.     pop    ds
  605.     mov    bx,0740h        ;box size
  606.     mov    dx,1008h        ;box location
  607.     mov    bp,msg_save_win+msg_nokey+msg_ram+msg_disp
  608.     call    message
  609.     mov    al,cs:bar_text_color
  610.     mov    ah,cs:bar_select_color
  611.     mov    bl,gs_numbers+gs_init+gs_key_wait+gs_close
  612.     mov    dx,1416h        ;location for data entry
  613.     mov    di,offset hr_buf
  614.     mov    cx,0303h        ;length of window and buffer
  615.     push    cs
  616.     pop    es
  617.     call    get_string
  618.     mov    si,offset hr_buf
  619.     call    DEC_STR_TO_WORD
  620. ;
  621. ; -al- now has record number, insert into message
  622. ;
  623.     mov    hr_rec,al
  624.     push    ax
  625.     mov    bp,msg_restore_win+msg_nokey
  626.     call    message
  627.     pop    ax
  628.     apop    es,ds,di,dx,cx,bx
  629.     ret        
  630. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  631. ; hr_warning  -  display a warning box
  632. ;  inputs:  cs:si = message ptr
  633. ;  outputs: none
  634. ;
  635. hr_warning:
  636.     apush    bx,cx,dx,di,ds,es
  637.     mov    bx,0740h        ;box size
  638.     mov    dx,0f08h        ;box location
  639.     mov    bp,msg_save_win+msg_restore_win+msg_anykey+msg_disp+msg_ram
  640.     push    cs
  641.     pop    ds
  642.     call    message
  643.     apop    es,ds,di,dx,cx,bx
  644.     ret
  645. comment 
  646. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -(MOUSE/KEY)
  647. WINDOW_CSTRING - display text with hyper formating
  648. ;
  649. ; inputs:    DS:[SI] pointing to the string
  650. ;            ds:[di] points to cursor posn in buffer
  651. ;          dx = starting row(dh)  starting column(dl)
  652. ;          bx = box total rows(bh)  box total columns(bl)
  653. ;            AH = color attribute (must be msg_text_color)
  654. ;            
  655. ; outputs:   table line_table is prepared.
  656. ;            cursor information is updated.
  657. ;
  658. ; note:     WINDOW_CSTRING was written to be used by WINDOW_EDIT to
  659. ;           display in a window and handle hyper words.  It does word
  660. ;           wrap and handles cr/lf characters.  The window text is
  661. ;           assumed to be terminated with a null character.
  662. ;
  663. ;           Unused portions of the window are cleared.
  664. ;           
  665. ;           HYPER triggers are imbedded into the text as two bytes which are
  666. ;           encoded as follows: 
  667. ;                                first byte   1fh         <-character
  668. ;                                second byte  (record #)  <-binary value
  669. ;
  670. ;           HYPER words must begin and end with a space with the HYPER
  671. ;           trigger after the first space.  The EDREC utility program
  672. ;           is an easy way to create HYPER entires.
  673. ;           
  674. ;           The text must be in a buffer larger than the window to allow
  675. ;           for inserts.  It is possible for the text to overflow the
  676. ;           buffer slightly and not show on the display.
  677. ;           
  678. ;         The line_info table is built from text scan and is
  679. ;         available as output to callers.  Its intended use is
  680. ;         to speed processing of hyper trigger words.  The format
  681. ;         of the line_table is:
  682. ;
  683. ;         line_struc    struc
  684. ;          line_start    dw    ?    ;ptr to first char. of line
  685. ;          line_end    dw    ?    ;ptr to last char, 0=end of data 0d=cr/lf at end
  686. ;                          ;                  n=wrap occured
  687. ;          chars        db    ?    ;number of chars (minus hyper triggers, cr/lf)
  688. ;          line_no    db    ?    ;line number in range 0-24
  689. ;         line_struc    ends
  690. ;
  691. ;         line_tbl_size    equ    25
  692. ;
  693. ;         line_table    label    byte
  694. ;             line_struc<?,?,?,0>
  695. ;        line_struc<?,?,?,01>
  696. ;        line_struc<?,?,?,02>
  697. ;        line_struc<?,?,?,03>
  698. ;        line_struc<?,?,?,04>
  699. ;        line_struc<?,?,?,05>
  700. ;        line_struc<?,?,?,06>
  701. ;        line_struc<?,?,?,07>
  702. ;        line_struc<?,?,?,08>
  703. ;        line_struc<?,?,?,09>
  704. ;        line_struc<?,?,?,10>
  705. ;        line_struc<?,?,?,11>
  706. ;        line_struc<?,?,?,12>
  707. ;        line_struc<?,?,?,13>
  708. ;        line_struc<?,?,?,14>
  709. ;        line_struc<?,?,?,15>
  710. ;        line_struc<?,?,?,16>
  711. ;        line_struc<?,?,?,17>
  712. ;        line_struc<?,?,?,18>
  713. ;        line_struc<?,?,?,19>
  714. ;        line_struc<?,?,?,20>
  715. ;        line_struc<?,?,?,21>
  716. ;        line_struc<?,?,?,22>
  717. ;        line_struc<?,?,?,23>
  718. ;        line_struc<?,?,?,24>
  719. ;* * * * * * * * * * * * * *
  720. 
  721. ; The line_info table is built from text scan and is available as output
  722. ; to callers
  723. line_struc    struc
  724.  line_start    dw    ?    ;ptr to first char. of line
  725.  line_end    dw    ?    ;ptr to last char, 0=end of data 0d=cr/lf at end
  726.                  ;                  n=wrap occured
  727.  chars        db    ?    ;number of chars (minus hyper triggers, cr/lf)
  728.  line_no    db    ?    ;line number in range 0-24
  729. line_struc    ends
  730.  
  731. line_tbl_size    equ    25
  732.  
  733. line_table    label    byte
  734.     line_struc<?,?,?,0>
  735.     line_struc<?,?,?,01>
  736.     line_struc<?,?,?,02>
  737.     line_struc<?,?,?,03>
  738.     line_struc<?,?,?,04>
  739.     line_struc<?,?,?,05>
  740.     line_struc<?,?,?,06>
  741.     line_struc<?,?,?,07>
  742.     line_struc<?,?,?,08>
  743.     line_struc<?,?,?,09>
  744.     line_struc<?,?,?,10>
  745.     line_struc<?,?,?,11>
  746.     line_struc<?,?,?,12>
  747.     line_struc<?,?,?,13>
  748.     line_struc<?,?,?,14>
  749.     line_struc<?,?,?,15>
  750.     line_struc<?,?,?,16>
  751.     line_struc<?,?,?,17>
  752.     line_struc<?,?,?,18>
  753.     line_struc<?,?,?,19>
  754.     line_struc<?,?,?,20>
  755.     line_struc<?,?,?,21>
  756.     line_struc<?,?,?,22>
  757.     line_struc<?,?,?,23>
  758.     line_struc<?,?,?,24>
  759. ;
  760. ; cursor location information
  761. ;
  762. cursor_buf_ptr    dw    ?    ;ptr into text
  763. cursor_line_tbl    dw    ?    ;ptr to line_table entry
  764. cursor_win_loc    label    word
  765. cursor_column    db    ?
  766. cursor_row    db    ?
  767. ;
  768. ; text processing variabales
  769. ;
  770. win_lp_count    db    ?    ;loop count
  771.  
  772. ;------------------------
  773.     public    window_cstring
  774. window_cstring    proc    far
  775.     apush    ax,bx,cx,dx,si,di,bp,ds,es
  776.     mov    cs:cursor_buf_ptr,di
  777.     mov    cs:win_lp_count,0
  778.     mov    bp,offset line_table        ;init table ptr
  779.     mov    es,cs:lib_info.crt_seg
  780. ;
  781.     mov    cx,cs:cursor_buf_ptr
  782.     mov    cs:show_line_cursor,cx        ;setup cursor for show line
  783. ;
  784. hs_10:    mov    cx,0                ;set line length to zero
  785. hs_13:    mov    cs:[bp.line_start],si        ;save line start
  786.  
  787. hs_20:    mov    al,byte ptr [si]        ;get next char
  788.     cmp    al,0
  789.     je    hs_31                ;jmp if end of line
  790.     cmp    al,0dh
  791.     je    hs_31                ;jmp if end of line
  792.     cmp    al,0ah
  793.     je    hs_31                ;jmp if end of line
  794.         cmp     al,1fh                ;hyper trigger?
  795.     jne    hs_21                ;jmp if not hyperkey trigger
  796. ;
  797. ; we have found a hyper key entry, skip over it
  798. ;
  799.     add    si,2
  800.     jmp    hs_20
  801. ;
  802. ; we have found a normal text char, count it and check if at box edge
  803. ;
  804. hs_21:    inc    cx                ;count this char
  805.     inc    si
  806.     cmp    cl,bl                ;check if at box right edge
  807.     jne    hs_20                ;jmp if still within box
  808.  
  809.     mov    cs:[bp.chars],cl         ;save ending char. count
  810.     mov    cs:[bp.line_end],si        ;save line end ptr
  811. ;
  812. ; we have filled to right edge, check if possible wrap word at end
  813. ;
  814.     cmp    byte ptr [si],0
  815.     je    hs_24
  816.     cmp    byte ptr [si],0dh
  817.     je    hs_24
  818.     cmp    byte ptr [si],' '
  819.     jne    hs_22                ;jmp if no wrap at end
  820.     dec    si
  821.     dec    cx
  822. ;
  823. ; we have filled to the right edge of the box, now scan back for word break
  824. ;
  825. hs_22:  cmp     byte ptr [si-1],1fh
  826.     jne    hs_23                ;jmp if not hyper key
  827.     sub    si,2                ;skip over hyper key
  828.     jmp    hs_22
  829. hs_23:  cmp     byte ptr [si],' '
  830.     je    hs_30                ;jmp if char break found
  831.     jcxz    hs_24                ;jmp if no word breaks
  832.     dec    si
  833.     dec    cx
  834.     jcxz    hs_23                ;jmp if on last char.
  835.     jmp    hs_22
  836. ;
  837. ; no word breaks were found, so display line as is
  838. ;
  839. hs_24:    mov    cl,cs:[bp.chars]
  840.     jmp    hs_32
  841. ;
  842. ; si =ptr to break pnt,    cx = length of line
  843. ; Check if word follows this space char or a single char.
  844. ;
  845. hs_30:
  846.     cmp    cl,bl                ;check if at right edge
  847.     je    hs_31                ; jmp if at right edge
  848.     inc    si
  849.     inc    cx
  850. hs_31:    mov    cs:[bp.line_end],si        ;save line end
  851. hs_32:    mov    si,cs:[bp.line_start]        ;restore line start ptr
  852.     mov    cs:[bp.chars],cl        ;save length of line
  853.  
  854. hs_38:    call    posn_to_adr            ;compute starting display offset
  855.     call    show_line            ;display line & fill to end
  856. ;
  857. ; check if last line ends with cr/lf which needs to be skipped
  858. ;
  859. hs_50:    cmp    bl,cs:[bp.chars]        ;check if at right edge
  860.     je    hs_52                ; skip cr/lf check if at edge
  861.     mov    si,cs:[bp.line_end]
  862.     cmp    byte ptr ds:[si],0dh
  863.     jne    hs_52
  864.     add    si,2                ;skip over cr/lf
  865. hs_52:    inc    dh                ;move to next display line
  866. ;
  867. ; check if last line of box has been filled
  868. ;
  869.     inc    cs:win_lp_count            ;move to next row on display
  870.     add    bp,size line_struc        ;move to next table entry
  871.     cmp    cs:win_lp_count,bh        ;check if all rows displayed
  872.     jne    hs_10                ;loop till done
  873. hs_EXIT:
  874.     apop    es,ds,bp,di,si,dx,cx,bx,ax
  875.     RET
  876. window_cstring    endp    
  877. ;-----------------------------------------------------------------------------
  878. ; show_line - write hyper message block, fill to end of window, & cursor sim
  879. ;   inputs:  ds:si = string ptr
  880. ;         es:di = display location
  881. ;            cs:bp = current line_table entry
  882. ;               cx = valid character count for line
  883. ;               dx = display address (save)
  884. ;               bx = window size (save)
  885. ;           show_line_cursor - set by caller, cleared if cursor match
  886. ;  output: ds:si = ptr to next line
  887. ;          es:di = ptr to right edge of window
  888. ;--------------------------------
  889. hyper_flag    db    0    ;0=normal text    1=hyper key word display active
  890.  
  891. cur_win_column    db    ?
  892. show_line_cursor dw    0    ;cursor buffer ptr, set by caller, cleared here
  893. ;--------------------------------
  894. show_line:
  895.     mov    cs:cur_win_column,0
  896. sl_lp:    jcxz    sl_fill            ;jmp if null line or end of line
  897.     mov    al,byte ptr ds:[si]    ;get next char.
  898.     cmp    al,1fh
  899.     jne    sl_10            ;jmp if not hyper trigger
  900.     mov    cs:hyper_flag,1
  901.     add    si,2            ;!
  902.     mov    al,byte ptr ds:[si]    ;!
  903. sl_10:    cmp    al,' '            ;check if space (end of hyper mode)
  904.     jne    sl_20            ;  jmp if not space
  905.     cmp    cs:hyper_flag,0
  906.     je    sl_20            ;jmp if not hyper end
  907.     mov    cs:hyper_flag,0
  908.     
  909. sl_20:    mov    ah,cs:msg_text_color
  910.     cmp    cs:hyper_flag,0        ;check if hyper mode active
  911.     je    sl_30            ; jmp if no hyper active
  912.     mov    ah,cs:msg_hyper_color
  913. sl_30:    cmp    si,cs:show_line_cursor     ;check if cursor here
  914.     jne    sl_40            ; jmp if no cursor here
  915.     call    cursor_set
  916.     xor    ah,33h
  917. sl_40:    stosw                ;display char
  918.     inc    si            ;move to next char
  919.     dec    cx
  920.     inc    cs:cur_win_column
  921.     jmp    sl_lp
  922. ;
  923. ; fill to the end of the window and check for cursor at start of fill
  924. ;  -si- points at next line start, or cr/lf, or 0 if blank line
  925. ;
  926. sl_fill:cmp    cs:cur_win_column,bl    ;check if at right edge
  927.     je    sl_50            ; jmp if at right edge
  928. ;
  929. ; check for special case of cursor beyond last char of line or null line
  930. ; with cursor.
  931. ;    
  932.     cmp    byte ptr [si],0dh
  933.     je    sl_42            ;jmp if possible  cursor at end of line.
  934.     cmp    byte ptr [si],0
  935.     jne    sl_50            ;jmp if no cursor on blank line
  936. sl_42:    cmp    si,cs:show_line_cursor    ;check if cursor at start of fill
  937.     jne    sl_50            ;jmp if no cursor here
  938.     call    cursor_set
  939.     mov    cs:show_line_cursor,0    ;disable future cursor matches
  940.     mov    al,' '
  941.     mov    ah,cs:msg_hyper_color
  942.     stosw
  943.     inc    cs:cur_win_column
  944. sl_50:    mov    ah,cs:msg_text_color
  945.     mov    al,' '
  946. sl_60:    mov    cl,bl            ;get window size
  947.     sub    cl,cs:cur_win_column
  948.     rep    stosw
  949. sl_70:    ret
  950. ;---------------------------------
  951. cursor_set:
  952.     push    ax
  953.     mov    cs:cursor_line_tbl,bp
  954.     mov    ah,cs:cur_win_column
  955.     mov    cs:cursor_column,ah
  956.     mov    ah,cs:[bp.line_no]
  957.     mov    cs:cursor_row,ah
  958.     pop    ax
  959.     ret
  960. ;--------------------------------------------------------------------------
  961.  
  962. LIBSEG    ENDS
  963.     end
  964.