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