Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2292 leency 1
; Cb-n#%li.-# @l$i Lkbnbe
2
convert_color:
3
	bswap	eax
4
	shr	eax, 8
5
	ret
6
 
7
draw_window_base:
8
	mov	al, byte [ebp+tls.color_main+3]
9
	and	eax, 0xF
10
	dec	eax
11
	js	.type1
12
	jz	.nodraw
13
	dec	eax
14
	jz	.type2
15
; window with skin
16
	push	1
17
	call	draw_border
18
	call	draw_caption_skinned
19
	movzx	eax, [ebp+tls.y_size]
20
	cmp	eax, 21+5
21
	jle	@f
22
	test    byte [ebp+tls.color_main+3], 40h
23
	jnz     @f
24
	push    1
25
	push    [ebp+tls.color_main]
26
	movzx   ecx, [ebp+tls.y_size]
27
	sub     ecx, 5
28
	push    ecx
29
	movzx   ecx, [ebp+tls.x_size]
30
	sub     ecx, 5
31
	push    ecx
32
	push    [_skinh]
33
	push    5
34
	call    rectangle_gradient
35
@@:
36
; close button
37
	mov	edx, 40000001h	; id=1, no draw
38
	xor	ebx, ebx
39
	cmp	[skin_btn_close.left], ebx
40
	jge	@f
41
	mov	ebx, dword [ebp+tls.x_size]
42
@@:
43
	add	ebx, [skin_btn_close.left]
44
	shl	ebx, 16
45
	mov	bx, word [skin_btn_close.width]
46
	dec	ebx
47
	mov	ecx, [skin_btn_close.top]
48
	shl	ecx, 16
49
	mov	cx, word [skin_btn_close.height]
50
	dec	ecx
51
	call	add_button
52
; minimize button
53
	mov	edx, 4000FFFFh	; id=65535, no draw
54
	xor	ebx, ebx
55
	cmp	[skin_btn_minimize.left], ebx
56
	jge	@f
57
	mov	ebx, dword [ebp+tls.x_size]
58
@@:
59
	add	ebx, [skin_btn_minimize.left]
60
	shl	ebx, 16
61
	mov	bx, word [skin_btn_minimize.width]
62
	dec	ebx
63
	mov	ecx, [skin_btn_minimize.top]
64
	shl	ecx, 16
65
	mov	cx, word [skin_btn_minimize.height]
66
	dec	ecx
67
	call	add_button
68
	jmp	.nodraw
69
.type1:
70
; border
71
	mov	eax, [ebp+tls.color_border]
72
	call	create_select_pen
73
	push	eax
74
	xor	esi, esi
75
	call	rect_wnd
76
	call	select_delete
77
; caption
78
        call    draw_caption_type1
79
; work area
80
        test    byte [ebp+tls.color_main+3], 40h
81
        jnz     .nodraw
82
	push	1
83
	push	[ebp+tls.color_main]
84
	movzx	eax, [ebp+tls.y_size]
85
	dec	eax
86
	push	eax
87
	movzx	eax, [ebp+tls.x_size]
88
	dec	eax
89
	push	eax
90
	push	21
91
	push	1
92
	call	rectangle_gradient
93
	jmp	.nodraw
94
.type2:
95
; border
96
	push	eax
97
	call	draw_border
98
; caption
99
        call    draw_caption_type2
100
; work area
101
        test    byte [ebp+tls.color_main+3], 40h
102
        jnz     .nodraw
103
	push	1
104
	push	[ebp+tls.color_main]
105
	movzx	eax, [ebp+tls.y_size]
106
	sub	eax, 5
107
	push	eax
108
	movzx	eax, [ebp+tls.x_size]
109
	sub	eax, 5
110
	push	eax
111
	push	20
112
	push	5
113
	call	rectangle_gradient
114
.nodraw:
115
; caption string
116
        call    draw_caption_string
117
; draw buttons
118
	pushad
119
	mov	esi, [ebp+tls.buttons]
120
@@:
121
	test	esi, esi
122
	jz	@f
123
	push	[esi+button_desc.next]
124
	mov	ebx, dword [esi+button_desc.xsize]
125
	mov	ecx, dword [esi+button_desc.ysize]
126
	test	byte [esi+button_desc.id+3], 0x40
127
	mov	esi, [esi+button_desc.color]
128
	jnz	.sk
129
	call	draw_button
130
.sk:
131
	pop	esi
132
	jmp	@b
133
@@:
134
	popad
135
	ret
136
 
137
draw_caption_type1:
138
	push	040404h
139
	push	[ebp+tls.color_capt]
140
	movzx	eax, [ebp+tls.y_size]
141
	dec	eax
142
	cmp	eax, 21
143
	jb	@f
144
	mov	eax, 21
145
@@:
146
	push	eax
147
	movzx	eax, [ebp+tls.x_size]
148
	dec	eax
149
	push	eax
150
	push	1
151
	push	1
152
	call	rectangle_gradient
153
        ret
154
 
155
draw_caption_type2:
156
	mov	eax, [ebp+tls.color_capt]
157
	mov	ecx, 0x040404
158
	test	eax, 0x40000000
159
	jz	@f
160
	or	ecx, 0x80000000
161
	xor	eax, 0xC0000000
162
@@:
163
	push	ecx
164
	push	eax
165
	movzx	eax, [ebp+tls.y_size]
166
	sub	eax, 4
167
	cmp	eax, 20
168
	jb	@f
169
	mov	eax, 20
170
@@:	push	eax
171
	movzx	eax, [ebp+tls.x_size]
172
	sub	eax, 4
173
	push	eax
174
	push	4
175
	push	4
176
	call	rectangle_gradient
177
	ret
178
 
179
draw_caption_skinned:
180
	xor	ebx, ebx
181
	mov	eax, [left_bmp]
182
	cmp	[ebp+tls.bActive], bl
183
	jnz	@f
184
	mov	eax, [left1_bmp]
185
@@:
186
	xor	ecx, ecx
187
	call	putbmp
188
	movzx	esi, [ebp+tls.x_size]
189
	mov	ecx, [eax+4]
190
	sub	esi, ecx
191
	mov	eax, [oper_bmp]
192
	cmp	[ebp+tls.bActive], bl
193
	jnz	@f
194
	mov	eax, [oper1_bmp]
195
@@:
196
	sub	esi, [eax+4]
197
	mov	eax, [base_bmp]
198
	cmp	[ebp+tls.bActive], bl
199
	jnz	@f
200
	mov	eax, [base1_bmp]
201
@@:
202
	cmp	esi, [eax+4]
203
	jle	.nobase
204
@@:
205
	call	putbmp
206
	add	ecx, [eax+4]
207
	sub	esi, [eax+4]
208
	jg	@b
209
.nobase:
210
	movzx	ecx, [ebp+tls.x_size]
211
	mov	eax, [oper_bmp]
212
	cmp	[ebp+tls.bActive], bl
213
	jnz	@f
214
	mov	eax, [oper1_bmp]
215
@@:
216
	sub	ecx, [eax+4]
217
 
218
putbmp:
219
; in: eax=bmpinfo,ecx=y*65536+x,edi=hDC
220
	push	eax ecx
221
	lea	edx, [eax+40]
222
	push	ebx		; fuColorUse = DIB_RGB_COLORS
223
	push	eax		; lpbmi
224
	push	edx		; lpBits
225
	push	dword [eax+8]	; cScanLines
226
	push	ebx		; uStartScan
227
	push	ebx		; YSrc
228
	push	ebx		; XSrc
229
	push	dword [eax+8]	; dwHeight
230
	push	dword [eax+4]	; dwWidth
231
	movzx	eax, cx
232
	shr	ecx, 10h
233
	push	ecx		; YDest
234
	push	eax		; XDest
235
	push	edi		; hDC
236
	call	[SetDIBitsToDevice]
237
	pop	ecx eax
238
	ret
239
 
240
draw_caption_string:
241
        test    byte [ebp+tls.color_main+3], 0x10
242
        jnz     @f
243
.ret:
244
.nodraw:
245
        ret
246
@@:
247
        mov     esi, [ebp+tls.caption]
248
        test    esi, esi
249
        jz      .ret
250
        add     esi, [base]
251
        mov     al, byte [ebp+tls.color_main+3]
252
        and     eax, 0xF
253
        dec     eax
254
        js      .type1
255
        jz      .nodraw
256
        dec     eax
257
        jz      .type2
258
; caption for skinned windows
259
; determine maximum caption length
260
        mov     ax, [ebp+tls.x_size]
261
        sub     ax, [margins+2]
262
        sub     ax, [margins]
263
        js      .ret
264
        cwd
265
        push    6
266
        pop     ebx
267
        div     bx
268
        mov     ecx, eax
269
; determine coordinates
270
        mov     ebx, dword [margins]
271
        mov     bx, word [_skinh]
272
        sub     bx, [margins+6]
273
        sub     bx, [margins+4]
274
        sar     bx, 1
275
        adc     bx, 0
276
        add     bx, [margins+6]
277
        add     bx, -3
278
.common:
279
        mov     edx, esi
280
@@:
281
        lodsb
282
        test    al, al
283
        loopnz  @b
284
        jnz     @f
285
        dec     esi
286
@@:     sub     esi, edx
287
        mov     ecx, dword [common_colors+16]
288
        jmp     i40_writetext_l2
289
.type1:
290
.type2:
291
; caption for windows without skin
292
        movzx   eax, [ebp+tls.x_size]
293
        sub     eax, 16
294
        js      .ret
295
        cdq
296
        push    6
297
        pop     ebx
298
        div     ebx
299
        mov     ecx, eax
300
        mov     ebx, 0x00080007
301
        jmp     .common
302
 
303
i40_draw_window:
304
	mov	[ebp+tls.color_main], edx
305
	mov	[ebp+tls.color_capt], esi
306
	mov	[ebp+tls.color_border], edi
307
	mov	[ebp+tls.curdraw], 0
308
	cmp	[ebp+tls.showwnd], 0
309
	jnz	.wasshown
310
; real size is 1 pixel more
311
	inc	ebx
312
	mov	dword [ebp+tls.x_size], ebx
313
	inc	ecx
314
	mov	dword [ebp+tls.y_size], ecx
315
	test    edx, 0x10000000
316
	jz      @f
317
	mov     [ebp+tls.caption], edi
318
@@:
319
	push	0
320
	movzx	eax, cx
321
	push	eax
322
	movzx	eax, bx
323
	push	eax
324
	shr	ecx, 10h
325
	push	ecx
326
	shr	ebx, 10h
327
	push	ebx
328
	push	[ebp+tls.hWnd]
329
	call	[MoveWindow]
330
	push	5	; SW_SHOW
331
	push	[ebp+tls.hWnd]
332
	call	[ShowWindow]
333
	mov	[ebp+tls.showwnd], 1
334
	cmp	[ebp+tls.lpShapeData], 0
335
	jz	@f
336
	call	set_window_shape
337
@@:
338
.wasshown:
339
; define client box
340
        test    byte [ebp+tls.color_main+3], 0x20
341
        jnz     .client_relative
342
        and     [ebp+tls.client_left], 0
343
        and     [ebp+tls.client_top], 0
344
        movzx   eax, [ebp+tls.x_size]
345
        mov     [ebp+tls.client_width], eax
346
        movzx   eax, [ebp+tls.y_size]
347
        mov     [ebp+tls.client_height], eax
348
        jmp     .client_set
349
.client_relative:
350
        mov     eax, [_skinh]
351
        mov     [window_topleft+8*3+4], eax
352
	mov	[window_topleft+8*4+4], eax
353
        mov     al, byte [ebp+tls.color_main+3]
354
        and     eax, 0xF
355
        mov     edx, [eax*8+window_topleft]
356
        mov     [ebp+tls.client_left], edx
357
        neg     edx
358
        movzx   ecx, [ebp+tls.x_size]
359
        lea     ecx, [ecx+edx*2]
360
        mov     [ebp+tls.client_width], ecx
361
        mov     eax, [eax*8+window_topleft+4]
362
        mov     [ebp+tls.client_top], eax
363
        movzx   ecx, [ebp+tls.y_size]
364
        sub     ecx, eax
365
        add     ecx, edx
366
        mov     [ebp+tls.client_height], ecx
367
.client_set:
368
	push	0
369
	push	[ebp+tls.hWnd]
370
	call	[ValidateRect]
371
	push	[ebp+tls.hWnd]
372
	call	[GetDC]
373
	xchg	eax, edi
374
	call	draw_window_base
375
	push	edi
376
	push	[ebp+tls.hWnd]
377
	call	[ReleaseDC]
378
	ret
379
 
380
i40_put_pixel:
381
	test	edx, 1000000h
382
	jnz	.negate
383
	mov	eax, edx
384
	call	convert_color
385
	push	eax
386
	add     ebx, [ebp+tls.client_left]
387
	add     ecx, [ebp+tls.client_top]
388
	push	ecx
389
	push	ebx
390
	push	[ebp+tls.hWnd]
391
	call	[GetDC]
392
	xchg	eax, edi
393
.1:
394
	push	edi
395
	call	[SetPixel]
396
	push	edi
397
	push	[ebp+tls.hWnd]
398
	call	[ReleaseDC]
399
	ret
400
.negate:
401
	push	ecx
402
	push	ecx
403
	push	ebx
404
	push	[ebp+tls.hWnd]
405
	call	[GetDC]
406
	xchg	eax, edi
407
	push	edi
408
	call	[GetPixel]
409
	pop	ecx
410
	not	eax
411
	push	eax
412
	push	ecx
413
	push	ebx
414
	jmp	.1
415
 
416
i40_getkey:
417
	movzx	ecx, [ebp+tls.keybuflen]
418
	jecxz	.empty
419
	lea	esi, [ebp+tls.keybuffer]
420
	mov	edi, esi
421
	lodsb
422
	shl	eax, 8
423
	mov	[esp+20h], ax
424
	dec	ecx
425
	mov	[ebp+tls.keybuflen], cl
426
	rep	movsb
427
	ret
428
.empty:
429
	mov	byte [esp+20h], 1
430
	ret
431
 
432
i40_get_sys_time:
433
	sub	esp, 10h
434
	push	esp
435
	call	[GetLocalTime]
436
	movzx	eax, word [esp+12]
437
	aam
438
	shl	ax, 4
439
	shr	ah, 4
440
	shl	eax, 16-4
441
	mov	ax, [esp+10]
442
	aam
443
	shl	ax, 4
444
	shr	ah, 4
445
	shr	ax, 4
446
	mov	bl, al
447
	mov	ax, [esp+8]
448
	aam
449
	shl	ax, 4
450
	shr	ah, 4
451
	shr	ax, 4
452
	mov	ah, bl
453
	add	esp, 10h
454
	mov	[esp+20h], eax
455
	ret
456
 
457
i40_writetext:
458
	add	edx, [base]
459
i40_writetext_l1:
460
        add     bx, word [ebp+tls.client_top]
461
        ror     ebx, 16
462
        add     bx, word [ebp+tls.client_left]
463
        ror     ebx, 16
464
i40_writetext_l2:
465
        push    edi
466
	push	ecx
467
	push	edx
468
	push	[ebp+tls.hWnd]
469
	call	[GetDC]
470
	mov	ecx, esi
471
	pop	esi
472
	pop	edi
473
	push	eax
474
; ecx=length, esi=pointer, ebx=x*65536+y, edi=font&color
475
.loop:
476
	xor	eax, eax
477
	lodsb
478
	test    edi, edi
479
	js      .test_asciiz
480
	dec     ecx
481
	js      .done
482
	jmp     @f
483
.test_asciiz:
484
        test    eax, eax
485
        jz      .done
486
@@:
487
	push	esi
488
	push	ecx
489
	mov	esi, [char_mt]
490
	lea	esi, [esi + eax*8]
491
	add	esi, eax
492
	mov     ecx, 6
493
	test	edi, 10000000h
494
	jz	@f
495
	sub	esi, [char_mt]
496
	add	esi, [char2_mt]
497
	add	esi, eax
498
	lodsb
499
	mov     ecx, eax
500
@@:
501
	mov	edx, 9
502
.intloop:
503
	lodsb
504
	push	ebx
505
	push    ecx
506
.intintloop:
507
        shr     al, 1
508
        pushad
509
        jnc     .nopix
510
	mov	eax, edi
511
@@:
512
	call	convert_color
513
	push	eax
514
	movzx	eax, bx
515
	push	eax
516
	shr	ebx, 16
517
	push	ebx
518
	push	dword [esp+3Ch]	; hDC
519
	call	[SetPixel]
520
	jmp     @f
521
.nopix:
522
        mov     eax, [esp+34h]
523
        test    edi, 0x40000000
524
        jnz     @b
525
@@:
526
	popad
527
	add	ebx, 10000h
528
	loop    .intintloop
529
	pop     ecx
530
	pop	ebx
531
	inc	ebx
532
	dec	edx
533
	jnz	.intloop
534
	sub	ebx, 9
535
   	shl	ecx, 16
536
	add	ebx, ecx
537
	pop	ecx
538
	pop	esi
539
	jmp	.loop
540
.done:
541
	push	[ebp+tls.hWnd]
542
	call	[ReleaseDC]
543
	pop     edi
544
	ret
545
 
546
i40_delay:
547
	imul	ebx, ebx, 10
548
	push	ebx
549
	call	[Sleep]
550
	ret
551
 
552
ramdisk2win32:
553
	push	edi
554
	add	ebx, [base]
555
	mov	esi, ramdisk_path
556
	push	esi
557
	call	[lstrlenA]
558
	xchg	eax, ecx
559
	rep	movsb
560
	push	edi
561
	push	edi
562
	mov	ecx, 8
563
@@:
564
	mov	al, [ebx]
565
	inc	ebx
566
	cmp	al, '.'
567
	jz	@f
568
	stosb
569
	loop	@b
570
@@:
571
	dec	edi
572
	cmp	byte [edi], ' '
573
	jz	@b
574
	inc	edi
575
	mov	al, '.'
576
	stosb
577
	cmp	[ebx], al
578
	jnz	@f
579
	inc	ebx
580
@@:
581
	mov	ecx, 3
582
@@:
583
	mov	al, [ebx]
584
	inc	ebx
585
	stosb
586
	loop	@b
587
@@:
588
	dec	edi
589
	cmp	byte [edi], ' '
590
	jz	@b
591
	inc	edi
592
	xor	eax, eax
593
	stosb
594
	call	[OemToCharA]
595
	xor	eax, eax
596
	pop	edi
597
	ret
598
 
599
i40_read_floppy_file:
600
	sub	esp, 512
601
	mov	edi, esp
602
	push	esi
603
	call	ramdisk2win32
604
	pop	ebx
605
	push	eax
606
	push	eax
607
	push	3
608
	push	eax
609
	push	1
610
	push	80000000h
611
	push	edi
612
	call	[CreateFileA]
613
	add	esp, 512
614
	inc	eax
615
	jz	.err_ret
616
	dec	eax
617
	xchg	eax, esi
618
	push	0
619
	push	esi
620
	call	[GetFileSize]
621
	xchg	eax, edi
622
	push	eax
623
	mov	ecx, esp
624
	push	0
625
	push	ecx
626
	push	edi
627
	add	ebx, [base]
628
	push	ebx
629
	push	esi
630
	call	[ReadFile]
631
	pop	eax
632
	push	esi
633
	call	[CloseHandle]
634
	mov	[esp+20h], edi
635
	ret
636
.err_ret:
637
	or	dword [esp+20h], -1
638
	ret
639
 
640
pad_bmp:
641
	pushad
642
	movzx	eax, cx
643
	shr	ecx, 10h
644
	lea	ecx, [ecx+ecx*2]
645
	add	ecx, 3
646
	and	ecx, not 3
647
	mul	ecx
648
	push	eax
649
	call	malloc
650
	mov	[esp+1Ch], eax
651
	popad
652
	push	eax
653
	mov	edi, eax
654
	push	ecx
655
	mov	esi, ebx
656
.extloop:
657
	push	ecx
658
	shr	ecx, 10h
659
	lea	ecx, [ecx+ecx*2]
660
	mov     eax, ecx
661
	shr     ecx, 2
662
	rep	movsd
663
	mov     ecx, eax
664
	and     ecx, 3
665
	rep     movsb
666
	mov	al, 0
667
@@:	test	edi, 3
668
	jz	@f
669
	stosb
670
	jmp	@b
671
@@:	pop	ecx
672
	dec	cx
673
	jnz	.extloop
674
	pop	ecx
675
	pop	edi
676
	jmp	pad_cont
677
 
678
i40_putimage:
679
	add	ebx, [base]
680
; Windows requires that all scanlines are DWORD-padded
681
	mov	edi, ebx
682
	test	ecx, 30000h
683
	jnz	pad_bmp
684
pad_cont:
685
	xor	esi, esi
686
; BITMAPINFO
687
	push	esi	; biClrImportant
688
	push	esi	; biClrUsed
689
	push	esi	; biYPelsPerMeter
690
	push	esi	; biXPelsPerMeter
691
	push	esi	; biSizeImage
692
	push	esi	; biCompression
693
	push	180001h	; biPlanes, biBitCount
694
	movzx	eax, cx
695
	neg	eax
696
	push	eax	; biHeight
697
	neg	eax
698
	shr	ecx, 10h
699
	push	ecx	; biWidth
700
	push	40	; biSize
701
	push	ebx
702
	lea	ebx, [esp+4]
703
; SetDIBitsToDevice
704
	push	esi	; fuColorUse = DIB_RGB_COLORS
705
	push	ebx	; lpbmi
706
	push	edi	; lpvBits
707
	push	eax	; cScanLines
708
	dec	eax
709
	push	eax	; uStartScan
710
	push	eax	; YSrc
711
	inc	eax
712
	push	esi	; XSrc
713
	push	eax	; dwHeight
714
	push	ecx	; dwWidth
715
	movzx	ecx, dx
716
	add     ecx, [ebp+tls.client_top]
717
	push	ecx	; YDest
718
	shr	edx, 10h
719
	add     edx, [ebp+tls.client_left]
720
	push	edx	; XDest
721
	push	[ebp+tls.hWnd]
722
	call	[GetDC]
723
	xchg	eax, ebx
724
	push	ebx	; hdc
725
	call	[SetDIBitsToDevice]
726
	xchg	eax, ebx
727
	pop	ebx
728
	add	esp, 40
729
	push	eax
730
	push	[ebp+tls.hWnd]
731
	call	[ReleaseDC]
732
	cmp	edi, ebx
733
	jz	@f
734
	push	edi
735
	call	free
736
@@:
737
	ret
738
 
739
draw_button:
740
	push	ebx
741
	push	ecx
742
	push	ebp
743
	mov	ebp, esp
744
; word [ebp+4]=y_size, word [ebp+6]=y_start, word [ebp+8]=x_size, word [ebp+10]=x_start
745
; button body
746
	push	esi
747
	cmp	[buttontype], 0
748
	jz	.flatbtn
749
	or	esi, 80000000h
750
	push	esi
751
	mov	edx, 2
752
.l2:
753
	cmp	byte [esp+edx], 0xEB
754
	jbe	@f
755
	mov	byte [esp+edx], 0xEB
756
@@:	add	byte [esp+edx], 0x14
757
	dec	edx
758
	jns	.l2
759
	pop	esi
760
	mov	eax, 010101h
761
	cmp	cx, 20
762
	ja	@f
763
	mov	eax, 020202h
764
@@:
765
	sub	esi, eax
766
.flatbtn:
767
	push	eax
768
	push	esi
769
	movzx	eax, word [ebp+6]
770
	add	ax, cx
771
	push	eax
772
	movzx	eax, word [ebp+10]
773
	add	ax, bx
774
	push	eax
775
	shr	ecx, 16
776
	push	ecx
777
	shr	ebx, 16
778
	push	ebx
779
	call	rectangle_gradient
780
; button frames
781
	pop	eax
782
	push	eax
783
	push	eax
784
	xor	ecx, ecx
785
.l1:
786
	cmp	byte [esp+ecx], 0xDF
787
	jbe	@f
788
	mov	byte [esp+ecx], 0xDF
789
@@:
790
	inc	ecx
791
	cmp	ecx, 3
792
	jb	.l1
793
	pop	eax
794
	add	eax, 202020h
795
	call	create_select_pen
796
	push	eax
797
	push	0
798
	movzx	eax, word [ebp+6]
799
	add	ax, [ebp+4]
800
	push	eax
801
	push	ebx
802
	push	edi
803
	call	[MoveToEx]
804
	movzx	eax, word [ebp+6]
805
	push	eax
806
	push	ebx
807
	push	edi
808
	call	[LineTo]
809
	movzx	eax, word [ebp+6]
810
	push	eax
811
	movzx	eax, word [ebp+8]
812
	add	ax, bx
813
	push	eax
814
	push	edi
815
	call	[LineTo]
816
	call	select_delete
817
	cmp	byte [ebp-4], 20h
818
	jae	@f
819
	mov	byte [ebp-4], 20h
820
@@:
821
	cmp	byte [ebp-3], 20h
822
	jae	@f
823
	mov	byte [ebp-3], 20h
824
@@:
825
	cmp	byte [ebp-2], 20h
826
	jae	@f
827
	mov	byte [ebp-2], 20h
828
@@:
829
	mov	eax, [ebp-4]
830
	sub	eax, 202020h
831
	call	create_select_pen
832
	push	eax
833
	movzx	eax, word [ebp+4]
834
	add	ax, [ebp+6]
835
	push	eax
836
	movzx	eax, word [ebp+8]
837
	add	ax, bx
838
	push	eax
839
	push	edi
840
	call	[LineTo]
841
	movzx	eax, word [ebp+4]
842
	add	ax, [ebp+6]
843
	push	eax
844
	push	ebx
845
	push	edi
846
	call	[LineTo]
847
	call	select_delete
848
	pop	eax
849
	pop	ebp
850
	pop	ecx
851
	pop	ebx
852
	ret
853
 
854
add_button:
855
	push	esi
856
	lea	esi, [ebp+tls.buttons]
857
@@:
858
	mov	eax, [esi]
859
	test	eax, eax
860
	jz	.end
861
	xchg	esi, eax
862
	jmp	@b
863
.end:
864
	push	ecx
865
	push	edx
866
	push	button_desc.size
867
	call	malloc
868
	mov	[esi], eax
869
	mov	[eax+button_desc.next], 0
870
	pop	[eax+button_desc.id]
871
	mov	dword [eax+button_desc.xsize], ebx
872
	pop	dword [eax+button_desc.ysize]
873
	pop	[eax+button_desc.color]
874
	ret
875
 
876
i40_define_button:
877
	test	edx, 0x80000000
878
	jnz	.delete
879
	rol     ebx, 16
880
	add     bx, word [ebp+tls.client_left]
881
	rol     ebx, 16
882
	rol     ecx, 16
883
	add     cx, word [ebp+tls.client_top]
884
	rol     ecx, 16
885
	test	edx, 0x40000000
886
	jnz	.nodraw
887
	push	ecx
888
	push	edx
889
	push	[ebp+tls.hWnd]
890
	call	[GetDC]
891
	xchg	eax, edi
892
	pop	edx
893
	pop	ecx
894
	pushad
895
	call	draw_button
896
	push	edi
897
	push	[ebp+tls.hWnd]
898
	call	[ReleaseDC]
899
	popad
900
.nodraw:
901
	call	add_button
902
.ret:
903
	ret
904
.delete:
905
	and	edx, not 0x80000000
906
	lea	esi, [ebp+tls.buttons]
907
@@:
908
	mov	eax, [esi]
909
	test	eax, eax
910
	jz	@f
911
; The kernel checks only low word of button ID!
912
	cmp	word [eax+button_desc.id], dx
913
	jz	.found
914
	xchg	eax, esi
915
	jmp	@b
916
@@:
917
	ret
918
.found:
919
; if active button is deleting, there is no more active button
920
	cmp	eax, [ebp+tls.active_button]
921
	jnz	@f
922
	and	[ebp+tls.active_button], 0
923
@@:
924
	push	[eax+button_desc.next]
925
	push	eax
926
	call	free
927
	pop	[esi+button_desc.next]
928
	ret
929
 
930
invalid_slot_msg db 'Emulated program has requested information on non-existent slot'
931
        db      ' and will be terminated',0
932
invalid_slot:
933
	call	release_shared
934
	push	0
935
	push	0
936
	push	invalid_slot_msg
937
	push	0
938
	call	[MessageBoxA]
939
	jmp	i40_terminate
940
 
941
get_os_process_info:
942
	pushad
943
	mov	ebx, 5
944
	call	i40_sys_service
945
	popad
946
	stosd		; .cpu_usage
947
	xor	eax, eax
948
	inc	eax
949
	stosw		; .window_stack_position
950
	stosw		; .window_stack_value
951
	dec	eax
952
	stosw		; .not_used1
953
	mov	eax, 'OS/I'
954
	stosd
955
	mov	eax, 'DLE '
956
	stosd
957
	mov	eax, '   '
958
	stosd
959
	xor	eax, eax
960
	stosd		; .memory_start
961
	mov	eax, 0x01000000-1
962
	stosd		; .used_memory
963
	xor	eax, eax
964
	inc	eax
965
	stosd		; .PID
966
	dec	eax
967
	stosd
968
	stosd
969
	stosd
970
	stosd
971
	stosw		; .slot_state
972
	scasw
973
	stosd
974
	stosd
975
	stosd
976
	stosd
977
	stosb
978
	jmp	got_process_info
979
 
980
i40_get_process_info:
981
	cmp	ecx, -1
982
	jnz	@f
983
	mov	ecx, [ebp+tls.cur_slot]
984
	inc	ecx
985
@@:
986
	add	ebx, [base]
987
	mov	edx, [shared_data]
988
;	cmp	ecx, [edx+shared_data_struc.alloc_threads]	; too many programs will fail
989
	cmp	ecx, 256
990
	ja	invalid_slot
991
	dec	ecx
992
	call	acquire_shared
993
	mov	eax, ecx
994
	call	get_slot_ptr
995
	mov	esi, edi
996
	mov	edi, ebx
997
	jecxz	get_os_process_info
998
	xor	eax, eax
999
	stosd		; .cpu_usage
1000
	mov	eax, [edx+shared_data_struc.alloc_threads]
1001
	stosw		; .window_stack_position
1002
	stosw		; .window_stack_value
1003
	xor	eax, eax
1004
	stosw		; .not_used1
1005
	push	esi
1006
	add	esi, 28
1007
	movsd
1008
	movsd
1009
	movsd
1010
	pop	esi
1011
	stosd		; .memory_start
1012
	mov	eax, [esi+24]
1013
	stosd		; .used_memory
1014
	mov	eax, [esi]
1015
	stosd		; .PID
1016
	push    ecx
1017
	xor	eax, eax
1018
	push	eax
1019
	push	eax
1020
	push	eax
1021
	push	eax
1022
	push	esp
1023
	push	dword [esi+20]
1024
	call	[GetWindowRect]
1025
	pop	eax
1026
	stosd
1027
	pop	eax
1028
	stosd
1029
	pop	eax
1030
	sub	eax, [edi-8]
1031
	sub	eax, 1
1032
	adc	eax, 0
1033
	stosd
1034
	pop	eax
1035
	sub	eax, [edi-8]
1036
	sub	eax, 1
1037
	adc	eax, 0
1038
	stosd
1039
	pop     ecx
1040
	and	word [edi], 0	; .slot_state
1041
	cmp	dword [esi], 0
1042
	jnz	@f
1043
	mov	byte [edi], 9
1044
@@:
1045
        scasd
1046
; client area coordinates
1047
        push    esi
1048
; for my window, return true coordinates from tls
1049
        cmp     ecx, [ebp+tls.cur_slot]
1050
        jnz     .notmy
1051
        lea     esi, [ebp+tls.client_left]
1052
        movsd
1053
        movsd
1054
        lodsd
1055
        dec     eax
1056
        stosd
1057
        lodsd
1058
        dec     eax
1059
        stosd
1060
        jmp     @f
1061
.notmy:
1062
; for other windows, return copy of window coordinates
1063
        add     esi, 0x22
1064
        movsd
1065
        movsd
1066
        movsd
1067
        movsd
1068
@@:
1069
        pop     esi
1070
; window state
1071
        sub     esp, 40
1072
        push    44
1073
        push    esp
1074
        push    dword [esi+20]
1075
        call    [GetWindowPlacement]
1076
        test    eax, eax
1077
        jnz     @f
1078
        add     esp, 44
1079
        jmp     .normal
1080
@@:
1081
        mov     eax, [esp+8]    ; showCmd
1082
        add     esp, 44
1083
        cmp     eax, 3
1084
        jz      .maximized
1085
        cmp     eax, 2
1086
        jz      .minimized
1087
        test    eax, eax
1088
        jz      .minimized
1089
        push    dword [esi+20]
1090
        call    [IsWindowVisible]
1091
        test    eax, eax
1092
        jz      .minimized
1093
.normal:
1094
        xor     eax, eax
1095
        jmp     @f
1096
.minimized:
1097
        mov     al, 2
1098
        jmp     @f
1099
.maximized:
1100
        mov     al, 1
1101
@@:
1102
        stosb
1103
got_process_info:
1104
	mov	eax, [shared_data]
1105
	mov	eax, [eax+shared_data_struc.alloc_threads]
1106
	mov	dword [esp+20h], eax	; number of processes
1107
	call	release_shared
1108
	ret
1109
 
1110
test_button_mouse:
1111
	cmp	al, 86h
1112
	jnz	@f
1113
	mov	al, 6
1114
	test	[ebp+tls.message_mask], 4
1115
	jz	@f
1116
	mov	[ebp+tls.translated_msg_code], al	; mouse
1117
	mov	al, 3	; button
1118
@@:	ret
1119
 
1120
event_test_redraw:
1121
; if function 0 has not been called, then redraw message is present
1122
;        cmp     [ebp+tls.showwnd], 0
1123
;        jnz     @f
1124
	cmp	[ebp+tls.curdraw], 0
1125
	jz	@f
1126
        test    [ebp+tls.message_mask], 1
1127
        jz      @f
1128
        pop     eax
1129
        mov     dword [esp+20h], 1
1130
@@:
1131
        ret
1132
 
1133
i40_wait_event:
1134
        call    event_test_redraw
1135
	sub	esp, 20h
1136
	xor	eax, eax
1137
	xchg	al, [ebp+tls.translated_msg_code]
1138
	test	eax, eax
1139
	jnz	@f
1140
	mov	al, 2
1141
	test	byte [ebp+tls.message_mask], al
1142
	jz	.nokey
1143
	cmp	[ebp+tls.keybuflen], ah
1144
	jnz	@f
1145
.nokey:
1146
	inc	eax
1147
	test	[ebp+tls.message_mask], 4
1148
	jz	.nobut
1149
	cmp	[ebp+tls.butbuflen], ah
1150
	jnz	@f
1151
.nobut:
1152
	mov	ebx, esp
1153
	push	0
1154
	push	0
1155
	push	0
1156
	push	ebx
1157
	call	[GetMessageA]
1158
	test	eax, eax
1159
	jz	i40_terminate
1160
	push	ebx
1161
	call	[TranslateMessage]
1162
	push	ebx
1163
	call	[DispatchMessageA]
1164
	add	esp, 20h
1165
	jmp	i40_wait_event
1166
@@:
1167
	add	esp, 20h
1168
	cmp	al, 6
1169
	jnz	@f
1170
	test	[ebp+tls.message_mask], 20h
1171
	jz	i40_wait_event
1172
@@:
1173
	call	test_button_mouse
1174
	mov	[esp+20h], eax
1175
	ret
1176
 
1177
i40_check_event:
1178
        call    event_test_redraw
1179
	sub	esp, 20h
1180
	xor	eax, eax
1181
	xchg	al, [ebp+tls.translated_msg_code]
1182
	or	eax, eax
1183
	jnz	.event
1184
	mov	al, 2
1185
	test	byte [ebp+tls.message_mask], al
1186
	jz	.nokey
1187
	cmp	[ebp+tls.keybuflen], ah
1188
	jnz	.event
1189
.nokey:
1190
	inc	eax
1191
	test	[ebp+tls.message_mask], 4
1192
	jz	.nobut
1193
	cmp	[ebp+tls.butbuflen], ah
1194
	jnz	.event
1195
.nobut:
1196
@@:
1197
	mov	ebx, esp
1198
	push	1
1199
	push	0
1200
	push	0
1201
	push	0
1202
	push	ebx
1203
	call	[PeekMessageA]
1204
	test	eax, eax
1205
	jz	.noevent
1206
	cmp	dword [ebx+4], 0x12	; WM_QUIT
1207
	jz	i40_terminate
1208
	push	ebx
1209
	call	[TranslateMessage]
1210
	push	ebx
1211
	call	[DispatchMessageA]
1212
	xor	eax, eax
1213
	cmp	[ebp+tls.curdraw], al
1214
	jnz	.redraw
1215
	xchg	al, [ebp+tls.translated_msg_code]
1216
	or	eax, eax
1217
	jz	@b
1218
.event:
1219
	add	esp, 20h
1220
	cmp	al, 6
1221
	jnz	@f
1222
	test	[ebp+tls.message_mask], 20h
1223
	jz	i40_check_event
1224
@@:
1225
	call	test_button_mouse
1226
	mov	[esp+20h], eax
1227
	ret
1228
.redraw:
1229
	inc	eax
1230
	add	esp, 20h
1231
	test	[ebp+tls.message_mask], eax
1232
	jz	i40_check_event
1233
	mov	[esp+20h], eax
1234
	ret
1235
.noevent:
1236
	add	esp, 20h
1237
	and	dword [esp+20h], 0
1238
	ret
1239
 
1240
i40_redraw_status:
1241
	dec	ebx
1242
	jz	.fn1
1243
	dec	ebx
1244
	jnz	not_supported_i40_fn
1245
	ret
1246
.fn1:
1247
; delete all defined buttons
1248
	xor	ebx, ebx
1249
	mov	[ebp+tls.active_button], ebx	; no more active buttons
1250
	xchg	ebx, [ebp+tls.buttons]
1251
@@:
1252
	test	ebx, ebx
1253
	jz	.done
1254
	push	ebx
1255
	mov	ebx, [ebx]
1256
	call	free
1257
	jmp	@b
1258
.done:
1259
	ret
1260
 
1261
i40_drawrect:
1262
	push	ecx
1263
	push	edx
1264
	push	[ebp+tls.hWnd]
1265
	call	[GetDC]
1266
	pop	edx
1267
	pop	ecx
1268
	xchg	eax, edi
1269
	push	1
1270
	push	edx
1271
	movzx	eax, cx
1272
	shr	ecx, 16
1273
	add     ecx, [ebp+tls.client_top]
1274
	add	eax, ecx
1275
	push	eax
1276
	movzx	eax, bx
1277
	shr	ebx, 16
1278
	add     ebx, [ebp+tls.client_left]
1279
	add	eax, ebx
1280
	push	eax
1281
	push	ecx
1282
	push	ebx
1283
	call	rectangle_gradient
1284
	push	edi
1285
	push	[ebp+tls.hWnd]
1286
	call	[ReleaseDC]
1287
	ret
1288
 
1289
get_screen_size:
1290
	call	[GetDesktopWindow]
1291
	push	eax
1292
	push	eax
1293
	call	[GetDC]
1294
	xchg	eax, esi
1295
	push	8	; HORZRES
1296
	push	esi
1297
	call	[GetDeviceCaps]
1298
	dec	eax
1299
	xchg	ebx, eax
1300
	shl	ebx, 16
1301
	push	10	; VERTRES
1302
	push	esi
1303
	call	[GetDeviceCaps]
1304
	dec	eax
1305
	or	ebx, eax
1306
	pop	eax
1307
	push	esi
1308
	push	eax
1309
	call	[ReleaseDC]
1310
	ret
1311
 
1312
i40_get_screen_size:
1313
	call	get_screen_size
1314
	mov	[esp+20h], ebx
1315
	ret
1316
 
1317
i40_set_background:
1318
	pushad
1319
	push	1
1320
	call	init_background
1321
	popad
1322
	mov	eax, [bgr_section]
1323
	test	eax, eax
1324
	jnz	@f
1325
	ret
1326
@@:
1327
	dec	ebx
1328
	jz	.setsize
1329
	dec	ebx
1330
	jz	.setpixel
1331
	dec	ebx
1332
	jz	.redraw
1333
	dec	ebx
1334
	jz	.method
1335
	dec	ebx
1336
	jz	.setblock
1337
	dec	ebx
1338
	jz	.map
1339
	dec	ebx
1340
	jnz	not_supported_i40_fn
1341
.unmap:
1342
	push	ecx
1343
	mov	esi, ecx
1344
	add	esi, [base]
1345
	lea	edi, [eax+10h]
1346
	mov	ecx, [eax]
1347
	imul	ecx, [eax+4]
1348
	lea	ecx, [ecx*3]
1349
	mov	edx, ecx
1350
	shr	ecx, 2
1351
	rep	movsd
1352
	mov	ecx, edx
1353
	and	ecx, 3
1354
	rep	movsb
1355
	mov	byte [eax+12], 1
1356
	mov	byte [eax+13], 0
1357
	pop	ecx
1358
	jmp	i40_sys_services.free_heap
1359
.map:
1360
	mov	cl, 1
1361
	xchg	cl, [eax+13]
1362
	test	cl, cl
1363
	jz	@f
1364
	push	eax ecx edx
1365
	push	100
1366
	call	[Sleep]
1367
	pop	edx ecx eax
1368
	jmp	.map
1369
@@:
1370
	lea	esi, [eax+10h]
1371
	mov	ecx, [eax]
1372
	imul	ecx, [eax+4]
1373
	lea	ecx, [ecx*3]
1374
	pushad
1375
	call	i40_sys_services.allocate_heap
1376
	popad
1377
	mov	[esp+20h], eax
1378
	test	eax, eax
1379
	jnz	@f
1380
	mov	byte [esi-10h+13], 0
1381
	ret
1382
@@:
1383
	mov	edi, eax
1384
	add	edi, [base]
1385
	mov	edx, ecx
1386
	shr	ecx, 2
1387
	rep	movsd
1388
	mov	ecx, edx
1389
	and	ecx, 3
1390
	rep	movsb
1391
	ret
1392
.setblock:
1393
	xchg	esi, ecx
1394
	add	esi, [base]
1395
	lea	edi, [eax+edx+10h]
1396
	rep	movsb
1397
	mov	byte [eax+12], 1
1398
	ret
1399
.setsize:
1400
	push	ecx
1401
@@:
1402
	mov	cl, 1
1403
	xchg	cl, [eax+13]
1404
	test	cl, cl
1405
	jz	@f
1406
	push	eax ecx edx
1407
	push	100
1408
	call	[Sleep]
1409
	pop	edx ecx eax
1410
	jmp	@b
1411
@@:
1412
	pop	ecx
1413
	mov	[eax], ecx
1414
	mov	[eax+4], edx
1415
	mov	byte [eax+12], 1
1416
	mov	byte [eax+13], 0
1417
	ret
1418
.method:
1419
	mov	[eax+8], ecx
1420
	mov	byte [eax+12], 1
1421
	ret
1422
.setpixel:
1423
	and	edx, 0x00FFFFFF
1424
	and	dword [eax+ecx+10h], 0xFF000000
1425
	or	[eax+ecx+10h], edx
1426
	mov	byte [eax+12], 1
1427
@@:	ret
1428
.redraw:
1429
	cmp	byte [eax+12], 0
1430
	jz	@b
1431
.redraw_force:
1432
	mov	byte [eax+12], 0
1433
	mov	ebx, 2
1434
	mov	eax, [shared_data]
1435
	cmp	[eax+shared_data_struc.vk], 0
1436
	jnz	.settmp
1437
	mov	eax, [SetBgrQuestion]
1438
	dec	eax
1439
	js	.ask
1440
	jz	.permanent
1441
	dec	eax
1442
	jz	.settmp
1443
; don't set
1444
	ret
1445
.ask:
1446
	push	123h
1447
	push	aConfirm
1448
	push	BgrQuestionText
1449
	push	0
1450
	call	[MessageBoxA]
1451
	cmp	al, 6
1452
	jz	.permanent
1453
	cmp	al, 7
1454
	jz	.settmp
1455
	ret
1456
.permanent:
1457
	inc	ebx
1458
.settmp:
1459
	push	eax
1460
	push	esp
1461
	push	3	; KEY_QUERY_VALUE | KEY_SET_VALUE
1462
	push	0
1463
	push	bgrkeyname
1464
	push	80000001h
1465
	call	[RegOpenKeyExA]
1466
	test	eax, eax
1467
	pop	esi
1468
	jnz	.nopos
1469
; save old reg values
1470
	push	'0'
1471
	push	'0'
1472
	push	2
1473
	mov	eax, esp
1474
	push	eax	; lpcbData
1475
	add	eax, 4
1476
	push	eax	; lpData
1477
	push	0	; lpType
1478
	push	0	; lpReserved
1479
	push	bgrstylevalue	; lpValueName
1480
	push	esi	; hKey
1481
	call	[RegQueryValueExA]
1482
	mov	eax, esp
1483
	mov	dword [eax], 2
1484
	push	eax	; lpcbData
1485
	add	eax, 8
1486
	push	eax	; lpData
1487
	push	0	; lpType
1488
	push	0	; lpReserved
1489
	push	bgrtilevalue	; lpValueName
1490
	push	esi	; hKey
1491
	call	[RegQueryValueExA]
1492
	pop	eax
1493
	mov	ecx, '0'
1494
	mov	eax, [bgr_section]
1495
	cmp	byte [eax+8], 1
1496
	jz	@f
1497
	mov	cl, '2'
1498
@@:
1499
	push	ecx
1500
	mov	eax, esp
1501
	push	2
1502
	push	eax
1503
	push	1
1504
	push	0
1505
	push	bgrstylevalue
1506
	push	esi
1507
	call	[RegSetValueExA]
1508
	pop	ecx
1509
	cmp	cl, '0'
1510
	jnz	.stretch
1511
	push	'1'	; tile
1512
	jmp	@f
1513
.stretch:
1514
	push	'0'
1515
@@:
1516
	mov	eax, esp
1517
	push	2
1518
	push	eax
1519
	push	1
1520
	push	0
1521
	push	bgrtilevalue
1522
	push	esi
1523
	call	[RegSetValueExA]
1524
	pop	ecx
1525
	push	esi
1526
	call	[RegCloseKey]
1527
.nopos:
1528
	mov	edi, win32_path
1529
	push	startcurdir
1530
	push	edi
1531
	call	[lstrcpyA]
1532
	push	bgrfilename
1533
	test	bl, 1
1534
	jnz	@f
1535
	mov	dword [esp], bgrtempfilename
1536
@@:
1537
	push	edi
1538
	call	[lstrcatA]
1539
	push	0
1540
	push	80h
1541
	push	2
1542
	push	0
1543
	push	0
1544
	push	40000000h
1545
	push	edi
1546
	call	[CreateFileA]
1547
	inc	eax
1548
	jnz	@f
1549
	push	10h
1550
	push	0
1551
	push	BgrFileErrorMsg
1552
	push	0
1553
	call	[MessageBoxA]
1554
	pop	ecx
1555
	pop	ecx
1556
	ret
1557
@@:
1558
	dec	eax
1559
	xchg	eax, esi
1560
; bmp header
1561
	mov	ecx, [bgr_section]
1562
	mov	eax, [ecx+4]
1563
	mov	[bgr_bmp_header+16h], eax
1564
	mov	eax, [ecx]
1565
	mov	[bgr_bmp_header+12h], eax
1566
	add	eax, eax
1567
	add	eax, [ecx]
1568
	add	eax, 3
1569
	and	al, not 3
1570
	mul	dword [ecx+4]
1571
; eax=size of image
1572
	mov	[bgr_bmp_header+22h], eax
1573
	add	eax, 36h
1574
	mov	[bgr_bmp_header+2], eax
1575
	push	eax
1576
	mov	eax, esp
1577
	push	0
1578
	push	eax
1579
	push	36h
1580
	push	bgr_bmp_header
1581
	push	esi
1582
	call	[WriteFile]
1583
	pop	eax
1584
; bmp data
1585
	mov	eax, [bgr_section]
1586
	mov	ecx, [eax+4]
1587
	lea	edi, [eax+10h]
1588
	mov	eax, [eax]
1589
	mul	ecx
1590
	imul	eax, 3
1591
	add	edi, eax
1592
.putline:
1593
	push	ecx
1594
	mov	ecx, [bgr_section]
1595
	mov	eax, [ecx]
1596
	add	eax, eax
1597
	add	eax, [ecx]
1598
	sub	edi, eax
1599
	push	eax
1600
	push	eax
1601
	mov	ecx, esp
1602
	push	0
1603
	push	ecx
1604
	push	eax
1605
	push	edi
1606
	push	esi
1607
	call	[WriteFile]
1608
	pop	eax
1609
	pop	ecx
1610
	and	ecx, 3
1611
	jz	.nopad
1612
.padloop:
1613
	push	ecx
1614
	push	0
1615
	push	eax
1616
	mov	eax, esp
1617
	push	0
1618
	push	eax
1619
	add	eax, 4
1620
	push	1
1621
	push	eax
1622
	push	esi
1623
	call	[WriteFile]
1624
	pop	eax
1625
	pop	eax
1626
	pop	ecx
1627
	loop	.padloop
1628
.nopad:
1629
	pop	ecx
1630
	loop	.putline
1631
	push	esi
1632
	call	[CloseHandle]
1633
	mov	eax, [shared_data]
1634
	mov	[eax+shared_data_struc.dwNewBgrTime], -1
1635
	;or	[dwNewBgrTime], -1
1636
	push	ebx
1637
	push	win32_path
1638
	push	0
1639
	push	14h
1640
	call	[SystemParametersInfoA]
1641
	cmp	bl, 2
1642
	jnz	@f
1643
	push	eax
1644
	push	esp
1645
	push	500
1646
	push	0
1647
	push	0
1648
	push	0
1649
	push	0x1A
1650
	push	0xFFFF
1651
	call	[SendMessageTimeoutA]
1652
	pop	eax
1653
; restore key values
1654
	push	eax
1655
	push	esp
1656
	push	2	; KEY_SET_VALUE
1657
	push	0
1658
	push	bgrkeyname
1659
	push	80000001h
1660
	call	[RegOpenKeyExA]
1661
	test	eax, eax
1662
	pop	esi
1663
	jnz	@f
1664
	mov	eax, esp
1665
	push	2
1666
	push	eax
1667
	push	1
1668
	push	0
1669
	push	bgrstylevalue
1670
	push	esi
1671
	call	[RegSetValueExA]
1672
	lea	eax, [esp+4]
1673
	push	2
1674
	push	eax
1675
	push	1
1676
	push	0
1677
	push	bgrtilevalue
1678
	push	esi
1679
	call	[RegSetValueExA]
1680
	push	esi
1681
	call	[RegCloseKey]
1682
@@:
1683
	mov	esi, [shared_data]
1684
	call	[GetTickCount]
1685
	add	eax, 3000
1686
	;mov	[dwNewBgrTime], eax
1687
	mov	[esi+shared_data_struc.dwNewBgrTime], eax
1688
	pop	ecx
1689
	pop	ecx
1690
	ret
1691
 
1692
i40_getbutton:
1693
	movzx	ecx, [ebp+tls.butbuflen]
1694
	jecxz	.empty
1695
	lea	edi, [ebp+tls.butbuffer]
1696
	mov	eax, [edi]
1697
	and	al, not 1
1698
	mov	[esp+20h], eax
1699
	lea	esi, [edi+4]
1700
	dec	ecx
1701
	mov	[ebp+tls.butbuflen], cl
1702
	rep	movsd
1703
	ret
1704
.empty:
1705
	mov	byte [esp+20h], 1
1706
	ret
1707
 
1708
i40_sys_service:
1709
	cmp	ebx, 1
1710
	jz	.19
1711
	cmp	ebx, 2
1712
	jz	.kill
1713
	cmp	ebx, 18
1714
	jnz	.not2
1715
.kill:
1716
	call	acquire_shared
1717
	xchg	eax, ecx
1718
	cmp	eax, 1
1719
	jbe	release_shared		; invalid PID/slot - ignore
1720
	mov	esi, [shared_data]
1721
	mov	edi, esi
1722
	mov	ecx, [esi]
1723
	add	esi, shared_data_struc.threads
1724
	cmp	ebx, 2
1725
	jz	.slot
1726
@@:
1727
	cmp	[esi], eax
1728
	jz	.found
1729
	add	esi, 64
1730
	loop	@b
1731
	jmp	release_shared		; no such PID - ignore
1732
.slot:
1733
	dec	eax
1734
	cmp	eax, ecx
1735
	jae	release_shared
1736
	shl	eax, 6
1737
	add	esi, eax
1738
	cmp	dword [esi], 0
1739
	jz	release_shared
1740
.found:
1741
; terminate self?
1742
	call	get_cur_slot_ptr
1743
	cmp	esi, edi
1744
	jnz	@f
1745
	call	release_shared
1746
	jmp	i40_terminate
1747
@@:
1748
; get thread and process handles
1749
	mov	eax, [esi+shared_data_struc.win32_hThread-shared_data_struc.threads]
1750
	call	server_convert
1751
	mov	edi, eax
1752
	call	release_shared
1753
; target thread is suspended? if so, do not wait
1754
	push	edi
1755
	call	[SuspendThread]
1756
	test	eax, eax
1757
	jnz	.suspended
1758
	push	edi
1759
	call	[ResumeThread]
1760
; send WM_CLOSE to thread window
1761
	push	0
1762
	push	0
1763
	push	0x10		; WM_CLOSE
1764
	push	[esi+shared_data_struc.hWnd-shared_data_struc.threads]
1765
	call	[PostMessageA]
1766
; wait no more than 1 second
1767
	push	1000
1768
	push	edi
1769
	call	[WaitForSingleObject]
1770
	cmp	eax, 258	; WAIT_TIMEOUT
1771
	jnz	.ret_close
1772
; let target thread to terminate itself
1773
	push	edi
1774
	call	[SuspendThread]
1775
.suspended:
1776
	mov	ebx, [esi+shared_data_struc.win32_stack-shared_data_struc.threads]
1777
	sub	esp, 0xB2*4
1778
	push	1000Fh
1779
	mov	esi, esp
1780
	push	esp
1781
	push	edi
1782
	call	[GetThreadContext]
1783
	mov	ax, ss
1784
	cmp	[esi+0xC8], ax
1785
	jz	@f
1786
	mov	[esi+0xC8], ss
1787
	mov	[esi+0xC4], ebx
1788
@@:
1789
	mov	[esi+0xBC], cs
1790
	mov	[esi+0x98], ds
1791
	mov	[esi+0x94], es
1792
	mov	[esi+0xB8], dword i40_terminate
1793
	push	esi
1794
	push	edi
1795
	call	[SetThreadContext]
1796
	add	esp, 0xB3*4
1797
@@:
1798
	push	edi
1799
	call	[ResumeThread]
1800
	cmp	eax, 1
1801
	ja	@b
1802
.ret_close:
1803
	push	edi
1804
	call	[CloseHandle]
1805
	ret
1806
.not2:
1807
	cmp	ebx, 3
1808
	jnz	.not3
1809
	cmp	ecx, 2
1810
	jb	.noactivate_ret
1811
	call	acquire_shared
1812
	mov	eax, [shared_data]
1813
	cmp	ecx, [eax+shared_data_struc.alloc_threads]
1814
	ja	.noactivate_release
1815
	lea	eax, [ecx-1]
1816
	call	get_slot_ptr
1817
	cmp	dword [edi], 0
1818
	jz	.noactivate_release
1819
	mov	esi, [edi+shared_data_struc.hWnd-shared_data_struc.threads]
1820
	call	release_shared
1821
.restore_given_window:
1822
	sub	esp, 40
1823
	push	44
1824
	push	esp
1825
	push	esi
1826
	call	[GetWindowPlacement]
1827
	mov	eax, [esp+8]
1828
	add	esp, 44
1829
	mov	ecx, 5	; SW_SHOW
1830
	cmp	al, 2	; SW_SHOWMINIMIZED
1831
	jnz	@f
1832
	mov	cl, 9	; SW_RESTORE
1833
@@:
1834
	push	ecx
1835
	push	esi
1836
	call	[ShowWindow]
1837
;	push	esi
1838
;	call	[BringWindowToTop]
1839
	push	esi
1840
	call	[SetForegroundWindow]
1841
	ret
1842
.noactivate_release:
1843
	call	release_shared
1844
.noactivate_ret:
1845
	ret
1846
.not3:
1847
	cmp	ebx, 4
1848
	jnz	.not4
1849
; get idle time - current implementation on NT simply returns cpuspeed
1850
	cmp	[bIs9x], 0
1851
	jz	.5
1852
idletime_via_ring0 = 1
1853
if ~idletime_via_ring0
1854
	mov	eax, [shared_data]
1855
	cmp	[eax+shared_data_struc.b9xPerfInited], 0
1856
	jnz	.perfinited
1857
	call	acquire_shared
1858
	cmp	[eax+shared_data_struc.b9xPerfInited], 0
1859
	jnz	@f
1860
	push	eax
1861
	push	esp	; phkResult
1862
	push	1	; samDesired = KEY_QUERY_VALUE
1863
	push	0	; ulOptions
1864
	push	perfstart	; lpSubKey
1865
	push	80000006h	; hKey = HKEY_DYN_DATA
1866
	call	[RegOpenKeyExA]
1867
	pop	esi
1868
	test	eax, eax
1869
	jnz	.perfinitfail
1870
	push	eax
1871
	mov	eax, esp
1872
	push	4
1873
	push	esp	; lpcbData
1874
	push	eax	; lpData
1875
	push	0	; lpType
1876
	push	0	; lpReserved
1877
	push	perfval	; lpValueName
1878
	push	esi	; hKey
1879
	call	[RegQueryValueExA]
1880
	pop	ecx
1881
	pop	ecx
1882
	push	eax
1883
	push	esi
1884
	call	[RegCloseKey]
1885
	pop	eax
1886
	test	eax, eax
1887
	jnz	.perfinitfail
1888
	push	200
1889
	call	[Sleep]		; give chance to collect data
1890
@@:
1891
	mov	eax, [shared_data]
1892
	mov	[eax+shared_data_struc.b9xPerfInited], 1
1893
	call	release_shared
1894
.perfinited:
1895
	push	100
1896
	pop	ebx
1897
	push	eax
1898
	push	esp	; phkResult
1899
	push	1	; samDesired = KEY_QUERY_VALUE
1900
	push	0	; ulOptions
1901
	push	perfget	; lpSubKey
1902
	push	80000006h	; hKey = HKEY_DYN_DATA
1903
	call	[RegOpenKeyExA]
1904
	pop	esi
1905
	test	eax, eax
1906
	jnz	@f
1907
	push	ebx
1908
	mov	eax, esp
1909
	push	4
1910
	push	esp	; lpcbData
1911
	push	eax	; lpData
1912
	push	0	; lpType
1913
	push	0	; lpReserved
1914
	push	perfval	; lpValueName
1915
	push	esi	; hKey
1916
	call	[RegQueryValueExA]
1917
	pop	ecx
1918
	pop	ebx
1919
	push	esi
1920
	call	[RegCloseKey]
1921
@@:
1922
	pushad
1923
	call	.5
1924
	popad
1925
	push	100
1926
	pop	ecx
1927
	sub	ebx, ecx
1928
	neg	ebx
1929
	mul	ebx
1930
	div	ecx
1931
	mov	[esp+20h], eax
1932
	ret
1933
.perfinitfail:
1934
	call	release_shared
1935
	push	40h
1936
	push	0
1937
	push	aPerfInitFailed
1938
	push	0
1939
	call	[MessageBoxA]
1940
	jmp	.5
1941
else
1942
	mov	eax, [shared_data]
1943
	cmp	[eax+shared_data_struc.b9xPerfInited], 0
1944
	jnz	@f
1945
.idlecount_init:
1946
	div	edx
1947
@@:
1948
	mov	ebx, [eax+shared_data_struc.idlecount]
1949
	pushad
1950
	call	.5
1951
	popad
1952
	mul	ebx
1953
	mov	ecx, 1000
1954
	div	ecx
1955
	mov	[esp+20h], eax
1956
	ret
1957
end if
1958
.not4:
1959
	cmp	ebx, 5
1960
	jnz	.not5
1961
.5:
1962
	mov	eax, [shared_data]
1963
	mov	ebx, [eax+shared_data_struc.cpuspeed]
1964
	test	ebx, ebx
1965
	jnz	@f
1966
; determine cpu speed
1967
; 1) check for value in registry
1968
	push	eax
1969
	push	esp
1970
	push	1	; KEY_QUERY_VALUE
1971
	push	0
1972
	push	keycpu
1973
	push	80000002h
1974
	call	[RegOpenKeyExA]
1975
	test	eax, eax
1976
	pop	eax
1977
	jnz	.nokey
1978
	xchg	eax, esi
1979
	push	eax
1980
	push	4
1981
	push	esp
1982
	lea	eax, [esp+8]
1983
	push	eax
1984
	push	0
1985
	push	0
1986
	push	keymhz
1987
	push	esi
1988
	call	[RegQueryValueExA]
1989
	push	eax
1990
	push	esi
1991
	call	[RegCloseKey]
1992
	pop	eax
1993
	test	eax, eax
1994
	pop	eax
1995
	pop	eax
1996
	jnz	.nokey
1997
	imul	eax, 1000000
1998
	jmp	.speed_found
1999
.nokey:
2000
; 2) sleep for 1/4 sec and read TSC
2001
	rdtsc
2002
	push	eax edx
2003
	push	250
2004
	call	[Sleep]
2005
	rdtsc
2006
	pop	ecx ebx
2007
	sub	eax, ebx
2008
	sbb	edx, ecx
2009
	shl	eax, 2
2010
.speed_found:
2011
	xchg	ebx, eax
2012
	mov	eax, [shared_data]
2013
	mov	[eax+shared_data_struc.cpuspeed], ebx
2014
@@:
2015
	mov	[esp+20h], ebx
2016
	ret
2017
.not5:
2018
	cmp	ebx, 7
2019
	jnz	.not7
2020
	mov	eax, [shared_data]
2021
	mov	eax, [eax+shared_data_struc.active_process]
2022
	mov	[esp+20h], eax
2023
	ret
2024
.not7:
2025
	cmp	ebx, 8
2026
	jnz	.not8
2027
	dec	ecx
2028
	jnz	@f
2029
	mov	eax, [shared_data]
2030
	movzx	eax, [eax+shared_data_struc.sound_flag]
2031
	mov	[esp+20h], eax
2032
	ret
2033
@@:
2034
	dec	ecx
2035
	jnz	not_supported_i40_fn
2036
	mov	eax, [shared_data]
2037
lock	xor	[eax+shared_data_struc.sound_flag], 1
2038
	ret
2039
.not8:
2040
	cmp	ebx, 9
2041
	jnz	.not9
2042
.19:
2043
	mov	eax, [shared_data]
2044
	cmp	[eax+shared_data_struc.vk], 0
2045
	jz	not_supported_i40_fn
2046
.server_terminate:
2047
	div	edx
2048
	ret
2049
.not9:
2050
	cmp	ebx, 10
2051
;	jnz	.not10
2052
;	call	minimize_window
2053
;	ret
2054
	jz	minimize_window
2055
.not10:
2056
	cmp	ebx, 11
2057
	jnz	.not11
2058
	dec	ecx
2059
	jnz	not_supported_i40_fn
2060
	xor	eax, eax
2061
	mov	edi, edx
2062
	add	edi, [base]
2063
; floppy is not supported yet => return "no floppy installed"
2064
	stosb
2065
; IDEx configuration
2066
; CD is not supported yet. On IDEx there may be only HD (or nothing)
2067
	xor	edx, edx
2068
	mov	esi, hd_partitions_num
2069
	push	esi
2070
.idex:
2071
	lodsd
2072
	shl     edx, 2
2073
	test	eax, eax
2074
	jz	@f
2075
	inc	edx
2076
@@:
2077
	cmp	esi, hd_partitions_num+4*4
2078
	jc	.idex
2079
	mov	[edi], dl
2080
	inc	edi
2081
; number of partitions
2082
	pop	esi
2083
	mov	cl, 4
2084
@@:
2085
	lodsd
2086
	stosb
2087
	loop	@b
2088
; reserved bytes
2089
        and     dword [edi], 0
2090
	ret
2091
.not11:
2092
	cmp	ebx, 12
2093
	jnz	.not12
2094
.return0:
2095
	and	dword [esp+20h], 0
2096
	ret
2097
.not12:
2098
	cmp	ebx, 13
2099
	jnz	.not13
2100
	mov	edi, ecx
2101
	add	edi, [base]
2102
	mov	esi, version_inf
2103
	mov	ecx, version_end - version_inf
2104
	rep	movsb
2105
	ret
2106
.not13:
2107
        cmp     ebx, 14
2108
        jz      .return0
2109
	cmp	ebx, 15
2110
	jnz	.not15
2111
	call	get_screen_size
2112
	movzx	eax, bx
2113
	inc	eax
2114
	shr	eax, 1
2115
	push	eax
2116
	shr	ebx, 16
2117
	inc	ebx
2118
	shr	ebx, 1
2119
	push	ebx
2120
	call	[SetCursorPos]
2121
	ret
2122
.not15:
2123
        cmp     ebx, 16
2124
        jnz     .not16
2125
        sub     esp, 20h
2126
        push    esp
2127
        call    [GlobalMemoryStatus]
2128
        mov     eax, [esp+12]
2129
        add     esp, 20h
2130
        shr     eax, 10
2131
        mov     [esp+20h], eax
2132
        ret
2133
.not16:
2134
        cmp     ebx, 17
2135
        jnz     .not17
2136
        sub     esp, 20h
2137
        push    esp
2138
        call    [GlobalMemoryStatus]
2139
        mov     eax, [esp+8]
2140
        add     esp, 20h
2141
        shr     eax, 10
2142
        mov     [esp+20h], eax
2143
        ret
2144
.not17:
2145
        cmp     ebx, 19
2146
        jnz     .not19
2147
        jecxz   .19_0
2148
        dec     ecx
2149
        jz      .19_1
2150
        dec     ecx
2151
        jz      .19_2
2152
        dec     ecx
2153
        jz      .19_3
2154
        dec     ecx
2155
        jnz     not_supported_i40_fn
2156
        movzx   eax, dx
2157
        push    eax
2158
        shr     edx, 16
2159
        push    edx
2160
        call    [SetCursorPos]
2161
        ret
2162
.19_0:
2163
        mov     eax, [shared_data]
2164
        movzx   eax, [eax+shared_data_struc.mouse_speed_factor]
2165
        mov     [esp+20h], eax
2166
        ret
2167
.19_1:
2168
        mov     eax, [shared_data]
2169
        mov     [eax+shared_data_struc.mouse_speed_factor], dx
2170
        ret
2171
.19_2:
2172
        mov     eax, [shared_data]
2173
        mov     eax, [eax+shared_data_struc.mouse_delay]
2174
        mov     [esp+20h], eax
2175
        ret
2176
.19_3:
2177
        mov     eax, [shared_data]
2178
        mov     [eax+shared_data_struc.mouse_delay], edx
2179
        ret
2180
.not19:
2181
	cmp	ebx, 21
2182
	jnz	.not21
2183
	xchg	eax, ecx
2184
	call	get_slot_num
2185
	mov	[esp+20h], edx
2186
	ret
2187
.not21:
2188
	cmp	ebx, 22
2189
	jnz	not_supported_i40_fn
2190
	cmp	ecx, 4
2191
	jae	not_supported_i40_fn
2192
	shr	ecx, 1
2193
	jnc	@f
2194
	xchg	eax, edx
2195
	call	get_slot_num
2196
@@:
2197
	dec	edx
2198
	jz	.22err
2199
	mov	esi, [shared_data]
2200
	cmp	edx, [esi]
2201
	jae	.22err
2202
	shl	edx, 6
2203
	mov	esi, [esi+edx+shared_data_struc.hWnd]
2204
	and	dword [esp+20h], 0
2205
	dec	ecx
2206
	js	minimize_given_window
2207
	jmp	.restore_given_window
2208
.22err:
2209
	or	dword [esp+20h], -1
2210
	ret
2211
 
2212
get_slot_num:
2213
	push	ecx
2214
	mov	esi, [shared_data]
2215
	mov	ecx, [esi]
2216
	add	esi, shared_data_struc.threads
2217
	xor	edx, edx
2218
@@:
2219
	inc	edx
2220
	cmp	[esi], eax
2221
	jz	@f
2222
	add	esi, 64
2223
	loop	@b
2224
	xor	edx, edx
2225
@@:
2226
	pop	ecx
2227
	ret
2228
 
2229
minimize_window:
2230
	mov	esi, [ebp+tls.hWnd]
2231
minimize_given_window:
2232
	mov	[ebp+tls.butbuflen], 0
2233
	xor	eax, eax	; SW_HIDE
2234
	mov	ecx, [shared_data]
2235
	cmp	[ecx+shared_data_struc.vk], 0
2236
	jnz	@f
2237
	mov	al, 6		; SW_MINIMIZE
2238
@@:
2239
	push	eax
2240
	push	esi
2241
	call	[ShowWindow]
2242
	ret
2243
 
2244
server_convert:
2245
	div	edx
2246
	ret
2247
 
2248
i40_sys_setup:
2249
	mov	eax, [shared_data]
2250
	and	dword [esp+20h], 0
2251
	dec	ebx
2252
	jnz	.nomidi
2253
	cmp	ecx, 100h
2254
	jb	.nomidi
2255
	cmp	ecx, 0xFFFF
2256
	ja	.nomidi
2257
	mov	[eax+shared_data_struc.midi_base], cx
2258
	ret
2259
.nomidi:
2260
	dec	ebx
2261
	jnz	.not2
2262
	mov	edi, keymap
2263
	dec	ecx
2264
	jz	.settable
2265
	mov	edi, keymap_shift
2266
	dec	ecx
2267
	jz	.settable
2268
	mov	edi, keymap_alt
2269
	dec	ecx
2270
	jnz	.nosettable
2271
.settable:
2272
	add	edx, [base]
2273
	mov	esi, edx
2274
	mov	ecx, 80h/4
2275
	rep	movsd
2276
	ret
2277
.nosettable:
2278
	cmp	ecx, 9-3
2279
	jnz	.nosetkeyboard
2280
	mov	[eax+shared_data_struc.keyboard], dx
2281
	ret
2282
.nosetkeyboard:
2283
	inc	dword [esp+20h]
2284
	ret
2285
.not2:
2286
	dec	ebx
2287
	jnz	.not3
2288
	mov	[eax+shared_data_struc.cd_base], cl
2289
	ret
2290
.not3:
2291
	dec	ebx
2292
	jnz	.not4
2293
	cmp	ecx, 0x100
2294
	jb	.not4
2295
	cmp	ecx, 0xFFFF
2296
	ja	.not4
2297
	mov	word [eax+shared_data_struc.sb16], cx
2298
	ret
2299
.not4:
2300
	dec	ebx
2301
	jnz	.not5
2302
	mov	[eax+shared_data_struc.syslang], ecx
2303
	ret
2304
.not5:
2305
	dec	ebx
2306
	jnz	.not6
2307
	cmp	ecx, 0x100
2308
	jb	.not6
2309
	mov	[eax+shared_data_struc.wss], ecx
2310
	ret
2311
.not6:
2312
	dec	ebx
2313
	jnz	.not7
2314
	mov	[eax+shared_data_struc.hd_base], cl
2315
	ret
2316
.not7:
2317
	dec	ebx
2318
	jnz	.not8
2319
	mov	[eax+shared_data_struc.fat32part], ecx
2320
	ret
2321
.not8:
2322
	dec	ebx
2323
	dec	ebx
2324
	jnz	.not10
2325
	mov	[eax+shared_data_struc.sound_dma], ecx
2326
	ret
2327
.not10:
2328
	dec	ebx
2329
	jnz	.not11
2330
	and	ecx, 1
2331
	mov	[eax+shared_data_struc.lba_read_enabled], ecx
2332
	ret
2333
.not11:
2334
	dec	ebx
2335
	jnz	.not12
2336
	and	ecx, 1
2337
	jz	.okcheck11
2338
	cmp	[eax+shared_data_struc.bAllowReadPCI], 0
2339
	jnz	.okcheck11
2340
; be silent, because in loading process (of VirtualKolibri) SETUP will try this anyway
2341
;	push	40h
2342
;	push	0
2343
;	push	aPciDisabled
2344
;	push	0
2345
;	call	[MessageBoxA]
2346
	ret
2347
.okcheck11:
2348
	mov	[eax+shared_data_struc.pci_access_enabled], ecx
2349
	ret
2350
.not12:
2351
	mov	byte [esp+20h], 21	; restore eax
2352
	jmp	not_supported_i40_fn
2353
 
2354
i40_wait_event_timeout:
2355
;        call    event_test_redraw
2356
;	imul	ebx, ebx, 10
2357
	sub	esp, 20h
2358
	mov	esi, esp
2359
	jmp	.M
2360
.L:
2361
	push	2
2362
	pop	eax
2363
	test	byte [ebp+tls.message_mask], al
2364
	jz	.nokey
2365
	cmp	[ebp+tls.keybuflen], ah
2366
	jnz	.event
2367
.nokey:
2368
	inc	eax
2369
	test	[ebp+tls.message_mask], 4
2370
	jz	.nobut
2371
	cmp	[ebp+tls.butbuflen], ah
2372
	jnz	.event
2373
.nobut:
2374
	push	1	; PM_REMOVE
2375
	push	0
2376
	push	0
2377
	push	0
2378
	push	esi
2379
	call	[PeekMessageA]
2380
	test	eax, eax
2381
	jz	.notfound
2382
	cmp	dword [esi+4], 0x12	; WM_QUIT
2383
	jz	i40_terminate
2384
	push	esi
2385
	call	[TranslateMessage]
2386
	push	esi
2387
	call	[DispatchMessageA]
2388
.M:
2389
	xor	eax, eax
2390
	cmp	[ebp+tls.curdraw], al
2391
	jz	@f
2392
	test	[ebp+tls.message_mask], 1
2393
	jz	@f
2394
	inc	eax
2395
	add	esp, 20h
2396
	mov	dword [esp+20h], eax
2397
	ret
2398
@@:
2399
	xchg	al, [ebp+tls.translated_msg_code]
2400
	test	eax, eax
2401
	jz	.L
2402
	cmp	al, 6
2403
	jnz	.event
2404
	test	[ebp+tls.message_mask], 20h
2405
	jz	.L
2406
.event:
2407
	add	esp, 20h
2408
	call	test_button_mouse
2409
	mov	[esp+20h], eax
2410
	ret
2411
.notfound:
2412
	push	10
2413
	call	[Sleep]
2414
	dec	ebx
2415
	jnz	.L
2416
.timeout:
2417
	add	esp, 20h
2418
	and	dword [esp+20h], 0
2419
	ret
2420
 
2421
i40_getsetup:
2422
	mov	eax, [shared_data]
2423
	dec	ebx
2424
	jnz	.not_midi_base
2425
	movzx	eax, [eax+shared_data_struc.midi_base]
2426
	mov	[esp+20h], eax
2427
	ret
2428
.not_midi_base:
2429
	dec	ebx
2430
	jnz	.not_keyboard
2431
	mov	esi, keymap
2432
	dec	ecx
2433
	jz	.getmap
2434
	mov	esi, keymap_shift
2435
	dec	ecx
2436
	jz	.getmap
2437
	mov	esi, keymap_alt
2438
	dec	ecx
2439
	jnz	.nobase
2440
.getmap:
2441
	mov	ecx, 128/4
2442
	mov	edi, edx
2443
	add	edi, [base]
2444
	rep	movsd
2445
	ret
2446
.nobase:
2447
	cmp	ecx, 9-3
2448
	jnz	not_supported_i40_fn
2449
	movzx	eax, [eax+shared_data_struc.keyboard]
2450
	mov	[esp+20h], eax
2451
	ret
2452
.not_keyboard:
2453
	dec	ebx
2454
	jnz	.not_cd_base
2455
	movzx	eax, [eax+shared_data_struc.cd_base]
2456
	mov	[esp+20h], eax
2457
	ret
2458
.not_cd_base:
2459
	dec	ebx
2460
	jnz	.not_sb16
2461
	mov	eax, [eax+shared_data_struc.sb16]
2462
	mov	[esp+20h], eax
2463
	ret
2464
.not_sb16:
2465
	dec	ebx
2466
	jnz	.not_lang
2467
	mov	eax, [eax+shared_data_struc.syslang]
2468
	mov	[esp+20h], eax
2469
	ret
2470
.not_lang:
2471
	dec	ebx
2472
	jnz	.not_wss
2473
	mov	eax, [eax+shared_data_struc.wss]
2474
	mov	[esp+20h], eax
2475
	ret
2476
.not_wss:
2477
	dec	ebx
2478
	jnz	.not_hdbase
2479
	movzx	eax, [eax+shared_data_struc.hd_base]
2480
	mov	[esp+20h], eax
2481
	ret
2482
.not_hdbase:
2483
	dec	ebx
2484
	jnz	.not_fat32part
2485
	mov	eax, [eax+shared_data_struc.fat32part]
2486
	mov	[esp+20h], eax
2487
	ret
2488
.not_fat32part:
2489
	dec	ebx
2490
	jnz	.not_timer_ticks
2491
	call	[GetTickCount]
2492
	push	10
2493
	pop	ecx
2494
	xor	edx, edx
2495
	div	ecx
2496
	mov	[esp+20h], eax
2497
	ret
2498
.not_timer_ticks:
2499
	dec	ebx
2500
	jnz	.not_sound_dma
2501
	mov	eax, [eax+shared_data_struc.sound_dma]
2502
	mov	[esp+20h], eax
2503
	ret
2504
.not_sound_dma:
2505
	dec	ebx
2506
	jnz	.not_lba_enabled
2507
	mov	eax, [eax+shared_data_struc.lba_read_enabled]
2508
	mov	[esp+20h], eax
2509
	ret
2510
.not_lba_enabled:
2511
	dec	ebx
2512
	jnz	.not_pci_enabled
2513
	mov	eax, [eax+shared_data_struc.pci_access_enabled]
2514
	mov	[esp+20h], eax
2515
	ret
2516
.not_pci_enabled:
2517
	mov	dword [esp+20h], 1	; this is kernel rule, not my
2518
	ret
2519
 
2520
i40_get_sys_date:
2521
	sub	esp, 10h
2522
	push	esp
2523
	call	[GetLocalTime]
2524
	movzx	eax, word [esp+6]
2525
	aam
2526
	shl	ax, 4
2527
	shr	ah, 4
2528
	shl	eax, 16-4
2529
	mov	ax, [esp+2]
2530
	aam
2531
	shl	ax, 4
2532
	shr	ah, 4
2533
	shr	ax, 4
2534
	mov	bl, al
2535
	mov	ax, [esp]
2536
	sub	ax, 2000
2537
	aam
2538
	shl	ax, 4
2539
	shr	ah, 4
2540
	shr	ax, 4
2541
	mov	ah, bl
2542
	add	esp, 10h
2543
	mov	[esp+20h], eax
2544
	ret
2545
 
2546
i40_current_folder:
2547
	add	ecx, [base]
2548
	dec	ebx
2549
	jz	.set
2550
	dec	ebx
2551
	jnz	not_supported_i40_fn
2552
	mov	edi, ecx
2553
	mov	esi, [ebp+tls.cur_dir]
2554
	push	edx
2555
	push	esi
2556
	call	[lstrlenA]
2557
	pop	ecx
2558
	inc	eax
2559
	cmp	ecx, eax
2560
	jb	@f
2561
	mov	ecx, eax
2562
@@:
2563
	rep	movsb
2564
	mov	byte [edi-1], 0
2565
	mov	[esp+20h], eax
2566
	ret
2567
.set:
2568
	mov	esi, ecx
2569
	cmp	byte [ecx], '/'
2570
	jnz	.relative
2571
	push	[ebp+tls.cur_dir]
2572
	call	free
2573
	push	esi
2574
	call	[lstrlenA]
2575
	inc	eax	; (for terminating zero)
2576
	inc	eax	; '/sys' -> '/rd/1' requires one additional byte
2577
	push	eax
2578
	push	eax
2579
	call	malloc
2580
	mov	[ebp+tls.cur_dir], eax
2581
	mov	edi, eax
2582
	pop	ecx
2583
	mov	eax, [esi]
2584
	or	eax, '    '
2585
	cmp	eax, '/sys'
2586
	jnz	@f
2587
	mov	eax, '/rd/'
2588
	stosd
2589
	mov	al, '1'
2590
	stosb
2591
	sub	ecx, 4
2592
	add	esi, 4
2593
@@:
2594
	rep	movsb
2595
	ret
2596
.relative:
2597
	push	[ebp+tls.cur_dir]
2598
	call	[lstrlenA]
2599
	push	eax
2600
	push	esi
2601
	call	[lstrlenA]
2602
	mov	edi, eax
2603
	inc	eax
2604
	add	[esp], eax
2605
	push	[ebp+tls.cur_dir]
2606
	push	0
2607
	push	[hHeap]
2608
	call	[HeapReAlloc]
2609
	mov	[ebp+tls.cur_dir], eax
2610
	add	edi, eax
2611
.l1:
2612
	cmp	word [esi], '.'
2613
	jz	.ret
2614
	cmp	word [esi], './'
2615
	jnz	@f
2616
	inc	esi
2617
	inc	esi
2618
	jmp	.l1
2619
@@:
2620
	cmp	word [esi], '..'
2621
	jnz	.copy
2622
	cmp	byte [esi+2], 0
2623
	jz	@f
2624
	cmp	byte [esi+2], '/'
2625
	jnz	.copy
2626
@@:
2627
	dec	edi
2628
	cmp	edi, [ebp+tls.cur_dir]
2629
	jbe	@f
2630
	cmp	byte [edi], '/'
2631
	jnz	@b
2632
@@:
2633
	inc	esi
2634
	inc	esi
2635
	cmp	byte [esi], 0
2636
	jz	.ret
2637
	inc	esi
2638
	jmp	.l1
2639
.copy:
2640
	lodsb
2641
	stosb
2642
	test	al, al
2643
	jnz	.copy
2644
	ret
2645
.ret:
2646
	mov	byte [edi], 0
2647
	ret
2648
 
2649
i40_delete_ramdisk_file:
2650
	sub	esp, 512
2651
	mov	edi, esp
2652
	call	ramdisk2win32
2653
	push	edi
2654
	call	[DeleteFileA]
2655
	add	esp, 512
2656
	ret
2657
 
2658
i40_write_ramdisk_file:
2659
	test	esi, esi
2660
	jnz	not_supported_i40_fn
2661
	sub	esp, 512
2662
	mov	edi, esp
2663
	push	ecx edx
2664
	call	ramdisk2win32
2665
	push	0
2666
	push	80h
2667
	push	2
2668
	push	0
2669
	push	0
2670
	push	40000000h
2671
	push	edi
2672
	call	[CreateFileA]
2673
	inc	eax
2674
	jz	.ret
2675
	dec	eax
2676
	xchg	eax, esi
2677
	pop	edx ecx
2678
	add	ecx, [base]
2679
	push	eax
2680
	mov	eax, esp
2681
	push	0
2682
	push	eax
2683
	push	edx
2684
	push	ecx
2685
	push	esi
2686
	call	[WriteFile]
2687
	pop	eax
2688
	push	esi
2689
	call	[CloseHandle]
2690
.ret:
2691
	add	esp, 512
2692
	and	dword [esp+20h], 0
2693
	ret
2694
 
2695
i40_screen_getpixel:
2696
	push	0
2697
	call	[GetDC]
2698
	xchg	eax, esi
2699
	push	8
2700
	push	esi
2701
	call	[GetDeviceCaps]
2702
	xchg	eax, ebx
2703
	xor	edx, edx
2704
	div	ebx
2705
	push	eax
2706
	push	edx
2707
	push	esi
2708
	call	[GetPixel]
2709
	push	eax
2710
	push	esi
2711
	push	0
2712
	call	[ReleaseDC]
2713
	pop	eax
2714
	call	convert_color
2715
	mov	[esp+20h], eax
2716
	ret
2717
 
2718
i40_screen_getarea:
2719
	add	ebx, [base]
2720
	push	ecx ebx edx
2721
	mov	edi, ecx
2722
	movsx	ebx, cx
2723
	sar	edi, 16
2724
	cmp	ebx, 0
2725
	jle	.nodata
2726
	cmp	edi, 0
2727
	jg	.okdata
2728
.nodata:
2729
	pop	edx ebx ecx
2730
	ret
2731
.okdata:
2732
	xor	eax, eax
2733
	push	eax
2734
	call	[GetDC]
2735
	push	eax
2736
	push	eax
2737
	call	[CreateCompatibleDC]
2738
	xchg	eax, esi
2739
	push	ebx
2740
	push	edi
2741
	push	dword [esp+8]
2742
	call	[CreateCompatibleBitmap]
2743
	push	eax
2744
	push	esi
2745
	call	[SelectObject]
2746
	push	eax
2747
	movzx	eax, word [esp+8]
2748
	movzx	ecx, word [esp+8+2]
2749
	push	0xCC0020
2750
	push	eax
2751
	push	ecx
2752
	push	dword [esp+16]
2753
	push	ebx
2754
	push	edi
2755
	push	0
2756
	push	0
2757
	push	esi
2758
	call	[BitBlt]
2759
	push	esi
2760
	call	[SelectObject]
2761
	push	ebp
2762
	xchg	eax, ebp
2763
; esi=hDC, ebp=hBitmap, ebx=height, edi=width
2764
	xor	eax, eax
2765
	push	eax	; biClrImportant
2766
	push	eax	; biClrUsed
2767
	push	eax	; biYPelsPerMeter
2768
	push	eax	; biXPelsPerMeter
2769
	push	eax	; biSizeImage
2770
	push	eax	; biCompression
2771
	push	180001h	; biBitCount, biPlanes
2772
	push	ebx	; biHeight
2773
	neg	dword [esp]
2774
	push	edi	; biWidth
2775
	push	40	; biSize
2776
	mov	ecx, esp
2777
	push	eax	; uUsage
2778
	push	ecx	; lpbi
2779
	mov	eax, [ecx+52]
2780
	test	edi, 3
2781
	jz	.width_aligned_1
2782
	lea	eax, [3*edi+3]
2783
	and	al, not 3
2784
	mul	ebx
2785
	call	malloc_big
2786
.width_aligned_1:
2787
	push	eax	; lpvBits
2788
	push	ebx	; cScanLines
2789
	push	0	; uStartScan
2790
	push	ebp	; hbmp
2791
	push	esi	; hdc
2792
	xchg	eax, edi
2793
	call	[GetDIBits]
2794
	add	esp, 40
2795
	push	ebp
2796
	call	[DeleteObject]
2797
	pop	ebp
2798
	push	esi
2799
	call	[DeleteDC]
2800
	push	0
2801
	call	[ReleaseDC]
2802
	pop	edx eax edx
2803
	cmp	eax, edi
2804
	jz	.ret
2805
; edi -> bits from Windows [dword-aligned scanlines], eax -> bits for Kolibri [no spaces],
2806
	shr	edx, 16
2807
; ebx = height, edx = width
2808
	push	8000h
2809
	push	0
2810
	push	edi
2811
	xchg	eax, edi
2812
	lea	edx, [edx*3]
2813
	xchg	eax, esi
2814
@@:
2815
	mov	ecx, edx
2816
	shr	ecx, 2
2817
	rep	movsd
2818
	mov	ecx, edx
2819
	and	ecx, 3
2820
	rep	movsb
2821
	add	esi, 3
2822
	and	esi, not 3
2823
	sub	ebx, 1
2824
	jnz	@b
2825
	call	[VirtualFree]
2826
.ret:
2827
	ret
2828
 
2829
i40_read_mouse_pos:
2830
	dec	ebx
2831
	js	.get_coord
2832
	jz	.get_coord
2833
	dec	ebx
2834
	jnz	.ifcursor
2835
	cmp	[bIs9x], 0
2836
	jnz	read_9x_mouse_buttons
2837
	xor	ebx, ebx
2838
	push	6	; VK_XBUTTON2
2839
	call	.aks
2840
	push	5	; VK_XBUTTON1
2841
	call	.aks
2842
	push	4	; VK_MBUTTON
2843
	call	.aks
2844
	push	2	; VK_RBUTTON
2845
	call	.aks
2846
	push	1	; VK_LBUTTON
2847
	call	.aks
2848
	mov	[esp+20h], ebx
2849
	ret
2850
.get_coord:
2851
	push	eax
2852
	push	eax
2853
	push	esp
2854
	call	[GetCursorPos]
2855
	pop	eax	; x
2856
	pop	ecx	; y
2857
	test	ebx, ebx
2858
	js	@f
2859
	sub     ax, [ebp+tls.x_start]
2860
	sub	ax, word [ebp+tls.client_left]
2861
	sub     cx, [ebp+tls.y_start]
2862
	sub	cx, word [ebp+tls.client_top]
2863
@@:
2864
	shl	eax, 16
2865
	add	eax, ecx
2866
	mov	[esp+20h], eax
2867
	ret
2868
.ifcursor:
2869
        dec     ebx
2870
        dec     ebx
2871
        jz      .load_cursor
2872
        dec     ebx
2873
        jz      .set_cursor
2874
        dec     ebx
2875
        jnz     .not_cursor
2876
.delete_cursor:
2877
        jecxz   .delete_invalid
2878
        call    acquire_shared
2879
        mov     eax, ecx
2880
        mov     ecx, num_cursors
2881
        mov     edi, [shared_data]
2882
        add     edi, shared_data_struc.cursors
2883
@@:
2884
        add     edi, 8
2885
        cmp     [edi-8], eax
2886
        loopnz  @b
2887
        jnz     .delete_invalid_release
2888
        mov     ecx, [ebp+tls.cur_slot]
2889
        cmp     [edi-4], ecx
2890
        jnz     .delete_invalid_release
2891
        and     dword [edi-8], 0
2892
        and     dword [edi-4], 0
2893
        call    release_shared
2894
        push    eax
2895
        call    [DestroyCursor]
2896
; the current kernel implementation returns garbage !
2897
        mov     dword [esp+20h], 0xBAADF00D     ; is it garbage? :-)
2898
        ret
2899
.delete_invalid_release:
2900
        call    release_shared
2901
.delete_invalid:
2902
        push    10h
2903
        push    0
2904
        push    aInvalidCursor
2905
        push    0
2906
        call    [MessageBoxA]
2907
; the current kernel implementation returns 6 !?
2908
        mov     dword [esp+20h], 6
2909
        ret
2910
.set_cursor:
2911
; set_cursor for invalid handle reverts to standard arrow
2912
        call    acquire_shared
2913
        mov     eax, ecx
2914
        jecxz   .setarrow
2915
        mov     ecx, num_cursors
2916
        mov     edi, [shared_data]
2917
        add     edi, shared_data_struc.cursors
2918
@@:
2919
        add     edi, 8
2920
        cmp     [edi-8], eax
2921
        loopnz  @b
2922
        jz      @f
2923
.setarrow:
2924
        mov     eax, [hArrow]
2925
@@:
2926
; N.B. I don't check process field, because the kernel allows to set
2927
;       cursors, loaded by another process
2928
        call    release_shared
2929
        mov     [ebp+tls.hCursor], eax
2930
        push    eax
2931
        call    [SetCursor]
2932
        mov     [esp+20h], eax
2933
        ret
2934
.load_cursor:
2935
        test    dx, dx
2936
        jz      .fromfile
2937
        dec     dx
2938
        jz      .frommem
2939
        dec     dx
2940
        jz      .indirect
2941
        jmp     not_supported_i40_fn
2942
.fromfile:
2943
        mov     esi, ecx
2944
        add     esi, [base]
2945
        sub     esp, 204h
2946
        mov     edi, esp
2947
        call    i40_file_system_lfn.parse
2948
        test    eax, eax
2949
        jz      @f
2950
        add     esp, 204h
2951
        and     dword [esp+20h], 0
2952
        ret
2953
@@:
2954
        push    10h     ; LR_LOADFROMFILE
2955
        push    32
2956
        push    32
2957
        push    2       ; IMAGE_CURSOR
2958
        push    edi
2959
        push    0
2960
        call    [LoadImageA]
2961
        add     esp, 204h
2962
        test    eax, eax
2963
        jnz     .addcursor
2964
        push    10h
2965
        push    0
2966
        push    aCursorFailed
2967
        jmp     .mberr
2968
.addcursor:
2969
        call    acquire_shared
2970
        mov     ecx, num_cursors
2971
        mov     edi, [shared_data]
2972
        add     edi, shared_data_struc.cursors
2973
@@:
2974
        add     edi, 8
2975
        cmp     dword [edi-8], 0
2976
        loopnz  @b
2977
        jz      @f
2978
        call    release_shared
2979
        push    10h
2980
        push    0
2981
        push    aCursorLimitExceeded
2982
        jmp     .mberr
2983
@@:
2984
        mov     [edi-8], eax
2985
        mov     edx, [ebp+tls.cur_slot]
2986
        mov     [edi-4], edx
2987
        call    release_shared
2988
        mov     [esp+20h], eax
2989
        ret
2990
.frommem:
2991
        add     ecx, [base]
2992
        cmp     dword [ecx], 0x020000
2993
        jz      @f
2994
        push    10h
2995
        push    0
2996
        push    aInvCursorData
2997
.mberr:
2998
        push    0
2999
        call    [MessageBoxA]
3000
.reterr:
3001
        and     dword [esp+20h], 0
3002
        ret
3003
@@:
3004
        cmp     word [ecx+4], 1
3005
        jz      @f
3006
        push    10h
3007
        push    0
3008
        push    aOnlyOneCursor
3009
        jmp     .mberr
3010
@@:
3011
        cmp     word [ecx+6], 0x2020
3012
        jz      @f
3013
        push    10h
3014
        push    0
3015
        push    aInvCursorDim
3016
        jmp     .mberr
3017
@@:
3018
        mov     eax, [ecx+0Ah]
3019
        add     ecx, [ecx+12h]
3020
        sub     ecx, 4
3021
        push    dword [ecx]
3022
        mov     [ecx], eax
3023
        push    ecx
3024
        push    0
3025
        push    32
3026
        push    32
3027
        push    0x00030000
3028
        push    0
3029
        push    0x2E8+4
3030
        push    ecx
3031
        call    [CreateIconFromResourceEx]
3032
        pop     ecx
3033
        pop     dword [ecx]
3034
        test    eax, eax
3035
        jnz     .addcursor
3036
.gen_failed:
3037
        push    10h
3038
        push    0
3039
        push    aCursorFailed
3040
        jmp     .mberr
3041
.indirect:
3042
        mov     ebx, edx
3043
        shr     ebx, 16         ; bl = y, bh = x
3044
        mov     esi, ecx
3045
        add     esi, [base]
3046
        push    32*32*4
3047
	call	malloc
3048
        mov     edi, eax
3049
        mov     ecx, 32*32
3050
        push    esi edi
3051
@@:
3052
        lodsd
3053
        and     eax, 0xFFFFFF
3054
        stosd
3055
        loop    @b
3056
        pop     edi esi
3057
        push    edi     ; lpvBits
3058
        push    32      ; cBitsPerPel
3059
        push    1       ; cPlanes
3060
        push    32      ; nHeight
3061
        push    32      ; nWidth
3062
        call    [CreateBitmap]
3063
        test    eax, eax
3064
        jnz     @f
3065
.free_edi:
3066
        push    edi
3067
	call	free
3068
        jmp     .gen_failed
3069
@@:
3070
        push    eax     ; ICONINFO.hbmColor
3071
        mov     ecx, 32*4
3072
        push    esi edi
3073
.1:
3074
        push    ecx
3075
        mov     cl, 8
3076
        xor     edx, edx
3077
@@:
3078
        lodsd
3079
        shr     eax, 24
3080
        setz    al
3081
        lea     edx, [edx*2+eax]
3082
        loop    @b
3083
        mov     al, dl
3084
        stosb
3085
        pop     ecx
3086
        loop    .1
3087
        pop     edi esi
3088
        push    edi     ; lpvBits
3089
        push    1       ; cBitsPerPel
3090
        push    1       ; cPlanes
3091
        push    32      ; nHeight
3092
        push    32      ; nWidth
3093
        call    [CreateBitmap]
3094
        test    eax, eax
3095
        jnz     @f
3096
        call    [DeleteObject]
3097
        jmp     .free_edi
3098
@@:
3099
        push    eax     ; ICONINFO.hbmMask
3100
        movzx   eax, bl
3101
        push    eax     ; ICONINFO.yHotSpot
3102
        movzx   eax, bh
3103
        push    eax     ; ICONINFO.xHotSpot
3104
        push    0       ; ICONINFO.fIcon
3105
        push    esp
3106
        call    [CreateIconIndirect]
3107
        mov     ebx, eax
3108
        add     esp, 12
3109
        call    [DeleteObject]
3110
        call    [DeleteObject]
3111
        test    ebx, ebx
3112
        jz      .free_edi
3113
        push    edi
3114
	call	free
3115
        mov     eax, ebx
3116
        jmp     .addcursor
3117
 
3118
.not_cursor:
3119
	dec	ebx
3120
	jnz	not_supported_i40_fn
3121
	mov	eax, [ebp+tls.scroll]
3122
	cdq
3123
	mov	ecx, 120	; WHEEL_DELTA
3124
	idiv	ecx
3125
	mov	[ebp+tls.scroll], edx
3126
	movzx	eax, ax
3127
	mov	[esp+20h], eax
3128
	ret
3129
 
3130
.aks:
3131
	push	dword [esp+4]
3132
	call	[GetAsyncKeyState]
3133
	cmp	ah, 80h
3134
	cmc
3135
	adc	ebx, ebx
3136
	ret	4
3137
 
3138
read_9x_mouse_buttons:
3139
	call	[jmp_temp_int33]
3140
	movzx	eax, bl
3141
	mov	[esp+20h], eax
3142
	ret
3143
 
3144
use16
3145
temp_code:
3146
	mov	eax, esp
3147
	mov	ss, [temp_ss]
3148
	mov	sp, temp_stack_size
3149
	push	eax
3150
 
3151
	mov	ax, 3
3152
	int	33h
3153
 
3154
	pop	eax
3155
	push	ds
3156
	pop	ss
3157
	mov	esp, eax
3158
	db	66h
3159
	retf
3160
 
3161
temp_code_int1A:
3162
	mov	esi, esp
3163
	mov	ss, [temp_ss]
3164
	mov	sp, temp_stack_size
3165
	push	esi
3166
 
3167
	int	1Ah
3168
 
3169
	pop	esi
3170
	push	ds
3171
	pop	ss
3172
	mov	esp, esi
3173
	db	66h
3174
	retf
3175
 
3176
temp_code_size = $ - temp_code
3177
use32
3178
 
3179
i40_draw_line:
3180
        push    edx
3181
	mov	esi, ecx
3182
	mov	eax, edx
3183
	call	convert_color
3184
	push	eax
3185
	push	eax
3186
	push	1
3187
	push	0
3188
	call	[CreatePen]
3189
	push	eax
3190
	push	[ebp+tls.hWnd]
3191
	call	[GetDC]
3192
	xchg	eax, edi
3193
	push	edi
3194
	call	[SelectObject]
3195
	push	eax
3196
	push    0
3197
	test    byte [esp+12+3], 0x01
3198
	jz      @f
3199
	push    6       ; R2_NOT
3200
	push    edi
3201
	call    [SetROP2]
3202
	mov     [esp], eax
3203
@@:
3204
	push	0
3205
	mov	eax, esi
3206
	shr	eax, 16
3207
	add     eax, [ebp+tls.client_top]
3208
	push	eax
3209
	mov	eax, ebx
3210
	shr	eax, 16
3211
	add     eax, [ebp+tls.client_left]
3212
	push	eax
3213
	push	edi
3214
	call	[MoveToEx]
3215
	movzx	esi, si
3216
	add     esi, [ebp+tls.client_top]
3217
	push	esi
3218
	movzx	ebx, bx
3219
	add     ebx, [ebp+tls.client_left]
3220
	push	ebx
3221
	push	edi
3222
	call	[LineTo]
3223
	pop     eax
3224
	test    byte [esp+8+3], 0x01
3225
	jz      @f
3226
	push    eax
3227
	push    edi
3228
	call    [SetROP2]
3229
	push    esi
3230
	push    ebx
3231
	push    edi
3232
	call    [GetPixel]
3233
	xor     eax, 0xFFFFFF
3234
	mov     [esp+4], eax
3235
@@:
3236
	pop	eax
3237
	pop	ecx
3238
	push	eax
3239
	push	ecx
3240
	push	esi
3241
	push	ebx
3242
	push	edi
3243
	call	[SetPixel]
3244
	push	edi
3245
	call	[SelectObject]
3246
	push	eax
3247
	call	[DeleteObject]
3248
	push	edi
3249
	push	[ebp+tls.hWnd]
3250
	call	[ReleaseDC]
3251
	pop     edx
3252
	ret
3253
 
3254
i40_get_background:
3255
	pushad
3256
	push	0
3257
	call	init_background
3258
	popad
3259
	mov	eax, [bgr_section]
3260
	dec	ebx
3261
	jz	.1
3262
	dec	ebx
3263
	jz	.2
3264
	dec	ebx
3265
	dec	ebx
3266
	jnz	not_supported_i40_fn
3267
	test	eax, eax
3268
	mov	ecx, 2
3269
	jz	@f
3270
	mov	ecx, [eax+8]
3271
@@:
3272
	mov	[esp+20h], ecx
3273
	ret
3274
.1:
3275
	test	eax, eax
3276
	jz	@f
3277
	mov	ecx, [eax]
3278
	shl	ecx, 16
3279
	mov	cx, [eax+4]
3280
	jmp	@b
3281
@@:
3282
	call	get_screen_size
3283
	add	ebx, 10001h
3284
@@:
3285
	mov	[esp+20h], ebx
3286
.ret:
3287
	ret
3288
.2:
3289
;	cmp	ecx, 0x160000-16
3290
;	jae	.ret
3291
	xor	ebx, ebx
3292
	test	eax, eax
3293
	jz	@b
3294
	mov	ebx, [eax+ecx+10h]
3295
	and	ebx, 0x00FFFFFF
3296
	jmp	@b
3297
 
3298
i40_set_event_mask:
3299
	test	ebx, not 1F7h
3300
	jnz	not_supported_i40_fn
3301
	mov	[ebp+tls.message_mask], ebx
3302
	ret
3303
 
3304
i40_reserve_free_ports:
3305
	cmp	ebx, 1
3306
	ja	not_supported_i40_fn
3307
	cmp	edx, 0xFFFF
3308
	ja	.inv_range
3309
	cmp	ecx, edx
3310
	jbe	.range_ok
3311
.inv_range:
3312
	push	30h
3313
	push	aWarning
3314
	push	PortsRangeErr
3315
	push	0
3316
	call	[MessageBoxA]
3317
	mov	dword [esp+20h], 1
3318
	ret
3319
.range_ok:
3320
	call	acquire_shared
3321
	mov	esi, [shared_data]
3322
	mov	eax, ecx
3323
	test	ebx, ebx
3324
	jnz	.free
3325
; reserve ports
3326
@@:
3327
	mov	edi, PortsNotEnabledErr
3328
	bt	dword [esi+shared_data_struc.DisabledPorts], eax
3329
	jc	.err_release
3330
	mov	edi, PortsUsedErr
3331
	bt	dword [esi+shared_data_struc.UsedIoMap], eax
3332
	jnc	.err_release
3333
	inc	eax
3334
	cmp	eax, edx
3335
	jbe	@b
3336
	mov	eax, ecx
3337
@@:
3338
	btr	dword [esi+shared_data_struc.UsedIoMap], eax
3339
	inc	eax
3340
	cmp	eax, edx
3341
	jbe	@b
3342
	jmp	.update_iomap
3343
.free:
3344
	mov	edi, PortsNotUsedErr
3345
	bt	dword [esi+shared_data_struc.UsedIoMap], eax
3346
	jc	.err_release
3347
	inc	eax
3348
	cmp	eax, edx
3349
	jbe	.free
3350
	mov	eax, ecx
3351
@@:
3352
	bts	dword [esi+shared_data_struc.UsedIoMap], eax
3353
	inc	eax
3354
	cmp	eax, edx
3355
	jbe	@b
3356
.update_iomap:
3357
	cmp	[bIs9x], 0
3358
	jz	.nt
3359
	call	release_shared
3360
	and	dword [esp+20h], 0
3361
	ret
3362
.nt:
3363
	mov	eax, [shared_data]
3364
	push	0
3365
	push	0
3366
	add	eax, shared_data_struc.UsedIoMap
3367
	push	2000h
3368
	push	eax
3369
	push	0x22203C
3370
	call	send_driver_request
3371
	mov	edi, DrvOpenErr
3372
	jnz	@f
3373
.err_release:
3374
	call	release_shared
3375
	push	30h
3376
	push	aWarning
3377
	push	edi
3378
	push	0
3379
	call	[MessageBoxA]
3380
	mov	dword [esp+20h], 1
3381
	ret
3382
@@:
3383
	call	release_shared
3384
;	push	0
3385
;	call	[Sleep]		; force task switch
3386
	and	dword [esp+20h], 0
3387
	ret
3388
 
3389
i40_display_number:
3390
	cmp	bl, 1
3391
	ja	not_supported_i40_fn
3392
	push	ebx esi
3393
	and	ebx, not 0xC0000000
3394
	xor	esi, esi
3395
	cmp	bl, 1
3396
	jb	.noptr
3397
	mov	eax, [base]
3398
	test	byte [esp+7], 0x40
3399
	jz	@f
3400
	mov	esi, [eax+ecx+4]
3401
@@:
3402
	mov	ecx, [eax+ecx]
3403
.noptr:
3404
	mov	eax, 10
3405
	cmp	bh, 1
3406
	jb	@f
3407
	mov	eax, 16
3408
	jz	@f
3409
	mov	eax, 2
3410
@@:
3411
	shr	ebx, 16
3412
	cmp	ebx, 64
3413
	jbe	@f
3414
	pop	esi ebx
3415
	jmp	not_supported_i40_fn
3416
@@:
3417
	push    edi
3418
	mov	edi, esp
3419
	sub	esp, 64
3420
	dec	edi
3421
	std
3422
	push	edx
3423
	push	ebx
3424
	xchg	eax, ecx
3425
	test	ebx, ebx
3426
	jz	.done
3427
.digit:
3428
	xor	edx, edx
3429
	test	esi, esi
3430
	jz	.dig0
3431
	push	eax
3432
	mov	eax, esi
3433
	div	ecx
3434
	pop	esi
3435
	xchg	eax, esi
3436
.dig0:
3437
	div	ecx
3438
	xchg	eax, edx
3439
	cmp	al, 10
3440
	sbb	al, 69h
3441
	das
3442
	stosb
3443
	xchg	eax, edx
3444
	dec	ebx
3445
	jnz	.digit
3446
.done:
3447
	cld
3448
	mov	edx, edi
3449
	inc	edx
3450
	pop	esi
3451
	pop	ebx
3452
	lea	edi, [esp+40h]
3453
	test	byte [esp+48h+3], 80h
3454
	jz	.okleadzero
3455
@@:
3456
	cmp	byte [edx], '0'
3457
	jnz	.okleadzero
3458
	inc	edx
3459
	dec	esi
3460
	cmp	edx, edi
3461
	jb	@b
3462
	dec	edx
3463
	inc	esi
3464
	mov	byte [edx], '0'
3465
.okleadzero:
3466
	mov	ecx, [edi+4]
3467
	and	ecx, not 0x80000000
3468
	mov     edi, [edi]
3469
	call	i40_writetext_l1
3470
	add	esp, 4Ch
3471
	ret
3472
 
3473
i40_display_settings:
3474
	dec	ebx
3475
	jnz	@f
3476
set_button_style:
3477
	div	edx
3478
	ret
3479
@@:
3480
	dec	ebx
3481
	jnz	@f
3482
	add	ecx, [base]
3483
set_wnd_colors:
3484
	div	edx
3485
	ret
3486
@@:
3487
	dec	ebx
3488
	jnz	@f
3489
	add	ecx, [base]
3490
get_wnd_colors:
3491
	div	edx
3492
	ret
3493
@@:
3494
	dec	ebx
3495
	jnz	@f
3496
	mov	eax, [_skinh]
3497
	mov	[esp+20h], eax
3498
	ret
3499
@@:
3500
	dec	ebx
3501
	jnz	@f
3502
	call	acquire_shared
3503
	mov	eax, [shared_data]
3504
	mov	ecx, [eax+shared_data_struc.workarea_right]
3505
	mov	[esp+20h], ecx
3506
	mov	ecx, [eax+shared_data_struc.workarea_left]
3507
	mov	[esp+22h], cx
3508
	mov	ecx, [eax+shared_data_struc.workarea_bottom]
3509
	mov	[esp+14h], ecx
3510
	mov	ecx, [eax+shared_data_struc.workarea_top]
3511
	mov	[esp+16h], cx
3512
	call	release_shared
3513
	ret
3514
@@:
3515
	dec	ebx
3516
	jnz	@f
3517
	call	acquire_shared
3518
	mov	eax, [shared_data]
3519
	mov	bx, cx
3520
	mov	[eax+shared_data_struc.workarea_right], ebx
3521
	shr	ecx, 10h
3522
	mov	[eax+shared_data_struc.workarea_left], ecx
3523
	mov	bx, dx
3524
	mov	[eax+shared_data_struc.workarea_bottom], ebx
3525
	shr	edx, 10h
3526
	mov	[eax+shared_data_struc.workarea_top], edx
3527
	call	release_shared
3528
	ret
3529
@@:
3530
	dec	ebx
3531
	jnz	not_supported_i40_fn
3532
	mov	eax, dword [margins]
3533
	mov	[esp+20h], eax
3534
	mov	eax, dword [margins+4]
3535
	mov	[esp+14h], eax
3536
	ret
3537
 
3538
i40_set_window_shape:
3539
	test	ebx, ebx
3540
	jnz	@f
3541
	mov	[ebp+tls.lpShapeData], ecx
3542
	jmp	.common
3543
@@:	dec	ebx
3544
	jnz	not_supported_i40_fn
3545
	inc	ebx
3546
	shl	ebx, cl
3547
	mov	[ebp+tls.scale], ebx
3548
.common:
3549
	cmp	[ebp+tls.showwnd], 0
3550
	jz	.done
3551
	call	set_window_shape
3552
.done:	ret
3553
 
3554
set_window_shape:
3555
	mov	esi, [ebp+tls.lpShapeData]
3556
	add	esi, [base]
3557
	movzx	ebx, [ebp+tls.y_size]
3558
	mov	eax, ebx
3559
	inc	eax
3560
	inc	eax
3561
	shl	eax, 4
3562
	push	eax
3563
	call	malloc
3564
	push	eax
3565
	xchg	eax, edi
3566
	push	20h
3567
	pop	eax
3568
	stosd		; RGNDATAHEADER.dwSize
3569
	push	1
3570
	pop	eax
3571
	stosd		; .iType
3572
	xor	eax, eax
3573
	stosd		; .nCount
3574
	stosd		; .nRgnSize
3575
	stosd		; RGNDATAHEADER.rcBound.left
3576
	stosd		; .top
3577
	movzx	eax, [ebp+tls.x_size]
3578
	stosd		; .right
3579
	movzx	eax, [ebp+tls.y_size]
3580
	stosd		; .bottom
3581
	xor	edx, edx	; edx=number of rects, ebp=allocated number of rects
3582
	xor	ecx, ecx
3583
.yloop:
3584
	push	ecx
3585
	xor	ecx, ecx
3586
.1:
3587
	lodsb
3588
	cmp	al, 0
3589
	jnz	.2
3590
	add	ecx, [ebp+tls.scale]
3591
	cmp	cx, [ebp+tls.x_size]
3592
	jae	.3
3593
	jmp	.1
3594
.2:
3595
	inc	edx
3596
	cmp	edx, ebx
3597
	ja	.realloc_rects
3598
.realloc_cont:
3599
	mov	[edi], ecx
3600
	pop	eax
3601
	mov	[edi+4], eax
3602
	push	eax
3603
	add	eax, [ebp+tls.scale]
3604
	mov	[edi+12], eax
3605
	add	ecx, [ebp+tls.scale]
3606
.4:
3607
	lodsb
3608
	cmp	al, 0
3609
	jz	.5
3610
	add	ecx, [ebp+tls.scale]
3611
	cmp	cx, [ebp+tls.x_size]
3612
	jb	.4
3613
.5:
3614
	mov	[edi+8], ecx
3615
	add	edi, 10h
3616
	add	ecx, [ebp+tls.scale]
3617
	cmp	cx, [ebp+tls.x_size]
3618
	jb	.1
3619
.3:
3620
	pop	ecx
3621
	add	ecx, [ebp+tls.scale]
3622
	cmp	cx, [ebp+tls.y_size]
3623
	jb	.yloop
3624
	pop	edi
3625
	mov	[edi+8], edx
3626
	push	edi
3627
	inc	edx
3628
	inc	edx
3629
	shl	edx, 4
3630
	push	edx
3631
	push	0
3632
	call	[ExtCreateRegion]
3633
	push	1
3634
	push	eax
3635
	push	[ebp+tls.hWnd]
3636
	call	[SetWindowRgn]
3637
	push	edi
3638
	call	free
3639
	ret
3640
 
3641
.realloc_rects:
3642
	push	ecx
3643
	push	edx
3644
	add	ebx, ebx	; multiply size by 2
3645
	mov	eax, ebx
3646
	inc	eax
3647
	inc	eax
3648
	shl	eax, 4
3649
	push	eax
3650
	push	dword [esp+10h]
3651
	push	0
3652
	push	[hHeap]
3653
	call	[HeapReAlloc]
3654
	sub	edi, [esp+0xC]
3655
	add	edi, eax
3656
	mov	[esp+0xC], eax
3657
	pop	edx
3658
	pop	ecx
3659
	jmp	.realloc_cont
3660
 
3661
i40_create_thread:
3662
	dec	ebx
3663
	jnz	not_supported_i40_fn
3664
	push	ecx
3665
	push	edx
3666
	push	16
3667
	call	malloc
3668
	xchg	eax, ebx
3669
	pop	dword [ebx+4]	; esp
3670
	pop	dword [ebx]	; eip
3671
	push	0
3672
	push	0
3673
	push	0
3674
	push	0
3675
	call	[CreateEventA]
3676
	mov	[ebx+8], eax
3677
	mov	eax, [ebp+tls.cur_dir]
3678
	mov	[ebx+12], eax
3679
	push	eax
3680
	push	esp
3681
	push	0
3682
	push	ebx
3683
	push	KolibriThreadProc
3684
	push	10000h
3685
	push	0
3686
	call	[CreateThread]
3687
	pop	ecx
3688
	test	eax, eax
3689
	jnz	@f
3690
	or	dword [esp+20h], -1
3691
	ret
3692
@@:
3693
	push	eax
3694
	call	[CloseHandle]
3695
	push	-1
3696
	push	dword [ebx+8]
3697
	call	[WaitForSingleObject]
3698
	push	dword [ebx+8]
3699
	call	[CloseHandle]
3700
	mov	esi, [ebx]
3701
	push	ebx
3702
	call	free
3703
; esi = slot; get PID
3704
	call	acquire_shared
3705
	xchg	eax, esi
3706
	call	get_slot_ptr
3707
	mov	eax, [edi]
3708
	mov	dword [esp+20h], eax
3709
	push	edi
3710
	call	get_cur_slot_ptr
3711
	lea	esi, [edi+24]
3712
	pop	edi
3713
	add	edi, 24
3714
	movsd
3715
	movsd
3716
	movsd
3717
	movsd
3718
	call	release_shared
3719
	ret
3720
 
3721
KolibriThreadProc:
3722
	mov	ebp, [tls_index]
3723
	mov	eax, [fs:2Ch]
3724
	mov	ebp, [eax+ebp*4]
3725
	mov	ebx, [esp+4]
3726
	mov	ecx, [ebx]
3727
	mov	edx, [ebx+4]
3728
	mov	[ebp+tls._cs], cs
3729
	mov	[ebp+tls._ds], ds
3730
	mov	[ebp+tls._fs], fs
3731
	mov	[ebp+tls._esp], edx
3732
	mov	[ebp+tls._eip], ecx
3733
	mov	esi, [ebx+12]
3734
	push	esi
3735
	call	[lstrlenA]
3736
	inc	eax
3737
	push	eax
3738
	push	eax
3739
	call	malloc
3740
	pop	ecx
3741
	mov	[ebp+tls.cur_dir], eax
3742
	mov	edi, eax
3743
	rep	movsb
3744
lock	inc	[NumThreads]
3745
	call	acquire_shared
3746
server_new_thread:
3747
	div	edx
3748
	call	release_shared
3749
	mov	[ebp+tls.cur_slot], ecx
3750
	mov	[ebx], ecx
3751
	push	dword [ebx+8]
3752
	call	[SetEvent]
3753
	xor	ebx, ebx
3754
	push	ebx
3755
	push	400000h
3756
	push	ebx
3757
	push	ebx
3758
	mov	eax, 80000000h
3759
	push	eax
3760
	push	eax
3761
	push	eax
3762
	push	eax
3763
	push	eax
3764
	push	[process_name]
3765
	push	classname
3766
	push	ebx
3767
	call	[CreateWindowExA]
3768
	mov	[ebp+tls.hWnd], eax
3769
	mov	[ebp+tls.bActive], 1
3770
	mov	[ebp+tls.bFirstMouseMove], 1
3771
	call	acquire_shared
3772
	call	get_cur_slot_ptr
3773
	mov	[edi+shared_data_struc.hWnd-shared_data_struc.threads], eax
3774
	call	release_shared
3775
	xor	eax, eax
3776
	xor	ecx, ecx
3777
	xor	edx, edx
3778
	xor	esi, esi
3779
	xor	edi, edi
3780
	push	202h
3781
	pushad
3782
	and	dword [esp+8], 0
3783
	jmp	i40_done
3784
 
3785
; initialize_winsock:
3786
	; push	ecx edx
3787
	; cmp	[WinSockDLL], -1
3788
	; jz	.failed_ret
3789
	; cmp	[WinSockDLL], 0
3790
	; jnz	.ok
3791
	; push	winsock_name
3792
	; call	[LoadLibraryA]
3793
	; mov	[WinSockDLL], eax
3794
	; test	eax, eax
3795
	; jz	.failed
3796
	; push	esi
3797
	; mov	esi, winsock_imports
3798
; .import:
3799
	; lodsd
3800
	; test	eax, eax
3801
	; jz	.importok
3802
	; push	eax
3803
	; push	[WinSockDLL]
3804
	; call	[GetProcAddress]
3805
	; mov	[esi-4], eax
3806
	; test	eax, eax
3807
	; jnz	.import
3808
	; pop	esi
3809
	; jmp	.failed
3810
; .importok:
3811
	; sub	esp, 190h
3812
	; push	esp
3813
	; push	101h
3814
	; call	[WSAStartup]
3815
	; add	esp, 190h
3816
	; test	eax, eax
3817
	; jz	.ok
3818
; .failed:
3819
	; or	[WinSockDLL], -1
3820
	; push	10h
3821
	; push	0
3822
	; push	aWinsockInitErr
3823
	; push	0
3824
	; call	[MessageBoxA]
3825
; .failed_ret:
3826
	; stc
3827
; .ok:
3828
	; pop	edx ecx
3829
	; ret
3830
 
3831
; i40_socket:
3832
	; call	initialize_winsock
3833
	; jnc	@f
3834
	; or	dword [esp+20h], -1
3835
	; ret
3836
; @@:
3837
	; cmp	ebx, 9
3838
	; jnz	not_supported_i40_fn
3839
; .is_localport_unused:
3840
	; mov	esi, ecx
3841
; ; destroy old tcp socket
3842
	; mov	eax, [ebp+tls.cursocket]
3843
	; test	eax, eax
3844
	; jz	@f
3845
	; dec	eax
3846
	; push	eax
3847
	; call	[closesocket]
3848
; @@:
3849
	; xor	ebx, ebx
3850
	; mov	[ebp+tls.curport], bx
3851
; ; create new tcp socket
3852
	; push	ebx	; protocol - unspecified
3853
	; push	1	; SOCK_STREAM aka TCP
3854
	; push	2	; AF_INET
3855
	; call	[socket]
3856
	; inc	eax
3857
	; mov	[ebp+tls.cursocket], eax
3858
	; jnz	@f
3859
	; push	10h
3860
	; push	ebx
3861
	; push	aSocketErr
3862
	; push	ebx
3863
	; call	[MessageBoxA]
3864
	; mov	dword [esp+20h], ebx
3865
	; ret
3866
; @@:
3867
	; push	ebx
3868
	; push	ebx	; sockaddr_in.sin_zero
3869
	; push	0x0100007F	; sockaddr_in.sin_addr = 127.0.0.1
3870
	; shl	esi, 16
3871
	; inc	esi
3872
	; inc	esi	; sockaddr_in.sin_family = 2 = AF_INET
3873
	; push	esi	; sockaddr_in.sin_port
3874
	; mov	ecx, esp
3875
	; push	10h	; namelen
3876
	; push	ecx	; name
3877
	; dec	eax
3878
	; push	eax	; s
3879
	; call	[bind]
3880
 
3881
i40_sound_interface:
3882
	cmp	ebx, 55
3883
	jnz	not_supported_i40_fn
3884
	mov	eax, [shared_data]
3885
	cmp	[eax+shared_data_struc.sound_flag], 0
3886
	jz	@f
3887
	ret
3888
@@:
3889
; prepare wave-block
3890
	push	800h
3891
	call	malloc
3892
	push	eax
3893
	lea	ebx, [eax+800h]
3894
	xchg	eax, edi
3895
	push	esi
3896
	mov	esi, wave_block_begin
3897
	mov	ecx, wbb_size/4
3898
	rep	movsd
3899
	stosd
3900
	pop	esi
3901
	add	esi, [base]
3902
.mainloop:
3903
	lodsb
3904
	test	al, al
3905
	jz	.done
3906
	cmp	al, 81h
3907
	jae	.note
3908
	movzx	edx, al
3909
	xor	eax, eax
3910
	lodsw
3911
	jmp	.doit
3912
.note:
3913
	sub	al, 81h
3914
	movzx	edx, al
3915
	lodsb
3916
	cmp	al, 0xFF
3917
	jz	.pause
3918
	mov	cl, al
3919
	and	eax, 0xF
3920
	movzx	eax, word [kontrOctave+eax+eax]
3921
	shr	cl, 4
3922
	shr	eax, cl
3923
.doit:
3924
; eax=divider (freq=1193180/divider), edx=time (in 1/100 sec)
3925
	mov	ecx, edx
3926
	mul	[wave_r]
3927
	div	[_1193180]
3928
	push	eax
3929
	mov	eax, ecx
3930
	mul	[wave_r]
3931
	div	[_100]
3932
	mov	ecx, eax
3933
	pop	edx
3934
.doit2:
3935
; ecx=number of bytes required for this note
3936
	lea	eax, [edi+ecx]
3937
	cmp	eax, ebx
3938
	ja	.realloc
3939
;	mov	al, 0xFF
3940
;	cmp	edx, ecx
3941
;	jbe	@f
3942
;	mov	al, 0	; this is for pause
3943
;@@:
3944
	mov	al, 80h
3945
; if edx is zero, make it 1
3946
	cmp	edx, 1
3947
	adc	edx, 0
3948
.writeloop:
3949
	push	ecx
3950
	cmp	ecx, edx
3951
	jb	@f
3952
	mov	ecx, edx
3953
@@:	rep	stosb
3954
	pop	ecx
3955
	xor	al, [sound_vol]
3956
	sub	ecx, edx
3957
	ja	.writeloop
3958
	jmp	.mainloop
3959
.pause:
3960
	mov	eax, edx
3961
	mul	[wave_r]
3962
	div	[_100]
3963
	mov	ecx, eax
3964
	mov	edx, eax
3965
	inc	edx
3966
	jmp	.doit2
3967
.realloc:
3968
	pop	eax
3969
	sub	ebx, eax
3970
	add	ebx, ebx	; ebx=new size
3971
	sub	edi, eax	; edi=delta
3972
	push	ecx edx
3973
	push	ebx
3974
	push	eax
3975
	push	0
3976
	push	[hHeap]
3977
	call	[HeapReAlloc]
3978
	pop	edx ecx
3979
	push	eax
3980
	add	ebx, eax
3981
	add	edi, eax
3982
	jmp	.doit2
3983
.done:
3984
	pop	ebx
3985
	sub	edi, ebx
3986
	sub	edi, 8
3987
	mov	[ebx+4], edi
3988
	sub	edi, 24h
3989
	mov	[ebx+28h], edi
3990
; because we use asynchronous call of PlaySoundA, we can not free used memory,
3991
; but we can free previous wave-block
3992
	push	0
3993
	push	0
3994
	push	0
3995
	call	[PlaySoundA]	; force previous sound terminate
3996
	push	5	; SND_ASYNC|SND_MEMORY
3997
	push	0
3998
	push	ebx
3999
	call	[PlaySoundA]
4000
	xchg	ebx, [ebp+tls.prev_snd_block]
4001
	test	ebx, ebx
4002
	jz	@f
4003
	push	ebx
4004
	call	free
4005
@@:
4006
	and	dword [esp+20h], 0
4007
	ret
4008
 
4009
i40_file_system:
4010
	add	ebx, [base]
4011
	lea	esi, [ebx+0x14]
4012
	cmp     dword [ebx], 0
4013
	jnz     not_supported_i40_fn
4014
emul_read_file:
4015
; read 0 bytes - OK
4016
	cmp	dword [ebx+8], 0
4017
	jnz	@f
4018
	and	dword [esp+20h], 0
4019
	ret
4020
@@:
4021
; check for root dir
4022
	cmp	byte [esi], 0
4023
	jz	.root
4024
	cmp	byte [esi+1], 0
4025
	jnz	.noroot
4026
.root:
4027
	mov	esi, dir0
4028
	mov	edi, [ebx+12]
4029
	add	edi, [base]
4030
	mov	ecx, 12
4031
	push	ecx
4032
	rep	movsb
4033
	add	edi, 32-12
4034
	pop	ecx
4035
	rep	movsb
4036
	and	dword [esp+20h], 0	; eax=0: read ok
4037
	mov	dword [esp+14h], 64	; ebx=size
4038
	ret
4039
.noroot:
4040
	sub	esp, 200h
4041
	call	convert_path
4042
	jc	emul_path_err
4043
	dec	eax
4044
	jz	.ramdisk
4045
	sub	al, 3
4046
	jae	.harddisk
4047
	add	esp, 200h
4048
	jmp	not_supported_i40_fn
4049
.ramdisk:
4050
	lodsb
4051
	cmp	al, 0
4052
	jz	.give_dir1
4053
; must be {/RD | /RAMDISK}{/1 | /FIRST}/...
4054
	lodsw
4055
	cmp	ax, '1\'
4056
	jz	.ramdisk_ok
4057
	cmp	ax, '1'
4058
	jz	.ramdisk_readdir
4059
	cmp	ax, 'FI'
4060
	jnz	emul_path_err
4061
	lodsd
4062
	cmp	eax, 'RST\'
4063
	jz	.ramdisk_ok
4064
	cmp	eax, 'RST'
4065
	jnz	emul_path_err
4066
.ramdisk_readdir:
4067
	add	esp, 200h
4068
	mov	esi, ramdisk_path
4069
	push	0	; read /rd/1
4070
	call	read_directory
4071
	mov	[esp+20h], eax
4072
	mov	[esp+14h], ebx
4073
	ret
4074
.ramdisk_ok:
4075
; now esi points to filename, relative from ramdisk
4076
	sub	esp, 200h
4077
	mov	edi, esp
4078
	push	ramdisk_path
4079
.doit1:
4080
	push	edi
4081
	call	[lstrcpyA]
4082
	cmp	byte [esi], 0
4083
	setz	al
4084
	push	eax
4085
	push	esi
4086
	push	edi
4087
	call	[lstrcatA]
4088
	pop	eax
4089
	lea	esi, [esp+200h]
4090
	xchg	esi, edi
4091
	mov	ecx, 200h/4
4092
	rep	movsd
4093
	add	esp, 200h
4094
	mov	esi, esp
4095
; now esi contains full Win32 name of requested file
4096
	push	eax
4097
	push	esi
4098
	call	[GetFileAttributesA]
4099
	inc	eax
4100
	pop	ecx
4101
	jz	emul_filenotfound
4102
	dec	eax
4103
	test	al, 10h		; FILE_ATTRIBUTE_DIRECTORY
4104
	jnz	.read_dir
4105
	push	0
4106
	push	0
4107
	push	3
4108
	push	0
4109
	push	1
4110
	push	80000000h
4111
	push	esi
4112
	call	[CreateFileA]
4113
	inc	eax
4114
	jz	emul_filenotfound
4115
	dec	eax
4116
	xchg	eax, esi
4117
	mov	eax, [ebx+4]
4118
	xor	edx, edx
4119
	shld	edx, eax, 9
4120
	shl	eax, 9
4121
	push	edx
4122
	mov	edi, esp
4123
	push	0
4124
	push	edi
4125
	push	eax
4126
	push	esi
4127
	call	[SetFilePointer]
4128
	push	0
4129
	push	edi
4130
	mov	eax, [ebx+8]
4131
	shl	eax, 9
4132
; check limits
4133
	mov	ecx, [limit]
4134
	inc	ecx
4135
	sub	ecx, [ebx+0xC]
4136
	cmp	eax, ecx
4137
	jbe	@f
4138
	mov	eax, ecx
4139
@@:	push	eax
4140
	mov	eax, [ebx+0xC]
4141
	add	eax, [base]
4142
	push	eax
4143
	push	esi
4144
	call	[ReadFile]
4145
	pop	eax
4146
	push	0
4147
	push	esi
4148
	call	[GetFileSize]
4149
	add	esp, 200h
4150
	mov	[esp+14h], eax
4151
	push	esi
4152
	call	[CloseHandle]
4153
	and	dword [esp+20h], 0
4154
	ret
4155
.read_dir:
4156
	inc	ecx
4157
	push	ecx	; 2 for exclude '..', 1 for all
4158
	call	read_directory
4159
	add	esp, 200h
4160
	mov	[esp+20h], eax
4161
	mov	[esp+14h], ebx
4162
	ret
4163
.harddisk:
4164
	movzx	edx, al
4165
	lodsb
4166
	test	al, al
4167
	jnz	@f
4168
	add	esp, 200h
4169
	mov	dword [esp+20h], 10	; access denied
4170
	ret
4171
@@:
4172
	xor	ecx, ecx	; partition
4173
@@:
4174
	lodsb
4175
	cmp	al, '\'
4176
	jz	@f
4177
	cmp	al, 0
4178
	jz	@f
4179
	sub	al, '0'
4180
	cmp	al, 9
4181
	ja	emul_path_err
4182
	imul	ecx, 10
4183
	add	cl, al
4184
	jmp	@b
4185
@@:
4186
	test	al, al
4187
	jnz	@f
4188
	dec	esi
4189
@@:
4190
	test	ecx, ecx
4191
	jz	emul_path_err
4192
	cmp	ecx, [hd_partitions_num+edx*4]
4193
	jbe	@f
4194
	add	esp, 200h
4195
	mov	dword [esp+20h], 4	; partition not defined
4196
	ret
4197
@@:
4198
	sub	esp, 200h
4199
	mov	edi, esp
4200
	mov	eax, [hd_partitions_array+edx*4]
4201
	dec	ecx
4202
	shl	ecx, 9
4203
	add	eax, ecx
4204
	push	eax
4205
	jmp	.doit1
4206
.give_dir1:
4207
	add	esp, 200h
4208
	mov	esi, dir1
4209
	mov	edi, [ebx+12]
4210
	add	edi, [base]
4211
	mov	ecx, 12
4212
	push	ecx
4213
	rep	movsb
4214
	and	dword [esp+20h], 0	; eax=0: read ok
4215
	mov	dword [esp+14h], 32	; ebx=size
4216
	ret
4217
 
4218
emul_path_err:
4219
	push	0
4220
	push	aWarning
4221
	push	aPathIsInvalid
4222
	push	0
4223
	call	[MessageBoxA]
4224
emul_filenotfound:
4225
	add	esp, 200h
4226
	mov	dword [esp+20h], 5	; file not found
4227
	cmp	dword [ebx], 10h
4228
	jnz	@f
4229
	neg	dword [esp+20h]
4230
@@:	ret
4231
 
4232
aWarning db 'Warning',0
4233
aPathIsInvalid db 'Requested path is invalid',0
4234
 
4235
convert_path:
4236
	lea	edi, [esp+4]
4237
	push	ebx
4238
	lea	ebx, [edi + 511]
4239
.1:
4240
	lodsb
4241
	cmp	al, '/'
4242
	jz	.1
4243
	dec	esi
4244
	mov	ecx, 11
4245
	sub	ebx, ecx
4246
	cmp	edi, ebx
4247
	ja	.5
4248
	mov	edx, edi
4249
	mov	al, ' '
4250
	add	ebx, ecx
4251
	rep	stosb
4252
	mov	edi, edx
4253
.2:
4254
	lodsb
4255
	cmp	al, '/'
4256
	jz	.3
4257
	cmp	al, '.'
4258
	jz	.4
4259
	cmp	al, 0
4260
	jz	.3
4261
	cmp	edi, ebx
4262
	jae	.5
4263
	cmp	al, 'a'
4264
	jb	@f
4265
	cmp	al, 'z'
4266
	ja	@f
4267
	sub	al, ' '
4268
@@:	stosb
4269
	jmp	.2
4270
.4:
4271
	lea	edi, [edx+8]
4272
	jmp	.2
4273
.3:
4274
	lea	edi, [edx+7]
4275
	mov	ecx, 8
4276
	std
4277
	mov	al, ' '
4278
	repz	scasb
4279
	cld
4280
	jz	.5
4281
	mov	ecx, [edx+8]
4282
	mov	[edi+3], ecx
4283
	mov	byte [edi+2], '.'
4284
	add	edi, 5
4285
	mov	ecx, 3
4286
	std
4287
	repz	scasb
4288
	cld
4289
	jz	@f
4290
	inc	edi
4291
	inc	edi
4292
@@:
4293
	mov	al, '\'
4294
	stosb
4295
	cmp	byte [esi-1], 0
4296
	jnz	.1
4297
	mov	byte [edi-1], 0
4298
	mov	esi, path_begin
4299
	xor	eax, eax
4300
	xor	ecx, ecx
4301
.6:
4302
	add	esi, ecx
4303
	lodsb
4304
	test	al, al
4305
	jz	.5
4306
	xchg	eax, ecx
4307
	lodsb
4308
	xchg	ecx, eax
4309
	lea	edi, [esp+8]
4310
	repz	cmpsb
4311
	jnz	.6
4312
	cmp	byte [edi], 0
4313
	jz	.7
4314
	cmp	byte [edi], '\'
4315
	jnz	.6
4316
.7:
4317
	mov	esi, edi
4318
	pop	ebx
4319
	push	eax
4320
	push	esi
4321
	push	esi
4322
	call	[OemToCharA]
4323
	pop	eax
4324
; convert /hd to /hdx
4325
	cmp	al, 3
4326
	jnz	@f
4327
	mov	eax, [shared_data]
4328
	movzx	eax, [eax+shared_data_struc.hd_base]
4329
	add	eax, 3
4330
@@:
4331
	clc
4332
	ret
4333
.5:
4334
	stc
4335
	pop	ebx
4336
	ret
4337
 
4338
read_directory:
4339
; in: ebx->fileinfo block, esi->mask
4340
;     byte [esp+4] = 0 for /rd/1, 1 for normal call, 2 for exclude '..'
4341
; out: eax,ebx according to kernel fn58 read /rd/1
4342
 
4343
; note that all returned values have been taken from kernel code
4344
 
4345
	mov	ecx, [ebx+8]	; number of blocks
4346
	mov	edi, [ebx+12]	; output memory
4347
	add	edi, [base]
4348
	mov	ebx, [ebx+4]	; start block
4349
; /rd/1 = 14 clusters
4350
	cmp	byte [esp+4], 0
4351
	jnz	.ok2
4352
	cmp	ebx, 14		; 14 clusters = root dir
4353
	jae	.err1
4354
	cmp	ecx, 14
4355
	jbe	.ok1
4356
.err1:
4357
	mov	eax, 5		; out of range
4358
	or	ebx, -1
4359
	ret	4
4360
.ok1:
4361
	lea	edx, [ebx+ecx]
4362
	cmp	edx, 14
4363
	pushfd
4364
	jbe	@f
4365
	sub	edx, 14
4366
	sub	ecx, edx
4367
	jz	.doret2
4368
@@:
4369
	popfd
4370
.ok2:
4371
	pushfd
4372
	shl	ebx, 9
4373
	shl	ecx, 9
4374
	xor	edx, edx
4375
	sub	esp, 200h
4376
	pushad
4377
	lea	edi, [esp+20h]
4378
	push	esi
4379
	call	[lstrlenA]
4380
	mov	ecx, eax
4381
	rep	movsb
4382
	mov	al, '\'
4383
	cmp	[edi-1], al
4384
	jz	@f
4385
	stosb
4386
@@:
4387
	mov	eax, '*.*'
4388
	stosd
4389
	popad
4390
	push	0
4391
	sub	esp, 400h
4392
.loop:
4393
	mov	esi, esp
4394
	push	ecx
4395
	lea	eax, [esi+404h]
4396
	call	get_next_file
4397
; if no file => zero record
4398
	test	eax, eax
4399
	jnz	.still
4400
	push	edi
4401
	mov	edi, esi
4402
	mov	ecx, 0x20/4
4403
	rep	stosd
4404
	pop	edi
4405
	mov	al, 0x20
4406
	add	[esi+400h], eax
4407
.still:
4408
	pop	ecx
4409
	cmp	byte [esp+60Ch], 1
4410
	jz	@f
4411
	cmp	word [esi], '..'
4412
	jz	.loop
4413
@@:
4414
	push	ecx
4415
	cmp	ebx, eax
4416
	jae	.skip
4417
	add	esi, ebx
4418
	mov	ecx, eax
4419
	sub	ecx, ebx
4420
	cmp	ecx, [esp]
4421
	jb	@f
4422
	mov	ecx, [esp]
4423
@@:
4424
	sub	[esp], ecx
4425
	rep	movsb
4426
.skip:
4427
	sub	ebx, eax
4428
	jae	@f
4429
	xor	ebx, ebx
4430
@@:
4431
	pop	ecx
4432
	test	ecx, ecx
4433
	jnz	.loop
4434
	call	done_find_file
4435
.doret:
4436
	add	esp, 400h
4437
	pop	ecx
4438
	add	esp, 200h
4439
.doret2:
4440
	xor	ebx, ebx
4441
	xor	eax, eax
4442
	cmp	byte [esp+8], 0
4443
	jz	.check_rd1
4444
	popfd
4445
;	cmp	edx, -1
4446
;	jz	.eof
4447
	cmp	ecx, 0x200
4448
	jae	.eof
4449
	jmp	.ret
4450
.check_rd1:
4451
	popfd
4452
	jb	.ret
4453
.eof:
4454
	mov	al, 6		; EOF
4455
.ret:	ret	4
4456
 
4457
get_next_file:
4458
; in: eax=mask, edx=hFindData, edx=0 or edx=-1, esi->buffer
4459
; out: buffer filled, eax=length
4460
	cmp	edx, -1
4461
	jnz	@f
4462
	xor	eax, eax
4463
	ret
4464
@@:
4465
	sub	esp, 0x140	; sizeof(WIN32_FIND_DATA)
4466
	pushad
4467
	lea	ecx, [esp+0x20]
4468
	push	ecx
4469
	test	edx, edx
4470
	jnz	.inited
4471
	push	eax
4472
	call	[FindFirstFileA]
4473
	mov	edx, eax
4474
	mov	[esp+0x14], edx
4475
	inc	eax
4476
	jmp	.cmn
4477
.inited:
4478
	push	edx
4479
	call	[FindNextFileA]
4480
	mov	edx, [esp+0x14]
4481
.cmn:
4482
	test	eax, eax
4483
	jnz	.ok
4484
	cmp	edx, -1
4485
	jz	@f
4486
	push	edx
4487
	call	[FindClose]
4488
@@:
4489
	popad
4490
	add	esp, 0x140
4491
	xor	eax, eax
4492
	or	edx, -1
4493
	ret
4494
.ok:
4495
	popad
4496
; Long File Names are not supported yet
4497
; file name
4498
	push	edi
4499
	lea	edi, [esp+4+0x130]	; WIN32_FIND_DATA.cAlternateFileName
4500
	cmp	byte [edi], 0
4501
	jnz	.shortname
4502
	push	esi
4503
	lea	esi, [esp+8+0x2C]	; WIN32_FIND_DATA.cFileName
4504
	push	edi
4505
.l2s:
4506
	lodsb
4507
	cmp	al, 'a'
4508
	jb	@f
4509
	cmp	al, 'z'
4510
	ja	@f
4511
	sub	al, 0x20
4512
@@:	stosb
4513
	cmp	al, 0
4514
	jnz	.l2s
4515
	pop	edi esi
4516
.shortname:
4517
	pushad
4518
	push	edi
4519
	push	edi
4520
	call	[CharToOemA]
4521
	popad
4522
; file name
4523
	mov	ecx, 10
4524
@@:
4525
	mov	byte [esi+ecx], ' '
4526
	dec	ecx
4527
	jns	@b
4528
	inc	ecx
4529
@@:
4530
	cmp	byte [edi], '.'
4531
	jnz	@f
4532
	inc	edi
4533
	mov	byte [esi+ecx], '.'
4534
	inc	ecx
4535
	jmp	@b
4536
@@:
4537
	mov	al, [edi]
4538
	inc	edi
4539
	cmp	al, 0
4540
	jz	.namedone
4541
	cmp	al, '.'
4542
	jz	.dot
4543
	mov	[esi+ecx], al
4544
	inc	ecx
4545
	jmp	@b
4546
.dot:
4547
	mov	cl, 8
4548
	jmp	@b
4549
.namedone:
4550
	pop	edi
4551
; attributes
4552
	mov	eax, [esp]	; WIN32_FIND_DATA.dwFileAttributes
4553
	and	al, 0x3F
4554
	mov	[esi+11], al
4555
	and	word [esi+12], 0
4556
; creation file and date
4557
	pushad
4558
	lea	eax, [esi+14]
4559
	push	eax
4560
	inc	eax
4561
	inc	eax
4562
	push	eax
4563
	lea	eax, [esp+8+20h+4]
4564
	push	eax
4565
	call	[FileTimeToDosDateTime]
4566
; last access date
4567
	lea	eax, [esp+1Ch]
4568
	push	eax
4569
	lea	eax, [esi+18]
4570
	push	eax
4571
	lea	eax, [esp+8+20h+0xC]
4572
	push	eax
4573
	call	[FileTimeToDosDateTime]
4574
; high word of cluster
4575
	and	word [esi+20], 0
4576
; last write file and date
4577
	lea	eax, [esi+22]
4578
	push	eax
4579
	inc	eax
4580
	inc	eax
4581
	push	eax
4582
	lea	eax, [esp+8+20h+0x14]
4583
	push	eax
4584
	call	[FileTimeToDosDateTime]
4585
; low word of cluster
4586
	mov	word [esi+26], 0xBAD	; random value
4587
; file size
4588
	popad
4589
	mov	eax, [esp+0x20]
4590
	mov	[esi+28], eax
4591
; return
4592
	add	esp, 0x140
4593
	mov	eax, 0x20
4594
	ret
4595
 
4596
done_find_file:
4597
	test	edx, edx
4598
	jz	.ret
4599
	cmp	edx, -1
4600
	jz	.ret
4601
	push	edx
4602
	push	edx
4603
	call	[FindClose]
4604
	pop	edx
4605
.ret:	ret
4606
 
4607
notify_run_prg:
4608
	test	esi, esi
4609
	jz	@f
4610
	add	esi, [base]
4611
@@:
4612
	call	acquire_shared
4613
	push	eax esi edi
4614
	mov	esi, [ebp+tls.cur_dir]
4615
	mov	edi, process_curdir
4616
@@:
4617
	lodsb
4618
	stosb
4619
	test	al, al
4620
	jz	@f
4621
	cmp	edi, process_curdir+4096
4622
	jb	@b
4623
	mov	byte [edi-1], 0
4624
@@:
4625
	pop	edi esi eax
4626
server_run_prg:
4627
	div	edx
4628
	call	release_shared
4629
	push	ecx
4630
	push	-1
4631
	push	ecx
4632
	call	[WaitForSingleObject]
4633
	call	[CloseHandle]
4634
server_get_run_result:
4635
	div	edx
4636
	jecxz	.ret
4637
	push	eax ecx edx
4638
	push	24
4639
	call	malloc
4640
	mov	[eax+16], esi
4641
	mov	[eax+20], edi
4642
	mov	esi, [ebp + tls.debuggees]
4643
	mov	[eax], esi
4644
	mov	[ebp + tls.debuggees], eax
4645
	pop	dword [eax+12]
4646
	pop	dword [eax+8]
4647
	pop	dword [eax+4]
4648
	mov	eax, [eax+4]
4649
.ret:
4650
	ret
4651
 
4652
i40_ipc:
4653
	dec	ebx
4654
	jnz	@f
4655
; set IPC memory
4656
	call	acquire_shared
4657
	call	get_cur_slot_ptr
4658
	add	ecx, [base]
4659
	mov	[edi+4], ecx
4660
	mov	[edi+8], edx
4661
	call	release_shared
4662
	and	dword [esp+20h], 0
4663
	ret
4664
@@:
4665
	dec	ebx
4666
	jnz	not_supported_i40_fn
4667
	add	edx, [base]
4668
	call	acquire_shared
4669
server_send_ipc:
4670
	div	edx
4671
	call	release_shared
4672
	test	eax, eax
4673
	jnz	@f
4674
	push	0
4675
	push	0
4676
	push	400h		; WM_USER
4677
	push	ecx
4678
	call	[PostMessageA]
4679
	xor	eax, eax
4680
@@:
4681
	mov	[esp+20h], eax
4682
	ret
4683
 
4684
i40_direct_scr_access:
4685
	cmp	[ColorDepth], 0
4686
	jnz	@f
4687
	push	10h
4688
	push	0
4689
	push	DSADisabled
4690
	push	0
4691
	call	[MessageBoxA]
4692
	jmp	i40_terminate
4693
@@:
4694
	dec	ebx
4695
	jz	.1
4696
	dec	ebx
4697
	jz	.2
4698
	dec	ebx
4699
	jz	.3
4700
	jmp	not_supported_i40_fn
4701
.1:
4702
	call	get_screen_size
4703
	add	ebx, 10001h
4704
	mov	[esp+20h], ebx
4705
	ret
4706
.2:
4707
	mov	eax, [ColorDepth]
4708
	mov	[esp+20h], eax
4709
	ret
4710
.3:
4711
	call	get_screen_size
4712
	shr	ebx, 16
4713
	lea	eax, [ebx+1]
4714
	mul	[ColorDepth]
4715
	shr	eax, 3
4716
	add	eax, 3
4717
	and	eax, not 3
4718
	mov	[esp+20h], eax
4719
	ret
4720
 
4721
i40_pci:
4722
	mov	eax, [shared_data]
4723
	cmp	[eax+shared_data_struc.pci_access_enabled], 0
4724
	jnz	@f
4725
.reterr:
4726
	or	dword [esp+20h], -1	; PCI access disabled
4727
	ret
4728
@@:
4729
	cmp	bl, 2
4730
	ja	.noinit
4731
	cmp	[eax+shared_data_struc.pci_data_init], 0
4732
	jnz	@f
4733
	push	eax ebx
4734
	call	pci_data_init
4735
	pop	ebx eax
4736
@@:
4737
	test	bl, bl
4738
	jnz	.not0
4739
	xor	ecx, ecx
4740
	cmp	[eax+shared_data_struc.pci_data_init], 1
4741
	jnz	.unsupp0	; emulate "unsupported" behavior
4742
	mov	ch, [eax+shared_data_struc.pci_bios_mj]
4743
	mov	cl, [eax+shared_data_struc.pci_bios_mn]
4744
.unsupp0:
4745
	mov	[esp+20h], ecx
4746
	ret
4747
.not0:
4748
	dec	bl
4749
	mov	ecx, ebx
4750
	jnz	.not1
4751
	cmp	[eax+shared_data_struc.pci_data_init], 1
4752
	jnz	.unsupp1
4753
	mov	cl, [eax+shared_data_struc.pci_bios_lb]
4754
.unsupp1:
4755
.retecx:
4756
	mov	[esp+20h], ecx
4757
	ret
4758
.not1:
4759
	test	[eax+shared_data_struc.pci_bios_pc], 1
4760
	jnz	@b
4761
	test	[eax+shared_data_struc.pci_bios_pc], 2
4762
	jz	@b
4763
	inc	ecx
4764
	jmp	@b
4765
.noinit:
4766
	sub	bl, 4
4767
	cmp	bl, 2
4768
	ja	not_supported_i40_fn
4769
	cmp	[bIs9x], 0
4770
	jz	.read_nt
4771
	mov	ah, 0xB1
4772
	mov	al, bl
4773
	add	al, 8
4774
	mov	bl, ch
4775
	movzx	di, cl
4776
	mov	ecx, ebx
4777
	call	[jmp_temp_int1A]
4778
	jc	.reterr
4779
	jmp	.retecx
4780
.read_nt:
4781
	push	cx
4782
	push	bx
4783
	mov	eax, esp
4784
	push	ecx
4785
	mov	ecx, esp
4786
	push	4
4787
	push	ecx
4788
	push	4
4789
	push	eax
4790
	push	0x222004
4791
	call	send_driver_request
4792
	pop	ecx edx
4793
	test	eax, eax
4794
	jnz	.retecx
4795
	push	30h
4796
	push	aWarning
4797
	push	DrvOpenErr
4798
	push	0
4799
	call	[MessageBoxA]
4800
	jmp	.reterr
4801
 
4802
pci_data_init:
4803
	call	acquire_shared
4804
	cmp	[bIs9x], 0
4805
	jz	.nt
4806
; On 9x systems, just do "int 1Ah" from 16-bit code
4807
	mov	ax, 0xB101
4808
	call	[jmp_temp_int1A]
4809
	test	ah, ah
4810
	jnz	.err
4811
	cmp	edx, 'PCI '
4812
	jnz	.err
4813
	mov	edx, [shared_data]
4814
	mov	[edx+shared_data_struc.pci_bios_mj], bh
4815
	mov	[edx+shared_data_struc.pci_bios_mn], bl
4816
	mov	[edx+shared_data_struc.pci_bios_lb], cl
4817
	mov	[edx+shared_data_struc.pci_bios_pc], al
4818
	mov	[edx+shared_data_struc.pci_data_init], 1
4819
	jmp	.ok
4820
.nt:
4821
; On NT systems, there is 'HKLM\HARDWARE\DESCRIPTION\System\MultifunctionAdapter' key,
4822
;   with some subkeys '0','1',..., which hold information on periphery.
4823
; Each PCI bus has its own subkey with 'Identifier'="PCI".
4824
; For first PCI bus 'Configuration Data' holds 4 additional bytes = info on PCI BIOS.
4825
.loop:
4826
	push	eax
4827
	push	esp	; phkResult
4828
	push	1	; samDesired = KEY_QUERY_VALUE
4829
	push	0	; ulOptions
4830
	push	keymfa	; lpSubKey
4831
	push	80000002h	; hKey = HKEY_LOCAL_MACHINE
4832
	call	[RegOpenKeyExA]
4833
	pop	esi	; key handle
4834
	test	eax, eax
4835
	jnz	.err	; subkeys are done, and we do not find required
4836
	push	eax
4837
	mov	eax, esp
4838
	push	4
4839
	push	esp	; lpcbData
4840
	push	eax	; lpData
4841
	push	0	; lpType
4842
	push	0	; lpReserved
4843
	push	aIdentifier	; lpValueName
4844
	push	esi	; hKey
4845
	call	[RegQueryValueExA]
4846
	pop	ecx
4847
	pop	edx
4848
	test	eax, eax
4849
	jnz	.cont
4850
	cmp	ecx, 4
4851
	jnz	.cont
4852
	cmp	edx, 'PCI'
4853
	jnz	.cont
4854
	sub	esp, 24h
4855
	mov	eax, esp
4856
	push	24h
4857
	push	esp
4858
	push	eax
4859
	push	0
4860
	push	0
4861
	push	aConfigurationData
4862
	push	esi
4863
	call	[RegQueryValueExA]
4864
	pop	ecx
4865
	test	eax, eax
4866
	jnz	.err3
4867
	cmp	ecx, 24h
4868
	jnz	.err3
4869
	mov	eax, [shared_data]
4870
	add	esp, 20h
4871
	pop	dword [eax+shared_data_struc.pci_bios_mj]
4872
	dec	[eax+shared_data_struc.pci_bios_lb]
4873
	js	.err2
4874
	mov	[eax+shared_data_struc.pci_data_init], 1
4875
	push	esi
4876
	call	[RegCloseKey]
4877
.ok:
4878
	call	release_shared
4879
	ret
4880
.cont:
4881
	push	esi
4882
	call	[RegCloseKey]
4883
	inc	[idxmfa]
4884
	cmp	[idxmfa], '9'
4885
	jbe	.loop
4886
	jmp	.err
4887
.err3:
4888
	add	esp, 24h
4889
.err2:
4890
	push	esi
4891
	call	[RegCloseKey]
4892
.err:
4893
	mov	eax, [shared_data]
4894
	mov	[eax+shared_data_struc.pci_data_init], 2
4895
	call	release_shared
4896
	push	40h
4897
	push	0
4898
	push	aCannotGetPci
4899
	push	0
4900
	call	[MessageBoxA]
4901
	ret
4902
 
4903
i40_debug_board:
4904
	dec	ebx
4905
	jz	.write
4906
	dec	ebx
4907
	jnz	not_supported_i40_fn
4908
.read:
4909
	call	acquire_shared
4910
	mov	eax, [shared_data]
4911
	mov	ecx, [eax+shared_data_struc.msg_board_count]
4912
	test	ecx, ecx
4913
	jnz	@f
4914
	mov	[esp+20h], ecx	; zero eax
4915
	mov	[esp+14h], ecx	; zero ebx
4916
	jmp	.ret
4917
@@:
4918
	dec	[eax+shared_data_struc.msg_board_count]
4919
	lea	edi, [eax+shared_data_struc.msg_board_data]
4920
	lea	esi, [edi+1]
4921
	movzx	edx, byte [edi]
4922
	mov	[esp+20h], edx
4923
	mov	dword [esp+14h], 1
4924
	dec	ecx
4925
	rep	movsb
4926
.ret:
4927
	jmp	release_shared
4928
.write:
4929
	call	acquire_shared
4930
	mov	eax, [shared_data]
4931
	mov	edx, [eax+shared_data_struc.msg_board_count]
4932
	mov	[eax+shared_data_struc.msg_board_data+edx], cl
4933
	inc	edx
4934
	and	edx, 511
4935
	mov	[eax+shared_data_struc.msg_board_count], edx
4936
	jmp	.ret
4937
 
4938
i40_resize_app_memory:
4939
	dec	ebx
4940
	jnz	not_supported_i40_fn
4941
	cmp     [heap_status], 0
4942
	jz      @f
4943
	push    30h
4944
	push    aWarning
4945
	push    aInvFn64Call
4946
	push    0
4947
	call    [MessageBoxA]
4948
	mov     dword [esp+20h], 1
4949
	ret
4950
@@:
4951
	cmp	[NumThreads], 1
4952
	jnz	not_supported_i40_fn
4953
	push	ecx
4954
	push	40h	; PAGE_EXECUTE_READWRITE
4955
	push	1000h	; MEM_COMMIT
4956
	push	ecx
4957
	push	0
4958
	call	[VirtualAlloc]
4959
	pop	ecx
4960
	test	eax, eax
4961
	jnz	.ok
4962
	mov	dword [esp+0x20], 1
4963
	ret
4964
.ok:
4965
	mov	edi, eax
4966
	mov	esi, [base]
4967
	push	ecx
4968
	cmp	ecx, [limit]
4969
	jbe	@f
4970
	mov	ecx, [limit]
4971
	inc	ecx
4972
@@:
4973
	push	eax
4974
	rep	movsb
4975
	call	acquire_shared
4976
	call	get_cur_slot_ptr
4977
	mov	ecx, [edi+4]
4978
	jecxz	@f
4979
	sub	ecx, [base]
4980
	add	ecx, [esp]
4981
	mov	[edi+4], ecx
4982
@@:
4983
	call	release_shared
4984
	push	8000h	; MEM_RELEASE
4985
	push	0
4986
	push	[base]
4987
	call	[VirtualFree]
4988
	pop	eax
4989
	pop	ecx
4990
	mov	[base], eax
4991
	dec	ecx
4992
	mov	[limit], ecx
4993
	mov     [fn9limit], ecx
4994
	call	get_cur_slot_ptr
4995
	mov	[edi+24], ecx
4996
	mov	esi, selector_data
4997
	mov	[esi+2], ax
4998
	shr	eax, 10h
4999
	mov	[esi+4], al
5000
	mov	[esi+7], ah
5001
	shr	ecx, 0Ch
5002
	mov	[esi], cx
5003
	shr	ecx, 10h
5004
	or	cl, 11000000b
5005
	mov	[esi+6], cl
5006
	mov	byte [esi+5], 11110010b
5007
	lea	edi, [esi+8]
5008
	movsd
5009
	movsd
5010
	mov	byte [esi+5], 11111010b
5011
	cmp	[bIs9x], 0
5012
	jnz	.9x
5013
	push	dword [esi-4]
5014
	push	dword [esi-8]
5015
	push	17h
5016
	push	dword [esi+4]
5017
	push	dword [esi]
5018
	push	0Fh
5019
	call	[NtSetLdtEntries]
5020
	mov	esi, ldterr
5021
	test	eax, eax
5022
	js	fail
5023
.d:	and	dword [esp+20h], 0
5024
	ret
5025
.9x:
5026
	mov	eax, sl0p
5027
	call	CallRing0
5028
	jmp	.d
5029
 
5030
convert_2bpp:
5031
	mov	esi, edi
5032
	add	esi, [base]
5033
	movzx	eax, word [esp]
5034
	pushad
5035
	add	ecx, 7
5036
	shr	ecx, 1
5037
	and	ecx, not 3
5038
	mul	ecx
5039
	push	eax
5040
	call	malloc
5041
	mov	[esp+1Ch], eax
5042
	popad
5043
	push	eax edx esi
5044
	mov	edi, eax
5045
	movzx	eax, word [esp+12]
5046
	mov	esi, ebx
5047
.extloop:
5048
	push	eax
5049
	push	ecx
5050
.innloop:
5051
	lodsb
5052
	mov	dl, al
5053
	push    eax
5054
	shr     al, 6
5055
	shr     dl, 4
5056
	shl     al, 4
5057
	and     dl, 3
5058
	or      al, dl
5059
	stosb
5060
	pop     eax
5061
	mov     dl, al
5062
	shl     al, 2
5063
	and     dl, 3
5064
	and     al, 0x30
5065
	or      al, dl
5066
	stosb
5067
	sub     ecx, 4
5068
	ja      .innloop
5069
	test	edi, 3
5070
	jz	@f
5071
	stosw
5072
@@:
5073
	pop	ecx
5074
	pop	eax
5075
	add	esi, [esp+16+0Ch]
5076
	dec	eax
5077
	jnz	.extloop
5078
	pop	esi edx edi
5079
	jmp	pad_cont8
5080
 
5081
pad_bmp8:
5082
	movzx	eax, word [esp]
5083
	pushad
5084
	add	ecx, 3
5085
	and	ecx, not 3
5086
	mul	ecx
5087
	push	eax
5088
	call	malloc
5089
	mov	[esp+1Ch], eax
5090
	popad
5091
	push	eax esi
5092
	mov	edi, eax
5093
	movzx	eax, word [esp+8]
5094
	mov	esi, ebx
5095
.extloop:
5096
	push	eax
5097
	push	ecx
5098
	mov     eax, ecx
5099
	shr     ecx, 2
5100
	rep	movsd
5101
	mov     ecx, eax
5102
	and     ecx, 3
5103
	rep     movsb
5104
	mov	ecx, eax
5105
	neg	ecx
5106
	and	ecx, 3
5107
	mov	al, 0
5108
	rep	stosb
5109
	pop	ecx
5110
	pop	eax
5111
        add     esi, [esp+4*3+0Ch]
5112
	dec	eax
5113
	jnz	.extloop
5114
	pop	esi edi
5115
	jmp	pad_cont8
5116
 
5117
i40_putimage_palette:
5118
	add	ebx, [base]
5119
	push	ecx
5120
	shr	ecx, 16
5121
	cmp	esi, 1
5122
	jz	.1
5123
	cmp	esi, 4
5124
	jz	.4
5125
	cmp	esi, 8
5126
	jz	.8
5127
	cmp	esi, 15
5128
	jz	.15
5129
	cmp	esi, 16
5130
	jz	.16
5131
	cmp	esi, 32
5132
	jz	.32
5133
	cmp	esi, 2
5134
	jz	convert_2bpp
5135
	cmp	esi, 24
5136
	jz	.24
5137
	pop	ecx
5138
	jmp	not_supported_i40_fn
5139
.24:
5140
	lea	ecx, [ecx*3]
5141
	jmp	@f
5142
.1:
5143
	add	ecx, 7
5144
	shr	ecx, 3
5145
	jmp	@f
5146
.2:
5147
	add	ecx, 3
5148
	shr	ecx, 2
5149
	jmp	@f
5150
.4:
5151
	inc	ecx
5152
	shr	ecx, 1
5153
	jmp	@f
5154
.32:
5155
	add	ecx, ecx
5156
.15:
5157
.16:
5158
	add	ecx, ecx
5159
.8:
5160
@@:
5161
	add     edi, [base]
5162
	mov     esi, edi
5163
; Windows requires that all scanlines are DWORD-padded
5164
	mov	edi, ebx
5165
	test	cl, 3
5166
	jnz	pad_bmp8
5167
	cmp     dword [esp+10h], 0
5168
	jnz     pad_bmp8
5169
pad_cont8:
5170
	pop	ecx
5171
	mov	eax, [esp+8]
5172
; palette
5173
        sub     esp, 256*4
5174
	push	ecx edi
5175
	lea	edi, [esp+8]
5176
	cmp	al, 8
5177
	jnz	@f
5178
        mov     ecx, 256
5179
        rep     movsd
5180
@@:
5181
	cmp	al, 4
5182
	jnz	@f
5183
	mov	ecx, 16
5184
	rep	movsd
5185
@@:
5186
	cmp	al, 2
5187
	jnz	@f
5188
	movsd
5189
	movsd
5190
	movsd
5191
	movsd
5192
	add	eax, eax
5193
@@:
5194
	cmp	al, 1
5195
	jnz	@f
5196
	movsd
5197
	movsd
5198
@@:
5199
	cmp	al, 16
5200
	jnz	@f
5201
	mov	dword [edi+0], 0xF800
5202
	mov	dword [edi+4], 0x07E0
5203
	mov	dword [edi+8], 0x001F
5204
@@:
5205
        pop     edi ecx
5206
        xor     esi, esi
5207
; BITMAPINFO
5208
	push	esi	; biClrImportant
5209
	push	esi	; biClrUsed
5210
	push	esi	; biYPelsPerMeter
5211
	push	esi	; biXPelsPerMeter
5212
	push	esi	; biSizeImage
5213
	cmp	al, 15
5214
	jnz	.no15
5215
	push	esi	; biCompression
5216
	push	100001h	; biPlanes, biBitCount
5217
	jmp	@f
5218
.no15:
5219
	cmp	al, 16
5220
	jnz	.no16
5221
	push	3	; biCompression
5222
	push	100001h	; biPlanes, biBitCount
5223
	jmp	@f
5224
.no16:
5225
	push	esi	; biCompression
5226
;	push	80001h	; biPlanes, biBitCount
5227
	shl	eax, 16
5228
	inc	eax
5229
	push	eax	; biPlanes, biBitCount
5230
@@:
5231
	movzx	eax, cx
5232
	neg	eax
5233
	push	eax	; biHeight
5234
	neg	eax
5235
	shr	ecx, 10h
5236
	push	ecx	; biWidth
5237
	push	40	; biSize
5238
	push	ebx
5239
	lea	ebx, [esp+4]
5240
; SetDIBitsToDevice
5241
	push	esi	; fuColorUse = DIB_RGB_COLORS
5242
	push	ebx	; lpbmi
5243
	push	edi	; lpvBits
5244
	push	eax	; cScanLines
5245
	dec	eax
5246
	push	eax	; uStartScan
5247
	push	eax	; YSrc
5248
	inc	eax
5249
	push	esi	; XSrc
5250
	push	eax	; dwHeight
5251
	push	ecx	; dwWidth
5252
	movzx	ecx, dx
5253
	add     ecx, [ebp+tls.client_top]
5254
	push	ecx	; YDest
5255
	shr	edx, 10h
5256
	add     edx, [ebp+tls.client_left]
5257
	push	edx	; XDest
5258
	push	[ebp+tls.hWnd]
5259
	call	[GetDC]
5260
	xchg	eax, ebx
5261
	push	ebx	; hdc
5262
	call	[SetDIBitsToDevice]
5263
	xchg	eax, ebx
5264
	pop	ebx
5265
	add	esp, 40+256*4
5266
	push	eax
5267
	push	[ebp+tls.hWnd]
5268
	call	[ReleaseDC]
5269
	cmp	edi, ebx
5270
	jz	@f
5271
	push	edi
5272
	call	free
5273
@@:
5274
	ret
5275
 
5276
i40_process_def:
5277
	dec	ebx
5278
	jz	.setmode
5279
	dec	ebx
5280
	jz	.getmode
5281
	dec	ebx
5282
	jz	.get_control
5283
	dec	ebx
5284
	jz	.add_hotkey
5285
	dec	ebx
5286
	jz	.del_hotkey
5287
	jmp	not_supported_i40_fn
5288
.setmode:
5289
	mov	[ebp+tls.usescancode], cl
5290
	ret
5291
.getmode:
5292
	movzx	eax, [ebp+tls.usescancode]
5293
	mov	[esp+20h], eax
5294
	ret
5295
.get_control:
5296
	mov	esi, .vkeycodes
5297
	mov	edi, 1
5298
.gcloop:
5299
	xor	eax, eax
5300
	lodsb
5301
	push	eax
5302
	call	[GetAsyncKeyState]
5303
	test	ax, ax
5304
	jns	@f
5305
	or	ebx, edi
5306
@@:
5307
	add	edi, edi
5308
	cmp	esi, .vkeycodes_end
5309
	jb	.gcloop
5310
	mov	[esp+20h], ebx
5311
	ret
5312
.add_hotkey:
5313
.del_hotkey:
5314
	and	dword [esp+20h], 0
5315
	ret
5316
.vkeycodes:
5317
	db	0xA0	; VK_LSHIFT
5318
	db	0xA1	; VK_RSHIFT
5319
	db	0xA2	; VK_LCONTROL
5320
	db	0xA3	; VK_RCONTROL
5321
	db	0xA4	; VK_LMENU
5322
	db	0xA5	; VK_RMENU
5323
	db	0x14	; VK_CAPITAL
5324
	db	0x90	; VK_NUMLOCK
5325
	db	0x91	; VK_SCROLL
5326
.vkeycodes_end:
5327
 
5328
i40_move_resize:
5329
	cmp	ebx, -1
5330
	jnz	@f
5331
	movzx	ebx, [ebp+tls.x_start]
5332
@@:	cmp	ecx, -1
5333
	jnz	@f
5334
	movzx	ecx, [ebp+tls.y_start]
5335
@@:	cmp	edx, -1
5336
	jnz	@f
5337
	movzx	edx, [ebp+tls.x_size]
5338
	dec	edx
5339
@@:	cmp	esi, -1
5340
	jnz	@f
5341
	movzx	esi, [ebp+tls.y_size]
5342
	dec	esi
5343
@@:
5344
	inc	edx
5345
	mov	[ebp+tls.x_start], bx
5346
	inc	esi
5347
	mov	[ebp+tls.y_start], cx
5348
	mov	[ebp+tls.x_size], dx
5349
	mov	[ebp+tls.y_size], si
5350
	push	1
5351
	push	esi
5352
	push	edx
5353
	push	ecx
5354
	push	ebx
5355
	push	[ebp+tls.hWnd]
5356
	call	[MoveWindow]
5357
	push	0
5358
	push	0
5359
	push	[ebp+tls.hWnd]
5360
	call	[InvalidateRect]
5361
	ret
5362
 
5363
i40_sys_services:
5364
        cmp     ebx, 3
5365
        jnz     .not3
5366
	mov	esi, [shared_data]
5367
	cmp     [esi+shared_data_struc.bAllowReadMSR], 0
5368
	mov     edi, aReadMSRDisabled
5369
	jz      .err
5370
	cmp	[bIs9x], 0
5371
	jz	.nt
5372
	mov     ecx, edx
5373
	mov	eax, rdmsrp
5374
	call	CallRing0
5375
	test	ebx, ebx
5376
	jnz	.nomsr
5377
	mov     [esp+20h], eax
5378
	mov     [esp+14h], edx
5379
	ret
5380
.nt:
5381
	push	0
5382
	push	edx
5383
	push	edx
5384
	mov	eax, esp
5385
	push	9
5386
	push	eax
5387
	push	4
5388
	push	eax
5389
	push	0x222000
5390
	call	send_driver_request
5391
	pop	ecx
5392
	pop	edx
5393
	pop	esi
5394
	mov	edi, DrvOpenErr
5395
	test	eax, eax
5396
	jz	.err
5397
	test	esi, esi
5398
	jnz	.nomsr
5399
	mov     [esp+20h], ecx
5400
	mov     [esp+14h], edx
5401
	ret
5402
.err:
5403
	push	30h
5404
	push	aWarning
5405
	push	edi
5406
	push	0
5407
	call	[MessageBoxA]
5408
	and     dword [esp+20h], 0
5409
	and     dword [esp+14h], 0
5410
	ret
5411
.nomsr:
5412
        push    10h
5413
        push    0
5414
        push    aNoMsr
5415
        push    0
5416
        call    [MessageBoxA]
5417
        jmp     i40_terminate
5418
.not3:
5419
        cmp     ebx, 11
5420
        jnz     .not11
5421
.initialize_heap:
5422
; initialize heap
5423
        cmp     [heap_status], 0
5424
        jz      .create_heap
5425
@@:
5426
        cmp     [heap_status], 1
5427
        jnz     @f
5428
        push    5
5429
        call    [Sleep]
5430
        jmp     @b
5431
@@:
5432
.heap_ret_size:
5433
        mov     eax, 0x5FC00000-0x1000
5434
        sub     eax, [heap_start]
5435
        mov     [esp+20h], eax
5436
        ret
5437
.create_heap:
5438
        cmp     [NumThreads], 1
5439
        jnz     not_supported_i40_fn
5440
        mov     [heap_status], 1
5441
        xor     ebx, ebx
5442
; reserve needed big region
5443
        mov     esi, 0x40000000
5444
@@:
5445
        push    40h     ; PAGE_EXECUTE_READWRITE
5446
        push    2000h   ; MEM_RESERVE
5447
        push    esi
5448
        push    ebx
5449
        call    [VirtualAlloc]
5450
        test    eax, eax
5451
        jnz     @f
5452
        shr     esi, 1
5453
        cmp     esi, 0x01000000
5454
        jae     @b
5455
.nomem_fatal:
5456
	xor	ebx, ebx
5457
        mov     esi, memerr
5458
        jmp     fail
5459
@@:
5460
        mov     [heap_region_size], esi
5461
        push    eax
5462
        mov     ecx, [limit]
5463
        inc     ecx
5464
        push    40h     ; PAGE_EXECUTE_READWRITE
5465
        push    1000h   ; MEM_COMMIT
5466
        push    ecx
5467
        push    eax
5468
        call    [VirtualAlloc]
5469
        test    eax, eax
5470
        jz      .nomem_fatal
5471
        mov     esi, [base]
5472
        pop     edi
5473
        push    edi
5474
        mov     edi, eax
5475
        mov     ecx, [limit]
5476
        inc     ecx
5477
        rep     movsb
5478
        push    8000h   ; MEM_RELEASE
5479
        push    ebx
5480
        push    [base]
5481
        call    [VirtualFree]
5482
        pop     eax
5483
        mov     [base], eax
5484
        mov     ecx, [heap_region_size]
5485
        dec     ecx
5486
        mov     [limit], ecx
5487
        mov     esi, selector_data
5488
        mov     [esi+2], ax
5489
        shr     eax, 10h
5490
        mov     [esi+4], al
5491
        mov     [esi+7], ah
5492
        shr     ecx, 0Ch
5493
        mov     [esi], cx
5494
        shr     ecx, 10h
5495
        or      cl, 11000000b
5496
        mov     [esi+6], cl
5497
        mov     byte [esi+5], 11110010b
5498
        lea     edi, [esi+8]
5499
        movsd
5500
        movsd
5501
        mov     byte [esi+5], 11111010b
5502
        cmp     [bIs9x], bl
5503
        jnz     .9x
5504
        push    dword [esi-4]
5505
        push    dword [esi-8]
5506
        push    17h
5507
        push    dword [esi+4]
5508
        push    dword [esi]
5509
        push    0Fh
5510
        call    [NtSetLdtEntries]
5511
        mov     esi, ldterr
5512
        test    eax, eax
5513
        js      fail
5514
        jmp     .heap_created
5515
.9x:
5516
        mov     eax, sl0p
5517
        call    CallRing0
5518
        xor	ebx, ebx
5519
.heap_created:
5520
        mov     eax, [fn9limit]
5521
        or      eax, 0xFFF
5522
        inc     eax
5523
        mov     [heap_start], eax
5524
        mov     eax, [heap_region_size]
5525
        sub     eax, [heap_start]
5526
        shr     eax, 10
5527
	call	malloc_big
5528
        mov     [heap_control_block], eax
5529
        test    eax, eax
5530
        jz      .nomem_fatal
5531
        mov     ecx, [heap_region_size]
5532
        sub     ecx, [heap_start]
5533
        or      ecx, 4
5534
        mov     [eax], ecx
5535
        push    heap_critical_sec
5536
        call    [InitializeCriticalSection]
5537
        mov     [heap_status], 2
5538
        jmp     .heap_ret_size
5539
.not11:
5540
        cmp     ebx, 12
5541
        jnz     .not12
5542
; allocate memory block in heap
5543
.allocate_heap:
5544
        cmp     [heap_status], 0
5545
        jnz     @f
5546
        push    30h
5547
        push    aWarning
5548
        push    aHeapNotInited
5549
        push    0
5550
        call    [MessageBoxA]
5551
        and     dword [esp+20h], 0
5552
        ret
5553
@@:
5554
        lea     edi, [ecx+0x1FFF]
5555
        and     edi, not 0xFFF
5556
@@:
5557
        cmp     [heap_status], 1
5558
        jnz     @f
5559
        push    5
5560
        call    [Sleep]
5561
        jmp     @b
5562
@@:
5563
        push    heap_critical_sec
5564
        call    [EnterCriticalSection]
5565
        xor     esi, esi
5566
        mov     ecx, [heap_region_size]
5567
        sub     ecx, [heap_start]
5568
        mov     edx, [heap_control_block]
5569
.l_0:
5570
        cmp     esi, ecx
5571
        jae     .m_exit
5572
        mov     ebx, esi
5573
        shr     ebx, 12
5574
        mov     eax, [edx+ebx*4]
5575
        test    al, 4
5576
        jz      .test_used
5577
        and     eax, not 0xFFF
5578
        cmp     eax, edi
5579
        jb      .m_next
5580
        jz      @f
5581
        push    esi
5582
        add     esi, edi
5583
        sub     eax, edi
5584
        or      al, 4
5585
        shr     esi, 12
5586
        mov     [edx+esi*4], eax
5587
        pop     esi
5588
        mov     eax, edi
5589
@@:
5590
        or      al, 8
5591
        mov     [edx+ebx*4], eax
5592
        mov     eax, [heap_start]
5593
        lea     eax, [eax+esi+0x1000]
5594
        push    eax
5595
        sub     edi, 0x1000
5596
; now do real allocate at eax with size edi
5597
        push    40h     ; PAGE_EXECUTE_READWRITE
5598
        push    1000h   ; MEM_COMMIT
5599
        push    edi
5600
        add     eax, [base]
5601
        push    eax
5602
        call    [VirtualAlloc]
5603
        test    eax, eax
5604
        jz      .nomem_fatal
5605
        jmp     .allocated
5606
.m_next:
5607
        add     esi, eax
5608
        jmp     .l_0
5609
.test_used:
5610
        test    al, 8
5611
        jnz     @f
5612
.fail_internal:
5613
        xor     ebx, ebx
5614
        mov     esi, aInternalError
5615
        jmp     fail
5616
@@:
5617
        and     eax, not 0xFFF
5618
        jmp     .m_next
5619
.m_exit:
5620
        push    0
5621
.allocated:
5622
        push    heap_critical_sec
5623
        call    [LeaveCriticalSection]
5624
        cmp     dword [esp], 0
5625
        jnz     @f
5626
        push    30h
5627
        push    aWarning
5628
        push    aMallocFailed
5629
        push    0
5630
        call    [MessageBoxA]
5631
@@:
5632
        pop     eax
5633
        mov     [esp+20h], eax
5634
        ret
5635
.not12:
5636
        cmp     ebx, 13
5637
        jnz     .not13
5638
; free memory block in heap
5639
.free_heap:
5640
        cmp     [heap_status], 0
5641
        jnz     @f
5642
        push    30h
5643
        push    aWarning
5644
        push    aHeapNotInited
5645
        push    0
5646
        call    [MessageBoxA]
5647
        and     dword [esp+20h], 0
5648
        ret
5649
@@:
5650
        test    ecx, ecx
5651
        jnz     @f
5652
; free(NULL) is OK
5653
        mov     dword [esp+20h], 1
5654
        ret
5655
@@:
5656
        mov     esi, ecx
5657
        cmp     [heap_status], 1
5658
        jnz     @f
5659
        push    5
5660
        call    [Sleep]
5661
        jmp     @b
5662
@@:
5663
        cmp     esi, [heap_region_size]
5664
        jae     .inv_exit
5665
        sub     esi, [heap_start]
5666
        jb      .inv_exit
5667
        cmp     esi, 0x1000
5668
        jae     @f
5669
.inv_exit:
5670
        mov     dword [esp+20h], 1
5671
.inv_exit_cmn:
5672
        push    30h
5673
        push    aWarning
5674
        push    aFreeInvalid
5675
        push    0
5676
        call    [MessageBoxA]
5677
        ret
5678
.inv_exit_realloc:
5679
        and     dword [esp+20h], 0
5680
        jmp     .inv_exit_cmn
5681
@@:
5682
        push    heap_critical_sec
5683
        call    [EnterCriticalSection]
5684
        mov     eax, esi
5685
        shr     esi, 12
5686
        dec     esi
5687
        mov     edx, [heap_control_block]
5688
	test	byte [edx+esi*4], 10h
5689
	jnz	.inv_exit_realloc
5690
        test    byte [edx+esi*4], 8
5691
        jz      .inv_wrn
5692
        test    eax, 0xFFF
5693
        jz      @f
5694
.inv_wrn:
5695
        push    edx
5696
        push    30h
5697
        push    aWarning
5698
        push    aFreeInvalid
5699
        push    0
5700
        call    [MessageBoxA]
5701
        pop     edx
5702
@@:
5703
        mov     eax, [edx+esi*4]
5704
        test    al, 8
5705
        jz      .freed
5706
        push    edx
5707
        and     eax, not 0xFFF
5708
        push    0x4000          ; MEM_DECOMMIT
5709
        sub     eax, 0x1000
5710
        push    eax
5711
        lea     eax, [esi+1]
5712
        shl     eax, 12
5713
        add     eax, [heap_start]
5714
        add     eax, [base]
5715
        push    eax
5716
        call    [VirtualFree]
5717
        pop     edx
5718
        mov     eax, [edx+esi*4]
5719
        and     eax, not 0xFFF
5720
        push    eax
5721
        or      al, 4
5722
        mov     [edx+esi*4], al
5723
        shr     eax, 12
5724
        add     eax, esi
5725
        test    byte [edx+eax*4], 4
5726
        jz      @f
5727
        xor     ecx, ecx
5728
        xchg    ecx, [edx+eax*4]
5729
        and     ecx, not 0xFFF
5730
        add     [edx+esi*4], ecx
5731
        add     [esp], ecx
5732
@@:
5733
        pop     eax
5734
        test    esi, esi
5735
        jz      .freed
5736
        xor     edi, edi
5737
.findprev:
5738
        cmp     edi, esi
5739
        jz      .foundprev
5740
        mov     ecx, edi
5741
        mov     ebx, [edx+ecx*4]
5742
        shr     ebx, 12
5743
        add     edi, ebx
5744
        jmp     .findprev
5745
.foundprev:
5746
        test    byte [edx+ecx*4], 4
5747
        jz      .freed
5748
        and     dword [edx+esi*4], 0
5749
        add     [edx+ecx*4], eax
5750
.freed:
5751
        push    heap_critical_sec
5752
        call    [LeaveCriticalSection]
5753
        mov     dword [esp+20h], 1
5754
        ret
5755
.not13:
5756
        cmp     ebx, 16
5757
        jnz     .not16
5758
        add     ecx, [base]
5759
        mov     esi, ecx
5760
        push    esi
5761
        push    aSound
5762
        call    [lstrcmpA]
5763
        test    eax, eax
5764
        jnz     @f
5765
        and     dword [esp+20h], 0
5766
        ret
5767
@@:
5768
        push    esi
5769
        push    aInfinity
5770
        call    [lstrcmpA]
5771
        test    eax, eax
5772
        jnz     @f
5773
        and     dword [esp+20h], 0
5774
        ret
5775
@@:
5776
        push    10h
5777
        push    0
5778
        push    aUnknownDriver
5779
        push    0
5780
        call    [MessageBoxA]
5781
        and     dword [esp+20h], 0
5782
        ret
5783
.not16:
5784
        cmp     ebx, 19
5785
        jnz     .not19
5786
; load DLL
5787
        sub     esp, 40
5788
        mov     eax, esp
5789
        sub     eax, [base]
5790
        push    0
5791
        push    0
5792
        push    eax
5793
        push    0
5794
        push    0
5795
        push    0
5796
        push    5
5797
        mov     ebx, esp
5798
        mov     [ebx+21], ecx
5799
        pushad
5800
        call    i40_file_system_lfn.noadd
5801
        popad
5802
        test    eax, eax
5803
        jz      @f
5804
.err1:
5805
        add     esp, 28+40
5806
        and     dword [esp+20h], 0
5807
        ret
5808
@@:
5809
        pop     eax
5810
        push    0
5811
        mov     ebx, esp
5812
        cmp     dword [ebx+28+36], 0
5813
        jnz     .err1
5814
        mov     eax, [ebx+28+32]
5815
        mov     [ebx+12], eax
5816
	call	malloc_big
5817
        test    eax, eax
5818
        jnz     @f
5819
.nomem_dll:
5820
        push    10h
5821
        push    memerr
5822
        push    aCannotLoadDll
5823
        push    0
5824
        call    [MessageBoxA]
5825
        jmp     .err1
5826
@@:
5827
        sub     eax, [base]
5828
        mov     [ebx+16], eax
5829
        push    ebx
5830
        pushad
5831
        call    i40_file_system_lfn.noadd
5832
        popad
5833
        pop     ebx
5834
        test    eax, eax
5835
        jnz     .err1
5836
        mov     eax, [ebx+16]
5837
        add     eax, [base]
5838
        mov     [ebx+16], eax
5839
        cmp     dword [eax], 'KPCK'
5840
        jnz     .notpacked
5841
	mov	eax, [eax+4]
5842
	call	malloc_big
5843
        test    eax, eax
5844
        jnz     @f
5845
        push    dword [ebx+16]
5846
        call    free_big
5847
        jmp     .nomem_dll
5848
@@:
5849
        push    eax
5850
        push    eax
5851
        push    dword [ebx+16]
5852
        call    unpack
5853
        push    dword [ebx+16]
5854
	call	free_big
5855
        pop     eax
5856
        mov     [ebx+16], eax
5857
.notpacked:
5858
        add     esp, 28+40
5859
; eax contains pointer to loaded file
5860
        mov     ebx, eax
5861
; 1. Calculate image size & allocate memory for image
5862
        movzx   ecx, word [eax+2]
5863
        lea     edx, [eax+20+16]
5864
        xor     esi, esi
5865
@@:
5866
        add     esi, [edx]
5867
	add	esi, 0xF
5868
	and	esi, not 0xF
5869
        add     edx, 40
5870
        loop    @b
5871
        pushad
5872
        call    .initialize_heap
5873
        mov     ecx, [esp+4]
5874
        call    .allocate_heap
5875
        popad
5876
        test    eax, eax
5877
        jnz     @f
5878
; no memory in user space, user has already been notified
5879
        and     dword [esp+20h], 0
5880
        ret
5881
@@:
5882
; eax = base addr in user space
5883
; ebx = pointer to loaded DLL data
5884
; 2. Copy image data
5885
        mov     edi, eax
5886
        add     edi, [base]
5887
        movzx   ecx, word [ebx+2]
5888
        lea     edx, [ebx+20+16]
5889
@@:
5890
        mov     [edx+12-16], edi
5891
        mov     esi, [edx+20-16]
5892
        test    esi, esi
5893
        jnz     .copy
5894
        add     edi, [edx+16-16]
5895
        jmp     .next
5896
.copy:
5897
        add     esi, ebx
5898
        push    ecx
5899
        mov     ecx, [edx+16-16]
5900
        rep     movsb
5901
        pop     ecx
5902
.next:
5903
        add     edi, 0xF
5904
        and     edi, not 0xF
5905
        add     edx, 40
5906
        loop    @b
5907
; 3. Fixup COFF symbols
5908
; symbols table = ebx + [ebx+8]
5909
; strings ptr = (symbols table)+[ebx+12]*18
5910
        mov     ecx, [ebx+12]
5911
        mov     edx, ebx
5912
        add     edx, [ebx+8]
5913
        lea     esi, [ecx+ecx*8]
5914
	lea	esi, [edx+esi*2]
5915
.fix_sym:
5916
        movsx   edi, word [edx+12]
5917
        test    edi, edi
5918
        jnz     .internal
5919
; current implementation does not support exports
5920
; this is kernel limitation, not my
5921
        and     dword [edx+8], 0
5922
        jmp     .next_sym
5923
.internal:
5924
	js	.next_sym
5925
        dec     edi
5926
        shl     edi, 3
5927
        lea     edi, [edi+edi*4]
5928
        mov     edi, [ebx+20+edi+12]
5929
        sub     edi, [base]
5930
        add     [edx+8], edi
5931
.next_sym:
5932
        add     edx, 18
5933
        loop    .fix_sym
5934
; 4. Fixup COFF relocations
5935
        movzx   ecx, word [ebx+2]
5936
        lea     esi, [ebx+20]
5937
.fix_sec_reloc:
5938
        mov     edi, [esi+24]
5939
        add     edi, ebx
5940
        push    ecx
5941
        movzx   ecx, word [esi+32]
5942
        jecxz   .next_sec_reloc
5943
.fix_reloc:
5944
        mov     edx, [edi+4]
5945
        lea     edx, [edx+edx*8]
5946
        lea     edx, [ebx+edx*2]
5947
        add     edx, [ebx+8]
5948
        mov     edx, [edx+8]
5949
        mov     eax, [edi]
5950
        add     eax, [esi+12]
5951
        cmp     word [edi+8], 6
5952
        jz      .dir32
5953
        cmp     word [edi+8], 20
5954
        jz      .rel32
5955
        pushad
5956
        push    30h
5957
        push    aWarning
5958
        push    aUnknownReloc
5959
        push    0
5960
        call    [MessageBoxA]
5961
        popad
5962
        jmp     .next_reloc
5963
.rel32:
5964
        sub     edx, eax
5965
        sub     edx, 4
5966
.dir32:
5967
        add     [eax], edx
5968
.next_reloc:
5969
        add     edi, 10
5970
        loop    .fix_reloc
5971
.next_sec_reloc:
5972
        add     esi, 40
5973
        pop     ecx
5974
        loop    .fix_sec_reloc
5975
; 5. Lookup 'EXPORTS' symbol
5976
        mov     eax, ebx
5977
        add     eax, [ebx+8]
5978
        mov     ecx, [ebx+12]
5979
.find_exp:
5980
        cmp     dword [eax], 'EXPO'
5981
        jnz     @f
5982
        cmp     dword [eax+4], 'RTS'
5983
        jz      .found_exp
5984
@@:
5985
        add     eax, 18
5986
        loop    .find_exp
5987
; 5b. Lookup '_EXPORTS' symbol
5988
	mov	eax, ebx
5989
	add	eax, [ebx+8]
5990
	mov	ecx, [ebx+12]
5991
.find__exp:
5992
	cmp	dword [eax], '_EXP'
5993
	jnz	@f
5994
	cmp	dword [eax+4], 'ORTS'
5995
	jz	.found_exp
5996
@@:
5997
	add	eax, 18
5998
	loop	.find__exp
5999
        push    30h
6000
        push    aWarning
6001
        push    aExportsNotFound
6002
        push    0
6003
        call    [MessageBoxA]
6004
        xor     eax, eax
6005
        jmp     @f
6006
.found_exp:
6007
        mov     eax, [eax+8]
6008
@@:
6009
        mov     [esp+20h], eax
6010
        push    ebx
6011
        call    free_big
6012
        ret
6013
.not19:
6014
        cmp     ebx, 20
6015
        jnz     .not20
6016
; reallocate memory block in heap
6017
        cmp     [heap_status], 0
6018
        jnz     @f
6019
        push    30h
6020
        push    aWarning
6021
        push    aHeapNotInited
6022
        push    0
6023
        call    [MessageBoxA]
6024
        and     dword [esp+20h], 0
6025
        ret
6026
@@:
6027
        cmp     [heap_status], 1
6028
        jnz     @f
6029
        push    ecx edx
6030
        push    5
6031
        call    [Sleep]
6032
        pop     edx ecx
6033
        jmp     @b
6034
@@:
6035
; realloc(NULL,sz) = malloc(sz)
6036
        test    edx, edx
6037
        jz      .allocate_heap
6038
        cmp     edx, [heap_region_size]
6039
        jae     .inv_exit_realloc
6040
        sub     edx, [heap_start]
6041
        jb      .inv_exit_realloc
6042
        cmp     edx, 0x1000
6043
        jb      .inv_exit_realloc
6044
        push    ecx edx
6045
        push    heap_critical_sec
6046
        call    [EnterCriticalSection]
6047
        pop     edx ecx
6048
        test    edx, 0xFFF
6049
        jnz     @f
6050
        shr     edx, 12
6051
        dec     edx
6052
        mov     esi, [heap_control_block]
6053
        mov     eax, [esi+edx*4]
6054
	test	al, 10h
6055
	jnz	@f
6056
        test    al, 8
6057
        jnz     .realloc_valid
6058
@@:
6059
        push    heap_critical_sec
6060
        call    [LeaveCriticalSection]
6061
        jmp     .inv_exit_realloc
6062
.realloc_valid:
6063
        add     ecx, 0x1FFF
6064
        and     ecx, not 0xFFF
6065
        and     eax, not 0xFFF
6066
        cmp     eax, ecx
6067
        jb      .realloc_inc
6068
        jz      .realloc_done
6069
        sub     eax, ecx
6070
        push    eax ecx edx
6071
        push    0x4000  ; MEM_DECOMMIT
6072
        push    eax
6073
        shl     edx, 12
6074
        add     edx, ecx
6075
        add     edx, [heap_start]
6076
        add     edx, [base]
6077
        push    edx
6078
        call    [VirtualFree]
6079
        test    eax, eax
6080
        jz      $
6081
        pop     edx ecx
6082
        mov     eax, ecx
6083
        cmp     eax, 0x1000
6084
        jz      .realloc_freeall
6085
        or      al, 8
6086
        mov     [esi+edx*4], eax
6087
        pop     eax
6088
        shr     ecx, 12
6089
        add     edx, ecx
6090
        mov     edi, [heap_region_size]
6091
        sub     edi, [heap_start]
6092
        shr     edi, 12
6093
        push    edx
6094
        mov     edx, eax
6095
        shr     edx, 12
6096
        add     edx, [esp]
6097
@@:
6098
        cmp     edx, edi
6099
        jae     @f
6100
        mov     ecx, [esi+edx*4]
6101
        test    cl, 4
6102
        jz      @f
6103
        and     dword [esi+edx*4], 0
6104
        and     ecx, not 0xFFF
6105
        add     eax, ecx
6106
        shr     ecx, 12
6107
        add     edx, ecx
6108
        jmp     @b
6109
@@:
6110
        pop     edx
6111
        or      al, 4
6112
        mov     [esi+edx*4], eax
6113
.realloc_done:
6114
        push    heap_critical_sec
6115
        call    [LeaveCriticalSection]
6116
        mov     eax, [esp+18h]
6117
        mov     [esp+20h], eax
6118
        ret
6119
.realloc_freeall:
6120
        pop     eax
6121
        xor     ecx, ecx
6122
        xor     eax, eax
6123
@@:
6124
        cmp     ecx, edx
6125
        jae     @f
6126
        mov     eax, [esi+ecx*4]
6127
        shr     eax, 12
6128
        add     ecx, eax
6129
        jmp     @b
6130
@@:
6131
        test    eax, eax
6132
        jz      @f
6133
        sub     ecx, eax
6134
        test    byte [esi+ecx*4], 4
6135
        jz      @f
6136
        xor     eax, eax
6137
        xchg    eax, [esi+edx*4]
6138
        and     eax, not 0xFFF
6139
        add     [esi+ecx*4], eax
6140
        mov     edx, ecx
6141
@@:
6142
        mov     eax, [esi+edx*4]
6143
        shr     eax, 12
6144
        add     eax, edx
6145
        mov     edi, [heap_region_size]
6146
        sub     edi, [heap_start]
6147
        shr     edi, 12
6148
        cmp     eax, edi
6149
        jae     @f
6150
        test    byte [esi+eax*4], 4
6151
        jz      @f
6152
        xor     ecx, ecx
6153
        xchg    ecx, [esi+eax*4]
6154
        and     ecx, not 0xFFF
6155
        add     [esi+edx*4], ecx
6156
@@:
6157
        mov     byte [esi+edx*4], 4
6158
        push    heap_critical_sec
6159
        call    [LeaveCriticalSection]
6160
        and     dword [esp+20h], 0
6161
        ret
6162
.realloc_inc:
6163
        mov     edi, [heap_region_size]
6164
        sub     edi, [heap_start]
6165
        shr     edi, 12
6166
        push    eax
6167
        shr     eax, 12
6168
        add     eax, edx
6169
        cmp     eax, edi
6170
        jae     .realloc_realloc
6171
        mov     eax, [esi+eax*4]
6172
        test    al, 4
6173
        jz      .realloc_realloc
6174
        and     eax, not 0xFFF
6175
        add     eax, [esp]
6176
        sub     eax, ecx
6177
        jb      .realloc_realloc
6178
; reallocate in place
6179
        jz      @f
6180
        push    ecx edx
6181
        shr     ecx, 12
6182
        add     edx, ecx
6183
        or      al, 4
6184
        mov     [esi+edx*4], eax
6185
        pop     edx ecx
6186
@@:
6187
        pop     eax
6188
        sub     ecx, eax
6189
        add     [esi+edx*4], ecx
6190
        mov     edi, edx
6191
        inc     edi
6192
        shl     edi, 12
6193
        add     edi, [heap_start]
6194
        mov     [esp+20h], edi
6195
        push    40h     ; PAGE_EXECUTE_READWRITE
6196
        push    1000h   ; MEM_COMMIT
6197
        push    ecx
6198
        shl     edx, 12
6199
        add     edx, eax
6200
        add     edx, [heap_start]
6201
        add     edx, [base]
6202
        push    edx
6203
        call    [VirtualAlloc]
6204
        test    eax, eax
6205
        jz      .nomem_fatal
6206
        push    heap_critical_sec
6207
        call    [LeaveCriticalSection]
6208
        ret
6209
.realloc_realloc:
6210
        pop     esi
6211
        push    ecx
6212
        push    heap_critical_sec
6213
        call    [LeaveCriticalSection]
6214
        pop     ecx
6215
        pushad
6216
        call    .allocate_heap
6217
        popad
6218
        mov     [esp+20h], eax
6219
        mov     edi, eax
6220
        test    edi, edi
6221
        jnz     @f
6222
        ret
6223
@@:
6224
        lea     ecx, [esi-0x1000]
6225
        mov     esi, [esp+18h]
6226
        push    esi
6227
        add     esi, [base]
6228
        add     edi, [base]
6229
        shr     ecx, 2
6230
        rep     movsd
6231
        pop     ecx
6232
        pushad
6233
        call    .free_heap
6234
        popad
6235
        ret
6236
.not20:
6237
	cmp	ebx, 22
6238
	jnz	.not22
6239
; open/create named memory area
6240
	test	esi, not 0xD
6241
	jnz	not_supported_i40_fn
6242
	add	ecx, [base]
6243
	mov	edi, ecx
6244
..server_create_shmem:
6245
	div	edx
6246
	test	eax, eax
6247
	jz	@f
6248
.shmem.err:
6249
	and	dword [esp+20h], 0
6250
	mov	[esp+18h], eax
6251
	ret
6252
@@:
6253
	pushad
6254
	call	.allocate_heap
6255
	popad
6256
	test	eax, eax
6257
	jnz	@f
6258
	mov	ecx, edi
6259
	call	..server_destroy_shmem
6260
	mov	al, 30
6261
	jmp	.shmem.err
6262
@@:
6263
	mov	[esp+20h], eax
6264
	mov	[esp+18h], edx
6265
	mov	ecx, eax
6266
	sub	ecx, [heap_start]
6267
	shr	ecx, 12
6268
	mov	edx, [heap_control_block]
6269
	or	byte [edx+(ecx-1)*4], 10h
6270
	add	eax, [base]
6271
..server_notify_shmem:
6272
	div	edx
6273
	push	eax
6274
	push	esp
6275
	push	1	; PAGE_NOACCESS
6276
	push	ecx
6277
	push	eax
6278
	call	[VirtualProtect]
6279
	pop	eax
6280
	ret
6281
.not22:
6282
	cmp	ebx, 23
6283
	jnz	not_supported_i40_fn
6284
	add	ecx, [base]
6285
	call	..server_destroy_shmem
6286
	jecxz	@f
6287
	sub	ecx, [base]
6288
	mov	eax, ecx
6289
	sub	eax, [heap_start]
6290
	shr	eax, 12
6291
	mov	edx, [heap_control_block]
6292
	and	byte [edx+(eax-1)*4], not 10h
6293
	pushad
6294
	call	.free_heap
6295
	popad
6296
	jmp	.ret22
6297
@@:
6298
	push	30h
6299
	push	aWarning
6300
	push	aCannotDestroyShMem
6301
	push	0
6302
	call	[MessageBoxA]
6303
.ret22:
6304
	mov	dword [esp+20h], 0x87654320
6305
	ret
6306
..server_destroy_shmem:
6307
	div	edx
6308
	ret
6309
 
6310
include 'unpacker.inc'
6311
 
6312
align 4
6313
debug_services_table:
6314
	dd	i40_debug_services.set_event_data
6315
	dd	i40_debug_services.getcontext
6316
	dd	i40_debug_services.setcontext
6317
	dd	not_supported_i40_fn	;i40_debug_services.detach
6318
	dd	i40_debug_services.suspend
6319
	dd	i40_debug_services.resume
6320
	dd	i40_debug_services.read_process_memory
6321
	dd	i40_debug_services.write_process_memory
6322
	dd	i40_debug_services.terminate
6323
;	dd	i40_debug_services.set_drx
6324
.size = ($ - debug_services_table)/4
6325
 
6326
i40_debug_services:
6327
	cmp	ebx, debug_services_table.size
6328
	jae	not_supported_i40_fn
6329
	jmp	dword [debug_services_table+ebx*4]
6330
.set_event_data:
6331
	call	get_cur_slot_ptr
6332
; atomic operation, no synchronization required
6333
	mov	[edi+shared_data_struc.debugger_mem-shared_data_struc.threads], ecx
6334
	ret
6335
.m1pop2:
6336
	pop	eax
6337
.m1pop:
6338
	pop	eax
6339
.m1:
6340
	or	dword [esp+20h], -1
6341
.ret:
6342
	ret
6343
.getcontext:
6344
	call	find_debuggee
6345
	test	ebx, ebx
6346
	jz	.ret
6347
	cmp	edx, 40
6348
	jnz	.ret
6349
	push	dword [ebx+12]
6350
	call	suspend_safe
6351
	sub	esp, 0xB2*4
6352
	push	1000Fh
6353
	mov	edi, esp
6354
	push	edi
6355
	push	dword [ebx+12]
6356
	call	[GetThreadContext]
6357
	add	esi, [base]
6358
	mov	ax, cs
6359
	cmp	word [edi+0xBC], ax
6360
	jz	.context_win
6361
	mov	eax, [edi+0xB8]
6362
	mov	[esi], eax
6363
	mov	eax, [edi+0xC0]
6364
	mov	[esi+4], eax
6365
	mov	eax, [edi+0xB0]
6366
	mov	[esi+8], eax
6367
	mov	eax, [edi+0xAC]
6368
	mov	[esi+12], eax
6369
	mov	eax, [edi+0xA8]
6370
	mov	[esi+16], eax
6371
	mov	eax, [edi+0xA4]
6372
	mov	[esi+20], eax
6373
	mov	eax, [edi+0xC4]
6374
	mov	[esi+24], eax
6375
	mov	eax, [edi+0xB4]
6376
	mov	[esi+28], eax
6377
	mov	eax, [edi+0xA0]
6378
	mov	[esi+32], eax
6379
	mov	eax, [edi+0x9C]
6380
	mov	[esi+36], eax
6381
	jmp	.gotcontext
6382
.context_win:
6383
	mov	eax, [ebx+16]
6384
	add	eax, tls._esp
6385
	sub	esp, 2Ch
6386
	mov	ecx, esp
6387
	push	0
6388
	push	esp
6389
	push	8
6390
	push	ecx
6391
	push	eax
6392
	push	dword [ebx+8]
6393
	call	[ReadProcessMemory]
6394
	pop	eax
6395
	pop	dword [esi+24]
6396
	pop	dword [esi]
6397
	mov	ecx, esp
6398
	push	0
6399
	push	esp
6400
	push	24h
6401
	push	ecx
6402
	push	dword [ebx+20]
6403
	push	dword [ebx+8]
6404
	call	[ReadProcessMemory]
6405
	pop	eax
6406
	pop	dword [esi+36]
6407
	pop	dword [esi+32]
6408
	pop	dword [esi+28]
6409
	pop	eax
6410
	pop	dword [esi+20]
6411
	pop	dword [esi+16]
6412
	pop	dword [esi+12]
6413
	pop	dword [esi+8]
6414
	pop	dword [esi+4]
6415
.gotcontext:
6416
	add	esp, 0xB3*4
6417
@@:
6418
	push	dword [ebx+12]
6419
	call	[ResumeThread]
6420
	ret
6421
.resume:
6422
	call	find_debuggee
6423
	test	ebx, ebx
6424
	jz	.ret
6425
	jmp	@b
6426
.suspend:
6427
	call	find_debuggee
6428
	test	ebx, ebx
6429
	jz	.ret
6430
	push	dword [ebx+12]
6431
	call	suspend_safe
6432
	ret
6433
.setcontext:
6434
	call	find_debuggee
6435
	test	ebx, ebx
6436
	jz	.ret
6437
	cmp	edx, 40
6438
	jnz	.ret
6439
	push	dword [ebx+12]
6440
	call	suspend_safe
6441
	sub	esp, 0xB2*4
6442
	push	1000Fh
6443
	mov	edi, esp
6444
	push	edi
6445
	push	dword [ebx+12]
6446
	call	[GetThreadContext]
6447
	add	esi, [base]
6448
	mov	ax, cs
6449
	cmp	word [edi+0xBC], ax
6450
	jz	.context_win_set
6451
	lodsd
6452
	mov	[edi+0xB8], eax
6453
	lodsd
6454
	mov	[edi+0xC0], eax
6455
	lodsd
6456
	mov	[edi+0xB0], eax
6457
	lodsd
6458
	mov	[edi+0xAC], eax
6459
	lodsd
6460
	mov	[edi+0xA8], eax
6461
	lodsd
6462
	mov	[edi+0xA4], eax
6463
	lodsd
6464
	mov	[edi+0xC4], eax
6465
	lodsd
6466
	mov	[edi+0xB4], eax
6467
	lodsd
6468
	mov	[edi+0xA0], eax
6469
	lodsd
6470
	mov	[edi+0x9C], eax
6471
	push	edi
6472
	push	dword [ebx+12]
6473
	call	[SetThreadContext]
6474
	jmp	.setcontextdone
6475
.context_win_set:
6476
	mov	edx, [ebx+16]
6477
	add	edx, tls._esp
6478
	lodsd
6479
	push	eax
6480
	push	dword [esi-4+24]
6481
	mov	ecx, esp
6482
	push	0
6483
	push	esp
6484
	push	8
6485
	push	ecx
6486
	push	eax
6487
	push	dword [ebx+8]
6488
	call	[WriteProcessMemory]
6489
	pop	eax
6490
	pop	eax
6491
	pop	eax
6492
	push	9
6493
	pop	ecx
6494
@@:
6495
	lodsd
6496
	push	eax
6497
	loop	@b
6498
	mov	ecx, esp
6499
	push	0
6500
	push	esp
6501
	push	24h
6502
	push	ecx
6503
	push	dword [ebx+20]
6504
	push	dword [ebx+8]
6505
	call	[WriteProcessMemory]
6506
	add	esp, 4+24h
6507
.setcontextdone:
6508
	add	esp, 0xB3*4
6509
	push	dword [ebx+12]
6510
	call	[ResumeThread]
6511
	ret
6512
.write_process_memory:
6513
	push	[WriteProcessMemory]
6514
	jmp	@f
6515
.read_process_memory:
6516
	push	[ReadProcessMemory]
6517
@@:
6518
	call	find_debuggee
6519
	test	ebx, ebx
6520
	jz	.m1pop
6521
; get base and limit of target process
6522
	push	eax
6523
	push	eax
6524
	mov	eax, esp
6525
	push	edx
6526
	push	0
6527
	push	esp
6528
	push	8
6529
	push	eax
6530
	push	base
6531
	push	dword [ebx+8]
6532
	call	[ReadProcessMemory]
6533
	pop	eax
6534
	pop	edx
6535
	pop	ecx	; ecx = [base] for target process
6536
	cmp	eax, 8
6537
	jnz	.m1pop2
6538
	pop	eax	; eax = [limit] for target process
6539
	push	edx
6540
	inc	eax
6541
	add	edx, esi
6542
	sub	edx, eax
6543
	jc	@f
6544
	sub	dword [esp], edx
6545
	jnc	@f
6546
	and	dword [esp], 0
6547
@@:
6548
	add	esi, ecx
6549
	pop	edx
6550
	pop	ecx
6551
	xor	eax, eax
6552
	test	edx, edx
6553
	jz	@f
6554
	push	-1
6555
	push	esp
6556
	add	edi, [base]
6557
	push	edx
6558
	push	edi
6559
	push	esi
6560
	push	dword [ebx+8]
6561
	call	ecx
6562
	pop	eax
6563
@@:
6564
	mov	[esp+20h], eax
6565
	ret
6566
.terminate:
6567
	call	find_debuggee
6568
	test	ebx, ebx
6569
	jnz	i40_sys_service.kill
6570
	ret
6571
.set_drx:
6572
	sub	esp, 0xB2*4
6573
	push	1001Fh
6574
	call	find_debuggee
6575
	test	ebx, ebx
6576
	jz	.ret1
6577
	mov	edi, esp
6578
	push	ecx edx
6579
	push	edi
6580
	push	dword [ebx+12]
6581
	call	[GetThreadContext]
6582
	pop	edx ecx
6583
	test	dh, dh
6584
	js	.clear
6585
; set hardware breakpoint, dl=index (0..3), dh=(length*4)+(condition), esi=address
6586
	cmp	esi, 0x80000000
6587
	jae	.ret1
6588
	cmp	dl, 4
6589
	jae	.ret1
6590
	test	dh, 0xF0
6591
	jnz	.ret1
6592
	mov	al, dh
6593
	and	al, 3
6594
	cmp	al, 2
6595
	jz	.ret1
6596
	movzx	eax, dh
6597
	shr	al, 2
6598
	cmp	al, 2
6599
	jz	.ret1
6600
	test	esi, eax
6601
	jnz	.ret1
6602
	push	edx
6603
	push	0
6604
	mov	eax, esp
6605
	push	eax
6606
	push	esp
6607
	push	4
6608
	push	eax
6609
	push	base
6610
	push	dword [ebx+8]
6611
	call	[ReadProcessMemory]
6612
	pop	eax
6613
	pop	eax
6614
	pop	edx
6615
	add	esi, eax
6616
	or	byte [edi+18h+1], 3	; set GE and LE flags
6617
	movzx	eax, dh
6618
	movzx	ecx, dl
6619
	add	ecx, ecx
6620
	bts	dword [edi+18h], ecx	; set L flag
6621
	mov	[edi+4+ecx*2], esi	; set DR
6622
	shl	eax, cl
6623
	mov	edx, 0xF
6624
	shl	edx, cl
6625
	not	edx
6626
	and	[edi+18h+2], dx
6627
	or	[edi+18h+2], ax		; set R/W and LEN fields
6628
	jmp	.set_and_ret
6629
.clear:
6630
	movzx	ecx, dl
6631
	add	ecx, ecx
6632
	btr	dword [edi+18h], ecx	; clear L flag
6633
.set_and_ret:
6634
	push	edi
6635
	push	dword [ebx+12]
6636
	call	[SetThreadContext]
6637
	add	esp, 0xB3*4
6638
	and	dword [esp+20h], 0
6639
	ret
6640
.ret1:
6641
	add	esp, 0xB3*4
6642
	push	30h
6643
	push	aWarning
6644
	push	aInvalidDataForDR
6645
	push	0
6646
	call	[MessageBoxA]
6647
	mov	dword [esp+20h], 1
6648
	ret
6649
 
6650
find_debuggee:
6651
	lea	ebx, [ebp+tls.debuggees]
6652
@@:
6653
	mov	ebx, [ebx]
6654
	test	ebx, ebx
6655
	jz	@f
6656
	cmp	dword [ebx+4], ecx
6657
	jnz	@b
6658
@@:
6659
	ret
6660
 
6661
suspend_safe:
6662
	xchg	ebx, [esp+4]
6663
.redo:
6664
	push	ebx
6665
	call	[SuspendThread]
6666
	sub	esp, 0xB2*4
6667
	push	1000Fh
6668
	push	esp
6669
	push	ebx
6670
	call	[GetThreadContext]
6671
	mov	ax, cs
6672
	cmp	word [context+0xBC], ax
6673
	jnz	.ok
6674
	cmp	dword [context+0xB8], i40_nt
6675
	jz	.wait
6676
	cmp	dword [context+0xB8], i40_9x
6677
	jb	.test2
6678
	cmp	dword [context+0xB8], safe_to_suspend
6679
	ja	.test2
6680
.wait:
6681
	add	esp, 0xB3*4
6682
	push	ebx
6683
	call	[ResumeThread]
6684
	push	50
6685
	call	[Sleep]
6686
	jmp	.redo
6687
.test2:
6688
	cmp	dword [context+0xB8], i40_done
6689
	jb	.ok
6690
	cmp	dword [context+0xB8], not_supported_i40_fn
6691
	jb	.wait
6692
.ok:
6693
	add	esp, 0xB3*4
6694
	xchg	ebx, [esp+4]
6695
	ret	4
6696
 
6697
rootdirs:
6698
        db      2,'rd'
6699
        dd      fs_OnRamdisk
6700
        dd      fs_NextRamdisk
6701
        db      7,'ramdisk'
6702
        dd      fs_OnRamdisk
6703
        dd      fs_NextRamdisk
6704
;        db      2,'fd'
6705
;        dd      fs_OnFloppy
6706
;        dd      fs_NextFloppy
6707
;        db      10,'floppydisk'
6708
;        dd      fs_OnFloppy
6709
;        dd      fs_NextFloppy
6710
        db      3,'hd0'
6711
        dd      fs_OnHd0
6712
        dd      fs_NextHd0
6713
        db      3,'hd1'
6714
        dd      fs_OnHd1
6715
        dd      fs_NextHd1
6716
        db      3,'hd2'
6717
        dd      fs_OnHd2
6718
        dd      fs_NextHd2
6719
        db      3,'hd3'
6720
        dd      fs_OnHd3
6721
        dd      fs_NextHd3
6722
        db      0
6723
 
6724
virtual_root_query:
6725
        dd      fs_HasRamdisk
6726
        db      'rd',0
6727
;        dd      fs_HasFloppy
6728
;        db      'fd',0
6729
        dd      fs_HasHd0
6730
        db      'hd0',0
6731
        dd      fs_HasHd1
6732
        db      'hd1',0
6733
        dd      fs_HasHd2
6734
        db      'hd2',0
6735
        dd      fs_HasHd3
6736
        db      'hd3',0
6737
        dd      0
6738
 
6739
i40_file_system_lfn:
6740
        add     ebx, [base]
6741
.noadd:
6742
        push    0
6743
; parse file name
6744
        lea     esi, [ebx+20]
6745
        lodsb
6746
        test    al, al
6747
        jnz     @f
6748
        mov     esi, [esi]
6749
        add     esi, [base]
6750
        lodsb
6751
        jmp     @f
6752
.parse:
6753
        push    edi
6754
        lodsb
6755
@@:
6756
	push	0
6757
        cmp     al, '/'
6758
        jz      @f
6759
	dec	esi
6760
	mov	dword [esp], esi
6761
	mov	esi, [ebp+tls.cur_dir]
6762
	inc	esi
6763
	jmp	@f
6764
.notfound:
6765
	pop	eax
6766
        pop     eax
6767
        test    eax, eax
6768
        mov     eax, 5                  ; file not found
6769
        jnz     .notfound_retparse
6770
        mov     [esp+20h], eax
6771
.notfound_retparse:
6772
        ret
6773
@@:
6774
	mov	eax, [esi]
6775
	or	eax, '   '
6776
	cmp	eax, 'sys'
6777
	jz	.sys1
6778
	cmp	eax, 'sys/'
6779
	jnz	@f
6780
	inc	esi
6781
.sys1:
6782
	mov	eax, ramdisk_path
6783
	add	esi, 3
6784
	jmp	fs_common
6785
@@:
6786
        cmp     byte [esi], 0
6787
        jz      .rootdir
6788
        mov     edi, rootdirs-8
6789
        xor     ecx, ecx
6790
        push    esi
6791
.scan1:
6792
        pop     esi
6793
        add     edi, ecx
6794
        scasd
6795
        scasd
6796
        mov     cl, byte [edi]
6797
        jecxz   .notfound
6798
        inc     edi
6799
        push    esi
6800
@@:
6801
        lodsb
6802
        or      al, 20h
6803
        scasb
6804
        loopz   @b
6805
        jnz     .scan1
6806
        lodsb
6807
        cmp     al, '/'
6808
        jz      .found1
6809
        test    al, al
6810
        jnz     .scan1
6811
        pop     eax
6812
; directory /xxx
6813
.maindir:
6814
	pop	eax
6815
        pop     eax
6816
        test    eax, eax
6817
        jz      @f
6818
.parse_access_denied:
6819
        mov     eax, 10         ; access denied
6820
        ret
6821
@@:
6822
        cmp     dword [ebx], 1
6823
        jnz     .access_denied
6824
        xor     eax, eax
6825
        push    dword [ebx+12]
6826
        mov     edx, [ebx+16]
6827
        add     edx, [base]
6828
        push    dword [ebx+4]   ; first block
6829
        mov     ebx, [ebx+8]    ; flags
6830
        and     ebx, 1
6831
        mov     esi, [edi+4]
6832
; [esp]=first block, [esp+4]=number of blocks, ebx=flags, edx=return area, esi='Next' handler
6833
        mov     edi, edx
6834
        mov     ecx, 32/4
6835
        rep     stosd
6836
        mov     byte [edx], 1   ; version
6837
.maindir_loop:
6838
        call    esi
6839
        jc      .maindir_done
6840
        inc     dword [edx+8]
6841
        dec     dword [esp]
6842
        jns     .maindir_loop
6843
        dec     dword [esp+4]
6844
        js      .maindir_loop
6845
        inc     dword [edx+4]
6846
        mov     dword [edi], 0x10       ; attributes: folder
6847
        mov     dword [edi+4], ebx      ; name type
6848
        push    eax
6849
        xor     eax, eax
6850
        add     edi, 8
6851
        mov     ecx, 40/4-2
6852
        rep     stosd
6853
        pop     eax
6854
        push    eax edx
6855
; convert number in eax to decimal ANSI/UNICODE string
6856
        push    edi
6857
        push    -'0'
6858
        mov     cl, 10
6859
@@:
6860
        xor     edx, edx
6861
        div     ecx
6862
        push    edx
6863
        test    eax, eax
6864
        jnz     @b
6865
@@:
6866
        pop     eax
6867
        add     al, '0'
6868
        stosb
6869
        pushf
6870
        test    bl, 1
6871
        jz      .ansi_name
6872
        xor     eax, eax
6873
        stosb
6874
.ansi_name:
6875
        popf
6876
        jnz     @b
6877
        pop     edi
6878
        add     edi, 520
6879
        test    bl, 1
6880
        jnz     @f
6881
        sub     edi, 520-264
6882
@@:
6883
        pop     edx eax
6884
        jmp     .maindir_loop
6885
.maindir_done:
6886
        mov     ebx, [edx+4]
6887
        xor     eax, eax
6888
        pop     ecx ecx
6889
        dec     ecx
6890
        js      @f
6891
        mov     al, 6
6892
@@:
6893
        mov     [esp+20h], eax
6894
        mov     [esp+14h], ebx
6895
        ret
6896
; directory /
6897
.rootdir:
6898
	pop	eax
6899
        pop     eax
6900
        test    eax, eax
6901
        jnz     .parse_access_denied
6902
        cmp     dword [ebx], 1  ; read folder?
6903
        jz      .readroot
6904
.access_denied:
6905
        mov     dword [esp+20h], 10      ; access denied
6906
        ret
6907
 
6908
.readroot:
6909
; virtual root folder - special handler
6910
        mov     esi, virtual_root_query
6911
        push    dword [ebx+12]
6912
        mov     edx, [ebx+16]
6913
        add     edx, [base]
6914
        push    dword [ebx+4]
6915
        mov     ebx, [ebx+8]
6916
        xor     eax, eax
6917
; eax=0, [esp]=first block, [esp+4]=number of blocks, ebx=flags, edx=return area
6918
        mov     edi, edx
6919
        mov     ecx, 32/4
6920
        rep     stosd
6921
        mov     byte [edx], 1   ; version
6922
.readroot_loop:
6923
        cmp     dword [esi], eax
6924
        jz      .readroot_done
6925
        call    dword [esi]
6926
        add     esi, 4
6927
        test    eax, eax
6928
        jnz     @f
6929
.readroot_next:
6930
        or      ecx, -1
6931
        xchg    esi, edi
6932
        repnz   scasb
6933
        xchg    esi, edi
6934
        jmp     .readroot_loop
6935
@@:
6936
        xor     eax, eax
6937
        inc     dword [edx+8]
6938
        dec     dword [esp]
6939
        jns     .readroot_next
6940
        dec     dword [esp+4]
6941
        js      .readroot_next
6942
        inc     dword [edx+4]
6943
        mov     dword [edi], 0x10       ; attributes: folder
6944
        mov     dword [edi+4], ebx      ; name type
6945
        add     edi, 8
6946
        push    40/4-2
6947
        pop     ecx
6948
        rep     stosd
6949
        push    edi
6950
@@:
6951
        lodsb
6952
        stosb
6953
        test    bl, 1
6954
        jz     .ansi_name2
6955
        mov     byte [edi], 0
6956
        inc     edi
6957
.ansi_name2:
6958
        test    eax, eax
6959
        jnz     @b
6960
        pop     edi
6961
        add     edi, 520
6962
        test    bl, 1
6963
        jnz     @f
6964
        sub     edi, 520-264
6965
@@:
6966
        jmp     .readroot_loop
6967
.readroot_done:
6968
        mov     ebx, [edx+4]
6969
        xor     eax, eax
6970
        pop     ecx ecx
6971
        dec     ecx
6972
        js      @f
6973
        mov     al, 6
6974
@@:
6975
        mov     [esp+20h], eax
6976
        mov     [esp+14h], ebx
6977
        ret
6978
 
6979
.found1:
6980
        pop     eax
6981
        cmp     byte [esi], 0
6982
        jz      .maindir
6983
; read partition number
6984
        xor     ecx, ecx
6985
        xor     eax, eax
6986
@@:
6987
        lodsb
6988
        cmp     al, '/'
6989
        jz      .done1
6990
        test    al, al
6991
        jz      .done1
6992
        sub     al, '0'
6993
        cmp     al, 9
6994
        ja      .notfound
6995
        imul    ecx, 10
6996
        add     ecx, eax
6997
        jmp     @b
6998
.done1:
6999
        test    ecx, ecx
7000
        jz      .notfound
7001
        test    al, al
7002
        jnz     @f
7003
        dec     esi
7004
@@:
7005
; now [edi] contains handler address, ecx - partition number,
7006
; esi points to ASCIIZ string - rest of name
7007
        jmp     dword [edi]
7008
 
7009
fs_NextRamdisk:
7010
        test    eax, eax
7011
        stc
7012
        jnz     @f
7013
        mov     al, 1
7014
        clc
7015
@@:     ret
7016
 
7017
fs_NextHd0:
7018
        push    0
7019
        jmp     fs_NextHd
7020
fs_NextHd1:
7021
        push    1
7022
        jmp     fs_NextHd
7023
fs_NextHd2:
7024
        push    2
7025
        jmp     fs_NextHd
7026
fs_NextHd3:
7027
        push    3
7028
fs_NextHd:
7029
        pop     ecx
7030
        mov     ecx, [hd_partitions_num+ecx*4]
7031
        cmp     eax, ecx
7032
        jae     .no
7033
        inc     eax
7034
        clc
7035
        ret
7036
.no:
7037
        stc
7038
        ret
7039
 
7040
fs_HasRamdisk:
7041
        mov     al, 1
7042
        ret
7043
 
7044
fs_HasHd0:
7045
        cmp     [hd_partitions_num], 0
7046
        setnz   al
7047
        ret
7048
fs_HasHd1:
7049
        cmp     [hd_partitions_num+4], 0
7050
        setnz   al
7051
        ret
7052
fs_HasHd2:
7053
        cmp     [hd_partitions_num+8], 0
7054
        setnz   al
7055
        ret
7056
fs_HasHd3:
7057
        cmp     [hd_partitions_num+12], 0
7058
        setnz   al
7059
        ret
7060
 
7061
fs_OnRamdisk:
7062
        cmp     ecx, 1
7063
        jnz     i40_file_system_lfn.notfound
7064
        mov     eax, ramdisk_path
7065
        jmp     fs_common
7066
 
7067
fs_OnHd0:
7068
        push    0
7069
        jmp     fs_OnHd
7070
fs_OnHd1:
7071
        push    1
7072
        jmp     fs_OnHd
7073
fs_OnHd2:
7074
        push    2
7075
        jmp     fs_OnHd
7076
fs_OnHd3:
7077
        push    3
7078
fs_OnHd:
7079
        pop     eax
7080
        cmp     ecx, [hd_partitions_num+eax*4]
7081
        jbe     @f
7082
        pop     eax eax
7083
        test    eax, eax
7084
        mov     eax, 5
7085
.hderr:
7086
        jnz     .ret
7087
        mov     dword [esp+20h], eax
7088
.ret:
7089
        ret
7090
@@:
7091
	dec	ecx
7092
        mov     eax, [hd_partitions_array+eax*4]
7093
        shl     ecx, 9
7094
        add     eax, ecx
7095
        cmp     byte [eax+511], 0
7096
        jz      fs_common
7097
; readonly disk - allow only subfunctions 0,1,5,7
7098
        cmp     dword [ebx], 0
7099
        jz      fs_common
7100
        cmp     dword [ebx], 1
7101
        jz      fs_common
7102
        cmp     dword [ebx], 5
7103
        jz      fs_common
7104
        cmp     dword [ebx], 7
7105
        jz      fs_common
7106
; access denied!
7107
        pop     eax eax
7108
        test    eax, eax
7109
        mov     eax, 10
7110
        jmp     .hderr
7111
fs_common:
7112
	pop	ecx
7113
        pop     edi
7114
        test    edi, edi
7115
        jnz     @f
7116
        sub     esp, 204h
7117
        mov     edi, esp
7118
@@:
7119
	push	ecx
7120
        push    eax
7121
        push    edi
7122
        call    [lstrcpyA]
7123
        push    edi
7124
        call    [lstrlenA]
7125
	pop	ecx
7126
        push    edi
7127
        add     edi, eax
7128
        sub     eax, 204h
7129
        neg     eax
7130
	push	ecx
7131
        push    eax
7132
        push    esi
7133
        push    edi
7134
        call    [lstrcpynA]
7135
	pop	ecx
7136
	jecxz	.slash_pass
7137
	cmp	byte [ecx], 0
7138
	jz	.slash_pass
7139
	mov	esi, ecx
7140
	push	edi
7141
	call	[lstrlenA]
7142
	add	edi, eax
7143
	mov	eax, edi
7144
	sub	eax, [esp]
7145
	sub	eax, 204h
7146
	neg	eax
7147
	push	eax
7148
	push	esi
7149
	push	edi
7150
	call	[lstrcpynA]
7151
.slash_pass:
7152
        mov     al, [edi]
7153
        test    al, al
7154
        jz      .slash_pass_done
7155
        cmp     al, '\'
7156
        jz      .invalid
7157
        cmp     al, '/'
7158
        jnz     @f
7159
        mov     al, '\'
7160
@@:
7161
        stosb
7162
        jmp     .slash_pass
7163
.slash_pass_done:
7164
; delete trailing slashes, if present
7165
        dec     edi
7166
        cmp     byte [edi], '\'
7167
        jz      .slash_pass_done
7168
        inc     edi
7169
        stosb
7170
; but do not delete one slash in X:\
7171
        pop     edi
7172
        cmp     byte [edi+1], ':'
7173
        jnz     @f
7174
        cmp     byte [edi+2], 0
7175
        jnz     @f
7176
        mov     word [edi+2], '\'
7177
@@:
7178
        push    edi
7179
        push    edi
7180
        call    [OemToCharA]
7181
; now edi -> Win32 path
7182
        cmp     edi, esp
7183
        jz      fs_do
7184
        xor     eax, eax
7185
        ret
7186
.invalid:
7187
        pop     edi
7188
        cmp     edi, esp
7189
        jnz     @f
7190
        add     esp, 204h
7191
        mov     dword [esp+20h], 5      ; file not found
7192
        ret
7193
@@:
7194
        push    5
7195
        pop     eax
7196
        ret
7197
fs_do:
7198
        cmp     dword [ebx], 10
7199
        jb      @f
7200
fs_unsupported:
7201
        add     esp, 204h
7202
        jmp     not_supported_i40_fn
7203
@@:
7204
        push    edi
7205
        call    [GetFileAttributesA]
7206
        mov     ecx, dword [ebx]
7207
        jmp     dword [i40_fs_subfunctions + ecx*4]
7208
 
7209
i40_fs_subfunctions:
7210
        dd      fs_read
7211
        dd      fs_read_folder
7212
        dd      fs_rewrite
7213
        dd      fs_write
7214
        dd      fs_setsize
7215
        dd      fs_getattr
7216
        dd      fs_setattr
7217
        dd      fs_execute
7218
        dd      fs_delete
7219
        dd      fs_makedir
7220
 
7221
fs_read:
7222
        inc     eax
7223
        jnz     @f
7224
        add     esp, 204h
7225
        mov     dword [esp+20h], 5      ; file not found
7226
        or      dword [esp+14h], -1
7227
        ret
7228
@@:
7229
        dec     eax
7230
        test    al, 10h         ; FILE_ATTRIBUTE_DIRECTORY
7231
        jz      @f
7232
        add     esp, 204h
7233
.access_denied:
7234
        mov     dword [esp+20h], 10     ; access denied
7235
        or      dword [esp+14h], -1
7236
        ret
7237
@@:
7238
        push    0
7239
        push    0
7240
        push    3
7241
        push    0
7242
        push    1
7243
        push    80000000h
7244
        push    edi
7245
        call    [CreateFileA]
7246
        add     esp, 204h
7247
        inc     eax
7248
        jz      .access_denied
7249
        dec     eax
7250
        xchg    eax, esi
7251
        push    dword [ebx+8]
7252
        mov     eax, esp
7253
        push    0
7254
        push    eax
7255
        push    dword [ebx+4]
7256
        push    esi
7257
        call    [SetFilePointer]
7258
        inc     eax
7259
        jnz     @f
7260
        call    [GetLastError]
7261
        test    eax, eax
7262
        jz      @f
7263
        pop     eax
7264
        mov     dword [esp+20h], 6      ; EOF
7265
        and     dword [esp+14h], 0      ; no bytes read
7266
        push    esi
7267
        call    [CloseHandle]
7268
        ret
7269
@@:
7270
        mov     eax, esp
7271
        push    0
7272
        push    eax
7273
;        mov     eax, [limit]
7274
;        inc     eax
7275
;        sub     eax, [ebx+16]
7276
;        cmp     eax, [ebx+12]
7277
;        jb      @f
7278
;        mov     eax, [ebx+12]
7279
;@@:
7280
;        push    eax
7281
        push    dword [ebx+12]
7282
        mov     eax, [ebx+16]
7283
        add     eax, [base]
7284
        push    eax
7285
        push    esi
7286
        call    [ReadFile]
7287
        pop     ecx
7288
        xor     eax, eax
7289
        cmp     ecx, [ebx+12]
7290
        jz      @f
7291
        mov     al, 6   ; EOF
7292
@@:
7293
        mov     [esp+20h], eax
7294
        mov     [esp+14h], ecx  ; bytes read
7295
        push    esi
7296
        call    [CloseHandle]
7297
        ret
7298
 
7299
fs_read_folder:
7300
        inc     eax
7301
        jnz     @f
7302
        add     esp, 204h
7303
        mov     dword [esp+20h], 5      ; file not found
7304
        or      dword [esp+14h], -1
7305
        ret
7306
@@:
7307
        push    edi
7308
        call    [lstrlenA]
7309
        cmp     eax, 202h
7310
        jb      @f
7311
        add     esp, 204h
7312
        mov     dword [esp+20h], 5
7313
        or      dword [esp+14h], -1
7314
        ret
7315
@@:
7316
        cmp     byte [edi+eax-1], '/'
7317
        jz      @f
7318
        cmp     byte [edi+eax-1], '\'
7319
        jz      @f
7320
        mov     byte [edi+eax], '/'
7321
        inc     eax
7322
@@:
7323
        mov     word [edi+eax], '*'
7324
        cmp     byte [esi], 0
7325
        mov     esi, 2
7326
        jz      @f
7327
        xor     esi, esi
7328
@@:
7329
        sub     esp, 140h       ; sizeof(WIN32_FIND_DATAA)
7330
        push    esp
7331
        push    edi
7332
        call    [FindFirstFileA]
7333
        inc     eax
7334
        jnz     @f
7335
        add     esp, 140h+204h
7336
        mov     dword [esp+20h], 10     ; access denied
7337
        or      dword [esp+14h], -1
7338
        ret
7339
@@:
7340
        dec     eax
7341
        push    dword [ebx+8]   ; flags
7342
        push    dword [ebx+4]   ; 1st block
7343
        push    dword [ebx+12]  ; number of blocks
7344
        mov     edi, [ebx+16]   ; buffer
7345
        add     edi, [base]
7346
        push    edi
7347
        xchg    eax, ebx
7348
        mov     ecx, 32/4
7349
        xor     eax, eax
7350
        rep     stosd
7351
        mov     byte [edi-32], 1        ; version
7352
.loop:
7353
        test    esi, 2
7354
        jz      .noroot
7355
        cmp     word [esp+16+44], '.'
7356
        jz      .cont
7357
        cmp     word [esp+16+44], '..'
7358
        jnz     .noroot
7359
        cmp     byte [esp+16+46], 0
7360
        jz      .cont
7361
.noroot:
7362
        pop     eax
7363
        push    eax
7364
        inc     dword [eax+8]   ; new file found
7365
        dec     dword [esp+8]
7366
        jns     .cont
7367
        dec     dword [esp+4]
7368
        js      .cont
7369
        inc     dword [eax+4]   ; new file copied
7370
        mov     eax, [esp+16]   ; attributes
7371
        and     eax, 3Fh
7372
        stosd
7373
        mov     al, [esp+12]    ; name type
7374
        and     eax, 1
7375
        stosd
7376
        lea     eax, [esp+16+4]
7377
        call    get_bdfe_time
7378
        lea     eax, [esp+16+12]
7379
        call    get_bdfe_time
7380
        lea     eax, [esp+16+20]
7381
        call    get_bdfe_time
7382
        mov     eax, [esp+16+32]
7383
        stosd
7384
        mov     eax, [esp+16+28]
7385
        stosd
7386
        lea     eax, [esp+16+44]
7387
        test    byte [esp+12], 1
7388
        jz      .name_ansi
7389
        push    260
7390
        push    edi
7391
        push    -1
7392
        push    eax
7393
        push    0
7394
        push    0
7395
        call    [MultiByteToWideChar]
7396
        add     edi, 260*2
7397
        jmp     .cont
7398
.name_ansi:
7399
        push    edi
7400
        push    eax
7401
        call    [CharToOemA]
7402
        add     edi, 264
7403
.cont:
7404
        lea     eax, [esp+16]
7405
        push    eax
7406
        push    ebx
7407
        call    [FindNextFileA]
7408
        test    eax, eax
7409
        jnz     .loop
7410
        push    ebx
7411
        call    [FindClose]
7412
        pop     edx
7413
        mov     ebx, [edx+4]
7414
        xor     eax, eax
7415
        pop     ecx
7416
        dec     ecx
7417
        js      @f
7418
        mov     al, 6
7419
@@:
7420
        add     esp, 140h+204h+8
7421
        mov     [esp+20h], eax
7422
        mov     [esp+14h], ebx
7423
        ret
7424
 
7425
get_bdfe_time:
7426
        sub     esp, 10h
7427
        push    esp
7428
        push    eax
7429
        call    [FileTimeToSystemTime]
7430
        mov     ax, [esp+8]
7431
        shl     eax, 16
7432
        mov     ah, [esp+10]
7433
        mov     al, [esp+12]
7434
        stosd
7435
        mov     ax, [esp+0]
7436
        shl     eax, 16
7437
        mov     ah, [esp+2]
7438
        mov     al, [esp+6]
7439
        stosd
7440
        add     esp, 10h
7441
        ret
7442
from_bdfe_time:
7443
        sub     esp, 10h
7444
        xor     eax, eax
7445
        lodsb
7446
        mov     [esp+12], ax
7447
        lodsb
7448
        mov     [esp+10], ax
7449
        lodsw
7450
        mov     [esp+8], ax
7451
        mov     ah, 0
7452
        lodsb
7453
        mov     [esp+6], ax
7454
        lodsb
7455
        mov     [esp+2], ax
7456
        lodsw
7457
        mov     [esp+0], ax
7458
        mov     eax, esp
7459
        push    edi
7460
        push    eax
7461
        call    [SystemTimeToFileTime]
7462
        add     esp, 10h
7463
        add     edi, 8
7464
        ret
7465
 
7466
fs_rewrite:
7467
        push    0
7468
        push    80h
7469
        push    2
7470
        push    0
7471
        push    0
7472
        push    40000000h
7473
        push    edi
7474
        call    [CreateFileA]
7475
        add     esp, 204h
7476
        inc     eax
7477
        jnz     @f
7478
        mov     dword [esp+20h], 10
7479
        and     dword [esp+14h], 0
7480
        ret
7481
@@:
7482
        dec     eax
7483
        xchg    eax, esi
7484
        push    eax
7485
        mov     eax, esp
7486
        push    0
7487
        push    eax
7488
        push    dword [ebx+12]
7489
        mov     eax, [ebx+16]
7490
        add     eax, [base]
7491
        push    eax
7492
        push    esi
7493
        call    [WriteFile]
7494
        pop     ebx
7495
        push    esi
7496
        call    [CloseHandle]
7497
        and     dword [esp+20h], 0
7498
        mov     [esp+14h], ebx
7499
        ret
7500
 
7501
fs_write:
7502
        inc     eax
7503
        jnz     @f
7504
        add     esp, 204h
7505
        mov     dword [esp+20h], 5      ; file not found
7506
        or      dword [esp+14h], -1
7507
        ret
7508
@@:
7509
        dec     eax
7510
        test    al, 10h         ; FILE_ATTRIBUTE_DIRECTORY
7511
        jz      @f
7512
        add     esp, 204h
7513
.access_denied:
7514
        mov     dword [esp+20h], 10     ; access denied
7515
        or      dword [esp+14h], -1
7516
        ret
7517
@@:
7518
        push    0
7519
        push    0
7520
        push    3
7521
        push    0
7522
        push    1
7523
        push    40000000h
7524
        push    edi
7525
        call    [CreateFileA]
7526
        add     esp, 204h
7527
        inc     eax
7528
        jz      .access_denied
7529
        dec     eax
7530
        xchg    eax, esi
7531
        push    dword [ebx+8]
7532
        mov     eax, esp
7533
        push    0
7534
        push    eax
7535
        push    dword [ebx+4]
7536
        push    esi
7537
        call    [SetFilePointer]
7538
        inc     eax
7539
        jnz     @f
7540
        call    [GetLastError]
7541
        test    eax, eax
7542
        jz      @f
7543
        pop     eax
7544
        mov     dword [esp+20h], 6      ; EOF
7545
        and     dword [esp+14h], 0      ; no bytes read
7546
        push    esi
7547
        call    [CloseHandle]
7548
        ret
7549
@@:
7550
        mov     eax, esp
7551
        push    0
7552
        push    eax
7553
        mov     eax, [limit]
7554
        inc     eax
7555
        sub     eax, [ebx+16]
7556
        cmp     eax, [ebx+12]
7557
        jb      @f
7558
        mov     eax, [ebx+12]
7559
@@:
7560
        push    eax
7561
        mov     eax, [ebx+16]
7562
        add     eax, [base]
7563
        push    eax
7564
        push    esi
7565
        call    [WriteFile]
7566
        pop     ecx
7567
        xor     eax, eax
7568
        cmp     ecx, [ebx+12]
7569
        jz      @f
7570
        mov     al, 6   ; EOF
7571
@@:
7572
        mov     [esp+20h], eax
7573
        mov     [esp+14h], ecx  ; bytes read
7574
        push    esi
7575
        call    [CloseHandle]
7576
        ret
7577
 
7578
fs_setsize:
7579
        inc     eax
7580
        jnz     @f
7581
        add     esp, 204h
7582
        mov     dword [esp+20h], 5      ; file not found
7583
        or      dword [esp+14h], -1
7584
        ret
7585
@@:
7586
        dec     eax
7587
        test    al, 10h         ; FILE_ATTRIBUTE_DIRECTORY
7588
        jz      @f
7589
        add     esp, 204h
7590
.access_denied:
7591
        mov     dword [esp+20h], 10     ; access denied
7592
        or      dword [esp+14h], -1
7593
        ret
7594
@@:
7595
        push    0
7596
        push    0
7597
        push    3
7598
        push    0
7599
        push    1
7600
        push    40000000h
7601
        push    edi
7602
        call    [CreateFileA]
7603
        add     esp, 204h
7604
        inc     eax
7605
        jz      .access_denied
7606
        dec     eax
7607
        xchg    eax, esi
7608
        push    dword [ebx+8]
7609
        mov     eax, esp
7610
        push    0
7611
        push    eax
7612
        push    dword [ebx+4]
7613
        push    esi
7614
        call    [SetFilePointer]
7615
        inc     eax
7616
        jnz     @f
7617
        call    [GetLastError]
7618
        test    eax, eax
7619
        jz      @f
7620
        pop     eax
7621
        mov     dword [esp+20h], 6      ; EOF
7622
        mov     dword [esp+14h], 1234567h       ; destroy ebx
7623
        push    esi
7624
        call    [CloseHandle]
7625
        ret
7626
@@:
7627
        pop     ecx
7628
        push    esi
7629
        call    [SetEndOfFile]
7630
        and     dword [esp+20h], 0
7631
        mov     dword [esp+14h], 234567h        ; destroy ebx
7632
        push    esi
7633
        call    [CloseHandle]
7634
        ret
7635
 
7636
fs_getattr:
7637
        inc     eax
7638
        jnz     @f
7639
.notfound:
7640
        add     esp, 204h
7641
        mov     dword [esp+20h], 5      ; file not found
7642
.ret_destroy_ebx:
7643
        mov     dword [esp+14h], 12345678h
7644
        ret
7645
@@:
7646
; Win32 does not allow to read attributes of root directories through FindFirstFile.
7647
; Moreover, on FAT systems the root directory simply does not contain attributes.
7648
; The current kernel implementation in Kolibri returns error eax = 2.
7649
; Let it be.
7650
        cmp     word [edi+1], ':\'
7651
        jnz     @f
7652
        cmp     byte [edi+3], 0
7653
        jnz     @f
7654
; The program requests root directory. Return eax=2.
7655
; N.B. All previous words are related to the case when Kolibri-disk is mapped to
7656
;      real disk, /hdi/j = N:\. Otherwise, it is possible to get real attributes
7657
;      of root directory, and emulator will do so (in another branch).
7658
        add     esp, 204h
7659
        mov     dword [esp+20h], 2
7660
        jmp     .ret_destroy_ebx
7661
@@:
7662
        sub     esp, 140h       ; sizeof(WIN32_FIND_DATAA)
7663
        push    esp
7664
        push    edi
7665
        call    [FindFirstFileA]
7666
        inc     eax
7667
        jnz     @f
7668
        add     esp, 140h+204h
7669
        mov     dword [esp+20h], 10     ; access denied
7670
        mov     dword [esp+14h], 12345678h
7671
        ret
7672
@@:
7673
        dec     eax
7674
        push    eax
7675
        call    [FindClose]
7676
        mov     edi, [ebx+16]
7677
        add     edi, [base]
7678
        pop     eax             ; attributes
7679
        and     eax, 3Fh
7680
        stosd
7681
        xor     eax, eax
7682
        stosd
7683
        mov     eax, esp
7684
        call    get_bdfe_time
7685
        lea     eax, [esp+12-4]
7686
        call    get_bdfe_time
7687
        lea     eax, [esp+20-4]
7688
        call    get_bdfe_time
7689
        mov     eax, [esp+32-4]
7690
        stosd
7691
        mov     eax, [esp+28-4]
7692
        stosd
7693
        add     esp, 140h-4+204h
7694
        and     dword [esp+20h], 0
7695
        mov     dword [esp+14h], 12345678h
7696
        ret
7697
 
7698
fs_setattr:
7699
        inc     eax
7700
        jz      fs_getattr.notfound
7701
        mov     esi, [ebx+16]
7702
        add     esi, [base]
7703
        lodsd
7704
        push    eax     ; remember attributes
7705
        push    80h     ; FILE_ATTRIBUTE_NORMAL
7706
        push    edi
7707
        call    [SetFileAttributesA]
7708
        push    0
7709
        push    0
7710
        push    3       ; OPEN_EXISTING
7711
        push    0
7712
        push    3       ; FILE_SHARE_READ | FILE_SHARE_WRITE
7713
        push    0x40000000      ; GENERIC_WRITE
7714
        push    edi
7715
        call    [CreateFileA]
7716
        mov     ebx, eax
7717
        inc     eax
7718
        jnz     @f
7719
        push    edi
7720
        call    [SetFileAttributesA]
7721
        add     esp, 204h
7722
        mov     dword [esp+20h], 10
7723
        ret
7724
@@:
7725
        lodsd
7726
        sub     esp, 8*3
7727
        mov     edi, esp
7728
        call    from_bdfe_time
7729
        call    from_bdfe_time
7730
        call    from_bdfe_time
7731
        lea     eax, [esp+16]
7732
        push    eax
7733
        sub     eax, 8
7734
        push    eax
7735
        sub     eax, 8
7736
        push    eax
7737
        push    ebx
7738
        call    [SetFileTime]
7739
        add     esp, 8*3
7740
        push    ebx
7741
        call    [CloseHandle]
7742
        push    edi
7743
        call    [SetFileAttributesA]
7744
        add     esp, 204h
7745
        and     dword [esp+20h], 0
7746
        ret
7747
 
7748
fs_execute:
7749
        inc     eax
7750
        jnz     @f
7751
        add     esp, 204h
7752
        mov     dword [esp+20h], -5     ; file not found
7753
        or      dword [esp+14h], -1
7754
        ret
7755
@@:
7756
	mov	eax, [ebx+4]
7757
        mov     esi, [ebx+8]
7758
        call    notify_run_prg
7759
        add     esp, 204h
7760
        mov     [esp+20h], eax
7761
        mov     dword [esp+14h], 23456789h
7762
        ret
7763
 
7764
fs_delete:
7765
        inc     eax
7766
        jnz     @f
7767
        add     esp, 204h
7768
        mov     dword [esp+20h], 5      ; file not found
7769
.ret:
7770
        mov     dword [esp+14h], 0x12345678
7771
        ret
7772
@@:
7773
        dec     eax
7774
        test    al, 10h
7775
        jnz     .directory
7776
        push    edi
7777
        call    [DeleteFileA]
7778
@@:
7779
        add     esp, 204h
7780
        and     dword [esp+20h], 0
7781
        test    eax, eax
7782
        jnz     .ret
7783
        mov     byte [esp+20h], 10      ; access denied
7784
        jmp     .ret
7785
.directory:
7786
        push    edi
7787
        call    [RemoveDirectoryA]
7788
        jmp     @b
7789
 
7790
fs_makedir:
7791
        push    0
7792
        push    edi
7793
        call    [CreateDirectoryA]
7794
        add     esp, 204h
7795
        and     dword [esp+20h], 0
7796
        test    eax, eax
7797
        jnz     @f
7798
        call	[GetLastError]
7799
        cmp	eax, 183	; ERROR_ALREADY_EXISTS
7800
        jz	@f
7801
        mov     byte [esp+20h], 10
7802
@@:
7803
        ret
7804
 
7805
i40_window_settings:
7806
        cmp     ebx, 1
7807
        jnz     not_supported_i40_fn
7808
        mov     [ebp+tls.caption], ecx
7809
        or      byte [ebp+tls.color_main+3], 10h
7810
        push    [ebp+tls.hWnd]
7811
        call    [GetDC]
7812
        push    eax
7813
        push    [ebp+tls.hWnd]
7814
        mov     edi, eax
7815
; redraw caption
7816
	mov	al, byte [ebp+tls.color_main+3]
7817
	and	eax, 0xF
7818
	dec	eax
7819
	js	.type1
7820
	jz	.nodraw
7821
	dec	eax
7822
	jz	.type2
7823
	call    draw_caption_skinned
7824
.str:
7825
	call    draw_caption_string
7826
.nodraw:
7827
        call    [ReleaseDC]
7828
        ret
7829
.type1:
7830
        call    draw_caption_type1
7831
        jmp     .str
7832
.type2:
7833
        call    draw_caption_type2
7834
        jmp     .str