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