Subversion Repositories Kolibri OS

Rev

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