Subversion Repositories Kolibri OS

Rev

Rev 996 | Details | Compare with Previous | Last modification | View Log | RSS feed

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