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