Subversion Repositories Kolibri OS

Rev

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

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