diff --git a/ColEm.mak b/ColEm.mak index a8268bf..4a126bf 100644 --- a/ColEm.mak +++ b/ColEm.mak @@ -1,6 +1,6 @@ COLEM=ColEm PSP_APP_NAME=ColEm PSP -PSP_APP_VER=2.5.2 +PSP_APP_VER=2.6.1 PSP_FW_VERSION=200 diff --git a/ColEm/Coleco.c b/ColEm/Coleco.c index 672e439..14a5c1b 100644 --- a/ColEm/Coleco.c +++ b/ColEm/Coleco.c @@ -5,7 +5,7 @@ /** This file contains implementation for the Coleco **/ /** specific hardware. Initialization code is also here. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1994-2007 **/ +/** Copyright (C) Marat Fayzullin 1994-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ @@ -318,9 +318,12 @@ int LoadROM(const char *Cartridge) /* If ROM not recognized, drop out */ if(!P) { fclose(F);return(0); } - /* Read the rest of the ROM */ + /* Clear ROM buffer and store the first two bytes */ + memset(P,NORAM,0x8000); P[0]=Buf[0]; P[1]=Buf[1]; + + /* Read the rest of the ROM */ #ifdef MINIZIP if(ZF) J=2+unzReadCurrentFile(ZF,P+2,0x7FFE); else @@ -361,7 +364,7 @@ int LoadROM(const char *Cartridge) /*************************************************************/ int SaveSTA(const char *StateFile) { - static byte Header[16] = "STF\032\001\0\0\0\0\0\0\0\0\0\0\0"; + static byte Header[16] = "STF\032\002\0\0\0\0\0\0\0\0\0\0\0"; unsigned int State[256],J; FILE *F; @@ -449,7 +452,7 @@ int LoadSTA(const char *StateFile) /* Read and check the header */ if(fread(Header,1,16,F)!=16) { fclose(F);return(0); } - if(memcmp(Header,"STF\032\001",5)) + if(memcmp(Header,"STF\032\002",5)) { fclose(F);return(0); } J=CartCRC(); if( @@ -646,29 +649,30 @@ int ResetColeco(int NewMode) /* Clear memory (important for NetPlay, to */ /* keep states at both sides consistent) */ - memset(RAM_MAIN_LO,NORAM,0x8000); - memset(RAM_MAIN_HI,NORAM,0x8000); - memset(RAM_EXP_LO,NORAM,0x8000); - memset(RAM_EXP_HI,NORAM,0x8000); - memset(RAM_OS7,NORAM,0x2000); + /* Clearing to zeros (Heist) */ + memset(RAM_MAIN_LO,0x00,0x8000); + memset(RAM_MAIN_HI,0x00,0x8000); + memset(RAM_EXP_LO,0x00,0x8000); + memset(RAM_EXP_HI,0x00,0x8000); + memset(RAM_OS7,0x00,0x2000); /* Set up memory pages */ SetMemory(Mode&CV_ADAM? 0x00:0x0F,0x00); + /* Set scanline parameters according to video type */ + /* (this has to be done before CPU and VDP are reset) */ + VDP.MaxSprites = Mode&CV_ALLSPRITE? 255:TMS9918_MAXSPRITES; + VDP.Scanlines = Mode&CV_PAL? TMS9929_LINES:TMS9918_LINES; + CPU.IPeriod = Mode&CV_PAL? TMS9929_LINE:TMS9918_LINE; + /* Reset TMS9918 VDP */ Reset9918(&VDP,ScrBuffer,ScrWidth,ScrHeight); - /* Set sprite limit */ - VDP.MaxSprites = Mode&CV_ALLSPRITE? 255:TMS9918_MAXSPRITES; /* Reset SN76489 PSG */ Reset76489(&PSG,0); Sync76489(&PSG,SN76489_SYNC); /* Reset Z80 CPU */ ResetZ80(&CPU); - /* Set scanline parameters according to video type */ - VDP.Scanlines = Mode&CV_PAL? TMS9929_LINES:TMS9918_LINES; - CPU.IPeriod = Mode&CV_PAL? TMS9929_LINE:TMS9918_LINE; - /* Set up the palette */ I = Mode&CV_PALETTE; I = I==CV_PALETTE0? 0:I==CV_PALETTE1? 16:I==CV_PALETTE2? 32:0; diff --git a/ColEm/Coleco.h b/ColEm/Coleco.h index d60b9ab..dd14cf3 100644 --- a/ColEm/Coleco.h +++ b/ColEm/Coleco.h @@ -6,7 +6,7 @@ /** and Coleco emulation itself. See Z80.h for #defines **/ /** related to Z80 emulation. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1994-2007 **/ +/** Copyright (C) Marat Fayzullin 1994-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ diff --git a/EMULib/DRV9918.c b/EMULib/DRV9918.c index 7c01ca7..c1e4842 100644 --- a/EMULib/DRV9918.c +++ b/EMULib/DRV9918.c @@ -7,7 +7,7 @@ /** TMS9918.h for declarations and TMS9918.c for the main **/ /** code. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1996-2008 **/ +/** Copyright (C) Marat Fayzullin 1996-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ @@ -281,10 +281,9 @@ void RefreshLine1(register TMS9918 *VDP,register byte Y) /*************************************************************/ void RefreshLine2(register TMS9918 *VDP,register byte Y) { - register byte X,K,Offset; - register byte *T,*PGT,*CLT; register pixel *P,FC,BC; - register int J; + register byte X,K,*T,*PGT,*CLT; + register int J,I,PGTMask,CLTMask; P = (pixel *)(VDP->XBuf) + VDP->Width*(Y+(VDP->Height-192)/2) @@ -297,19 +296,20 @@ void RefreshLine2(register TMS9918 *VDP,register byte Y) } else { - J = (int)(Y&0xC0)<<5; - PGT = VDP->ChrGen+J; - CLT = VDP->ColTab+J; + J = ((int)(Y&0xC0)<<5)+(Y&0x07); + PGT = VDP->ChrGen; + CLT = VDP->ColTab; + PGTMask = VDP->ChrGenM; + CLTMask = VDP->ColTabM; T = VDP->ChrTab+((int)(Y&0xF8)<<2); - Offset = Y&0x07; for(X=0;X<32;X++) { - J = ((int)*T<<3)+Offset; - K = CLT[J]; + I = (int)*T<<3; + K = CLT[(J+I)&CLTMask]; FC = VDP->XPal[K>>4]; BC = VDP->XPal[K&0x0F]; - K = PGT[J]; + K = PGT[(J+I)&PGTMask]; P[0] = K&0x80? FC:BC; P[1] = K&0x40? FC:BC; P[2] = K&0x20? FC:BC; diff --git a/EMULib/EMULib.h b/EMULib/EMULib.h index 9006100..e21b336 100644 --- a/EMULib/EMULib.h +++ b/EMULib/EMULib.h @@ -5,7 +5,7 @@ /** This file contains platform-independent definitions and **/ /** declarations for the emulation library. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1996-2008 **/ +/** Copyright (C) Marat Fayzullin 1996-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ diff --git a/EMULib/MIDIFreq.h b/EMULib/MIDIFreq.h index 31fba68..11f9c72 100644 --- a/EMULib/MIDIFreq.h +++ b/EMULib/MIDIFreq.h @@ -6,7 +6,7 @@ /** into MIDI octave/note numbers. It is included from the **/ /** Sound.c and SndWin.c files. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1996-2008 **/ +/** Copyright (C) Marat Fayzullin 1996-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ diff --git a/EMULib/SN76489.c b/EMULib/SN76489.c index ffad296..49943c9 100644 --- a/EMULib/SN76489.c +++ b/EMULib/SN76489.c @@ -5,7 +5,7 @@ /** This file contains emulation for the SN76489 sound chip **/ /** produced by Intel. See SN76489.h for declarations. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1996-2008 **/ +/** Copyright (C) Marat Fayzullin 1996-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ diff --git a/EMULib/SN76489.h b/EMULib/SN76489.h index 6951159..8435847 100644 --- a/EMULib/SN76489.h +++ b/EMULib/SN76489.h @@ -5,7 +5,7 @@ /** This file contains emulation for the SN76489 sound chip **/ /** produced by Intel. See SN76489.c for the code. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1996-2008 **/ +/** Copyright (C) Marat Fayzullin 1996-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ diff --git a/EMULib/Sound.c b/EMULib/Sound.c index 862e775..9f279b0 100644 --- a/EMULib/Sound.c +++ b/EMULib/Sound.c @@ -6,7 +6,7 @@ /** and functions needed to log soundtrack into a MIDI **/ /** file. See Sound.h for declarations. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1996-2008 **/ +/** Copyright (C) Marat Fayzullin 1996-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ @@ -16,7 +16,7 @@ #include #include -#ifdef UNIX +#if defined(UNIX) || defined(MAEMO) || defined(STMP3700) || defined(NXC2600) #include #endif @@ -85,13 +85,31 @@ static struct int Pos; /* Wave current position in Data */ int Count; /* Phase counter */ -} WaveCH[SND_CHANNELS]; +} WaveCH[SND_CHANNELS] = +{ + { SND_MELODIC,0,0,0,0,0,0,0 }, + { SND_MELODIC,0,0,0,0,0,0,0 }, + { SND_MELODIC,0,0,0,0,0,0,0 }, + { SND_MELODIC,0,0,0,0,0,0,0 }, + { SND_MELODIC,0,0,0,0,0,0,0 }, + { SND_MELODIC,0,0,0,0,0,0,0 }, + { SND_MELODIC,0,0,0,0,0,0,0 }, + { SND_MELODIC,0,0,0,0,0,0,0 }, + { SND_MELODIC,0,0,0,0,0,0,0 }, + { SND_MELODIC,0,0,0,0,0,0,0 }, + { SND_MELODIC,0,0,0,0,0,0,0 }, + { SND_MELODIC,0,0,0,0,0,0,0 }, + { SND_MELODIC,0,0,0,0,0,0,0 }, + { SND_MELODIC,0,0,0,0,0,0,0 }, + { SND_MELODIC,0,0,0,0,0,0,0 }, + { SND_MELODIC,0,0,0,0,0,0,0 } +}; /** RenderAudio() Variables *******************************************/ -static int SndRate = 0; /* Sound rate (1=Adlib, 0=Off) */ -static int NoiseGen = 1; /* Noise generator seed */ -int MasterSwitch = 0xFFFF; /* Switches to turn channels on/off */ -int MasterVolume = 192; /* Master volume */ +static int SndRate = 0; /* Sound rate (0=Off) */ +static int NoiseGen = 1; /* Noise generator seed */ +int MasterSwitch = 0xFFFF; /* Switches to turn channels on/off */ +int MasterVolume = 192; /* Master volume */ /** MIDI Logging Variables ********************************************/ static const char *LogName = 0; /* MIDI logging file name */ @@ -208,7 +226,7 @@ void SetWave(int Channel,const signed char *Data,int Length,int Rate) WaveCH[Channel].Type = SND_WAVE; WaveCH[Channel].Length = Length; WaveCH[Channel].Rate = Rate; - WaveCH[Channel].Pos = 0; + WaveCH[Channel].Pos = Length? WaveCH[Channel].Pos%Length:0; WaveCH[Channel].Count = 0; WaveCH[Channel].Data = Data; @@ -565,16 +583,14 @@ unsigned int InitSound(unsigned int Rate,unsigned int Latency) /* Shut down current sound */ TrashSound(); - /* Initialize internal variables */ - SndRate = 0; - MasterVolume = 0; - MasterSwitch = 0; - NoiseGen = 1; + /* Initialize internal variables (keeping MasterVolume/MasterSwitch!) */ + SndRate = 0; + NoiseGen = 1; /* Reset sound parameters */ for(I=0;I0? (SndRate<<15)/WaveCH[J].Freq/WaveCH[J].Rate - : (SndRate<<15)/WaveCH[J].Freq/WaveCH[J].Length; + K = WaveCH[J].Rate>0? + (SndRate<<15)/WaveCH[J].Freq/WaveCH[J].Rate + : (SndRate<<15)/WaveCH[J].Freq/WaveCH[J].Length; L1 = WaveCH[J].Pos%WaveCH[J].Length; L2 = WaveCH[J].Count; A1 = WaveCH[J].Data[L1]*V; @@ -738,8 +758,12 @@ unsigned int PlayAudio(int *Wave,unsigned int Samples) { D = ((*Wave++)*MasterVolume)/255; D = D>32767? 32767:D<-32768? -32768:D; -#ifdef BPS16 +#if defined(BPU16) + Buf[I] = D+32768; +#elif defined(BPS16) Buf[I] = D; +#elif defined(BPU8) + Buf[I] = (D>>8)+128; #else Buf[I] = D>>8; #endif @@ -765,16 +789,20 @@ unsigned int RenderAndPlayAudio(unsigned int Samples) /* Exit if wave sound not initialized */ if(SndRate<8192) return(0); + J = GetFreeAudio(); + Samples = SamplesOwnXBuf = 0; } - memset(VDP->R,0,sizeof(VDP->R)); + memset(VDP->VRAM,0x00,0x4000); + memset(VDP->R,0x00,sizeof(VDP->R)); VDP->UCount = 0; VDP->VAddr = 0x0000; @@ -117,13 +118,22 @@ void Reset9918(TMS9918 *VDP,byte *Buffer,int Width,int Height) VDP->VKey = 1; VDP->WKey = 1; VDP->Mode = 0; - VDP->Line = VDP->Scanlines; + VDP->Line = 0; + VDP->CLatch = 0; + VDP->DLatch = 0; + VDP->FGColor = 0; + VDP->BGColor = 0; VDP->ChrTab = VDP->VRAM; VDP->ChrGen = VDP->VRAM; VDP->ColTab = VDP->VRAM; VDP->SprTab = VDP->VRAM; VDP->SprGen = VDP->VRAM; + + VDP->ChrTabM = ~0; + VDP->ColTabM = ~0; + VDP->ChrGenM = ~0; + VDP->SprTabM = ~0; } /** Trash9918() **********************************************/ @@ -189,21 +199,29 @@ byte Write9918(TMS9918 *VDP,byte R,byte V) VDP->ChrGen = VDP->VRAM+(((int)(VDP->R[4]&Screen9918[V].R4)<<11)&VRAMMask); VDP->SprTab = VDP->VRAM+(((int)(VDP->R[5]&Screen9918[V].R5)<<7)&VRAMMask); VDP->SprGen = VDP->VRAM+(((int)(VDP->R[6]&Screen9918[V].R6)<<11)&VRAMMask); + VDP->ChrTabM = ((int)(VDP->R[2]|~Screen9918[V].M2)<<10)|0x03FF; + VDP->ColTabM = ((int)(VDP->R[3]|~Screen9918[V].M3)<<6)|0x1C03F; + VDP->ChrGenM = ((int)(VDP->R[4]|~Screen9918[V].M4)<<11)|0x007FF; + VDP->SprTabM = ((int)(VDP->R[5]|~Screen9918[V].M5)<<7)|0x1807F; VDP->Mode = V; } break; case 2: /* Name Table */ VDP->ChrTab=VDP->VRAM+(((int)(V&Screen9918[VDP->Mode].R2)<<10)&VRAMMask); + VDP->ChrTabM = ((int)(V|~Screen9918[VDP->Mode].M2)<<10)|0x03FF; break; case 3: /* Color Table */ VDP->ColTab=VDP->VRAM+(((int)(V&Screen9918[VDP->Mode].R3)<<6)&VRAMMask); + VDP->ColTabM = ((int)(V|~Screen9918[VDP->Mode].M3)<<6)|0x1C03F; break; case 4: /* Pattern Table */ VDP->ChrGen=VDP->VRAM+(((int)(V&Screen9918[VDP->Mode].R4)<<11)&VRAMMask); + VDP->ChrGenM = ((int)(V|~Screen9918[VDP->Mode].M4)<<11)|0x007FF; break; case 5: /* Sprite Attributes */ VDP->SprTab=VDP->VRAM+(((int)(V&Screen9918[VDP->Mode].R5)<<7)&VRAMMask); + VDP->SprTabM = ((int)(V|~Screen9918[VDP->Mode].M5)<<7)|0x1807F; break; case 6: /* Sprite Patterns */ VDP->SprGen=VDP->VRAM+(((int)(V&Screen9918[VDP->Mode].R6)<<11)&VRAMMask); diff --git a/EMULib/TMS9918.h b/EMULib/TMS9918.h index c8ea9bc..5375f68 100644 --- a/EMULib/TMS9918.h +++ b/EMULib/TMS9918.h @@ -6,7 +6,7 @@ /** produced by Texas Instruments. See files TMS9918.c and **/ /** DRV9918.c for implementation. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1996-2008 **/ +/** Copyright (C) Marat Fayzullin 1996-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ @@ -80,8 +80,10 @@ typedef struct { unsigned char R,G,B; } RGB; typedef unsigned int pixel; #elif defined(BPP16) typedef unsigned short pixel; -#else +#elif defined(BPP8) typedef unsigned char pixel; +#else +typedef unsigned int pixel; #endif #endif @@ -115,6 +117,12 @@ typedef struct byte *SprGen; /* Sprite Pattern Table */ byte *ColTab; /* Color Table */ + /* Table Address Masks */ + int ChrTabM; /* ChrTab[] address mask */ + int ColTabM; /* ColTab[] address mask */ + int ChrGenM; /* ChrGen[] address mask */ + int SprTabM; /* SprTab[] address mask */ + /* Picture Rendering */ void *XBuf; /* Buffer where picture is formed */ int XPal[16]; /* Colors obtained with SetColor() */ diff --git a/Z80/Codes.h b/Z80/Codes.h index 6d55bd5..8596ea9 100644 --- a/Z80/Codes.h +++ b/Z80/Codes.h @@ -5,7 +5,7 @@ /** This file contains implementation for the main table of **/ /** Z80 commands. It is included from Z80.c. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1994-2008 **/ +/** Copyright (C) Marat Fayzullin 1994-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ diff --git a/Z80/CodesCB.h b/Z80/CodesCB.h index bd300d4..8f5d002 100644 --- a/Z80/CodesCB.h +++ b/Z80/CodesCB.h @@ -5,7 +5,7 @@ /** This file contains implementation for the CB table of **/ /** Z80 commands. It is included from Z80.c. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1994-2008 **/ +/** Copyright (C) Marat Fayzullin 1994-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ diff --git a/Z80/CodesED.h b/Z80/CodesED.h index 45c7fa0..60e4bc9 100644 --- a/Z80/CodesED.h +++ b/Z80/CodesED.h @@ -5,7 +5,7 @@ /** This file contains implementation for the ED table of **/ /** Z80 commands. It is included from Z80.c. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1994-2008 **/ +/** Copyright (C) Marat Fayzullin 1994-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ diff --git a/Z80/CodesXCB.h b/Z80/CodesXCB.h index 5ef3d05..f5b12b1 100644 --- a/Z80/CodesXCB.h +++ b/Z80/CodesXCB.h @@ -5,7 +5,7 @@ /** This file contains implementation for FD/DD-CB tables **/ /** of Z80 commands. It is included from Z80.c. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1994-2008 **/ +/** Copyright (C) Marat Fayzullin 1994-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ diff --git a/Z80/CodesXX.h b/Z80/CodesXX.h index 79a45ed..823280e 100644 --- a/Z80/CodesXX.h +++ b/Z80/CodesXX.h @@ -5,7 +5,7 @@ /** This file contains implementation for FD/DD tables of **/ /** Z80 commands. It is included from Z80.c. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1994-2008 **/ +/** Copyright (C) Marat Fayzullin 1994-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ diff --git a/Z80/Debug.c b/Z80/Debug.c index 4523b7e..7effaa3 100644 --- a/Z80/Debug.c +++ b/Z80/Debug.c @@ -6,7 +6,7 @@ /** the Z80 emulator which is called on each Z80 step when **/ /** Trap!=0. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1995-2008 **/ +/** Copyright (C) Marat Fayzullin 1995-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ diff --git a/Z80/Tables.h b/Z80/Tables.h index 27f0db3..8c4a237 100644 --- a/Z80/Tables.h +++ b/Z80/Tables.h @@ -7,7 +7,7 @@ /** There are also timing tables for Z80 opcodes. This file **/ /** is included from Z80.c. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1994-2008 **/ +/** Copyright (C) Marat Fayzullin 1994-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ diff --git a/Z80/Z80.c b/Z80/Z80.c index 64b6dbd..6fe329a 100644 --- a/Z80/Z80.c +++ b/Z80/Z80.c @@ -7,7 +7,7 @@ /** LoopZ80(), and PatchZ80() functions to accomodate the **/ /** emulated machine's architecture. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1994-2008 **/ +/** Copyright (C) Marat Fayzullin 1994-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ @@ -58,6 +58,14 @@ extern byte *RAM[]; INLINE byte OpZ80(word A) { return(RAM[A>>13][A&0x1FFF]); } #endif +#ifdef ATI85 +#define RdZ80 RDZ80 +#define WrZ80 WRZ80 +extern byte *Page[],*ROM; +INLINE byte RdZ80(word A) { return(Page[A>>14][A&0x3FFF]); } +INLINE void WrZ80(word A,byte V) { if(Page[A>>14]>14][A&0x3FFF]=V; } +#endif + /** FAST_RDOP ************************************************/ /** With this #define not present, RdZ80() should perform **/ /** the functions of OpZ80(). **/ diff --git a/Z80/Z80.h b/Z80/Z80.h index 0a54ee0..e0c09dc 100644 --- a/Z80/Z80.h +++ b/Z80/Z80.h @@ -5,7 +5,7 @@ /** This file contains declarations relevant to emulation **/ /** of Z80 CPU. **/ /** **/ -/** Copyright (C) Marat Fayzullin 1994-2008 **/ +/** Copyright (C) Marat Fayzullin 1994-2010 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/