Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
425 victor 1
$Revision: 537 $
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
865
        mov     eax, [BgrDataWidth]
866
        xor     edx, edx
867
        mov     ecx, [ScreenWidth]
868
        inc     ecx
869
        div     ecx
870
        push    eax     ; quo
871
        push    edx     ; rem
872
        mov     eax, [BgrDataHeight]
873
        xor     edx, edx
874
        mov     ecx, [ScreenHeight]
875
        inc     ecx
876
        div     ecx
877
        push    eax
878
        push    edx
879
; External loop for all y from start to end
880
        mov     ebx, [draw_data+32+RECT.top]    ; y start
881
        mov     ebp, [draw_data+32+RECT.left]   ; x start
882
; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
883
;                       and LFB data (output for our function) [edi]
884
        mov     eax, [BytesPerScanLine]
885
        mul     ebx
886
        xchg    ebp, eax
887
        add     ebp, eax
888
        add     ebp, eax
889
        add     ebp, eax
890
        cmp     [ScreenBPP], byte 24    ; 24 or 32 bpp ? - x size
891
        jz      @f
892
        add     ebp, eax
469 serge 893
@@:
527 diamond 894
        add     ebp, [LFBAddress]
469 serge 895
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
527 diamond 896
        call    calculate_edi
897
        xchg    edi, ebp
898
; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
899
        push    ebx
900
; 2) Calculate offset in background memory block
901
        push    eax
902
        mov     eax, ebx
903
        mul     dword [BgrDataHeight]
904
        mov     ecx, [ScreenHeight]
905
        inc     ecx
906
        div     ecx             ; eax := y * BgrDataHeight / ScreenHeight
907
                                ; edx := (y * BgrDataHeight) mod ScreenHeight
908
        mov     esi, eax
909
        pop     eax
910
        push    edx             ; dword [esp] = (y * BgrDataHeight) mod ScreenHeight
911
                                ; dword [esp+4] = y * BgrDataHeight / ScreenHeight
912
        push    eax
913
        mov     ecx, [BgrDataWidth]
536 diamond 914
        lea     edx, [ecx*3]
915
        imul    edx, [BgrDataHeight]
916
        add     edx, [img_background]
917
        push    edx
527 diamond 918
        mul     ecx
919
        imul    esi, ecx
920
        dec     ecx
921
        push    ecx
922
        mov     ecx, [ScreenWidth]
923
        inc     ecx
924
        div     ecx             ; eax := x * BgrDataWidth / ScreenWidth
925
                                ; edx := (x * BgrDataWidth) mod ScreenWidth
926
        add     esi, eax
927
        lea     esi, [esi*3]
928
        add     esi, [img_background]
929
        push    ecx edx esi
930
; 3) Loop through redraw rectangle and copy background data
931
; Registers meaning:
932
; ecx = (x * BgrDataWidth) / ScreenWidth
933
; edx = (x * BgrDataWidth) mod ScreenWidth (used to fast recalculating of ecx,esi)
934
; esi -> bgr memory, edi -> output
935
; ebp = offset in WinMapAddress
936
; dword [esp] = saved esi
937
; dword [esp+4] = saved edx
938
; dword [esp+8] = saved ecx
536 diamond 939
; dword [esp+12] = BgrDataWidth-1, x-limit for overlapping of points
940
; dword [esp+16] = end of bgr memory (defines y-limit for overlapping of points)
941
; dword [esp+20] = x
942
; dword [esp+24] = (y * BgrDataHeight) mod ScreenHeight (used to fast recalculating of esi)
943
; dword [esp+28] = y
527 diamond 944
; precalculated constants:
536 diamond 945
; dword [esp+32] = BgrDataHeight mod ScreenHeight
946
; dword [esp+36] = BgrDataHeight div ScreenHeight
947
; dword [esp+40] = BgrDataWidth mod ScreenWidth
948
; dword [esp+44] = BgrDataWidth div ScreenWidth
527 diamond 949
sdp3:
536 diamond 950
        add     edx, [esp+40]
527 diamond 951
        cmp     [ebp+WinMapAddress], byte 1
952
        jnz     snbgp
953
        mov     al, [esi+2]
954
        shl     eax, 16
955
        mov     ax, [esi]
956
        cmp     ecx, [esp+12]
957
        jae     @f
536 diamond 958
        cmp     edx, [ScreenWidth]
959
        jb      @f
527 diamond 960
        mov     ebx, [esi+2]
961
        shr     ebx, 8
962
        call    overlapping_of_points
469 serge 963
@@:
536 diamond 964
        mov     ebx, [esp+24]
965
        add     ebx, [esp+32]
966
        cmp     ebx, [ScreenHeight]
967
        jbe     @f
968
        mov     ebx, [BgrDataWidth]
969
        lea     ebx, [ebx*3]
970
        add     ebx, esi
971
        cmp     ebx, [esp+16]
972
        jae     @f
973
        mov     ebx, [ebx-1]
974
        shr     ebx, 8
975
        call    overlapping_of_points
976
@@:
527 diamond 977
        mov     [edi], ax
978
        shr     eax, 16
979
        mov     [edi+2], al
980
snbgp:
981
        cmp     [ScreenBPP], byte 25
982
        sbb     edi, -4
983
        add     ebp, 1
536 diamond 984
        mov     eax, [esp+20]
527 diamond 985
        add     eax, 1
536 diamond 986
        mov     [esp+20], eax
527 diamond 987
        cmp     eax, [draw_data+32+RECT.right]
988
        ja      sdp4
536 diamond 989
        mov     eax, [esp+44]
527 diamond 990
        add     ecx, eax
991
        lea     eax, [eax*3]
992
        add     esi, eax
536 diamond 993
;        add     edx, [esp+40]
527 diamond 994
        cmp     edx, [ScreenWidth]
995
        jbe     sdp3
996
        sub     edx, [ScreenWidth]
997
        add     ecx, 1
998
        add     esi, 3
999
        sub     edx, 1
1000
        jmp     sdp3
1001
sdp4:
1002
; next y
536 diamond 1003
        mov     ebx, [esp+28]
527 diamond 1004
        add     ebx, 1
536 diamond 1005
        mov     [esp+28], ebx
527 diamond 1006
        cmp     ebx, [draw_data+32+RECT.bottom]
1007
        ja      sdpdone
1008
; advance edi, ebp to next scan line
1009
        sub     eax, [draw_data+32+RECT.left]
1010
        sub     ebp, eax
1011
        add     ebp, [ScreenWidth]
1012
        add     ebp, 1
1013
        sub     edi, eax
1014
        sub     edi, eax
1015
        sub     edi, eax
1016
        cmp     [ScreenBPP], byte 24
1017
        jz      @f
1018
        sub     edi, eax
379 serge 1019
@@:
527 diamond 1020
        add     edi, [BytesPerScanLine]
1021
; restore ecx,edx; advance esi to next background line
1022
        pop     esi edx ecx
1023
        push    ecx edx
1024
        xor     ebx, ebx
536 diamond 1025
        mov     eax, [esp+24-4]
1026
        add     eax, [esp+32-4]
527 diamond 1027
        cmp     eax, [ScreenHeight]
1028
        jbe     @f
1029
        sub     eax, [ScreenHeight]
1030
        mov     ebx, 1
1031
        sub     eax, ebx
379 serge 1032
@@:
536 diamond 1033
        mov     [esp+24-4], eax
1034
        add     ebx, [esp+36-4]
527 diamond 1035
        lea     ebx, [ebx*3]
1036
        imul    ebx, [BgrDataWidth]
1037
        add     esi, ebx
1038
        push    esi
1039
        mov     eax, [draw_data+32+RECT.left]
536 diamond 1040
        mov     [esp+20], eax
527 diamond 1041
        jmp     sdp3
1042
sdpdone:
536 diamond 1043
        add     esp, 48
527 diamond 1044
        popad
1045
        mov     [EGA_counter],1
1046
        call    VGA_drawbackground
1047
        ret
1 ha 1048
 
379 serge 1049
overlapping_of_points:
527 diamond 1050
        push    ecx edx edi
1051
        mov     ecx, eax
1052
        mov     edx, ebx
1053
        movzx   eax, cl
1054
        movzx   ebx, dl
1055
        add     eax, ebx
1056
        rcr     eax, 1
1057
        movzx   edi, ax
1058
        movzx   eax, ch
1059
        movzx   ebx, dh
1060
        add     eax, ebx
1061
        rcr     eax, 1
1062
        ror     edi, 8
1063
        add     edi, eax
1064
        shr     ecx, 8
1065
        shr     edx, 8
1066
        movzx   eax, ch
1067
        movzx   ebx, dh
1068
        add     eax, ebx
1069
        rcr     eax, 1
1070
        ror     edi, 8
1071
        add     eax, edi
1072
        ror     eax, 16
1073
        pop     edi edx ecx
1074
        ret