home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 5 / ctrom5b.zip / ctrom5b / PROGRAM / ASM / ALIB30B / MSG1.ASM < prev    next >
Assembly Source File  |  1994-12-01  |  18KB  |  658 lines

  1.     page    66,132
  2. ;******************************** MSG1.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    draw_box:far
  14.     extrn    dbase_read:far
  15.     extrn    window_string:far
  16.     extrn    yes_or_no:far
  17.     extrn    key_or_mouse:far
  18.     extrn    random_word2:far
  19.     extrn    dbase_init:far
  20.     extrn    dbase_close:far
  21.     extrn    save_window:far
  22.     extrn    restore_window:far
  23.     extrn    box_shrink:far
  24.     extrn    MENU_SYSTEM:far
  25.     extrn    posn_to_adr:near
  26.     extrn    adr_to_posn:near
  27.     extrn    $vertical_repeat_chr:near
  28.     extrn    lib_info:byte
  29.     extrn    msg_text_color:byte
  30.     extrn    msg_hyper_color:byte
  31. comment 
  32. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -( MESSAGE )
  33. message - boxed message display
  34. ;
  35. ; inputs:
  36. ;            bh = rows in box         (if flag msg_disp)
  37. ;            bl = columns in box      (if flag msg_disp)
  38. ;            cx = record #            (if flag msg_disp & not msg_rand)
  39. ;            dx = box upper left loc  (if flag msg_disp)
  40. ;         ds:si = ptr to file name    (if flag msg_open and not msg_ram)
  41. ;         ds:si = ptr to msg text     (if flag msg_ram and msg_open)
  42. ;            bp = flags, see equates
  43. ;            es = file selector       (if not flag msg_open)
  44. ;
  45. ; outputs:   no carry
  46. ;              es = file selector  (if no msg_close flag)
  47. ;              al = yes/no response (if msg_yesno flag was set)
  48. ;            carry
  49. ;           ax = error code      xx02 = code error, flag bits in -bp- wrong
  50. ;                  xx03 = disk read error
  51. ;                    10(decimal) = open error or file not found
  52. ;
  53. ; note:   This function displays a boxed message in various
  54. ;         formats.  All messages are found in memory or a file
  55. ;         which uses the database format for variable length ascii
  56. ;         records.  A specific message is selected by record #
  57. ;         using the database library routines.
  58. ;
  59. ;         The Hyper text mode uses a special file which is
  60. ;         formated with records compatable with the database
  61. ;         variable lenght record format.  Each record is
  62. ;         terminated with a zero.  The record can contain hyper
  63. ;         triggers to point to other topics(records).  The hyper
  64. ;         triggers consist of the following:
  65. ;
  66. ;          byte 0    space  <- the trigger word must start with a space
  67. ;          byte 1    1fh    <- the special character signals start of hyper
  68. ;          byte 2     n     <- binary number which is record# 1-255
  69. ;          byte 3+   ...    <- string which is to be highlighted trigger word
  70. ;          byte n    space  <- trigger word is ended with a space
  71. ;* * * * * * * * * * * * * *
  72. 
  73. ;-------------------------------
  74. msg_flags    dw    0    ;flags (see equates)
  75. temp_mloc    dw    0    ;display location for message
  76. temp_box_size    dw    0    ;box rows/columns
  77.  
  78. rand_pkt    dw    0    ;seed1
  79.         dw    0    ;seed2
  80.         dw    007fh    ;mask
  81.         db    1    ;method 1 or 2
  82.  
  83. msg_offset    dw    0    ;the message pointer, or filename text
  84. msg_segment    dw    0
  85.  
  86. message_fname    db    40 dup (0)
  87.  
  88. msg_rec_no    dw    0    ;record#
  89. msg_dbase_sel    dw    0    ;dbase selector
  90. ;-------------------------------
  91. ; hyper menu (top menu bar)
  92. ;
  93. hyper_menu    label    byte
  94.     db    0            ;m_flag
  95.     db    0            ;top row
  96.     db    0            ;left column
  97.     db    1            ;total rows
  98. plug_c    db    76            ;total columns
  99.     db    4            ;menu options
  100.     dw    0            ;main selection
  101.     dw    0            ;sub selection
  102. ; hyper option #0 -PREVIOUS-
  103.     db    0            ;e_count
  104.     db    0            ;e_sub_length
  105.     db    25            ;e_hot_key (alt-t)
  106.     db    14            ;e_length
  107.     dw    hyper_opt0_text        ;e_text_ptr
  108.     dw    hyper_previous         ;e_process
  109.     db    1            ;e_column
  110. hplug1    db    0            ;e_row
  111. ; hyper option #1 -FWD-BROWSE-
  112.     db    0            ;e_count
  113.     db    0            ;e_sub_length
  114.     db    33            ;e_hot_key (alt-a)
  115.     db    10            ;e_length
  116.     dw    hyper_opt1_text        ;e_text_ptr
  117.     dw    hyper_fwd        ;e_process
  118.     db    8            ;e_column
  119. hplug2    db    0            ;e_row
  120. ; hyper option #2 -BAK-BROWSE-
  121.     db    0            ;e_count
  122.     db    0            ;e_sub_length
  123.     db    48            ;e_hot_key (alt-b)
  124.     db    10            ;e_length
  125.     dw    hyper_opt2_text        ;e_text_ptr
  126.     dw    hyper_bak        ;e_process
  127.     db    15            ;e_column
  128. hplug3    db    0            ;e_row
  129. ; hyper option #3 -EXIT-HYPER-
  130.     db    0            ;e_count
  131.     db    0            ;e_sub_length
  132.     db    18            ;e_hot_key (alt-b)
  133.     db    10            ;e_length
  134.     dw    hyper_opt3_text        ;e_text_ptr
  135.     dw    hyper_exit        ;e_process
  136.     db    22            ;e_column
  137. hplug4    db    0            ;e_row
  138. ; hyper option end, dummy option
  139.     db    0            ;e_count
  140.     db    0            ;e_sub_length
  141.     db    00            ;e_hot_key (alt-b)
  142.     db    0            ;e_length
  143.     dw    0                     ;e_text_ptr
  144.     dw    0            ;e_process
  145.     db    0            ;e_column
  146.     db    0            ;e_row
  147.  
  148. hyper_opt0_text     db 'Previous-topic',0
  149. hyper_opt1_text     db 'Fwd-browse',0
  150. hyper_opt2_text     db 'Bak-browse',0
  151. hyper_opt3_text     db 'Exit-hyper',0
  152. hyper_opt4_text     label    byte    ;dummy for menu placement calc
  153.  
  154. ;-------------------------------
  155.     public    message
  156. message        proc    far
  157.     apush    bx,cx,dx,si,di,ds,es
  158.     cld
  159.     mov    cs:msg_flags,bp
  160.     mov    word ptr cs:msg_rec_no,cx    ;save record#
  161.     mov    cs:temp_mloc,dx            ;save display location
  162.     mov    cs:temp_box_size,bx        ;save box rows & colums
  163.     mov    byte ptr cs:plug_c,bl        ;save total columns in window
  164.     mov    cs:msg_dbase_sel,es
  165.     mov    cs:msg_offset,si        ;save message offset
  166.     mov    cs:msg_segment,ds        ;save message segemnt
  167.     
  168.     inc    dh
  169.     mov    cs:hplug1,dh            ;set hyper menu bar column
  170.     mov    cs:hplug2,dh
  171.     mov    cs:hplug3,dh
  172.     mov    cs:hplug4,dh
  173.  
  174.     inc    dl
  175.     mov    cs:hplug1-1,dl
  176.     add    dl,(offset hyper_opt1_text - hyper_opt0_text)+2
  177.     mov    cs:hplug2-1,dl
  178.     add    dl,(offset hyper_opt2_text - hyper_opt1_text)+2
  179.     mov    cs:hplug3-1,dl
  180.     add    dl,(offset hyper_opt3_text - hyper_opt2_text)+2
  181.     mov    cs:hplug4-1,dl
  182. ;
  183. ; move message file name to local storage
  184. ;
  185.     push    cs
  186.     pop    es
  187.     mov    di,offset message_fname
  188.     mov    cx,40
  189.     rep    movsb                ;move filename asciiz here
  190.  
  191.     push    cs
  192.     pop    ds
  193. ;
  194. ; check if the database needs to be opened.
  195. ;    
  196. msg_1:    test    msg_flags,msg_open
  197.     jz    msg_2            ;jmp if dbase already open
  198. ;
  199. ; open the database (message file)
  200. ;
  201.     mov    dx,offset message_fname ;get file name
  202.     call    dbase_init
  203.     mov    msg_dbase_sel,bx    ;save dbase selector
  204.     cmp    al,0            ;check for errors
  205.     jne    msg_err1        ;jmp if error opening database
  206. ;
  207. ; check if window area save is needed
  208. ;
  209. msg_2:    test    msg_flags,msg_save_win
  210.     jz    msg_3            ;jmp if no window save needed
  211.     mov    bx,temp_box_size    ;get box rows/columns
  212.     mov    dx,temp_mloc        ;get box location
  213.     call    save_window        ;save area of screen
  214. ;
  215. ; draw the message box
  216. ;
  217. msg_3:    test    msg_flags,msg_disp
  218.     jz    msg_4            ;jmp if no display needed
  219.     mov    bx,temp_box_size    ;get box rows/columns
  220.     mov    dx,temp_mloc        ;get box location
  221.     mov    al,0            ;single line box
  222.     mov    ah,msg_text_color    ;get box color
  223.     call    draw_box
  224. ;
  225. ; check if message is in memory or on disk
  226. ;
  227.     test    cs:msg_flags,msg_ram
  228.     jz    hyper_entry        ;jmp if message on disk
  229.     mov    si,cs:msg_offset
  230.     mov    es,cs:msg_segment
  231.     jmp    msg_shrink
  232. ;
  233. ; read the message from disk
  234. ;
  235. hyper_entry:
  236.     mov    es,msg_dbase_sel    ;get dbase selector
  237.     mov    dx,msg_rec_no        ;get record#
  238.     call    dbase_read        ;returns es:si=msg ptr  cx=msg len
  239.     cmp    al,0            ;check for error
  240.     je    msg_shrink        ;jmp if read ok
  241.     mov    msg_rec_no,1        ;force record# 1 and retry
  242.     mov    dx,1
  243.     call    dbase_read
  244.     cmp    al,0
  245.     jne    msg_err2        ;jmp if error
  246. ;
  247. ; shrink the box
  248. ;
  249. msg_shrink:
  250.     mov    bx,temp_box_size    ;get box rows/columns
  251.     mov    dx,temp_mloc        ;get box location
  252.     call    box_shrink        ;adjust box for text fill
  253.     mov    ah,cs:msg_text_color
  254.     push    ds            ;move
  255.     push    es            ;  -es- to
  256.     pop    ds            ;   -ds-
  257. ;
  258. ; check type of box display
  259. ;
  260.     test    msg_flags,msg_hyper    ;check if hyper display
  261.     jnz    hyper_msg        ;jmp if hyper display
  262. ;
  263. ; normal message, fill the box with text, es:si=msg  cx=len  bx=box siz dx=loc
  264. ;
  265.     call    window_string        ;ds:si=string dx=loc bx=box size ah=color
  266.     pop    ds            ;restore -ds-
  267.     jmp    msg_4            ;skip over hyper display
  268. ;
  269. ; hyper format message display
  270. ;
  271. hyper_msg:
  272.     inc    dh            ;move down one row past menu bar
  273.     dec    bh            ;decrement number of rows avail.
  274.     call    hyper_display        ;returns hyper_table ptr (di)
  275.     pop    ds
  276. ;
  277. ; check type of key processing
  278. ;
  279. msg_4:    test    cs:msg_flags,msg_nokey
  280.     jnz    msg_8            ;jmp if no key wait
  281.     test    cs:msg_flags,msg_anykey
  282.     jz    msg_5            ;jmp if not wait for any key
  283. ;
  284. ; wait for any key option selected
  285. ;
  286.     call    KEY_OR_MOUSE        ;get next key or click
  287.     jmp    msg_8    
  288. ;
  289. ; check if yes/no response needed
  290. ;
  291. msg_5:    test    cs:msg_flags,msg_yesno
  292.     jz    msg_6            ;jmp if not yes/no wait
  293.     mov    al,0            ;normal yes/no ignore bad keys
  294.     call    yes_or_no
  295.     jmp    msg_8            ;continue
  296. ;
  297. ; check if this is hyper key wait
  298. ;
  299. msg_6:    test    cs:msg_flags,msg_hyper
  300.     jz    msg_err3
  301. ;
  302. ; this is a wait for hyper key, put up a menu bar at top of hyper box
  303. ;
  304. msg_7:    mov    bx,offset hyper_menu    ;ds:bx = menu table ptr
  305.     mov    dx,cs:temp_mloc
  306.     mov    word ptr ds:[bx.m_left_column],dx ;store message location
  307.     mov    dx,cs:temp_box_size
  308.     mov    word ptr ds:[bx.m_columns],dx
  309.     sub    [bx.m_columns],2
  310.     add    [bx.m_left_column],1
  311.     add    [bx.m_top_row],1
  312.     mov    ah,bar_display+return_bad_key    ;show menu & return unknown keys
  313.     call    MENU_SYSTEM
  314.     add    [bx.m_columns],2
  315.     sub    [bx.m_left_column],1
  316.     sub    [bx.m_top_row],1
  317. ;
  318. ; decode last key press
  319. ;
  320.     cmp    cl,1            ;check if process hit
  321.     jne    hyper_1            ;  jmp if not process
  322.     jmp    ax            ;go to process
  323. hyper_1:
  324.     cmp    cl,4            ;check if abort key
  325.     je    msg_8            ;  jmp if abort key
  326.  
  327.     cmp    ax,0151h
  328.     je    hyper_fwd
  329.     cmp    ax,0149h
  330.     je    hyper_bak
  331. ;
  332. ; check if a hyper trigger occured.  cs:di = ptr to hyper table
  333. ;                     if cl=2  ax=unknown key, dx=cursor loc
  334. ;                     if cl=3  dx=click row/col
  335. ;
  336. ; legal keys are <Enter> if over hyper trigger.
  337. ;                <click> if over hyper trigger.
  338. ;
  339. htrigger_scan:    
  340.     cmp    cs:[di.hrec_no],0    ;check if end of list
  341.     je    msg_7            ; jmp if this is not hyper trigger
  342.     cmp    dh,[di.hrow]
  343.     jne    nxt_hyper
  344.     cmp    dl,[di.hleft_col]
  345.     jb    nxt_hyper        ;jmp if not this hyper
  346.     cmp    dl,[di.hright_col]
  347.     jb    new_hyper_rec        ;jmp if hyper hit
  348. nxt_hyper:
  349.     add    di,size hyper_struc
  350.     jmp    htrigger_scan
  351. new_hyper_rec:
  352.     mov    dx,msg_rec_no
  353.     call    hyper_push        ;save origional location
  354.     mov    dl,[di.hrec_no]
  355.     mov    dh,0
  356. hyper_entry2:    
  357.     mov    cs:msg_rec_no,dx
  358.     jmp    hyper_entry        ;go display new record#
  359. ;
  360. ; display the previous topic
  361. ;
  362. hyper_previous:
  363.     call    hyper_pop
  364.     cmp    dx,0            ;check if stack empty
  365.     jne    hyper_entry2        ;jmp if previous item exists
  366.     jmp    msg_7            ;jmp if there is no previous topic
  367. ;
  368. ; move forward in message file
  369. ;
  370. hyper_fwd:
  371.     mov    dx,cs:msg_rec_no
  372.     inc    dx
  373.     jmp    hyper_entry2
  374. ;
  375. ; move backwards in message file
  376. ;
  377. hyper_bak:
  378.     mov    dx,cs:msg_rec_no
  379.     cmp    dx,1
  380.     je    msg_7            ;jmp if can't go back
  381.     dec    dx
  382.     jmp    hyper_entry2
  383. ;
  384. ; quit/exit hyper dislay
  385. ;
  386. hyper_exit:
  387.     mov    cs:hyper_stack_ptr,offset hyper_stack
  388.     jmp    msg_8
  389. ;
  390. ; check if window restore necessary
  391. ;    
  392. msg_8:    test    cs:msg_flags,msg_restore_win
  393.     jz    msg_9            ;jmp if no window restore
  394. ;
  395. ; restore the origional display
  396. ;
  397.     call    restore_window
  398. ;
  399. ; check if dbase(file) is to be left open
  400. ;
  401. msg_9:    test    cs:msg_flags,msg_close
  402.     jz    msg_exit        ;jmp if dbase is to be left open
  403. ;
  404. ; close the database
  405. ;
  406.     call    dbase_close
  407.     clc
  408.     jmp    msg_exit
  409. ;
  410. msg_err1:
  411.     mov    ah,fatal_error+error_text
  412.     mov    al,10                ;file open error
  413.     mov    bp,offset message_fname
  414.     jmp    msg_err
  415.  
  416. msg_err2:
  417.     mov    ah,fatal_error+error_text
  418.     mov    al,3                ;file read error
  419.     mov    bp,offset message_fname
  420.     jmp    msg_err
  421. ;
  422. ; keyboard handling flags not set correctly
  423. ;
  424. msg_err3:                
  425.     mov    ah,fatal_error
  426.     mov    al,2
  427.  
  428. msg_err:
  429.     stc
  430. ;
  431. msg_exit:
  432.     apop    es,ds,di,si,dx,cx,bx
  433.     retf
  434. message        endp                  
  435. ;         
  436. ;-----------------------------------------------------------------------------
  437. ; hyper_display - display test with hyper formating
  438. ;            print ASCIIZ string directly to the video buffer in a
  439. ;            window of screen, with word wrap.  String must be terminated
  440. ;            by a NUL character. WINDOW_STRING clears any portion of the window
  441. ;            not occupied by the string.
  442. ;         cr/lf characters cause a new line within the window.
  443. ;            HYPER triggers are imbedded into the text as two bytes which are
  444. ;            encoded as follows: 
  445. ;                                 first byte   1fh         <-character
  446. ;                                 second byte  (record #)  <-binary value
  447. ;
  448. ;Call with:   DS:[SI] pointing to the string
  449. ;          dx = starting row(dh)  starting column(dl)
  450. ;          bx = box total rows(bh)  box total columns(bl)
  451. ;             AH = color attribute (must be msg_text_color)
  452. ;  outputs: cs:di points at the hyper_table, end of table has rec# of zero
  453. ;
  454. ;--------------------------
  455. ; The hyper table is used to identify all hyper triggers within the text
  456. hyper_struc    struc
  457.  hrec_no    db    ?        ;set to zero if end of table
  458.  hrow        db    ?        ;trigger row
  459.  hleft_col    db    ?        ;trigger left column (start of range)
  460.  hright_col    db    ?        ;trigger right column (end of range)
  461. hyper_struc    ends
  462.  
  463. hyper_tbl_size    equ    20
  464.  
  465. hyper_table    db     (hyper_tbl_size)*(size hyper_struc) dup (0)
  466.  
  467. hyper_table_ptr dw    0    ;pointer to next hyper_table append point
  468.  
  469. hs_str_ptr    dw    0
  470. hs_wscan_cx    dw    0            ;scan for word break cx save
  471. hs_lp_cnt    db    0
  472. ;------------------------
  473.     public    hyper_display
  474. hyper_display:
  475.     apush    ax,bx,cx,dx,si,bp,ds,es
  476.     mov    cs:hyper_table_ptr,offset hyper_table
  477.     mov    es,cs:lib_info.crt_seg
  478.     mov    cs:hs_lp_cnt,bh
  479. ;
  480. ; skip over any cr/lf characters at start of this line
  481. ;
  482. hs_10:    mov    cx,0                ;set line length to zero
  483. hs_10a: cmp    byte ptr [si],0
  484.     jne    hs_13                ;jmp if not at end of string
  485.     call    posn_to_adr
  486.     jmp    hs_40                ;go fill line with blanks
  487. ;
  488. ; the first character of string has been found, not cr/lf/zero, find line len
  489. ;
  490. hs_13:    mov     cs:hs_str_ptr,si          ;save si
  491.  
  492. hs_20:    cmp    byte ptr [si],0
  493.     je    hs_30                ;jmp if end of line
  494.     cmp    byte ptr [si],0dh
  495.     je    hs_30                ;jmp if end of line
  496.     cmp    byte ptr [si],0ah
  497.     je    hs_30                ;jmp if end of line
  498.         cmp     byte ptr [si],1fh
  499.     jne    hs_21                ;jmp if not hyperkey trigger
  500. ;
  501. ; we have found a hyper key entry, skip over it
  502. ;
  503.     add    si,2
  504.     jmp    hs_20
  505. ;
  506. ; we have found a normal text char, count it and check if at box edge
  507. ;
  508. hs_21:
  509.     inc    cx                ;count this char
  510.     inc    si
  511.     cmp    cl,bl                ;check if at box right edge
  512.     jne    hs_20                ;jmp if still within box
  513. ;
  514. ; we have filled to the right edge of the box, now scan back for word break
  515. ;
  516.     mov    cs:hs_wscan_cx,cx         ;save ending char. count
  517. hs_22:  cmp     byte ptr [si-1],1fh
  518.     jne    hs_23                ;jmp if not hyper key
  519.     sub    si,2                ;skip over hyper key
  520.     jmp    hs_22
  521. hs_23:    dec    si
  522.         cmp     byte ptr [si],' '
  523.     je    hs_30                ;jmp if char break found
  524.     loop    hs_22
  525. ;
  526. ; no word breaks were found, so display line as is
  527. ;
  528.     mov    cx,cs:hs_wscan_cx
  529. ;
  530. ; si =ptr to line end,    cx = length of line
  531. ;
  532. hs_30:    mov    si,cs:hs_str_ptr         ;restore line start ptr
  533.     mov    cs:hs_wscan_cx,cx
  534.     call    posn_to_adr            ;compute starting display offset
  535.     jcxz    hs_40
  536.     call    $put_hyper_crt
  537. ;
  538. ; now check if we need to fill to end of box with blanks
  539. ;
  540.     mov    cx,cs:hs_wscan_cx        ;restore -cx-
  541. hs_40:    sub    cl,bl                ;display count - box size
  542.     neg    cl
  543.     jz    hs_50                ;jmp if no fill needed
  544. ;
  545. ; clear remainder of this line on display
  546. ;
  547.     push    si
  548.     mov    si,1
  549.         mov     al,' '
  550.     call    $vertical_repeat_chr
  551.     pop    si
  552. ;
  553. ; check if last line ends with crlf which needs to be skipped
  554. ;
  555. hs_50:    cmp    byte ptr [si],0dh
  556.     jne    hs_52                ;jmp if no cr/lf
  557.     add    si,2
  558.         
  559. ;
  560. ; check if last line of box has been filled
  561. ;
  562. hs_52:    inc    dh                ;move to next row on display
  563.     dec    cs:hs_lp_cnt            ;decrement row count
  564.     jnz    hs_10                ;loop till done
  565.  
  566. hs_EXIT:
  567.     apop    es,ds,bp,si,dx,cx,bx,ax
  568.     mov    di,offset hyper_table
  569.     RET
  570. ;-----------------------------------------------------------------------------
  571. ; $put_hyper_crt - write hyper message block (line) and update hyper_table
  572. ;   inputs:  ds:si = string ptr
  573. ;         es:di = display location
  574. ;        ah = display color (must be msg_text_color)
  575. ;--------------------------------
  576. put_hyper_flag    db    0    ;0=normal text    1=hyper key word display active
  577. ;--------------------------------
  578. $put_hyper_crt:
  579.     apush    bx,dx
  580.     mov    bx,cs:hyper_table_ptr
  581. phc_lp: lodsb                ;get display char
  582.     or    al,al
  583.     jz    phc_end            ;jmp if end of message
  584.         cmp     al,1fh
  585.     jne    phc_1            ;jmp if not hyper trigger
  586. ;
  587. ; we have found a hyper trigger, add entry to table and highlight entry
  588. ;
  589.     mov    cs:put_hyper_flag,1    ;enable hyper mode
  590.     call    adr_to_posn
  591.     mov    cs:[bx.hrow],dh        ;save current row
  592.     mov    cs:[bx.hleft_col],dl    ;save current column
  593.     lodsb                ;get record#
  594.     sub    al,21h
  595.     mov    cs:[bx.hrec_no],al    ;save hyper record#
  596.     mov    ah,cs:msg_hyper_color    ;change to hyper color
  597.     jmp    phc_lp
  598.  
  599. phc_1:    cmp    cs:put_hyper_flag,0    ;check if hyper key word display
  600.     je    phc_2            ; jmp if normal text being displayed
  601.         cmp     al,' '                  ;check if end of hyper key word
  602.     jne    phc_2            ; jmp if not end yet
  603.     mov    ah,cs:msg_text_color    ;change color back to normal
  604.     mov    cs:put_hyper_flag,0    ;disable hyper color
  605.     call    adr_to_posn
  606.     mov    cs:[bx.hright_col],dl    ;save end location of hyper keyword
  607.     add    bx,size hyper_struc    ;move to next structure loc
  608. phc_2:    stosw                ;write data to crt
  609.     loop    phc_lp            ;loop till done
  610. phc_end:mov    cs:hyper_table_ptr,bx
  611.     mov    cs:[bx.hrec_no],0    ;terminate table for now
  612.     apop    dx,bx
  613.     ret
  614.  
  615. ;-----------------------------------------------------------------------------
  616. ; hyper_push - push record number on the stack
  617. ;   inputs:  dx = record#
  618. ;   outputs: none
  619. ;
  620. ;------------------------
  621. hyper_stack_size    equ    20
  622. hyper_stack    dw    hyper_stack_size dup (0)
  623. hyper_stack_end    label    byte
  624. hyper_stack_ptr    dw    hyper_stack
  625. ;------------------------
  626. hyper_push:
  627.     push    bx
  628.     mov    bx,cs:hyper_stack_ptr
  629.     cmp    bx,offset hyper_stack_end
  630.     je    hpush_exit            ;jmp if stack full
  631.     mov    word ptr cs:[bx],dx
  632.     add    cs:hyper_stack_ptr,2
  633. hpush_exit:
  634.     pop    bx
  635.     ret
  636. ;-----------------------------------------------------------------------------
  637. ; hyper_pop - return last stack push
  638. ;  inputs: none
  639. ;  output: dx = last record# or zero if stack empty
  640. ;
  641. hyper_pop:
  642.     push    bx
  643.     mov    bx,cs:hyper_stack_ptr
  644.     cmp    bx,offset hyper_stack
  645.     jne    hpop_1                ;jmp if stack has entry
  646.     mov    dx,0
  647.     jmp    hpop_exit
  648. hpop_1:    sub    bx,2                ;move to previous entry
  649.     mov    dx,word ptr cs:[bx]        ;get previous record#
  650.     mov    cs:hyper_stack_ptr,bx
  651. hpop_exit:
  652.     pop    bx
  653.     ret        
  654.  
  655.  
  656. LIBSEG    ENDS
  657. ;;    end
  658.