diff --git a/programs/other/krule/KosFile.cpp b/programs/other/krule/KosFile.cpp new file mode 100644 index 0000000000..1bf8c33fcd --- /dev/null +++ b/programs/other/krule/KosFile.cpp @@ -0,0 +1,131 @@ +#include "kosSyst.h" +#include "kosfile.h" + + +CKosFile::CKosFile(char *fileName) +{ + // + this->fileInfo.bufferPtr = new Byte[FILE_BUFFER_SIZE]; + // + this->filePointer = 0; + this->bufferPointer = 0; + this->validBuffer = false; + // + strcpy( this->fileInfo.fileURL, fileName ); +} + + +CKosFile::~CKosFile(void) +{ + // + delete this->fileInfo.bufferPtr; +} + + +void CKosFile::ValidateBuffer() +{ + // + if ( this->validBuffer ) + { + // + if ( this->filePointer < this->bufferPointer + || this->filePointer >= (this->bufferPointer + FILE_BUFFER_SIZE) ) + { + // + this->validBuffer = false; + } + } +} + + +void CKosFile::UpdateBuffer(void) +{ + // + if ( ! this->validBuffer ) + { + // + this->fileInfo.OffsetLow = this->filePointer / OS_BLOCK_SIZE; + this->fileInfo.OffsetHigh = 0; + // + this->bufferPointer = this->fileInfo.OffsetLow * OS_BLOCK_SIZE; + // + this->fileInfo.dataCount = FILE_BUFFER_BLOCKS; + // + this->fileInfo.rwMode = 0; + // + Dword rr = kos_FileSystemAccess( &(this->fileInfo) ); + this->validBuffer = ( rr == 0 ); + } +} + + +int CKosFile::Seek(int seekFrom, int seekStep) +{ + // + switch ( seekFrom ) + { + // + case SEEK_SET: + // + this->filePointer = seekStep; + break; + // + case SEEK_CUR: + // + this->filePointer += seekStep; + break; + } + // + this->ValidateBuffer(); + // + return this->filePointer; +} + + +int CKosFile::Read(Byte *targetPtr, int readCount) +{ + int bufferLeast, result; + + // + result = 0; + // + do + { + // + this->UpdateBuffer(); + // + if ( ! this->validBuffer ) return result; + // + bufferLeast = FILE_BUFFER_SIZE - (this->filePointer - this->bufferPointer); + // + if ( bufferLeast > readCount ) bufferLeast = readCount; + // + if ( bufferLeast ) + { + // + memcpy( + targetPtr, + this->fileInfo.bufferPtr + (this->filePointer - this->bufferPointer), + bufferLeast + ); + // + targetPtr += bufferLeast; + readCount -= bufferLeast; + this->filePointer += bufferLeast; + // + result += bufferLeast; + } + // + this->ValidateBuffer(); + } + while ( readCount > 0 ); + // + return result; +} + + +int CKosFile::Write(Byte *sourcePtr, int writeCount) +{ + return 0; +} + diff --git a/programs/other/krule/KosFile.h b/programs/other/krule/KosFile.h new file mode 100644 index 0000000000..5f7c18e9bc --- /dev/null +++ b/programs/other/krule/KosFile.h @@ -0,0 +1,26 @@ +#pragma once + +#define SEEK_SET 0 +#define SEEK_CUR 1 + +#define FILE_BUFFER_SIZE 512 +#define OS_BLOCK_SIZE 1 +#define FILE_BUFFER_BLOCKS (FILE_BUFFER_SIZE / OS_BLOCK_SIZE) + + +class CKosFile +{ +public: + CKosFile(char *fileName); + virtual ~CKosFile(void); + virtual int Read(Byte *targetPtr, int readCount); + virtual int Write(Byte *sourcePtr, int writeCount); + virtual int Seek(int seekFrom, int seekStep); +protected: + int filePointer; + int bufferPointer; + bool validBuffer; + kosFileInfo fileInfo; + virtual void ValidateBuffer(void); + virtual void UpdateBuffer(void); +}; diff --git a/programs/other/krule/MCSMEMM.H b/programs/other/krule/MCSMEMM.H new file mode 100644 index 0000000000..42d61eaadb --- /dev/null +++ b/programs/other/krule/MCSMEMM.H @@ -0,0 +1,28 @@ +// + +struct MemBlock +{ + Dword Size; + Dword Addr; + MemBlock *Next; + MemBlock *Previous; +}; + + +#define INITIALQUEUESIZE (32 * 4) + +#define FALSE 0 +#define TRUE -1 + +#define MB_FREE 0 +#define MB_USER 1 + +#define SIZE_ALIGN 4 + + + +Byte *allocmem( Dword reqsize ); +Dword freemem( void *vaddress ); + + + diff --git a/programs/other/krule/Tupfile.lua b/programs/other/krule/Tupfile.lua new file mode 100644 index 0000000000..f95e7696d1 --- /dev/null +++ b/programs/other/krule/Tupfile.lua @@ -0,0 +1,5 @@ +if tup.getconfig("NO_MSVC") ~= "" then return end +HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../.." or tup.getconfig("HELPERDIR") +tup.include(HELPERDIR .. "/use_msvc.lua") +compile_msvc{"*.cpp"} +link_msvc("krule") diff --git a/programs/other/krule/build.bat b/programs/other/krule/build.bat new file mode 100644 index 0000000000..2aee3766f3 --- /dev/null +++ b/programs/other/krule/build.bat @@ -0,0 +1,9 @@ +call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" + +@cl /c /O2 /nologo /GS- /GR- /fp:fast *.cpp +@link /nologo /manifest:no /entry:crtStartUp /subsystem:native /base:0 /fixed /align:16 /nodefaultlib hello.obj *.obj +@del krule +@pe2kos hello.exe krule +@del hello.exe +@del *.obj +pause \ No newline at end of file diff --git a/programs/other/krule/kosSyst.cpp b/programs/other/krule/kosSyst.cpp new file mode 100644 index 0000000000..b6e630c382 --- /dev/null +++ b/programs/other/krule/kosSyst.cpp @@ -0,0 +1,835 @@ +#include "kosSyst.h" +#include + +#define atexitBufferSize 32 + + +char pureCallMessage[] = "PURE function call!"; + +char *kosExePath = NULL; + +// +void (__cdecl *atExitList[atexitBufferSize])(); +int atExitFnNum = 0; +// +int __cdecl atexit( void (__cdecl *func )( void )) +{ + // + if ( atExitFnNum < atexitBufferSize ) + { + // + atExitList[atExitFnNum++] = func; + return 0; + } + else + { + return 1; + } +} + + +// +Dword RandomSeed = 1; +// +void rtlSrand( Dword seed ) +{ + RandomSeed = seed; +} +// +Dword rtlRand( void ) +{ + //маска 0x80000776 + + Dword dwi, i; + + for ( i = 0; i < 32; i++ ) + { + + dwi = RandomSeed & 0x80000776; + + __asm{ + mov eax, dwi + mov edx, eax + bswap eax + xor eax, edx + xor al, ah + setpo al + movzx eax, al + mov dwi, eax + } + + RandomSeed = ( RandomSeed << 1 ) | ( dwi & 1 ); + } + + return RandomSeed; +} + +#if _MSC_VER >= 1400 +// +void * __cdecl memcpy( void *dst, const void *src, size_t bytesCount ) +{ + __asm{ + mov edi, dst + mov eax, dst + mov esi, src + mov ecx, bytesCount + rep movsb + } +} + +// +void memset( Byte *dst, Byte filler, Dword count ) +{ + // + __asm{ + mov edi, dst + mov al, filler + mov ecx, count + rep stosb + } +} +#endif + +// +Dword rtlInterlockedExchange( Dword *target, Dword value ) +{ +// Dword result; + + // + __asm{ + mov eax, value + mov ebx, target + xchg eax, [ebx] +// mov result, eax + } + // +// return result; +} + + +////////////////////////////////////////////////////////////////////// +// +// копирование строки +// + +char * __cdecl strcpy( char *target, const char *source ) +{ + char *result = target; + + while( target[0] = source[0] ) + { + target++; + source++; + } + + return result; +} + + +////////////////////////////////////////////////////////////////////// +// +// реверсивный поиск символа +// + +char * __cdecl strrchr( const char * string, int c ) +{ + char *cPtr; + + // + for ( cPtr = (char *)string + strlen( string ); cPtr >= string; cPtr-- ) + { + // + if ( *cPtr == c ) return cPtr; + } + // + return NULL; +} + + +////////////////////////////////////////////////////////////////////// +// +// определение длины строки +// + +int __cdecl strlen( const char *line ) +{ + int i; + + for( i=0; line[i] != 0; i++ ); + return i; +} + + + +////////////////////////////////////////////////////////////////////// +// +// перевод шестнадцатиричного числа в символ +// + +unsigned int num2hex( unsigned int num ) +{ + if( num < 10 ) + return num + '0'; + return num - 10 + 'A'; +} + + +////////////////////////////////////////////////////////////////////// +// +// вывод строки на печать +// + +Dword dectab[] = { 1000000000, 100000000, 10000000, 1000000, 100000, + 10000, 1000, 100, 10, 0 }; + +// +void sprintf( char *Str, char* Format, ... ) +{ + int i, fmtlinesize, j, k, flag; + Dword head, tail; + char c; + va_list arglist; + // + va_start(arglist, Format); + + // + fmtlinesize = strlen( Format ); + // + if( fmtlinesize == 0 ) return; + + // + for( i = 0, j = 0; i < fmtlinesize; i++ ) + { + // + c = Format[i]; + // + if( c != '%' ) + { + Str[j++] = c; + continue; + } + // + i++; + // + if( i >= fmtlinesize ) break; + + // + flag = 0; + // + c = Format[i]; + // + switch( c ) + { + // + case '%': + Str[j++] = c; + break; + // вывод строки + case 'S': + Byte* str; + str = va_arg(arglist, Byte*); + for( k = 0; ( c = str[k] ) != 0; k++ ) + { + Str[j++] = c; + } + break; + // вывод байта + case 'B': + k = va_arg(arglist, int) & 0xFF; + Str[j++] = num2hex( ( k >> 4 ) & 0xF ); + Str[j++] = num2hex( k & 0xF ); + break; + // вывод символа + case 'C': + Str[j++] = va_arg(arglist, int) & 0xFF; + break; + // вывод двойного слова в шестнадцатиричном виде + case 'X': + Dword val; + val = va_arg(arglist, Dword); + for( k = 7; k >= 0; k-- ) + { + // + c = num2hex ( ( val >> (k * 4) ) & 0xF ); + // + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + } + // + if( flag == 0 ) Str[j++] = '0'; + break; + // вывод двойного слова в десятичном виде + case 'U': + head = va_arg(arglist, Dword); + tail = 0; + for( k = 0; dectab[k] != 0; k++ ) + { + tail = head % dectab[k]; + head /= dectab[k]; + c = head + '0'; + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + // + head = tail; + } + // + c = head + '0'; + Str[j++] = c; + break; + // вывод 64-битного слова в шестнадцатиричном виде + case 'Q': + unsigned int low_dword, high_dword; + low_dword = va_arg(arglist, unsigned int); + high_dword = va_arg(arglist, unsigned int); + for( k = 7; k >= 0; k-- ) + { + // + c = num2hex ( ( ( high_dword + 1) >> (k * 4) ) & 0xF ); + // + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + } + // + for( k=7; k >= 0; k-- ) + { + // + c = num2hex ( ( low_dword >> (k * 4) ) & 0xF ); + // + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + } + // + if( flag == 0 ) Str[j++] = '0'; + // + break; + // + default: + break; + } + } + // + Str[j] = 0; +} + + +// функция -1 завершения процесса +void kos_ExitApp() +{ + int i; + + // + for ( i = atExitFnNum - 1; i >= 0; i-- ) + { + // + atExitList[i](); + } + // + __asm{ + mov eax, -1 + int 0x40 + } +} + + +// функция 0 +void kos_DefineAndDrawWindow( + Word x, Word y, + Word sizeX, Word sizeY, + Byte mainAreaType, + Dword mainAreaColour, + Byte headerType, + Dword headerColour, + Dword borderColour + ) +{ + Dword arg1, arg2, arg3, arg4; + + // + arg1 = ( x << 16 ) + sizeX; + arg2 = ( y << 16 ) + sizeY; + arg3 = ( mainAreaType << 24 ) | mainAreaColour; + arg4 = ( headerType << 24 ) | headerColour; + // + __asm{ + mov eax, 0 + mov ebx, arg1 + mov ecx, arg2 + mov edx, arg3 + mov esi, arg4 + mov edi, borderColour + int 0x40 + } +} + + +// функция 1 поставить точку +void kos_PutPixel( Dword x, Dword y, Dword colour ) +{ + // + __asm{ + mov eax, 1 + mov ebx, x + mov ecx, y + mov edx, colour + int 0x40 + } +} + + +// функция 2 получить код нажатой клавиши +bool kos_GetKey( Byte &keyCode ) +{ + Dword result; + + // + __asm{ + mov eax, 2 + int 0x40 + mov result, eax + } + // + keyCode = result >> 8; + // + return ( result & 0xFF ) == 0; +} + + +// функция 3 получить время +Dword kos_GetSystemClock() +{ +// Dword result; + + // + __asm{ + mov eax, 3 + int 0x40 +// mov result, eax + } + // +// return result; +} + + +// функция 4 +void kos_WriteTextToWindow( + Word x, + Word y, + Byte fontType, + Dword textColour, + char *textPtr, + Dword textLen + ) +{ + Dword arg1, arg2; + + // + arg1 = ( x << 16 ) | y; + arg2 = ( fontType << 24 ) | textColour; + // + __asm{ + mov eax, 4 + mov ebx, arg1 + mov ecx, arg2 + mov edx, textPtr + mov esi, textLen + int 0x40 + } +} + + +// функция 5 пауза, в сотых долях секунды +void kos_Pause( Dword value ) +{ + // + __asm{ + mov eax, 5 + mov ebx, value + int 0x40 + } +} + + +// функция 7 нарисовать изображение +void kos_PutImage( RGB * imagePtr, Word sizeX, Word sizeY, Word x, Word y ) +{ + Dword arg1, arg2; + + // + arg1 = ( sizeX << 16 ) | sizeY; + arg2 = ( x << 16 ) | y; + // + __asm{ + mov eax, 7 + mov ebx, imagePtr + mov ecx, arg1 + mov edx, arg2 + int 0x40 + } +} + + + +// функция 8 определить кнопку +void kos_DefineButton( Word x, Word y, Word sizeX, Word sizeY, Dword buttonID, Dword colour ) +{ + Dword arg1, arg2; + + // + arg1 = ( x << 16 ) | sizeX; + arg2 = ( y << 16 ) | sizeY; + // + __asm{ + mov eax, 8 + mov ebx, arg1 + mov ecx, arg2 + mov edx, buttonID + mov esi, colour + int 0x40 + } +} + + +// функция 9 - информация о процессе +Dword kos_ProcessInfo( sProcessInfo *targetPtr, Dword processID ) +{ +// Dword result; + + // + __asm{ + mov eax, 9 + mov ebx, targetPtr + mov ecx, processID + int 0x40 +// mov result, eax + } + // +// return result; +} + + +// функция 10 +Dword kos_WaitForEvent() +{ +// Dword result; + + __asm{ + mov eax, 10 + int 0x40 +// mov result, eax + } + +// return result; +} + + +// функция 11 +Dword kos_CheckForEvent() +{ +// Dword result; + + __asm{ + mov eax, 11 + int 0x40 +// mov result, eax + } + +// return result; +} + + +// функция 12 +void kos_WindowRedrawStatus( Dword status ) +{ + __asm{ + mov eax, 12 + mov ebx, status + int 0x40 + } +} + + +// функция 13 нарисовать полосу +void kos_DrawBar( Word x, Word y, Word sizeX, Word sizeY, Dword colour ) +{ + Dword arg1, arg2; + + // + arg1 = ( x << 16 ) | sizeX; + arg2 = ( y << 16 ) | sizeY; + // + __asm{ + mov eax, 13 + mov ebx, arg1 + mov ecx, arg2 + mov edx, colour + int 0x40 + } +} + + +// функция 17 +bool kos_GetButtonID( Dword &buttonID ) +{ + Dword result; + + // + __asm{ + mov eax, 17 + int 0x40 + mov result, eax + } + // + buttonID = result >> 8; + // + return (result & 0xFF) == 0; +} + + +// функция 23 +Dword kos_WaitForEvent( Dword timeOut ) +{ +// Dword result; + + __asm{ + mov eax, 23 + mov ebx, timeOut + int 0x40 +// mov result, eax + } + +// return result; +} + + +// получение информации о состоянии "мыши" функция 37 +void kos_GetMouseState( Dword & buttons, int & cursorX, int & cursorY ) +{ + Dword mB; + Word curX; + Word curY; + sProcessInfo sPI; + + // + __asm{ + mov eax, 37 + mov ebx, 0 + int 0x40 + mov curY, ax + shr eax, 16 + mov curX, ax + mov eax, 37 + mov ebx, 2 + int 0x40 + mov mB, eax + } + // + kos_ProcessInfo( &sPI ); + // + buttons = mB; + cursorX = curX - sPI.processInfo.x_start; + cursorY = curY - sPI.processInfo.y_start; +} + + +// функция 40 установить маску событий +void kos_SetMaskForEvents( Dword mask ) +{ + // + __asm{ + mov eax, 40 + mov ebx, mask + int 0x40 + } +} + + +// функция 47 вывести в окно приложения число +void kos_DisplayNumberToWindow( + Dword value, + Dword digitsNum, + Word x, + Word y, + Dword colour, + eNumberBase nBase, + bool valueIsPointer + ) +{ + Dword arg1, arg2; + + // + arg1 = ( valueIsPointer ? 1 : 0 ) | + ( ((Byte)nBase) << 8 ) | + ( ( digitsNum & 0x1F ) << 16 ); + arg2 = ( x << 16 ) | y; + // + __asm{ + mov eax, 47 + mov ebx, arg1 + mov ecx, value + mov edx, arg2 + mov esi, colour + int 0x40 + } +} + + +// функция 70 доступ к файловой системе +Dword kos_FileSystemAccess( kosFileInfo *fileInfo ) +{ +// Dword result; + + // + __asm{ + mov eax, 70 + mov ebx, fileInfo + int 0x40 +// mov result, eax + } + // +// return result; +} + + +// функция 63 вывод символя в окно отладки +void kos_DebugOutChar( char ccc ) +{ + // + __asm{ + mov eax, 63 + mov ebx, 1 + mov cl, ccc + int 0x40 + } +} + + +// функция 66 режим получения данных от клавиатуры +void kos_SetKeyboardDataMode( Dword mode ) +{ + // + __asm{ + mov eax, 66 + mov ebx, 1 + mov ecx, mode + int 0x40 + } +} + + +// вывод строки в окно отладки +void rtlDebugOutString( char *str ) +{ + // + for ( ; str[0] != 0; str++ ) + { + kos_DebugOutChar( str[0] ); + } + // + kos_DebugOutChar( 13 ); + kos_DebugOutChar( 10 ); +} + + +// функция 64 изменение количества памяти, выделенной для программы +bool kos_ApplicationMemoryResize( Dword targetSize ) +{ + Dword result; + + // + __asm{ + mov eax, 64 + mov ebx, 1 + mov ecx, targetSize + int 0x40 + mov result, eax + } + // + return result == 0; +} + + +// функция 67 изменить параметры окна, параметр == -1 не меняется +void kos_ChangeWindow( Dword x, Dword y, Dword sizeX, Dword sizeY ) +{ + // + __asm{ + mov eax, 67 + mov ebx, x + mov ecx, y + mov edx, sizeX + mov esi, sizeY + int 0x40 + } +} + + + +// вызов абстрактного метода +int __cdecl _purecall() +{ + rtlDebugOutString( pureCallMessage ); + kos_ExitApp(); + return 0; +} + + +// вызов статических инициализаторов +// заодно инициализация генератора случайных чисел +//#pragma section(".CRT$XCA",long,read,write) +//#pragma section(".CRT$XCZ",long,read,write) +#pragma data_seg(".CRT$XCA") +#pragma data_seg(".CRT$XCZ") +typedef void (__cdecl *_PVFV)(void); +__declspec(allocate(".CRT$XCA")) _PVFV __xc_a[1] = { NULL }; +__declspec(allocate(".CRT$XCZ")) _PVFV __xc_z[1] = { NULL }; +// +#pragma comment(linker, "/merge:.CRT=.rdata") +// +void crtStartUp() +{ + // вызываем инициализаторы по списку, NULL'ы игнорируем + for ( _PVFV *pbegin = __xc_a; pbegin < __xc_z; pbegin++ ) + { + // + if ( *pbegin != NULL ) + (**pbegin)(); + } + // инициализируем генератор случайных чисел + rtlSrand( kos_GetSystemClock() ); + // путь к файлу процесса + kosExePath = *((char **)0x20); + // вызов главной функции приложения + kos_Main(); + // выход + kos_ExitApp(); +} + + diff --git a/programs/other/krule/kosSyst.h b/programs/other/krule/kosSyst.h new file mode 100644 index 0000000000..5772c47e05 --- /dev/null +++ b/programs/other/krule/kosSyst.h @@ -0,0 +1,209 @@ +typedef unsigned __int32 Dword; +typedef unsigned __int16 Word; +typedef unsigned __int8 Byte; +//typedef unsigned __int32 size_t; + +#define NULL 0 + +#define MAX_PATH 256 + +#define FO_READ 0 +#define FO_WRITE 2 + +#define EM_WINDOW_REDRAW 1 +#define EM_KEY_PRESS 2 +#define EM_BUTTON_CLICK 4 +#define EM_APP_CLOSE 8 +#define EM_DRAW_BACKGROUND 16 +#define EM_MOUSE_EVENT 32 +#define EM_IPC 64 +#define EM_NETWORK 256 + +#define KM_CHARS 0 +#define KM_SCANS 1 + +#define WRS_BEGIN 1 +#define WRS_END 2 + +#define PROCESS_ID_SELF -1 + +#define abs(a) (a<0?0-a:a) + +extern "C" double acos(double x); +extern "C" double asin(double x); +extern "C" double floor(double x); +extern "C" double round(double x); +#pragma function(acos,asin) +#if _MSC_VER > 1200 +#pragma function(floor) +#endif + + +struct kosFileInfo +{ + Dword rwMode; + Dword OffsetLow; + Dword OffsetHigh; + Dword dataCount; + Byte *bufferPtr; + char fileURL[MAX_PATH]; +}; + + +struct RGB +{ + Byte b; + Byte g; + Byte r; + // + RGB() {}; + // + RGB( Dword value ) + { + r = (Byte)(value >> 16); + g = (Byte)(value >> 8); + b = (Byte)value; + }; + // + bool operator != ( RGB &another ) + { + return this->b != another.b || this->g != another.g || this->r != another.r; + }; + // + bool operator == ( RGB &another ) + { + return this->b == another.b && this->g == another.g && this->r == another.r; + }; +}; + + +union sProcessInfo +{ + Byte rawData[1024]; + struct + { + Dword cpu_usage; + Word window_stack_position; + Word window_stack_value; + Word reserved1; + char process_name[12]; + Dword memory_start; + Dword used_memory; + Dword PID; + Dword x_start; + Dword y_start; + Dword x_size; + Dword y_size; + Word slot_state; + } processInfo; +}; + +// +extern char *kosExePath; + +// +void crtStartUp(); +// +int __cdecl _purecall(); +// +int __cdecl atexit( void (__cdecl *func )( void )); +// +void rtlSrand( Dword seed ); +Dword rtlRand( void ); +// +char * __cdecl strcpy( char *target, const char *source ); +int __cdecl strlen( const char *line ); +char * __cdecl strrchr( const char * string, int c ); + +#if _MSC_VER < 1400 +extern "C" void * __cdecl memcpy( void *dst, const void *src, size_t bytesCount ); +extern "C" void memset( Byte *dst, Byte filler, Dword count ); +#pragma intrinsic(memcpy,memset) +#else +void * __cdecl memcpy( void *dst, const void *src, size_t bytesCount ); +void memset( Byte *dst, Byte filler, Dword count ); +#endif + +void sprintf( char *Str, char* Format, ... ); +// +Dword rtlInterlockedExchange( Dword *target, Dword value ); +// функция -1 завершения процесса +void kos_ExitApp(); +// функция 0 +void kos_DefineAndDrawWindow( + Word x, Word y, + Word sizeX, Word sizeY, + Byte mainAreaType, Dword mainAreaColour, + Byte headerType, Dword headerColour, + Dword borderColour + ); +// функция 1 поставить точку +void kos_PutPixel( Dword x, Dword y, Dword colour ); +// функция 2 получить код нажатой клавиши +bool kos_GetKey( Byte &keyCode ); +// функция 3 получить время +Dword kos_GetSystemClock(); +// функция 4 +void kos_WriteTextToWindow( + Word x, Word y, + Byte fontType, + Dword textColour, + char *textPtr, + Dword textLen + ); +// функция 7 нарисовать изображение +void kos_PutImage( RGB * imagePtr, Word sizeX, Word sizeY, Word x, Word y ); +// функция 8 определить кнопку +void kos_DefineButton( Word x, Word y, Word sizeX, Word sizeY, Dword buttonID, Dword colour ); +// функция 5 пауза, в сотых долях секунды +void kos_Pause( Dword value ); +// функция 9 - информация о процессе +Dword kos_ProcessInfo( sProcessInfo *targetPtr, Dword processID = PROCESS_ID_SELF ); +// функция 10 +Dword kos_WaitForEvent(); +// функция 11 +Dword kos_CheckForEvent(); +// функция 12 +void kos_WindowRedrawStatus( Dword status ); +// функция 13 нарисовать полосу +void kos_DrawBar( Word x, Word y, Word sizeX, Word sizeY, Dword colour ); +// функция 17 +bool kos_GetButtonID( Dword &buttonID ); +// функция 23 +Dword kos_WaitForEvent( Dword timeOut ); +// +enum eNumberBase +{ + nbDecimal = 0, + nbHex, + nbBin +}; +// получение информации о состоянии "мыши" функция 37 +void kos_GetMouseState( Dword & buttons, int & cursorX, int & cursorY ); +// функция 40 установить маску событий +void kos_SetMaskForEvents( Dword mask ); +// функция 47 вывести в окно приложения число +void kos_DisplayNumberToWindow( + Dword value, + Dword digitsNum, + Word x, + Word y, + Dword colour, + eNumberBase nBase = nbDecimal, + bool valueIsPointer = false + ); +// функция 58 доступ к файловой системе +Dword kos_FileSystemAccess( kosFileInfo *fileInfo ); +// функция 63 +void kos_DebugOutChar( char ccc ); +// +void rtlDebugOutString( char *str ); +// функция 64 изменить параметры окна, параметр == -1 не меняется +void kos_ChangeWindow( Dword x, Dword y, Dword sizeX, Dword sizeY ); +// функция 67 изменение количества памяти, выделенной для программы +bool kos_ApplicationMemoryResize( Dword targetSize ); +// функция 66 режим получения данных от клавиатуры +void kos_SetKeyboardDataMode( Dword mode ); + +// +void kos_Main(); diff --git a/programs/other/krule/krule.cpp b/programs/other/krule/krule.cpp new file mode 100644 index 0000000000..889a18e0ad --- /dev/null +++ b/programs/other/krule/krule.cpp @@ -0,0 +1,55 @@ +#include "kosSyst.h" +#include "kosFile.h" +#include "stdafx.h" +#include + +const char header[] = "Kolibri Rule"; + + + +void draw_window(void) +{ + int a=5; + int b=10; + // start redraw + kos_WindowRedrawStatus(1); + // define&draw window + kos_DefineAndDrawWindow(10,40,360,68, + 0x33,0xFEF977,0,0,(Dword)header); + while (a<355) + { + kos_DrawBar(a,0,1,30,0x000000); + a=a+10; + } + while (b<350) + { + kos_DrawBar(b,0,1,20,0x000000); + b=b+10; + } + + // end redraw + kos_WindowRedrawStatus(2); +} + +void kos_Main() +{ + draw_window(); + for (;;) + { + switch (kos_WaitForEvent()) + { + case 1: + draw_window(); + break; + case 2: + // key pressed, read it and ignore + Byte keyCode; + kos_GetKey(keyCode); + break; + case 3: + // button pressed; we have only one button, close + kos_ExitApp(); + } + } + +} \ No newline at end of file diff --git a/programs/other/krule/math.cpp b/programs/other/krule/math.cpp new file mode 100644 index 0000000000..6b348ed777 --- /dev/null +++ b/programs/other/krule/math.cpp @@ -0,0 +1,83 @@ +#include +#include "kosSyst.h" +extern "C" int _fltused = 0; +double acos(double x) +{ + __asm { + fld qword ptr [esp+4] + fld1 + fadd st, st(1) + fld1 + fsub st, st(2) + fmulp st(1), st + fsqrt + fxch st(1) + fpatan + } +} +double asin(double x) +{ + __asm { + fld qword ptr [esp+4] + fld1 + fadd st, st(1) + fld1 + fsub st, st(2) + fmulp st(1), st + fsqrt + fpatan + ret + } +} +#if _MSC_VER <= 1200 +extern "C" double _ftol(double x) +{ + __asm { + fld qword ptr [esp+4] + push 1F3Fh + fstcw word ptr [esp+2] + fldcw word ptr [esp] + frndint + fldcw word ptr [esp+2] + add esp, 4 + } +} +#endif +double ceil(double x) +{ + __asm { + fld qword ptr [esp+4] + push 1B3Fh + fstcw word ptr [esp+2] + fldcw word ptr [esp] + frndint + fldcw word ptr [esp+2] + add esp, 4 + } +} + +double floor(double x) +{ + __asm { + fld qword ptr [esp+4] + push 173Fh + fstcw word ptr [esp+2] + fldcw word ptr [esp] + frndint + fldcw word ptr [esp+2] + add esp, 4 + } +} + +double round(double x) +{ + __asm { + fld qword ptr [esp+4] + push 133Fh + fstcw word ptr [esp+2] + fldcw word ptr [esp] + frndint + fldcw word ptr [esp+2] + add esp, 4 + } +} diff --git a/programs/other/krule/mcsmemm.cpp b/programs/other/krule/mcsmemm.cpp new file mode 100644 index 0000000000..20feab80f6 --- /dev/null +++ b/programs/other/krule/mcsmemm.cpp @@ -0,0 +1,329 @@ +// memman.cpp : Defines the entry point for the console application. +// + +#include "kosSyst.h" +#include "mcsmemm.h" + + +void * __cdecl operator new ( size_t count, size_t element_size ) +{ + return allocmem( (Dword)(count * element_size) ); +} + +void * __cdecl operator new [] ( size_t amount ) +{ + return allocmem( (Dword)amount ); +} + +void * __cdecl operator new ( size_t amount ) +{ + return allocmem( (Dword)amount ); +} + +void __cdecl operator delete ( void *pointer ) +{ + if ( pointer != NULL ) freemem( pointer ); +} + +void __cdecl operator delete [] ( void *pointer ) +{ + if ( pointer != NULL ) freemem( pointer ); +} + + +// +Dword mmMutex = FALSE; +MemBlock *rootfree = NULL; +MemBlock *rootuser = NULL; +bool mmInitialized = false; +Byte *mmHeapTop = NULL; + + +// +Byte * AllocMemFromSystem( Dword reqSize ) +{ + Byte *result; + sProcessInfo pInfo; + + // + if ( mmInitialized ) + { + result = mmHeapTop; + } + else + { + // + kos_ProcessInfo( &pInfo ); + // + result = (Byte *)(pInfo.processInfo.used_memory + 1); + // + mmInitialized = true; + } + // + if ( ! kos_ApplicationMemoryResize( ((Dword)result) + reqSize ) ) + { + result = NULL; + } + // + mmHeapTop = result + reqSize; + // + return result; +} + + +// +Byte *allocmem( Dword reqsize ) +{ + MemBlock *BlockForCheck; + MemBlock *LastKnownGood; + Dword tail; + Byte *address; + + //подровняем размер + if( ( tail = reqsize % SIZE_ALIGN ) != 0 ) + { + reqsize += SIZE_ALIGN - tail; + } + + LastKnownGood = NULL; + + // ждём освобождения мьютекса + while ( rtlInterlockedExchange( &mmMutex, TRUE ) ) + { + // + kos_Pause( 1 ); + } + + //ищем подходящий свободный блок + if( rootfree != NULL ) + { + for ( BlockForCheck = rootfree; ; BlockForCheck = BlockForCheck->Next ) + { + if ( BlockForCheck->Size >= reqsize ) + { + //нашли + if ( LastKnownGood != NULL ) + { + if ( LastKnownGood->Size >= BlockForCheck->Size ) + LastKnownGood = BlockForCheck; + } + else + LastKnownGood = BlockForCheck; + if ( LastKnownGood->Size == reqsize ) + break; + } + if ( BlockForCheck->Next == NULL ) + break; + } + } + + if ( LastKnownGood != NULL ) + { + //проверим найденный блок на возможность деления + tail = LastKnownGood->Size - reqsize; + if ( tail >= ( sizeof(MemBlock) + SIZE_ALIGN ) ) + { + //будем разбивать + BlockForCheck = (MemBlock *)( ( (Byte *)LastKnownGood ) + tail ); + BlockForCheck->Size = reqsize; + //вставим занятый блок в начало списка занатых блоков + if( rootuser != NULL ) + { + BlockForCheck->Next = rootuser; + rootuser->Previous = BlockForCheck; + BlockForCheck->Previous = NULL; + rootuser = BlockForCheck; + } + else + { + rootuser = BlockForCheck; + BlockForCheck->Next = NULL; + BlockForCheck->Previous = NULL; + } + + //изменим размер оставшейся части + LastKnownGood->Size = tail - sizeof(MemBlock); + address = ( (Byte *)BlockForCheck ) + sizeof(MemBlock); + + // отпустим мьютекс + rtlInterlockedExchange( &mmMutex, FALSE ); + + return address; + } + else + { + //перемести блок из очереди свободных в начало очереди занятых + //сначала выкинем его из очереди свободных + if ( LastKnownGood->Previous != NULL ) + { + LastKnownGood->Previous->Next = LastKnownGood->Next; + } + else + { + //блок стоит в начале очереди + rootfree = LastKnownGood->Next; + } + if( LastKnownGood->Next != NULL ) + { + LastKnownGood->Next->Previous = LastKnownGood->Previous; + } + //теперь вставим его в очередь занятых + if( rootuser != NULL ) + { + LastKnownGood->Next = rootuser; + rootuser->Previous = LastKnownGood; + LastKnownGood->Previous = NULL; + rootuser = LastKnownGood; + } + else + { + rootuser = LastKnownGood; + LastKnownGood->Next = NULL; + LastKnownGood->Previous = NULL; + } + // + address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock); + + // отпустим мьютекс + rtlInterlockedExchange( &mmMutex, FALSE ); + + return address; + } + } + else + { + //надо получить ещё кусочек памяти + LastKnownGood = (MemBlock *)AllocMemFromSystem( reqsize + sizeof(MemBlock) ); + // + if( LastKnownGood != NULL ) + { + LastKnownGood->Size = reqsize; + //теперь вставим его в очередь занятых + if( rootuser != NULL ) + { + LastKnownGood->Next = rootuser; + rootuser->Previous = LastKnownGood; + LastKnownGood->Previous = NULL; + rootuser = LastKnownGood; + } + else + { + rootuser = LastKnownGood; + LastKnownGood->Next = NULL; + LastKnownGood->Previous = NULL; + } + address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock); + + // отпустим мьютекс + rtlInterlockedExchange( &mmMutex, FALSE ); + + return address; + } + } + + // отпустим мьютекс + rtlInterlockedExchange( &mmMutex, FALSE ); + + // + rtlDebugOutString( "allocmem failed." ); + kos_ExitApp(); + // + return NULL; +} + +// +Dword freemem( void *vaddress ) +{ + Dword result; + + Byte *checknext, *address = (Byte *)vaddress; + + // ждём освобождения мьютекса + while ( rtlInterlockedExchange( &mmMutex, TRUE ) ) + { + // + kos_Pause( 1 ); + } + + MemBlock *released = (MemBlock *)( address - sizeof(MemBlock) ); + + result = released->Size; + + //убираем блок из списка занятых + if ( released->Previous != NULL ) + { + released->Previous->Next = released->Next; + } + else + { + rootuser = released->Next; + } + if ( released->Next != NULL ) + { + released->Next->Previous = released->Previous; + } + //закинем теперь этот блок в список свободных + released->Next = rootfree; + released->Previous = NULL; + rootfree = released; + if ( released->Next != NULL ) + { + released->Next->Previous = released; + } + + //теперь поищем смежные свободные блоки + checknext = (Byte *)(rootfree) + ( rootfree->Size + sizeof(MemBlock) ); + // + for ( released = rootfree->Next; released != NULL; released = released->Next ) + { + if ( checknext == (Byte *)released ) + { + //собираем блоки вместе + //сначала выкинем из очереди свободных + released->Previous->Next = released->Next; + if( released->Next != NULL ) + { + released->Next->Previous = released->Previous; + } + //теперь увеличим размер корневого блока + rootfree->Size += released->Size + sizeof(MemBlock); + break; + } + } + //если надо, поищем блоки перед текщим. + checknext = (Byte *)(rootfree); + // + if ( released == NULL ) + { + for ( released = rootfree->Next; released != NULL; released = released->Next ) + { + if ( checknext == (Byte *)released + ( released->Size + sizeof(MemBlock) ) ) + { + //собираем блоки вместе + //увеличим размер блока + released->Size += rootfree->Size + sizeof(MemBlock); + //теперь выкинем из очереди свободных + released->Previous->Next = released->Next; + if ( released->Next != NULL ) + { + released->Next->Previous = released->Previous; + } + //и закинем его в начало очереди вместо присоединённого блока из корня списка + if ( rootfree->Next != NULL ) + { + rootfree->Next->Previous = released; + } + released->Next = rootfree->Next; + released->Previous = NULL; + rootfree = released; + break; + } + } + } + + // отпустим мьютекс + rtlInterlockedExchange( &mmMutex, FALSE ); + + return result; +} + diff --git a/programs/other/krule/stdafx.cpp b/programs/other/krule/stdafx.cpp new file mode 100644 index 0000000000..eec82ebe13 --- /dev/null +++ b/programs/other/krule/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// FixedPoint.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/programs/other/krule/stdafx.h b/programs/other/krule/stdafx.h new file mode 100644 index 0000000000..09467228a1 --- /dev/null +++ b/programs/other/krule/stdafx.h @@ -0,0 +1,11 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +// TODO: reference additional headers your program requires here