Subversion Repositories Kolibri OS

Rev

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