home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / 2d / modex.asm < prev    next >
Assembly Source File  |  1998-06-08  |  17KB  |  836 lines

  1. ;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  2. ;SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  3. ;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  4. ;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  5. ;IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  6. ;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  7. ;FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  8. ;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  9. ;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  10. ;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  11. ;
  12. ; $Source: f:/miner/source/2d/rcs/modex.asm $
  13. ; $Revision: 1.19 $
  14. ; $Author: john $
  15. ; $Date: 1995/03/01 15:37:46 $
  16. ;
  17. ; Routines to access ModeX VGA memory
  18. ;
  19. ; $Log: modex.asm $
  20. ; Revision 1.19  1995/03/01  15:37:46  john
  21. ; Better ModeX support.
  22. ; Revision 1.18  1994/11/24  13:24:20  john
  23. ; Made sure that some rep movs had the cld set first.
  24. ; Took some unused functions out.
  25. ; Revision 1.17  1994/09/22  18:15:02  john
  26. ; Made flip page wait for retrace.
  27. ; Revision 1.16  1994/09/22  16:08:27  john
  28. ; Fixed some palette stuff.
  29. ; Revision 1.15  1994/07/13  12:03:05  john
  30. ; Added assembly modex line-drawer.
  31. ; Revision 1.14  1994/05/06  12:50:34  john
  32. ; Added supertransparency; neatend things up; took out warnings.
  33. ; Revision 1.13  1994/05/03  19:39:04  john
  34. ; *** empty log message ***
  35. ; Revision 1.12  1994/02/18  15:32:32  john
  36. ; *** empty log message ***
  37. ; Revision 1.11  1993/12/21  11:40:36  john
  38. ; *** empty log message ***
  39. ; Revision 1.10  1993/12/09  15:02:26  john
  40. ; Changed palette stuff majorly
  41. ; Revision 1.9  1993/12/03  12:11:32  john
  42. ; fixed cx/ecx loop bugs.
  43. ; Revision 1.8  1993/11/16  11:28:18  john
  44. ; *** empty log message ***
  45. ; Revision 1.7  1993/10/15  16:23:23  john
  46. ; y
  47. ; Revision 1.6  1993/09/28  19:07:19  john
  48. ; stripped the waitforretrace out of fade to speed things up.
  49. ; Revision 1.5  1993/09/26  18:58:58  john
  50. ; fade stuff
  51. ; Revision 1.4  1993/09/21  14:01:15  john
  52. ; turned off video before mode set to reduce flicker.
  53. ; Revision 1.3  1993/09/08  11:38:36  john
  54. ; changed rcs stuff at beginning.
  55. ;
  56. ;
  57.  
  58.  
  59. .386
  60.  
  61. _DATA   SEGMENT BYTE PUBLIC USE32 'DATA'
  62.  
  63. INCLUDE psmacros.inc
  64. INCLUDE TWEAK.INC
  65. INCLUDE VGAREGS.INC
  66.  
  67. extd _gr_var_bwidth
  68.  
  69. extd _modex_line_vertincr
  70. extd _modex_line_incr1        
  71. extd _modex_line_incr2        
  72.     _modex_line_routine    dd ?
  73. extd _modex_line_x1        
  74. extd _modex_line_y1        
  75. extd _modex_line_x2        
  76. extd _modex_line_y2        
  77. extb _modex_line_Color
  78.  
  79.     SavedColor      db ?
  80.  
  81. LEFT_MASK1      = 1000b
  82. LEFT_MASK2      = 1100b
  83. LEFT_MASK3      = 1110b
  84. RIGHT_MASK1     = 0001b
  85. RIGHT_MASK2     = 0011b
  86. RIGHT_MASK3     = 0111b
  87. ALL_MASK        = 1111b
  88.  
  89. tmppal          db 768 dup (0)
  90. fb_pal          dd ?
  91. fb_add          dw ?
  92. fb_count        dd ?
  93.  
  94. MaskTable1  db  ALL_MASK AND RIGHT_MASK1,
  95.                 ALL_MASK AND RIGHT_MASK2,
  96.                 ALL_MASK AND RIGHT_MASK3,
  97.                 ALL_MASK,
  98.                 LEFT_MASK3 AND RIGHT_MASK1,
  99.                 LEFT_MASK3 AND RIGHT_MASK2,
  100.                 LEFT_MASK3 AND RIGHT_MASK3,
  101.                 LEFT_MASK3,
  102.                 LEFT_MASK2 AND RIGHT_MASK1,
  103.                 LEFT_MASK2 AND RIGHT_MASK2,
  104.                 LEFT_MASK2 AND RIGHT_MASK3,
  105.                 LEFT_MASK2,
  106.                 LEFT_MASK1 AND RIGHT_MASK1,
  107.                 LEFT_MASK1 AND RIGHT_MASK2,
  108.                 LEFT_MASK1 AND RIGHT_MASK3,
  109.                 LEFT_MASK1,
  110.  
  111. MaskTable2  db  ALL_MASK,RIGHT_MASK1,
  112.                 ALL_MASK,RIGHT_MASK2,
  113.                 ALL_MASK,RIGHT_MASK3,
  114.                 ALL_MASK,ALL_MASK,
  115.                 LEFT_MASK3,RIGHT_MASK1,
  116.                 LEFT_MASK3,RIGHT_MASK2,
  117.                 LEFT_MASK3,RIGHT_MASK3,
  118.                 LEFT_MASK3,ALL_MASK,
  119.                 LEFT_MASK2,RIGHT_MASK1,
  120.                 LEFT_MASK2,RIGHT_MASK2,
  121.                 LEFT_MASK2,RIGHT_MASK3,
  122.                 LEFT_MASK2,ALL_MASK,
  123.                 LEFT_MASK1,RIGHT_MASK1,
  124.                 LEFT_MASK1,RIGHT_MASK2,
  125.                 LEFT_MASK1,RIGHT_MASK3,
  126.                 LEFT_MASK1,ALL_MASK
  127.  
  128. DrawTable   dd  DrawMR,
  129.                 DrawMR,
  130.                 DrawMR,
  131.                 DrawM,
  132.                 DrawLMR,
  133.                 DrawLMR,
  134.                 DrawLMR,
  135.                 DrawLM,
  136.                 DrawLMR,
  137.                 DrawLMR,
  138.                 DrawLMR,
  139.                 DrawLM,
  140.                 DrawLMR,
  141.                 DrawLMR,
  142.                 DrawLMR,
  143.                 DrawLM
  144.  
  145. _DATA   ENDS
  146.  
  147. DGROUP  GROUP _DATA
  148.  
  149.  
  150. _TEXT   SEGMENT BYTE PUBLIC USE32 'CODE'
  151.  
  152.         ASSUME  DS:_DATA
  153.         ASSUME  CS:_TEXT
  154.  
  155. PUBLIC  gr_sync_display_
  156.  
  157. gr_sync_display_:
  158.  
  159.         push    ax
  160.         push    dx
  161.         mov     dx, VERT_RESCAN
  162. VS2A:   in      al, dx
  163.         and     al, 08h
  164.         jnz     VS2A        ; Loop until not in vertical retrace
  165. VS2B:   in      al, dx
  166.         and     al, 08h
  167.         jz      VS2B        ; Loop until in vertical retrace
  168.  
  169.         pop     dx
  170.         pop     ax
  171.         ret
  172.  
  173.  
  174. PUBLIC  gr_modex_uscanline_
  175.  
  176. gr_modex_uscanline_:
  177.         push    edi
  178.  
  179.         ; EAX = X1  (X1 and X2 don't need to be sorted)
  180.         ; EDX = X2
  181.         ; EBX = Y
  182.         ; ECX = Color
  183.  
  184.         mov     SavedColor, cl
  185.  
  186.         ;mov     ebx, _RowOffset[ebx*4]
  187.         mov    edi, _gr_var_bwidth
  188.         imul    edi, ebx
  189.         add     edi, 0A0000h
  190.         cmp     eax, edx
  191.         jle     @f
  192.         xchg    eax, edx
  193. @@:     mov     bl, al
  194.         shl     bl, 2
  195.         mov     bh, dl
  196.         and     bh, 011b
  197.         or      bl, bh
  198.         and     ebx, 0fh
  199.         ; BX = LeftRight switch command. (4bit)
  200.         shr     eax, 2
  201.         shr     edx, 2
  202.         add     edi, eax
  203.         ; EDI = Offset into video memory
  204.         mov     ecx, edx
  205.         sub     ecx, eax
  206.         ; ECX = X2/4 - X1/4 - 1
  207.         jnz     LargerThan4
  208.  
  209. ;======================= ONE GROUP OF 4 OR LESS TO DRAW ====================
  210.  
  211.         mov     dx, SC_INDEX
  212.         mov     al, SC_MAP_MASK
  213.         out     dx, al
  214.         inc     dx
  215.         mov     al, MaskTable1[ebx]
  216.         out     dx, al
  217.         mov     al, SavedColor
  218.         mov     [edi], al           ; Write the one pixel
  219.         pop     edi
  220.         ret
  221.  
  222. LargerThan4:
  223.         dec     ecx
  224.         jnz     LargerThan8
  225.  
  226. ;===================== TWO GROUPS OF 4 OR LESS TO DRAW ====================
  227.  
  228.         mov     cx, WORD PTR MaskTable2[ebx*2]
  229.         mov     bl, SavedColor
  230.         mov     dx, SC_INDEX
  231.         mov     al, SC_MAP_MASK
  232.         out     dx, al
  233.         inc     dx
  234.         mov     al, cl
  235.         out     dx, al
  236.         mov     [edi], bl           ; Write the left pixel
  237.         mov     al, ch
  238.         out     dx, al
  239.         mov     [edi+1], bl         ; Write the right pixel
  240.         pop     edi
  241.         ret
  242.  
  243. ;========================= MANY GROUPS OF 4 TO DRAW ======================
  244. LargerThan8:
  245.         mov     dx, SC_INDEX
  246.         mov     al, SC_MAP_MASK
  247.         out     dx, al
  248.         inc     dx
  249.         ; DX = SC_INDEX
  250.         mov     al, SavedColor
  251.         mov     ah, al
  252.         ; AL,AH = color of pixel
  253.         jmp     NEAR32 PTR DrawTable[ebx*4]
  254.  
  255.  
  256. DrawM:  ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index
  257.         mov     al, ALL_MASK
  258.         out     dx, al
  259.         mov     al, ah
  260.         cld
  261.         add     ecx, 2
  262.         shr     ecx, 1
  263.         rep     stosw       ; Write the middle pixels
  264.         jnc     @F
  265.         stosb               ; Write the middle odd pixel
  266. @@:     pop     edi
  267.         ret
  268.  
  269. DrawLM:
  270.         ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index
  271.         mov     al, BYTE PTR MaskTable2[ebx*2]
  272.         out     dx, al
  273.         mov     [edi], ah       ; Write leftmost pixels
  274.         inc     edi
  275.         mov     al, ALL_MASK
  276.         out     dx, al
  277.         mov     al, ah
  278.         cld
  279.         inc     ecx
  280.         shr     ecx, 1
  281.         rep     stosw       ; Write the middle pixels
  282.         jnc     @F
  283.         stosb               ; Write the middle odd pixel
  284. @@:     pop     edi
  285.         ret
  286.  
  287.  
  288. DrawLMR: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index
  289.         mov     bx, WORD PTR MaskTable2[ebx*2]
  290.         mov     al, bl
  291.         out     dx, al
  292.         mov     [edi], ah       ; Write leftmost pixels
  293.         inc     edi
  294.         mov     al, ALL_MASK
  295.         out     dx, al
  296.         mov     al, ah
  297.         cld
  298.         shr     ecx, 1
  299.         rep     stosw       ; Write the middle pixels
  300.         jnc     @F
  301.         stosb               ; Write the middle odd pixel
  302. @@:     mov     al, bh
  303.         out     dx, al
  304.         mov     [edi], ah   ; Write the rightmost pixels
  305.         pop     edi
  306.         ret
  307.  
  308. DrawMR: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index
  309.         mov     bx, WORD PTR MaskTable2[ebx*2]
  310.         mov     al, ALL_MASK
  311.         out     dx, al
  312.         mov     al, ah
  313.         cld
  314.         inc     ecx
  315.         shr     ecx, 1
  316.         rep     stosw       ; Write the middle pixels
  317.         jnc     @F
  318.         stosb               ; Write the middle odd pixel
  319. @@:     mov     al, bh
  320.         out     dx, al
  321.         mov     [edi], ah   ; Write the rightmost pixels
  322.         pop     edi
  323.         ret
  324.  
  325.  
  326. PUBLIC gr_modex_setmode_
  327.  
  328. gr_modex_setmode_:
  329.  
  330.     push  ebx
  331.     push  ecx
  332.     push  edx
  333.     push  esi
  334.     push  edi
  335.  
  336.     mov   ecx, eax
  337.     dec   ecx
  338.  
  339.     cmp   ecx, LAST_X_MODE
  340.     jbe   @f
  341.     mov   ecx, 0
  342. @@:
  343.  
  344.     ;call  turn_screen_off
  345.  
  346.     push  ecx                   ; some bios's dont preserve cx
  347.  
  348.     ;mov ax, 1201h
  349.     ;mov bl, 31h     ; disable palette loading at mode switch
  350.     ;int 10h
  351.     mov   ax,13h                ; let the BIOS set standard 256-color
  352.     int   10h                   ;  mode (320x200 linear)
  353.     ;mov ax, 1200h
  354.     ;mov bl, 31h     ; enable palette loading at mode switch
  355.     ;int 10h
  356.  
  357.     pop   ecx
  358.  
  359.     mov   dx,SC_INDEX
  360.     mov   ax,0604h
  361.     out   dx,ax                 ; disable chain4 mode
  362.  
  363.     mov   dx,SC_INDEX
  364.     mov   ax,0100h
  365.     out   dx,ax                 ; synchronous reset while setting Misc
  366.                                 ;  Output for safety, even though clock
  367.                                 ;  unchanged
  368.  
  369.     mov   esi, dword ptr ModeTable[ecx*4]
  370.     lodsb
  371.  
  372.     or    al,al
  373.     jz    DontSetDot
  374.  
  375.     mov   dx,MISC_OUTPUT
  376.     out   dx,al               ; select the dot clock and Horiz
  377.                               ;  scanning rate
  378.  
  379.     ;mov   dx,SC_INDEX
  380.     ;mov   al,01h
  381.     ;out   dx,al
  382.     ;inc   dx
  383.     ;in    al, dx
  384.     ;or    al, 1000b
  385.     ;out   dx, al
  386.  
  387. DontSetDot:
  388.     mov   dx,SC_INDEX
  389.     mov   ax,0300h
  390.     out   dx,ax        ; undo reset (restart sequencer)
  391.  
  392.     mov   dx,CRTC_INDEX       ; reprogram the CRT Controller
  393.     mov   al,11h              ; VSync End reg contains register write
  394.     out   dx,al               ; protect bit
  395.     inc   dx                  ; CRT Controller Data register
  396.     in    al,dx               ; get current VSync End register setting
  397.     and   al,07fh             ; remove write protect on various
  398.     out   dx,al               ; CRTC registers
  399.     dec   dx                  ; CRT Controller Index
  400.     cld
  401.     xor   ecx,ecx
  402.     lodsb
  403.     mov   cl,al
  404.  
  405. SetCRTParmsLoop:
  406.     lodsw                     ; get the next CRT Index/Data pair
  407.     out   dx,ax               ; set the next CRT Index/Data pair
  408.     loop  SetCRTParmsLoop
  409.  
  410.     mov   dx,SC_INDEX
  411.     mov   ax,0f02h
  412.     out   dx,ax       ; enable writes to all four planes
  413.     mov   edi, 0A0000h        ; point ES:DI to display memory
  414.     xor   ax,ax               ; clear to zero-value pixels
  415.     mov   ecx,8000h           ; # of words in display memory
  416.     rep   stosw               ; clear all of display memory
  417.  
  418.     ;  Set pysical screen dimensions
  419.  
  420.     xor   eax, eax
  421.     lodsw                               ; Load scrn pixel width
  422.     mov   cx, ax
  423.     shl   eax, 16
  424.  
  425.     mov   dx,CRTC_INDEX
  426.     mov   al,CRTC_OFFSET
  427.     out   dx,al
  428.     inc   dx
  429.     mov   ax,cx
  430.     shr   ax,3
  431.     out   dx,al
  432.  
  433.     ;mov     si, 360
  434.     ;@@:
  435.     ;mov     ax, 04f06h
  436.     ;mov     bl, 0
  437.     ;mov     cx, si
  438.     ;int     10h
  439.     ;cmp     cx, si
  440.     ;je      @f
  441.     ;inc     si
  442.     ;jmp     @B
  443.     ;@@:
  444.     ;movzx     eax, si
  445.  
  446.     lodsw                               ; Load Screen Phys. Height
  447.  
  448.     ;call  turn_screen_on
  449.  
  450.     pop  edi
  451.     pop  esi
  452.     pop  edx
  453.     pop  ecx
  454.     pop  ebx
  455.  
  456.     ret
  457.  
  458. PUBLIC gr_modex_setplane_
  459.  
  460. gr_modex_setplane_:
  461.  
  462.         push    cx
  463.         push    dx
  464.  
  465.         mov     cl, al
  466.  
  467.         ; SELECT WRITE PLANE
  468.         and     cl,011b             ;CL = plane
  469.         mov     ax,0100h + MAP_MASK ;AL = index in SC of Map Mask reg
  470.         shl     ah,cl               ;set only the bit for the required
  471.                                     ; plane to 1
  472.         mov     dx,SC_INDEX         ;set the Map Mask to enable only the
  473.        out     dx,ax               ; pixel's plane
  474.  
  475.         ; SELECT READ PLANE
  476.         mov     ah,cl               ;AH = plane
  477.         mov     al,READ_MAP         ;AL = index in GC of the Read Map reg
  478.         mov     dx,GC_INDEX         ;set the Read Map to read the pixel's
  479.         out     dx,ax               ; plane
  480.  
  481.         pop     dx
  482.         pop     cx
  483.  
  484.         ret
  485.  
  486. PUBLIC  gr_modex_setstart_
  487.  
  488. gr_modex_setstart_:
  489.  
  490.         ; EAX = X
  491.         ; EDX = Y
  492.         ; EBX = Wait for retrace
  493.  
  494.         push    ebx
  495.         push    ecx
  496.         push    ebx
  497.  
  498.         mov    ecx, _gr_var_bwidth
  499.         imul    ecx, edx
  500.  
  501.         shr     eax, 2
  502.         add     eax, ecx
  503.  
  504.         mov     ch, ah
  505.         mov     bh, al
  506.  
  507.         mov     bl, CC_START_LO
  508.         mov     cl, CC_START_HI
  509.  
  510.         cli
  511.         mov     dx, VERT_RESCAN
  512. WaitDE: in      al, dx
  513.         test    al, 01h
  514.         jnz     WaitDE
  515.  
  516.         mov     dx, CRTC_INDEX
  517.         mov     ax, bx
  518.         out     dx, ax      ; Start address low
  519.         mov     ax, cx
  520.         out     dx, ax      ; Start address high
  521.         sti
  522.  
  523.         pop    ebx
  524.         cmp    ebx, 0
  525.         je    NoWaitVS
  526.         mov     dx, VERT_RESCAN
  527. WaitVS: in      al, dx
  528.         test    al, 08h
  529.         jz      WaitVS      ; Loop until in vertical retrace
  530. NoWaitVS:
  531.  
  532.         pop     ecx
  533.         pop     ebx
  534.  
  535.         ret
  536.  
  537.  
  538.  
  539.  
  540. ModeXAddr       macro
  541. ; given: ebx=x, eax=y, return cl=plane mask, ebx=address, trash eax
  542.     mov    cl, bl
  543.     and    cl, 3
  544.     shr    ebx, 2
  545.     imul    eax, _gr_var_bwidth 
  546.     add    ebx, eax
  547.     add    ebx, 0A0000h
  548.     endm
  549.  
  550.  
  551. ;-----------------------------------------------------------------------
  552. ;
  553. ; Line drawing function for all MODE X 256 Color resolutions
  554. ; Based on code from "PC and PS/2 Video Systems" by Richard Wilton.
  555.  
  556. PUBLIC gr_modex_line_
  557.  
  558. gr_modex_line_:
  559.     pusha
  560.  
  561.     mov    dx,SC_INDEX    ; setup for plane mask access
  562.  
  563. ; check for vertical line
  564.  
  565.     mov    esi,_gr_var_bwidth
  566.     mov    ecx,_modex_line_x2
  567.     sub    ecx,_modex_line_x1
  568.     jz    VertLine
  569.  
  570. ; force x1 < x2
  571.  
  572.     jns    L01
  573.  
  574.     neg    ecx
  575.  
  576.     mov    ebx,_modex_line_x2
  577.     xchg    ebx,_modex_line_x1
  578.     mov    _modex_line_x2,ebx
  579.  
  580.     mov    ebx,_modex_line_y2
  581.     xchg    ebx,_modex_line_y1
  582.     mov    _modex_line_y2,ebx
  583.  
  584. ; calc dy = abs(y2 - y1)
  585.  
  586. L01:
  587.     mov    ebx,_modex_line_y2
  588.     sub    ebx,_modex_line_y1
  589.     jnz    short skip
  590.     jmp     HorizLine
  591. skip:        jns    L03
  592.  
  593.     neg    ebx
  594.     neg    esi
  595.  
  596. ; select appropriate routine for slope of line
  597.  
  598. L03:
  599.     mov    _modex_line_vertincr,esi
  600.     mov    _modex_line_routine,offset LoSlopeLine
  601.     cmp    ebx,ecx
  602.     jle    L04
  603.     mov    _modex_line_routine,offset HiSlopeLine
  604.     xchg    ebx,ecx
  605.  
  606. ; calc initial decision variable and increments
  607.  
  608. L04:
  609.     shl    ebx,1
  610.     mov    _modex_line_incr1,ebx
  611.     sub    ebx,ecx
  612.     mov    esi,ebx
  613.     sub    ebx,ecx
  614.     mov    _modex_line_incr2,ebx
  615.  
  616. ; calc first pixel address
  617.  
  618.     push    ecx
  619.     mov    eax,_modex_line_y1
  620.     mov    ebx,_modex_line_x1
  621.     ModeXAddr
  622.     mov    edi,ebx
  623.     mov    al,1
  624.     shl    al,cl
  625.     mov    ah,al        ; duplicate nybble
  626.     shl    al,4
  627.     add    ah,al
  628.     mov    bl,ah
  629.     pop    ecx
  630.     inc    ecx
  631.     jmp    [_modex_line_routine]
  632.  
  633. ; routine for verticle lines
  634.  
  635. VertLine:
  636.     mov    eax,_modex_line_y1
  637.     mov    ebx,_modex_line_y2
  638.     mov    ecx,ebx
  639.     sub    ecx,eax
  640.     jge    L31
  641.     neg    ecx
  642.     mov    eax,ebx
  643.  
  644. L31:
  645.     inc    ecx
  646.     mov    ebx,_modex_line_x1
  647.     push    ecx
  648.     ModeXAddr
  649.  
  650.     mov    ah,1
  651.     shl    ah,cl
  652.     mov    al,MAP_MASK
  653.     out    dx,ax
  654.     pop    ecx
  655.     mov    ax, word ptr _modex_line_Color
  656.  
  657. ; draw the line
  658.  
  659. L32:
  660.     mov    [ebx],al
  661.     add    ebx,esi
  662.     loop    L32
  663.     jmp    Lexit
  664.  
  665. ; routine for horizontal line
  666.  
  667. HorizLine:
  668.  
  669.     mov    eax,_modex_line_y1
  670.     mov    ebx,_modex_line_x1
  671.     ModeXAddr
  672.  
  673.     mov    edi,ebx     ; set dl = first byte mask
  674.     mov    dl,00fh
  675.     shl    dl,cl
  676.  
  677.     mov    ecx,_modex_line_x2 ; set dh = last byte mask
  678.     and    cl,3
  679.     mov    dh,00eh
  680.     shl    dh,cl
  681.     not    dh
  682.  
  683. ; determine byte offset of first and last pixel in line
  684.  
  685.     mov    eax,_modex_line_x2
  686.     mov    ebx,_modex_line_x1
  687.  
  688.     shr    eax,2     ; set ax = last byte column
  689.     shr    ebx,2    ; set bx = first byte column
  690.     mov    ecx,eax    ; cx = ax - bx
  691.     sub    ecx,ebx
  692.  
  693.     mov        eax,edx    ; mov end byte masks to ax
  694.     mov    dx,SC_INDEX ; setup dx for VGA outs
  695.     mov     bl,_modex_line_Color
  696.  
  697. ; set pixels in leftmost byte of line
  698.  
  699.     or    ecx,ecx      ; is start and end pt in same byte
  700.     jnz    L42        ; no !
  701.     and    ah,al      ; combine start and end masks
  702.     jmp    short L44
  703.  
  704. L42:            push    eax
  705.     mov     ah,al
  706.     mov     al,MAP_MASK
  707.     out     dx,ax
  708.     mov    al,bl
  709.     stosb
  710.     dec    ecx
  711.  
  712. ; draw remainder of the line
  713.  
  714. L43:
  715.     mov    ah,0Fh
  716.     mov    al,MAP_MASK
  717.     out    dx,ax
  718.     mov    al,bl
  719.     rep    stosb
  720.     pop     eax
  721.  
  722. ; set pixels in rightmost byte of line
  723.  
  724. L44:    
  725.     mov    al,MAP_MASK
  726.     out    dx, ax
  727.     mov     byte ptr [edi],bl
  728.     jmp    Lexit
  729.  
  730.  
  731. ; routine for dy >= dx (slope <= 1)
  732.  
  733. LoSlopeLine:
  734.     mov    al,MAP_MASK
  735.     mov    bh,byte ptr _modex_line_Color
  736. L10:
  737.     mov    ah,bl
  738.  
  739. L11:
  740.     or    ah,bl
  741.     rol    bl,1
  742.     jc    L14
  743.  
  744. ; bit mask not shifted out
  745.  
  746.     or    esi,esi
  747.     jns    L12
  748.     add    esi,_modex_line_incr1
  749.     loop    L11
  750.  
  751.     out    dx,ax
  752.     mov    [edi],bh
  753.     jmp    short Lexit
  754.  
  755. L12:
  756.     add    esi,_modex_line_incr2
  757.     out    dx,ax
  758.     mov    [edi],bh
  759.     add    edi,_modex_line_vertincr
  760.     loop    L10
  761.     jmp    short Lexit
  762.  
  763. ; bit mask shifted out
  764.  
  765. L14:            out    dx,ax
  766.     mov    [edi],bh
  767.     inc    edi
  768.     or    esi,esi
  769.     jns    L15
  770.     add    esi,_modex_line_incr1
  771.     loop    L10
  772.     jmp    short Lexit
  773.  
  774. L15:
  775.     add    esi,_modex_line_incr2
  776.     add    edi,_modex_line_vertincr
  777.     loop    L10
  778.     jmp    short Lexit
  779.  
  780. ; routine for dy > dx (slope > 1)
  781.  
  782. HiSlopeLine:
  783.     mov    ebx,_modex_line_vertincr
  784.     mov    al,MAP_MASK
  785. L21:    out    dx,ax
  786.     push    eax
  787.     mov    al,_modex_line_Color
  788.     mov    [edi],al
  789.     pop    eax
  790.     add    edi,ebx
  791.  
  792. L22:
  793.     or    esi,esi
  794.     jns    L23
  795.  
  796.     add    esi,_modex_line_incr1
  797.     loop    L21
  798.     jmp    short Lexit
  799.  
  800. L23:
  801.     add    esi,_modex_line_incr2
  802.     rol    ah,1
  803.     adc    edi,0
  804. lx21:    loop    L21
  805.  
  806. ; return to caller
  807.  
  808. Lexit:
  809.     popa
  810.     ret
  811.  
  812.  
  813.  
  814. _TEXT   ENDS
  815.  
  816.  
  817.         END
  818. 
  819.