Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
990 barsuk 1
#include "kosSyst.h"
2
#include "func.h"
3
#include 
4
 
5
#define atexitBufferSize	32
6
 
1764 clevermous 7
// Autobuild uses FASM method for exe->kos,
8
// MENUET01 header should be present in EXE.
9
#ifdef AUTOBUILD
10
char kosExePath[1024];
11
char exeStack[16384];
12
// must be alphabetically first in the image
13
#pragma data_seg(".1seg")
14
extern "C" struct
15
{
16
	char header[8];
17
	int headerver;
18
	void* entry;
19
	void* i_end;
20
	void* memsize;
21
	void* stack;
22
	void* params;
23
	void* icon;
24
} header = {
25
	{'M', 'E', 'N', 'U', 'E', 'T', '0', '1'},
26
	1,
27
	&crtStartUp,
28
	0,	// filled by doexe2.asm
29
	0,	// filled by doexe2.asm
30
	exeStack + sizeof(exeStack),
31
	NULL,
32
	kosExePath
33
};
34
#pragma data_seg()
35
#else
36
char *kosExePath = NULL;
37
#endif
990 barsuk 38
 
39
char pureCallMessage[] = "PURE function call!";
40
 
41
//
42
void (__cdecl *atExitList[atexitBufferSize])();
43
int atExitFnNum = 0;
44
//
45
int __cdecl atexit( void (__cdecl *func )( void ))
46
{
47
	//
48
	if ( atExitFnNum < atexitBufferSize )
49
	{
50
		//
51
		atExitList[atExitFnNum++] = func;
52
		return 0;
53
	}
54
	else
55
	{
56
		return 1;
57
	}
58
}
59
 
60
 
61
//
62
Dword RandomSeed = 1;
63
//
64
void rtlSrand( Dword seed )
65
{
66
	RandomSeed = seed;
67
}
68
//
69
Dword rtlRand( void )
70
{
71
  //маска 0x80000776
72
 
73
  Dword dwi, i;
74
 
75
  for ( i = 0; i < 32; i++ )
76
  {
77
 
78
    dwi = RandomSeed & 0x80000776;
79
 
80
      __asm{
81
            mov   eax, dwi
82
            mov   edx, eax
83
            bswap eax
84
            xor   eax, edx
85
            xor   al, ah
86
            setpo al
87
            movzx eax, al
88
            mov   dwi, eax
89
    }
90
 
91
    RandomSeed = ( RandomSeed << 1 ) | ( dwi & 1 );
92
  }
93
 
94
 return RandomSeed;
95
}
96
 
1764 clevermous 97
#ifdef AUTOBUILD
98
// Well, not really related to auto-build, but some compilation issue
99
void memcpy( void *dst, const void *src, size_t bytesCount )
990 barsuk 100
{
101
	__asm{
102
		mov edi, dst
1764 clevermous 103
//		mov eax, dst
990 barsuk 104
		mov esi, src
105
		mov ecx, bytesCount
106
		rep movsb
107
	}
108
}
109
 
110
//
111
void memset( Byte *dst, Byte filler, Dword count )
112
{
113
	//
114
	__asm{
115
		mov edi, dst
116
		mov al, filler
117
		mov ecx, count
118
		rep stosb
119
	}
1764 clevermous 120
}
121
#endif
990 barsuk 122
 
123
 
124
//
125
Dword rtlInterlockedExchange( Dword *target, Dword value )
126
{
127
//	Dword result;
128
 
129
	//
130
	__asm{
131
		mov eax, value
132
		mov ebx, target
133
		xchg eax, [ebx]
134
//		mov result, eax
135
	}
136
	//
137
//	return result;
138
}
139
 
140
 
141
//////////////////////////////////////////////////////////////////////
142
//
143
// копирование строки
144
//
145
 
146
char * __cdecl strcpy( char *target, const char *source )
147
{
148
	char *result = target;
149
 
150
	while( target[0] = source[0] )
151
	{
152
		target++;
153
		source++;
154
	}
155
 
156
	return result;
157
}
158
 
159
 
160
//////////////////////////////////////////////////////////////////////
161
//
162
// реверсивный поиск символа
163
//
164
 
165
char * __cdecl strrchr( const char * string, int c )
166
{
167
	char *cPtr;
168
 
169
	//
170
	for ( cPtr = (char *)string + strlen( string ); cPtr >= string; cPtr-- )
171
	{
172
		//
173
		if ( *cPtr == c ) return cPtr;
174
	}
175
	//
176
	return NULL;
177
}
178
 
179
 
180
//////////////////////////////////////////////////////////////////////
181
//
182
// определение длины строки
183
//
184
 
185
int __cdecl strlen( const char *line )
186
{
187
  int i;
188
 
189
  for( i=0; line[i] != 0; i++ );
190
  return i;
191
}
192
 
193
 
194
 
195
//////////////////////////////////////////////////////////////////////
196
//
197
// перевод шестнадцатиричного числа в символ
198
//
199
 
200
unsigned int num2hex( unsigned int num )
201
{
202
  if( num < 10 )
203
    return num + '0';
204
  return num - 10 + 'A';
205
}
206
 
207
 
208
//////////////////////////////////////////////////////////////////////
209
//
210
// вывод строки на печать. barsuk добавил %f
211
 
212
//#define PREC 2
213
//#define HALF 0.499
214
#define PREC 6
215
#define HALF 0.4999999
216
 
217
double double_tab[]={1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
218
1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, 1e30};
219
 
220
 
221
//
222
 
223
Dword dectab[] = { 1000000000, 100000000, 10000000, 1000000, 100000,
224
                   10000, 1000, 100, 10, 0 };
225
 
226
//
227
void sprintf( char *Str, char* Format, ... )
228
{
229
	int i, fmtlinesize, j, k, flag;
230
	Dword head, tail;
231
	char c;
232
	va_list arglist;
233
	//
234
	va_start(arglist, Format);
235
 
236
	//
237
	fmtlinesize = strlen( Format );
238
	//
239
	if( fmtlinesize == 0 ) return;
240
 
241
	//
242
	for( i = 0, j = 0; i < fmtlinesize; i++ )
243
	{
244
		//
245
		c = Format[i];
246
		//
247
		if( c != '%' )
248
		{
249
			Str[j++] = c;
250
			continue;
251
		}
252
		//
253
		i++;
254
		//
255
		if( i >= fmtlinesize ) break;
256
 
257
		//
258
		flag = 0;
259
		//
260
		c = Format[i];
261
		//
262
		switch( c )
263
		{
264
		//
265
		case '%':
266
			Str[j++] = c;
267
			break;
268
		// вывод строки
269
		case 'S':
270
			Byte* str;
271
			str = va_arg(arglist, Byte*);
272
			for( k = 0; ( c = str[k] ) != 0; k++ )
273
			{
274
				Str[j++] = c;
275
			}
276
			break;
277
		// вывод байта
278
		case 'B':
279
			k = va_arg(arglist, int) & 0xFF;
280
			Str[j++] = num2hex( ( k >> 4 ) & 0xF );
281
			Str[j++] = num2hex( k & 0xF );
282
			break;
283
		// вывод символа
284
		case 'C':
285
			Str[j++] = va_arg(arglist, int) & 0xFF;
286
			break;
287
		// вывод двойного слова в шестнадцатиричном виде
288
		case 'X':
289
			Dword val;
290
			val = va_arg(arglist, Dword);
291
			for( k = 7; k >= 0; k-- )
292
			{
293
				//
294
				c = num2hex ( ( val >> (k * 4) ) & 0xF );
295
				//
296
				if( c == '0' )
297
				{
298
					if( flag ) Str[j++] = c;
299
				}
300
				else
301
				{
302
					flag++;
303
					Str[j++] = c;
304
				}
305
			}
306
			//
307
			if( flag == 0 ) Str[j++] = '0';
308
			break;
309
		// вывод двойного слова в десятичном виде
310
		case 'U':
311
			head = va_arg(arglist, Dword);
312
			tail = 0;
313
			for( k = 0; dectab[k] != 0; k++ )
314
			{
315
				tail = head % dectab[k];
316
				head /= dectab[k];
317
				c = head + '0';
318
				if( c == '0' )
319
				{
320
					if( flag ) Str[j++] = c;
321
				}
322
				else
323
				{
324
					flag++;
325
					Str[j++] = c;
326
				}
327
				//
328
				head = tail;
329
			}
330
			//
331
			c = head + '0';
332
			Str[j++] = c;
333
			break;
334
		// вещественное число в формате 7.2
335
		case 'f':
336
		case 'F':
337
		case 'g':
338
		case 'G':
339
			{
340
			double val, w;
341
			int p;
342
			val = va_arg(arglist, double);
343
			if (val < 0.0)
344
			{
345
				Str[j++] = '-';
346
				val = -val;
347
			}
348
			for (k = 0; k < 30; k++)
349
				if (val < double_tab[k])
350
					break;
351
 
352
			if (val < 1.0)
353
			{
354
				Str[j++] = '0';
355
			}
356
 
357
			for (p = 1; p < k + 1; p++)
358
			{
359
				int d = (int)di(val / double_tab[k - p] - HALF) % 10;
360
				Str[j++] = '0' + d;
361
				val -= d * double_tab[k - p];
362
			}
363
			Str[j++] = '.';
364
			w = 0.1;
365
			for (p = 0; p < PREC - 1; p++)
366
			{
367
				val-=floor(val);
368
				Str[j++] = '0' + di(val / w - HALF) % 10;
369
				w /= 10.0;
370
			}
371
			}
372
			break;
373
 
374
		// вывод 64-битного слова в шестнадцатиричном виде
375
		case 'Q':
376
			unsigned int low_dword, high_dword;
377
			low_dword = va_arg(arglist, unsigned int);
378
			high_dword = va_arg(arglist, unsigned int);
379
			for( k = 7; k >= 0; k-- )
380
			{
381
				//
382
				c = num2hex ( ( ( high_dword + 1) >> (k * 4) ) & 0xF );
383
				//
384
				if( c == '0' )
385
				{
386
					if( flag ) Str[j++] = c;
387
				}
388
				else
389
				{
390
					flag++;
391
					Str[j++] = c;
392
				}
393
			}
394
			//
395
			for( k=7; k >= 0; k-- )
396
			{
397
				//
398
				c = num2hex ( ( low_dword >> (k * 4) ) & 0xF );
399
				//
400
				if( c == '0' )
401
				{
402
					if( flag ) Str[j++] = c;
403
				}
404
				else
405
				{
406
					flag++;
407
					Str[j++] = c;
408
				}
409
			}
410
			//
411
			if( flag == 0 ) Str[j++] = '0';
412
			//
413
			break;
414
		//
415
		default:
416
			break;
417
		}
418
	}
419
	//
420
	Str[j] = 0;
421
}
422
 
423
 
424
// функция -1 завершения процесса
425
void kos_ExitApp()
426
{
427
	int i;
428
 
429
	//
430
	for ( i = atExitFnNum - 1; i >= 0; i-- )
431
	{
432
		//
433
		atExitList[i]();
434
	}
435
	//
436
	__asm{
437
		mov eax, -1
438
		int 0x40
439
	}
440
}
441
 
442
 
443
// функция 0
444
void kos_DefineAndDrawWindow(
445
	Word x, Word y,
446
	Word sizeX, Word sizeY,
447
	Byte mainAreaType,
448
	Dword mainAreaColour,
449
	Byte headerType,
450
	Dword headerColour,
451
	Dword borderColour
452
	)
453
{
454
	Dword arg1, arg2, arg3, arg4;
455
 
456
	//
457
	arg1 = ( x << 16 ) + sizeX;
458
	arg2 = ( y << 16 ) + sizeY;
459
	arg3 = ( mainAreaType << 24 ) | mainAreaColour;
460
	arg4 = ( headerType << 24 ) | headerColour;
461
	//
462
	__asm{
463
		mov eax, 0
464
		mov ebx, arg1
465
		mov ecx, arg2
466
		mov edx, arg3
467
		mov esi, arg4
468
		mov edi, borderColour
469
		int 0x40
470
	}
471
}
472
 
473
 
474
// функция 1 поставить точку
475
void kos_PutPixel( Dword x, Dword y, Dword colour )
476
{
477
	//
478
	__asm{
479
		mov eax, 1
480
		mov ebx, x
481
		mov ecx, y
482
		mov edx, colour
483
		int 0x40
484
	}
485
}
486
 
487
 
488
// функция 2 получить код нажатой клавиши
489
bool kos_GetKey( Byte &keyCode )
490
{
491
	Dword result;
492
 
493
	//
494
	__asm{
495
		mov eax, 2
496
		int 0x40
497
		mov result, eax
498
	}
499
	//
500
	keyCode = result >> 8;
501
	//
502
	return ( result & 0xFF ) == 0;
503
}
504
 
505
 
506
// функция 3 получить время
507
Dword kos_GetSystemClock()
508
{
509
//	Dword result;
510
 
511
	//
512
	__asm{
513
		mov eax, 3
514
		int 0x40
515
//		mov result, eax
516
	}
517
	//
518
//	return result;
519
}
520
 
521
 
522
// функция 4
523
void kos_WriteTextToWindow(
524
	Word x,
525
	Word y,
526
	Byte fontType,
527
	Dword textColour,
528
	char *textPtr,
529
	Dword textLen
530
	)
531
{
532
	Dword arg1, arg2;
533
 
534
	//
535
	arg1 = ( x << 16 ) | y;
536
	arg2 = ( fontType << 24 ) | textColour;
537
	//
538
	__asm{
539
		mov eax, 4
540
		mov ebx, arg1
541
		mov ecx, arg2
542
		mov edx, textPtr
543
		mov esi, textLen
544
		int 0x40
545
	}
546
}
547
 
548
 
549
// функция 5 пауза, в сотых долях секунды
550
void kos_Pause( Dword value )
551
{
552
	//
553
	__asm{
554
		mov eax, 5
555
		mov ebx, value
556
		int 0x40
557
	}
558
}
559
 
560
 
561
// функция 7 нарисовать изображение
562
void kos_PutImage( RGB * imagePtr, Word sizeX, Word sizeY, Word x, Word y )
563
{
564
	Dword arg1, arg2;
565
 
566
	//
567
	arg1 = ( sizeX << 16 ) | sizeY;
568
	arg2 = ( x << 16 ) | y;
569
	//
570
	__asm{
571
		mov eax, 7
572
		mov ebx, imagePtr
573
		mov ecx, arg1
574
		mov edx, arg2
575
		int 0x40
576
	}
577
}
578
 
579
 
580
 
581
// функция 8 определить кнопку
582
void kos_DefineButton( Word x, Word y, Word sizeX, Word sizeY, Dword buttonID, Dword colour )
583
{
584
	Dword arg1, arg2;
585
 
586
	//
587
	arg1 = ( x << 16 ) | sizeX;
588
	arg2 = ( y << 16 ) | sizeY;
589
	//
590
	__asm{
591
		mov eax, 8
592
		mov ebx, arg1
593
		mov ecx, arg2
594
		mov edx, buttonID
595
		mov esi, colour
596
		int 0x40
597
	}
598
}
599
 
600
 
601
// функция 9 - информация о процессе
602
Dword kos_ProcessInfo( sProcessInfo *targetPtr, Dword processID )
603
{
604
//	Dword result;
605
 
606
	//
607
	__asm{
608
		mov eax, 9
609
		mov ebx, targetPtr
610
		mov ecx, processID
611
		int 0x40
612
//		mov result, eax
613
	}
614
	//
615
//	return result;
616
}
617
 
618
 
619
// функция 10
620
Dword kos_WaitForEvent()
621
{
622
//	Dword result;
623
 
624
	__asm{
625
		mov eax, 10
626
		int 0x40
627
//		mov result, eax
628
	}
629
 
630
//	return result;
631
}
632
 
633
 
634
// функция 11
635
Dword kos_CheckForEvent()
636
{
637
//	Dword result;
638
 
639
	__asm{
640
		mov eax, 11
641
		int 0x40
642
//		mov result, eax
643
	}
644
 
645
//	return result;
646
}
647
 
648
 
649
// функция 12
650
void kos_WindowRedrawStatus( Dword status )
651
{
652
	__asm{
653
		mov eax, 12
654
		mov ebx, status
655
		int 0x40
656
	}
657
}
658
 
659
 
660
// функция 13 нарисовать полосу
661
void kos_DrawBar( Word x, Word y, Word sizeX, Word sizeY, Dword colour )
662
{
663
	Dword arg1, arg2;
664
 
665
	//
666
	arg1 = ( x << 16 ) | sizeX;
667
	arg2 = ( y << 16 ) | sizeY;
668
	//
669
	__asm{
670
		mov eax, 13
671
		mov ebx, arg1
672
		mov ecx, arg2
673
		mov edx, colour
674
		int 0x40
675
	}
676
}
677
 
678
 
679
// функция 17
680
bool kos_GetButtonID( Dword &buttonID )
681
{
682
	Dword result;
683
 
684
	//
685
	__asm{
686
		mov eax, 17
687
		int 0x40
688
		mov result, eax
689
	}
690
	//
691
	buttonID = result >> 8;
692
	//
693
	return (result & 0xFF) == 0;
694
}
695
 
696
 
697
// функция 23
698
Dword kos_WaitForEvent( Dword timeOut )
699
{
700
//	Dword result;
701
 
702
	__asm{
703
		mov eax, 23
704
		mov ebx, timeOut
705
		int 0x40
706
//		mov result, eax
707
	}
708
 
709
//	return result;
710
}
711
 
712
 
713
// получение информации о состоянии "мыши" функция 37
714
void kos_GetMouseState( Dword & buttons, int & cursorX, int & cursorY )
715
{
716
	Dword mB;
717
	Word curX;
718
	Word curY;
719
	sProcessInfo sPI;
720
 
721
	//
722
	__asm{
723
		mov		eax, 37
724
		mov		ebx, 0
725
		int		0x40
726
		mov		curY, ax
727
		shr		eax, 16
728
		mov		curX, ax
729
		mov		eax, 37
730
		mov		ebx, 2
731
		int		0x40
732
		mov		mB, eax
733
	}
734
	//
735
	kos_ProcessInfo( &sPI );
736
	//
737
	buttons = mB;
738
	cursorX = curX - sPI.processInfo.x_start;
739
	cursorY = curY - sPI.processInfo.y_start;
740
}
741
 
742
 
743
// функция 40 установить маску событий
744
void kos_SetMaskForEvents( Dword mask )
745
{
746
	//
747
	__asm{
748
		mov eax, 40
749
		mov ebx, mask
750
		int 0x40
751
	}
752
}
753
 
754
 
755
// функция 47 вывести в окно приложения число
756
void kos_DisplayNumberToWindow(
757
   Dword value,
758
   Dword digitsNum,
759
   Word x,
760
   Word y,
761
   Dword colour,
762
   eNumberBase nBase,
763
   bool valueIsPointer
764
   )
765
{
766
	Dword arg1, arg2;
767
 
768
	//
769
	arg1 = ( valueIsPointer ? 1 : 0 ) |
770
		( ((Byte)nBase) << 8 ) |
771
		( ( digitsNum & 0x1F ) << 16 );
772
	arg2 = ( x << 16 ) | y;
773
	//
774
	__asm{
775
		mov eax, 47
776
		mov ebx, arg1
777
		mov ecx, value
778
		mov edx, arg2
779
		mov esi, colour
780
		int 0x40
781
	}
782
}
783
 
784
 
785
// функция 70 доступ к файловой системе
786
Dword kos_FileSystemAccess( kosFileInfo *fileInfo )
787
{
788
//	Dword result;
789
 
790
	//
791
	__asm{
792
		mov eax, 70
793
		mov ebx, fileInfo
794
		int 0x40
795
//		mov result, eax
796
	}
797
	//
798
//	return result;
799
}
800
 
801
 
802
// функция 63 вывод символя в окно отладки
803
void kos_DebugOutChar( char ccc )
804
{
805
	//
806
	__asm{
807
		mov eax, 63
808
		mov ebx, 1
809
		mov cl, ccc
810
		int 0x40
811
	}
812
}
813
 
814
 
815
// функция 66 режим получения данных от клавиатуры
816
void kos_SetKeyboardDataMode( Dword mode )
817
{
818
	//
819
	__asm{
820
		mov eax, 66
821
		mov ebx, 1
822
		mov ecx, mode
823
		int 0x40
824
	}
825
}
826
 
827
 
828
// вывод строки в окно отладки
829
void rtlDebugOutString( char *str )
830
{
831
	//
832
	for ( ; str[0] != 0; str++ )
833
	{
834
		kos_DebugOutChar( str[0] );
835
	}
836
	//
837
	kos_DebugOutChar( 13 );
838
	kos_DebugOutChar( 10 );
839
}
840
 
841
 
842
// функция 64 изменение количества памяти, выделенной для программы
843
bool kos_ApplicationMemoryResize( Dword targetSize )
844
{
845
	Dword result;
846
 
847
	//
848
	__asm{
849
		mov eax, 64
850
		mov ebx, 1
851
		mov ecx, targetSize
852
		int 0x40
853
		mov result, eax
854
	}
855
	//
856
	return result == 0;
857
}
858
 
859
 
860
// функция 67 изменить параметры окна, параметр == -1 не меняется
861
void kos_ChangeWindow( Dword x, Dword y, Dword sizeX, Dword sizeY )
862
{
863
	//
864
	__asm{
865
		mov eax, 67
866
		mov ebx, x
867
		mov ecx, y
868
		mov edx, sizeX
869
		mov esi, sizeY
870
		int 0x40
871
	}
872
}
873
 
874
void kos_InitHeap()
875
{
876
	__asm{
877
		mov eax, 68
878
		mov ebx, 11
879
		int 0x40
880
	}
881
}
882
 
883
 
884
 
885
// вызов абстрактного метода
886
int __cdecl _purecall()
887
{
888
	rtlDebugOutString( pureCallMessage );
889
	kos_ExitApp();
890
	return 0;
891
}
892
 
893
 
894
// вызов статических инициализаторов
895
// заодно инициализация генератора случайных чисел
896
//#pragma section(".CRT$XCA",long,read,write)
897
//#pragma section(".CRT$XCZ",long,read,write)
898
#pragma data_seg(".CRT$XCA")
899
#pragma data_seg(".CRT$XCZ")
900
typedef void (__cdecl *_PVFV)(void);
1764 clevermous 901
//__declspec(allocate(".CRT$XCA"))  _PVFV __xc_a[1] = { NULL };
902
//__declspec(allocate(".CRT$XCZ"))  _PVFV __xc_z[1] = { NULL };
990 barsuk 903
//
1764 clevermous 904
extern void ALMOST_HALF_init();
990 barsuk 905
#pragma comment(linker, "/merge:.CRT=.rdata")
906
//
907
void crtStartUp()
908
{
1764 clevermous 909
#ifdef AUTOBUILD
910
// linker will try to remove unused variables; force header to be included
911
	header.header;
912
#endif
990 barsuk 913
	// вызываем инициализаторы по списку, NULL'ы игнорируем
1764 clevermous 914
	/*for ( _PVFV *pbegin = __xc_a; pbegin < __xc_z; pbegin++ )
990 barsuk 915
	{
916
		//
917
		if ( *pbegin != NULL )
918
			(**pbegin)();
1764 clevermous 919
	}*/
920
	ALMOST_HALF_init();
990 barsuk 921
	// инициализируем генератор случайных чисел
922
	rtlSrand( kos_GetSystemClock() );
1764 clevermous 923
#ifndef AUTOBUILD
990 barsuk 924
	// путь к файлу процесса
925
	kosExePath = *((char **)0x20);
1764 clevermous 926
#endif
990 barsuk 927
	// вызов главной функции приложения
928
	kos_Main();
929
	// выход
930
	kos_ExitApp();
931
}
932