Subversion Repositories Kolibri OS

Rev

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

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