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