]> icculus.org git repositories - btb/d2x.git/blob - unused/vga/vesa.asm
Cygwin support, using SDL.
[btb/d2x.git] / unused / vga / vesa.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 .386
12
13 OPTION OLDSTRUCTS
14 INCLUDE VGAREGS.INC
15 INCLUDE GR.INC
16
17 _DATA   SEGMENT BYTE PUBLIC USE32 'DATA'
18
19                 PUBLIC      __A0000
20                 __A0000      dw  ?
21
22                 BufferPtr   dd  0
23                 BufferSeg   dw  0
24                 GoalMode    dw  ?
25                 LastPage    db  0FFh
26
27                 BPR         dw  ?
28                 TempReg     dd  ?
29
30                 ; Information from VESA return SuperVGA Information
31
32                 VESAVersion         dw  ?
33                 OEMStringPtr        dd  ?
34                 Capabilities        dd  ?
35                 VideoModePtr        dd  ?
36                 TotalMemory         dw  ?
37                 WinGranularity      dw  ?
38                 WinSize             dw  ?
39                 WinFuncPtr          dd  ?
40                 PageSizeShift       db  ?
41                 WinAttributes       dw  ?
42                 
43
44                 VESA_Signature      = 041534556h
45
46 REALREGS    STRUCT
47                 RealEDI     dd      ?
48                 RealESI     dd      ?
49                 RealEBP     dd      ?
50                 Reserved    dd      ?
51                 RealEBX     dd      ?
52                 RealEDX     dd      ?
53                 RealECX     dd      ?
54                 RealEAX     dd      ?
55                 RealFlags   dw      ?
56                 RealES      dw      ?
57                 RealDS      dw      ?
58                 RealFS      dw      ?
59                 RealGS      dw      ?
60                 RealIP      dw      ?
61                 RealCS      dw      ?
62                 RealSP      dw      ?
63                 RealSS      dw      ?
64 REALREGS    ENDS
65
66                 regs    REALREGS    < >
67
68                 vesa_error      dd      ?
69                 SourceInc   dd  ?
70                 DestInc     dw  ?
71                 RowWidth    dd  ?
72
73                 extern _gr_var_color:dword, _gr_var_bwidth:dword
74
75
76 _DATA   ENDS
77
78 DGROUP  GROUP _DATA
79
80
81 _TEXT   SEGMENT BYTE PUBLIC USE32 'CODE'
82
83                 ASSUME  DS:_DATA
84                 ASSUME  CS:_TEXT
85
86 MyStosd MACRO Width:REQ
87 ; Assumes:   EDI = Dest Address
88 ;            Width = a 32-bit value, can't be ECX or EDI
89 ; Trashes:   ECX will be zero
90 ;            EDI = Dest Address + Width
91 ;            EDX = ????
92 ;            Width
93 LOCAL Aligned
94                         cmp     Width, 16
95                         jbe     Aligned
96                         mov     ecx, edi
97                         and     ecx, 3
98                         jcxz    Aligned
99                         neg     ecx
100                         add     ecx, 4
101                         sub     Width, ecx
102                         rep     stosb
103 Aligned:                mov     ecx, Width
104                         shr     ecx, 2
105                         rep     stosd
106                         mov     ecx, Width
107                         and     ecx, 3
108                         rep     stosb
109 ENDM
110
111
112 ENTER_PROC  MACRO
113                         push    esi
114                         push    edi
115                         push    ebp
116                         push    eax
117                         push    ebx
118                         push    ecx
119                         push    edx
120 ENDM
121
122 EXIT_PROC   MACRO
123
124                         cmp     [esp-4], edx
125                         je      @f
126                         ; YOU TRASHED EDX !!!!!!!
127                         int     3
128 @@:         pop     edx
129
130                         cmp     [esp-4], ecx
131                         je      @f
132                         ; YOU TRASHED ECX !!!!!!!
133                         int     3
134 @@:         pop     ecx
135
136                         cmp     [esp-4], ebx
137                         je      @f
138                         ; YOU TRASHED EBX !!!!!!!
139                         int     3
140 @@:         pop     ebx
141
142                         cmp     [esp-4], eax
143                         je      @f
144                         ; YOU TRASHED EAX !!!!!!!
145                         int     3
146 @@:         pop     eax
147
148                         cmp     [esp-4], ebp
149                         je      @f
150                         ; YOU TRASHED EBP !!!!!!!
151                         int     3
152 @@:         pop     ebp
153
154                         cmp     [esp-4], edi
155                         je      @f
156                         ; YOU TRASHED EDI !!!!!!!
157                         int     3
158 @@:         pop     edi
159
160                         cmp     [esp-4], esi
161                         je      @f
162                         ; YOU TRASHED ESI !!!!!!!
163                         int     3
164 @@:         pop     esi
165
166 ENDM
167
168
169 MyMovsd MACRO Width:REQ
170 ; Assumes:   EDI = Dest Address
171 ;            ESI = Source Address
172 ;            Width = a 32-bit value, can't be ECX or EDI or ESI
173 ;            Assumes that ESI is already aligned
174 ; Trashes:   ECX will be zero
175 ;            EDI = Dest Address + Width
176 ;            ESI = Source Address + Width
177 ;            EDX = ????
178 LOCAL Aligned
179                         cmp     Width, 16
180                         jbe     Aligned
181                         mov     ecx, edi
182                         and     ecx, 3
183                         jcxz    Aligned
184                         neg     ecx
185                         add     ecx, 4
186                         sub     Width, ecx
187                         rep     movsb
188 Aligned:    mov     ecx, Width
189                         shr     ecx, 2
190                         rep     movsd
191                         mov     ecx, Width
192                         and     ecx, 3
193                         rep     movsb
194 ENDM
195
196
197 EBXFarTo32:
198                         push    ecx
199                         mov     ecx, ebx
200                         and     ecx, 0FFFF0000h
201                         shr     ecx, 12
202                         and     ebx, 0FFFFh
203                         add     ebx, ecx
204                         pop     ecx
205                         ret
206
207 PUBLIC  gr_init_A0000_
208
209 gr_init_A0000_:
210
211                         push    ebx
212                         mov     ax, 0002h
213                         mov     bx, 0a000h
214                         int     31h
215                         jc      NoGo
216                         mov     __A0000, ax
217                         pop     ebx
218                         xor     eax, eax
219                         ret
220 NoGo:       pop     ebx
221                         mov     eax, 1
222                         ret
223
224 PUBLIC  gr_vesa_checkmode_
225
226 gr_vesa_checkmode_:
227                         pushad
228
229                         mov     GoalMode, ax
230                         cmp     BufferSeg, 0
231                         jne     GotDosMemory
232
233                         ; Allocate a 256 byte block of DOS memory using DPMI
234                         mov     ax, 0100h
235                         mov     bx, 16
236                         int     31h
237                         jc      NoMemory
238
239                         ; AX = real mode segment of allocated block
240                         and     eax, 0FFFFh
241                         mov     BufferSeg, ax
242                         shl     eax, 4      ; EAX = 32-bit pointer to DOS memory
243                         mov     BufferPtr, eax
244 GotDosMemory:
245
246
247                         ; Get SuperVGA information
248                         mov     ax, BufferSeg
249                         mov     regs.RealEDI, 0
250                         mov     regs.RealESI, 0
251                         mov     regs.RealEBP, 0
252                         mov     regs.Reserved, 0
253                         mov     regs.RealEBX, 0
254                         mov     regs.RealEDX, 0
255                         mov     regs.RealECX, 0
256                         mov     regs.RealEAX, 04f00h
257                         mov     regs.RealFlags, 0
258                         mov     regs.RealES, ax
259                         mov     regs.RealDS, 0
260                         mov     regs.RealFS, 0
261                         mov     regs.RealGS, 0
262                         mov     regs.RealIP, 0
263                         mov     regs.RealCS, 0
264                         mov     regs.RealSP, 0
265                         mov     regs.RealSS, 0
266
267                         mov     bl, 10h
268                         xor     bh, bh
269                         xor     ecx, ecx
270                         mov     edi, offset regs
271                         mov     ax, 0300h
272                         int     31h
273
274                         mov     eax, regs.RealEAX
275                         cmp     ax, 04fh
276                         jne     NoVESADriver
277
278                         ; Make sure there is a VESA signature
279                         mov     eax, BufferPtr
280                         cmp     dword ptr[eax+0], VESA_Signature
281                         jne     NoVESADriver
282
283                         ; We now have a valid VESA driver loaded
284
285                         mov     bx, word ptr [eax+4]
286                         mov     VESAVersion, bx
287
288                         mov     ebx, dword ptr [eax+6]
289                         call    EBXFarTo32
290                         mov     OEMStringPtr, ebx
291
292                         mov     ebx, dword ptr [eax+10]
293                         mov     Capabilities, ebx
294
295                         mov     bx, word ptr [eax+18]
296                         mov     TotalMemory, bx
297
298                         mov     ebx, dword ptr [eax+14]
299                         call    EBXFarTo32
300                         mov     VideoModePtr, ebx
301
302 TryAnotherMode:
303                         mov     ax, word ptr [ebx]
304                         add     ebx, 2
305                         cmp     ax, GoalMode
306                         je      ModeSupported
307                         cmp     ax, -1
308                         je      ModeNotSupported
309                         jmp     TryAnotherMode
310
311 ModeSupported:
312
313                         ; Get SuperVGA information
314                         mov     ax, BufferSeg
315                         movzx   ecx, GoalMode
316                         mov     regs.RealEDI, 0
317                         mov     regs.RealESI, 0
318                         mov     regs.RealEBP, 0
319                         mov     regs.Reserved, 0
320                         mov     regs.RealEBX, 0
321                         mov     regs.RealEDX, 0
322                         mov     regs.RealECX, ecx
323                         mov     regs.RealEAX, 04f01h
324                         mov     regs.RealFlags, 0
325                         mov     regs.RealES, ax
326                         mov     regs.RealDS, 0
327                         mov     regs.RealFS, 0
328                         mov     regs.RealGS, 0
329                         mov     regs.RealIP, 0
330                         mov     regs.RealCS, 0
331                         mov     regs.RealSP, 0
332                         mov     regs.RealSS, 0
333
334                         mov     bl, 10h
335                         xor     bh, bh
336                         xor     cx, cx
337                         mov     edi, offset regs
338                         mov     ax, 0300h
339                         int     31h
340
341                         mov     eax, regs.RealEAX
342                         cmp     ax, 04fh
343                         jne     BadStatus
344
345                         ; Check if this mode supported by hardware.
346                         mov     eax, BufferPtr
347                         mov     bx, [eax]
348                         bt      bx, 0
349                         jnc     HardwareNotSupported
350
351
352                         mov     bx, [eax+4]
353                         cmp     bx, 64
354                         jne     @f
355                         mov     PageSizeShift, 0
356                         jmp     GranularityOK
357 @@:                     cmp     bx, 32
358                         jne     @f
359                         mov     PageSizeShift, 1
360                         jmp     GranularityOK
361 @@:                     cmp     bx, 16
362                         jne     @f
363                         mov     PageSizeShift, 2
364                         jmp     GranularityOK
365 @@:                     cmp     bx, 8
366                         jne     @f
367                         mov     PageSizeShift, 3
368                         jmp     GranularityOK
369 @@:                     cmp     bx, 4
370                         jne     @f
371                         mov     PageSizeShift, 4
372                         jmp     GranularityOK
373 @@:                     cmp     bx, 2
374                         jne     @f
375                         mov     PageSizeShift, 5
376                         jmp     GranularityOK
377 @@:                     cmp     bx, 1
378                         jne     WrongGranularity
379                         mov     PageSizeShift, 6
380
381 GranularityOK:
382                         shl     bx, 10
383                         mov     WinGranularity, bx
384
385                         mov     bx, [eax+6]
386                         mov     WinSize, bx
387
388                         mov     ebx, [eax+12]
389                         call    EBXFarTo32
390                         mov     WinFuncPtr, ebx
391
392                         mov     bl, byte ptr [eax+2]
393                         mov     bh, byte ptr [eax+3]
394                         mov     word ptr WinAttributes, bx
395
396                         movzx   ebx, word ptr [eax+16]
397
398 NoError:
399                         mov     vesa_error, 0
400                         jmp     Done
401
402 WrongGranularity:
403                         mov     vesa_error, 2
404                         jmp     Done
405
406 HardwareNotSupported:
407                         mov     vesa_error, 3
408                         jmp     Done
409
410 ModeNotSupported:
411                         mov     vesa_error, 4
412                         jmp     Done
413
414 NoVESADriver:
415                         mov     vesa_error, 5
416                         jmp     Done
417
418 BadStatus:
419                         mov     vesa_error, 6
420                         jmp     Done
421
422 NoMemory:
423                         mov     vesa_error, 7
424                         jmp     Done
425
426 DPMIError:
427                         mov     vesa_error, 8
428
429 Done:                   popad
430                         mov     eax, vesa_error
431
432                         ret
433
434 PUBLIC  gr_get_dos_mem_
435
436 gr_get_dos_mem_:
437                         
438                 ; eax = how many bytes
439
440                 push    ebx
441                 
442                 mov     ebx, eax
443                 shr     ebx, 4
444                 mov     eax, 0100h
445                 int     31h
446                 jc      nomem
447                 and     eax, 0ffffh
448                 shl     eax, 4
449                 pop     ebx
450                 ret
451
452 nomem:          pop     ebx
453                 mov     eax,0
454                 ret
455                 
456
457
458
459 PUBLIC gr_vesa_setmodea_
460
461 gr_vesa_setmodea_:
462
463                 ; eax = mode
464                 pushad
465                 mov     LastPage,0ffh   ;force page reset  
466                 mov     ebx, eax                                
467                 mov     eax, 04f02h
468                 int     10h
469                 cmp     ax, 04fh
470                 jne     BadStatus
471                 jmp     NoError
472
473 PUBLIC  gr_vesa_setpage_
474
475 gr_vesa_setpage_:
476
477                         ; EAX = 64K Page number
478                         and     eax, 0ffh
479                         cmp     al, LastPage
480                         jne     @f
481                         ret
482 @@:                     mov     LastPage, al
483                         push    edx
484                         push    ebx
485                         push    ecx
486                         mov     edx, eax
487                         mov     cl, PageSizeShift
488                         shl     edx, cl         ; Convert from 64K pages to GranUnit pages.
489                         push    edx
490                         xor     ebx, ebx        ; BH=Select window, BL=Window A
491                         mov     eax, 04f05h     ; AX=Super VGA video memory window control
492                         int     10h
493
494                         ; New code to fix those ATI Mach64's with separate 
495                         ; read/write pages. 
496                         mov     bx, word ptr WinAttributes
497                         and     ebx, 0110b      ; Set if PageA can read and write
498                         cmp     ebx, 0110b      
499                         jne     WinACantReadAndWrite
500                         pop     edx
501                         pop     ecx
502                         pop     ebx
503                         pop     edx
504                         ret
505
506 WinACantReadAndWrite:   ; Page A can't read and write, so we need to update page B also!
507                         pop     edx             ; DX=Window
508                         mov     ebx, 1          ; BH=Select window, BL=Window B
509                         mov     eax, 04f05h     ; AX=Super VGA video memory window control
510                         int     10h
511                         pop     ecx
512                         pop     ebx
513                         pop     edx
514                         ret
515       
516 PUBLIC  gr_vesa_incpage_
517
518 gr_vesa_incpage_:
519                         push    eax
520                         xor     eax, eax
521                         mov     al, LastPage
522                         inc     eax
523                         call    gr_vesa_setpage_
524                         pop     eax
525                         ret
526
527 PUBLIC  gr_vesa_setstart_
528
529 gr_vesa_setstart_:
530
531                         ; EAX = First column
532                         ; EDX = First row
533                         push    ebx
534                         push    ecx
535                         mov     ecx, eax
536                         mov     eax, 4f07h
537                         xor     ebx, ebx
538                         int     10h
539                         pop     ecx
540                         pop     ebx
541                         ret
542
543
544 PUBLIC  gr_vesa_setlogical_
545
546 gr_vesa_setlogical_:
547
548                         ; EAX = line width
549                         push    ebx
550                         push    ecx
551                         push    edx
552
553                         mov     cx, ax
554                         mov     ax, 04f06h
555                         mov     bl, 0
556                         int     10h
557                         and     ebx, 0FFFFh
558                         mov     ax, cx
559
560                         pop     edx
561                         pop     ecx
562                         pop     ebx
563                         ret
564
565
566
567 PUBLIC gr_vesa_scanline_
568
569 gr_vesa_scanline_:
570
571                         ; EAX = x1
572                         ; EDX = x2
573                         ; EBX = y
574                         ; ECX = color
575
576                         push    edi
577                         cld
578                         cmp     edx, eax
579                         jge     @f
580                         xchg    edx, eax
581
582 @@:                     mov     edi, ebx
583                         imul    edi, _gr_var_bwidth
584                         add     edi, eax        ; EDI = y*bpr+x1
585                         sub     edx, eax        ; ECX = x2-x1
586                         inc     edx
587
588                         mov     eax, edi
589                         shr     eax, 16
590
591                         call    gr_vesa_setpage_
592
593                         and     edi, 00FFFFh
594                         or      edi, 0A0000h
595
596                         ;mov     eax, _Table8to32[ecx*4]
597                         mov     ch, cl
598                         mov     ax, cx
599                         shl     eax, 16
600                         mov     ax, cx
601
602                         ; edx = width in bytes
603                         ; edi = dest
604                         mov     bx, dx
605                         add     bx, di
606                         jnc     scanonepage
607
608                         sub     dx, bx
609                         movzx   ecx, dx
610                         
611                         shr     ecx, 1                  
612                         rep     stosw
613                         adc     ecx, ecx
614                         rep     stosb
615
616                         movzx   edx, bx
617                         cmp     edx, 0
618                         je      scandone
619
620                         call    gr_vesa_incpage_
621                         mov     edi, 0A0000h
622
623 scanonepage:
624                         movzx   ecx, dx
625
626                         shr     ecx, 1                  
627                         rep     stosw
628                         adc     ecx, ecx
629                         rep     stosb
630
631 scandone:
632
633                         pop     edi
634                         ret
635
636
637 PUBLIC gr_vesa_set_logical_
638
639 gr_vesa_set_logical_:
640
641                         ; EAX = logical width in pixels
642
643                         push    ebx
644                         push    ecx
645
646                         mov     ecx, eax
647                         mov     eax, 04f06h
648                         mov     bl, 0
649                         int     10h
650                         and     ebx, 0ffffh
651
652                         movzx   eax, cx
653
654                         pop     ecx
655                         pop     ebx
656
657                         ret
658
659
660 PUBLIC gr_vesa_pixel_
661
662 gr_vesa_pixel_:
663                         ; EAX = color (in AL)
664                         ; EDX = offset from 0A0000
665                         push    ebx
666                         mov     bl, al
667
668                         mov     eax, edx
669                         shr     eax, 16
670                         and     edx, 0ffffh
671
672                         call    gr_vesa_setpage_
673                         mov     [edx+0A0000h], bl
674                         pop     ebx
675                         ret
676
677 PUBLIC gr_vesa_bitblt_
678
679 gr_vesa_bitblt_:
680
681                         ; EAX = source_ptr
682                         ; EDX = vesa_address
683                         ; EBX = height
684                         ; ECX = width
685
686                         push    edi
687                         push    esi
688
689                         mov     esi, eax        ; Point ESI to source bitmap
690
691                         ; Set the initial page
692                         mov     eax, edx            ; Move offset into SVGA into eax
693                         shr     eax, 16             ; Page = offset / 64K
694                         call    gr_vesa_setpage_
695
696                         mov     edi, edx            ; EDI = offset into SVGA
697                         and     edi,  0FFFFh        ; EDI = offset into 64K page
698                         add     edi, 0A0000h        ; EDI = ptr to dest
699
700
701                         mov     edx, _gr_var_bwidth
702                         sub     edx, ecx            ; EDX = amount to step each row
703
704
705                         mov     eax, ecx
706
707 NextScanLine:
708                         push    eax
709                         MyMovsd eax
710                         pop     eax
711
712                         dec     ebx
713                         jz      DoneBlt
714
715                         add     di, dx
716                         jnc     NextScanLine
717
718                         ; Need to increment page!
719                         call    gr_vesa_incpage_
720                         jmp     NextScanLine
721
722 DoneBlt:    pop     esi
723                         pop     edi
724
725                         ret
726
727 PUBLIC gr_vesa_bitmap_
728
729 gr_vesa_bitmap_:
730
731                         ; EAX = Source bitmap       (LINEAR)
732                         ; EDX = Destination bitmap  (SVGA)
733                         ; EBX = x
734                         ; ECX = y
735
736                         push    esi
737                         push    edi
738                         push    ebp
739                         push    es
740
741                         push    eax
742                         mov     eax, [edx].bm_data
743                         imul    ecx, _gr_var_bwidth
744                         add     eax, ecx
745                         add     eax, ebx
746                         mov     edi, eax            ; EDI = offset into SVGA
747                         shr     eax, 16
748                         call    gr_vesa_setpage_
749
750                         mov     ax, __A0000
751                         mov     es, ax
752                         pop     eax
753
754                         mov     esi, [eax].bm_data
755                         and     edi, 0ffffh
756
757                         movzx   ecx, [eax].bm_h
758
759 NextScanLine1:
760                                 push    ecx
761                                 movzx   ecx, [eax].bm_w
762                                 mov     bx, cx
763                                 add     bx, di
764                                 jnc     OnePage
765
766                                 sub     cx,bx
767                                 mov     ebp, ecx
768                                 MyMovsd ebp
769                                 and     edi, 00ffffh        ; IN CASE IT WENT OVER 64K
770                                 mov     cx,bx
771                                 call    gr_vesa_incpage_
772                                 jcxz    DoneWithLine
773 OnePage:
774                                 mov     ebp, ecx
775                                 MyMovsd ebp
776                                 and     edi, 00ffffh        ; IN CASE IT WENT OVER 64K
777
778 DoneWithLine:   mov     bx, [eax].bm_rowsize
779                                 sub     bx, [eax].bm_w
780                                 and     ebx, 0ffffh
781                                 add     esi, ebx
782                                 mov     bx, [edx].bm_rowsize
783                                 sub     bx, [eax].bm_w
784                                 add     di, bx
785                                 jnc     NoPageInc
786                                 call    gr_vesa_incpage_
787 NoPageInc:  pop     ecx
788                         dec     ecx
789                         jz      @f
790                         jmp     NextScanLine1
791
792 @@:
793
794                         pop es
795                         pop ebp
796                         pop edi
797                         pop esi
798                         ret
799
800
801
802
803 PUBLIC gr_vesa_update_
804
805 gr_vesa_update_:
806
807                         ; EAX = Source bitmap       (LINEAR)
808                         ; EDX = Destination bitmap  (SVGA)
809                         ; EBX = Old source bitmap   (LINEAR)
810
811                         push    ecx
812                         push    esi
813                         push    edi
814                         push    ebp
815                         push    fs
816
817                         push    eax
818                         mov     eax, [edx].bm_data
819                         mov     ebp, eax            ; EDI = offset into SVGA
820                         shr     eax, 16
821                         call    gr_vesa_setpage_
822
823                         mov     ax, __A0000
824                         mov     fs, ax
825                         pop     eax
826
827                         mov     esi, [eax].bm_data
828                         and     ebp, 0ffffh
829
830                         movzx   ecx, [eax].bm_h
831
832                         mov     edi, [ebx].bm_data
833
834                         movzx   ebx, [eax].bm_rowsize
835                         sub     bx, [eax].bm_w
836                         mov     SourceInc, ebx
837
838                         movzx   ebx, [edx].bm_rowsize
839                         sub     bx, [eax].bm_w
840                         mov     DestInc, bx
841
842                         movzx   ebx, [eax].bm_w
843                         mov     RowWidth, ebx
844
845 NextScanLine3:
846                                 push    ecx
847                                 mov     ecx, RowWidth
848                                 mov     dx, cx
849                                 add     dx, bp
850                                 jnc     OnePage3
851
852                                 sub     cx,dx
853                                 mov     ebx, esi
854
855 InnerLoop3:     repe    cmpsb
856                                 mov     al, [esi-1]
857                                 sub     esi, ebx
858                                 mov     fs:[ebp+esi-1], al       ; EDX = dest + size - bytes to end
859                                 add     esi, ebx
860                                 cmp     ecx, 0
861                                 jne     InnerLoop3
862
863                                 sub     esi, ebx
864                                 add     ebp, esi
865                                 add     esi, ebx
866                                 and     ebp, 00ffffh        ; IN CASE IT WENT OVER 64K
867
868                                 mov     cx,dx
869                                 call    gr_vesa_incpage_
870                                 jcxz    DoneWithLine3
871 OnePage3:
872                                 mov     ebx, esi
873                                 mov     edx, ecx
874                                 and     edx, 11b
875                                 shr     ecx, 2
876
877 InnerLoop4:     repe    cmpsd
878                                 mov     eax, [esi-4]
879                                 sub     esi, ebx
880                                 mov     fs:[ebp+esi-4], eax       ; EDX = dest + size - bytes to end
881                                 add     esi, ebx
882                                 cmp     ecx, 0
883                                 jne     InnerLoop4
884
885                                 mov     ecx, edx
886                                 jecxz   EvenWidth
887 InnerLoop5:     repe    cmpsb
888                                 mov     al, [esi-1]
889                                 sub     esi, ebx
890                                 mov     fs:[ebp+esi-1], al       ; EDX = dest + size - bytes to end
891                                 add     esi, ebx
892                                 cmp     ecx, 0
893                                 jne     InnerLoop5
894
895 EvenWidth:      sub     esi, ebx
896                                 add     ebp, esi
897                                 add     esi, ebx
898                                 and     ebp, 00ffffh        ; IN CASE IT WENT OVER 64K
899
900 DoneWithLine3:
901                                 add     esi, SourceInc
902                                 add     edi, SourceInc
903                                 add     bp, DestInc
904                                 jnc     NoPageInc3
905                                 call    gr_vesa_incpage_
906 NoPageInc3: pop     ecx
907                         dec     ecx
908                         jnz     NextScanLine3
909
910                         pop     fs
911                         pop     ebp
912                         pop     edi
913                         pop     esi
914                         pop     ecx
915                         ret
916
917
918
919
920 _TEXT   ENDS
921
922
923                 END
924
925