home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c070 / 4.ddi / TOOLS.4 / TCTSRC1.EXE / VIDIREC0.ASM < prev    next >
Encoding:
Assembly Source File  |  1989-03-31  |  20.8 KB  |  747 lines

  1.     page    60,126
  2.  
  3. ; Name        vidirec0 -- Read or write rectangle directly from or to
  4. ;                video adapter
  5. ;
  6. ; Synopsis    ercode = vidirec0(ppfrom,ppto,num_rows,row_length,
  7. ;               scn_width,attr,option,gap);
  8. ;
  9. ;        int ercode     Error code:  1 if option is unknown,
  10. ;                          0 if okay.
  11. ;        const char far * const *ppfrom
  12. ;                 Pointer to far char pointer containing
  13. ;                 address of source buffer
  14. ;        char far **ppto  Pointer to far char pointer containing
  15. ;                 address of destination buffer
  16. ;        int num_rows     Number of rows in the rectangle
  17. ;        int row_length     Width of the rectangle (in columns)
  18. ;        int scn_width     Twice the screen width (80 or 160 bytes)
  19. ;        int attr     Foreground and background attributes
  20. ;                 (only used for certain options)
  21. ;        int option     Style and direction of I/O; also
  22. ;                 whether interference is to be prevented.
  23. ;                 See discussion and table below.
  24. ;        unsigned gap     Character cells between successive rows
  25. ;                 of data buffer in memory (ignored for
  26. ;                 some option values.)
  27. ;
  28. ; Description    This function reads or writes a rectangular buffer
  29. ;        directly from or to the video memory on an IBM
  30. ;        Color/Graphics Adapter, Monochrome Adapter, or
  31. ;        compatible adapter.  It can do so with attention to the
  32. ;        horizontal and vertical retrace intervals for maximum
  33. ;        throughput without interference.  The characters are
  34. ;        transferred row by row.
  35. ;
  36. ;        The buffer addresses are stored in far char pointers
  37. ;        pointed to by ppfrom and ppto.    Either or both of these
  38. ;        may point to physical locations in video memory,
  39. ;        depending on the value of option.
  40. ;
  41. ;        Several styles of I/O are available.  They are selected
  42. ;        by the value of option.  Bit 15 of option, if set,
  43. ;        indicates that the transfer is to be performed without
  44. ;        regard to interference.  The remaining bits of option
  45. ;        form an integer which should be selected from the
  46. ;        following table:
  47. ;
  48. ;        Option    Description
  49. ;        ------    -----------
  50. ;           0    Write characters to the screen without attributes.
  51. ;            *ppfrom points to a buffer of characters.
  52. ;            (Same as option 13 with gap == 0.)
  53. ;           1    Write characters to the screen with attributes.
  54. ;            *ppfrom points to a buffer of (char,attr) pairs.
  55. ;            (Same as option 14 with gap == 0.)
  56. ;           2    Write characters to the screen with constant
  57. ;                attribute specified by attr.
  58. ;            *ppfrom points to a buffer of characters.
  59. ;            (Same as option 15 with gap == 0.)
  60. ;           3    Fill screen rectangle with constant char & attr.
  61. ;            *ppfrom points to the character.
  62. ;            Attr specifies the attribute.
  63. ;           4    Fill screen rectangle with constant attribute
  64. ;                without altering characters displayed.
  65. ;            ppfrom is ignored.
  66. ;           5    Read characters from screen without attributes.
  67. ;            **ppto is filled with the characters.  (Note
  68. ;                that no trailing NUL is added.)
  69. ;            (Same as option 16 with gap == 0.)
  70. ;           6    Read characters from screen with attributes.
  71. ;            **ppto is filled with (char,attr) pairs.
  72. ;            (Same as option 17 with gap == 0.)
  73. ;           7    Copy window (with attributes) upward or directly
  74. ;                leftward on same display page.
  75. ;           8    Copy window (without attributes) upward or
  76. ;                directly leftward on same display page.
  77. ;           9    Copy window (with attributes) downward or
  78. ;                directly rightward on same display page.
  79. ;          10    Copy window (without attributes) downward or
  80. ;                directly rightward on same display page.
  81. ;          11    Copy window (with attributes) to non-overlapping
  82. ;                window or to another display page.
  83. ;          12    Copy window (without attributes) to non-
  84. ;                overlapping window or to another display page.
  85. ;
  86. ;            Note:  The preceding options all ignore "gap".
  87. ;
  88. ;          13    Write characters to the screen without attributes.
  89. ;            *ppfrom points to a buffer of characters whose
  90. ;                rows are separated by "gap" bytes.
  91. ;          14    Write characters to the screen with attributes.
  92. ;            *ppfrom points to a buffer of (char,attr) pairs
  93. ;                whose rows are separated by "gap" pairs.
  94. ;          15    Write characters to the screen with constant
  95. ;                attribute specified by attr.
  96. ;            *ppfrom points to a buffer of characters whose
  97. ;                rows are separated by "gap" bytes.
  98. ;          16    Read characters from screen without attributes.
  99. ;            **ppto is filled with the characters.  (Note
  100. ;                that no trailing NUL is added.)  The rows of
  101. ;                **ppto are separated by "gap" bytes.
  102. ;          17    Read characters from screen with attributes.
  103. ;            **ppto is filled with (char,attr) pairs.  The
  104. ;                rows of **ppto are separated by "gap" pairs.
  105. ;
  106. ;        Beware:  None of the arguments is checked for
  107. ;        correctness (except that option is checked for
  108. ;        out-of-range values)!
  109. ;
  110. ;        If bit 15 of option is clear (indicating protection
  111. ;        against interference), interrupts will be left enabled
  112. ;        when this procedure exits.
  113. ;
  114. ; Returns    ercode          Error code:  1 if option is unknown,
  115. ;                           0 if okay.
  116. ;        **ppto          Data in destination buffer
  117. ;
  118. ; Version    6.00 (C)Copyright Blaise Computing Inc.  1986-1989
  119. ;
  120.  
  121. video_status_port   equ     3DAh
  122.  
  123.     include     beginasm.mac
  124.     beginMod    utamove
  125.  
  126. ;   Symbols to aid in referencing arguments on stack
  127. ;   (Some of these items are also used as local variables.):
  128.  
  129. a        equ     0
  130. b        equ     a + sizeDPointer
  131. c        equ     b + sizeDPointer
  132. d        equ     c + 2
  133. e        equ     d + 2
  134. f        equ     e + 2
  135. g        equ     f + 2
  136. h        equ     g + 2
  137.  
  138. ppfrom        equ           [bp + stkoff + a]
  139. ppto        equ           [bp + stkoff + b]
  140. num_rows    equ     byte  ptr [bp + stkoff + c]
  141. row_length  equ     byte  ptr [bp + stkoff + d]
  142. scn_width   equ     word  ptr [bp + stkoff + e]
  143. attr        equ     byte  ptr [bp + stkoff + f]
  144. option        equ     word  ptr [bp + stkoff + g]
  145. gap        equ     word  ptr [bp + stkoff + h]
  146.  
  147. ;   Format of the table entry for one option:
  148.  
  149. option_entry    struc
  150. do_setup    dw    ?   ; Address of setup_proc.
  151. do_slow     dw    ?   ; Address of slow_proc.
  152. do_fast     dw    ?   ; Address of fast_proc.
  153. do_newrow    dw    ?   ; Address of newrow_proc.
  154. dirflag     db    ?   ; Direction:  down or up.
  155. option_entry    ends
  156.  
  157. ;   Macro to wait until the beginning of a horizontal
  158. ;   retrace interval.  On exit, interrupts are off.
  159.  
  160. await_horiz_retrace macro
  161.     local    await_display_on,await_display_off
  162.     sti
  163.     nop
  164. await_display_on:
  165.     in    al,dx
  166.     shr    al,1
  167.     jc    await_display_on
  168.     cli
  169. await_display_off:
  170.     in    al,dx
  171.     shr    al,1
  172.     jnc    await_display_off
  173.     endm
  174.  
  175. ;   Here are macros to define procedures for each style of I/O as
  176. ;    specified by "option".
  177. ;
  178. ;   Each style of I/O requires four procedures:
  179. ;    (1) a specialized setup procedure ("setup_proc") (which may
  180. ;        do nothing)
  181. ;    (2) a procedure ("slow_proc") to do the entire read or write
  182. ;        while avoiding video interference;
  183. ;    (3) a procedure ("fast_proc") to do the entire read or write
  184. ;        without regard to interference (i.e., as fast as possible);
  185. ;    (4) a procedure ("newrow_proc") to adjust address registers
  186. ;        (SI and/or DI) and the column counter (CX) for a new row
  187. ;        of the rectangle.
  188. ;   These four procedures will be addressed through table "option_table"
  189. ;    defined below.
  190. ;   Since these procedures must therefore be highly regular in form,
  191. ;    the following macros aid in defining the beginning and end of
  192. ;    each.
  193.  
  194. begin_setup_proc    macro   o_name  ;; Define beginning of setup procedure
  195. o_name&_setup_proc  proc    near
  196.             endm
  197.  
  198. end_setup_proc        macro   o_name  ;; Define end of setup procedure
  199.             ret
  200. o_name&_setup_proc  endp
  201.             endm
  202.  
  203.                 ; On entry to each slow_proc,
  204.                 ;
  205.                 ;    BX = address of option_table entry;
  206.                 ;    CX = number of cells in one row;
  207.                 ;    DX = I/O address of video status port.
  208.                 ;
  209.                 ; Also, usually
  210.                 ;    DS:SI = address of first source byte;
  211.                 ;    ES:DI = address of first target byte.
  212.                 ;
  213.                 ; Additional entry conditions are satisfied
  214.                 ;    by the setup_proc.
  215.  
  216. begin_slow_proc     macro   o_name,save_bx_flag
  217. o_name&_slow_proc   proc    near
  218.             ifidn   <save_bx_flag>,<save_bx>
  219.             push    bx        ;; Some options must use BX as
  220.                     ;; additional storage space, so
  221.                     ;; save BX if requested.
  222.             endif
  223. o_name&_single_loop:            ;; Begin loop that transfers one
  224.                     ;; character cell.
  225.             endm
  226.  
  227. end_slow_proc        macro   o_name,save_bx_flag
  228.             local   done
  229.             loop    o_name&_single_loop ;; Transfer one more cell
  230.                         ;; in this row.
  231.  
  232.             sti
  233.             ifidn   <save_bx_flag>,<save_bx>
  234.             pop    bx        ;; Restore BX if it was used for
  235.                     ;; temporary data.
  236.             endif
  237.             dec     num_rows
  238.             jz        done
  239.             call    cs:[bx].do_newrow    ;; Use BX to invoke
  240.                         ;; proper newrow_proc.
  241.             jmp     short o_name&_slow_proc ;; Do next row.
  242. done:            ret                 ;; Done.
  243. o_name&_slow_proc   endp
  244.             endm
  245.  
  246.                 ; Each fast_proc has the same entry
  247.                 ; conditions as slow_proc.
  248.  
  249. begin_fast_proc     macro   o_name
  250. o_name&_fast_proc   proc    near
  251.             endm
  252.  
  253. end_fast_proc        macro   o_name
  254.             local   done
  255.  
  256.             dec     num_rows
  257.             jz        done
  258.             call    cs:[bx].do_newrow    ;; Use BX to invoke
  259.                         ;; proper newrow_proc.
  260.             jmp     short o_name&_fast_proc
  261. done:            ret
  262. o_name&_fast_proc   endp
  263.             endm
  264.  
  265.                 ; Each newrow_proc assumes CH == 0.
  266.  
  267. begin_newrow_proc   macro   o_name
  268. o_name&_newrow_proc proc    near
  269.             mov     cl,row_length
  270.             endm
  271.  
  272. end_newrow_proc     macro   o_name
  273.             ret
  274. o_name&_newrow_proc endp
  275.             endm
  276.  
  277. ; *************************************************************
  278. ; *********   DEFINE FOUR PROCEDURES FOR EACH OPTION **********
  279. ; *************************************************************
  280. ;
  281. ;   (Note:  many of these definitions just refer to others using "equ".)
  282.  
  283.     beginCseg vidirec0
  284.  
  285. ;   W_CHARS:    Write characters to the screen without attributes.
  286.  
  287.     begin_setup_proc    w_chars     ; No setup needed.
  288.     end_setup_proc    w_chars
  289.  
  290.     begin_slow_proc    w_chars
  291.      await_horiz_retrace
  292.      movsb
  293.      inc     di
  294.     end_slow_proc    w_chars
  295.  
  296.     begin_fast_proc    w_chars
  297. w_chars_fast_loop:
  298.      movsb
  299.      inc     di
  300.      loop     w_chars_fast_loop
  301.     end_fast_proc    w_chars
  302.  
  303.     begin_newrow_proc    w_chars
  304.      sub     di,cx
  305.      sub     di,cx
  306.      add     di,scn_width
  307.     end_newrow_proc    w_chars
  308.  
  309. ;   W_CHAR_ATTRS:  Write characters & attributes to the screen.
  310.  
  311. w_char_attrs_setup_proc     equ     w_chars_setup_proc ; No setup needed.
  312.  
  313.     begin_slow_proc    w_char_attrs,save_bx
  314.      lodsw                ; Insufficient time for a
  315.      mov     bx,ax            ; whole "movsw", so do the job
  316.      await_horiz_retrace        ; by a "lodsw" plus a "stosw".
  317.      mov     ax,bx
  318.      stosw
  319.     end_slow_proc    w_char_attrs,save_bx
  320.  
  321.     begin_fast_proc    w_char_attrs
  322.      rep  movsw
  323.     end_fast_proc    w_char_attrs
  324.  
  325. w_char_attrs_newrow_proc    equ     w_chars_newrow_proc
  326.  
  327. ;   CONST_ATTR:  Write characters to screen with constant attribute
  328. ;         specified in AH.
  329.  
  330.     begin_setup_proc    const_attr
  331.      mov     ah,attr
  332.     end_setup_proc    const_attr
  333.  
  334.  
  335.     begin_slow_proc    const_attr,save_bx
  336.      lodsb                ; Insufficient time for "lodsb"
  337.      mov     bl,al            ; plus "stosw", so do the job
  338.      await_horiz_retrace        ; in halves.
  339.      mov     al,bl
  340.      stosw
  341.     end_slow_proc    const_attr,save_bx
  342.  
  343.     begin_fast_proc    const_attr
  344. const_attr_fast_loop:
  345.      lodsb
  346.      stosw
  347.      loop     const_attr_fast_loop
  348.     end_fast_proc    const_attr
  349.  
  350. const_attr_newrow_proc        equ     w_chars_newrow_proc
  351.  
  352. ;   CONST_CHAR_ATTR:  Fill rectangle with constant character
  353. ;              and attribute (stored in SI).
  354.  
  355.     begin_setup_proc    const_char_attr
  356.      mov    ah,attr
  357.      mov    al,[si]
  358.      mov    si,ax         ; Keep char & attr in SI for the loop
  359.     end_setup_proc    const_char_attr
  360.  
  361.     begin_slow_proc    const_char_attr
  362.      await_horiz_retrace
  363.      mov    ax,si
  364.      stosw
  365.     end_slow_proc    const_char_attr
  366.  
  367.     begin_fast_proc    const_char_attr
  368.      mov    ax,si
  369.      rep    stosw
  370.     end_fast_proc    const_char_attr
  371.  
  372. const_char_attr_newrow_proc   equ   w_chars_newrow_proc
  373.  
  374. ;   CONST_ATTR_ONLY:  Change attribute on rectangle to value
  375. ;              stored in AH.
  376.  
  377.     begin_setup_proc    const_attr_only
  378.      mov    ah,attr
  379.     end_setup_proc    const_attr_only
  380.  
  381.     begin_slow_proc    const_attr_only
  382.      await_horiz_retrace
  383.      inc    di
  384.      mov    al,ah
  385.      stosb
  386.     end_slow_proc    const_attr_only
  387.  
  388.     begin_fast_proc    const_attr_only
  389.      mov    al,ah
  390. const_attr_only_fast_loop:
  391.      inc    di
  392.      stosb
  393.      loop    const_attr_only_fast_loop
  394.     end_fast_proc    const_attr_only
  395.  
  396. const_attr_only_newrow_proc   equ   w_chars_newrow_proc
  397.  
  398. ;   R_CHARS:  Read only characters from screen.
  399.  
  400. r_chars_setup_proc     equ     w_chars_setup_proc ; No setup needed.
  401.  
  402.     begin_slow_proc    r_chars
  403.      await_horiz_retrace
  404.      movsb
  405.      inc    si
  406.     end_slow_proc    r_chars
  407.  
  408.     begin_fast_proc    r_chars
  409. r_chars_fast_loop:
  410.      movsb
  411.      inc    si
  412.      loop    r_chars_fast_loop
  413.     end_fast_proc    r_chars
  414.  
  415.     begin_newrow_proc    r_chars
  416.      sub    si,cx
  417.      sub    si,cx
  418.      add    si,scn_width
  419.     end_newrow_proc    r_chars
  420.  
  421. ;   R_CHAR_ATTRS:  Read characters & attributes from screen.
  422.  
  423. r_char_attrs_setup_proc     equ     w_chars_setup_proc ; No setup needed.
  424.  
  425.     begin_slow_proc    r_char_attrs
  426.      await_horiz_retrace
  427.      movsw
  428.     end_slow_proc    r_char_attrs
  429.  
  430. r_char_attrs_fast_proc        equ     w_char_attrs_fast_proc
  431. r_char_attrs_newrow_proc    equ     r_chars_newrow_proc
  432.  
  433. ;   UP_CHAR_ATTRS:  Copy characters & attributes upward on the screen
  434. ;            or directly to the left.  Start at upper left
  435. ;            corner of rectangle.
  436.  
  437. up_char_attrs_setup_proc     equ     w_chars_setup_proc ; No setup needed.
  438.  
  439.     begin_slow_proc    up_char_attrs,save_bx
  440.      await_horiz_retrace
  441.      lodsw                ; Insufficient time for a
  442.      mov     bx,ax            ; whole "movsw", so do the job
  443.      await_horiz_retrace        ; by a "lodsw" plus a "stosw".
  444.      mov     ax,bx
  445.      stosw
  446.     end_slow_proc    up_char_attrs,save_bx
  447.  
  448. up_char_attrs_fast_proc      equ     w_char_attrs_fast_proc
  449.  
  450.     begin_newrow_proc    up_char_attrs
  451.      sub    si,cx
  452.      sub    si,cx
  453.      add    si,scn_width
  454.      sub    di,cx
  455.      sub    di,cx
  456.      add    di,scn_width
  457.     end_newrow_proc    up_char_attrs
  458.  
  459. ;   UP_CHARS:        Copy only characters upward on the screen
  460. ;            or directly to the left.  Start at upper left
  461. ;            corner of rectangle.
  462.  
  463. up_chars_setup_proc    equ    w_chars_setup_proc ; No setup needed.
  464.  
  465.     begin_slow_proc    up_chars
  466.     await_horiz_retrace
  467.     movsb
  468.     inc    si
  469.     inc    di
  470.     end_slow_proc    up_chars
  471.  
  472.     begin_fast_proc    up_chars
  473. up_chars_fast_loop:
  474.     movsb
  475.     inc    si
  476.     inc    di
  477.     loop    up_chars_fast_loop
  478.     end_fast_proc    up_chars
  479.  
  480. up_chars_newrow_proc    equ    up_char_attrs_newrow_proc
  481.  
  482. ;   DOWN_CHAR_ATTRS:  Copy characters & attributes downward on the screen
  483. ;              or directly to the right.  Start at lower right
  484. ;              corner of rectangle.
  485.  
  486.     begin_setup_proc    down_char_attrs
  487.     mov    al,num_rows    ; Adjust SI and DI to point
  488.     dec    al        ; at the last character in the
  489.     mov    cx,scn_width    ; rectangle instead of the first.
  490.     mul    cl
  491.     mov    cl,row_length
  492.     mov    ch,0
  493.     dec    cx
  494.     add    cx,cx
  495.     add    ax,cx
  496.  
  497.     add    si,ax
  498.     add    di,ax
  499.     end_setup_proc    down_char_attrs
  500.  
  501. down_char_attrs_slow_proc   equ     up_char_attrs_slow_proc
  502. down_char_attrs_fast_proc   equ     up_char_attrs_fast_proc
  503.  
  504.     begin_newrow_proc    down_char_attrs
  505.     add    si,cx
  506.     add    si,cx
  507.     sub    si,scn_width
  508.     add    di,cx
  509.     add    di,cx
  510.     sub    di,scn_width
  511.     end_newrow_proc    down_char_attrs
  512.  
  513. ;   DOWN_CHARS:  Copy only characters downward on the screen
  514. ;         or directly to the right.  Start at lower right
  515. ;         corner of rectangle.
  516.  
  517. down_chars_setup_proc      equ      down_char_attrs_setup_proc
  518.  
  519.     begin_slow_proc    down_chars
  520.     await_horiz_retrace
  521.     movsb
  522.     dec    si
  523.     dec    di
  524.     end_slow_proc    down_chars
  525.  
  526.     begin_fast_proc    down_chars
  527. down_chars_fast_loop:
  528.     movsb
  529.     dec    si
  530.     dec    di
  531.     loop    down_chars_fast_loop
  532.     end_fast_proc    down_chars
  533.  
  534. down_chars_newrow_proc        equ     down_char_attrs_newrow_proc
  535.  
  536. ;   W_CHARS_GAP:    Write characters to the screen without attributes.
  537.  
  538. w_chars_gap_setup_proc        equ     w_chars_setup_proc ; No setup needed.
  539. w_chars_gap_slow_proc        equ     w_chars_slow_proc
  540. w_chars_gap_fast_proc        equ     w_chars_fast_proc
  541.  
  542.     begin_newrow_proc    w_chars_gap
  543.      sub     di,cx
  544.      sub     di,cx
  545.      add     di,scn_width
  546.      add     si,gap
  547.     end_newrow_proc    w_chars_gap
  548.  
  549. ;   W_CHAR_ATTRS_GAP:  Write characters & attributes to the screen.
  550.  
  551. w_char_attrs_gap_setup_proc equ     w_char_attrs_setup_proc ; No setup needed.
  552. w_char_attrs_gap_slow_proc  equ     w_char_attrs_slow_proc
  553. w_char_attrs_gap_fast_proc  equ     w_char_attrs_fast_proc
  554.  
  555.     begin_newrow_proc    w_char_attrs_gap
  556.      sub     di,cx
  557.      sub     di,cx
  558.      add     di,scn_width
  559.      add     si,gap
  560.      add     si,gap
  561.     end_newrow_proc    w_char_attrs_gap
  562.  
  563. ;   CONST_ATTR_GAP:  Write characters to screen with constant attribute
  564. ;             specified in AH.
  565.  
  566. const_attr_gap_setup_proc   equ     const_attr_setup_proc
  567. const_attr_gap_slow_proc    equ     const_attr_slow_proc
  568. const_attr_gap_fast_proc    equ     const_attr_fast_proc
  569. const_attr_gap_newrow_proc  equ     w_chars_gap_newrow_proc
  570.  
  571. ;   R_CHARS_GAP:  Read only characters from screen.
  572.  
  573. r_chars_gap_setup_proc        equ     r_chars_setup_proc ; No setup needed.
  574. r_chars_gap_slow_proc        equ     r_chars_slow_proc
  575. r_chars_gap_fast_proc        equ     r_chars_fast_proc
  576.  
  577.     begin_newrow_proc    r_chars_gap
  578.      sub    si,cx
  579.      sub    si,cx
  580.      add    si,scn_width
  581.      add    di,gap
  582.     end_newrow_proc    r_chars_gap
  583.  
  584. ;   R_CHAR_ATTRS_GAP:  Read characters & attributes from screen.
  585.  
  586. r_char_attrs_gap_setup_proc equ     r_char_attrs_setup_proc ; No setup needed.
  587. r_char_attrs_gap_slow_proc  equ     r_char_attrs_slow_proc
  588. r_char_attrs_gap_fast_proc  equ     r_char_attrs_fast_proc
  589.  
  590.     begin_newrow_proc    r_char_attrs_gap
  591.      sub    si,cx
  592.      sub    si,cx
  593.      add    si,scn_width
  594.      add    di,gap
  595.      add    di,gap
  596.     end_newrow_proc    r_char_attrs_gap
  597.  
  598. ; *******************************************************************
  599. ; **********   DEFINE THE TABLE OF OPTION INFORMATION  **************
  600. ; *******************************************************************
  601.  
  602. ;   Values for dirflag:
  603.  
  604. down    equ    1        ; Decreasing addresses (up the screen)
  605. up    equ    0        ; Increasing addresses (down the screen)
  606.  
  607. ;   Macro to create one table entry:
  608.  
  609. o_e        macro    o_name,dir
  610. option_entry <o_name&_setup_proc,o_name&_slow_proc,o_name&_fast_proc,o_name&_newrow_proc,dir>
  611.         endm
  612.  
  613. ;   The table itself follows.  It's part of the code segment.
  614.  
  615. option_table:
  616.         o_e    w_chars,up         ; 0
  617. end_of_first    label    option_entry
  618.         o_e    w_char_attrs,up      ; 1
  619.         o_e    const_attr,up         ; 2
  620.         o_e    const_char_attr,up   ; 3
  621.         o_e    const_attr_only,up   ; 4
  622.         o_e    r_chars,up         ; 5
  623.         o_e    r_char_attrs,up      ; 6
  624.         o_e    up_char_attrs,up     ; 7
  625.         o_e    up_chars,up         ; 8
  626.         o_e    down_char_attrs,down ; 9
  627.         o_e    down_chars,down      ; 10
  628.         o_e    up_char_attrs,up     ; 11
  629.         o_e    up_chars,up         ; 12
  630.  
  631.         o_e    w_chars_gap,up         ; 13
  632.         o_e    w_char_attrs_gap,up  ; 14
  633.         o_e    const_attr_gap,up    ; 15
  634.         o_e    r_chars_gap,up         ; 16
  635.         o_e    r_char_attrs_gap,up  ; 17
  636.  
  637.                 ; (Note that options 11 and 12 just
  638.                 ; refer to the procedures used by options
  639.                 ; 7 and 8, respectively, because the
  640.                 ; same algorithms suffice.)
  641.  
  642. end_of_table    label    option_entry
  643.  
  644. size_of_entry    equ    end_of_first - option_table
  645. table_length    equ    (end_of_table - option_table)/size_of_entry
  646.  
  647.  
  648. ; ********************************************************************
  649. ; **********************   BEGIN THE ACTUAL CODE   *******************
  650. ; ********************************************************************
  651.  
  652.     beginProc vidirec0
  653.  
  654.     push    bp           ; Save the frame pointer
  655.     mov    bp,sp
  656.  
  657.     push    di
  658.     push    si
  659.     push    ds
  660.     push    es
  661.  
  662.     mov    ax,option
  663.     mov    dx,ax            ; Spare copy of raw option
  664.     and    ax,7fffh        ; Ignore bit 15 of option.
  665.  
  666.     cmp    ax,table_length     ; Check for option value beyond table.
  667.     jb    option_ok
  668.  
  669. bad_option:
  670.     mov    ax,1            ; Invalid option
  671.     jmp    short exit
  672.  
  673. option_ok:
  674.     mov    cl,size_of_entry    ; Convert option value into address
  675.     mul    cl            ; of proper table entry.
  676.     jc    bad_option
  677.     add    ax,offset option_table
  678.     mov    option,ax        ; Save address of table entry.
  679.  
  680.     mov    bx,ax            ; Set DF according to dirflag value
  681.     cmp    cs:[bx].dirflag,down; in table.
  682.     je    downward
  683.  
  684.     cld
  685.     jmp    short have_set_direction
  686.  
  687. downward:
  688.     std
  689.  
  690. have_set_direction:
  691.  
  692.     if    LONGDATA
  693.     lds    bx,dword ptr ppto
  694.     assume    ds:nothing
  695.     else
  696.     mov    bx,ppto
  697.     endif
  698.     les    di,[bx]         ; Put target address into ES:DI.
  699.     assume    es:nothing
  700.  
  701.     if    LONGDATA
  702.     lds    bx,dword ptr ppfrom
  703.     assume    ds:nothing
  704.     else
  705.     mov    bx,ppfrom
  706.     endif
  707.     lds    si,[bx]         ; Put source address into DS:SI.
  708.     assume    ds:nothing
  709.  
  710.     mov    bx,option
  711.  
  712.     call    cs:[bx].do_setup    ; Do specialized portion
  713.                     ; of setup.
  714.  
  715.                     ; Complete the setup.
  716.     mov    cl,row_length
  717.     mov    ch,0
  718.     test    dh,80h
  719.     mov    dx,video_status_port
  720.     jnz    no_waiting
  721.  
  722.     call    cs:[bx].do_slow     ; Invoke slow_proc.
  723.     jmp    short done
  724.  
  725. no_waiting:
  726.     call    cs:[bx].do_fast     ; Invoke fast_proc.
  727.  
  728. done:
  729.     xor    ax,ax            ; Successful completion
  730.  
  731. exit:
  732.     sti
  733.     pop    es
  734.     pop    ds
  735.     pop    si
  736.     pop    di
  737.  
  738.     cld
  739.     pop    bp            ; Get the original frame pointer.
  740.     ret
  741.  
  742.     endProc vidirec0
  743.     endCseg vidirec0
  744.     endMod    vidirec0
  745.  
  746.     end
  747.