Subversion Repositories Kolibri OS

Rev

Rev 837 | Rev 914 | 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: 840 $
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
 
753 serge 26
;Screen_Max_X             equ     0xfe00
27
;Screen_Max_Y            equ     0xfe04
381 serge 28
;BytesPerScanLine        equ     0xfe08
29
;LFBAddress              equ     0xfe80
30
;ScreenBPP               equ     0xfbf1
1 ha 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
753 serge 173
     mov     eax, [Screen_Max_X]
469 serge 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]
753 serge 198
     imul    eax, [Screen_Max_X]
469 serge 199
     add     eax, [putimg.abs_cy]
200
     add     eax, [putimg.abs_cx]
840 serge 201
     add     eax, [_display_data]
469 serge 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]
753 serge 233
     add     ebp, [putimg.winmap_newline] ;[Screen_Max_X]
469 serge 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]
753 serge 266
     add     ebp, [putimg.winmap_newline] ;[Screen_Max_X]
469 serge 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:
753 serge 298
     cmp   [Screen_Max_X], eax
469 serge 299
     jb    .exit
753 serge 300
     cmp   [Screen_Max_Y], ebx
469 serge 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
753 serge 347
     imul    edi, [Screen_Max_X]
469 serge 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
753 serge 604
     mov     eax, [Screen_Max_X]
469 serge 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]
753 serge 627
     imul    eax, [Screen_Max_X]
469 serge 628
     add     eax, [drbar.abs_cy]
629
     add     eax, [drbar.abs_cx]
840 serge 630
     add     eax, [_display_data]
469 serge 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
753 serge 727
;     mov ebx,[Screen_Max_X] ; Screen_X_size
1 ha 728
;     inc ebx   ; +1
840 serge 729
;     sub eax,display_data ; -AddrBuffer
1 ha 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 serge 753
;        mov  ebx,[Screen_Max_X]
1 ha 754
;        inc  ebx
840 serge 755
;        sub  eax,display_data
1 ha 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
840 serge 779
; 1) Calculate pointers in display_data (does pixel belong to OS thread?) [ebp]
527 diamond 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
840 serge 795
 
796
        add ebp, [_display_data]
797
 
798
; Now eax=x, ebx=y, edi->output, ebp=offset in display_data
527 diamond 799
; 2) Calculate offset in background memory block
800
        push    eax
801
        xor     edx, edx
802
        mov     eax, ebx
784 diamond 803
        div     dword [BgrDataHeight]   ; edx := y mod BgrDataHeight
527 diamond 804
        pop     eax
805
        push    eax
784 diamond 806
        mov     ecx, [BgrDataWidth]
527 diamond 807
        mov     esi, edx
784 diamond 808
        imul    esi, ecx                ; esi := (y mod BgrDataHeight) * BgrDataWidth
527 diamond 809
        xor     edx, edx
784 diamond 810
        div     ecx             ; edx := x mod BgrDataWidth
811
        sub     ecx, edx
527 diamond 812
        add     esi, edx        ; esi := (y mod BgrDataHeight)*BgrDataWidth + (x mod BgrDataWidth)
813
        pop     eax
814
        lea     esi, [esi*3]
815
        add     esi, [img_background]
816
        xor     edx, edx
817
        inc     edx
818
; 3) Loop through redraw rectangle and copy background data
819
; Registers meaning:
820
; eax = x, ebx = y (screen coordinates)
821
; ecx = deltax - number of pixels left in current tile block
822
; edx = 1
823
; esi -> bgr memory, edi -> output
840 serge 824
; ebp = offset in display_data
527 diamond 825
dp3:
840 serge 826
        cmp     [ebp], dl
527 diamond 827
        jnz     nbgp
828
        movsb
829
        movsb
830
        movsb
831
        jmp     @f
469 serge 832
nbgp:
527 diamond 833
        add     esi, 3
834
        add     edi, 3
469 serge 835
@@:
527 diamond 836
        cmp     [ScreenBPP], byte 25    ; 24 or 32 bpp?
837
        sbb     edi, -1         ; +1 for 32 bpp
838
; I do not use 'inc eax' because this is slightly slower then 'add eax,1'
839
        add     ebp, edx
840
        add     eax, edx
841
        cmp     eax, [draw_data+32+RECT.right]
842
        ja      dp4
843
        sub     ecx, edx
844
        jnz     dp3
845
; next tile block on x-axis
846
        mov     ecx, [BgrDataWidth]
847
        sub     esi, ecx
848
        sub     esi, ecx
849
        sub     esi, ecx
850
        jmp     dp3
851
dp4:
852
; next scan line
853
        inc     ebx
854
        cmp     ebx, [draw_data+32+RECT.bottom]
855
        jbe     dp2
856
        popad
857
        mov     [EGA_counter], 1
858
        call    VGA_drawbackground
859
        ret
1 ha 860
 
861
; ----------
862
 
863
 
864
vesa20_drawbackground_stretch:
527 diamond 865
        call    [disable_mouse]
866
        pushad
867
; Helper variables
755 diamond 868
; calculate 2^32*(BgrDataWidth-1) mod (ScreenWidth-1)
527 diamond 869
        mov     eax, [BgrDataWidth]
546 diamond 870
        dec     eax
527 diamond 871
        xor     edx, edx
753 serge 872
        div     dword [Screen_Max_X]
546 diamond 873
        push    eax     ; high
874
        xor     eax, eax
753 serge 875
        div     dword [Screen_Max_X]
546 diamond 876
        push    eax     ; low
877
; the same for height
527 diamond 878
        mov     eax, [BgrDataHeight]
546 diamond 879
        dec     eax
527 diamond 880
        xor     edx, edx
753 serge 881
        div     dword [Screen_Max_Y]
546 diamond 882
        push    eax     ; high
883
        xor     eax, eax
753 serge 884
        div     dword [Screen_Max_Y]
546 diamond 885
        push    eax     ; low
527 diamond 886
; External loop for all y from start to end
887
        mov     ebx, [draw_data+32+RECT.top]    ; y start
888
        mov     ebp, [draw_data+32+RECT.left]   ; x start
840 serge 889
; 1) Calculate pointers in display_data (does pixel belong to OS thread?) [ebp]
527 diamond 890
;                       and LFB data (output for our function) [edi]
891
        mov     eax, [BytesPerScanLine]
892
        mul     ebx
893
        xchg    ebp, eax
894
        add     ebp, eax
895
        add     ebp, eax
896
        add     ebp, eax
897
        cmp     [ScreenBPP], byte 24    ; 24 or 32 bpp ? - x size
898
        jz      @f
899
        add     ebp, eax
469 serge 900
@@:
527 diamond 901
        add     ebp, [LFBAddress]
469 serge 902
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
527 diamond 903
        call    calculate_edi
904
        xchg    edi, ebp
840 serge 905
; Now eax=x, ebx=y, edi->output, ebp=offset in display_data
527 diamond 906
        push    ebx
546 diamond 907
        push    eax
527 diamond 908
; 2) Calculate offset in background memory block
909
        mov     eax, ebx
546 diamond 910
        imul    ebx, dword [esp+12]
911
        mul     dword [esp+8]
755 diamond 912
        add     edx, ebx        ; edx:eax = y * 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
546 diamond 913
        mov     esi, edx
914
        imul    esi, [BgrDataWidth]
915
        push    edx
527 diamond 916
        push    eax
546 diamond 917
        mov     eax, [esp+8]
918
        mul     dword [esp+28]
919
        push    eax
920
        mov     eax, [esp+12]
921
        mul     dword [esp+28]
922
        add     [esp], edx
755 diamond 923
        pop     edx             ; edx:eax = x * 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
546 diamond 924
        add     esi, edx
527 diamond 925
        lea     esi, [esi*3]
926
        add     esi, [img_background]
555 diamond 927
        push    eax
928
        push    edx
929
        push    esi
930
; 3) Smooth horizontal
931
bgr_resmooth0:
932
        mov     ecx, [esp+8]
933
        mov     edx, [esp+4]
934
        mov     esi, [esp]
935
        push    edi
936
        mov     edi, bgr_cur_line
937
        call    smooth_line
938
bgr_resmooth1:
559 diamond 939
        mov     eax, [esp+16+4]
940
        inc     eax
941
        cmp     eax, [BgrDataHeight]
942
        jae     bgr.no2nd
555 diamond 943
        mov     ecx, [esp+8+4]
944
        mov     edx, [esp+4+4]
945
        mov     esi, [esp+4]
946
        add     esi, [BgrDataWidth]
947
        add     esi, [BgrDataWidth]
948
        add     esi, [BgrDataWidth]
949
        mov     edi, bgr_next_line
950
        call    smooth_line
951
bgr.no2nd:
952
        pop     edi
953
sdp3:
954
        xor     esi, esi
955
        mov     ecx, [esp+12]
956
; 4) Loop through redraw rectangle and copy background data
527 diamond 957
; Registers meaning:
555 diamond 958
; esi = offset in current line, edi -> output
840 serge 959
; ebp = offset in display_data
555 diamond 960
; dword [esp] = offset in bgr data
755 diamond 961
; qword [esp+4] = x * 2^32 * (BgrDataWidth-1) / (ScreenWidth-1)
962
; qword [esp+12] = y * 2^32 * (BgrDataHeight-1) / (ScreenHeight-1)
536 diamond 963
; dword [esp+20] = x
546 diamond 964
; dword [esp+24] = y
527 diamond 965
; precalculated constants:
755 diamond 966
; qword [esp+28] = 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
967
; qword [esp+36] = 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
555 diamond 968
sdp3a:
840 serge 969
        mov eax, [_display_data]
970
        cmp     [ebp+eax], byte 1
527 diamond 971
        jnz     snbgp
555 diamond 972
        mov     eax, [bgr_cur_line+esi]
546 diamond 973
        test    ecx, ecx
974
        jz      .novert
555 diamond 975
        mov     ebx, [bgr_next_line+esi]
976
        call    [overlapping_of_points_ptr]
546 diamond 977
.novert:
527 diamond 978
        mov     [edi], ax
979
        shr     eax, 16
980
        mov     [edi+2], al
981
snbgp:
982
        cmp     [ScreenBPP], byte 25
983
        sbb     edi, -4
984
        add     ebp, 1
536 diamond 985
        mov     eax, [esp+20]
527 diamond 986
        add     eax, 1
536 diamond 987
        mov     [esp+20], eax
555 diamond 988
        add     esi, 4
527 diamond 989
        cmp     eax, [draw_data+32+RECT.right]
555 diamond 990
        jbe     sdp3a
527 diamond 991
sdp4:
992
; next y
546 diamond 993
        mov     ebx, [esp+24]
527 diamond 994
        add     ebx, 1
546 diamond 995
        mov     [esp+24], ebx
527 diamond 996
        cmp     ebx, [draw_data+32+RECT.bottom]
997
        ja      sdpdone
998
; advance edi, ebp to next scan line
999
        sub     eax, [draw_data+32+RECT.left]
1000
        sub     ebp, eax
753 serge 1001
        add     ebp, [Screen_Max_X]
527 diamond 1002
        add     ebp, 1
1003
        sub     edi, eax
1004
        sub     edi, eax
1005
        sub     edi, eax
1006
        cmp     [ScreenBPP], byte 24
1007
        jz      @f
1008
        sub     edi, eax
379 serge 1009
@@:
527 diamond 1010
        add     edi, [BytesPerScanLine]
1011
; restore ecx,edx; advance esi to next background line
546 diamond 1012
        mov     eax, [esp+28]
1013
        mov     ebx, [esp+32]
1014
        add     [esp+12], eax
1015
        mov     eax, [esp+16]
1016
        adc     [esp+16], ebx
555 diamond 1017
        sub     eax, [esp+16]
1018
        mov     ebx, eax
546 diamond 1019
        lea     eax, [eax*3]
1020
        imul    eax, [BgrDataWidth]
555 diamond 1021
        sub     [esp], eax
527 diamond 1022
        mov     eax, [draw_data+32+RECT.left]
536 diamond 1023
        mov     [esp+20], eax
555 diamond 1024
        test    ebx, ebx
1025
        jz      sdp3
1026
        cmp     ebx, -1
1027
        jnz     bgr_resmooth0
1028
        push    edi
1029
        mov     esi, bgr_next_line
1030
        mov     edi, bgr_cur_line
753 serge 1031
        mov     ecx, [Screen_Max_X]
555 diamond 1032
        inc     ecx
1033
        rep     movsd
1034
        jmp     bgr_resmooth1
527 diamond 1035
sdpdone:
546 diamond 1036
        add     esp, 44
527 diamond 1037
        popad
1038
        mov     [EGA_counter],1
1039
        call    VGA_drawbackground
1040
        ret
1 ha 1041
 
555 diamond 1042
uglobal
1043
align 4
1044
bgr_cur_line    rd      1280    ; maximum width of screen
1045
bgr_next_line   rd      1280
1046
endg
1047
 
1048
smooth_line:
1049
        mov     al, [esi+2]
1050
        shl     eax, 16
1051
        mov     ax, [esi]
1052
        test    ecx, ecx
1053
        jz      @f
1054
        mov     ebx, [esi+2]
1055
        shr     ebx, 8
1056
        call    [overlapping_of_points_ptr]
1057
@@:
1058
        stosd
1059
        mov     eax, [esp+20+8]
1060
        add     eax, 1
1061
        mov     [esp+20+8], eax
1062
        cmp     eax, [draw_data+32+RECT.right]
1063
        ja      @f
1064
        add     ecx, [esp+36+8]
1065
        mov     eax, edx
1066
        adc     edx, [esp+40+8]
1067
        sub     eax, edx
1068
        lea     eax, [eax*3]
1069
        sub     esi, eax
1070
        jmp     smooth_line
1071
@@:
1072
        mov     eax, [draw_data+32+RECT.left]
1073
        mov     [esp+20+8], eax
1074
        ret
1075
 
1076
align 16
379 serge 1077
overlapping_of_points:
555 diamond 1078
if 0
1079
; this version of procedure works, but is slower than next version
546 diamond 1080
        push    ecx edx
1081
        mov     edx, eax
1082
        push    esi
1083
        shr     ecx, 24
1084
        mov     esi, ecx
1085
        mov     ecx, ebx
1086
        movzx   ebx, dl
527 diamond 1087
        movzx   eax, cl
546 diamond 1088
        sub     eax, ebx
527 diamond 1089
        movzx   ebx, dh
546 diamond 1090
        imul    eax, esi
1091
        add     dl, ah
527 diamond 1092
        movzx   eax, ch
546 diamond 1093
        sub     eax, ebx
1094
        imul    eax, esi
1095
        add     dh, ah
1096
        ror     ecx, 16
1097
        ror     edx, 16
1098
        movzx   eax, cl
1099
        movzx   ebx, dl
1100
        sub     eax, ebx
1101
        imul    eax, esi
1102
        pop     esi
1103
        add     dl, ah
1104
        mov     eax, edx
1105
        pop     edx
527 diamond 1106
        ror     eax, 16
546 diamond 1107
        pop     ecx
527 diamond 1108
        ret
555 diamond 1109
else
1110
        push    ecx edx
1111
        mov     edx, eax
1112
        push    esi
1113
        shr     ecx, 26
1114
        mov     esi, ecx
1115
        mov     ecx, ebx
1116
        shl     esi, 9
1117
        movzx   ebx, dl
1118
        movzx   eax, cl
1119
        sub     eax, ebx
1120
        movzx   ebx, dh
1121
        add     dl, [BgrAuxTable+(eax+0x100)+esi]
1122
        movzx   eax, ch
1123
        sub     eax, ebx
1124
        add     dh, [BgrAuxTable+(eax+0x100)+esi]
1125
        ror     ecx, 16
1126
        ror     edx, 16
1127
        movzx   eax, cl
1128
        movzx   ebx, dl
1129
        sub     eax, ebx
1130
        add     dl, [BgrAuxTable+(eax+0x100)+esi]
1131
        pop     esi
1132
        mov     eax, edx
1133
        pop     edx
1134
        ror     eax, 16
1135
        pop     ecx
1136
        ret
1137
end if
1138
 
1139
iglobal
1140
align 4
1141
overlapping_of_points_ptr       dd      overlapping_of_points
1142
endg
1143
 
1144
init_background:
1145
        mov     edi, BgrAuxTable
1146
        xor     edx, edx
1147
.loop2:
1148
        mov     eax, edx
1149
        shl     eax, 8
1150
        neg     eax
1151
        mov     ecx, 0x200
1152
.loop1:
1153
        mov     byte [edi], ah
1154
        inc     edi
1155
        add     eax, edx
1156
        loop    .loop1
1157
        add     dl, 4
1158
        jnz     .loop2
564 diamond 1159
        test    byte [cpu_caps+(CAPS_MMX/8)], 1 shl (CAPS_MMX mod 8)
555 diamond 1160
        jz      @f
1161
        mov     [overlapping_of_points_ptr], overlapping_of_points_mmx
1162
@@:
1163
        ret
1164
 
1165
align 16
1166
overlapping_of_points_mmx:
1167
        movd    mm0, eax
1168
        movd    mm4, eax
1169
        movd    mm1, ebx
1170
        pxor    mm2, mm2
1171
        punpcklbw mm0, mm2
1172
        punpcklbw mm1, mm2
1173
        psubw   mm1, mm0
1174
        movd    mm3, ecx
1175
        psrld   mm3, 24
1176
        packuswb mm3, mm3
1177
        packuswb mm3, mm3
1178
        pmullw  mm1, mm3
1179
        psrlw   mm1, 8
1180
        packuswb mm1, mm2
1181
        paddb   mm4, mm1
1182
        movd    eax, mm4
1183
        ret