Subversion Repositories Kolibri OS

Rev

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