Subversion Repositories Kolibri OS

Rev

Rev 2288 | Rev 2423 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;  VESA20.INC                                                  ;;
7
;;                                                              ;;
8
;;  Vesa 2.0 functions for MenuetOS                             ;;
9
;;                                                              ;;
10
;;  Copyright 2002 Ville Turjanmaa                              ;;
11
;;  Alexey, kgaz@crosswindws.net                                ;;
12
;;  - Voodoo compatible graphics                                ;;
13
;;  Juan M. Caravaca                                            ;;
14
;;  - Graphics optimimizations eg. drawline                     ;;
15
;;                                                              ;;
16
;;  See file COPYING for details                                ;;
17
;;                                                              ;;
18
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19
 
20
$Revision: 2353 $
21
 
22
 
23
; If you're planning to write your own video driver I suggest
24
; you replace the VESA12.INC file and see those instructions.
25
 
26
;Screen_Max_X             equ     0xfe00
27
;Screen_Max_Y            equ     0xfe04
28
;BytesPerScanLine        equ     0xfe08
29
;LFBAddress              equ     0xfe80
30
;ScreenBPP               equ     0xfbf1
31
 
32
 
33
 
34
;*************************************************
35
; getpixel
36
;
37
; in:
38
; eax = x coordinate
39
; ebx = y coordinate
40
;
41
; ret:
42
; ecx = 00 RR GG BB
43
 
44
getpixel:
45
        push    eax ebx edx edi
46
        call    dword [GETPIXEL]
47
        pop     edi edx ebx eax
48
        ret
49
 
50
Vesa20_getpixel24:
51
; eax = x
52
; ebx = y
53
        imul    ebx, [BytesPerScanLine] ; ebx = y * y multiplier
54
        lea     edi, [eax+eax*2]; edi = x*3
55
        add     edi, ebx      ; edi = x*3+(y*y multiplier)
56
        mov     ecx, [LFB_BASE+edi]
57
        and     ecx, 0xffffff
58
        ret
59
 
60
Vesa20_getpixel32:
61
        imul    ebx, [BytesPerScanLine] ; ebx = y * y multiplier
62
        lea     edi, [ebx+eax*4]; edi = x*4+(y*y multiplier)
63
        mov     ecx, [LFB_BASE+edi]
64
        and     ecx, 0xffffff
65
        ret
66
 
67
;*************************************************
68
 
69
virtual at esp
70
 putimg:
71
   .real_sx        dd ?
72
   .real_sy        dd ?
73
   .image_sx       dd ?
74
   .image_sy       dd ?
75
   .image_cx       dd ?
76
   .image_cy       dd ?
77
   .pti            dd ?
78
   .abs_cx         dd ?
79
   .abs_cy         dd ?
80
   .line_increment dd ?
81
   .winmap_newline dd ?
82
   .screen_newline dd ?
83
   .stack_data = 4*12
84
   .edi         dd      ?
85
   .esi         dd      ?
86
   .ebp         dd      ?
87
   .esp         dd      ?
88
   .ebx         dd      ?
89
   .edx         dd      ?
90
   .ecx         dd      ?
91
   .eax         dd      ?
92
   .ret_addr    dd      ?
93
   .arg_0       dd      ?
94
end virtual
95
 
96
align 16
97
; ebx = pointer
98
; ecx = size [x|y]
99
; edx = coordinates [x|y]
100
; ebp = pointer to 'get' function
101
; esi = pointer to 'init' function
102
; edi = parameter for 'get' function
103
 
104
vesa20_putimage:
105
        pushad
106
        call    [_display.disable_mouse]
107
        sub     esp, putimg.stack_data
108
; save pointer to image
109
        mov     [putimg.pti], ebx
110
; unpack the size
111
        mov     eax, ecx
112
        and     ecx, 0xFFFF
113
        shr     eax, 16
114
        mov     [putimg.image_sx], eax
115
        mov     [putimg.image_sy], ecx
116
; unpack the coordinates
117
        mov     eax, edx
118
        and     edx, 0xFFFF
119
        shr     eax, 16
120
        mov     [putimg.image_cx], eax
121
        mov     [putimg.image_cy], edx
122
; calculate absolute (i.e. screen) coordinates
123
        mov     eax, [TASK_BASE]
124
        mov     ebx, [eax-twdw + WDATA.box.left]
125
        add     ebx, [putimg.image_cx]
126
        mov     [putimg.abs_cx], ebx
127
        mov     ebx, [eax-twdw + WDATA.box.top]
128
        add     ebx, [putimg.image_cy]
129
        mov     [putimg.abs_cy], ebx
130
; real_sx = MIN(wnd_sx-image_cx, image_sx);
131
        mov     ebx, [eax-twdw + WDATA.box.width]; ebx = wnd_sx
132
; \begin{diamond}[20.08.2006]
133
; note that WDATA.box.width is one pixel less than real window x-size
134
        inc     ebx
135
; \end{diamond}[20.08.2006]
136
        sub     ebx, [putimg.image_cx]
137
        ja      @f
138
        add     esp, putimg.stack_data
139
        popad
140
        ret
141
@@:
142
        cmp     ebx, [putimg.image_sx]
143
        jbe     .end_x
144
        mov     ebx, [putimg.image_sx]
145
.end_x:
146
        mov     [putimg.real_sx], ebx
147
; init real_sy
148
        mov     ebx, [eax-twdw + WDATA.box.height]; ebx = wnd_sy
149
; \begin{diamond}[20.08.2006]
150
        inc     ebx
151
; \end{diamond}[20.08.2006]
152
        sub     ebx, [putimg.image_cy]
153
        ja      @f
154
        add     esp, putimg.stack_data
155
        popad
156
        ret
157
@@:
158
        cmp     ebx, [putimg.image_sy]
159
        jbe     .end_y
160
        mov     ebx, [putimg.image_sy]
161
.end_y:
162
        mov     [putimg.real_sy], ebx
163
; line increment
164
        mov     eax, [putimg.image_sx]
165
        mov     ecx, [putimg.real_sx]
166
        sub     eax, ecx
167
;;     imul    eax, [putimg.source_bpp]
168
;     lea     eax, [eax + eax * 2]
169
        call    esi
170
        add     eax, [putimg.arg_0]
171
        mov     [putimg.line_increment], eax
172
; winmap new line increment
173
        mov     eax, [Screen_Max_X]
174
        inc     eax
175
        sub     eax, [putimg.real_sx]
176
        mov     [putimg.winmap_newline], eax
177
; screen new line increment
178
        mov     eax, [BytesPerScanLine]
179
        movzx   ebx, byte [ScreenBPP]
180
        shr     ebx, 3
181
        imul    ecx, ebx
182
        sub     eax, ecx
183
        mov     [putimg.screen_newline], eax
184
; pointer to image
185
        mov     esi, [putimg.pti]
186
; pointer to screen
187
        mov     edx, [putimg.abs_cy]
188
        imul    edx, [BytesPerScanLine]
189
        mov     eax, [putimg.abs_cx]
190
        movzx   ebx, byte [ScreenBPP]
191
        shr     ebx, 3
192
        imul    eax, ebx
193
        add     edx, eax
194
; pointer to pixel map
195
        mov     eax, [putimg.abs_cy]
196
        imul    eax, [Screen_Max_X]
197
        add     eax, [putimg.abs_cy]
198
        add     eax, [putimg.abs_cx]
199
        add     eax, [_WinMapAddress]
200
        xchg    eax, ebp
201
; get process number
202
        mov     ebx, [CURRENT_TASK]
203
        cmp     byte [ScreenBPP], 32
204
        je      put_image_end_32
205
;put_image_end_24:
206
        mov     edi, [putimg.real_sy]
207
align   4
208
.new_line:
209
        mov     ecx, [putimg.real_sx]
210
;     push    ebp edx
211
align   4
212
.new_x:
213
        push    [putimg.edi]
214
        mov     eax, [putimg.ebp+4]
215
        call    eax
216
        cmp     [ebp], bl
217
        jne     .skip
218
;     mov     eax, [esi]        ; eax = RRBBGGRR
219
        mov     [LFB_BASE+edx], ax
220
        shr     eax, 16
221
        mov     [LFB_BASE+edx+2], al
222
.skip:
223
;     add     esi, 3 ;[putimg.source_bpp]
224
        add     edx, 3
225
        inc     ebp
226
        dec     ecx
227
        jnz     .new_x
228
;     pop     edx ebp
229
        add     esi, [putimg.line_increment]
230
        add     edx, [putimg.screen_newline];[BytesPerScanLine]
231
        add     ebp, [putimg.winmap_newline];[Screen_Max_X]
232
;     inc     ebp
233
        cmp     [putimg.ebp], putimage_get1bpp
234
        jz      .correct
235
        cmp     [putimg.ebp], putimage_get2bpp
236
        jz      .correct
237
        cmp     [putimg.ebp], putimage_get4bpp
238
        jnz     @f
239
.correct:
240
        mov     eax, [putimg.edi]
241
        mov     byte [eax], 80h
242
@@:
243
        dec     edi
244
        jnz     .new_line
245
.finish:
246
        add     esp, putimg.stack_data
247
        popad
248
        ret
249
 
250
put_image_end_32:
251
        mov     edi, [putimg.real_sy]
252
align   4
253
.new_line:
254
        mov     ecx, [putimg.real_sx]
255
;     push    ebp edx
256
align   4
257
.new_x:
258
        push    [putimg.edi]
259
        mov     eax, [putimg.ebp+4]
260
        call    eax
261
        cmp     [ebp], bl
262
        jne     .skip
263
;     mov     eax, [esi]        ; ecx = RRBBGGRR
264
        mov     [LFB_BASE+edx], eax
265
.skip:
266
;     add     esi, [putimg.source_bpp]
267
        add     edx, 4
268
        inc     ebp
269
        dec     ecx
270
        jnz     .new_x
271
;     pop     edx ebp
272
        add     esi, [putimg.line_increment]
273
        add     edx, [putimg.screen_newline];[BytesPerScanLine]
274
        add     ebp, [putimg.winmap_newline];[Screen_Max_X]
275
;     inc     ebp
276
        cmp     [putimg.ebp], putimage_get1bpp
277
        jz      .correct
278
        cmp     [putimg.ebp], putimage_get2bpp
279
        jz      .correct
280
        cmp     [putimg.ebp], putimage_get4bpp
281
        jnz     @f
282
.correct:
283
        mov     eax, [putimg.edi]
284
        mov     byte [eax], 80h
285
@@:
286
        dec     edi
287
        jnz     .new_line
288
.finish:
289
        add     esp, putimg.stack_data
290
        popad
291
        call    VGA__putimage
292
        mov     [EGA_counter], 1
293
        ret
294
 
295
 
296
;*************************************************
297
align 4
298
__sys_putpixel:
299
 
300
; eax = x coordinate
301
; ebx = y coordinate
302
; ecx = ?? RR GG BB    ; 0x01000000 negation
303
; edi = 0x00000001 force
304
 
305
;;;        mov  [novesachecksum], dword 0
306
        pushad
307
        cmp     [Screen_Max_X], eax
308
        jb      .exit
309
        cmp     [Screen_Max_Y], ebx
310
        jb      .exit
311
        test    edi, 1           ; force ?
312
        jnz     .forced
313
 
314
; not forced:
315
 
316
        push    eax
317
        mov     edx, [_display.width]; screen x size
318
        imul    edx, ebx
319
        add     eax, [_WinMapAddress]
320
        movzx   edx, byte [eax+edx]
321
        cmp     edx, [CURRENT_TASK]
322
        pop     eax
323
        jne     .exit
324
 
325
.forced:
326
; check if negation
327
        test    ecx, 0x01000000
328
        jz      .noneg
329
        call    getpixel
330
        not     ecx
331
        mov     [esp+32-8], ecx
332
.noneg:
333
; OK to set pixel
334
        call    dword [PUTPIXEL]; call the real put_pixel function
335
.exit:
336
        popad
337
        ret
338
 
339
align 4
340
Vesa20_putpixel24:
341
; eax = x
342
; ebx = y
343
        imul    ebx, [BytesPerScanLine]  ; ebx = y * y multiplier
344
        lea     edi, [eax+eax*2]; edi = x*3
345
        mov     eax, [esp+32-8+4]
346
        mov     [LFB_BASE+ebx+edi], ax
347
        shr     eax, 16
348
        mov     [LFB_BASE+ebx+edi+2], al
349
        ret
350
 
351
 
352
align 4
353
Vesa20_putpixel32:
354
; eax = x
355
; ebx = y
356
        imul    ebx, [BytesPerScanLine]  ; ebx = y * y multiplier
357
        lea     edi, [ebx+eax*4]; edi = x*4+(y*y multiplier)
358
        mov     eax, [esp+32-8+4]; eax = color
359
        mov     [LFB_BASE+edi], eax
360
        ret
361
 
362
;*************************************************
363
 
364
;align 4
365
calculate_edi:
366
        mov     edi, ebx
367
        imul    edi, [Screen_Max_X]
368
        add     edi, ebx
369
        add     edi, eax
370
        ret
371
 
372
;*************************************************
373
 
374
; DRAWLINE
375
 
376
align 4
377
__sys_draw_line:
378
;     inc   [mouse_pause]
379
        call    [_display.disable_mouse]
380
 
381
; draw a line
382
; eax = HIWORD = x1
383
;       LOWORD = x2
384
; ebx = HIWORD = y1
385
;       LOWORD = y2
386
; ecx = color
387
; edi = force ?
388
        pusha
389
 
390
dl_x1 equ esp+20
391
dl_y1 equ esp+16
392
dl_x2 equ esp+12
393
dl_y2 equ esp+8
394
dl_dx equ esp+4
395
dl_dy equ esp+0
396
 
397
        xor     edx, edx   ; clear edx
398
        xor     esi, esi   ; unpack arguments
399
        xor     ebp, ebp
400
        mov     si, ax     ; esi = x2
401
        mov     bp, bx     ; ebp = y2
402
        shr     eax, 16    ; eax = x1
403
        shr     ebx, 16    ; ebx = y1
404
        push    eax        ; save x1
405
        push    ebx        ; save y1
406
        push    esi        ; save x2
407
        push    ebp        ; save y2
408
; checking x-axis...
409
        sub     esi, eax   ; esi = x2-x1
410
        push    esi        ; save y2-y1
411
        jl      .x2lx1     ; is x2 less than x1 ?
412
        jg      .no_vline  ; x1 > x2 ?
413
        mov     edx, ebp   ; else (if x1=x2)
414
        call    vline
415
        push    edx ; necessary to rightly restore stack frame at .exit
416
        jmp     .exit
417
.x2lx1:
418
        neg     esi         ; get esi absolute value
419
.no_vline:
420
; checking y-axis...
421
        sub     ebp, ebx    ; ebp = y2-y1
422
        push    ebp         ; save y2-y1
423
        jl      .y2ly1      ; is y2 less than y1 ?
424
        jg      .no_hline   ; y1 > y2 ?
425
        mov     edx, [dl_x2]; else (if y1=y2)
426
        call    hline
427
        jmp     .exit
428
 
429
.y2ly1:
430
        neg     ebp         ; get ebp absolute value
431
.no_hline:
432
        cmp     ebp, esi
433
        jle     .x_rules    ; |y2-y1| < |x2-x1|  ?
434
        cmp     [dl_y2], ebx; make sure y1 is at the begining
435
        jge     .no_reverse1
436
        neg     dword [dl_dx]
437
        mov     edx, [dl_x2]
438
        mov     [dl_x2], eax
439
        mov     [dl_x1], edx
440
        mov     edx, [dl_y2]
441
        mov     [dl_y2], ebx
442
        mov     [dl_y1], edx
443
.no_reverse1:
444
        mov     eax, [dl_dx]
445
        cdq                 ; extend eax sing to edx
446
        shl     eax, 16     ; using 16bit fix-point maths
447
        idiv    ebp         ; eax = ((x2-x1)*65536)/(y2-y1)
2353 mario79 448
;--------------------------------------
449
; correction for the remainder of the division
450
        shl     edx, 1
451
        cmp     ebp, edx
452
        jb      @f
453
        inc     eax
454
@@:
455
;--------------------------------------
2288 clevermous 456
        mov     edx, ebp    ; edx = counter (number of pixels to draw)
457
        mov     ebp, 1 *65536; <<16   ; ebp = dy = 1.0
458
        mov     esi, eax    ; esi = dx
459
        jmp     .y_rules
460
 
461
.x_rules:
462
        cmp     [dl_x2], eax ; make sure x1 is at the begining
463
        jge     .no_reverse2
464
        neg     dword [dl_dy]
465
        mov     edx, [dl_x2]
466
        mov     [dl_x2], eax
467
        mov     [dl_x1], edx
468
        mov     edx, [dl_y2]
469
        mov     [dl_y2], ebx
470
        mov     [dl_y1], edx
471
.no_reverse2:
472
        xor     edx, edx
473
        mov     eax, [dl_dy]
474
        cdq                 ; extend eax sing to edx
475
        shl     eax, 16     ; using 16bit fix-point maths
476
        idiv    esi         ; eax = ((y2-y1)*65536)/(x2-x1)
2353 mario79 477
;--------------------------------------
478
; correction for the remainder of the division
479
        shl     edx, 1
480
        cmp     esi, edx
481
        jb      @f
482
        inc     eax
483
@@:
484
;--------------------------------------
2288 clevermous 485
        mov     edx, esi    ; edx = counter (number of pixels to draw)
486
        mov     esi, 1 *65536;<< 16   ; esi = dx = 1.0
487
        mov     ebp, eax    ; ebp = dy
488
.y_rules:
489
        mov     eax, [dl_x1]
490
        mov     ebx, [dl_y1]
491
        shl     eax, 16
492
        shl     ebx, 16
2353 mario79 493
;-----------------------------------------------------------------------------
2288 clevermous 494
align 4
495
.draw:
496
        push    eax ebx
2353 mario79 497
;--------------------------------------
498
; correction for the remainder of the division
499
        test    ah, 0x80
500
        jz      @f
501
        add     eax, 1 shl 16
502
@@:
503
;--------------------------------------
2288 clevermous 504
        shr     eax, 16
2353 mario79 505
;--------------------------------------
506
; correction for the remainder of the division
507
        test    bh, 0x80
508
        jz      @f
509
        add     ebx, 1 shl 16
510
@@:
511
;--------------------------------------
2288 clevermous 512
        shr     ebx, 16
513
        call    [putpixel]
514
        pop     ebx eax
515
        add     ebx, ebp     ; y = y+dy
516
        add     eax, esi     ; x = x+dx
517
        dec     edx
518
        jnz     .draw
519
; force last drawn pixel to be at (x2,y2)
520
        mov     eax, [dl_x2]
521
        mov     ebx, [dl_y2]
522
        call    [putpixel]
523
.exit:
524
        add     esp, 6*4
525
        popa
526
;     dec   [mouse_pause]
527
        call    [draw_pointer]
528
        ret
529
 
530
 
531
hline:
532
; draw an horizontal line
533
; eax = x1
534
; edx = x2
535
; ebx = y
536
; ecx = color
537
; edi = force ?
538
        push    eax edx
539
        cmp     edx, eax   ; make sure x2 is above x1
540
        jge     @f
541
        xchg    eax, edx
542
align   4
543
@@:
544
        call    [putpixel]
545
        inc     eax
546
        cmp     eax, edx
547
        jle     @b
548
        pop     edx eax
549
        ret
550
 
551
 
552
vline:
553
; draw a vertical line
554
; eax = x
555
; ebx = y1
556
; edx = y2
557
; ecx = color
558
; edi = force ?
559
        push    ebx edx
560
        cmp     edx, ebx   ; make sure y2 is above y1
561
        jge     @f
562
        xchg    ebx, edx
563
align   4
564
@@:
565
        call    [putpixel]
566
        inc     ebx
567
        cmp     ebx, edx
568
        jle     @b
569
        pop     edx ebx
570
        ret
571
 
572
 
573
;*************************************************
574
 
575
 
576
virtual at esp
577
drbar:
578
     .bar_sx       dd ?
579
     .bar_sy       dd ?
580
     .bar_cx       dd ?
581
     .bar_cy       dd ?
582
     .abs_cx       dd ?
583
     .abs_cy       dd ?
584
     .real_sx      dd ?
585
     .real_sy      dd ?
586
     .color        dd ?
587
     .line_inc_scr dd ?
588
     .line_inc_map dd ?
589
     .stack_data = 4*11
590
end virtual
591
 
592
align 4
593
; eax   cx
594
; ebx   cy
595
; ecx   xe
596
; edx   ye
597
; edi   color
598
vesa20_drawbar:
599
        pushad
600
        call    [_display.disable_mouse]
601
        sub     esp, drbar.stack_data
602
        mov     [drbar.color], edi
603
        sub     edx, ebx
604
        jle     .exit       ;// mike.dld, 2005-01-29
605
        sub     ecx, eax
606
        jle     .exit       ;// mike.dld, 2005-01-29
607
        mov     [drbar.bar_sy], edx
608
        mov     [drbar.bar_sx], ecx
609
        mov     [drbar.bar_cx], eax
610
        mov     [drbar.bar_cy], ebx
611
        mov     edi, [TASK_BASE]
612
        add     eax, [edi-twdw + WDATA.box.left]; win_cx
613
        add     ebx, [edi-twdw + WDATA.box.top]; win_cy
614
        mov     [drbar.abs_cx], eax
615
        mov     [drbar.abs_cy], ebx
616
; real_sx = MIN(wnd_sx-bar_cx, bar_sx);
617
        mov     ebx, [edi-twdw + WDATA.box.width]; ebx = wnd_sx
618
; \begin{diamond}[20.08.2006]
619
; note that WDATA.box.width is one pixel less than real window x-size
620
        inc     ebx
621
; \end{diamond}[20.08.2006]
622
        sub     ebx, [drbar.bar_cx]
623
        ja      @f
624
.exit:                       ;// mike.dld, 2005-01-29
625
        add     esp, drbar.stack_data
626
        popad
627
        xor     eax, eax
628
        inc     eax
629
        ret
630
@@:
631
        cmp     ebx, [drbar.bar_sx]
632
        jbe     .end_x
633
        mov     ebx, [drbar.bar_sx]
634
.end_x:
635
        mov     [drbar.real_sx], ebx
636
; real_sy = MIN(wnd_sy-bar_cy, bar_sy);
637
        mov     ebx, [edi-twdw + WDATA.box.height]; ebx = wnd_sy
638
; \begin{diamond}[20.08.2006]
639
        inc     ebx
640
; \end{diamond}
641
        sub     ebx, [drbar.bar_cy]
642
        ja      @f
643
        add     esp, drbar.stack_data
644
        popad
645
        xor     eax, eax
646
        inc     eax
647
        ret
648
@@:
649
        cmp     ebx, [drbar.bar_sy]
650
        jbe     .end_y
651
        mov     ebx, [drbar.bar_sy]
652
.end_y:
653
        mov     [drbar.real_sy], ebx
654
; line_inc_map
655
        mov     eax, [Screen_Max_X]
656
        sub     eax, [drbar.real_sx]
657
        inc     eax
658
        mov     [drbar.line_inc_map], eax
659
; line_inc_scr
660
        mov     eax, [drbar.real_sx]
661
        movzx   ebx, byte [ScreenBPP]
662
        shr     ebx, 3
663
        imul    eax, ebx
664
        neg     eax
665
        add     eax, [BytesPerScanLine]
666
        mov     [drbar.line_inc_scr], eax
667
; pointer to screen
668
        mov     edx, [drbar.abs_cy]
669
        imul    edx, [BytesPerScanLine]
670
        mov     eax, [drbar.abs_cx]
671
;     movzx   ebx, byte [ScreenBPP]
672
;     shr     ebx, 3
673
        imul    eax, ebx
674
        add     edx, eax
675
; pointer to pixel map
676
        mov     eax, [drbar.abs_cy]
677
        imul    eax, [Screen_Max_X]
678
        add     eax, [drbar.abs_cy]
679
        add     eax, [drbar.abs_cx]
680
        add     eax, [_WinMapAddress]
681
        xchg    eax, ebp
682
; get process number
683
        mov     ebx, [CURRENT_TASK]
684
        cmp     byte [ScreenBPP], 24
685
        jne     draw_bar_end_32
686
draw_bar_end_24:
687
        mov     eax, [drbar.color] ;; BBGGRR00
688
        mov     bh, al             ;; bh  = BB
689
        shr     eax, 8             ;; eax = RRGG
690
; eax - color high   RRGG
691
; bl - process num
692
; bh - color low    BB
693
; ecx - temp
694
; edx - pointer to screen
695
; esi - counter
696
; edi - counter
697
        mov     esi, [drbar.real_sy]
698
align   4
699
.new_y:
700
        mov     edi, [drbar.real_sx]
701
align   4
702
.new_x:
703
        cmp     byte [ebp], bl
704
        jne     .skip
705
 
706
        mov     [LFB_BASE+edx], bh
707
        mov     [LFB_BASE+edx + 1], ax
708
.skip:
709
; add pixel
710
        add     edx, 3
711
        inc     ebp
712
        dec     edi
713
        jnz     .new_x
714
; add line
715
        add     edx, [drbar.line_inc_scr]
716
        add     ebp, [drbar.line_inc_map]
717
;  drawing gradient bars
718
        test    eax, 0x00800000
719
        jz      @f
720
        test    bh, bh
721
        jz      @f
722
        dec     bh
723
@@:
724
; 
725
        dec     esi
726
        jnz     .new_y
727
        add     esp, drbar.stack_data
728
        popad
729
        xor     eax, eax
730
        ret
731
 
732
draw_bar_end_32:
733
        mov     eax, [drbar.color] ;; BBGGRR00
734
        mov     esi, [drbar.real_sy]
735
align   4
736
.new_y:
737
        mov     edi, [drbar.real_sx]
738
align   4
739
.new_x:
740
        cmp     byte [ebp], bl
741
        jne     .skip
742
 
743
        mov     [LFB_BASE+edx], eax
744
.skip:
745
; add pixel
746
        add     edx, 4
747
        inc     ebp
748
        dec     edi
749
        jnz     .new_x
750
; add line
751
        add     edx, [drbar.line_inc_scr]
752
        add     ebp, [drbar.line_inc_map]
753
;  drawing gradient bars
754
        test    eax, 0x80000000
755
        jz      @f
756
        test    al, al
757
        jz      @f
758
        dec     al
759
@@:
760
; 
761
        dec     esi
762
        jnz     .new_y
763
        add     esp, drbar.stack_data
764
        popad
765
        call    VGA_draw_bar
766
        xor     eax, eax
767
        mov     [EGA_counter], 1
768
        ret
769
 
770
align 4
771
vesa20_drawbackground_tiled:
772
        call    [_display.disable_mouse]
773
        pushad
774
; External loop for all y from start to end
775
        mov     ebx, [draw_data+32+RECT.top]    ; y start
776
dp2:
777
        mov     ebp, [draw_data+32+RECT.left]   ; x start
778
; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
779
;                       and LFB data (output for our function) [edi]
780
        mov     eax, [BytesPerScanLine]
781
        mul     ebx
782
        xchg    ebp, eax
783
        add     ebp, eax
784
        add     ebp, eax
785
        add     ebp, eax
786
        cmp     [ScreenBPP], byte 24    ; 24 or 32 bpp ? - x size
787
        jz      @f
788
        add     ebp, eax
789
@@:
790
        add     ebp, LFB_BASE
791
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
792
        call    calculate_edi
793
        xchg    edi, ebp
794
        add     ebp, [_WinMapAddress]
795
; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
796
; 2) Calculate offset in background memory block
797
        push    eax
798
        xor     edx, edx
799
        mov     eax, ebx
800
        div     dword [BgrDataHeight]   ; edx := y mod BgrDataHeight
801
        pop     eax
802
        push    eax
803
        mov     ecx, [BgrDataWidth]
804
        mov     esi, edx
805
        imul    esi, ecx                ; esi := (y mod BgrDataHeight) * BgrDataWidth
806
        xor     edx, edx
807
        div     ecx             ; edx := x mod BgrDataWidth
808
        sub     ecx, edx
809
        add     esi, edx        ; esi := (y mod BgrDataHeight)*BgrDataWidth + (x mod BgrDataWidth)
810
        pop     eax
811
        lea     esi, [esi*3]
812
        add     esi, [img_background]
813
        xor     edx, edx
814
        inc     edx
815
; 3) Loop through redraw rectangle and copy background data
816
; Registers meaning:
817
; eax = x, ebx = y (screen coordinates)
818
; ecx = deltax - number of pixels left in current tile block
819
; edx = 1
820
; esi -> bgr memory, edi -> output
821
; ebp = offset in WinMapAddress
822
dp3:
823
        cmp     [ebp], dl
824
        jnz     nbgp
825
        movsb
826
        movsb
827
        movsb
828
        jmp     @f
829
nbgp:
830
        add     esi, 3
831
        add     edi, 3
832
@@:
833
        cmp     [ScreenBPP], byte 25    ; 24 or 32 bpp?
834
        sbb     edi, -1         ; +1 for 32 bpp
835
; I do not use 'inc eax' because this is slightly slower then 'add eax,1'
836
        add     ebp, edx
837
        add     eax, edx
838
        cmp     eax, [draw_data+32+RECT.right]
839
        ja      dp4
840
        sub     ecx, edx
841
        jnz     dp3
842
; next tile block on x-axis
843
        mov     ecx, [BgrDataWidth]
844
        sub     esi, ecx
845
        sub     esi, ecx
846
        sub     esi, ecx
847
        jmp     dp3
848
dp4:
849
; next scan line
850
        inc     ebx
851
        cmp     ebx, [draw_data+32+RECT.bottom]
852
        jbe     dp2
853
        popad
854
        mov     [EGA_counter], 1
855
        call    VGA_drawbackground
856
        ret
857
 
858
; ----------
859
 
860
 
861
vesa20_drawbackground_stretch:
862
        call    [_display.disable_mouse]
863
        pushad
864
; Helper variables
865
; calculate 2^32*(BgrDataWidth-1) mod (ScreenWidth-1)
866
        mov     eax, [BgrDataWidth]
867
        dec     eax
868
        xor     edx, edx
869
        div     dword [Screen_Max_X]
870
        push    eax     ; high
871
        xor     eax, eax
872
        div     dword [Screen_Max_X]
873
        push    eax     ; low
874
; the same for height
875
        mov     eax, [BgrDataHeight]
876
        dec     eax
877
        xor     edx, edx
878
        div     dword [Screen_Max_Y]
879
        push    eax     ; high
880
        xor     eax, eax
881
        div     dword [Screen_Max_Y]
882
        push    eax     ; low
883
; External loop for all y from start to end
884
        mov     ebx, [draw_data+32+RECT.top]    ; y start
885
        mov     ebp, [draw_data+32+RECT.left]   ; x start
886
; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
887
;                       and LFB data (output for our function) [edi]
888
        mov     eax, [BytesPerScanLine]
889
        mul     ebx
890
        xchg    ebp, eax
891
        add     ebp, eax
892
        add     ebp, eax
893
        add     ebp, eax
894
        cmp     [ScreenBPP], byte 24    ; 24 or 32 bpp ? - x size
895
        jz      @f
896
        add     ebp, eax
897
@@:
898
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
899
        call    calculate_edi
900
        xchg    edi, ebp
901
; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
902
        push    ebx
903
        push    eax
904
; 2) Calculate offset in background memory block
905
        mov     eax, ebx
906
        imul    ebx, dword [esp+12]
907
        mul     dword [esp+8]
908
        add     edx, ebx        ; edx:eax = y * 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
909
        mov     esi, edx
910
        imul    esi, [BgrDataWidth]
911
        push    edx
912
        push    eax
913
        mov     eax, [esp+8]
914
        mul     dword [esp+28]
915
        push    eax
916
        mov     eax, [esp+12]
917
        mul     dword [esp+28]
918
        add     [esp], edx
919
        pop     edx             ; edx:eax = x * 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
920
        add     esi, edx
921
        lea     esi, [esi*3]
922
        add     esi, [img_background]
923
        push    eax
924
        push    edx
925
        push    esi
926
; 3) Smooth horizontal
927
bgr_resmooth0:
928
        mov     ecx, [esp+8]
929
        mov     edx, [esp+4]
930
        mov     esi, [esp]
931
        push    edi
932
        mov     edi, bgr_cur_line
933
        call    smooth_line
934
bgr_resmooth1:
935
        mov     eax, [esp+16+4]
936
        inc     eax
937
        cmp     eax, [BgrDataHeight]
938
        jae     bgr.no2nd
939
        mov     ecx, [esp+8+4]
940
        mov     edx, [esp+4+4]
941
        mov     esi, [esp+4]
942
        add     esi, [BgrDataWidth]
943
        add     esi, [BgrDataWidth]
944
        add     esi, [BgrDataWidth]
945
        mov     edi, bgr_next_line
946
        call    smooth_line
947
bgr.no2nd:
948
        pop     edi
949
sdp3:
950
        xor     esi, esi
951
        mov     ecx, [esp+12]
952
; 4) Loop through redraw rectangle and copy background data
953
; Registers meaning:
954
; esi = offset in current line, edi -> output
955
; ebp = offset in WinMapAddress
956
; dword [esp] = offset in bgr data
957
; qword [esp+4] = x * 2^32 * (BgrDataWidth-1) / (ScreenWidth-1)
958
; qword [esp+12] = y * 2^32 * (BgrDataHeight-1) / (ScreenHeight-1)
959
; dword [esp+20] = x
960
; dword [esp+24] = y
961
; precalculated constants:
962
; qword [esp+28] = 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
963
; qword [esp+36] = 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
964
sdp3a:
965
        mov     eax, [_WinMapAddress]
966
        cmp     [ebp+eax], byte 1
967
        jnz     snbgp
968
        mov     eax, [bgr_cur_line+esi]
969
        test    ecx, ecx
970
        jz      .novert
971
        mov     ebx, [bgr_next_line+esi]
972
        call    [overlapping_of_points_ptr]
973
.novert:
974
 
975
        mov     [LFB_BASE+edi], ax
976
        shr     eax, 16
977
 
978
        mov     [LFB_BASE+edi+2], al
979
snbgp:
980
        cmp     [ScreenBPP], byte 25
981
        sbb     edi, -4
982
        add     ebp, 1
983
        mov     eax, [esp+20]
984
        add     eax, 1
985
        mov     [esp+20], eax
986
        add     esi, 4
987
        cmp     eax, [draw_data+32+RECT.right]
988
        jbe     sdp3a
989
sdp4:
990
; next y
991
        mov     ebx, [esp+24]
992
        add     ebx, 1
993
        mov     [esp+24], ebx
994
        cmp     ebx, [draw_data+32+RECT.bottom]
995
        ja      sdpdone
996
; advance edi, ebp to next scan line
997
        sub     eax, [draw_data+32+RECT.left]
998
        sub     ebp, eax
999
        add     ebp, [Screen_Max_X]
1000
        add     ebp, 1
1001
        sub     edi, eax
1002
        sub     edi, eax
1003
        sub     edi, eax
1004
        cmp     [ScreenBPP], byte 24
1005
        jz      @f
1006
        sub     edi, eax
1007
@@:
1008
        add     edi, [BytesPerScanLine]
1009
; restore ecx,edx; advance esi to next background line
1010
        mov     eax, [esp+28]
1011
        mov     ebx, [esp+32]
1012
        add     [esp+12], eax
1013
        mov     eax, [esp+16]
1014
        adc     [esp+16], ebx
1015
        sub     eax, [esp+16]
1016
        mov     ebx, eax
1017
        lea     eax, [eax*3]
1018
        imul    eax, [BgrDataWidth]
1019
        sub     [esp], eax
1020
        mov     eax, [draw_data+32+RECT.left]
1021
        mov     [esp+20], eax
1022
        test    ebx, ebx
1023
        jz      sdp3
1024
        cmp     ebx, -1
1025
        jnz     bgr_resmooth0
1026
        push    edi
1027
        mov     esi, bgr_next_line
1028
        mov     edi, bgr_cur_line
1029
        mov     ecx, [Screen_Max_X]
1030
        inc     ecx
1031
        rep movsd
1032
        jmp     bgr_resmooth1
1033
sdpdone:
1034
        add     esp, 44
1035
        popad
1036
        mov     [EGA_counter], 1
1037
        call    VGA_drawbackground
1038
        ret
1039
 
1040
uglobal
1041
align 4
1042
bgr_cur_line    rd      1920    ; maximum width of screen
1043
bgr_next_line   rd      1920
1044
endg
1045
 
1046
smooth_line:
1047
        mov     al, [esi+2]
1048
        shl     eax, 16
1049
        mov     ax, [esi]
1050
        test    ecx, ecx
1051
        jz      @f
1052
        mov     ebx, [esi+2]
1053
        shr     ebx, 8
1054
        call    [overlapping_of_points_ptr]
1055
@@:
1056
        stosd
1057
        mov     eax, [esp+20+8]
1058
        add     eax, 1
1059
        mov     [esp+20+8], eax
1060
        cmp     eax, [draw_data+32+RECT.right]
1061
        ja      @f
1062
        add     ecx, [esp+36+8]
1063
        mov     eax, edx
1064
        adc     edx, [esp+40+8]
1065
        sub     eax, edx
1066
        lea     eax, [eax*3]
1067
        sub     esi, eax
1068
        jmp     smooth_line
1069
@@:
1070
        mov     eax, [draw_data+32+RECT.left]
1071
        mov     [esp+20+8], eax
1072
        ret
1073
 
1074
align 16
1075
overlapping_of_points:
1076
if 0
1077
; this version of procedure works, but is slower than next version
1078
        push    ecx edx
1079
        mov     edx, eax
1080
        push    esi
1081
        shr     ecx, 24
1082
        mov     esi, ecx
1083
        mov     ecx, ebx
1084
        movzx   ebx, dl
1085
        movzx   eax, cl
1086
        sub     eax, ebx
1087
        movzx   ebx, dh
1088
        imul    eax, esi
1089
        add     dl, ah
1090
        movzx   eax, ch
1091
        sub     eax, ebx
1092
        imul    eax, esi
1093
        add     dh, ah
1094
        ror     ecx, 16
1095
        ror     edx, 16
1096
        movzx   eax, cl
1097
        movzx   ebx, dl
1098
        sub     eax, ebx
1099
        imul    eax, esi
1100
        pop     esi
1101
        add     dl, ah
1102
        mov     eax, edx
1103
        pop     edx
1104
        ror     eax, 16
1105
        pop     ecx
1106
        ret
1107
else
1108
        push    ecx edx
1109
        mov     edx, eax
1110
        push    esi
1111
        shr     ecx, 26
1112
        mov     esi, ecx
1113
        mov     ecx, ebx
1114
        shl     esi, 9
1115
        movzx   ebx, dl
1116
        movzx   eax, cl
1117
        sub     eax, ebx
1118
        movzx   ebx, dh
1119
        add     dl, [BgrAuxTable+(eax+0x100)+esi]
1120
        movzx   eax, ch
1121
        sub     eax, ebx
1122
        add     dh, [BgrAuxTable+(eax+0x100)+esi]
1123
        ror     ecx, 16
1124
        ror     edx, 16
1125
        movzx   eax, cl
1126
        movzx   ebx, dl
1127
        sub     eax, ebx
1128
        add     dl, [BgrAuxTable+(eax+0x100)+esi]
1129
        pop     esi
1130
        mov     eax, edx
1131
        pop     edx
1132
        ror     eax, 16
1133
        pop     ecx
1134
        ret
1135
end if
1136
 
1137
iglobal
1138
align 4
1139
overlapping_of_points_ptr       dd      overlapping_of_points
1140
endg
1141
 
1142
init_background:
1143
        mov     edi, BgrAuxTable
1144
        xor     edx, edx
1145
.loop2:
1146
        mov     eax, edx
1147
        shl     eax, 8
1148
        neg     eax
1149
        mov     ecx, 0x200
1150
.loop1:
1151
        mov     byte [edi], ah
1152
        inc     edi
1153
        add     eax, edx
1154
        loop    .loop1
1155
        add     dl, 4
1156
        jnz     .loop2
1157
        test    byte [cpu_caps+(CAPS_MMX/8)], 1 shl (CAPS_MMX mod 8)
1158
        jz      @f
1159
        mov     [overlapping_of_points_ptr], overlapping_of_points_mmx
1160
@@:
1161
        ret
1162
 
1163
align 16
1164
overlapping_of_points_mmx:
1165
        movd    mm0, eax
1166
        movd    mm4, eax
1167
        movd    mm1, ebx
1168
        pxor    mm2, mm2
1169
        punpcklbw mm0, mm2
1170
        punpcklbw mm1, mm2
1171
        psubw   mm1, mm0
1172
        movd    mm3, ecx
1173
        psrld   mm3, 24
1174
        packuswb mm3, mm3
1175
        packuswb mm3, mm3
1176
        pmullw  mm1, mm3
1177
        psrlw   mm1, 8
1178
        packuswb mm1, mm2
1179
        paddb   mm4, mm1
1180
        movd    eax, mm4
1181
        ret