Subversion Repositories Kolibri OS

Rev

Rev 2353 | Rev 2430 | 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: 2423 $
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
2423 mario79 303
                       ; 0x02000000 used for draw_rectangle without top line
304
                       ;            for example drawwindow_III and drawwindow_IV
2288 clevermous 305
; edi = 0x00000001 force
306
 
307
;;;        mov  [novesachecksum], dword 0
308
        pushad
309
        cmp     [Screen_Max_X], eax
310
        jb      .exit
311
        cmp     [Screen_Max_Y], ebx
312
        jb      .exit
313
        test    edi, 1           ; force ?
314
        jnz     .forced
315
 
316
; not forced:
317
 
318
        push    eax
319
        mov     edx, [_display.width]; screen x size
320
        imul    edx, ebx
321
        add     eax, [_WinMapAddress]
322
        movzx   edx, byte [eax+edx]
323
        cmp     edx, [CURRENT_TASK]
324
        pop     eax
325
        jne     .exit
326
 
327
.forced:
328
; check if negation
329
        test    ecx, 0x01000000
330
        jz      .noneg
331
        call    getpixel
332
        not     ecx
333
        mov     [esp+32-8], ecx
334
.noneg:
335
; OK to set pixel
336
        call    dword [PUTPIXEL]; call the real put_pixel function
337
.exit:
338
        popad
339
        ret
340
 
341
align 4
342
Vesa20_putpixel24:
343
; eax = x
344
; ebx = y
345
        imul    ebx, [BytesPerScanLine]  ; ebx = y * y multiplier
346
        lea     edi, [eax+eax*2]; edi = x*3
347
        mov     eax, [esp+32-8+4]
348
        mov     [LFB_BASE+ebx+edi], ax
349
        shr     eax, 16
350
        mov     [LFB_BASE+ebx+edi+2], al
351
        ret
352
 
353
 
354
align 4
355
Vesa20_putpixel32:
356
; eax = x
357
; ebx = y
358
        imul    ebx, [BytesPerScanLine]  ; ebx = y * y multiplier
359
        lea     edi, [ebx+eax*4]; edi = x*4+(y*y multiplier)
360
        mov     eax, [esp+32-8+4]; eax = color
361
        mov     [LFB_BASE+edi], eax
362
        ret
363
 
364
;*************************************************
365
 
366
;align 4
367
calculate_edi:
368
        mov     edi, ebx
369
        imul    edi, [Screen_Max_X]
370
        add     edi, ebx
371
        add     edi, eax
372
        ret
373
 
374
;*************************************************
375
 
376
; DRAWLINE
377
 
378
align 4
379
__sys_draw_line:
380
;     inc   [mouse_pause]
381
        call    [_display.disable_mouse]
382
 
383
; draw a line
384
; eax = HIWORD = x1
385
;       LOWORD = x2
386
; ebx = HIWORD = y1
387
;       LOWORD = y2
388
; ecx = color
389
; edi = force ?
390
        pusha
391
 
392
dl_x1 equ esp+20
393
dl_y1 equ esp+16
394
dl_x2 equ esp+12
395
dl_y2 equ esp+8
396
dl_dx equ esp+4
397
dl_dy equ esp+0
398
 
399
        xor     edx, edx   ; clear edx
400
        xor     esi, esi   ; unpack arguments
401
        xor     ebp, ebp
402
        mov     si, ax     ; esi = x2
403
        mov     bp, bx     ; ebp = y2
404
        shr     eax, 16    ; eax = x1
405
        shr     ebx, 16    ; ebx = y1
406
        push    eax        ; save x1
407
        push    ebx        ; save y1
408
        push    esi        ; save x2
409
        push    ebp        ; save y2
410
; checking x-axis...
411
        sub     esi, eax   ; esi = x2-x1
412
        push    esi        ; save y2-y1
413
        jl      .x2lx1     ; is x2 less than x1 ?
414
        jg      .no_vline  ; x1 > x2 ?
415
        mov     edx, ebp   ; else (if x1=x2)
416
        call    vline
417
        push    edx ; necessary to rightly restore stack frame at .exit
418
        jmp     .exit
419
.x2lx1:
420
        neg     esi         ; get esi absolute value
421
.no_vline:
422
; checking y-axis...
423
        sub     ebp, ebx    ; ebp = y2-y1
424
        push    ebp         ; save y2-y1
425
        jl      .y2ly1      ; is y2 less than y1 ?
426
        jg      .no_hline   ; y1 > y2 ?
427
        mov     edx, [dl_x2]; else (if y1=y2)
428
        call    hline
429
        jmp     .exit
430
 
431
.y2ly1:
432
        neg     ebp         ; get ebp absolute value
433
.no_hline:
434
        cmp     ebp, esi
435
        jle     .x_rules    ; |y2-y1| < |x2-x1|  ?
436
        cmp     [dl_y2], ebx; make sure y1 is at the begining
437
        jge     .no_reverse1
438
        neg     dword [dl_dx]
439
        mov     edx, [dl_x2]
440
        mov     [dl_x2], eax
441
        mov     [dl_x1], edx
442
        mov     edx, [dl_y2]
443
        mov     [dl_y2], ebx
444
        mov     [dl_y1], edx
445
.no_reverse1:
446
        mov     eax, [dl_dx]
447
        cdq                 ; extend eax sing to edx
448
        shl     eax, 16     ; using 16bit fix-point maths
449
        idiv    ebp         ; eax = ((x2-x1)*65536)/(y2-y1)
2353 mario79 450
;--------------------------------------
451
; correction for the remainder of the division
452
        shl     edx, 1
453
        cmp     ebp, edx
454
        jb      @f
455
        inc     eax
456
@@:
457
;--------------------------------------
2288 clevermous 458
        mov     edx, ebp    ; edx = counter (number of pixels to draw)
459
        mov     ebp, 1 *65536; <<16   ; ebp = dy = 1.0
460
        mov     esi, eax    ; esi = dx
461
        jmp     .y_rules
462
 
463
.x_rules:
464
        cmp     [dl_x2], eax ; make sure x1 is at the begining
465
        jge     .no_reverse2
466
        neg     dword [dl_dy]
467
        mov     edx, [dl_x2]
468
        mov     [dl_x2], eax
469
        mov     [dl_x1], edx
470
        mov     edx, [dl_y2]
471
        mov     [dl_y2], ebx
472
        mov     [dl_y1], edx
473
.no_reverse2:
474
        xor     edx, edx
475
        mov     eax, [dl_dy]
476
        cdq                 ; extend eax sing to edx
477
        shl     eax, 16     ; using 16bit fix-point maths
478
        idiv    esi         ; eax = ((y2-y1)*65536)/(x2-x1)
2353 mario79 479
;--------------------------------------
480
; correction for the remainder of the division
481
        shl     edx, 1
482
        cmp     esi, edx
483
        jb      @f
484
        inc     eax
485
@@:
486
;--------------------------------------
2288 clevermous 487
        mov     edx, esi    ; edx = counter (number of pixels to draw)
488
        mov     esi, 1 *65536;<< 16   ; esi = dx = 1.0
489
        mov     ebp, eax    ; ebp = dy
490
.y_rules:
491
        mov     eax, [dl_x1]
492
        mov     ebx, [dl_y1]
493
        shl     eax, 16
494
        shl     ebx, 16
2353 mario79 495
;-----------------------------------------------------------------------------
2288 clevermous 496
align 4
497
.draw:
498
        push    eax ebx
2353 mario79 499
;--------------------------------------
500
; correction for the remainder of the division
501
        test    ah, 0x80
502
        jz      @f
503
        add     eax, 1 shl 16
504
@@:
505
;--------------------------------------
2288 clevermous 506
        shr     eax, 16
2353 mario79 507
;--------------------------------------
508
; correction for the remainder of the division
509
        test    bh, 0x80
510
        jz      @f
511
        add     ebx, 1 shl 16
512
@@:
513
;--------------------------------------
2288 clevermous 514
        shr     ebx, 16
515
        call    [putpixel]
516
        pop     ebx eax
517
        add     ebx, ebp     ; y = y+dy
518
        add     eax, esi     ; x = x+dx
519
        dec     edx
520
        jnz     .draw
521
; force last drawn pixel to be at (x2,y2)
522
        mov     eax, [dl_x2]
523
        mov     ebx, [dl_y2]
524
        call    [putpixel]
525
.exit:
526
        add     esp, 6*4
527
        popa
528
;     dec   [mouse_pause]
529
        call    [draw_pointer]
530
        ret
531
 
532
 
533
hline:
534
; draw an horizontal line
535
; eax = x1
536
; edx = x2
537
; ebx = y
538
; ecx = color
539
; edi = force ?
540
        push    eax edx
541
        cmp     edx, eax   ; make sure x2 is above x1
542
        jge     @f
543
        xchg    eax, edx
544
align   4
545
@@:
546
        call    [putpixel]
547
        inc     eax
548
        cmp     eax, edx
549
        jle     @b
550
        pop     edx eax
551
        ret
552
 
553
 
554
vline:
555
; draw a vertical line
556
; eax = x
557
; ebx = y1
558
; edx = y2
559
; ecx = color
560
; edi = force ?
561
        push    ebx edx
562
        cmp     edx, ebx   ; make sure y2 is above y1
563
        jge     @f
564
        xchg    ebx, edx
565
align   4
566
@@:
567
        call    [putpixel]
568
        inc     ebx
569
        cmp     ebx, edx
570
        jle     @b
571
        pop     edx ebx
572
        ret
573
 
574
 
575
;*************************************************
576
 
577
 
578
virtual at esp
579
drbar:
580
     .bar_sx       dd ?
581
     .bar_sy       dd ?
582
     .bar_cx       dd ?
583
     .bar_cy       dd ?
584
     .abs_cx       dd ?
585
     .abs_cy       dd ?
586
     .real_sx      dd ?
587
     .real_sy      dd ?
588
     .color        dd ?
589
     .line_inc_scr dd ?
590
     .line_inc_map dd ?
591
     .stack_data = 4*11
592
end virtual
593
 
594
align 4
595
; eax   cx
596
; ebx   cy
597
; ecx   xe
598
; edx   ye
599
; edi   color
600
vesa20_drawbar:
601
        pushad
602
        call    [_display.disable_mouse]
603
        sub     esp, drbar.stack_data
604
        mov     [drbar.color], edi
605
        sub     edx, ebx
606
        jle     .exit       ;// mike.dld, 2005-01-29
607
        sub     ecx, eax
608
        jle     .exit       ;// mike.dld, 2005-01-29
609
        mov     [drbar.bar_sy], edx
610
        mov     [drbar.bar_sx], ecx
611
        mov     [drbar.bar_cx], eax
612
        mov     [drbar.bar_cy], ebx
613
        mov     edi, [TASK_BASE]
614
        add     eax, [edi-twdw + WDATA.box.left]; win_cx
615
        add     ebx, [edi-twdw + WDATA.box.top]; win_cy
616
        mov     [drbar.abs_cx], eax
617
        mov     [drbar.abs_cy], ebx
618
; real_sx = MIN(wnd_sx-bar_cx, bar_sx);
619
        mov     ebx, [edi-twdw + WDATA.box.width]; ebx = wnd_sx
620
; \begin{diamond}[20.08.2006]
621
; note that WDATA.box.width is one pixel less than real window x-size
622
        inc     ebx
623
; \end{diamond}[20.08.2006]
624
        sub     ebx, [drbar.bar_cx]
625
        ja      @f
626
.exit:                       ;// mike.dld, 2005-01-29
627
        add     esp, drbar.stack_data
628
        popad
629
        xor     eax, eax
630
        inc     eax
631
        ret
632
@@:
633
        cmp     ebx, [drbar.bar_sx]
634
        jbe     .end_x
635
        mov     ebx, [drbar.bar_sx]
636
.end_x:
637
        mov     [drbar.real_sx], ebx
638
; real_sy = MIN(wnd_sy-bar_cy, bar_sy);
639
        mov     ebx, [edi-twdw + WDATA.box.height]; ebx = wnd_sy
640
; \begin{diamond}[20.08.2006]
641
        inc     ebx
642
; \end{diamond}
643
        sub     ebx, [drbar.bar_cy]
644
        ja      @f
645
        add     esp, drbar.stack_data
646
        popad
647
        xor     eax, eax
648
        inc     eax
649
        ret
650
@@:
651
        cmp     ebx, [drbar.bar_sy]
652
        jbe     .end_y
653
        mov     ebx, [drbar.bar_sy]
654
.end_y:
655
        mov     [drbar.real_sy], ebx
656
; line_inc_map
657
        mov     eax, [Screen_Max_X]
658
        sub     eax, [drbar.real_sx]
659
        inc     eax
660
        mov     [drbar.line_inc_map], eax
661
; line_inc_scr
662
        mov     eax, [drbar.real_sx]
663
        movzx   ebx, byte [ScreenBPP]
664
        shr     ebx, 3
665
        imul    eax, ebx
666
        neg     eax
667
        add     eax, [BytesPerScanLine]
668
        mov     [drbar.line_inc_scr], eax
669
; pointer to screen
670
        mov     edx, [drbar.abs_cy]
671
        imul    edx, [BytesPerScanLine]
672
        mov     eax, [drbar.abs_cx]
673
;     movzx   ebx, byte [ScreenBPP]
674
;     shr     ebx, 3
675
        imul    eax, ebx
676
        add     edx, eax
677
; pointer to pixel map
678
        mov     eax, [drbar.abs_cy]
679
        imul    eax, [Screen_Max_X]
680
        add     eax, [drbar.abs_cy]
681
        add     eax, [drbar.abs_cx]
682
        add     eax, [_WinMapAddress]
683
        xchg    eax, ebp
684
; get process number
685
        mov     ebx, [CURRENT_TASK]
686
        cmp     byte [ScreenBPP], 24
687
        jne     draw_bar_end_32
688
draw_bar_end_24:
689
        mov     eax, [drbar.color] ;; BBGGRR00
690
        mov     bh, al             ;; bh  = BB
691
        shr     eax, 8             ;; eax = RRGG
692
; eax - color high   RRGG
693
; bl - process num
694
; bh - color low    BB
695
; ecx - temp
696
; edx - pointer to screen
697
; esi - counter
698
; edi - counter
699
        mov     esi, [drbar.real_sy]
700
align   4
701
.new_y:
702
        mov     edi, [drbar.real_sx]
703
align   4
704
.new_x:
705
        cmp     byte [ebp], bl
706
        jne     .skip
707
 
708
        mov     [LFB_BASE+edx], bh
709
        mov     [LFB_BASE+edx + 1], ax
710
.skip:
711
; add pixel
712
        add     edx, 3
713
        inc     ebp
714
        dec     edi
715
        jnz     .new_x
716
; add line
717
        add     edx, [drbar.line_inc_scr]
718
        add     ebp, [drbar.line_inc_map]
719
;  drawing gradient bars
720
        test    eax, 0x00800000
721
        jz      @f
722
        test    bh, bh
723
        jz      @f
724
        dec     bh
725
@@:
726
; 
727
        dec     esi
728
        jnz     .new_y
729
        add     esp, drbar.stack_data
730
        popad
731
        xor     eax, eax
732
        ret
733
 
734
draw_bar_end_32:
735
        mov     eax, [drbar.color] ;; BBGGRR00
736
        mov     esi, [drbar.real_sy]
737
align   4
738
.new_y:
739
        mov     edi, [drbar.real_sx]
740
align   4
741
.new_x:
742
        cmp     byte [ebp], bl
743
        jne     .skip
744
 
745
        mov     [LFB_BASE+edx], eax
746
.skip:
747
; add pixel
748
        add     edx, 4
749
        inc     ebp
750
        dec     edi
751
        jnz     .new_x
752
; add line
753
        add     edx, [drbar.line_inc_scr]
754
        add     ebp, [drbar.line_inc_map]
755
;  drawing gradient bars
756
        test    eax, 0x80000000
757
        jz      @f
758
        test    al, al
759
        jz      @f
760
        dec     al
761
@@:
762
; 
763
        dec     esi
764
        jnz     .new_y
765
        add     esp, drbar.stack_data
766
        popad
767
        call    VGA_draw_bar
768
        xor     eax, eax
769
        mov     [EGA_counter], 1
770
        ret
771
 
772
align 4
773
vesa20_drawbackground_tiled:
774
        call    [_display.disable_mouse]
775
        pushad
776
; External loop for all y from start to end
777
        mov     ebx, [draw_data+32+RECT.top]    ; y start
778
dp2:
779
        mov     ebp, [draw_data+32+RECT.left]   ; x start
780
; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
781
;                       and LFB data (output for our function) [edi]
782
        mov     eax, [BytesPerScanLine]
783
        mul     ebx
784
        xchg    ebp, eax
785
        add     ebp, eax
786
        add     ebp, eax
787
        add     ebp, eax
788
        cmp     [ScreenBPP], byte 24    ; 24 or 32 bpp ? - x size
789
        jz      @f
790
        add     ebp, eax
791
@@:
792
        add     ebp, LFB_BASE
793
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
794
        call    calculate_edi
795
        xchg    edi, ebp
796
        add     ebp, [_WinMapAddress]
797
; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
798
; 2) Calculate offset in background memory block
799
        push    eax
800
        xor     edx, edx
801
        mov     eax, ebx
802
        div     dword [BgrDataHeight]   ; edx := y mod BgrDataHeight
803
        pop     eax
804
        push    eax
805
        mov     ecx, [BgrDataWidth]
806
        mov     esi, edx
807
        imul    esi, ecx                ; esi := (y mod BgrDataHeight) * BgrDataWidth
808
        xor     edx, edx
809
        div     ecx             ; edx := x mod BgrDataWidth
810
        sub     ecx, edx
811
        add     esi, edx        ; esi := (y mod BgrDataHeight)*BgrDataWidth + (x mod BgrDataWidth)
812
        pop     eax
813
        lea     esi, [esi*3]
814
        add     esi, [img_background]
815
        xor     edx, edx
816
        inc     edx
817
; 3) Loop through redraw rectangle and copy background data
818
; Registers meaning:
819
; eax = x, ebx = y (screen coordinates)
820
; ecx = deltax - number of pixels left in current tile block
821
; edx = 1
822
; esi -> bgr memory, edi -> output
823
; ebp = offset in WinMapAddress
824
dp3:
825
        cmp     [ebp], dl
826
        jnz     nbgp
827
        movsb
828
        movsb
829
        movsb
830
        jmp     @f
831
nbgp:
832
        add     esi, 3
833
        add     edi, 3
834
@@:
835
        cmp     [ScreenBPP], byte 25    ; 24 or 32 bpp?
836
        sbb     edi, -1         ; +1 for 32 bpp
837
; I do not use 'inc eax' because this is slightly slower then 'add eax,1'
838
        add     ebp, edx
839
        add     eax, edx
840
        cmp     eax, [draw_data+32+RECT.right]
841
        ja      dp4
842
        sub     ecx, edx
843
        jnz     dp3
844
; next tile block on x-axis
845
        mov     ecx, [BgrDataWidth]
846
        sub     esi, ecx
847
        sub     esi, ecx
848
        sub     esi, ecx
849
        jmp     dp3
850
dp4:
851
; next scan line
852
        inc     ebx
853
        cmp     ebx, [draw_data+32+RECT.bottom]
854
        jbe     dp2
855
        popad
856
        mov     [EGA_counter], 1
857
        call    VGA_drawbackground
858
        ret
859
 
860
; ----------
861
 
862
 
863
vesa20_drawbackground_stretch:
864
        call    [_display.disable_mouse]
865
        pushad
866
; Helper variables
867
; calculate 2^32*(BgrDataWidth-1) mod (ScreenWidth-1)
868
        mov     eax, [BgrDataWidth]
869
        dec     eax
870
        xor     edx, edx
871
        div     dword [Screen_Max_X]
872
        push    eax     ; high
873
        xor     eax, eax
874
        div     dword [Screen_Max_X]
875
        push    eax     ; low
876
; the same for height
877
        mov     eax, [BgrDataHeight]
878
        dec     eax
879
        xor     edx, edx
880
        div     dword [Screen_Max_Y]
881
        push    eax     ; high
882
        xor     eax, eax
883
        div     dword [Screen_Max_Y]
884
        push    eax     ; low
885
; External loop for all y from start to end
886
        mov     ebx, [draw_data+32+RECT.top]    ; y start
887
        mov     ebp, [draw_data+32+RECT.left]   ; x start
888
; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
889
;                       and LFB data (output for our function) [edi]
890
        mov     eax, [BytesPerScanLine]
891
        mul     ebx
892
        xchg    ebp, eax
893
        add     ebp, eax
894
        add     ebp, eax
895
        add     ebp, eax
896
        cmp     [ScreenBPP], byte 24    ; 24 or 32 bpp ? - x size
897
        jz      @f
898
        add     ebp, eax
899
@@:
900
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
901
        call    calculate_edi
902
        xchg    edi, ebp
903
; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
904
        push    ebx
905
        push    eax
906
; 2) Calculate offset in background memory block
907
        mov     eax, ebx
908
        imul    ebx, dword [esp+12]
909
        mul     dword [esp+8]
910
        add     edx, ebx        ; edx:eax = y * 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
911
        mov     esi, edx
912
        imul    esi, [BgrDataWidth]
913
        push    edx
914
        push    eax
915
        mov     eax, [esp+8]
916
        mul     dword [esp+28]
917
        push    eax
918
        mov     eax, [esp+12]
919
        mul     dword [esp+28]
920
        add     [esp], edx
921
        pop     edx             ; edx:eax = x * 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
922
        add     esi, edx
923
        lea     esi, [esi*3]
924
        add     esi, [img_background]
925
        push    eax
926
        push    edx
927
        push    esi
928
; 3) Smooth horizontal
929
bgr_resmooth0:
930
        mov     ecx, [esp+8]
931
        mov     edx, [esp+4]
932
        mov     esi, [esp]
933
        push    edi
934
        mov     edi, bgr_cur_line
935
        call    smooth_line
936
bgr_resmooth1:
937
        mov     eax, [esp+16+4]
938
        inc     eax
939
        cmp     eax, [BgrDataHeight]
940
        jae     bgr.no2nd
941
        mov     ecx, [esp+8+4]
942
        mov     edx, [esp+4+4]
943
        mov     esi, [esp+4]
944
        add     esi, [BgrDataWidth]
945
        add     esi, [BgrDataWidth]
946
        add     esi, [BgrDataWidth]
947
        mov     edi, bgr_next_line
948
        call    smooth_line
949
bgr.no2nd:
950
        pop     edi
951
sdp3:
952
        xor     esi, esi
953
        mov     ecx, [esp+12]
954
; 4) Loop through redraw rectangle and copy background data
955
; Registers meaning:
956
; esi = offset in current line, edi -> output
957
; ebp = offset in WinMapAddress
958
; dword [esp] = offset in bgr data
959
; qword [esp+4] = x * 2^32 * (BgrDataWidth-1) / (ScreenWidth-1)
960
; qword [esp+12] = y * 2^32 * (BgrDataHeight-1) / (ScreenHeight-1)
961
; dword [esp+20] = x
962
; dword [esp+24] = y
963
; precalculated constants:
964
; qword [esp+28] = 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
965
; qword [esp+36] = 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
966
sdp3a:
967
        mov     eax, [_WinMapAddress]
968
        cmp     [ebp+eax], byte 1
969
        jnz     snbgp
970
        mov     eax, [bgr_cur_line+esi]
971
        test    ecx, ecx
972
        jz      .novert
973
        mov     ebx, [bgr_next_line+esi]
974
        call    [overlapping_of_points_ptr]
975
.novert:
976
 
977
        mov     [LFB_BASE+edi], ax
978
        shr     eax, 16
979
 
980
        mov     [LFB_BASE+edi+2], al
981
snbgp:
982
        cmp     [ScreenBPP], byte 25
983
        sbb     edi, -4
984
        add     ebp, 1
985
        mov     eax, [esp+20]
986
        add     eax, 1
987
        mov     [esp+20], eax
988
        add     esi, 4
989
        cmp     eax, [draw_data+32+RECT.right]
990
        jbe     sdp3a
991
sdp4:
992
; next y
993
        mov     ebx, [esp+24]
994
        add     ebx, 1
995
        mov     [esp+24], ebx
996
        cmp     ebx, [draw_data+32+RECT.bottom]
997
        ja      sdpdone
998
; advance edi, ebp to next scan line
999
        sub     eax, [draw_data+32+RECT.left]
1000
        sub     ebp, eax
1001
        add     ebp, [Screen_Max_X]
1002
        add     ebp, 1
1003
        sub     edi, eax
1004
        sub     edi, eax
1005
        sub     edi, eax
1006
        cmp     [ScreenBPP], byte 24
1007
        jz      @f
1008
        sub     edi, eax
1009
@@:
1010
        add     edi, [BytesPerScanLine]
1011
; restore ecx,edx; advance esi to next background line
1012
        mov     eax, [esp+28]
1013
        mov     ebx, [esp+32]
1014
        add     [esp+12], eax
1015
        mov     eax, [esp+16]
1016
        adc     [esp+16], ebx
1017
        sub     eax, [esp+16]
1018
        mov     ebx, eax
1019
        lea     eax, [eax*3]
1020
        imul    eax, [BgrDataWidth]
1021
        sub     [esp], eax
1022
        mov     eax, [draw_data+32+RECT.left]
1023
        mov     [esp+20], eax
1024
        test    ebx, ebx
1025
        jz      sdp3
1026
        cmp     ebx, -1
1027
        jnz     bgr_resmooth0
1028
        push    edi
1029
        mov     esi, bgr_next_line
1030
        mov     edi, bgr_cur_line
1031
        mov     ecx, [Screen_Max_X]
1032
        inc     ecx
1033
        rep movsd
1034
        jmp     bgr_resmooth1
1035
sdpdone:
1036
        add     esp, 44
1037
        popad
1038
        mov     [EGA_counter], 1
1039
        call    VGA_drawbackground
1040
        ret
1041
 
1042
uglobal
1043
align 4
1044
bgr_cur_line    rd      1920    ; maximum width of screen
1045
bgr_next_line   rd      1920
1046
endg
1047
 
1048
smooth_line:
1049
        mov     al, [esi+2]
1050
        shl     eax, 16
1051
        mov     ax, [esi]
1052
        test    ecx, ecx
1053
        jz      @f
1054
        mov     ebx, [esi+2]
1055
        shr     ebx, 8
1056
        call    [overlapping_of_points_ptr]
1057
@@:
1058
        stosd
1059
        mov     eax, [esp+20+8]
1060
        add     eax, 1
1061
        mov     [esp+20+8], eax
1062
        cmp     eax, [draw_data+32+RECT.right]
1063
        ja      @f
1064
        add     ecx, [esp+36+8]
1065
        mov     eax, edx
1066
        adc     edx, [esp+40+8]
1067
        sub     eax, edx
1068
        lea     eax, [eax*3]
1069
        sub     esi, eax
1070
        jmp     smooth_line
1071
@@:
1072
        mov     eax, [draw_data+32+RECT.left]
1073
        mov     [esp+20+8], eax
1074
        ret
1075
 
1076
align 16
1077
overlapping_of_points:
1078
if 0
1079
; this version of procedure works, but is slower than next version
1080
        push    ecx edx
1081
        mov     edx, eax
1082
        push    esi
1083
        shr     ecx, 24
1084
        mov     esi, ecx
1085
        mov     ecx, ebx
1086
        movzx   ebx, dl
1087
        movzx   eax, cl
1088
        sub     eax, ebx
1089
        movzx   ebx, dh
1090
        imul    eax, esi
1091
        add     dl, ah
1092
        movzx   eax, ch
1093
        sub     eax, ebx
1094
        imul    eax, esi
1095
        add     dh, ah
1096
        ror     ecx, 16
1097
        ror     edx, 16
1098
        movzx   eax, cl
1099
        movzx   ebx, dl
1100
        sub     eax, ebx
1101
        imul    eax, esi
1102
        pop     esi
1103
        add     dl, ah
1104
        mov     eax, edx
1105
        pop     edx
1106
        ror     eax, 16
1107
        pop     ecx
1108
        ret
1109
else
1110
        push    ecx edx
1111
        mov     edx, eax
1112
        push    esi
1113
        shr     ecx, 26
1114
        mov     esi, ecx
1115
        mov     ecx, ebx
1116
        shl     esi, 9
1117
        movzx   ebx, dl
1118
        movzx   eax, cl
1119
        sub     eax, ebx
1120
        movzx   ebx, dh
1121
        add     dl, [BgrAuxTable+(eax+0x100)+esi]
1122
        movzx   eax, ch
1123
        sub     eax, ebx
1124
        add     dh, [BgrAuxTable+(eax+0x100)+esi]
1125
        ror     ecx, 16
1126
        ror     edx, 16
1127
        movzx   eax, cl
1128
        movzx   ebx, dl
1129
        sub     eax, ebx
1130
        add     dl, [BgrAuxTable+(eax+0x100)+esi]
1131
        pop     esi
1132
        mov     eax, edx
1133
        pop     edx
1134
        ror     eax, 16
1135
        pop     ecx
1136
        ret
1137
end if
1138
 
1139
iglobal
1140
align 4
1141
overlapping_of_points_ptr       dd      overlapping_of_points
1142
endg
1143
 
1144
init_background:
1145
        mov     edi, BgrAuxTable
1146
        xor     edx, edx
1147
.loop2:
1148
        mov     eax, edx
1149
        shl     eax, 8
1150
        neg     eax
1151
        mov     ecx, 0x200
1152
.loop1:
1153
        mov     byte [edi], ah
1154
        inc     edi
1155
        add     eax, edx
1156
        loop    .loop1
1157
        add     dl, 4
1158
        jnz     .loop2
1159
        test    byte [cpu_caps+(CAPS_MMX/8)], 1 shl (CAPS_MMX mod 8)
1160
        jz      @f
1161
        mov     [overlapping_of_points_ptr], overlapping_of_points_mmx
1162
@@:
1163
        ret
1164
 
1165
align 16
1166
overlapping_of_points_mmx:
1167
        movd    mm0, eax
1168
        movd    mm4, eax
1169
        movd    mm1, ebx
1170
        pxor    mm2, mm2
1171
        punpcklbw mm0, mm2
1172
        punpcklbw mm1, mm2
1173
        psubw   mm1, mm0
1174
        movd    mm3, ecx
1175
        psrld   mm3, 24
1176
        packuswb mm3, mm3
1177
        packuswb mm3, mm3
1178
        pmullw  mm1, mm3
1179
        psrlw   mm1, 8
1180
        packuswb mm1, mm2
1181
        paddb   mm4, mm1
1182
        movd    eax, mm4
1183
        ret