
# define errors (-1)
# define no_errors 0


# include "android_io.h"
# include "emulate.h"


#if !defined ANDROID
# include <stdlib.h>
# include <string.h>
# include <sys/timeb.h>
# include <stdio.h>
#else
#define printf(...) ((void)__android_log_print(ANDROID_LOG_INFO, "emulate1", __VA_ARGS__))
# include  "android_io.cpp"
#endif


#if !defined TRUE
# define TRUE 1
#endif

#if !defined FALSE
# define FALSE 0
#endif


# include "48.rom.cpp"
# include "128.rom.cpp"
# include "128p.rom.cpp"
# include "trdos.rom.cpp"
# include "scorpion.rom.cpp"
# include "TapeLoad128.z80.cpp"
# include "aaaa.z80.cpp"
# include "aaa_scorp.z80.cpp"
# include "disk048.trd.cpp"


#if !defined ANDROID
#include <QtCore/QtGlobal>
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
#define BIGENDIAN
#endif
#endif


# define BOOL int
//# define NULL 0


# define SB_ICON_WIDTH 14
# define SB_ICON_HEIGHT 8
# define ICON_SIZE 19
# define ICON_BUFFER_LEN 1024
# define SEPARATOR_WIDTH 3

# define THio_read_STACKSIZE 16384


# define on  1
# define off 0

# define m_48k 0
# define m_128k 1

# define SOUND_ARRAY_LEN 1000

# define MAX_OUTPUT 0x7fff
# define STEP 800

# define AY_AFINE	    (0)
# define AY_ACOARSE     (1)
# define AY_BFINE	    (2)
# define AY_BCOARSE     (3)
# define AY_CFINE	    (4)
# define AY_CCOARSE	    (5)
# define AY_NOISEPER    (6)
# define AY_ENABLE	    (7)
# define AY_AVOL	    (8)
# define AY_BVOL	    (9)
# define AY_CVOL	    (10)
# define AY_EFINE	    (11)
# define AY_ECOARSE	    (12)
# define AY_ESHAPE	    (13)
# define AY_PORTA	    (14)

# define BEEPER 255


# define ini_file_version_string "glukalka configuration file v3.00"
# define TAPE_MAX_BLOCKS 100

# define TIMER_CONST 19

# define SOUND_TICKS_PER_FRAME_CONST 882
# define SOUND_TICKS_PER_FRAME_2_CONST 441
# define SOUND_TICKS_PER_FRAME_4_CONST 220
# define SOUND_TICKS_PER_FRAME_MAX 10000

typedef struct 
{
	unsigned long tcounter;
	unsigned char r;
	unsigned char v;
	unsigned int pos;
} AY8910_STEPS;

typedef struct
{
	unsigned char  bank;
	unsigned short addr;
	unsigned short value;
	unsigned char  old;
	void * next;
	int position;
} POKE_type;

typedef struct 
{
	char name [30];
	POKE_type * POKEs;
	void * next;
	int position;
} trainer_struct;

typedef struct
{
	char present;
	int pos;	
	short size;
	unsigned char num;
} sectors_t;

typedef struct 
{
	char filename[255];	
	unsigned char trk;
	unsigned char ro;
	sectors_t sectors[85*2*32];
} discs_type;

#if !defined BIGENDIAN

typedef struct
{
	unsigned b0  : 1;                                                                  
	unsigned b1  : 1;
	unsigned b2  : 1;
	unsigned b3  : 1;
	unsigned b4  : 1;
	unsigned b5  : 1;
	unsigned b6  : 1;
	unsigned b7  : 1;
} rs_type;

#else

typedef struct
{
	unsigned b7  : 1;                                                                  
	unsigned b6  : 1;
	unsigned b5  : 1;
	unsigned b4  : 1;
	unsigned b3  : 1;
	unsigned b2  : 1;
	unsigned b1  : 1;
	unsigned b0  : 1;
} rs_type;

#endif

typedef struct
{
	unsigned char line;
	unsigned int y;
	int a;
} screen_type;

typedef struct
{
	unsigned short b[8];
} attrib_type;

typedef struct 
{
	unsigned char id;
	unsigned int len;
	unsigned int ilen;
	void * info;
	unsigned char * data1;
	int position;
	void * next;
}tape_struct;

typedef struct 
{
	unsigned short pause;
	unsigned short len;
} ROM_bl_type;

typedef struct
{
	unsigned short pilotL;
	unsigned short syncFL;
	unsigned short syncSL;
	unsigned short zeroL;
	unsigned short oneL;
	unsigned short pilot_toneL_inPulses;
	unsigned char  used_bits;
	unsigned short pause;
	unsigned char  l1, l2, l3;
} turbo_block_type;

typedef struct
{
	unsigned short len, n;
} Pure_toneT;

typedef struct
{
	unsigned short z, o;
	unsigned char used;
	unsigned short pause;
	unsigned char l1,l2,l3;
} Pure_dataT;

typedef struct 
{
	unsigned char type, id, value;
} hardwareT;

typedef struct 
{
	unsigned short TS;
	unsigned short pause;
	unsigned char used;
	unsigned char l1,l2,l3;
} direct_recT;

typedef struct 
{
	unsigned char major;	
	unsigned char minor;	
}zxtapeT;

typedef struct 
{
	void * data;
	void * data1;
	void * data2;
} messageT;


/****************** variables **********************/


int Log = 0;

unsigned int XColors32[]=
{
	0xFF000000|0, 0xFF000000|191, 0xFF000000|12517376, 0xFF000000|12517567, 0xFF000000|48896, 0xFF000000|49087, 0xFF000000|12566272, 0xFF000000|12566463,
	0xFF000000|0, 0xFF000000|255, 0xFF000000|16711680, 0xFF000000|16711935, 0xFF000000|65280, 0xFF000000|65535, 0xFF000000|16776960, 0xFF000000|16777215
};


int sec_size = 256;

char homedir1 [200] = {0};

int tape_position;

unsigned long long TC = 0;

int last_tape_p;

int sound_fil = -1;

int scan=off;

int GetScan()
{
	return scan;
}

void SetScan(int arg)
{
	scan=arg;
}

char DirectStack[16384];

unsigned char lastPort1ffdScOut;

unsigned char ram8[16384];
unsigned char ram9[16384];
unsigned char ramA[16384];
unsigned char ramB[16384];
unsigned char ramC[16384];
unsigned char ramD[16384];
unsigned char ramE[16384];
unsigned char ramF[16384];

unsigned char * new_rom;
unsigned char * new_ram;

#define DIRECT_RECORDING_BUFFER_SIZE 882
unsigned char direct_recording_buffer[DIRECT_RECORDING_BUFFER_SIZE];
unsigned int direct_recording_buffer_pos=(DIRECT_RECORDING_BUFFER_SIZE-1);

unsigned int direct_recording=0;

int audio3;

unsigned int z80_spd_new;


unsigned char p_ff_in;

unsigned int NT_T_INT_LEN;
unsigned int NT_T_UP; /*(16+40)*224*/
unsigned int NT_T_LP; /*32+20*/
unsigned int NT_T_RP; /*12*/
unsigned int NT_T_DP; /*48*224*/

char DumpAudioFileName[256];

int direct_mic=0;

unsigned int tapeMIC_pos_prev=0;

int tape_paused=0;

int tape_io_readonly = false;
char * tape_type;

signed short tape_rew_counter;
const short tape_rew_counter_const=3500000/44100;

unsigned char tape[10*1024*1024*2];
unsigned char tapeS[10*1024*1024*2];

# define tapeMIC_max 10*1024*1024
unsigned char tapeMIC[tapeMIC_max];
unsigned int tapeMIC_pos=0;

unsigned int tape_pos=0, tape_len=0; 

tape_struct * tape_next=NULL;

messageT message;

tape_struct * tapes=NULL;

char tape_filename[255]={0};

int tape_traps = 1;

int TT(void)
{
	return tape_traps;
}

void STT(int rrr)
{
	tape_traps = rrr;
}

int * GetTT()
{
	return (&tape_traps);
}

int kempston_mouse;

int * GetKM(void)
{
	return (&kempston_mouse);
}

int leds_global;

int * Leds()
{
	return (&leds_global);
}


unsigned char avol_max=0, bvol_max=0, cvol_max=0;

unsigned char Atone;
unsigned char Anoice;

unsigned char Btone;
unsigned char Bnoice;

unsigned char Ctone;
unsigned char Cnoice;

int ledsY;

# define CurrentDiscNum (vg_last_portFF_out&3)
# define CurrentDisk discs[vg_last_portFF_out&3]
unsigned long long cmd_done=0;

unsigned char ParityTBL[256];

int showQTape=0;

int * GetSQT()
{
	return (&showQTape);
}

int showFloppik=0;

int logit=2;

int SOUND_TICKS_PER_FRAME;
int SOUND_TICKS_PER_FRAME_2;
int SOUND_TICKS_PER_FRAME_4;

int toio_write=0;
int toio_writeaddr;

int pointer;
int side;

unsigned char track[655360];
unsigned char * toio_read;
unsigned int toio_read_num=0;
unsigned int toio_read_position=0;
unsigned char six_bytes[6];

unsigned char vg_spin;
unsigned char vg_direction; /*0 - k nulevoi 1 - ot nulevoi*/

unsigned char vg_reg_trk;
unsigned char vg_reg_sec;
unsigned char vg_reg_dat;
unsigned char vg_portFF_in;
unsigned char vg_last_portFF_out=0;

union aaaa                                                                                        
{
	unsigned char byte;
	rs_type bit;
} vg_rs; 


discs_type discs[4];

int TRDOS=off;

trainer_struct * trainers=NULL;

unsigned int beeper_volume=12;

unsigned int * GetBV(void)
{	
	return (&beeper_volume);
}

unsigned short bpr=0; 

unsigned char up, holded;
unsigned char env_volume;
unsigned char cont,att,alt,hold;

unsigned short sound_buffer[SOUND_TICKS_PER_FRAME_MAX*2*2]; /* 2 kanala */

void * GetSoundBuffer(void)
{
	return ((void *)sound_buffer);
}

unsigned short sound_bufferD[SOUND_TICKS_PER_FRAME_MAX*2*2]; /* 2 kanala */

unsigned short soundA[SOUND_TICKS_PER_FRAME_MAX*2];
unsigned short soundB[SOUND_TICKS_PER_FRAME_MAX*2];
unsigned short soundC[SOUND_TICKS_PER_FRAME_MAX*2];

unsigned short beeper_buffer[SOUND_TICKS_PER_FRAME_MAX*2];

unsigned char channelA_enabled;
unsigned char channelB_enabled;
unsigned char channelC_enabled;

unsigned char noiseA_enabled;
unsigned char noiseB_enabled;
unsigned char noiseC_enabled;

unsigned int GeneratorA_period;
unsigned int GeneratorB_period;
unsigned int GeneratorC_period;

unsigned int GeneratorA_counter;
unsigned int GeneratorB_counter;
unsigned int GeneratorC_counter;

unsigned int NoiceA_counter;
unsigned int NoiceB_counter;
unsigned int NoiceC_counter;

long int rndA;
long int rndB;
long int rndC;

unsigned int PeriodN, periodE;
unsigned int Envelope_counter;

unsigned short * mixing_ch[10];

int PSGcounter=0;
AY8910_STEPS PSGARRAY[SOUND_ARRAY_LEN];		

unsigned int UpdateStep;
int register_latch;
unsigned char Regs[16];
unsigned char Regs1[16];

unsigned short VolTable[16]=
{
	0x0000/2, 0x0344/2, 0x04BC/2, 0x06ED/2, 
	0x0A3B/2, 0x0F23/2, 0x1515/2, 0x2277/2, 
	0x2898/2, 0x4142/2, 0x5B2B/2, 0x726C/2, 
	0x9069/2, 0xB555/2, 0xD79B/2, 0xFFFF/2 
};

unsigned char last_tape_out;
int vz80;

char audio_name[255] = {0};

char * Get_audio_name(void)
{
	return (audio_name);
}

int audio;

int audio2;

char filenameT[255];
char tstring[300];

int timeout=TIMER_CONST;
int timerid;
int joy_type = 2; /* 0-kempston; 1-sinclair*/

char inifilepath[255];

unsigned char stereo_mode=0; /* 2=Mono 1=ABC 0=ACB*/

unsigned char * GetSM()
{
	return (&stereo_mode);
}

unsigned int emulator_speed=100;
char stereo_mode_string[32];
char start_directory[1255];


int screen_w, screen_h;

char joystick_type[32];
char joystick2_type[32];

char Mode[32];

int GetJOY(void)
{
	//printf("GetJOY \n");
	return joy_type;
}

void SetJOY(int type)
{
	joy_type = type;

	//printf("SetJOY %d\n", joy_type);
}

char * GetMode()
{
	return (Mode);
}

void SetMode(char * aaa)
{
	strcpy(Mode, aaa);
}

int tape_stopped=on;

int screen_io_created=0;

unsigned char last7ffdout;

unsigned char data_bus=255;

#if !defined BIGENDIAN
typedef union {
	struct { unsigned char l, h; } b;
	struct { unsigned short w; }w;
} regpair;
#endif

#if defined BIGENDIAN
typedef union {
	struct { unsigned char h,  l; } b;
	struct { unsigned short w; }w;
} regpair;
#endif

typedef struct {
	regpair af,bc,de,hl;
	regpair af_,bc_,de_,hl_;
	regpair ix,iy;
	unsigned char i,r,r7; 
	regpair sp,pc;
	unsigned char iff1,iff2, im;
	int halted;
} processor;

processor pz80;

#define IFF1 pz80.iff1
#define IFF2 pz80.iff2
#define IM pz80.im
#define halted pz80.halted
#define interrupts pz80.iff1

#define A   pz80.af.b.h
#define F   pz80.af.b.l
#define AF  pz80.af.w.w

#define B   pz80.bc.b.h
#define C   pz80.bc.b.l
#define BC  pz80.bc.w.w

#define D   pz80.de.b.h
#define E   pz80.de.b.l
#define DE  pz80.de.w.w

#define H   pz80.hl.b.h
#define L   pz80.hl.b.l
#define HL  pz80.hl.w.w

#define A_  pz80.af_.b.h
#define A1  pz80.af_.b.h
#define F_  pz80.af_.b.l
#define F1  pz80.af_.b.l
#define AF_ pz80.af_.w.w

#define B_  pz80.bc_.b.h
#define B1  pz80.bc_.b.h
#define C_  pz80.bc_.b.l
#define C1  pz80.bc_.b.l
#define BC_ pz80.bc_.w.w

#define D_  pz80.de_.b.h.
#define D1  pz80.de_.b.h
#define E_  pz80.de_.b.l
#define E1  pz80.de_.b.l
#define DE_ pz80.de_.w.w

#define H_  pz80.hl_.b.h
#define H1  pz80.hl_.b.h
#define L_  pz80.hl_.b.l
#define L1  pz80.hl_.b.l
#define HL_ pz80.hl_.w.w

#define IXH pz80.ix.b.h
#define IXL pz80.ix.b.l
#define IXh pz80.ix.b.h
#define IXl pz80.ix.b.l
#define IX  pz80.ix.w.w

#define IYH pz80.iy.b.h
#define IYL pz80.iy.b.l
#define IYh pz80.iy.b.h
#define IYl pz80.iy.b.l
#define IY  pz80.iy.w.w

#define SPH pz80.sp.b.h
#define SPL pz80.sp.b.l
#define SP  pz80.sp.w.w

#define PCH pz80.pc.b.h
#define PCL pz80.pc.b.l
#define PC  pz80.pc.w.w

#define I  pz80.i
#define R  pz80.r
#define R7 pz80.r7

unsigned char A2, B2, C2, D2, E2, F2, H2, L2;
unsigned short HL1_1;
unsigned short XX;

unsigned char border;

KeybPortType f7fe, fbfe, fdfe, fefe, effe, dffe, bffe, sffe;
kempston_type kempston;

void FillKeybp( KeybPortType **pf7fe, KeybPortType  **pfbfe, KeybPortType  **pfdfe, KeybPortType  **pfefe, KeybPortType  **peffe, 
	KeybPortType **pdffe, KeybPortType  **pbffe, KeybPortType  **psffe, kempston_type **k, int ** t)
{
	*pf7fe = &f7fe;
	*pfbfe = &fbfe;
	*pfdfe = &fdfe;
	*pfefe = &fefe;
	*peffe = &effe;
	*pdffe = &dffe;
	*pbffe = &bffe;
	*psffe = &sffe;

	*k=&kempston;
	*t=&joy_type;
}

unsigned char CPU12[49152];

unsigned char RAM0[16384];
unsigned char RAM1[16384];
unsigned char RAM3[16384];
unsigned char RAM4[16384];
unsigned char RAM6[16384];
unsigned char RAM7[16384];

unsigned char ROM0[16384];
unsigned char ROM1[16384];
unsigned char ROMTRD[16384];
unsigned char ROMSCRP[16384];

unsigned char mode;


unsigned char * screen48;
unsigned char * attrib48;

unsigned char * RAM5;
unsigned char * RAM2;

unsigned char * videomemory = NULL;

int rk=0;
int flashcounter=0;
int rb,rc;
int ri;
int rf,rt,rr;


unsigned int tcounter=0;


/******** xzx ********/

unsigned short work16;
unsigned char work8;
unsigned int work32;
unsigned char val;
unsigned short reg;

int idx;

int sub_hcarry_tbl1[] = { 0, 1, 1, 1, 0, 0, 0, 1 };
int sub_overflow_tbl1[] = { 0, 0, 0, 1, 1, 0, 0, 0 };
int hcarry_tbl1[] = { 0, 0, 1, 0, 1, 0, 1, 1 };
int overflow_tbl1[] = { 0, 1, 0, 0, 0, 0, 1, 0 };

int sub_hcarry_tbl(int arg)
{
	return (sub_hcarry_tbl1[arg&7]);
}

int hcarry_tbl(int arg)
{
	return (hcarry_tbl1[arg&7]);
}

int sub_overflow_tbl(int arg)
{
	return (sub_overflow_tbl1[arg&7]);
}

int overflow_tbl(int arg)
{
	return (overflow_tbl1[arg&7]);
}


/***********************/

/******** fuse ***********/
unsigned char add;
unsigned char carry;
/*************************/

unsigned char ferv;
unsigned char fer1;
void timerfunc(void);
void SaveZ80(char * path, char *);
void Set_z80times_per_line(unsigned int);
void MessageBoxInfo(char * string);
void UpdateSoundBuffer(void);
void ApplySoundRegister(int r, int v);
void ApplyPoke(POKE_type * p, char * trainer_name);
trainer_struct * FindTrainer(int num);
void PrintSpInfo();
void InitToolTips(void);
void reDrawFlashed(void);
int  z80a(int);
unsigned long long GetCurrentTime1(void);
unsigned char IsCDNio_ready(void);
tape_struct * FindTapeByPosition(int p);
unsigned char b2bget(unsigned char * otkuda, unsigned int pos);
void AddTapeBlock(char * arg1, unsigned char id, unsigned int len, unsigned char * data, int ilen, void * info, int show, int);
void tape_SetActiveAndPause(tape_struct * arg);
char * tape_GAInfo1st(unsigned char * arg);
tape_struct * TapeFindParent(tape_struct * arg);
void WorkWithBuffer(unsigned char * buffer,unsigned long filelen);
void RecoveryTape(int tape_RAM, unsigned char * tape_buffer);
void WorkWithBuffer2(unsigned char * buffer, unsigned long filelen);
void lpf(unsigned char * b, int len);
void ScorpionSetPage(void);
void io_readTZX(char * filename, char *);
void io_readTAP(char * filename, char *);
void io_readWAV(char * filename, char *);
void byteswp(unsigned char * arg);


void TODO (char * unused)
{

}

char * ImagesDir()
{
	return(start_directory);
}

void SetSOUND_TICKS_PER_FRAME(void)
{
	double koef;


	koef=(double)timeout/(double)TIMER_CONST;

	SOUND_TICKS_PER_FRAME   = (int)((double)SOUND_TICKS_PER_FRAME_CONST * koef);
	SOUND_TICKS_PER_FRAME_2 = (int)((double)SOUND_TICKS_PER_FRAME_2_CONST * koef);
	SOUND_TICKS_PER_FRAME_4 = (int)((double)SOUND_TICKS_PER_FRAME_4_CONST * koef);

	if (SOUND_TICKS_PER_FRAME>SOUND_TICKS_PER_FRAME_MAX)
		SOUND_TICKS_PER_FRAME=SOUND_TICKS_PER_FRAME_MAX;
	if (SOUND_TICKS_PER_FRAME_2>SOUND_TICKS_PER_FRAME_MAX)
		SOUND_TICKS_PER_FRAME_2=SOUND_TICKS_PER_FRAME_MAX;
	if (SOUND_TICKS_PER_FRAME_4>SOUND_TICKS_PER_FRAME_MAX)
		SOUND_TICKS_PER_FRAME_4=SOUND_TICKS_PER_FRAME_MAX;
}

void AYio_writeRegNV(int r, int v)
{
	if (PSGcounter==SOUND_ARRAY_LEN)
		return;

	PSGARRAY[PSGcounter].tcounter=tcounter;
	PSGARRAY[PSGcounter].r=r;
	PSGARRAY[PSGcounter].v=v;

	PSGcounter++;
}

# define MAX_AY_PER_TAKT 50
# define MAX_AY_PER_FILE 100000

typedef struct
{
	unsigned char registers[MAX_AY_PER_TAKT][MAX_AY_PER_FILE];
	unsigned char values[MAX_AY_PER_TAKT][MAX_AY_PER_FILE];
	int tcounter;
	unsigned char counter[MAX_AY_PER_FILE];
} A___Y;


A___Y A_Y;

void AYio_writeReg(int r, int v)
{
	if (r > 15) return;

	A_Y.registers[A_Y.counter[A_Y.tcounter]][A_Y.tcounter] = r;	
	A_Y.values[A_Y.counter[A_Y.tcounter]][A_Y.tcounter] = v;

	A_Y.counter[A_Y.tcounter]++;

	if (A_Y.counter[A_Y.tcounter]==MAX_AY_PER_TAKT)
		A_Y.counter[A_Y.tcounter]--;



	Regs[r] = v;

	if (PSGcounter==SOUND_ARRAY_LEN)
		return;

	PSGARRAY[PSGcounter].tcounter=tcounter;
	PSGARRAY[PSGcounter].r=r;
	PSGARRAY[PSGcounter].v=v;

	PSGcounter++;
}

#define ex(h,l) (h*256+l) 

unsigned char io_readByte(unsigned short address)
{
	if ((address>=16384)&&(address<49152))
		return(CPU12[address]);

	if (address>=49152)
		return(new_ram[address-49152]);

	if (TRDOS && (new_rom!=ROMSCRP)) 
		return(ROMTRD[address]);

	return(new_rom[address]);
}

#if defined ANDROID
# include <android/log.h>
# endif

void PrintSpInfo()
{
	char message [200];

	char * rams;

	if (new_ram == RAM0) rams = "RAM0";
	if (new_ram == RAM1) rams = "RAM1";
	if (new_ram == RAM2) rams = "RAM2";
	if (new_ram == RAM3) rams = "RAM3";
	if (new_ram == RAM4) rams = "RAM4";
	if (new_ram == RAM5) rams = "RAM5";
	if (new_ram == RAM6) rams = "RAM6";
	if (new_ram == RAM7) rams = "RAM7";
	if (new_ram == ram8) rams = "RAM8";
	if (new_ram == ram9) rams = "RAM9";
	if (new_ram == ramA) rams = "RAMA";
	if (new_ram == ramB) rams = "RAMB";
	if (new_ram == ramC) rams = "RAMC";
	if (new_ram == ramD) rams = "RAMD";
	if (new_ram == ramE) rams = "RAME";
	if (new_ram == ramF) rams = "RAMF";

	char * roms;

	if (new_rom == ROM0) roms = "ROM0";
	if (new_rom == ROM1) roms = "ROM1";
	if (TRDOS) roms = "ROMT";
	if (new_rom == ROMSCRP) roms = "ROMS";

	sprintf(message, "%04X [PC]%02X%02X%02X%02X [SP-2]%02X%02X%02X%02X%02X AF=%04X BC=%04X DE=%04X HL=%04X SP=%04X IX=%04X IY=%04X 7FFD=%02X 1FFD=%02X %s %s ",
		PC,
		io_readByte(PC),   io_readByte(PC+1), io_readByte(PC+2), io_readByte(PC+3),
		io_readByte(SP-2), io_readByte(SP-1), io_readByte(SP),   io_readByte(SP+1), io_readByte(SP+2),
		AF, BC, DE, HL, SP, IX, IY,
		last7ffdout, lastPort1ffdScOut,
		rams,
		roms
		);

#if defined ANDROID
	__android_log_print(ANDROID_LOG_DEBUG, "LOG_TAG", "%s",message);
#else
	printf ("%s", message);
#endif

}


# define ZS_RAM ram8 


unsigned char prevbyte;
void io_writeByte(unsigned short address, unsigned char byte)
{
	if ((address>=16384)&&(address<49152))
	{
		CPU12[address]=byte;

		return;
	}	

	if (address>=49152)
	{
		new_ram[address-49152]=byte;
	}

	if ((new_rom==ZS_RAM)&&(address<16384))
		ZS_RAM[address]=byte;
}

void io_writeByte(unsigned short address, unsigned short byte)
{
	io_writeByte(address, (unsigned char)byte);
}

void io_writeByte(unsigned short address, int byte)
{
	io_writeByte(address, (unsigned char)byte);
}

unsigned char * GiveAddrW1(unsigned short address)
{
	if ((address>=16383)&&(address<49152))
		return(&CPU12[address]);

	if (address>=49152)
		return(&new_ram[address-49152]);


	printf("GiveAddrW : end of function. This is bug. Report it.\n");
	return(&CPU12[16384]);
}

void InitKempston(void)
{
	kempston.bit.left=0;
	kempston.bit.right=0;
	kempston.bit.up=0;
	kempston.bit.down=0;
	kempston.bit.fire=0;
	kempston.bit.unused=0;
}


void MapROM0()
{
	new_rom=ROM0;
	//printf("MapROM0");
}

void MapROM1()
{
	new_rom=ROM1;
	//printf("MapROM1");
}

void z80Reset(void)
{
	A=F=B=C=D=E=H=L=A1=F1=B1=C1=D1=E1=H1=L1=0;
	IX=IY=SP=PC=0;
	interrupts=off;
	IM=0;
	halted=off;
	I=0;

	TRDOS=off;
}

int Load128ROMs (void)
{
	memcpy (ROM0, b128, 16384);
	memcpy (ROM1, &b128[16384], 16384);

	return(no_errors);
}

int Load48ROMs(void)
{
	memcpy (ROM0, b48, 16384);
	memcpy (ROM1, b48, 16384);

	return(no_errors);
}

int LoadPentagonROMs(void)
{
	memcpy (ROM0, b128p, 16384);
	memcpy (ROM1, &b128p[16384], 16384);
	memcpy (ROMTRD, btrdos, 16384);

	return(no_errors);
}

int LoadScorpionROMs(void)
{
	memcpy (ROM0, &bscorpion[0], 16384);
	memcpy (ROM1, &bscorpion[16384], 16384);
	memcpy (ROMSCRP, &bscorpion[32768], 16384);
	memcpy (ROMTRD, &bscorpion[49152], 16384);

	return(no_errors);
}

void Set48kMode()
{
	mode=m_48k;
	//Show128mode(0);
}

void Set128kMode()
{
	mode=m_128k;
	//Show128mode(1);
}

int Reset(void)
{
	Zamolchi();

	//	strcpy (Mode, "Pentagon");

	if (io_strcasecmp(Mode, "128")==0)
	{
		if (Load128ROMs()==errors)
		{
			printf("Can't load ROM Image.\n");
			return(errors);
		}

		Set128kMode();
	}

	if (io_strcasecmp(Mode, "48")==0)
	{
		if (Load48ROMs()==errors)
		{
			printf("Can't load ROM Image.\n");
			return(errors);
		}

		Set48kMode();
	}

	if (io_strcasecmp(Mode,"Pentagon")==0)
	{
		if (LoadPentagonROMs()==errors)
		{
			printf("Can't load ROM Image.\n");
			return(errors);
		}

		Set128kMode();
	}

	if (io_strcasecmp(Mode,"Scorpion")==0)
	{
		lastPort1ffdScOut=0;

		if (LoadScorpionROMs()==errors)
		{
			printf("Can't load ROM Image.\n");
			return(errors);
		}

		Set128kMode();
	}

	screen48=&CPU12[16384];
	attrib48=&CPU12[22528];

	z80Reset();
	MapROM0();

	border=7;
	data_bus=255;

	//setZ80spd_100(NULL, (XtPointer)35, NULL);

	return(no_errors);
}

void ClearKeyPort(KeybPortType * p)
{
	p->d0=1;
	p->d1=1;
	p->d2=1;
	p->d3=1;
	p->d4=1;
	p->u1=1;
	p->u2=1;
	p->tape=1;
}

void ClearKeyboard(void)
{
	ClearKeyPort(&f7fe);
	ClearKeyPort(&fbfe);
	ClearKeyPort(&fdfe);
	ClearKeyPort(&fefe);
	ClearKeyPort(&effe);
	ClearKeyPort(&dffe);
	ClearKeyPort(&bffe);
	ClearKeyPort(&sffe);
}

void Set48Screen()
{
	screen48=&CPU12[16384];
	attrib48=&CPU12[22528];
}

int Spectrum_Init(void)
{
	screen48=&CPU12[16384];
	attrib48=&CPU12[22528];

	RAM5=&CPU12[16384];
	RAM2=&CPU12[32768];

	new_ram=RAM0;

	ClearKeyboard();
	InitKempston();

	/*
	if (LoadImageIntoZXRAM("resources/t2.scr")==errors)
	{
	printf("Can't load t2.scr. Exiting.\n");
	ExitWithError(-1,"");
	}
	*/

	if (Reset()==errors)
		return(errors);
	else
		return(no_errors);
}

//struct timeb dbtt;
//unsigned short dbms=0;

unsigned short what16=0;
unsigned short what08=0;

void PortFeOut(unsigned char what)
{
	border = what&7;

	if (what&0x8)
		last_tape_out=250;
	else
		last_tape_out=5;

	if ((tape_pos>=tape_len)||(tape_paused))
	{
		if ((what&16)!=what16)
			AYio_writeRegNV(BEEPER, what&16);
		if (( what&8)!=what08)
			AYio_writeRegNV(BEEPER, what&8);

		what16=what&16;
		what08= what&8;
	}
}

unsigned char Keybbitarray2Char (KeybPortType arg)
{
	unsigned char rv=0;

	if (arg.d0)   rv|= 1;
	if (arg.d1)   rv|= 2;
	if (arg.d2)   rv|= 4;
	if (arg.d3)   rv|= 8;
	if (arg.d4)   rv|= 16;
	if (arg.u1)   rv|= 32;
	if (arg.tape) rv|= 64;
	if (arg.u2)   rv|= 128;

	return (rv);    
}

unsigned char PortFeIn(unsigned char a8a15)
{
	a8a15=~a8a15;
	ferv=255;


#if !defined BIGENDIAN
	if (a8a15&1)
	{	
		memcpy(&fer1,&fefe,1);
		ferv&=fer1;	
	}

	if (a8a15&2)
	{	
		memcpy(&fer1,&fdfe,1);
		ferv&=fer1;	
	}

	if (a8a15&4)
	{	
		memcpy(&fer1,&fbfe,1);
		ferv&=fer1;	
	}

	if (a8a15&8)
	{	
		memcpy(&fer1,&f7fe,1);
		ferv&=fer1;	
	}

	if (a8a15&16)
	{	
		memcpy(&fer1,&effe,1);
		ferv&=fer1;	
	}

	if (a8a15&32)
	{	
		memcpy(&fer1,&dffe,1);
		ferv&=fer1;	
	}

	if (a8a15&64)
	{	
		memcpy(&fer1,&bffe,1);
		ferv&=fer1;	
	}

	if (a8a15&128)
	{	
		memcpy(&fer1,&sffe,1);
		ferv&=fer1;	
	}
#endif

#if defined BIGENDIAN
	if (a8a15&1)
	{	
		fer1=Keybbitarray2Char(fefe);
		ferv&=fer1;	
	}

	if (a8a15&2)
	{	
		fer1=Keybbitarray2Char(fdfe);
		ferv&=fer1;
	}

	if (a8a15&4)
	{	
		fer1=Keybbitarray2Char(fbfe);
		ferv&=fer1;	
	}

	if (a8a15&8)
	{	
		fer1=Keybbitarray2Char(f7fe);
		ferv&=fer1;	
	}

	if (a8a15&16)
	{	
		fer1=Keybbitarray2Char(effe);
		ferv&=fer1;	
	}

	if (a8a15&32)
	{	
		fer1=Keybbitarray2Char(dffe);
		ferv&=fer1;	
	}

	if (a8a15&64)
	{	
		fer1=Keybbitarray2Char(bffe);
		ferv&=fer1;	
	}

	if (a8a15&128)
	{	
		fer1=Keybbitarray2Char(sffe);
		ferv&=fer1;	
	}
#endif

	if (direct_recording)
	{
		if (direct_recording_buffer[direct_recording_buffer_pos]>127)
			ferv|=0x40;
		else
			ferv&=0xbf;	
	}
	else
	{
		if (b2bget(tape, tape_pos))
			ferv|=0x40;
		else
			ferv&=0xbf;
	}

	return(ferv);
}

void Port7ffdOut(unsigned char what)
{
	if (mode==m_48k)
		return;

	if ( (what&8)!=(last7ffdout&8) ) 
	{
		if (what&8)
		{
			screen48=&RAM7[0];
			attrib48=&RAM7[22528-16384];
		}
		else
		{
			screen48=&CPU12[16384];
			attrib48=&CPU12[22528];	
		}	
	}

	last7ffdout=what;	

	//printf ("%s\n", Mode);

	if ((Mode[0]=='s')||(Mode[0]=='S'))
	{
		if (!(lastPort1ffdScOut&2) && !(lastPort1ffdScOut&1))
		{
			if (what&16)	
				MapROM1();
			else
				MapROM0();
		}
	}
	else
	{
		if (what&16)	
			MapROM1();
		else
			MapROM0();
	}

	if (what&32)	
	{
		if (mode!=m_48k)
			Set48kMode();
	}

	if ((Mode[0]=='s')||(Mode[0]=='S'))
	{
		if (lastPort1ffdScOut&16) ScorpionSetPage(); 
		else
		{
			switch(what&7)
			{
			case 0: new_ram=RAM0; return;	
			case 1: new_ram=RAM1; return;	
			case 2: new_ram=RAM2; return;	
			case 3: new_ram=RAM3; return;	
			case 4: new_ram=RAM4; return;	
			case 5: new_ram=RAM5; return;	
			case 6: new_ram=RAM6; return;	
			case 7: new_ram=RAM7; return;	
			}
		}
	}
	else	
	{
		switch(what&7)
		{
		case 0: new_ram=RAM0; return;	
		case 1: new_ram=RAM1; return;	
		case 2: new_ram=RAM2; return;	
		case 3: new_ram=RAM3; return;	
		case 4: new_ram=RAM4; return;	
		case 5: new_ram=RAM5; return;	
		case 6: new_ram=RAM6; return;	
		case 7: new_ram=RAM7; return;	
		}
	}
}

void PortfffdOut(unsigned char what)
{
	register_latch=what&0x0f;
}

void PortbffdOut(unsigned char what)
{
	if ((tape_pos>=tape_len)||(tape_paused))
		AYio_writeReg(register_latch,what);
}

unsigned char PortfffdIn()
{
	return(Regs[register_latch]);
}

unsigned char Kempston(void)
{
	return(kempston.byte);
}

void ExitWithError(int n, char * c)
{
	TODO ("ExitWithError");
}

#if !defined BIGENDIAN
unsigned char * p2b;
void io_writeToSpAddrVal(unsigned short sp_addr, unsigned short data)
{
	p2b=(unsigned char*)&data;

	io_writeByte(sp_addr, p2b[0]);
	io_writeByte(++sp_addr, p2b[1]);
}
#endif

#if defined BIGENDIAN
char * p2b;
void io_writeToSpAddrVal(unsigned short sp_addr, unsigned short data)
{
	p2b=(char*)&data;

	io_writeByte(sp_addr, p2b[1]);
	io_writeByte(++sp_addr, p2b[0]);
}
#endif


#if !defined BIGENDIAN
void io_writeToRamAddrSpAddr(char * kuda, unsigned short sp_addr_otkuda)
{
	*(char*)kuda = io_readByte(sp_addr_otkuda);
	*(char*)(kuda+1) = io_readByte(++sp_addr_otkuda);
}

void io_writeToRamAddrSpAddr(unsigned char * kuda, unsigned short sp_addr_otkuda)
{
	*(char*)kuda = io_readByte(sp_addr_otkuda);
	*(char*)(kuda+1) = io_readByte(++sp_addr_otkuda);
}
#endif

#if defined BIGENDIAN
void io_writeToRamAddrSpAddr(char * kuda, unsigned short sp_addr_otkuda)
{
	*(char*)kuda = io_readByte(sp_addr_otkuda+1);
	*(char*)(kuda+1) = io_readByte(sp_addr_otkuda);
}

void io_writeToRamAddrSpAddr(unsigned char * kuda, unsigned short sp_addr_otkuda)
{
	*(char*)kuda = io_readByte(sp_addr_otkuda+1);
	*(char*)(kuda+1) = io_readByte(sp_addr_otkuda);
}
#endif

void myFflagZ_s(char arg)
{
	if (arg) F|=64;
	else F&=~64;
}

void myFflagH_s(char arg)
{
	if (arg) F|=16;
	else F&=~16;
}

void myFflagC_s(char arg)
{
	if (arg) F|=1;
	else F&=~1;
}

unsigned char myFflagC_r(void)
{
	if (F&1) return 1;
	else return 0;
}

void myFflagN_s(char arg)
{
	if (arg) F|=2;
	else F&=~2;
}

void myFflagS_s(char arg)
{
	if (arg) F|=128;
	else F&=~128;
}

void myFflagPV_s(char arg)
{
	if (arg) F|=4;
	else F&=~4;
}

void zero (unsigned char ger)
{
	if (!ger) myFflagZ_s (1);
	else myFflagZ_s (0);
}

void znak (unsigned char ger)
{
	if (ger>=128) myFflagS_s(1);
	else myFflagS_s(0);
}

void zero (unsigned short ger)
{
	if (!(unsigned char)ger) myFflagZ_s (1);
	else myFflagZ_s (0);
}

void znak (unsigned short ger)
{
	if ((unsigned char)ger>=128) myFflagS_s(1);
	else myFflagS_s(0);
}

void parity (unsigned char ger)
{
	if (ParityTBL[ger])myFflagPV_s(1);
	else myFflagPV_s(0);
}

#define ZnakA   znak(A)
#define ZeroA   zero(A)
#define ParityA parity(A)

void push (unsigned short data)
{
	SP-=2;
	io_writeToSpAddrVal(SP,data);
}

void pop (unsigned short * data)
{
	io_writeToRamAddrSpAddr((char *)data, SP);
	SP+=2;
}

void bit(unsigned char reg, unsigned char bit) 
{
	myFflagZ_s  ((((reg) & (0x01 << (bit))) == 0)); 
	myFflagPV_s ((((reg) & (0x01 << (bit))) == 0));
	myFflagN_s  (0);               
	znak(reg); 
}

void vg_seek_delay(unsigned char dst_track) 
{
	if ((dst_track-discs[vg_last_portFF_out&3].trk)>0)
		vg_direction=1;
	if ((dst_track-discs[vg_last_portFF_out&3].trk)<0)
		vg_direction=0;

	cmd_done = GetCurrentTime1()+20*abs(dst_track-CurrentDisk.trk);

	if (IsCDNio_ready()) vg_portFF_in = 0x80;
	else vg_portFF_in = 0x80;

	CurrentDisk.trk = dst_track;
	vg_reg_trk=dst_track;
}

void vg_setFlagsSeeks()
{
	vg_rs.bit.b0=0;

	if (discs[vg_last_portFF_out&3].trk==0)
		vg_rs.bit.b2=1;
	else
		vg_rs.bit.b2=0;

	vg_rs.bit.b3=0;
	vg_rs.bit.b4=0;
	vg_rs.bit.b6=discs[vg_last_portFF_out&3].ro;
	vg_rs.bit.b7=IsCDNio_ready();
}

int GetData(int num, int Track, int Sec)
{
	//Sec = Sec & 127;

	for (int track=0; track<85; track++)
	{
		for (int side=0; side<2; side++)
		{
			for (int sec=0; sec<32; sec++)
			{
				if (discs[num].sectors[(track*2+side)*32 + sec].present && (discs[num].sectors[(track*2+side)*32 + sec].num == Sec) && (Track == (track*2+side)))
				{
					sec_size = discs[num].sectors[(track*2+side)*32 + sec].size;
					return (discs[num].sectors[(track*2+side)*32 + sec].pos);
				}
			}
		}
	}

	printf ("Sector is not found ! trk=%d sec=%d\n", Track, Sec);

	//sec_size = 0;
	return 0;
}

void vg_port1F_outTRD(unsigned char what)
{
	int trdFIL;


	if (vg_last_portFF_out&0x10) side=0;
	else		side=1;


	//printf("what = %d trk=%d side=%d regsec=%d regtrk=%d disk=%d \n", what, discs[vg_last_portFF_out&3].trk, side, vg_reg_sec, vg_reg_trk, vg_last_portFF_out&3);

	if ((what & 0xF0) == 0xD0) /* interrupt */
	{
		vg_portFF_in = 0x80;
		vg_setFlagsSeeks();

		return;
	}	

	if ((what & 0xF0) == 0x00) /* seek trk0 */
	{
		//printf ("1 %d \n", vg_rs.byte);
		vg_seek_delay(0);
		//printf ("2 %d \n", vg_rs.byte);
		vg_rs.bit.b5=what&8;
		//printf ("3 %d \n", vg_rs.byte);
		vg_setFlagsSeeks();
		//printf ("4 %d \n", vg_rs.byte);
		if (what&8) vg_spin=on;
		//printf ("5 %d \n", vg_rs.byte);
		return;
	}

	if ((what & 0xF0) == 0x10) /* seek track */
	{
		vg_seek_delay(vg_reg_dat);
		vg_rs.bit.b5=what&8;
		vg_setFlagsSeeks();
		if (what&8) vg_spin=on;

		return;
	}

	if ((what & 0xE0) == 0x40) /* fwd */
	{
		vg_direction = 1;
		what = 0x20; /* step */
	}
	if ((what & 0xE0) == 0x60) /* back */
	{
		vg_direction = 0;
		what = 0x20; /* step */
	}
	if ((what & 0xE0) == 0x20) /* step */
	{
		if (vg_direction)
			vg_seek_delay(++CurrentDisk.trk);
		else
			vg_seek_delay(--CurrentDisk.trk);

		vg_rs.bit.b5=1;
		vg_setFlagsSeeks();
		vg_spin=on;

		return;
	}

	if ((what & 0xE0) == 0x80) /* io_readsec */
	{
		vg_rs.byte = 0x81;
		vg_portFF_in = 0x40;
		vg_spin=off;

		if (IsCDNio_ready())
		{
			vg_rs.byte = 0x90;
			vg_portFF_in = 0x80; 

			printf("No disk in drive %c\n", 'A'+CurrentDiscNum);

			return;
		}

		if (!sec_size)
		{
			vg_rs.byte |= 0x10; /* sector not found */
			vg_portFF_in = 0x80;

			printf("1 sector not found %d\n", vg_reg_sec);

			return;
		}

		trdFIL=io_open(NULL, discs[vg_last_portFF_out&3].filename, O_RDONLY);

		if (trdFIL==-1)
		{
			printf("vg_port1F_outTRD : Can't io_open file %s vg_last_portFF_out=%x !!!\n",discs[vg_last_portFF_out&3].filename, vg_last_portFF_out);

			vg_rs.byte = 0x90;
			vg_portFF_in = 0x80; 

			return;
		}

		//TRK
		pointer=GetData(vg_last_portFF_out&3, discs[vg_last_portFF_out&3].trk*2+side, vg_reg_sec);// ;;(discs[vg_last_portFF_out&3].trk*2+side)*256*16+(vg_reg_sec-1)*256;

		//printf ("%d\n", pointer);

		if (
			io_lseek(trdFIL,pointer,SEEK_SET)
			!=pointer)
		{
			printf("vg_port1F_outTRD : seek failed !!! poiner = %d.\n", pointer);
			io_close(trdFIL);

			vg_rs.byte |= 0x10; /* sector not found */
			vg_portFF_in = 0x80;

			return;
		}

		if (what&0x10)
		{
			//printf("Multisectronaya:io_read vg_reg_sec=%d !\n", vg_reg_sec);

			int max_sec;
			if (sec_size == 512)
				max_sec = 9;
			if (sec_size == 256)
				max_sec = 16;
			if (sec_size == 1024)
				max_sec = 5;


			io_read(trdFIL, track, sec_size*(max_sec));

			io_close(trdFIL);

			toio_read=track;
			toio_read_num=sec_size*(max_sec);
			toio_read_position=0;

			/* vg_portFF_in=0x80; */
			/* *** !!! ***         */
			/* todo : Eto proverit' !!! */
		}
		else
		{
			if (io_read(trdFIL, track, sec_size)==sec_size)
			{
				io_close(trdFIL);

				toio_read=track;
				toio_read_num=sec_size;
				toio_read_position=0;

				cmd_done = GetCurrentTime1()+30;
			}
			else
			{
				io_close(trdFIL);

				vg_rs.byte |= 0x10; /* sector not found */
				vg_portFF_in = 0x80;


				printf("io_read(trdFIL, track, 256)!=256\n");
			}
		}

		return;
	}

	if ((what & 0xFB) == 0xC0) /* io_read adr */
	{
		vg_rs.byte = 0x81;
		vg_portFF_in = 0x40;

		six_bytes[0]=discs[vg_last_portFF_out&3].trk;
		six_bytes[1]=0; 
		six_bytes[2]=vg_reg_sec;
		six_bytes[3]=1;
		six_bytes[4]=0; /* todo : crc !!! */
		six_bytes[5]=0; /* todo : crc !!! */

		toio_read=six_bytes;
		toio_read_num=6;
		toio_read_position=0;

		cmd_done = GetCurrentTime1()+30;
		vg_spin=off;

		return;
	}	

	if ((what & 0xE0) == 0xA0) /* io_writesec */
	{
		vg_rs.byte = 0x81;
		vg_portFF_in = 0x40;
		vg_spin=off;


		if (CurrentDisk.ro) 
		{
			vg_rs.byte = 0x60;
			vg_portFF_in = 0x80;
			return;
		}

		if (IsCDNio_ready())
		{
			vg_rs.byte = 0x90;
			vg_portFF_in = 0x80; 

			printf("net diska\n");

			return;
		}

		if (!sec_size)
		{
			vg_rs.byte |= 0x10; /* sector not found */
			vg_portFF_in = 0x80;			

			printf("2 sector not found %d\n", vg_reg_sec);

			return;
		}

		toio_writeaddr=GetData(vg_last_portFF_out&3, discs[vg_last_portFF_out&3].trk*2+side, vg_reg_sec);
		toio_write=sec_size;

		vg_spin=off;

		return;		
	}		

	printf("vg_port1F_outTRD : unknown command 0x%x\n",what);
	/* ExitWithError(0,""); */
}

void vg_port1F_out(unsigned char what)
{
	vg_port1F_outTRD(what);
}

void vg_io_write(unsigned char data)
{
	static int trdFIL;


	if (toio_write==0)
		return;

	//printf ("%d = %c \n", toio_writeaddr, data);

	if ((toio_writeaddr%256) == 0)
	 trdFIL=io_open(NULL, discs[vg_last_portFF_out&3].filename, O_RDWR);

	if (trdFIL==-1)
		return;

	if (
		io_lseek(trdFIL, toio_writeaddr, SEEK_SET)
		!=toio_writeaddr)
	{
		toio_write=0;

		printf("vg_port1F_outTRD : seek failed !!! poiner = %d.\n", toio_writeaddr);
		io_close(trdFIL);
		return;
	}

	io_write(trdFIL, &data, 1);

	if ((toio_writeaddr%256) == 255)
	io_close(trdFIL);

	toio_write--;
	toio_writeaddr++;

	if (toio_write==0)
	{
		io_close(trdFIL);
		vg_portFF_in=0x80;
		vg_rs.byte=0;
		/*
		vg_rs.bit.b0=0; // Busy 
		vg_rs.bit.b1=0; // DRQ copy
		*/
	}
	else
		vg_portFF_in=0x40;
}

void OutPortTRDOS(unsigned char A0A7, unsigned char what)
{
	/* printf("OutPortTRDOS : port=0x%x value==0x%x\n", A0A7, what); */

	showFloppik=1;

	if (A0A7==0x1f)
	{
		vg_port1F_out(what);
		return;
	}

	if (A0A7==0x3f)
	{
		vg_reg_trk=what;
		return;
	}

	if (A0A7==0x5f)
	{
		vg_reg_sec=what;
		return;
	}

	if (A0A7==0x7f)
	{
		vg_reg_dat=what;
		vg_io_write(what);
		return;
	}

	if (A0A7==0xff)
	{
		vg_last_portFF_out=what;
		return;
	}

	printf("OutPortTRDOS : port=%x value:%d\n",A0A7,what);
}

void ScorpionSetPage(void)
{
	switch(last7ffdout&7)
	{
	case 0: new_ram=ram8; return;	
	case 1: new_ram=ram9; return;	
	case 2: new_ram=ramA; return;	
	case 3: new_ram=ramB; return;	
	case 4: new_ram=ramC; return;	
	case 5: new_ram=ramD; return;	
	case 6: new_ram=ramE; return;	
	case 7: new_ram=ramF; return;	
	}
}

void Port1ffdScOut(unsigned char what)
{
	lastPort1ffdScOut=what;



	if (what&2) new_rom=ROMSCRP; 
	else 
	{
		if (last7ffdout&16)	
			MapROM1();
		else
			MapROM0();
	}
	
	if (what&16) ScorpionSetPage(); 
	else 
	{
		switch(last7ffdout&7)
		{
		case 0: new_ram=RAM0; break;	
		case 1: new_ram=RAM1; break;	
		case 2: new_ram=RAM2; break;	
		case 3: new_ram=RAM3; break;	
		case 4: new_ram=RAM4; break;	
		case 5: new_ram=RAM5; break;	
		case 6: new_ram=RAM6; break;	
		case 7: new_ram=RAM7; break;	
		}
	}
	
	if (what&1) new_rom=ZS_RAM;
}

void OutPort(unsigned char A0A7, unsigned char A8A15, unsigned char what)
{
	if ((Mode[0]=='S')||(Mode[0]=='s'))
	{
		if ((A0A7==0xfd)&&(A8A15==0x1f))
		{
			Port1ffdScOut(what);
			return;
		}
	}

	if ((TRDOS)&&((A0A7==0xff)||(A0A7==0x7f)||(A0A7==0x1f)||(A0A7==0x3f)||(A0A7==0x5f))) 
	{
		OutPortTRDOS(A0A7, what);
		//printf ("out TRD %d %d \n", A0A7, what);	
		return;
	}

	/*fd              //7f */
	if (((A0A7&3)<2)&&(A8A15<0x80))
	{
		Port7ffdOut(what);
		return;
	}	

	/*fd              //bf */
	if (((A0A7&3)<2)&&(A8A15<0xc0))
	{
		PortbffdOut(what);
		return;
	}	

	/*fd              //ff */
	if (((A0A7&3)<2)&&(A8A15>=0xc0))
	{
		PortfffdOut(what);
		return;
	}

	if (A0A7==0xfe)
	{
		PortFeOut(what);
		return;
	}

#if defined pedantic
	printf("OutPort : Unknown port %x. Exiting.\n",A8A15*256+A0A7);
	ExitWithError(-1,"");
	return;
#endif
}

unsigned char vg_io_read_reg_datTRD()
{
	/* printf("vg_io_read_reg_dat : %d\n",toio_read_position); */

	if (toio_read_position>=toio_read_num)
		return (vg_reg_dat);

	vg_reg_dat=toio_read[toio_read_position];

	if (((toio_read_position&0x00ff)==0)&&toio_read_position!=0)
		vg_reg_sec++;

	if (vg_reg_sec>16) vg_reg_sec=1;

	toio_read_position++;

	if (toio_read_position==toio_read_num)
	{
		vg_portFF_in=0x80;

		vg_rs.byte=0;
		/*
		vg_rs.bit.b0=0; // Busy
		vg_rs.bit.b1=0; // DRQ copy
		*/
	}
	else
	{
		vg_portFF_in=0x40;

		vg_rs.bit.b0=1; /* Busy */
		vg_rs.bit.b1=1; /* DRQ copy */
	}


	return(vg_reg_dat);
}

unsigned char IsCDNio_ready(void)
{
	if (!io_strncasecmp(CurrentDisk.filename, "none", 4)) return(1);

	return(0);
}

unsigned long long GetCurrentTime1(void)
{
	return (TC/4);
}

unsigned char InPortTRDOS(unsigned char A0A7)
{
	unsigned long long ttt;
	static int first = 1;


	if (first)
	{
		//printf ("ree\n");
		//SaveZ80("TRD_Load_128.z80");
		first = 0;
	}

	showFloppik=1;

	if (vg_spin) 
	{
		if (IsCDNio_ready())
			vg_rs.bit.b1=0;
		else
		{
			ttt = GetCurrentTime1();

			if ( (ttt%1000<=20) || ((ttt%1000>=200)&&(ttt%1000<=220)) || ((ttt%1000>=400)&&(ttt%1000<=420)) || ((ttt%1000>=600)&&(ttt%1000<=620)) || ((ttt%1000>=800)&&(ttt%1000<=820)) )
				vg_rs.bit.b1=1;
			else
				vg_rs.bit.b1=0;
		}
	}

	if (A0A7==0x1f)
	{
		if (IsCDNio_ready()) return(0x80);
		return(vg_rs.byte);
	}

	if (A0A7==0x3f)return(vg_reg_trk);
	if (A0A7==0x5f)return(vg_reg_sec);
	if (A0A7==0x7f)
	{
		return(vg_io_read_reg_datTRD());
	}
	if (A0A7==0xff)
	{
		if (GetCurrentTime1()<cmd_done) return(vg_portFF_in&~0x40);
		return(vg_portFF_in);
	}

	//printf("InPortTRDOS : port=%x\n",A0A7);
	return(0xff);
}

unsigned char InPort(unsigned char A0A7, unsigned char A8A15)
{
	unsigned char rv;


	if ((TRDOS)&&((A0A7==0xff)||(A0A7==0x7f)||(A0A7==0x1f)||(A0A7==0x3f)||(A0A7==0x5f))) 
	{
		rv=InPortTRDOS(A0A7);

		//printf("InPortTRDOS : port = %x returned= %x\n", A0A7, rv); 

		return (rv);
	}

	if (kempston_mouse)
	{
		switch (A8A15*256+A0A7)
		{
# if !defined ANDROID
		case 0xfadf: return kmGetKeys();
		case 0xfbdf: return kmGetX();
		case 0xffdf: return kmGetY();
# endif
		}
	}

	//printf("%x %x\n", A0A7, A8A15);

	switch(A0A7)
	{
	case 0xfe: 
		return(PortFeIn(A8A15));

	case 0x1f: 
		return(Kempston());
	}		

	/*fd              //7f */
	if (((A0A7&3)<2)&&(A8A15<0x80))
		return(last7ffdout);

	/*fd              //ff */
	if (((A0A7&3)<2)&&(A8A15>=0xc0))
		return(PortfffdIn());


#if defined pedantic
	printf("InPort : Unknown port %x. Exiting.\n",A0A7+A8A15*256);
	ExitWithError(-1,"");
#endif


	return(p_ff_in);
}

void RLC (unsigned char * reg)
{   
	*reg = (((*reg) << 1) | myFflagC_r());

	myFflagC_s((*reg & 0x80) != 0);                                                
	znak(*reg);                                                
	zero(*reg);
	parity(*reg);
	myFflagH_s(0);
	myFflagN_s(0);
}                                 

int CB (void)
{
	switch(io_readByte(PC))
	{
		/* komandi vklyuchenuia bitov */

	case 0xc7: 
		{
			A|=1;
			PC++;
			return(8);
		}

	case 0xc4: 
		{
			H|=1;
			PC++;
			return(8);
		}

	case 0xc5: 
		{
			L|=1;
			PC++;
			return(8);
		}

	case 0xc0: 
		{
			B|=1;
			PC++;
			return(8);
		}

	case 0xc1: 
		{
			C|=1;
			PC++;
			return(8);
		}

	case 0xc2: 
		{
			D|=1;
			PC++;
			return(8);
		}

	case 0xc3: 
		{
			E|=1;
			PC++;
			return(8);
		}

	case 0xc6: 
		{
			work8=io_readByte(HL);
			work8|=1;
			io_writeByte(HL,work8);
			PC++;
			return(15);
		}


	case 0xcf: 
		{
			A|=2;
			PC++;
			return(8);
		}

	case 0xcc: 
		{
			H|=2;
			PC++;
			return(8);
		}

	case 0xcd: 
		{
			L|=2;
			PC++;
			return(8);
		}

	case 0xc8: 

		{
			B|=2;
			PC++;
			return(8);
		}

	case 0xc9: 
		{
			C|=2;
			PC++;
			return(8);
		}

	case 0xca: 
		{
			D|=2;
			PC++;
			return(8);
		}

	case 0xcb: 
		{
			E|=2;
			PC++;
			return(8);
		}

	case 0xce: 
		{
			work8=io_readByte(HL);
			work8|=2;
			io_writeByte(HL,work8);

			PC++;
			return(15);
		}


	case 0xd7: 
		{
			A|=4;
			PC++;
			return(8);
		}

	case 0xd4: 
		{
			H|=4;
			PC++;
			return(8);
		}

	case 0xd5: 
		{
			L|=4;
			PC++;
			return(8);
		}

	case 0xd0: 
		{
			B|=4;
			PC++;
			return(8);
		}

	case 0xd1: 

		{
			C|=4;
			PC++;
			return(8);
		}

	case 0xd2: 
		{
			D|=4;
			PC++;
			return(8);
		}

	case 0xd3: 
		{
			E|=4;
			PC++;
			return(8);
		}

	case 0xd6: 
		{
			work8=io_readByte(HL);
			work8|=4;
			io_writeByte(HL,work8);

			PC++;
			return(15);
		}


	case 0xdf: 
		{
			A|=8;
			PC++;
			return(8);
		}

	case 0xdc: 
		{
			H|=8;
			PC++;
			return(8);
		}

	case 0xdd: 
		{


			L|=8;
			PC++;
			return(8);
		}

	case 0xd8: 
		{
			B|=8;
			PC++;
			return(8);
		}

	case 0xd9: 
		{
			C|=8;
			PC++;
			return(8);
		}

	case 0xda: 
		{
			D|=8;
			PC++;
			return(8);
		}

	case 0xdb: 
		{
			E|=8;
			PC++;
			return(8);
		}

	case 0xde: 
		{
			work8=io_readByte(HL);
			work8|=8;
			io_writeByte(HL,work8);	

			PC++;
			return(15);
		}


	case 0xe7: 
		{
			A|=16;
			PC++;
			return(8);
		}

	case 0xe4: 
		{
			H|=16;
			PC++;
			return(8);
		}

	case 0xe5: 
		{
			L|=16;
			PC++;
			return(8);
		}

	case 0xe0: 
		{
			B|=16;
			PC++;
			return(8);
		}

	case 0xe1: 
		{
			C|=16;
			PC++;
			return(8);
		}

	case 0xe2: 
		{
			D|=16;
			PC++;
			return(8);
		}

	case 0xe3: 
		{
			E|=16;
			PC++;
			return(8);
		}

	case 0xe6: 
		{
			work8=io_readByte(HL);
			work8|=16;
			io_writeByte(HL,work8);

			PC++;
			return(15);
		}



	case 0xef: 
		{
			A|=32;
			PC++;
			return(8);
		}

	case 0xec: 
		{
			H|=32;
			PC++;
			return(8);
		}

	case 0xed: 
		{
			L|=32;
			PC++;
			return(8);
		}

	case 0xe8: 
		{
			B|=32;
			PC++;
			return(8);
		}

	case 0xe9: 
		{
			C|=32;
			PC++;
			return(8);
		}

	case 0xea: 
		{
			D|=32;
			PC++;
			return(8);
		}

	case 0xeb: 
		{
			E|=32;
			PC++;
			return(8);
		}

	case 0xee: 
		{
			work8=io_readByte(HL);
			work8|=32;
			io_writeByte(HL,work8);

			PC++;
			return(15);
		}


	case 0xf7: 
		{
			A|=64;
			PC++;
			return(8);
		}

	case 0xf4: 
		{
			H|=64;
			PC++;
			return(8);
		}

	case 0xf5: 
		{
			L|=64;
			PC++;
			return(8);
		}

	case 0xf0: 
		{
			B|=64;
			PC++;
			return(8);
		}

	case 0xf1: 

		{
			C|=64;
			PC++;
			return(8);
		}

	case 0xf2: 
		{
			D|=64;
			PC++;
			return(8);
		}

	case 0xf3: 
		{
			E|=64;
			PC++;
			return(8);
		}

	case 0xf6: 
		{

			work8=io_readByte(HL);
			work8|=64;
			io_writeByte(HL,work8);	

			PC++;
			return(15);
		}


	case 0xff: 
		{

			A|=128;
			PC++;
			return(8);
		}

	case 0xfc: 
		{
			H|=128;
			PC++;
			return(8);
		}

	case 0xfd: 
		{
			L|=128;
			PC++;
			return(8);
		}

	case 0xf8: 
		{
			B|=128;
			PC++;
			return(8);
		}

	case 0xf9: 
		{
			C|=128;
			PC++;
			return(8);
		}

	case 0xfa: 
		{
			D|=128;
			PC++;
			return(8);
		}

	case 0xfb: 
		{
			E|=128;
			PC++;
			return(8);
		}

	case 0xfe: 
		{
			work8=io_readByte(HL);
			work8|=128;
			io_writeByte(HL,work8);

			PC++;
			return(15);
		}

		/* viklucheniye bitov */

	case 0x87: 
		{
			A&=0xfe;
			PC++;
			return(8);
		}

	case 0x84: 
		{
			H&=0xfe;
			PC++;
			return(8);
		}

	case 0x85: 
		{
			L&=0xfe;
			PC++;
			return(8);
		}

	case 0x80: 
		{
			B&=0xfe;
			PC++;
			return(8);
		}

	case 0x81: 
		{
			C&=0xfe;
			PC++;
			return(8);
		}

	case 0x82: 
		{
			D&=0xfe;
			PC++;
			return(8);
		}

	case 0x83: 
		{
			E&=0xfe;
			PC++;
			return(8);
		}

	case 0x86: 
		{
			work8=io_readByte(HL);
			work8&=0xfe;
			io_writeByte(HL,work8);

			PC++;
			return(15);
		}


	case 0x8f: 
		{
			A&=0xfd;
			PC++;
			return(8);
		}

	case 0x8c: 
		{
			H&=0xfd;
			PC++;
			return(8);
		}

	case 0x8d: 
		{
			L&=0xfd;
			PC++;
			return(8);
		}

	case 0x88: 
		{
			B&=0xfd;
			PC++;
			return(8);
		}

	case 0x89: 
		{
			C&=0xfd;
			PC++;
			return(8);
		}

	case 0x8a: 
		{
			D&=0xfd;
			PC++;


			return(8);
		}

	case 0x8b: 
		{
			E&=0xfd;
			PC++;
			return(8);
		}

	case 0x8e: 
		{
			work8=io_readByte(HL);
			work8&=0xfd;
			io_writeByte(HL,work8);

			PC++;
			return(15);
		}


	case 0x97: 
		{
			A&=0xfb;
			PC++;
			return(8);
		}


	case 0x94: 
		{
			H&=0xfb;
			PC++;
			return(8);

		}

	case 0x95: 
		{
			L&=0xfb;
			PC++;
			return(8);
		}

	case 0x90: 
		{
			B&=0xfb;
			PC++;

			return(8);
		}


	case 0x91: 
		{
			C&=0xfb;
			PC++;
			return(8);


		}

	case 0x92: 
		{


			D&=0xfb;
			PC++;
			return(8);
		}

	case 0x93: 
		{
			E&=0xfb;
			PC++;
			return(8);
		}

	case 0x96: 
		{
			work8=io_readByte(HL);
			work8&=0xfb;
			io_writeByte(HL,work8);

			PC++;
			return(15);
		}


	case 0x9f: 
		{
			A&=0xf7;
			PC++;


			return(8);
		}


	case 0x9c: 
		{
			H&=0xf7;
			PC++;
			return(8);
		}

	case 0x9d: 
		{

			L&=0xf7;
			PC++;
			return(8);
		}

	case 0x98: 
		{
			B&=0xf7;
			PC++;
			return(8);
		}

	case 0x99: 
		{
			C&=0xf7;
			PC++;
			return(8);
		}

	case 0x9a: 
		{
			D&=0xf7;
			PC++;
			return(8);
		}

	case 0x9b: 
		{
			E&=0xf7;
			PC++;
			return(8);
		}

	case 0x9e: 
		{
			work8=io_readByte(HL);
			work8&=0xf7;
			io_writeByte(HL,work8);

			PC++;
			return(15);
		}


	case 0xa7: 
		{
			A&=0xef;
			PC++;
			return(8);
		}

	case 0xa4: 
		{
			H&=0xef;
			PC++;
			return(8);
		}

	case 0xa5: 
		{
			L&=0xef;
			PC++;
			return(8);
		}

	case 0xa0: 
		{
			B&=0xef;
			PC++;
			return(8);
		}

	case 0xa1: 
		{
			C&=0xef;
			PC++;
			return(8);
		}



	case 0xa2: 
		{
			D&=0xef;
			PC++;
			return(8);
		}

	case 0xa3: 
		{
			E&=0xef;
			PC++;
			return(8);
		}

	case 0xa6: 
		{

			work8=io_readByte(HL);
			work8&=0xef;

			io_writeByte(HL,work8);

			PC++;
			return(15);
		}

	case 0xaf: 
		{
			A&=0xdf;
			PC++;
			return(8);
		}


	case 0xac: 

		{
			H&=0xdf;
			PC++;
			return(8);
		}

	case 0xad: 
		{
			L&=0xdf;
			PC++;
			return(8);
		}

	case 0xa8: 
		{
			B&=0xdf;
			PC++;

			return(8);
		}

	case 0xa9: 
		{
			C&=0xdf;
			PC++;
			return(8);
		}

	case 0xaa: 
		{
			D&=0xdf;
			PC++;
			return(8);
		}

	case 0xab: 
		{
			E&=0xdf;
			PC++;
			return(8);
		}

	case 0xae: 
		{
			work8=io_readByte(HL);
			work8&=0xdf;
			io_writeByte(HL,work8);

			PC++;
			return(15);
		}


	case 0xb7: 
		{
			A&=0xbf;
			PC++;
			return(8);
		}


	case 0xb4: 
		{
			H&=0xbf;
			PC++;
			return(8);
		}

	case 0xb5: 


		{
			L&=0xbf;
			PC++;
			return(8);
		}

	case 0xb0: 
		{
			B&=0xbf;
			PC++;
			return(8);
		}

	case 0xb1: 
		{
			C&=0xbf;

			PC++;
			return(8);
		}

	case 0xb2: 
		{

			D&=0xbf;
			PC++;
			return(8);
		}

	case 0xb3: 
		{
			E&=0xbf;
			PC++;
			return(8);
		}

	case 0xb6: 
		{

			work8=io_readByte(HL);
			work8&=0xbf;
			io_writeByte(HL,work8);

			PC++;
			return(15);
		}

	case 0xbf: 
		{
			A&=0x7f;
			PC++;
			return(8);
		}

	case 0xbc: 
		{
			H&=0x7f;
			PC++;
			return(8);
		}

	case 0xbd: 
		{
			L&=0x7f;
			PC++;
			return(8);
		}

	case 0xb8: 
		{
			B&=0x7f;
			PC++;
			return(8);
		}

	case 0xb9: 
		{
			C&=0x7f;
			PC++;
			return(8);
		}

	case 0xba: 
		{
			D&=0x7f;
			PC++;
			return(8);
		}

	case 0xbb: 
		{
			E&=0x7f;
			PC++;
			return(8);
		}

	case 0xbe: 
		{
			work8=io_readByte(HL);
			work8&=0x7f;
			io_writeByte(HL,work8);


			PC++;
			return(15);
		}

		/* proverka bitov */

	case 0x47: 
		{
			bit(A,0);
			PC++;
			return(8);
		}

	case 0x44: 
		{
			bit(H,0);
			PC++;
			return(8);
		}

	case 0x45: 
		{
			bit(L,0);
			PC++;
			return(8);
		}

	case 0x40: 
		{
			bit(B,0);
			PC++;
			return(8);
		}

	case 0x41: 
		{
			bit(C,0);
			PC++;
			return(8);
		}

	case 0x42: 
		{

			bit(D,0);
			PC++;
			return(8);
		}

	case 0x43: 
		{
			bit(E,0);
			PC++;
			return(8);
		}

	case 0x46: 
		{
			bit(io_readByte(HL),0);
			PC++;
			return(15);
		}

	case 0x4f: 


		{
			bit(A,1);
			PC++;
			return(8);
		}

	case 0x4c: 
		{
			bit(H,1);
			PC++;
			return(8);
		}

	case 0x4d: 
		{
			bit(L,1);
			PC++;
			return(8);
		}


	case 0x48: 
		{
			bit(B,1);
			PC++;
			return(8);
		}

	case 0x49: 
		{
			bit(C,1);
			PC++;
			return(8);
		}

	case 0x4a: 
		{
			bit(D,1);
			PC++;
			return(8);
		}

	case 0x4b: 
		{
			bit(E,1);
			PC++;
			return(8);
		}

	case 0x4e: 
		{
			bit(io_readByte(HL),1);
			PC++;
			return(15);
		}


	case 0x57: 
		{
			bit(A,2);
			PC++;
			return(8);
		}

	case 0x54: 
		{
			bit(H,2);
			PC++;
			return(8);
		}

	case 0x55: 
		{
			bit(L,2);
			PC++;
			return(8);
		}

	case 0x50: 
		{
			bit(B,2);
			PC++;
			return(8);
		}

	case 0x51: 
		{
			bit(C,2);
			PC++;
			return(8);
		}

	case 0x52: 
		{
			bit(D,2);
			PC++;
			return(8);

		}

	case 0x53: 
		{
			bit(E,2);
			PC++;
			return(8);
		}

	case 0x56: 
		{
			bit(io_readByte(HL),2);
			PC++;
			return(15);
		}


	case 0x5f: 
		{
			bit(A,3);
			PC++;
			return(8);
		}

	case 0x5c: 
		{
			bit(H,3);
			PC++;
			return(8);
		}

	case 0x5d: 
		{
			bit(L,3);
			PC++;
			return(8);
		}

	case 0x58: 
		{
			bit(B,3);
			PC++;
			return(8);
		}

	case 0x59: 
		{
			bit(C,3);
			PC++;
			return(8);
		}

	case 0x5a: 
		{
			bit(D,3);
			PC++;
			return(8);
		}

	case 0x5b: 
		{
			bit(E,3);
			PC++;
			return(8);
		}

	case 0x5e: 
		{
			bit(io_readByte(HL),3);
			PC++;
			return(15);
		}


	case 0x67: 
		{
			bit(A,4);
			PC++;
			return(8);
		}

	case 0x64: 
		{
			bit(H,4);
			PC++;
			return(8);
		}

	case 0x65: 
		{
			bit(L,4);
			PC++;
			return(8);
		}

	case 0x60: 
		{
			bit(B,4);
			PC++;
			return(8);
		}

	case 0x61: 
		{
			bit(C,4);
			PC++;
			return(8);
		}

	case 0x62: 
		{
			bit(D,4);
			PC++;
			return(8);
		}

	case 0x63: 
		{
			bit(E,4);
			PC++;
			return(8);
		}

	case 0x66: 
		{
			bit(io_readByte(HL),4);
			PC++;
			return(15);
		}


	case 0x6f: 
		{
			bit(A,5);
			PC++;
			return(8);
		}

	case 0x6c: 
		{
			bit(H,5);
			PC++;
			return(8);
		}

	case 0x6d: 
		{
			bit(L,5);
			PC++;
			return(8);
		}

	case 0x68: 
		{
			bit(B,5);
			PC++;
			return(8);
		}

	case 0x69: 
		{
			bit(C,5);
			PC++;
			return(8);
		}

	case 0x6a: 
		{
			bit(D,5);
			PC++;
			return(8);
		}

	case 0x6b: 
		{
			bit(E,5);
			PC++;
			return(8);
		}

	case 0x6e: 
		{
			bit(io_readByte(HL),5);
			PC++;
			return(15);
		}


	case 0x77: 
		{
			bit(A,6);
			PC++;
			return(8);
		}

	case 0x74: 
		{
			bit(H,6);
			PC++;
			return(8);
		}

	case 0x75: 
		{

			bit(L,6);
			PC++;
			return(8);
		}

	case 0x70: 
		{
			bit(B,6);
			PC++;
			return(8);
		}


	case 0x71: 
		{
			bit(C,6);
			PC++;
			return(8);
		}

	case 0x72: 
		{
			bit(D,6);
			PC++;
			return(8);
		}

	case 0x73: 
		{
			bit(E,6);
			PC++;
			return(8);
		}

	case 0x76: 
		{
			bit(io_readByte(HL),6);
			PC++;
			return(15);
		}



	case 0x7f: 
		{
			bit(A,7);
			PC++;
			return(8);
		}

	case 0x7c: 
		{
			bit(H,7);
			PC++;
			return(8);
		}

	case 0x7d: 
		{
			bit(L,7);
			PC++;
			return(8);
		}

	case 0x78: 
		{
			bit(B,7);
			PC++;
			return(8);
		}

	case 0x79: 
		{
			bit(C,7);
			PC++;
			return(8);
		}

	case 0x7a: 
		{
			bit(D,7);
			PC++;
			return(8);
		}

	case 0x7b: 
		{
			bit(E,7);
			PC++;
			return(8);
		}

	case 0x7e: 
		{
			bit(io_readByte(HL),7);
			PC++;
			return(15);
		}

		/* komandi sdviga i rottatsii bitov */

		/* komandi srl */
	case 0x3f:
		{
			myFflagC_s( A & 0x01);                                                                  
			A >>= 1;                                                                                   
			znak(A);                                                
			zero(A);
			parity(A);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x3c:
		{
			myFflagC_s( H & 0x01);                                                                  
			H >>= 1;                                                                                   
			znak(H);                                                
			zero(H);
			parity(H);

			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x3d:
		{
			myFflagC_s( L & 0x01);                                                                  
			L>>= 1;                                                                                   
			znak(L);                                                
			zero(L);
			parity(L);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x38:
		{
			myFflagC_s( B & 0x01);                                                                  
			B>>= 1;                                                                                   
			znak(B);                                                
			zero(B);
			parity(B);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x39:
		{
			myFflagC_s( C & 0x01);                                                                  
			C>>= 1;                                                                                   

			znak(C);                                                
			zero(C);
			parity(C);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x3a:
		{
			myFflagC_s( D & 0x01);                                                                  
			D>>= 1;                                                                                   
			znak(D);                                                
			zero(D);
			parity(D);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x3b:
		{
			myFflagC_s( E & 0x01);                                                                  
			E>>= 1;                                                                                   
			znak(E);                                                
			zero(E);
			parity(E);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}


	case 0x3e:
		{
			myFflagC_s( io_readByte(HL) & 0x01);

			work8=io_readByte(HL);
			work8>>=1;
			io_writeByte(HL,work8);

			znak(io_readByte(HL));                                                
			zero(io_readByte(HL));
			parity(io_readByte(HL));
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(15);
		}

		/* komandi rlc */
	case 0x07:
		{
			myFflagC_s( ((A & 0x80) != 0));                                                 
			A= (A << 1) | myFflagC_r();
			znak(A);                                                
			zero(A);
			parity(A);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x04:
		{
			myFflagC_s( ((H & 0x80) != 0));                                                 
			H= (H << 1) | myFflagC_r();
			znak(H);                                                
			zero(H);

			parity(H);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x05:
		{
			myFflagC_s( ((L & 0x80) != 0));                                                 

			L= (L << 1) | myFflagC_r();
			znak(L);                                                
			zero(L);
			parity(L);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x00:
		{
			myFflagC_s( ((B & 0x80) != 0));                                                
			B= (B << 1) | myFflagC_r();

			znak(B);                                                
			zero(B);
			parity(B);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}



	case 0x01:
		{
			myFflagC_s( ((C & 0x80) != 0));                                                 
			C= (C << 1) | myFflagC_r();
			znak(C);                                                
			zero(C);
			parity(C);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x02:
		{
			myFflagC_s( ((D & 0x80) != 0));                                                 
			D= (D << 1) | myFflagC_r();

			znak(D);                                                
			zero(D);
			parity(D);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x03:
		{
			myFflagC_s( ((E & 0x80) != 0));                                                 
			E= (E << 1) | myFflagC_r();
			znak(E);                                                
			zero(E);
			parity(E);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x06:
		{
			myFflagC_s( ((io_readByte(HL) & 0x80) != 0));                                                 
			io_writeByte(HL, ((io_readByte(HL) << 1) | myFflagC_r()));
			znak(io_readByte(HL));                                                
			zero(io_readByte(HL));
			parity(io_readByte(HL));
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(15);
		}

		/* komandi rl */

	case 0x17:
		{
			work8 = ((A & 0x80) != 0);                                                
			A= (A << 1) | myFflagC_r();                                                  
			myFflagC_s( work8);
			znak(A);                                                
			zero(A);
			parity(A);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x14:
		{
			work8 = ((H & 0x80) != 0);                                                
			H= (H << 1) | myFflagC_r();                                                  
			myFflagC_s( work8 );
			znak(H);                                                
			zero(H);
			parity(H);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x15:
		{
			work8 = ((L & 0x80) != 0);                                                
			L= (L << 1) | myFflagC_r();                                                  
			myFflagC_s( work8 );
			znak(L);                                                
			zero(L);
			parity(L);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x10:
		{
			work8 = ((B & 0x80) != 0);                                                
			B= (B << 1) | myFflagC_r();                                                  
			myFflagC_s( work8 );
			znak(B);                                                
			zero(B);
			parity(B);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x11:

		{
			work8 = ((C & 0x80) != 0);                                                
			C= (C << 1) | myFflagC_r();                                                  
			myFflagC_s( work8 );
			znak(C);                                                
			zero(C);
			parity(C);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x12:
		{
			work8 = ((D & 0x80) != 0);                                                
			D= (D << 1) | myFflagC_r();                                                  
			myFflagC_s(work8 );
			znak(D);                                                
			zero(D);
			parity(D);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x13:
		{
			work8 = ((E & 0x80) != 0);                                                
			E= (E << 1) | myFflagC_r();                                                  
			myFflagC_s( work8 );
			znak(E);                                                
			zero(E);
			parity(E);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x16:
		{
			work8 = ((io_readByte(HL) & 0x80) != 0);                                                
			io_writeByte(HL, ((io_readByte(HL) << 1) | myFflagC_r()));                                                  
			myFflagC_s( work8 );
			znak(io_readByte(HL));                                                
			zero(io_readByte(HL));
			parity(io_readByte(HL));
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(15);
		}

		/* komandi rr */

	case 0x1f:
		{
			work8 = A & 0x01;                                                                 
			A= (A >> 1) | (myFflagC_r() * 128);                                   
			myFflagC_s( work8 );

			znak(A);                                                
			zero(A);
			parity(A);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x1c:
		{
			work8 = H & 0x01;                                                                 
			H= (H >> 1) | (myFflagC_r() * 128);                                   
			myFflagC_s( work8 );

			znak(H);                                                
			zero(H);
			parity(H);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x1d:
		{
			work8 = L & 0x01;                                                                 
			L= (L >> 1) | (myFflagC_r() * 128);                                   
			myFflagC_s( work8 );

			znak(L);                                                
			zero(L);
			parity(L);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x18:
		{
			work8 = B & 0x01;                                                                 
			B= (B >> 1) | (myFflagC_r() * 128);                                   
			myFflagC_s( work8 );

			znak(B);                                                
			zero(B);
			parity(B);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x19:
		{
			work8 = C & 0x01;                                                                 
			C= (C >> 1) | (myFflagC_r() * 128);                                   
			myFflagC_s( work8 );

			znak(C);                                                
			zero(C);
			parity(C);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x1a:
		{
			work8 = D & 0x01;                                                                 
			D= (D >> 1) | (myFflagC_r() * 128);                                   
			myFflagC_s( work8 );

			znak(D);                                                
			zero(D);
			parity(D);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x1b:
		{
			work8 = E & 0x01;                                                                 
			E= (E >> 1) | (myFflagC_r() * 128);                                   
			myFflagC_s( work8 );

			znak(E);                                                
			zero(E);
			parity(E);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x1e:
		{
			work8 = io_readByte(HL) & 0x01;                                                                 
			io_writeByte(HL, ((io_readByte(HL) >> 1) | (myFflagC_r() * 128)));                                   
			myFflagC_s( work8 );

			znak(io_readByte(HL));                                                
			zero(io_readByte(HL));
			parity(io_readByte(HL));
			myFflagH_s(0);
			myFflagN_s(0);


			PC++;

			return(15);
		}

		/* komandi sla */

	case 0x27:
		{  
			myFflagC_s( ((A & 0x80) != 0) );                                                 
			A<<= 1;                                                                                    


			znak(A);                                                
			zero(A);
			parity(A);
			myFflagH_s(0);
			myFflagN_s(0);


			PC++;
			return(8);
		}

	case 0x24:
		{  
			myFflagC_s( ((H & 0x80) != 0) );                                                 
			H<<= 1;                                                                               

			znak(H);                                                
			zero(H);

			parity(H);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x25:
		{  
			myFflagC_s( ((L & 0x80) != 0) );                                                 
			L<<= 1;                                                                                    

			znak(L);                                                
			zero(L);
			parity(L);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;

			return(8);
		}

	case 0x20:
		{  
			myFflagC_s( ((B & 0x80) != 0) );                                                 
			B<<= 1;                                                                                    

			znak(B);                                                
			zero(B);
			parity(B);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x21:
		{  
			myFflagC_s( ((C & 0x80) != 0));                                                 

			C<<= 1;                                                                                    


			znak(C);                                                
			zero(C);
			parity(C);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x22:
		{  
			myFflagC_s( ((D & 0x80) != 0));                                                 
			D<<= 1;                                                                                    

			znak(D);                                                
			zero(D);
			parity(D);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x23:
		{  
			myFflagC_s( ((E & 0x80) != 0) );                                                 
			E <<= 1;                                                                                    

			znak(E);                                                
			zero(E);
			parity(E);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x26:

		{  
			myFflagC_s( ((io_readByte(HL) & 0x80) != 0));                                                 


			work8=io_readByte(HL);
			work8<<=1;
			io_writeByte(HL,work8);

			znak(io_readByte(HL));                                                
			zero(io_readByte(HL));
			parity(io_readByte(HL));

			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(15);
		}


		/* komandi rrc */

	case 0x0f:
		{
			myFflagC_s( A & 0x01 );                                                                  
			A= (A >> 1) | (myFflagC_r() * 128);                                   

			znak(A);                                                
			zero(A);
			parity(A);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);	
		}

	case 0x0c:
		{
			myFflagC_s( H & 0x01 );                                                                  
			H= (H >> 1) | (myFflagC_r() * 128);                                   

			znak(H);                                                
			zero(H);
			parity(H);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);	
		}

	case 0x0d:
		{
			myFflagC_s( L & 0x01);                                                                  
			L= (L >> 1) | (myFflagC_r() * 128);                                   

			znak(L);                                                
			zero(L);
			parity(L);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);	
		}

	case 0x08:
		{
			myFflagC_s( B & 0x01);                                                                  
			B= (B >> 1) | (myFflagC_r() * 128);                                   

			znak(B);                                                
			zero(B);
			parity(B);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);	
		}

	case 0x09:

		{
			myFflagC_s( C & 0x01);                                                                  
			C= (C >> 1) | (myFflagC_r() * 128);                                   

			znak(C);                                                
			zero(C);
			parity(C);
			myFflagH_s(0);
			myFflagN_s(0);


			PC++;
			return(8);	
		}

	case 0x0a:
		{
			myFflagC_s( D & 0x01 );                                                                  
			D= (D >> 1) | (myFflagC_r() * 128);                                   

			znak(D);                                                
			zero(D);
			parity(D);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);	
		}

	case 0x0b:
		{
			myFflagC_s( E & 0x01 );                                                                  
			E= (E >> 1) | (myFflagC_r() * 128);                                   

			znak(E);                                                
			zero(E);
			parity(E);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);	
		}

	case 0x0e:
		{
			myFflagC_s( io_readByte(HL) & 0x01);                                                                  
			io_writeByte(HL, ((io_readByte(HL) >> 1) | (myFflagC_r() * 128)));                                   

			znak(io_readByte(HL));                                                
			zero(io_readByte(HL));
			parity(io_readByte(HL));
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(15);	
		}

		/* komandi sra */

	case 0x2f:
		{
			myFflagC_s( A & 0x01);                                                                  
			work8 = A & 0x80;                                                                 
			A= (A >> 1) | work8;                                                 

			znak(A);                                                
			zero(A);
			parity(A);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x2c:
		{
			myFflagC_s( H & 0x01);                                                                  
			work8 = H & 0x80;                                                                 
			H= (H >> 1) | work8;                                                 

			znak(H);                                                
			zero(H);
			parity(H);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x2d:
		{
			myFflagC_s( L & 0x01 );                                                                  
			work8 = L & 0x80;                                                                 
			L= (L >> 1) | work8;                                                 

			znak(L);                                                
			zero(L);
			parity(L);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x28:
		{
			myFflagC_s( B & 0x01);                                                                  
			work8 = B & 0x80;                                                                 
			B= (B >> 1) | work8;                                                 

			znak(B);                                                
			zero(B);
			parity(B);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x29:
		{
			myFflagC_s( C & 0x01 );                                                                  
			work8 = C & 0x80;                                                                 
			C= (C >> 1) | work8;                                                 

			znak(C);                                                
			zero(C);
			parity(C);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x2a:
		{
			myFflagC_s( D & 0x01 );                                                                  
			work8 = D & 0x80;                                                                 
			D= (D >> 1) | work8;                                                 

			znak(D);                                                
			zero(D);
			parity(D);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x2b:
		{
			myFflagC_s( E & 0x01 );                                                                  
			work8 = E & 0x80;                                                                 
			E= (E >> 1) | work8;                                                 

			znak(E);                                                
			zero(E);
			parity(E);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x2e:
		{
			myFflagC_s( io_readByte(HL) & 0x01 );                                                                  
			work8 = io_readByte(HL) & 0x80;                                                                 
			io_writeByte(HL, ((io_readByte(HL) >> 1) | work8));                                                 

			znak(io_readByte(HL));                                                
			zero(io_readByte(HL));
			parity(io_readByte(HL));
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

		/* komandi sli */

	case 0x30:
		{
			myFflagC_s( ((B & 0x80) != 0));
			B= (B << 1) | 0x01;

			znak(B);
			zero(B);
			parity(B);

			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x31:
		{
			myFflagC_s( ((C & 0x80) != 0));
			C= (C << 1) | 0x01;

			znak(C);
			zero(C);
			parity(C);

			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x32:
		{
			myFflagC_s( ((D & 0x80) != 0));
			D= (D << 1) | 0x01;

			znak(D);
			zero(D);
			parity(D);

			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}

	case 0x33:
		{
			myFflagC_s( ((E & 0x80) != 0));
			E= (E << 1) | 0x01;

			znak(E);
			zero(E);
			parity(E);

			myFflagH_s(0);
			myFflagN_s(0);



			PC++;
			return(8);
		}	
	case 0x34:
		{
			myFflagC_s( ((H & 0x80) != 0));
			H= (H << 1) | 0x01;

			znak(H);
			zero(H);
			parity(H);

			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}	

	case 0x35:
		{

			myFflagC_s( ((L & 0x80) != 0));
			L= (L << 1) | 0x01;

			znak(L);
			zero(L);
			parity(L);

			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}	

	case 0x36:
		{
			work8 = io_readByte(HL);

			myFflagC_s( ((work8 & 0x80) != 0));
			work8= (work8 << 1) | 0x01;


			znak(work8);
			zero(work8);
			parity(work8);

			myFflagH_s(0);
			myFflagN_s(0);

			io_writeByte(HL, work8);

			PC++;
			return(15);
		}	

	case 0x37:
		{
			myFflagC_s( ((A & 0x80) != 0));
			A= (A << 1) | 0x01;

			znak(A);
			zero(A);
			parity(A);

			myFflagH_s(0);
			myFflagN_s(0);	

			PC++;
			return(8);
		}
	}

	printf("\nZ80 : Unknown instruction cb%x at address %x.\n",io_readByte(PC),PC-1);
	ExitWithError(-1,"");

	return(0); /* eto chtob ne kvakalo */
}

int FD (void)
{
	switch(io_readByte(PC))
	{
	case 0x21: /* ld iy, nn */
		{
			io_writeToRamAddrSpAddr((unsigned char *)&IY, PC+1);
			PC+=3;
			return(14);
		}

	case 0xf9: /* ld sp, iy */
		{
			SP=IY;
			PC++;
			return(10);
		}

	case 0x2a: /* ld iy, (nn) */
		{
			io_writeToRamAddrSpAddr((unsigned char *)&IY, ex(io_readByte(PC+2), io_readByte(PC+1)));

			PC+=3;
			return(20);
		}

	case 0x22: /* ld (nn), iy */
		{
			io_writeToSpAddrVal(ex(io_readByte(PC+2), io_readByte(PC+1)), IY);

			PC+=3;
			return(20);
		}

		/* zagruzka registrov iz pamyati indexnoy adresatsiei */

	case 0x7e: 
		{

			A=io_readByte(IY+(signed char)io_readByte(PC+1));
			PC+=2;
			return(19);
		}

	case 0x66: 

		{
			H=io_readByte(IY+(signed char)io_readByte(PC+1));
			PC+=2;
			return(19);
		}

	case 0x6e: 
		{
			L=io_readByte(IY+(signed char)io_readByte(PC+1));
			PC+=2;
			return(19);
		}

	case 0x46: 
		{
			B=io_readByte(IY+(signed char)io_readByte(PC+1));
			PC+=2;
			return(19);
		}

	case 0x4e: 
		{
			C=io_readByte(IY+(signed char)io_readByte(PC+1));
			PC+=2;
			return(19);
		}

	case 0x56: 
		{
			D=io_readByte(IY+(signed char)io_readByte(PC+1));
			PC+=2;
			return(19);
		}

	case 0x5e: 
		{
			E=io_readByte(IY+(signed char)io_readByte(PC+1));
			PC+=2;
			return(19);
		}

		/* zapis' v pamyat' indexnoy adresatsiei */

	case 0x77: 
		{
			io_writeByte(IY+(signed char)io_readByte(PC+1),A);
			PC+=2;
			return(19);
		}


	case 0x74: 
		{
			io_writeByte(IY+(signed char)io_readByte(PC+1),H);
			PC+=2;
			return(19);
		}

	case 0x75: 
		{
			io_writeByte(IY+(signed char)io_readByte(PC+1),L);
			PC+=2;
			return(19);
		}

	case 0x70: 
		{
			io_writeByte(IY+(signed char)io_readByte(PC+1),B);
			PC+=2;
			return(19);
		}

	case 0x71: 
		{
			io_writeByte(IY+(signed char)io_readByte(PC+1),C);
			PC+=2;
			return(19);
		}

	case 0x72: 
		{
			io_writeByte(IY+(signed char)io_readByte(PC+1),D);
			PC+=2;
			return(19);
		}

	case 0x73: 
		{
			io_writeByte(IY+(signed char)io_readByte(PC+1),E);
			PC+=2;
			return(19);
		}

	case 0x36: 
		{
			io_writeByte(IY+(signed char)io_readByte(PC+1),io_readByte(PC+2));
			PC+=3;
			return(19);
		}

	case 0xa6: /* and (iy+s) */
		{
			A=A&(io_readByte(IY+(signed char)io_readByte(PC+1)));

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC+=2;
			return(19);
		}	

	case 0xb6: /* or (iy+s) */
		{
			A=A|(io_readByte(IY+(signed char)io_readByte(PC+1)));

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC+=2;
			return(19);
		}	

	case 0xae: /* xor (iy+s) */
		{
			A=A^(io_readByte(IY+(signed char)io_readByte(PC+1)));

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC+=2;
			return(19);
		}	

	case 0xe9: /* jp (iy) */
		{
			PC=IY;
			return(8);
		}

	case 0x35: /* dec (iy+s) */
		{
			work8=io_readByte(IY+(signed char)io_readByte(PC+1));
			work8--;
			io_writeByte(IY+(signed char)io_readByte(PC+1),work8);

			znak(io_readByte(IY+(signed char)io_readByte(PC+1)));
			zero(io_readByte(IY+(signed char)io_readByte(PC+1)));
			myFflagPV_s((io_readByte(IY+(signed char)io_readByte(PC+1))==0x7f));
			myFflagN_s(1);
			myFflagH_s(((io_readByte(IY+(signed char)io_readByte(PC+1))&0x0f)==0x0f));

			PC+=2;
			return(23);
		}

	case 0x2b: /* dec iy */
		{
			IY--;
			PC++;
			return(10);
		}


	case 0xbe: /* cp (iy+s) */
		{	
			val=io_readByte(IY+(signed char)io_readByte(PC+1));

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                                
			myFflagZ_s(   ((work16 & 0xff) == 0));                                                

			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC+=2;
			return(19);
		}

	case 0x9e: /* sbc a, (iy+s) */
		{
			val=io_readByte(IY+(signed char)io_readByte(PC+1));

			work16 = A - (val) - myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;                                                                              
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC+=2;
			return(19);
		}

	case 0x86: /* add a, (iy+s) */
		{
			val=io_readByte(IY+(signed char)io_readByte(PC+1));

			work16 = A + (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                              
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s(   overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC+=2;
			return(19);
		}

		/* komandi prostogo slojeniya */

	case 0x29:
		{
			reg=IY;
			XX=IY;

			work32 = XX + (reg);                                            
			idx = ((XX & 0x0800) >> 9) |                                    
				(((reg) & 0x0800) >> 10) |                            
				((work32 & 0x0800) >> 11);                            
			XX = work32 & 0xffff;                                           
			myFflagH_s(hcarry_tbl(idx));                                     
			myFflagN_s(0);                                                    
			myFflagC_s(((work32 & 0x10000) != 0));  
			IY=XX;

			PC++;
			return(15);
		}

	case 0x09:
		{
			reg=BC;
			XX=IY;

			work32 = XX + (reg);                                            
			idx = ((XX & 0x0800) >> 9) |                                    
				(((reg) & 0x0800) >> 10) |                            
				((work32 & 0x0800) >> 11);                            
			XX = work32 & 0xffff;                                           
			myFflagH_s(   hcarry_tbl(idx));                                     
			myFflagN_s(0);                                                    
			myFflagC_s( ((work32 & 0x10000) != 0));  
			IY=XX;

			PC++;
			return(15);
		}

	case 0x19:
		{
			reg=DE;
			XX=IY;

			work32 = XX + (reg);                                            
			idx = ((XX & 0x0800) >> 9) |                                    
				(((reg) & 0x0800) >> 10) |                            
				((work32 & 0x0800) >> 11);                            
			XX = work32 & 0xffff;                                           
			myFflagH_s(   hcarry_tbl(idx));                                     
			myFflagN_s(0);                                                    
			myFflagC_s( ((work32 & 0x10000) != 0));  
			IY=XX;

			PC++;
			return(15);
		}

	case 0x39:
		{
			reg=SP;
			XX=IY;

			work32 = XX + (reg);                                            
			idx = ((XX & 0x0800) >> 9) |                                    
				(((reg) & 0x0800) >> 10) |                            
				((work32 & 0x0800) >> 11);                            
			XX = work32 & 0xffff;                                           
			myFflagH_s(   hcarry_tbl(idx));                                     
			myFflagN_s(0);                                                    
			myFflagC_s( ((work32 & 0x10000) != 0));  
			IY=XX;

			PC++;
			return(15);
		}

	case 0x34 : /* inc (iy+s) */
		{
			reg=io_readByte(IY+(signed char)io_readByte(PC+1));

			reg++;                                                                                                
			znak(reg);                                                 
			zero(reg);                                                                  
			myFflagH_s(   (((reg) & 0x0f) == 0));                                                 
			myFflagPV_s(   ((reg) == 0x80));                                                               
			myFflagN_s(0);
			io_writeByte(IY+(signed char)io_readByte(PC+1), reg);

			PC+=2;
			return(23);
		}

	case 0x23 : /* inc iy */
		{
			IY++;

			PC++;
			return(10);
		}

	case 0xcb :  
		{
			switch(io_readByte(PC+2))
			{
				/* vklyuchenie bitov */
			case 0xc6: 

				{
					work8=io_readByte(IY+(signed char)io_readByte(PC+1));
					work8|=1;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0xce: 
				{
					work8=io_readByte(IY+(signed char)io_readByte(PC+1));
					work8|=2;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);

					break;
				}

			case 0xd6: 

				{
					work8=io_readByte(IY+(signed char)io_readByte(PC+1));

					work8|=4;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0xde: 
				{
					work8=io_readByte(IY+(signed char)io_readByte(PC+1));
					work8|=8;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0xe6: 
				{
					work8=io_readByte(IY+(signed char)io_readByte(PC+1));
					work8|=16;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0xee: 
				{
					work8=io_readByte(IY+(signed char)io_readByte(PC+1));
					work8|=32;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0xf6: 
				{
					work8=io_readByte(IY+(signed char)io_readByte(PC+1));
					work8|=64;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0xfe: 
				{
					work8=io_readByte(IY+(signed char)io_readByte(PC+1));
					work8|=128;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);

					break;
				}

				/* viklyuchenie bitov */
			case 0x86: 
				{
					work8=io_readByte(IY+(signed char)io_readByte(PC+1));
					work8&=0xfe;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0x8e: 
				{
					work8=io_readByte(IY+(signed char)io_readByte(PC+1));
					work8&=0xfd;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0x96: 
				{
					work8=io_readByte(IY+(signed char)io_readByte(PC+1));

					work8&=0xfb;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0x9e:
				{
					work8=io_readByte(IY+(signed char)io_readByte(PC+1));
					work8&=0xf7;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);


					break;
				}
			case 0xa6: 
				{
					work8=io_readByte(IY+(signed char)io_readByte(PC+1));
					work8&=0xef;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0xae: 
				{
					work8=io_readByte(IY+(signed char)io_readByte(PC+1));
					work8&=0xdf;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0xb6: 
				{
					work8=io_readByte(IY+(signed char)io_readByte(PC+1));
					work8&=0xbf;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0xbe: 
				{
					work8=io_readByte(IY+(signed char)io_readByte(PC+1));
					work8&=0x7f;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);


					break;
				}

				/* poriverka bitov */
			case 0x40:
			case 0x41:
			case 0x42:
			case 0x43:
			case 0x44:
			case 0x45:
			case 0x47:	
			case 0x46: 
				{
					bit(io_readByte(IY+(signed char)io_readByte(PC+1)),0);							
					break;
				}
			case 0x48:
			case 0x49:
			case 0x4a:
			case 0x4b:
			case 0x4c:
			case 0x4d:
			case 0x4e:	
			case 0x4f: 
				{
					bit(io_readByte(IY+(signed char)io_readByte(PC+1)),1);							
					break;
				}
			case 0x56: 
				{
					bit(io_readByte(IY+(signed char)io_readByte(PC+1)),2);							
					break;
				}
			case 0x5e: 
				{
					bit(io_readByte(IY+(signed char)io_readByte(PC+1)),3);							
					break;
				}
			case 0x66: 
				{
					bit(io_readByte(IY+(signed char)io_readByte(PC+1)),4);							
					break;
				}
			case 0x6e: 
				{
					bit(io_readByte(IY+(signed char)io_readByte(PC+1)),5);							
					break;
				}

			case 0x76: 
				{
					bit(io_readByte(IY+(signed char)io_readByte(PC+1)),6);							
					break;
				}
			case 0x7e: 
			case 0x7F:
				{
					bit(io_readByte(IY+(signed char)io_readByte(PC+1)),7);							
					break;
				}

			case 0x3e: /* srl (iy+s) */


				{
					myFflagC_s( io_readByte(IY+(signed char)io_readByte(PC+1)) & 0x01);                                                                  

					work8=io_readByte(IY+(signed char)io_readByte(PC+1));
					work8>>=1;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);

					znak(io_readByte(IY+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IY+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IY+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}

			case 0x0e: /* rrc (iy+s) */
				{
					myFflagC_s( io_readByte(IY+(signed char)io_readByte(PC+1)) & 0x01);                                                                  

					io_writeByte(IY+(signed char)io_readByte(PC+1), (io_readByte(IY+(signed char)io_readByte(PC+1)) >> 1) | (myFflagC_r() * 128));                                   

					znak(io_readByte(IY+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IY+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IY+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}

			case 0x26: /* sla (iy+s) */
				{  
					myFflagC_s( ((io_readByte(IY+(signed char)io_readByte(PC+1)) & 0x80) != 0));                                                 

					work8=io_readByte(IY+(signed char)io_readByte(PC+1));
					work8<<=1;
					io_writeByte(IY+(signed char)io_readByte(PC+1),work8);


					znak(io_readByte(IY+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IY+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IY+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}

			case 0x1e: /* rr (iy+s) */
				{
					work8 = io_readByte(IY+(signed char)io_readByte(PC+1)) & 0x01;                                                                 
					io_writeByte(IY+(signed char)io_readByte(PC+1),(io_readByte(IY+(signed char)io_readByte(PC+1)) >> 1) | (myFflagC_r() * 128));                                   
					myFflagC_s( work8);

					znak(io_readByte(IY+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IY+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IY+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}

			case 0x06: /* rlc (iy+s) */
				{
					myFflagC_s( ((io_readByte(IY+(signed char)io_readByte(PC+1)) & 0x80) != 0));                                                 
					io_writeByte(IY+(signed char)io_readByte(PC+1),(io_readByte(IY+(signed char)io_readByte(PC+1)) << 1) | myFflagC_r());

					znak(io_readByte(IY+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IY+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IY+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}

			case 0x16: /* rl (iy+s) */
				{
					work8 = ((io_readByte(IY+(signed char)io_readByte(PC+1)) & 0x80) != 0);                                                
					io_writeByte(IY+(signed char)io_readByte(PC+1), ((io_readByte(IY+(signed char)io_readByte(PC+1)) << 1) | myFflagC_r()));                                                  
					myFflagC_s( work8);
					znak(io_readByte(IY+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IY+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IY+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}

			case 0x2e: /* sra (iy+s) */
				{
					myFflagC_s( io_readByte(IY+(signed char)io_readByte(PC+1)) & 0x01);                                                                  
					work8 = io_readByte(IY+(signed char)io_readByte(PC+1)) & 0x80;                                                                 
					io_writeByte(IY+(signed char)io_readByte(PC+1), ((io_readByte(IY+(signed char)io_readByte(PC+1)) >> 1) | work8));                                                 

					znak(io_readByte(IY+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IY+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IY+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}

			case 0x0f:
				{
					A = io_readByte(IY+(signed char)io_readByte(PC+1));                                                        

					myFflagC_s( A & 0x01);                                                                  
					A= (A >> 1) | (myFflagC_r() * 128);                                   

					znak(A);                                                
					zero(A);
					parity(A);
					myFflagH_s(0);
					myFflagN_s(0);

					io_writeByte(IY+(signed char)io_readByte(PC+1), A); 

					break; 
				}	

			case 0x00:
				{
					B = io_readByte((IY+(signed char)io_readByte(PC+1)));                                                                                   
					RLC(&B);                                                                                               
					io_writeByte((IY+(signed char)io_readByte(PC+1)), B);                                                                                    
					break;  
				}



			case 0x01:
				{
					C = io_readByte((IY+(signed char)io_readByte(PC+1)));                                                                                   
					RLC(&C);                                                                                               
					io_writeByte((IY+(signed char)io_readByte(PC+1)), C);                                                                                    
					break;  
				}

			case 0x02:
				{
					D = io_readByte((IY+(signed char)io_readByte(PC+1)));                                                                                   
					RLC(&D);                                                                                               
					io_writeByte((IY+(signed char)io_readByte(PC+1)), D);                                                                                    
					break;  
				}

			case 0x03:

				{
					//					unsigned short SS =  IY+(signed char)io_readByte(PC+1);
					//printf ("SS=%d \n", SS);
					E = io_readByte((IY+(signed char)io_readByte(PC+1)));                                                                                   
					//				printf ("E=%d \n", E);
					RLC(&E);
					//			printf ("RLC(E)=%d \n", E);
					io_writeByte((IY+(signed char)io_readByte(PC+1)), E);                                                                                    
					break;  
				}

			case 0x04:
				{
					H = io_readByte((IY+(signed char)io_readByte(PC+1)));                                                                                   
					RLC(&H);                                                                                               
					io_writeByte((IY+(signed char)io_readByte(PC+1)), H);                                                                                    

					break;  
				}

			case 0x05:
				{
					L = io_readByte((IY+(signed char)io_readByte(PC+1)));                                                                                   
					RLC(&L);                                                                                               
					io_writeByte((IY+(signed char)io_readByte(PC+1)), L);                                                                                    
					break;  
				}

			default :
				printf("Z80 :  fd cb S %2x. Unknown. PC=%4x.\n",io_readByte(PC+2),PC-1);
				ExitWithError(-1,"");
			}

			PC+=3;
			return(23);
		}

	case 0xe5 : /* push iy */
		{
			push(IY);

			PC++;
			return(15);
		}

	case 0x96 : /* sub (iy+s) */
		{
			val=io_readByte(IY+(signed char)io_readByte(PC+1));	

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              

			ZnakA;                                                             
			ZeroA;                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s( sub_overflow_tbl(idx >> 4) );                                    

			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC+=2;
			return(19);
		}

	case 0xe1 : /* pop iy */
		{
			pop(&IY);

			PC++;
			return(14);
		}

	case 0x8e: /* adc a,(iy+s) */
		{
			val=io_readByte(IY+(signed char)io_readByte(PC+1));

			work16 = A + (val) + myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;

			ZeroA;
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s( overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC+=2;
			return(19);
		}

	case 0xe3 : /* ex (sp),iy */

		{
			pop(&XX);
			push(IY);
			IY=XX;

			PC++;
			return(23);
		}


		/* operatsii s polovinkami IY start */

	case 0x24: /* inc IYh   */
		{
			IYh++;

			znak(IYh);                                                 
			zero(IYh);                                                                  
			myFflagH_s(   (((IYh) & 0x0f) == 0));                                                 
			myFflagPV_s(   ((IYh) == 0x80));                                                               


			myFflagN_s(0);

			PC++;
			return(8);                                                              
		}	


	case 0x25:   /* dec IYh */
		{
			IYh--;


			znak(IYh);
			zero(IYh);
			myFflagPV_s((IYh==0x7f));
			myFflagN_s(1);
			myFflagH_s(    ((IYh&0x0f)==0x0f));

			PC++;
			return(8); 
		}

	case 0x26: 
		{
			IYh=io_readByte(PC+1);

			PC+=2;
			return(11);
		}

	case 0x2c: /* inc IYl   */
		{
			IYl++;

			znak(IYl);                                                 
			zero(IYl);                                                                  
			myFflagH_s(   (((IYl) & 0x0f) == 0));                                                 
			myFflagPV_s(   ((IYl) == 0x80));                                                               
			myFflagN_s(0);

			PC++;
			return(8);                                                              
		}	

	case 0x2d:   /* dec IYl */
		{
			IYl--;

			znak(IYl);
			zero(IYl);
			myFflagPV_s((IYl==0x7f));
			myFflagN_s(1);
			myFflagH_s(    ((IYl&0x0f)==0x0f));

			PC++;
			return(8); 
		}

	case 0x2e: 
		{
			IYl=io_readByte(PC+1);

			PC+=2;
			return(11);
		}

	case 0x44:    
		{
			B=IYh;

			PC++;
			return(8);
		}

	case 0x45:    
		{
			B=IYl;

			PC++;
			return(8);
		}	

	case 0x4c:    
		{
			C=IYh;

			PC++;
			return(8);
		}

	case 0x4d:    
		{
			C=IYl;

			PC++;
			return(8);
		}	

	case 0x54:    
		{
			D=IYh;

			PC++;
			return(8);
		}

	case 0x55:    
		{
			D=IYl;

			PC++;
			return(8);
		}	

	case 0x5c:    
		{
			E=IYh;

			PC++;
			return(8);
		}

	case 0x5d:    
		{
			E=IYl;

			PC++;
			return(8);
		}	

	case 0x60:    
		{
			IYh=B;

			PC++;
			return(8);
		}	

	case 0x61:    
		{
			IYh=C;

			PC++;
			return(8);
		}	

	case 0x62:    
		{
			IYh=D;

			PC++;
			return(8);
		}	

	case 0x63:    
		{
			IYh=E;

			PC++;
			return(8);
		}	

	case 0x64:    
		{
			IYh=IYh;

			PC++;
			return(8);
		}	

	case 0x65:    
		{
			IYh=IYl;

			PC++;
			return(8);
		}	


	case 0x67:    
		{
			IYh=A;

			PC++;
			return(8);
		}	


	case 0x68:    
		{
			IYl=B;

			PC++;
			return(8);
		}	

	case 0x69:    
		{
			IYl=C;

			PC++;
			return(8);
		}	

	case 0x6a:    
		{
			IYl=D;

			PC++;
			return(8);
		}	

	case 0x6b:    
		{
			IYl=E;

			PC++;
			return(8);
		}	

	case 0x6c:    
		{
			IYl=IYh;

			PC++;
			return(8);
		}	

	case 0x6d:    
		{
			IYl=IYl;

			PC++;
			return(8);
		}	

	case 0x6f:    
		{
			IYl=A;

			PC++;
			return(8);
		}

	case 0x7c:    

		{
			A=IYh;

			PC++;
			return(8);
		}


	case 0x7d:    
		{
			A=IYl;

			PC++;
			return(8);
		}

	case 0x84:
		{
			val=IYh;

			work16 = A + (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                              
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s(   overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(8);	
		}

	case 0x85:
		{
			val=IYl;

			work16 = A + (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                              
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 

			myFflagPV_s(   overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(8);	
		}

	case 0x8c:
		{
			val=IYh;

			work16 = A + (val) + myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s( overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(8);
		}

	case 0x8d:
		{
			val=IYl;

			work16 = A + (val) + myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s( overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(8);
		}

	case 0x94 :
		{
			val=IYh;	

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s( sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(8);
		}

	case 0x95 :
		{
			val=IYl;	

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s( sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(8);
		}

	case 0x9c:
		{
			val=IYh;

			work16 = A - (val) - myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;                                                                              
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(8);
		}

	case 0x9d:
		{
			val=IYl;

			work16 = A - (val) - myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;                                                                              
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work16 & 0x0100) != 0));


			PC++;
			return(8);
		}

	case 0xa4:


		{
			A=A&IYh;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}	

	case 0xa5:
		{
			A=A&IYl;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}	

	case 0xac:

		{
			A=A^IYh;


			ParityA;




			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}	

	case 0xad:
		{
			A=A^IYl;

			ParityA;

			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}	

	case 0xb4:
		{
			A=A|IYh;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}	

	case 0xb5:
		{
			A=A|IYl;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}	

	case 0xbc:
		{	
			val=IYh;



			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                                
			myFflagZ_s(   ((work16 & 0xff) == 0));                                                
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(8);
		}

	case 0xbd:
		{	
			val=IYl;

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                                
			myFflagZ_s(   ((work16 & 0xff) == 0));                                                
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0) );

			PC++;
			return(8);
		}

	case 0x3b: /* dec SP */
		{
			SP--;

			PC++;
			return(10);
		}

	case 0xbf: /* NOP */
		{	

			PC++;
			return(8);
		}

	case 0xaf: /* NOP */
		{

			PC++;
			return(8);
		}	

	default :
		return(z80a(0)+4);
	}

	printf("\nZ80 : Unknown instruction fd%x at address %x.\n",io_readByte(PC),PC-1);
	ExitWithError(-1,"");
}


int DD (void)
{
	switch(io_readByte(PC))
	{

	case 0x21: /*ld ix, nn*/
		{
			io_writeToRamAddrSpAddr((unsigned char *)&IX,PC+1);
			PC+=3;
			return(14);
		}

	case 0xf9: /*ld sp, ix*/
		{
			SP=IX;
			PC++;
			return(10);
		}

	case 0x5b: /* ld de, (nn) */
		{
			E=io_readByte(ex(io_readByte(PC+2),io_readByte(PC+1)));
			D=io_readByte(ex(io_readByte(PC+2),io_readByte(PC+1))+1);
			PC+=3;
			return(20);
		}

	case 0x2a: /* ld ix, (nn) */
		{
			io_writeToRamAddrSpAddr((unsigned char *)&IX, ex(io_readByte(PC+2),io_readByte(PC+1)));
			PC+=3;
			return(20);
		}

	case 0x22: /* ld (nn), ix */
		{
			io_writeToSpAddrVal(ex(io_readByte(PC+2),io_readByte(PC+1)),IX);
			PC+=3;
			return(20);
		}

		/* zagruzka registrov iz pamyati indexnoy adresatsiei */

	case 0x7e: 
		{
			A=io_readByte(IX+(signed char)io_readByte(PC+1));
			PC+=2;
			return(19);
		}

	case 0x66: 
		{
			H=io_readByte(IX+(signed char)io_readByte(PC+1));
			PC+=2;
			return(19);
		}

	case 0x6e: 
		{
			L=io_readByte(IX+(signed char)io_readByte(PC+1));
			PC+=2;
			return(19);
		}

	case 0x46: 
		{

			B=io_readByte(IX+(signed char)io_readByte(PC+1));

			PC+=2;
			return(19);
		}

	case 0x4e: 
		{

			C=io_readByte(IX+(signed char)io_readByte(PC+1));
			PC+=2;
			return(19);
		}

	case 0x56: 
		{
			D=io_readByte(IX+(signed char)io_readByte(PC+1));
			PC+=2;
			return(19);
		}

	case 0x5e: 
		{
			E=io_readByte(IX+(signed char)io_readByte(PC+1));
			PC+=2;
			return(19);
		}

		/* zapis' v pamyat' indexnoy adresatsiei */

	case 0x77: 
		{
			io_writeByte(IX+(signed char)io_readByte(PC+1),A);
			PC+=2;
			return(19);
		}

	case 0x74: 

		{
			io_writeByte(IX+(signed char)io_readByte(PC+1),H);
			PC+=2;
			return(19);
		}

	case 0x75: 
		{
			io_writeByte(IX+(signed char)io_readByte(PC+1),L);
			PC+=2;
			return(19);
		}

	case 0x70: 
		{
			io_writeByte(IX+(signed char)io_readByte(PC+1),B);
			PC+=2;
			return(19);
		}

	case 0x71: 
		{
			io_writeByte(IX+(signed char)io_readByte(PC+1),C);
			PC+=2;
			return(19);

		}

	case 0x72: 
		{
			io_writeByte(IX+(signed char)io_readByte(PC+1),D);
			PC+=2;
			return(19);
		}

	case 0x73: 
		{
			io_writeByte(IX+(signed char)io_readByte(PC+1),E);
			PC+=2;
			return(19);
		}

	case 0x36: 
		{
			io_writeByte(IX+(signed char)io_readByte(PC+1),io_readByte(PC+2));

			PC+=3;
			return(19);
		}

	case 0xa6: /* and (ix+s) */
		{
			A=A&(io_readByte(IX+(signed char)io_readByte(PC+1)));

			ParityA;

			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC+=2;
			return(19);
		}	


	case 0xb6: /* or (ix+s) */
		{
			A=A|(io_readByte(IX+(signed char)io_readByte(PC+1)));

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC+=2;
			return(19);

		}	

	case 0xae: /* xor (ix+s) */
		{
			A=A^(io_readByte(IX+(signed char)io_readByte(PC+1)));

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC+=2;
			return(19);
		}	

	case 0xe9: /* jp (ix) */
		{
			PC=IX;
			return(8);
		}

	case 0x35: /* dec (ix+s) */
		{
			work8=io_readByte(IX+(signed char)io_readByte(PC+1));
			work8--;
			io_writeByte(IX+(signed char)io_readByte(PC+1),work8);

			znak(io_readByte(IX+(signed char)io_readByte(PC+1)));
			zero(io_readByte(IX+(signed char)io_readByte(PC+1)));
			myFflagPV_s((io_readByte(IX+(signed char)io_readByte(PC+1))==0x7f));
			myFflagN_s(1);

			/* !!! */ 				
			/* myF.flagH=((io_readByte(IX+(signed char)io_readByte(PC+1))&0x0f)==0x0f); */

			PC+=2;
			return(23);
		}

	case 0x2b: /* dec ix */
		{
			IX--;
			PC++;
			return(10);
		}

	case 0xbe: /* cp (ix+s) */
		{	
			val=io_readByte(IX+(signed char)io_readByte(PC+1));

			work16 = A - (val);                                                                             

			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                                
			myFflagZ_s(   ((work16 & 0xff) == 0));                                                
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    

			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0) );

			PC+=2;
			return(19);
		}

	case 0x9e: /*sbc a, (ix+s) */
		{
			val=io_readByte(IX+(signed char)io_readByte(PC+1));

			work16 = A - (val) - myFflagC_r();                                                    

			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;                                                                              
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC+=2;


			return(19);
		}

	case 0x86: /* add a, (ix+s) */
		{
			val=io_readByte(IX+(signed char)io_readByte(PC+1));

			work16 = A + (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               

				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;       

			// Ispravil ?
			//myFflagH_s(   hcarry_tbl(idx & 0x7));                                                

			myFflagPV_s(   overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC+=2;
			return(19);
		}


		/* komandi prostogo slojeniya */


	case 0x29:
		{
			reg=IX;
			XX=IX;

			work32 = XX + (reg);                                            
			idx = ((XX & 0x0800) >> 9) |                                    
				(((reg) & 0x0800) >> 10) |                            
				((work32 & 0x0800) >> 11);                            
			XX = work32 & 0xffff;                                           
			myFflagH_s(   hcarry_tbl(idx));                                     
			myFflagN_s(0);                                                    
			myFflagC_s( ((work32 & 0x10000) != 0));  
			IX=XX;

			PC++;
			return(15);
		}

	case 0x09:
		{
			reg=BC;
			XX=IX;


			work32 = XX + (reg);                                            
			idx = ((XX & 0x0800) >> 9) |                                    
				(((reg) & 0x0800) >> 10) |                            
				((work32 & 0x0800) >> 11);                            
			XX = work32 & 0xffff;                                           
			myFflagH_s(   hcarry_tbl(idx));                                     
			myFflagN_s(0);                                                    
			myFflagC_s( ((work32 & 0x10000) != 0));  
			IX=XX;

			PC++;
			return(15);
		}

	case 0x19:
		{
			reg=DE;
			XX=IX;

			work32 = XX + (reg);                                            
			idx = ((XX & 0x0800) >> 9) |                                    
				(((reg) & 0x0800) >> 10) |                            
				((work32 & 0x0800) >> 11);                            
			XX = work32 & 0xffff;                                           
			myFflagH_s(   hcarry_tbl(idx));                                     
			myFflagN_s(0);                                                    
			myFflagC_s( ((work32 & 0x10000) != 0));  
			IX=XX;

			PC++;
			return(15);
		}

	case 0x39:
		{
			reg=SP;
			XX=IX;

			work32 = XX + (reg);                                            
			idx = ((XX & 0x0800) >> 9) |                                    
				(((reg) & 0x0800) >> 10) |                            
				((work32 & 0x0800) >> 11);                            
			XX = work32 & 0xffff;                                           
			myFflagH_s(   hcarry_tbl(idx));                                     
			myFflagN_s(0);                                                    
			myFflagC_s( ((work32 & 0x10000) != 0));  
			IX=XX;

			PC++;
			return(15);
		}

	case 0x34 : /* inc (ix+s) */
		{
			reg=io_readByte(IX+(signed char)io_readByte(PC+1));

			reg++;                                                                                                
			znak(reg);                                                 
			zero(reg);                                                                  
			myFflagH_s(   (((reg) & 0x0f) == 0));                                                 
			myFflagPV_s(   ((reg) == 0x80));                                                               
			myFflagN_s(0);
			io_writeByte(IX+(signed char)io_readByte(PC+1),reg);

			PC+=2;
			return(23);
		}

	case 0x23 : /* inc ix */
		{

			IX++;

			PC++;
			return(10);
		}

	case 0xcb :  
		{
			/* R+=2; */

			switch(io_readByte(PC+2))
			{    
				/* vklyuchenie bitov **/
			case 0xc6: 
				{
					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8|=1;

					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0xce: 
				{
					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8|=2;
					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0xd6: 
				{
					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8|=4;
					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);


					break;
				}
			case 0xde: 
				{
					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8|=8;
					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0xe6: 
				{
					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8|=16;
					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0xee: 
				{
					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8|=32;
					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0xf6: 
				{
					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8|=64;
					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0xfe: 
				{

					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8|=128;
					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);

					break;
				}

				/* viklyuchenie bitov */
			case 0x86: 
				{
					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8&=0xfe;
					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0x8e: 
				{
					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8&=0xfd;
					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0x96: 
				{
					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8&=0xfb;
					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0x9e: 
				{
					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8&=0xf7;
					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);


					break;
				}
			case 0xa6: 
				{
					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8&=0xef;
					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0xae: 
				{
					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8&=0xdf;
					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);

					break;
				}

			case 0xb6: 
				{

					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8&=0xbf;
					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);

					break;
				}
			case 0xbe: 
				{
					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8&=0x7f;
					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);

					break;
				}

				/* proverka bitov */
			case 0x40:
			case 0x41:
			case 0x42:
			case 0x43:
			case 0x44:
			case 0x45:
			case 0x47:
			case 0x46:
				{
					bit(io_readByte(IX+(signed char)io_readByte(PC+1)),0);							
					break;
				}
			case 0x48:
			case 0x49:
			case 0x4a:
			case 0x4b:
			case 0x4c:
			case 0x4d:
			case 0x4e:	
			case 0x4f: 
				{
					bit(io_readByte(IX+(signed char)io_readByte(PC+1)),1);							
					break;
				}
			case 0x56: 
				{
					bit(io_readByte(IX+(signed char)io_readByte(PC+1)),2);							
					break;
				}
			case 0x5e: 
				{
					bit(io_readByte(IX+(signed char)io_readByte(PC+1)),3);							
					break;
				}
			case 0x66: 
				{
					bit(io_readByte(IX+(signed char)io_readByte(PC+1)),4);							
					break;
				}
			case 0x6e: 
				{
					bit(io_readByte(IX+(signed char)io_readByte(PC+1)),5);							
					break;

				}
			case 0x76: 
				{
					bit(io_readByte(IX+(signed char)io_readByte(PC+1)),6);							
					break;
				}
			case 0x7e: 
			case 0x7f:
				{
					bit(io_readByte(IX+(signed char)io_readByte(PC+1)),7);							
					break;
				}

			case 0x3e: /* srl (ix+s) */
				{
					myFflagC_s( io_readByte(IX+(signed char)io_readByte(PC+1)) & 0x01);                                                                  

					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8>>=1;
					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);

					znak(io_readByte(IX+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IX+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IX+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}

			case 0x0e: /* rrc (ix+s) */
				{
					myFflagC_s( io_readByte(IX+(signed char)io_readByte(PC+1)) & 0x01);                                                                  
					io_writeByte(IX+(signed char)io_readByte(PC+1),((io_readByte(IX+(signed char)io_readByte(PC+1)) >> 1) | (myFflagC_r() * 128)));                                   

					znak(io_readByte(IX+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IX+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IX+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}

			case 0x26: /*sla (ix+s)*/
				{  
					myFflagC_s( ((io_readByte(IX+(signed char)io_readByte(PC+1)) & 0x80) != 0));                                                 

					work8=io_readByte(IX+(signed char)io_readByte(PC+1));
					work8<<=1;
					io_writeByte(IX+(signed char)io_readByte(PC+1),work8);

					znak(io_readByte(IX+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IX+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IX+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}

			case 0x1e: /*rr (ix+s) */
				{
					work8 = io_readByte(IX+(signed char)io_readByte(PC+1)) & 0x01;                                                                 
					io_writeByte(IX+(signed char)io_readByte(PC+1), ((io_readByte(IX+(signed char)io_readByte(PC+1)) >> 1) | (myFflagC_r() * 128)));                                   
					myFflagC_s( work8 );

					znak(io_readByte(IX+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IX+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IX+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;

				}

			case 0x00: /*RLC  (IX+nn)   &  LD   B,(IX+nn)*/
				{
					myFflagC_s( ((io_readByte(IX+(signed char)io_readByte(PC+1)) & 0x80) != 0) );                                                 

					B = ((io_readByte(IX+(signed char)io_readByte(PC+1)) << 1) | myFflagC_r());
					io_writeByte(IX+(signed char)io_readByte(PC+1), B);

					znak(io_readByte(IX+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IX+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IX+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}


			case 0x01: /*RLC  (IX+nn)   &  LD   C,(IX+nn)*/
				{
					myFflagC_s( ((io_readByte(IX+(signed char)io_readByte(PC+1)) & 0x80) != 0) );                                                 

					C = ((io_readByte(IX+(signed char)io_readByte(PC+1)) << 1) | myFflagC_r());
					io_writeByte(IX+(signed char)io_readByte(PC+1), C);

					znak(io_readByte(IX+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IX+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IX+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}

			case 0x02: /*RLC  (IX+nn)   &  LD   D,(IX+nn)*/
				{
					myFflagC_s( ((io_readByte(IX+(signed char)io_readByte(PC+1)) & 0x80) != 0) );                                                 					
					D = ((io_readByte(IX+(signed char)io_readByte(PC+1)) << 1) | myFflagC_r());

					io_writeByte(IX+(signed char)io_readByte(PC+1), D);

					znak(io_readByte(IX+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IX+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IX+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}


			case 0x03: /*RLC  (IX+nn)   &  LD   E,(IX+nn)*/
				{
					myFflagC_s( ((io_readByte(IX+(signed char)io_readByte(PC+1)) & 0x80) != 0) );                                                 

					E = ((io_readByte(IX+(signed char)io_readByte(PC+1)) << 1) | myFflagC_r());
					io_writeByte(IX+(signed char)io_readByte(PC+1), E);

					znak(io_readByte(IX+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IX+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IX+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}


			case 0x04: /*RLC  (IX+nn)   &  LD   H,(IX+nn)*/
				{
					myFflagC_s( ((io_readByte(IX+(signed char)io_readByte(PC+1)) & 0x80) != 0) );                                                 

					H = ((io_readByte(IX+(signed char)io_readByte(PC+1)) << 1) | myFflagC_r());
					io_writeByte(IX+(signed char)io_readByte(PC+1), H);

					znak(io_readByte(IX+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IX+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IX+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}




			case 0x05: /*RLC  (IX+nn)   &  LD   L,(IX+nn)*/
				{
					myFflagC_s( ((io_readByte(IX+(signed char)io_readByte(PC+1)) & 0x80) != 0) );                                                 

					L = ((io_readByte(IX+(signed char)io_readByte(PC+1)) << 1) | myFflagC_r());
					io_writeByte(IX+(signed char)io_readByte(PC+1), L);

					znak(io_readByte(IX+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IX+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IX+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}


			case 0x06: /*rlc (ix+s)*/  ///  !!!!  LD   F,(IX+nn)*/
				{
					myFflagC_s( ((io_readByte(IX+(signed char)io_readByte(PC+1)) & 0x80) != 0) );                                                 
					io_writeByte(IX+(signed char)io_readByte(PC+1), ((io_readByte(IX+(signed char)io_readByte(PC+1)) << 1) | myFflagC_r()));

					znak(io_readByte(IX+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IX+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IX+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}

			case 0x07: /*RLC  (IX+nn)   &  LD   A,(IX+nn)*/
				{
					myFflagC_s( ((io_readByte(IX+(signed char)io_readByte(PC+1)) & 0x80) != 0) );                                                 

					A = ((io_readByte(IX+(signed char)io_readByte(PC+1)) << 1) | myFflagC_r());
					io_writeByte(IX+(signed char)io_readByte(PC+1), L);

					znak(io_readByte(IX+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IX+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IX+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}



			case 0x16: /* rl (ix+s) */
				{
					work8 = ((io_readByte(IX+(signed char)io_readByte(PC+1)) & 0x80) != 0);                                                
					io_writeByte(IX+(signed char)io_readByte(PC+1), ((io_readByte(IX+(signed char)io_readByte(PC+1)) << 1) | myFflagC_r()));                                                  
					myFflagC_s( work8);
					znak(io_readByte(IX+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IX+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IX+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}

			case 0x2e: /* sra (ix+s) */
				{
					myFflagC_s( io_readByte(IX+(signed char)io_readByte(PC+1)) & 0x01);                                                                  
					work8 = io_readByte(IX+(signed char)io_readByte(PC+1)) & 0x80;                                                                 
					io_writeByte(IX+(signed char)io_readByte(PC+1), ((io_readByte(IX+(signed char)io_readByte(PC+1)) >> 1) | work8));                                                 

					znak(io_readByte(IX+(signed char)io_readByte(PC+1)));                                                
					zero(io_readByte(IX+(signed char)io_readByte(PC+1)));
					parity(io_readByte(IX+(signed char)io_readByte(PC+1)));
					myFflagH_s(0);
					myFflagN_s(0);

					break;
				}

			case 0x0f:
				{
					A = io_readByte(IX+(signed char)io_readByte(PC+1));                                                        

					myFflagC_s( A & 0x01 );                                                                  
					A= (A >> 1) | (myFflagC_r() * 128);                                   

					znak(A);                                                
					zero(A);
					parity(A);
					myFflagH_s(0);
					myFflagN_s(0);

					io_writeByte(IX+(signed char)io_readByte(PC+1), A); 

					break; 
				}	

			default :
				printf("Z80 :  dd cb S %2x. Unknown. PC=%4x.\n",io_readByte(PC+2),PC-1);
				ExitWithError(-1,"");
			}

			PC+=3;
			return(23);
		}

	case 0xe5 : /* push ix */
		{
			push(IX);
			PC++;
			return(15);
		}

	case 0x96 : /* sub (ix+s) */
		{
			val=io_readByte(IX+(signed char)io_readByte(PC+1));	

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s( sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC+=2;
			return(19);
		}

	case 0xe1 : /* pop ix */
		{
			pop(&IX);

			PC++;
			return(14);
		}

	case 0x8e: /*adc a,(ix+s) */
		{
			val=io_readByte(IX+(signed char)io_readByte(PC+1));

			work16 = A + (val) + myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s( overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0) );

			PC+=2;
			return(19);
		}

	case 0xe3 : /* ex (sp),ix */
		{
			pop(&XX);
			push(IX);

			IX=XX;

			PC++;
			return(23);
		}


		/* operatsii s polovinkami IX start */

	case 0x24: /*  inc IXh   */
		{
			IXh++;

			znak(IXh);                                                 
			zero(IXh);                                                                  
			myFflagH_s(   (((IXh) & 0x0f) == 0));                                                 
			myFflagPV_s(   ((IXh) == 0x80));                                                               
			myFflagN_s(0);

			PC++;
			return(8);                                                              
		}	

	case 0x25:   /* dec IXh */
		{
			IXh--;

			znak(IXh);
			zero(IXh);
			myFflagPV_s((IXh==0x7f));
			myFflagN_s(1);
			myFflagH_s(    ((IXh&0x0f)==0x0f));

			PC++;
			return(8); 
		}


	case 0x26: 
		{
			IXh=io_readByte(PC+1);

			PC+=2;
			return(11);
		}

	case 0x2c: /* inc IXl   */
		{
			IXl++;


			znak(IXl);                                                 
			zero(IXl);                                                                  
			myFflagH_s(   (((IXl) & 0x0f) == 0));                                                 
			myFflagPV_s(   ((IXl) == 0x80));                                                               
			myFflagN_s(0);

			PC++;
			return(8);                                                              
		}	

	case 0x2d:   /* dec IXl */
		{
			IXl--;

			znak(IXl);
			zero(IXl);
			myFflagPV_s((IXl==0x7f));
			myFflagN_s(1);
			myFflagH_s(    ((IXl&0x0f)==0x0f));

			PC++;
			return(8); 
		}

	case 0x2e: 
		{
			IXl=io_readByte(PC+1);

			PC+=2;
			return(11);
		}

	case 0x44:    
		{
			B=IXh;

			PC++;
			return(8);
		}

	case 0x45:    

		{
			B=IXl;

			PC++;
			return(8);
		}	

	case 0x4c:    
		{
			C=IXh;

			PC++;
			return(8);

		}

	case 0x4d:    
		{
			C=IXl;

			PC++;
			return(8);
		}	

	case 0x54:    
		{
			D=IXh;

			PC++;
			return(8);
		}

	case 0x55:    
		{
			D=IXl;

			PC++;
			return(8);
		}	

	case 0x5c:    
		{
			E=IXh;

			PC++;
			return(8);
		}

	case 0x5d:    
		{
			E=IXl;

			PC++;
			return(8);
		}	

	case 0x60:    
		{
			IXh=B;


			PC++;
			return(8);
		}	

	case 0x61:    
		{
			IXh=C;

			PC++;
			return(8);
		}	

	case 0x62:    
		{
			IXh=D;

			PC++;
			return(8);
		}	

	case 0x63:    
		{
			IXh=E;

			PC++;
			return(8);
		}	

	case 0x64:    
		{
			IXh=IXh;

			PC++;
			return(8);
		}	


	case 0x65:    
		{
			IXh=IXl;

			PC++;
			return(8);
		}	

	case 0x67:    
		{
			IXh=A;

			PC++;
			return(8);
		}	


	case 0x68:    
		{
			IXl=B;

			PC++;
			return(8);

		}	


	case 0x69:    
		{
			IXl=C;

			PC++;
			return(8);
		}	

	case 0x6a:    
		{
			IXl=D;

			PC++;
			return(8);
		}	

	case 0x6b:    
		{
			IXl=E;

			PC++;
			return(8);
		}	

	case 0x6c:    
		{
			IXl=IXh;


			PC++;
			return(8);
		}	

	case 0x6d:    
		{
			IXl=IXl;

			PC++;

			return(8);
		}	

	case 0x6f:    
		{
			IXl=A;

			PC++;
			return(8);
		}

	case 0x7c:    
		{
			A=IXh;

			PC++;
			return(8);
		}

	case 0x7d:    
		{
			A=IXl;


			PC++;
			return(8);

		}

	case 0x84:
		{
			val=IXh;

			work16 = A + (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                              
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s(   overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0) );

			PC++;
			return(8);	
		}

	case 0x85:
		{

			val=IXl;

			work16 = A + (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                              
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s(   overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0) );

			PC++;
			return(8);	
		}

	case 0x8c:
		{
			val=IXh;

			work16 = A + (val) + myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s( overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0) );

			PC++;
			return(8);
		}

	case 0x8d:
		{
			val=IXl;

			work16 = A + (val) + myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s( overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0) );

			PC++;
			return(8);
		}

	case 0x94 :
		{
			val=IXh;	

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       

			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s( sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(8);
		}

	case 0x95 :

		{
			val=IXl;	

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s( sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(8);
		}

	case 0x9c:
		{
			val=IXh;

			work16 = A - (val) - myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;                                                                              
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(8);
		}

	case 0x9d:
		{
			val=IXl;

			work16 = A - (val) - myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;                                                                              
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(8);
		}

	case 0xa4:
		{

			A=A&IXh;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);


			PC++;
			return(8);
		}	

	case 0xa5:
		{
			A=A&IXl;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}	

	case 0xac:
		{
			A=A^IXh;

			ParityA;
			ZnakA;
			ZeroA;

			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}	

	case 0xad:
		{
			A=A^IXl;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}	

	case 0xb4:
		{
			A=A|IXh;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}	

	case 0xb5:
		{
			A=A|IXl;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);


			PC++;
			return(8);
		}	

	case 0xbc:
		{	
			val=IXh;

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                                
			myFflagZ_s(   ((work16 & 0xff) == 0));                                                
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(8);

		}

	case 0xbd:
		{	
			val=IXl;

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                                
			myFflagZ_s(   ((work16 & 0xff) == 0));                                                
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(8);
		}

	case 0xbf:
		{	
			val=A;

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                                
			myFflagZ_s(   ((work16 & 0xff) == 0));                                                
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(8);
		}

	case 0xaf:
		{
			A=A^A;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(8);
		}	

	default :
		return(z80a(0)+4);
	}

	printf("\nZ80 : Unknown instruction dd%x at address %x.\n",io_readByte(PC),PC-1);
	ExitWithError(-1,"");
}

int ED (void)
{
	switch(io_readByte(PC))
	{
		//im0 undoc
	case 0x76 :
		{

			IM=0;

			PC++;
			return(8);

		}

	case 0x6b: /* ld hl, (nn) */
		{
			L=io_readByte(ex(io_readByte(PC+2),io_readByte(PC+1)));
			H=io_readByte(ex(io_readByte(PC+2),io_readByte(PC+1))+1);
			PC+=3;
			return(20);
		}

	case 0x7b: /* ld sp, (nn) */
		{
			io_writeToRamAddrSpAddr((unsigned char *)&SP, ex(io_readByte(PC+2),io_readByte(PC+1)));
			PC+=3;
			return(20);
		}

	case 0x4b: /* ld bc, (nn) */
		{
			C=io_readByte(ex(io_readByte(PC+2),io_readByte(PC+1)));
			B=io_readByte(ex(io_readByte(PC+2),io_readByte(PC+1))+1);
			PC+=3;
			return(20);
		}

	case 0x5b: /* ld de, (nn) */
		{
			E=io_readByte(ex(io_readByte(PC+2),io_readByte(PC+1)));
			D=io_readByte(ex(io_readByte(PC+2),io_readByte(PC+1))+1);
			PC+=3;
			return(20);
		}

	case 0x63: /* ld (nn), hl */
		{
			io_writeByte(ex(io_readByte(PC+2),io_readByte(PC+1)),L);
			io_writeByte(ex(io_readByte(PC+2),io_readByte(PC+1))+1,H);
			PC+=3;
			return(20);
		}

	case 0x73: /* ld (nn), sp */
		{
			io_writeToSpAddrVal(ex(io_readByte(PC+2),io_readByte(PC+1)),SP);
			PC+=3;
			return(20);
		}

	case 0x43: /* ld (nn),bc */
		{
			io_writeByte(ex(io_readByte(PC+2),io_readByte(PC+1)),C);
			io_writeByte(ex(io_readByte(PC+2),io_readByte(PC+1))+1,B);
			PC+=3;
			return(20);
		}

	case 0x53: /* ld (nn),de */
		{
			io_writeByte(ex(io_readByte(PC+2),io_readByte(PC+1)),E);
			io_writeByte(ex(io_readByte(PC+2),io_readByte(PC+1))+1,D);
			PC+=3;
			return(20);
		}

	case 0x47:
		{
			I=A; /* ld i,a */
			PC++;
			return(9);
		}

		/* komandi vichitania s uchetom perenosa */

	case 0x62:
		{
			reg=HL;

			work32 = HL - (reg) - myFflagC_r();                                                   
			idx = ((HL & 0x8800) >> 9) |                                                    
				(((reg) & 0x8800) >> 10) |                                            
				((work32 & 0x8800) >> 11);                                            
			HL1_1 = work32 & 0xffff;                                                                   
			myFflagS_s(   ((HL1_1 & 0x8000) != 0));                                                  
			myFflagZ_s(   (HL1_1 == 0));                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work32 & 0x10000) != 0));
			HL=HL1_1;

			PC++;
			return(15);
		}

	case 0x42:
		{
			reg=BC;

			work32 = HL - (reg) - myFflagC_r();                                                   
			idx = ((HL & 0x8800) >> 9) |                                                    
				(((reg) & 0x8800) >> 10) |                                            
				((work32 & 0x8800) >> 11);                                            
			HL1_1 = work32 & 0xffff;                                                                   
			myFflagS_s(   ((HL1_1 & 0x8000) != 0));                                                  
			myFflagZ_s(   (HL1_1 == 0));                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work32 & 0x10000) != 0));
			HL=HL1_1;

			PC++;
			return(15);
		}

	case 0x52:
		{
			reg=DE;

			work32 = HL - (reg) - myFflagC_r();                                                   
			idx = ((HL & 0x8800) >> 9) |                                                    
				(((reg) & 0x8800) >> 10) |                                            
				((work32 & 0x8800) >> 11);                                            
			HL1_1 = work32 & 0xffff;                                                                   
			myFflagS_s(   ((HL1_1 & 0x8000) != 0));                                                  
			myFflagZ_s(   (HL1_1 == 0));                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work32 & 0x10000) != 0));
			HL=HL1_1;

			PC++;
			return(15);
		}

	case 0x72:
		{
			reg=SP;

			work32 = HL - (reg) - myFflagC_r();                                                   
			idx = ((HL & 0x8800) >> 9) |                                                    
				(((reg) & 0x8800) >> 10) |                                            
				((work32 & 0x8800) >> 11);                                            
			HL1_1 = work32 & 0xffff;                                                                   
			myFflagS_s(   ((HL1_1 & 0x8000) != 0));                                                  
			myFflagZ_s(   (HL1_1 == 0));                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work32 & 0x10000) != 0));
			HL=HL1_1;

			PC++;
			return(15);
		}

	case 0xb8: /* lddr */
		{
			io_writeByte(DE,io_readByte(HL));
			BC--;

			HL--; DE--;

			if (!BC)
			{
				myFflagPV_s(0);
				myFflagH_s(0);
				myFflagN_s(0);
				PC++;
				return(16);
			}
			else
			{
				myFflagPV_s(1);
				myFflagH_s(0);
				myFflagN_s(0);
				PC--;
				return(21);
			}
		}

	case 0xa8: /* ldd */
		{
			io_writeByte(DE,io_readByte(HL));
			BC--;

			HL--; DE--;

			if (!BC)
				myFflagPV_s(0);
			else
				myFflagPV_s(1);

			myFflagH_s(0);
			myFflagN_s(0);
			PC++;
			return(16);
		}

	case 0xb0: /* ldir */
		{
			io_writeByte(DE,io_readByte(HL));
			BC--;

			HL++; DE++;

			if (!BC)
			{
				myFflagPV_s(0);
				myFflagH_s(0);
				myFflagN_s(0);
				PC++;
				return(16);
			}
			else
			{
				myFflagPV_s(1);
				myFflagH_s(0);
				myFflagN_s(0);			
				PC--;
				return(21);
			}
		}

	case 0xa0: /* ldi */
		{
			io_writeByte(DE,io_readByte(HL));
			BC--;

			HL++; DE++;

			if (!BC)
				myFflagPV_s(0);
			else
				myFflagPV_s(1);

			myFflagH_s(0);
			myFflagN_s(0);
			PC++;
			return(16);
		}

	case 0x56: /* im1 */
		{
			IM=1;

			PC++;
			return(8);
		}


		/* komandi vivoda na vneshnie ustroistva */

	case 0x79:
		{
			OutPort(C,B,A);
			PC+=1;
			return(12);
		}

	case 0x61:
		{
			OutPort(C,B,H);
			PC+=1;
			return(12);
		}

	case 0x69:
		{
			OutPort(C,B,L);
			PC+=1;
			return(12);
		}

	case 0x41:
		{
			OutPort(C,B,B);
			PC+=1;
			return(12);
		}

	case 0x49:
		{
			OutPort(C,B,C);
			PC+=1;
			return(12);
		}

	case 0x51:
		{
			OutPort(C,B,D);
			PC+=1;
			return(12);

		}

	case 0x59:
		{
			OutPort(C,B,E);
			PC+=1;
			return(12);
		}

		/* komandi vvoda ot vneshnih ystroistv */

	case 0x78: 
		{
			A=InPort(C,B);
			myFflagN_s(0);
			myFflagH_s(0);
			parity(A);
			zero(A);
			znak(A);

			PC+=1;
			return(12);
		}

	case 0x60: 
		{
			H=InPort(C,B);
			myFflagN_s(0);
			myFflagH_s(0);
			parity(H);
			zero(H);
			znak(H);

			PC+=1;
			return(12);
		}

	case 0x68: 
		{
			L=InPort(C,B);
			myFflagN_s(0);
			myFflagH_s(0);
			parity(L);
			zero(L);
			znak(L);

			PC+=1;
			return(12);
		}

	case 0x40: 
		{
			B=InPort(C,B);
			myFflagN_s(0);
			myFflagH_s(0);
			parity(B);
			zero(B);
			znak(B);


			PC+=1;
			return(12);
		}

	case 0x48: 
		{
			C=InPort(C,B);
			myFflagN_s(0);
			myFflagH_s(0);
			parity(C);
			zero(C);
			znak(C);

			PC+=1;
			return(12);
		}

	case 0x50: 
		{
			D=InPort(C,B);
			myFflagN_s(0);
			myFflagH_s(0);
			parity(D);
			zero(D);
			znak(D);

			PC+=1;

			return(12);
		}

	case 0x58: 
		{
			E=InPort(C,B);
			myFflagN_s(0);
			myFflagH_s(0);
			parity(E);
			zero(E);
			znak(E);

			PC+=1;
			return(12);
		}




	case 0x70: 
		{
			F=InPort(C,B);
			myFflagN_s(0);
			myFflagH_s(0);
			parity(F);
			zero(F);
			znak(F);

			PC+=1;
			return(12);
		}

		/* komandi slojeniya s uchetom prenosa */

	case 0x6a:
		{
			reg=HL;
			HL1_1=HL;

			work32 = HL1_1 + reg + myFflagC_r();							
			idx = ((HL1_1 & 0x8800) >> 9) |							
				((reg & 0x8800) >> 10) |						
				((work32 & 0x8800) >> 11);						
			HL1_1 = work32 & 0xffff;									
			myFflagS_s(   ((HL1_1 & 0x8000) != 0));							
			myFflagZ_s( (HL1_1 == 0) );										
			myFflagH_s(   hcarry_tbl(idx & 0x7));							
			myFflagPV_s( overflow_tbl(idx >> 4));						
			myFflagN_s(0);											
			myFflagC_s( ((work32 & 0x10000) != 0) );		
			HL=HL1_1;

			PC++;
			return(15);
		}

	case 0x4a:
		{
			reg=BC;
			HL1_1=HL;

			work32 = HL1_1 + reg + myFflagC_r();							
			idx = ((HL1_1 & 0x8800) >> 9) |							
				((reg & 0x8800) >> 10) |						
				((work32 & 0x8800) >> 11);						
			HL1_1 = work32 & 0xffff;									
			myFflagS_s(   ((HL1_1 & 0x8000) != 0));
			myFflagZ_s( (HL1_1 == 0) );										
			myFflagH_s(   hcarry_tbl(idx & 0x7));							
			myFflagPV_s( overflow_tbl(idx >> 4));						
			myFflagN_s(0);											
			myFflagC_s( ((work32 & 0x10000) != 0) );		
			HL=HL1_1;

			PC++;
			return(15);
		}

	case 0x5a:
		{
			reg=DE;
			HL1_1=HL;

			work32 = HL1_1 + reg + myFflagC_r();							
			idx = ((HL1_1 & 0x8800) >> 9) |							
				((reg & 0x8800) >> 10) |						
				((work32 & 0x8800) >> 11);						
			HL1_1 = work32 & 0xffff;									
			myFflagS_s(   ((HL1_1 & 0x8000) != 0));							
			myFflagZ_s( (HL1_1 == 0) );										
			myFflagH_s(   hcarry_tbl(idx & 0x7));							
			myFflagPV_s( overflow_tbl(idx >> 4) );						

			myFflagN_s(0);											

			myFflagC_s( ((work32 & 0x10000) != 0) );		
			HL=HL1_1;

			PC++;
			return(15);
		}

	case 0x7a:
		{

			reg=SP;
			HL1_1=HL;

			work32 = HL1_1 + reg + myFflagC_r();							
			idx = ((HL1_1 & 0x8800) >> 9) |							
				((reg & 0x8800) >> 10) |
				((work32 & 0x8800) >> 11);						
			HL1_1 = work32 & 0xffff;									
			myFflagS_s(   ((HL1_1 & 0x8000) != 0));							
			myFflagZ_s( (HL1_1 == 0) );										
			myFflagH_s(   hcarry_tbl(idx & 0x7));							
			myFflagPV_s( overflow_tbl(idx >> 4) );						
			myFflagN_s(0);											
			myFflagC_s( ((work32 & 0x10000) != 0) );		
			HL=HL1_1;


			PC++;
			return(11);
		}

	case 0x5f: /* ld a,r */
		{
			A=(R&0x7f) | (R7&0x80);

			myFflagPV_s(interrupts);

			ZnakA;
			ZeroA;

			myFflagN_s(0);
			myFflagH_s(0);

			PC++;
			return(9);
		}


	case 0x4d: /* reti */
	case 0x5d:
	case 0x6d:
	case 0x7d:
		{
			pop(&PC);
			/* interrupts=on; */
			return(14);
		}

	case 0x75:
	case 0x55:
	case 0x65:
	case 0x45: /* retn */
		{
			pop(&PC);
			/* interrupts=on; */
			return(14);
		}

	case 0xb9: /* cpdr */
		{
			val = io_readByte(HL);

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                               
			myFflagZ_s(   ((work16 & 0xff) == 0));                                                
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s( sub_overflow_tbl(idx >> 4) );                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			HL--; BC--;

			myFflagPV_s(   (BC != 0));

			if ((F&4) && (!(F&64)))
			{
				PC --;
				return(21);
			}

			PC++;

			return(16);
		}

	case 0xb1: /* cpir */
		{
			val = io_readByte(HL);

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                               
			myFflagZ_s(   ((work16 & 0xff) == 0));                                                
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s( sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			HL++; BC--;

			myFflagPV_s (BC != 0);

			if ((F&4) && (!(F&64)))
			{
				PC --;
				return(21);
			}

			PC++;
			return(16);
		}

	case 0x44 : /* neg */

	case 0x4c:     /* undocummented (from xzx)*/
	case 0x54:     /* undocummented (from xzx) */
	case 0x5c:     /* undocummented (from xzx) */
	case 0x64:     /* undocummented (from xzx) */
	case 0x6c:     /* undocummented (from xzx)*/
	case 0x74:     /* undocummented (from xzx)*/
	case 0x7c:     /* undocummented (from xzx) */
		{
			work8 = A;
			A = 0;
			val=work8;

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       

			A = work16 & 0xff;                                                                              
			myFflagS_s(   ((A & 0x80) != 0));                                                             
			myFflagZ_s(   (A == 0));                                                                              
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                   
			myFflagC_s( ((work16 & 0x0100) != 0) );

			PC++;
			return(8);
		}

	case 0x5e : /* im2 */
	case 0x7e :
		{
			IM=2;

			PC++;
			return(8);
		}

	case 0x6f: /* rld */
		{
			work8 = io_readByte(HL);
			io_writeByte(HL,((work8 << 4) | (A & 0x0f)));
			A = (A & 0xf0) | (work8 >> 4);
			myFflagS_s( ((A & 0x80) != 0) );
			ZeroA;
			myFflagH_s(0);
			ParityA;
			myFflagN_s(0);

			PC++;
			return(18);
		}	

	case 0x57 : /* ld a,i */
		{
			A=I;
			ZnakA;
			ZeroA;
			myFflagH_s(0);
			myFflagPV_s(interrupts); /* !!! */
			myFflagN_s(0);

			PC++;
			return(9);
		}


	case 0xab:
		{
			B--;  
			OutPort(C,B,io_readByte(HL));

			HL--;

			myFflagZ_s(   (B == 0));                                                       
			myFflagN_s(0);                                                             

			PC++;
			return(16);
		}	

	case 0x4f:
		{
			R7=R=A;

			PC++;
			return(9); 
		}




	case 0xa9: /* cpd */        
		{
			work8 = io_readByte(HL);                                                                      

			/* !cmp! */
			val=work8;

			work16 = A - val;                                                               
			idx = ((A & 0x88) >> 1) |                                                         
				(((val) & 0x88) >> 2) |                                                 
				((work16 & 0x88) >> 3);                                                 
			myFflagS_s( ((work16 & 0x80) != 0) );                                                
			myFflagZ_s( ((work16 & 0xff) == 0) );                                                 
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                            
			myFflagPV_s( sub_overflow_tbl(idx >> 4));                                            
			myFflagN_s(1);                                                                      
			myFflagC_s( ((work16 & 0x0100) != 0) ); 
			/* !cmp! */                                                                               

			HL--; BC--;

			myFflagPV_s(   (BC != 0));                                                                       


			PC++;
			return(16);
		}	

	case 0x67:  /* rrd */
		{
			work8 = io_readByte(HL);                                                                      
			io_writeByte(HL, ((work8 >> 4) | (A << 4)));                                                     
			A = (A & 0xf0) | (work8 & 0x0f);                                                          
			ZnakA;
			ZeroA;                                                                        
			ParityA;                                                                       
			myFflagH_s(0);  
			myFflagN_s(0);                                                                              

			PC++;
			return(18);
		}	

	case 0xa1:   /* cpi */
		{
			work8 = io_readByte(HL);                                                                      

			/* !cmp! */
			val=work8;

			work16 = A - val;                                                               
			idx = ((A & 0x88) >> 1) |                                                         
				(((val) & 0x88) >> 2) |                                                 
				((work16 & 0x88) >> 3);                                                 
			myFflagS_s( ((work16 & 0x80) != 0) );                                                
			myFflagZ_s( ((work16 & 0xff) == 0) );                                                 
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                            
			myFflagPV_s( sub_overflow_tbl(idx >> 4));                                            
			myFflagN_s(1);                                                                      
			myFflagC_s( ((work16 & 0x0100) != 0) ); 
			/* !cmp! */


			HL++; BC--;

			myFflagPV_s(   (BC != 0));                                                                       

			PC++;
			return(16);
		}

	case 0xa3:

		{
			B--;                                                                    
			OutPort(C,B,io_readByte(HL));
			HL++;                                                                   
			myFflagZ_s( (B == 0) );                                                      
			myFflagN_s(1);                                                            

			PC++;
			return(16);
		}

	case 0xa2:
		{
			io_writeByte(HL, InPort(C,B));

			B--; 
			HL++; 
			myFflagZ_s(   (B == 0));
			myFflagN_s(1);

			PC++;
			return(16);
		}

	case 0x46:
	case 0x4e:
	case 0x66:
	case 0x6e:
		{
			IM=0;

			PC++;
			return(8);
		}

	case 0x71:
		{
			OutPort(C,B,0);

			PC++;
			return(12);
		}

	case 0x00:
	case 0x01:
	case 0x02:
	case 0x03:
	case 0x04:
	case 0x05:
	case 0x06:
	case 0x07:
	case 0x08:
	case 0x09:
	case 0x0A:
	case 0x0B:
	case 0x0C:
	case 0x0D:
	case 0x0E:
	case 0x0F:

	case 0x10:
	case 0x11:
	case 0x12:
	case 0x13:
	case 0x14:
	case 0x15:
	case 0x16:
	case 0x17:
	case 0x18:
	case 0x19:
	case 0x1A:
	case 0x1B:
	case 0x1C:
	case 0x1D:
	case 0x1E:
	case 0x1F:

	case 0x20:
	case 0x21:
	case 0x22:
	case 0x23:
	case 0x24:
	case 0x25:
	case 0x26:
	case 0x27:
	case 0x28:
	case 0x29:
	case 0x2A:
	case 0x2B:
	case 0x2C:
	case 0x2D:
	case 0x2E:
	case 0x2F:

	case 0x30:
	case 0x31:
	case 0x32:
	case 0x33:
	case 0x34:
	case 0x35:
	case 0x36:
	case 0x37:
	case 0x38:
	case 0x39:
	case 0x3A:
	case 0x3B:
	case 0x3C:
	case 0x3D:
	case 0x3E:
	case 0x3F:

	case 0xBC:
	case 0xBD:
	case 0xBE:
	case 0xBF:

	case 0xC0:
	case 0xC1:
	case 0xC2:
	case 0xC3:
	case 0xC4:
	case 0xC5:
	case 0xC6:
	case 0xC7:
	case 0xC8:
	case 0xC9:
	case 0xCA:
	case 0xCB:
	case 0xCC:
	case 0xCD:
	case 0xCE:
	case 0xCF:

	case 0xD0:
	case 0xD1:
	case 0xD2:
	case 0xD3:
	case 0xD4:
	case 0xD5:
	case 0xD6:
	case 0xD7:
	case 0xD8:
	case 0xD9:
	case 0xDA:
	case 0xDB:
	case 0xDC:
	case 0xDD:
	case 0xDE:
	case 0xDF:

	case 0xE0:
	case 0xE1:
	case 0xE2:
	case 0xE3:
	case 0xE4:
	case 0xE5:
	case 0xE6:
	case 0xE7:
	case 0xE8:
	case 0xE9:
	case 0xEA:
	case 0xEB:
	case 0xEC:
	case 0xED:
	case 0xEE:
	case 0xEF:


	case 0xB4:
	case 0xB5:
	case 0xB6:
	case 0xB7:

	case 0xAC:
	case 0xAD:
	case 0xAE:
	case 0xAF:

	case 0xA4:
	case 0xA5:
	case 0xA6:
	case 0xA7:

	case 0x7F:

	case 0x80:
	case 0x81:
	case 0x82:
	case 0x83:
	case 0x84:
	case 0x85:
	case 0x86:
	case 0x87:
	case 0x88:
	case 0x89:
	case 0x8A:
	case 0x8B:
	case 0x8C:
	case 0x8D:
	case 0x8E:
	case 0x8F:

	case 0x90:
	case 0x91:
	case 0x92:
	case 0x93:
	case 0x94:
	case 0x95:
	case 0x96:
	case 0x97:
	case 0x98:
	case 0x99:
	case 0x9A:
	case 0x9B:
	case 0x9C:
	case 0x9D:
	case 0x9E:
	case 0x9F:

		{ /* NOP */

			PC++;
			return(8);
		}	
	}

	printf("\nZ80 : Unknown instruction ed%x at address %x.\n",io_readByte(PC),PC-1);
	ExitWithError(-1,"");

	return(0); /* eto chtob ne kvakalo */
}

int NadoPropustitEtotTapeBlock(tape_struct * t)
{
	if (t==NULL) return(0);

	if ((t->id==0x30)||(t->id==0x32)||(t->id==0x33)||(t->id==0x35)||(t->id=='Z')) return (1);

	return(0);
}


int TapeNextNext(void)
{
	tape_struct * next;
	int first=0;


	if (tapes==NULL)
	{
		tape_next=NULL;
		return(1);
	}

	if (tape_next == NULL)
		return 0;

	next = (tape_struct *)tape_next->next;

LR:
	if (next==tape_next)
		return(1);

	if (next==NULL)
	{
		next= FindTapeByPosition(1);
		first=1;	
	}

	if ((NadoPropustitEtotTapeBlock(next))||(next->position==0))
	{
		next = (tape_struct *) next->next;
		goto LR;
	}

	//EnsureVisibleAndSelect(next->position);

	tape_next=next;

	return(first);
}

int ABlockStandartniyP(tape_struct * t)
{
	unsigned char * data;


	//return 1;

	if (!t) return(0);


	if (!tape_traps) return(0);
	if (t->id!=0x10) return(0);

	data=t->data1;

	if ((data[0]!=0)&&(data[0]!=255)) return(0);

	return(1);
}

int AMojnoliTrapit(void)
{
	if (TRDOS) return(0);
	if (tape_next==NULL) return(0);

	if (NadoPropustitEtotTapeBlock(tape_next))
		TapeNextNext();

	if (ABlockStandartniyP(tape_next)) return(1);
	return(0);
}

unsigned char b2bget(unsigned char * otkuda, unsigned int pos)
{
	unsigned int bc;
	unsigned char bn;
	unsigned char byte;
	unsigned char mn;

	bc=pos/8;
	bn=pos-bc*8;

	byte=otkuda[bc];

	switch (bn)
	{
	case 0 : mn=128; break;
	case 1 : mn=64;  break;
	case 2 : mn=32;  break;
	case 3 : mn=16;  break;

	case 4 : mn=8; break;
	case 5 : mn=4; break;
	case 6 : mn=2; break;
	case 7 : mn=1; break;

	default :
		mn=0;
		printf("b2bget : bn==%d. This is bug. report it.\n",bn);
	}


	if (byte&mn) return(1);
	return(0);
}

void b2bset(unsigned char * kuda, unsigned int pos, unsigned char bit)
{
	unsigned int bc;
	unsigned char bn;
	unsigned char mn;

	bc=pos/8;
	bn=pos-bc*8;

	switch (bn)
	{
	case 0 : mn=128; break;
	case 1 : mn=64;  break;
	case 2 : mn=32;  break;
	case 3 : mn=16;  break;

	case 4 : mn=8; break;
	case 5 : mn=4; break;
	case 6 : mn=2; break;
	case 7 : mn=1; break;

	default :
		mn=0;
		printf("b2bset : bn==%d. This is bug. report it.\n",bn);
	}

	if (!bit)
		kuda[bc]&=~mn;
	else
		kuda[bc]|=mn;
}

unsigned char kkk = 0;
int Fill(unsigned char * tape, unsigned int * tape_len, tape_struct * next)
{
	turbo_block_type * t1;
	unsigned int i,j,l;
	unsigned char byte;
	ROM_bl_type * rom;
	unsigned short len16;
	Pure_toneT * ptone;
	unsigned short * pulses;
	Pure_dataT * pdata;
	int len;
	direct_recT * direct;


	/* printf("%d\n", next->id);*/


	///*
	if (next->id==0x11)
	{
		t1 = (turbo_block_type *) next->info;

		for (i=0; i<t1->pilot_toneL_inPulses; i++)
		{
			for (j=0; j<((double)44100/((double)3500000/(double)t1->pilotL)); j++)
				b2bset(tape, (*tape_len)++,kkk);
			kkk=1-kkk;

			for (j=0; j<((double)44100/((double)3500000/(double)t1->pilotL)); j++)
				b2bset(tape, (*tape_len)++,kkk);
			kkk=1-kkk;
		}

		for (j=0; j<((double)44100/((double)3500000/(double)t1->syncFL)); j++)
			b2bset(tape, (*tape_len)++,kkk);
		kkk=1-kkk;

		for (j=0; j<((double)44100/((double)3500000/(double)t1->syncSL)); j++)
			b2bset(tape, (*tape_len)++,kkk);
		kkk=1-kkk;

		for (i=0; i<(unsigned int)(t1->l1+t1->l2*256+t1->l3*65536); i++)
		{
			byte=next->data1[i];
			for (l=0; l<8; l++)
			{
				if (b2bget(&byte,l))
				{
					for (j=0; j<((double)44100/((double)3500000/(double)t1->oneL)); j++)
						b2bset(tape, (*tape_len)++,kkk);
					kkk=1-kkk;

					for (j=0; j<((double)44100/((double)3500000/(double)t1->oneL)); j++)
						b2bset(tape, (*tape_len)++,kkk);
					kkk=1-kkk;
				}
				else
				{
					for (j=0; j<((double)44100/((double)3500000/(double)t1->zeroL)); j++)
						b2bset(tape, (*tape_len)++,kkk);
					kkk=1-kkk;

					for (j=0; j<((double)44100/((double)3500000/(double)t1->zeroL)); j++)
						b2bset(tape, (*tape_len)++,kkk);
					kkk=1-kkk;
				}	
			}
		}

		byte=next->data1[i];
		for (l=0; l<t1->used_bits; l++)
		{
			if (b2bget(&byte,l))
			{
				for (j=0; j<((double)44100/((double)3500000/(double)t1->oneL)); j++)
					b2bset(tape, (*tape_len)++,kkk);
				kkk=1-kkk;

				for (j=0; j<((double)44100/((double)3500000/(double)t1->oneL)); j++)
					b2bset(tape, (*tape_len)++,kkk);
				kkk=1-kkk;
			}
			else
			{
				for (j=0; j<((double)44100/((double)3500000/(double)t1->zeroL)); j++)
					b2bset(tape, (*tape_len)++,kkk);
				kkk=1-kkk;

				for (j=0; j<((double)44100/((double)3500000/(double)t1->zeroL)); j++)
					b2bset(tape, (*tape_len)++,kkk);
				kkk=1-kkk;
			}	
		}			

		for (j=0; j<((double)44100*(double)t1->pause/(double)1000); j++)
			b2bset(tape, (*tape_len)++,kkk);
		if (t1->pause)
			kkk=1-kkk;

		return(no_errors);
	}

	if (next->id==0x10)
	{
		rom = (ROM_bl_type *)next->info;

		for (i=0; i<8064; i++)
		{
			for (j=0; j<((double)44100/((double)3500000/(double)2168)); j++)
				b2bset(tape, (*tape_len)++,kkk);
			kkk=1-kkk;

			for (j=0; j<((double)44100/((double)3500000/(double)2168)); j++)
				b2bset(tape, (*tape_len)++,kkk);
			kkk=1-kkk;
		}

		for (j=0; j<((double)44100/((double)3500000/(double)667)); j++)
			b2bset(tape, (*tape_len)++,kkk);
		kkk=1-kkk;

		for (j=0; j<((double)44100/((double)3500000/(double)735)); j++)
			b2bset(tape, (*tape_len)++,kkk);
		kkk=1-kkk;

		for (i=0; i<(rom->len); i++)
		{
			byte=next->data1[i];
			for (l=0; l<8; l++)
			{
				if (b2bget(&byte,l))
				{
					for (j=0; j<((double)44100/((double)3500000/(double)1710)); j++)
						b2bset(tape, (*tape_len)++,kkk);
					kkk=1-kkk;

					for (j=0; j<((double)44100/((double)3500000/(double)1710)); j++)
						b2bset(tape, (*tape_len)++,kkk);
					kkk=1-kkk;
				}
				else
				{
					for (j=0; j<((double)44100/((double)3500000/(double)855)); j++)
						b2bset(tape, (*tape_len)++,kkk);
					kkk=1-kkk;

					for (j=0; j<((double)44100/((double)3500000/(double)855)); j++)
						b2bset(tape, (*tape_len)++,kkk);
					kkk=1-kkk;
				}	
			}
		}

		for (j=0; j<((double)44100*(double)rom->pause/(double)1000); j++)
			b2bset(tape, (*tape_len)++,kkk);
		kkk=1-kkk;

		return(no_errors);
	}

	if (next->id==0x20)
	{
		memcpy(&len16, next->info, 2);

		if (!len16)
			return(errors);

		kkk=0;
		for (j=0; j<((double)44100*(double)len16/(double)1000); j++)
			b2bset(tape, (*tape_len)++,kkk);
		kkk=1-kkk;

		return(no_errors);
	}

	if (next->id==0x12)
	{
		ptone = (Pure_toneT *)next->info;

		for (i=0; i<ptone->n; i++)
		{
			for (j=0; j<((double)44100/((double)3500000/(double)ptone->len)); j++)
				b2bset(tape, (*tape_len)++,kkk);
			kkk=1-kkk;
		}

		return(no_errors);
	}

	if (next->id==0x13)
	{
		len=next->len/2;
		pulses=(unsigned short *)next->data1;

		for (i=0; i<(unsigned int)len; i++)
		{
			/*printf("%d\n", pulses[i]);*/

			for (j=0; j<((double)44100/((double)3500000/(double)pulses[i])); j++)
				b2bset(tape, (*tape_len)++,kkk);
			kkk=1-kkk;
		}

		return(no_errors);
	}

	if (next->id==0x14)
	{
		pdata = (Pure_dataT *)next->info;

		for (i=0; i<(unsigned int)(pdata->l1+pdata->l2*256+pdata->l3*65536-1); i++)
		{
			byte=next->data1[i];
			for (l=0; l<8; l++)
			{
				if (b2bget(&byte,l))
				{
					for (j=0; j<((double)44100/((double)3500000/(double)pdata->o)); j++)
						b2bset(tape, (*tape_len)++,kkk);
					kkk=1-kkk;

					for (j=0; j<((double)44100/((double)3500000/(double)pdata->o)); j++)
						b2bset(tape, (*tape_len)++,kkk);
					kkk=1-kkk;
				}
				else
				{
					for (j=0; j<((double)44100/((double)3500000/(double)pdata->z)-(((pdata->z)<700)?2:3)); j++)
						b2bset(tape, (*tape_len)++,kkk);
					kkk=1-kkk;

					for (j=0; j<((double)44100/((double)3500000/(double)pdata->z)-(((pdata->z)<700)?2:3)); j++)
						b2bset(tape, (*tape_len)++,kkk);
					kkk=1-kkk;
				}	
			}
		}

		byte=next->data1[i];
		for (l=0; l<pdata->used; l++)
		{
			if (b2bget(&byte,l))
			{
				for (j=0; j<((double)44100/((double)3500000/(double)pdata->o)); j++)
					b2bset(tape, (*tape_len)++,kkk);
				kkk=1-kkk;

				for (j=0; j<((double)44100/((double)3500000/(double)pdata->o)); j++)
					b2bset(tape, (*tape_len)++,kkk);
				kkk=1-kkk;
			}
			else
			{
				for (j=0; j<((double)44100/((double)3500000/(double)pdata->z)-(((pdata->z)<700)?2:3)); j++)
					b2bset(tape, (*tape_len)++,kkk);
				kkk=1-kkk;

				for (j=0; j<((double)44100/((double)3500000/(double)pdata->z)-(((pdata->z)<700)?2:3)); j++)
					b2bset(tape, (*tape_len)++,kkk);
				kkk=1-kkk;
			}	
		}			

		for (j=0; j<((double)44100*(double)pdata->pause/(double)1000); j++)
			b2bset(tape, (*tape_len)++,kkk);
		if (pdata->pause)
			kkk=1-kkk;

		return(no_errors);
	}

	if (next->id==0x15)
	{
		direct = (direct_recT *)next->info;

		if (direct->TS==79)
		{
			for (i=0; i<(next->len*8-1); i++)
				b2bset(tape, (*tape_len)++, b2bget(next->data1, i));

			for (l=0; l<direct->used; l++)
				b2bset(tape, (*tape_len)++, b2bget(next->data1, i+l));
		}
		else
		{
			for (i=0; i<(next->len*8-1); i++)
			{
				b2bset(tape, (*tape_len)++, b2bget(next->data1, i));
				b2bset(tape, (*tape_len)++, b2bget(next->data1, i));
			}

			for (l=0; l<direct->used; l++)
			{
				b2bset(tape, (*tape_len)++, b2bget(next->data1, i+l));
				b2bset(tape, (*tape_len)++, b2bget(next->data1, i+l));
			}
		}

		for (j=0; j<((double)44100*(double)direct->pause/(double)1000); j++)
			b2bset(tape, (*tape_len)++,kkk);
		if (direct->pause)
			kkk=1-kkk;

		return(no_errors);
	}

	if (next->id==0x22)
	{
		for (j=0; j<((double)44100/((double)3500000/(double)4000)); j++)
			b2bset(tape, (*tape_len)++,kkk);
		kkk=1-kkk;

		return(errors);
	}

	return(errors);
}

void setZ80spd_100(int unused, int client_data, int unused_cbs)
{
	TODO ("SPEED_REGULATOTS");
	Set_z80times_per_line(client_data);
}

void tape_pauseF(int w, int client_data, int cbs)
{
	tape_paused=1;

	//TapeSetString("TAPE PAUSED", 0);
}

unsigned short neproigrannaya_pausa=0;

void tapeFill_tape(int Force)
{
	int group=0;
	tape_struct * next;
	unsigned int j;

	ROM_bl_type * rom;
	unsigned short len16;

	unsigned short rep=0;
	int i;
	signed short * jump;



	if (!tape_next) return;

	tape_len=tape_pos=0;

	if (NadoPropustitEtotTapeBlock(tape_next))
		TapeNextNext();

	if ((ABlockStandartniyP(tape_next))&&(!Force))
	{
		showQTape=1;
		//EnableWidget(tape_lb);

		/*
		DisableWidget(tape_stop);
		DisableWidget(tape_pause);
		*/

		TODO("edw");

		rom= (ROM_bl_type *)tape_next->info;
		neproigrannaya_pausa = rom->pause;

		return;
	}

	Zamolchi();

	kkk=0;
	for (j=0; j<((double)44100*(double)neproigrannaya_pausa/(double)1000); j++)
		b2bset(tape,tape_len++,kkk);
	neproigrannaya_pausa=0;

	kkk=0;
	next=tape_next;
	while (TRUE)
	{
LW:
		if (next->id==0x20)
		{
			memcpy(&len16, next->info, 2);

			if (!len16)
			{
				tape_pauseF(0, 0, 0);
				return;
			}
			else
				Fill(tape, &tape_len, next);
		}

		if (Fill(tape, &tape_len, next)==no_errors)
			goto LE;

		if (next->id==0x21)
		{
			group=1;
			goto LE;
		}

		if (next->id==0x22)
		{
			group=0;
			goto LE;
		}

		if (next->id==0x24) 
		{
			memcpy(&rep, next->info, 2);
			goto LE;
		}

		if (next->id==0x25) 
		{
			if (rep) rep--;

			if (rep)
			{
				while (1)
				{
					next=TapeFindParent(next);
					if (next->id==0x24)
					{
						next= (tape_struct *)next->next;
						goto LW;
					}
				}
			}

			goto LE;
		}

		if (next->id==0x23) 
		{
			jump = (short *)next->info;

			i=0;
			if (*jump>0)
			{
LP1:
				next = (tape_struct *) next->next;
				i++;

				if (i<*jump) goto LP1;
			}
			else
			{
LO:
				next=TapeFindParent(next);
				i--;

				if (i>*jump) goto LO;
			}

			//EnsureVisibleAndSelect(next->position);
			tape_next=next;

			tapeFill_tape(0);
			return;
		}

		printf("*** tapeFill_tape : UNKNOWN BLOCK ID=0x%x ! This is bug. Report it. ***\n", next->id);

LE:
		if ((!group)&&(!rep)) 
		{
			tape_rew_counter=tape_rew_counter_const;

			showQTape=2;			

			return;
		}

		next = (tape_struct *) next->next;
	}
}

void TapeTrapLoad(void)
{
	int i;
	unsigned char * data;



	data=(unsigned char *)(tape_next->data1+1);

	F |= 0x1;
	F &= 0xBF;	

	F=179; // !!!

	A = 0;

	B=0xb0;
	C=0x01;

	H=0;
	L=data[tape_next->len-2]; 

	for (i=IX; i<(IX+DE); i++)
		io_writeByte(i,data[i-IX]);

	DE-=(tape_next->len-2);	
	IX+=(tape_next->len-2);

	showQTape=1;

	TapeNextNext();
	tapeFill_tape(0);
}

void TapeTrapSave(void)
{
	unsigned char data [65536];
	int i;
	unsigned char a;
	int len;
	ROM_bl_type rom;


	len=DE+2;
	data[0]=A;

	for (i=IX; i<(IX+DE); i++)
		data[i-IX+1]=io_readByte(i);

	a=data[0];
	for (i=1;i<(DE+1);i++)
		a^=data[i];

	data[len-1]=a;

	rom.pause=1000;
	rom.len=len;

	AddTapeBlock("", 0x10, len, data, sizeof(rom), &rom, 1, tape_position++);

	showQTape=1;
}

void tape_stopF(int w, int client_data, int cbs)
{
	TapeNextNext();

	tape_pos=tape_len=0; 
	showQTape=0;

	tape_paused=0;

}

int disk_a = 0;
int nmi = 0;

void GenerateNMI(void)
{
	if (Mode[0]=='p' || Mode[0]=='P' || Mode[0]=='S' || Mode[0]=='s')
	{
		nmi = 1;

			if (PC<16384)
				printf ("No return !\n");
		//Log = 1;
	}
}

int z80a(int interrupt)
{
	


	if (Log)
	{
		PrintSpInfo();
		printf (" %d\n", interrupt);
	}


	R++;

	
		if (nmi && PC>=16384)
		{
					nmi = 0;

					interrupts=off;
					halted=off;

					if (Mode[0]=='p' || Mode[0]=='P')
					TRDOS = on;
					else
					//new_rom=ROMSCRP;
					TRDOS = on;

					push(PC);
					PC=0x0066;

					//Log=1;

					return(11);
		}	


	if (interrupt)
	{
		//PrintSpInfo();

		if (interrupts)
		{
			interrupts=off;
			halted=off;

		

			switch(IM)
			{
			case 1: 
				{
					push(PC);
					PC=0x0038;

					return(13);
				}

			case 2: 
				{
					push(PC);
					io_writeToRamAddrSpAddr((unsigned char *)&PC, I*256+data_bus);

					return(19);
				}

			case 0:
				{
					if (data_bus==255)
					{
						push(PC);
						PC=0x0038;

						return(12);
					}
					else
					{
						printf("data_bus == %d. This is not supported.",data_bus);
						ExitWithError(-1,"");
					}
					/* !!! a vot tuta ne dodelano*/
				}

			default:
				{
					printf("Unknown interrupts type %d.\n",IM);
					ExitWithError(-1,"");
				}
			}
		}
	}

	if (halted)
		return(4);

	if (PC>=16384)
		TRDOS=off;
	else
	{
		if (((PC&0xff00)==0x3d00))
		{
			if (new_rom!=ROM0) 
			{
				if ((Mode[0]=='P')||(Mode[0]=='p')||(Mode[0]=='S')||(Mode[0]=='s'))
				{
					TRDOS=on;
					disk_a = 1;
				}
			}
		}

		if ((PC==1218)&&(!TRDOS)&&tape_traps && tape_next) 
		{
			TapeTrapSave();
			pop(&PC);
			return(4);
		}


		if (((PC==1366)||(PC==1378)) && tape_traps && tape_next) 
		{
			if ((tape_pos<tape_len) && (tape_next->id!=0x15) && (DE!=tape_next->len-2))
			{
				tape_stopF(0, 0, 0);
			}

			if (DE==tape_next->len-2)
			{
				TapeTrapLoad();
				PC=0x5e2;
				return(4);
			}
			else
				tapeFill_tape(1);
		}

		if (PC==1366 && !tape_traps)
		{
			if (tape_pos>=tape_len) tapeFill_tape(1);
		}
	}

	if (PC==9)
	{

	}

	switch(io_readByte(PC))
	{
		/* interrupts*/

	case 0xf3: /* di */
		{
			interrupts=off; 
			PC++;
			return(4);
		}


	case 0xfb: /* ei */
		{
			interrupts=on;
			PC++;
			return(4);
		}

		/* zagruzka chisla v registr */

	case 0x3e:
		{
			A=io_readByte(PC+1);
			PC+=2;
			return(7);
		}

	case 0x06:
		{
			B=io_readByte(PC+1);
			PC+=2;
			return(7);
		}

	case 0x0e:
		{
			C=io_readByte(PC+1);
			PC+=2;
			return(7);
		}

	case 0x16:
		{
			D=io_readByte(PC+1);
			PC+=2;
			return(7);
		}

	case 0x1e:
		{
			E=io_readByte(PC+1);
			PC+=2;
			return(7);
		}

	case 0x26:
		{
			H=io_readByte(PC+1);
			PC+=2;
			return(7);
		}

	case 0x2e:
		{
			L=io_readByte(PC+1);
			PC+=2;
			return(7);
		}

		/* zagruzka chisla v registrovuu paru */

	case 0x21:
		{
			L=io_readByte(PC+1);

			H=io_readByte(PC+2);
			PC+=3;
			return(10);
		}

	case 0x11:
		{
			E=io_readByte(PC+1);
			D=io_readByte(PC+2);
			PC+=3;
			return(10);
		}

	case 0x01:
		{
			C=io_readByte(PC+1);
			B=io_readByte(PC+2);
			PC+=3;
			return(10);
		}

	case 0x31:
		{
			io_writeToRamAddrSpAddr((unsigned char *)&SP, PC+1);
			PC+=3;
			return(10);
		}

		/* Kopirovanie soderjimogo odinochnih registrov */

	case 0x7f:
		{
			A=A;
			PC++;
			return(4);
		}

	case 0x7c:
		{
			A=H;
			PC++;
			return(4);
		}

	case 0x7d:
		{
			A=L;
			PC++;
			return(4);
		}

	case 0x78:
		{
			A=B;
			PC++;
			return(4);
		}

	case 0x79:
		{
			A=C;
			PC++;
			return(4);

		}

	case 0x7a:
		{
			A=D;
			PC++;
			return(4);
		}

	case 0x7b:

		{
			A=E;
			PC++;
			return(4);
		}

	case 0x67:
		{
			H=A;
			PC++;
			return(4);
		}

	case 0x64:
		{
			H=H;
			PC++;
			return(4);
		}

	case 0x65:
		{
			H=L;
			PC++;
			return(4);
		}

	case 0x60:
		{
			H=B;
			PC++;
			return(4);
		}

	case 0x61:
		{
			H=C;
			PC++;

			return(4);
		}

	case 0x62:

		{
			H=D;
			PC++;
			return(4);
		}

	case 0x63:
		{
			H=E;
			PC++;
			return(4);
		}

	case 0x6f:
		{
			L=A;
			PC++;
			return(4);

		}

	case 0x6c:
		{
			L=H;

			PC++;
			return(4);
		}

	case 0x6d:
		{
			L=L;
			PC++;
			return(4);
		}

	case 0x68:
		{
			L=B;
			PC++;

			return(4);
		}


	case 0x69:
		{
			L=C;
			PC++;
			return(4);
		}

	case 0x6a:
		{
			L=D;
			PC++;
			return(4);
		}

	case 0x6b:
		{
			L=E;
			PC++;
			return(4);
		}

	case 0x47:

		{
			B=A;
			PC++;
			return(4);
		}

	case 0x44:
		{
			B=H;
			PC++;
			return(4);
		}

	case 0x45:
		{
			B=L;
			PC++;
			return(4);
		}

	case 0x40:
		{
			B=B;
			PC++;
			return(4);
		}

	case 0x41:
		{
			B=C;
			PC++;
			return(4);
		}



	case 0x42:

		{
			B=D;
			PC++;
			return(4);
		}

	case 0x43:
		{
			B=E;
			PC++;
			return(4);
		}

	case 0x4f:
		{
			C=A;
			PC++;
			return(4);
		}

	case 0x4c:
		{
			C=H;
			PC++;
			return(4);
		}

	case 0x4d:
		{
			C=L;
			PC++;
			return(4);
		}

	case 0x48:
		{
			C=B;
			PC++;
			return(4);
		}

	case 0x49:
		{
			C=C;
			PC++;
			return(4);
		}


	case 0x4a:
		{
			C=D;
			PC++;
			return(4);
		}

	case 0x4b:
		{
			C=E;
			PC++;
			return(4);
		}

	case 0x57:
		{
			D=A;
			PC++;
			return(4);
		}

	case 0x54:
		{
			D=H;
			PC++;
			return(4);
		}

	case 0x55:
		{
			D=L;
			PC++;
			return(4);
		}

	case 0x50:
		{
			D=B;
			PC++;
			return(4);
		}

	case 0x51:
		{
			D=C;
			PC++;
			return(4);
		}

	case 0x52:
		{
			D=D;
			PC++;
			return(4);
		}

	case 0x53:
		{
			D=E;
			PC++;
			return(4);
		}

	case 0x5f:
		{
			E=A;
			PC++;
			return(4);
		}

	case 0x5c:
		{
			E=H;
			PC++;
			return(4);
		}

	case 0x5d:
		{
			E=L;
			PC++;
			return(4);
		}

	case 0x58:
		{
			E=B;
			PC++;
			return(4);
		}

	case 0x59:
		{
			E=C;
			PC++;
			return(4);
		}

	case 0x5a:
		{
			E=D;
			PC++;
			return(4);
		}

	case 0x5b:
		{
			E=E;
			PC++;
			return(4);
		}

		/* kopirovanie soderjimogo registrovih par */

	case 0xf9:
		{
			SP=HL;
			PC++;
			return(6);
		}

		/* zagruzka registrov iz pamyati pryamoy adresitsiei */

	case 0x3a:
		{
			A=io_readByte(ex(io_readByte(PC+2), io_readByte(PC+1)));

			

			//ParityA;
			//ZnakA;
			//ZeroA;
			//myFflagC_s(0);
			//myFflagH_s(0);
			//myFflagN_s(0);  Ñêîðåå íå íàäî

			PC+=3;
			return(13);
		}

	case 0x2a:
		{
			L=io_readByte(ex(io_readByte(PC+2), io_readByte(PC+1)));
			H=io_readByte(ex(io_readByte(PC+2), io_readByte(PC+1))+1);

			PC+=3;
			return(16);
		}

		/* zagruzka registrov iz pamyati kosvennoy adresatsiei */

	case 0x7e:

		{
			A=io_readByte(HL);
			PC++;
			return(7);
		}

	case 0x0a:
		{
			A=io_readByte(BC);
			PC++;
			return(7);
		}

	case 0x1a:
		{

			A=io_readByte(DE);
			PC++;
			return(7);
		}

	case 0x66:

		{

			H=io_readByte(HL);
			PC++;
			return(7);
		}

	case 0x6e:
		{
			L=io_readByte(HL);
			PC++;
			return(7);
		}

	case 0x46:
		{
			B=io_readByte(HL);
			PC++;
			return(7);
		}

	case 0x4e:
		{
			C=io_readByte(HL);
			PC++;
			return(7);
		}

	case 0x56:
		{
			D=io_readByte(HL);
			PC++;
			return(7);
		}

	case 0x5e:
		{
			E=io_readByte(HL);
			PC++;
			return(7);
		}

		/* 	komandi obmena */

	case 0xeb:
		{
			D2=D; E2=E;
			D=H; E=L;
			H=D2; L=E2;
			PC++;
			return(4);
		}	

	case 0xd9:
		{
			B2=B; C2=C; D2=D; E2=E; H2=H; L2=L;
			B=B1; C=C1; D=D1; E=E1; H=H1; L=L1;
			B1=B2; C1=C2; D1=D2; E1=E2; H1=H2; L1=L2;

			PC++;
			return(4);
		}	


	case 0x08:
		{
			A2=A; F2=F; 

			A=A1; F=F1; 
			A1=A2; F1=F2; 

			PC++;
			return(4);
		}	

		/* zapis' v pamyat' pryamoi adresatsiei */

	case 0x32:
		{
			io_writeByte(ex(io_readByte(PC+2),io_readByte(PC+1)),A);
			PC+=3;
			return(13);
		}

	case 0x22:
		{
			io_writeByte(ex(io_readByte(PC+2),io_readByte(PC+1)),L);
			io_writeByte(ex(io_readByte(PC+2),io_readByte(PC+1))+1,H);

			PC+=3;
			return(16);
		}	

		/* Zapis' v pamyat' s kosvennoi adresatsiei */

	case 0x77:
		{
			io_writeByte(HL,A);
			PC++;
			return(7);
		}


	case 0x02:
		{
			io_writeByte(BC,A);
			PC++;
			return(7);
		}

	case 0x12:
		{
			io_writeByte(DE,A);
			PC++;
			return(7);
		}

	case 0x74:
		{

			io_writeByte(HL,H);
			PC++;
			return(7);
		}

	case 0x75:
		{
			io_writeByte(HL,L);
			PC++;
			return(7);
		}

	case 0x70:
		{
			io_writeByte(HL,B);
			PC++;
			return(7);
		}

	case 0x71:
		{
			io_writeByte(HL,C);
			PC++;
			return(7);
		}


	case 0x72:
		{
			io_writeByte(HL,D);
			PC++;
			return(7);
		}

	case 0x73:
		{
			io_writeByte(HL,E);
			PC++;
			return(7);
		}

	case 0x36:
		{
			io_writeByte(HL,io_readByte(PC+1));

			PC+=2;
			return(10);
		}	


		/* komandi logiki */

		/*  AND	*/
	case 0xe6:
		{
			A=A&io_readByte(PC+1);

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC+=2;
			return(7);
		}	

	case 0xa7:
		{
			A=A&A;



			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xa4:
		{
			A=A&H;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xa5:
		{
			A=A&L;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xa0:
		{
			A=A&B;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xa1:
		{
			A=A&C;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xa2:
		{
			A=A&D;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	


	case 0xa3:
		{
			A=A&E;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xa6:
		{
			A=A&(io_readByte(HL));

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(7);
		}	

		/* OR */
	case 0xf6:
		{
			A=A|io_readByte(PC+1);

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC+=2;
			return(7);
		}	

	case 0xb7:
		{
			A=A|A;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xb4:
		{
			A=A|H;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xb5:
		{
			A=A|L;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xb0:
		{
			A=A|B;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xb1:
		{
			A=A|C;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;

			return(4);
		}	

	case 0xb2:
		{
			A=A|D;

			ParityA;
			ZnakA;

			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xb3:
		{
			A=A|E;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xb6:
		{
			A=A|(io_readByte(HL));

			ParityA;

			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);

			myFflagN_s(0);

			PC++;
			return(7);
		}

		/* XOR */
	case 0xee:

		{
			A=A^io_readByte(PC+1);


			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC+=2;
			return(7);
		}	

	case 0xaf:

		{
			A=A^A;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xac:
		{
			A=A^H;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xad:
		{
			A=A^L;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);

			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xa8:

		{
			A=A^B;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);

			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xa9:
		{
			A=A^C;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xaa:
		{
			A=A^D;

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);



			PC++;
			return(4);

		}	

	case 0xab:
		{
			A=A^E;


			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}	

	case 0xae:
		{
			A=A^(io_readByte(HL));

			ParityA;
			ZnakA;
			ZeroA;
			myFflagC_s(0);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(7);
		}


		/* komandi perehoda */

	case 0xc3:
		{
			io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
			return(10);
		}

	case 0xe9:
		{
			PC=HL;
			return(4);
		}

	case 0xda:
		{
			if (myFflagC_r())
				io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
			else
				PC+=3;

			return(10);
		}

	case 0xd2:
		{
			if (!myFflagC_r())
				io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
			else
				PC+=3;

			return(10);
		}

	case 0xca:
		{
			if (F&64)
				io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
			else
				PC+=3;

			return(10);
		}

	case 0xc2:
		{
			if (!(F&64))
				io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
			else
				PC+=3;

			return(10);
		}

	case 0xf2:
		{
			if (!(F&128))
				io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
			else
				PC+=3;

			return(10);
		}

	case 0xfa:
		{
			if (F&128)
				io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
			else
				PC+=3;

			return(10);
		}

	case 0xea:
		{
			if (F&4)
				io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
			else
				PC+=3;

			return(10);

		}

	case 0xe2:
		{
			if (!(F&4))
				io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
			else
				PC+=3;

			return(10);
		}

	case 0x18:
		{
			PC+=(signed char)io_readByte(PC+1);
			PC+=2;

			return(12); 
		}

	case 0x38:
		{
			if (myFflagC_r())
			{
				PC+=(signed char)io_readByte(PC+1);
				PC+=2;
				return(12); 
			}
			else
			{
				PC+=2;
				return(7); 
			}
		}

	case 0x30:
		{
			if (!myFflagC_r())


			{
				PC+=(signed char)io_readByte(PC+1);
				PC+=2;
				return(12); 
			}
			else
			{
				PC+=2;
				return(7); 
			}
		}	

	case 0x28:
		{
			if (F&64)
			{
				PC+=(signed char)io_readByte(PC+1);
				PC+=2;
				return(12); 
			}
			else
			{
				PC+=2;
				return(7); 
			}
		}

	case 0x20:
		{
			if (!(F&64))
			{
				PC+=(signed char)io_readByte(PC+1);
				PC+=2;
				return(12); 
			}
			else
			{
				PC+=2;
				return(7); 
			}
		}

	case 0x10: /* djnz */
		{
			B--;
			if (B!=0)
			{
				PC+=(signed char)io_readByte(PC+1);
				PC+=2;
				return(13);
			}
			else
			{
				PC+=2;
				return(8); 
			}
		}

		/* Decrement */

	case 0x0d:
		{
			C--;

			znak(C);
			zero(C);
			myFflagPV_s((C==0x7f));
			myFflagN_s(1);
			myFflagH_s(    ((C&0x0f)==0x0f));

			PC++;
			return(4);
		}	

	case 0x3d:
		{
			A--;

			znak(A);
			zero(A);
			myFflagPV_s((A==0x7f));
			myFflagN_s(1);
			myFflagH_s(    ((A&0x0f)==0x0f));

			PC++;
			return(4);
		}

	case 0x25:
		{
			H--;

			znak(H);
			zero(H);
			myFflagPV_s((H==0x7f));
			myFflagN_s(1);
			myFflagH_s(    ((H&0x0f)==0x0f));

			PC++;
			return(4);
		}

	case 0x2d:
		{
			L--;

			znak(L);
			zero(L);
			myFflagPV_s((L==0x7f));
			myFflagN_s(1);
			myFflagH_s(    ((L&0x0f)==0x0f));

			PC++;
			return(4);
		}

	case 0x05:
		{
			B--;

			znak(B);
			zero(B);
			myFflagPV_s((B==0x7f));
			myFflagN_s(1);
			myFflagH_s(    ((B&0x0f)==0x0f));

			PC++;
			return(4);
		}

	case 0x1d:
		{
			E--;


			znak(E);
			zero(E);
			myFflagPV_s((E==0x7f));
			myFflagN_s(1);
			myFflagH_s(    ((E&0x0f)==0x0f));

			PC++;
			return(7);
		}

	case 0x15:
		{
			D--;

			znak(D);
			zero(D);
			myFflagPV_s((D==0x7f));
			myFflagN_s(1);
			myFflagH_s(    ((D&0x0f)==0x0f));

			PC++;
			return(7);

		}

	case 0x35:
		{
			work8=io_readByte(HL);
			work8--;
			io_writeByte(HL,work8);

			znak(io_readByte(HL));
			zero(io_readByte(HL));
			myFflagPV_s((io_readByte(HL)==0x7f));
			myFflagN_s(1);
			myFflagH_s(    ((io_readByte(HL)&0x0f)==0x0f));

			PC++;
			return(11);
		}

	case 0x2b:
		{	
			HL--;

			PC++;
			return(6);
		}

	case 0x0b:
		{	
			BC--;

			PC++;
			return(6);

		}

	case 0x1b:
		{	
			DE--;

			PC++;
			return(6);
		}

	case 0x3b:
		{	
			SP--;
			PC++;
			return(6);
		}

		/* komandi sravnenia	*/


	case 0xbf:
		{	
			val=A;

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                                
			myFflagZ_s(   ((work16 & 0xff) == 0));                                                
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0xbc:
		{	
			val=H;

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                                
			myFflagZ_s(   ((work16 & 0xff) == 0));                                                
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0xbd:
		{	
			val=L;

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                                
			myFflagZ_s(   ((work16 & 0xff) == 0));                                                
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0xb8:
		{	
			val=B;

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                                
			myFflagZ_s(   ((work16 & 0xff) == 0));                                                
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0xb9:
		{	
			val=C;

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                                
			myFflagZ_s(   ((work16 & 0xff) == 0));                                                
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    

			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0xba:
		{	
			val=D;

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                                
			myFflagZ_s(   ((work16 & 0xff) == 0));                                                
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));


			PC++;
			return(4);
		}

	case 0xbb:
		{	
			val=E;

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                                
			myFflagZ_s(   ((work16 & 0xff) == 0));                                                
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);

		}

	case 0xfe:
		{	
			val=io_readByte(PC+1);

			if (val == 0x15)
			{
				//Log = 1;
			}

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       

				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                                

			myFflagZ_s(   ((work16 & 0xff) == 0));                                                
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC+=2;
			return(7);
		}

	case 0xbe:
		{	
			val=io_readByte(HL);

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               

				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			myFflagS_s(   ((work16 & 0x80) != 0));                                                
			myFflagZ_s(   ((work16 & 0xff) == 0));                                                
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(7);
		}

		/* vichitanie s uchetom perenosa */

	case 0xde:
		{
			val=io_readByte(PC+1);

			work16 = A - (val) - myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;                                                                              
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC+=2;

			return(7);
		}

	case 0x9f:

		{
			val=A;

			work16 = A - (val) - myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;                                                                              
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0x9c:
		{

			val=H;

			work16 = A - (val) - myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;                                                                              
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0x9d:
		{
			val=L;

			work16 = A - (val) - myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;                                                                              
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0x98:
		{
			val=B;

			work16 = A - (val) - myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;                                                                              
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0x99:
		{
			val=C;

			work16 = A - (val) - myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;                                                                              
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}


	case 0x9a:
		{
			val=D;

			work16 = A - (val) - myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;                                                                              
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0x9b:
		{
			val=E;

			work16 = A - (val) - myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;                                                                              
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0x9e:
		{
			val=io_readByte(HL);

			work16 = A - (val) - myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;                                                                              
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s(   sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);
			myFflagC_s( ((work16 & 0x0100) != 0));


			PC++;
			return(7);
		}

		/* komandi prostogo slojeniya	*/

	case 0x87:
		{
			val=A;

			work16 = A + (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                              
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s(   overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));



			PC++;
			return(4);
		}

	case 0x84:
		{
			val=H;

			work16 = A + (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                              
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s(   overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0) );

			PC++;
			return(4);
		}

	case 0x85:
		{
			val=L;

			work16 = A + (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                              
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s(   overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0) );

			PC++;
			return(4);
		}

	case 0x80:
		{
			val=B;

			work16 = A + (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                              
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s(   overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0) );


			PC++;
			return(4);
		}

	case 0x81:
		{
			val=C;

			work16 = A + (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                              
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s(   overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0) );

			PC++;
			return(4);
		}

	case 0x82:
		{
			val=D;

			work16 = A + (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              

			ZnakA;                                                             
			ZeroA;                                                                              
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s(   overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0) );

			PC++;
			return(4);
		}

	case 0x83:
		{
			val=E;

			work16 = A + (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                              
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s(   overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0) );

			PC++;
			return(4);
		}


	case 0xc6:
		{
			val=io_readByte(PC+1);

			work16 = A + (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                              
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s(   overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0) );

			PC+=2;
			return(7);
		}

	case 0x86:
		{
			val=io_readByte(HL);

			work16 = A + (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                              
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s(   overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(7);
		}

	case 0x29:
		{
			reg=HL;

			work32 = HL + reg;                                                                    
			idx = ((HL & 0x8800) >> 9) |                                                    
				(((reg) & 0x8800) >> 10) |                                            
				((work32 & 0x8800) >> 11);                                            
			HL1_1 = work32 & 0xffff;       

			//printf("%d %d\n", idx, hcarry_tbl(idx));

			myFflagH_s(   hcarry_tbl(idx));                                                               

			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work32 & 0x10000) != 0));
			HL=HL1_1;


			PC++;
			return(11);
		}

	case 0x09:
		{
			reg=BC;

			work32 = HL + reg;                                                                    
			idx = ((HL & 0x8800) >> 9) |                                                    
				(((reg) & 0x8800) >> 10) |                                            
				((work32 & 0x8800) >> 11);                                            
			HL1_1 = work32 & 0xffff;                                                                   

			myFflagH_s(   hcarry_tbl(idx));                                                               
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work32 & 0x10000) != 0) );
			HL=HL1_1;

			PC++;
			return(11);
		}

	case 0x19:
		{
			reg=DE;

			work32 = HL + reg;                                                                    
			idx = ((HL & 0x8800) >> 9) |                                                    
				(((reg) & 0x8800) >> 10) |                                            
				((work32 & 0x8800) >> 11);                                            
			HL1_1 = work32 & 0xffff;                                                                   
			myFflagH_s(   hcarry_tbl(idx));                                                               
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work32 & 0x10000) != 0) );

			HL=HL1_1;

			PC++;
			return(11);
		}

	case 0x39:
		{
			reg=SP;

			work32 = HL + reg;                                                                    
			idx = ((HL & 0x8800) >> 9) |                                                    
				(((reg) & 0x8800) >> 10) |                                            
				((work32 & 0x8800) >> 11);                                            
			HL1_1 = work32 & 0xffff;                                                                   
			myFflagH_s(   hcarry_tbl(idx));                                                               
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work32 & 0x10000) != 0) );
			HL=HL1_1;

			PC++;
			return(11);
		}



		/* increment */

	case 0x3c :
		{
			reg=A;


			reg++;                                                                                                
			znak(reg);                                                 
			zero(reg);                                                                  
			myFflagH_s(   (((reg) & 0x0f) == 0));                                                 
			myFflagPV_s(   ((reg) == 0x80));                                                               
			myFflagN_s(0);
			A = (unsigned char) reg;

			PC++;
			return(4);
		}

	case 0x24 :
		{
			reg=H;

			reg++;                                                                                                
			znak(reg);                                                 
			zero(reg);                                                                  
			myFflagH_s(   (((reg) & 0x0f) == 0));                                                 
			myFflagPV_s(   ((reg) == 0x80));                                                               
			myFflagN_s(0);
			H = (unsigned char) reg;

			PC++;
			return(4);
		}

	case 0x2c :
		{
			reg=L;

			reg++;                                                                                                
			znak(reg);                                                 
			zero(reg);                                                                  
			myFflagH_s(   (((reg) & 0x0f) == 0));                                                 
			myFflagPV_s(   ((reg) == 0x80));                                                               

			myFflagN_s(0);
			L = (unsigned char) reg;

			PC++;
			return(4);
		}

	case 0x04 :
		{
			reg=B;


			reg++;                                                                                                
			znak(reg);                                                 
			zero(reg);                                                                  
			myFflagH_s(   (((reg) & 0x0f) == 0));                                                 
			myFflagPV_s(   ((reg) == 0x80));                                                               
			myFflagN_s(0);
			B = (unsigned char)reg;

			PC++;
			return(4);
		}

	case 0x0c :
		{
			reg=C;

			reg++;                                                                                                
			znak(reg);                                                 
			zero(reg);                                                                  
			myFflagH_s(   (((reg) & 0x0f) == 0));                                                 
			myFflagPV_s(   ((reg) == 0x80));                                                               
			myFflagN_s(0);
			C = (unsigned char) reg;

			PC++;
			return(4);
		}

	case 0x14 :
		{
			reg=D;

			reg++;                                                                                                
			znak(reg);                                                 
			zero(reg);                                                                  
			myFflagH_s(   (((reg) & 0x0f) == 0));                                                 
			myFflagPV_s(   ((reg) == 0x80));                                                               
			myFflagN_s(0);
			D = (unsigned char) reg;

			PC++;
			return(4);
		}

	case 0x1c :
		{
			reg=E;

			reg++;                                                                                                
			znak(reg);                                                 
			zero(reg);                                                                  
			myFflagH_s(   (((reg) & 0x0f) == 0));                                                 
			myFflagPV_s(   ((reg) == 0x80));                                                               
			myFflagN_s(0);
			E = (unsigned char) reg;

			PC++;
			return(4);
		}

	case 0x34 :
		{
			reg=io_readByte(HL);

			reg++;                                                                                                
			znak(reg);                                                 
			zero(reg);                                                                  
			myFflagH_s(   (((reg) & 0x0f) == 0));                                                 
			myFflagPV_s(   ((reg) == 0x80));                                                               
			myFflagN_s(0);
			io_writeByte(HL,reg);

			PC++;
			return(11);
		}

	case 0x23 :
		{
			HL++;

			PC++;
			return(6);
		}

	case 0x03 :
		{
			BC++;

			PC++;
			return(6);
		}

	case 0x13 :
		{
			DE++;

			PC++;
			return(6);
		}

	case 0x33 :
		{
			SP++;

			PC++;
			return(6);
		}

		/* komandi push */

	case 0xf5 :
		{
			push(AF);
			PC++;
			return(11);
		}

	case 0xc5 :
		{
			push(BC);
			PC++;
			return(11);
		}

	case 0xd5 :
		{
			push(DE);
			PC++;
			return(11);
		}

	case 0xe5 :
		{
			push(HL);
			PC++;
			return(11);
		}

		/*	komandi prostogo vichitania */

	case 0x97 :
		{
			val=A;	

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s( sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0x94 :
		{
			val=H;	

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             

			myFflagPV_s( sub_overflow_tbl(idx >> 4) );                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0x95 :
		{
			val=L;	


			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s( sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0x90 :
		{
			val=B;	

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s( sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0x91 :
		{
			val=C;	

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s( sub_overflow_tbl(idx >> 4));
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0x92 :
		{
			val=D;	


			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s( sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0x93 :
		{
			val=E;	

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s( sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0xd6 :
		{
			val=io_readByte(PC+1);	

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       

				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s( sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC+=2;
			return(7);
		}

	case 0x96 :
		{
			val=io_readByte(HL);	

			work16 = A - (val);                                                                             
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;                                                             
			ZeroA;                                                                             
			myFflagH_s(   sub_hcarry_tbl(idx & 0x7));                                             
			myFflagPV_s( sub_overflow_tbl(idx >> 4));                                    
			myFflagN_s(1);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(7);
		}

		/* komandi pop */

	case 0xf1 :
		{
			pop(&work16);
			A=work16/256;
			F=work16-A*256;


			PC++;
			return(10);
		}

	case 0xc1 :
		{
			pop(&work16);
			B=work16/256;
			C=work16-B*256;

			PC++;
			return(10);
		}

	case 0xd1 :
		{
			pop(&work16);
			D=work16/256;
			E=work16-D*256;

			PC++;
			return(10);
		}

	case 0xe1 :
		{
			pop(&work16);
			H=work16/256;
			L=work16-H*256;

			PC++;
			return(10);
		}
		/*
		/// POP END
		*/
		/* komandi obrazheniya k pzu (rst) */

	case 0xc7 :
		{
			push(PC+1);
			PC=0x0000;
			return(11);
		}

	case 0xcf :
		{
			push(PC+1);
			PC=0x0008;
			return(11);
		}

	case 0xd7 :
		{
			push(PC+1);
			PC=0x0010;
			return(11);
		}

	case 0xdf :
		{
			push(PC+1);
			PC=0x0018;
			return(11);
		}

	case 0xe7 :
		{
			push(PC+1);
			PC=0x0020;
			return(11);
		}

	case 0xef :
		{
			push(PC+1);
			PC=0x0028;
			return(11);
		}

	case 0xf7 :
		{
			push(PC+1);
			PC=0x0030;
			return(11);
		}

	case 0xff :
		{
			push(PC+1);
			PC=0x0038;
			return(11);
		}


		/* komandi rotatsii bitov */


	case 0x0f: /* rrca */
		{
			myFflagC_s( A & 1);
			A = (A >> 1) | (128 * myFflagC_r());
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}

	case 0x1f: /* rra */
		{
			work8 = myFflagC_r();
			myFflagC_s( A & 0x01);
			A = (A >> 1) | (work8 * 128);
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}

	case 0x07 : /* rlca */
		{
			myFflagC_s( ((A & 0x80) != 0));
			A = (A << 1) | myFflagC_r();
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}

	case 0x17 : /* rla */
		{ 
			work8 = myFflagC_r();
			myFflagC_s( ((A & 0x80) != 0) );
			A = (A << 1) | work8;
			myFflagH_s(0);
			myFflagN_s(0);

			PC++;
			return(4);
		}

		/* komandi vizova podprogramm */

	case 0xcd :
		{
			push(PC+3);
			io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
			return(17);
		}

	case 0xdc :
		{
			if (myFflagC_r())
			{
				push(PC+3);
				io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
				return(17);
			}
			PC+=3;
			return(11);
		}

	case 0xd4 :
		{
			if (!myFflagC_r())
			{
				push(PC+3);
				io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
				return(17);
			}
			PC+=3;
			return(11);
		}

	case 0xcc :

		{
			if (F&64)
			{
				push(PC+3);
				io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
				return(17);
			}
			PC+=3;
			return(11);
		}

	case 0xc4 :
		{
			if (!(F&64))
			{
				push(PC+3);
				io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
				return(17);
			}
			PC+=3;
			return(11);
		}

	case 0xfc :
		{
			if (F&128)
			{
				push(PC+3);
				io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
				return(17);
			}
			PC+=3;
			return(11);
		}

	case 0xf4 :
		{
			if (!(F&128))
			{
				push(PC+3);
				io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
				return(17);
			}
			PC+=3;
			return(11);
		}

	case 0xec :
		{
			if (F&4)
			{
				push(PC+3);
				io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
				return(17);
			}
			PC+=3;
			return(11);
		}

	case 0xe4 :
		{
			if (!(F&4))

			{
				push(PC+3);
				io_writeToRamAddrSpAddr((unsigned char *)&PC, PC+1);
				return(17);
			}
			PC+=3;
			return(11);
		}

		/* komandi vozvrata iz podprogramm */

	case 0xc9 :
		{
			pop(&PC);
			return(10);
		}

	case 0xd8 :
		{
			if (myFflagC_r())

			{
				pop(&PC);
				return(11);
			}
			PC++;
			return(5);
		}

	case 0xd0 :

		{
			if (!myFflagC_r())
			{
				pop(&PC);
				return(11);
			}
			PC++;
			return(5);
		}

	case 0xc8 :
		{
			if (F&64)
			{
				pop(&PC);
				return(11);
			}
			PC++;


			return(5);
		}

	case 0xc0 :
		{
			if (!(F&64))
			{
				pop(&PC);
				return(11);
			}
			PC++;
			return(5);
		}


	case 0xf8 :
		{

			if (F&128)
			{
				pop(&PC);
				return(11);
			}
			PC++;
			return(5);
		}

	case 0xf0 :
		{
			if (!(F&128))
			{
				pop(&PC);
				return(11);
			}
			PC++;
			return(5);
		}

	case 0xe8 :

		{
			if (F&4)
			{
				pop(&PC);
				return(11);
			}
			PC++;
			return(5);
		}

	case 0xe0 :
		{
			if (!(F&4))
			{
				pop(&PC);
				return(11);
			}
			PC++;
			return(5);
		}

	case 0xd3: /* out (n),a */
		{
			OutPort(io_readByte(PC+1),A,A);
			PC+=2;
			return(11);
		}

	case 0xdb: /* in a, (n) */
		{
			A=InPort(io_readByte(PC+1),A);
			PC+=2;
			return(11);
		}

		/* komandi slojeniya s uchetom perenosa */

	case 0x8f:
		{
			val=A;

			work16 = A + (val) + myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s( overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0) );

			PC++;
			return(4);
		}

	case 0x8c:
		{
			val=H;

			work16 = A + (val) + myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s( overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0) );

			PC++;
			return(4);
		}

	case 0x8d:
		{
			val=L;

			work16 = A + (val) + myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s( overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0) );


			PC++;
			return(4);
		}


	case 0x88:

		{
			val=B;

			work16 = A + (val) + myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s( overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0x89:

		{
			val=C;

			work16 = A + (val) + myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;



			ZeroA;
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s( overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0x8a:
		{
			val=D;

			work16 = A + (val) + myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               


				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s( overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0x8b:
		{
			val=E;

			work16 = A + (val) + myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       

			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s( overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(4);
		}

	case 0xce:
		{
			val=io_readByte(PC+1);

			work16 = A + (val) + myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s( overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC+=2;
			return(7);
		}

	case 0x8e:
		{
			val=io_readByte(HL);

			work16 = A + (val) + myFflagC_r();                                                    
			idx = ((A & 0x88) >> 1) |                                                               
				(((val) & 0x88) >> 2) |                                                       
				((work16 & 0x88) >> 3);                                                       
			A = work16 & 0xff;                                                                              
			ZnakA;
			ZeroA;
			myFflagH_s(   hcarry_tbl(idx & 0x7));                                                 
			myFflagPV_s( overflow_tbl(idx >> 4));                                                
			myFflagN_s(0);                                                                                    
			myFflagC_s( ((work16 & 0x0100) != 0));

			PC++;
			return(7);
		}


	case 0x00: /* nop */
		{
			PC++;
			return(4);
		}

	case 0x2f: /* cpl */
		{
			A^=0xff;

			myFflagH_s(1);
			myFflagN_s(1);

			PC++;
			return(4);
		}

	case 0x37: /* scf */
		{
			myFflagC_s(1);
			myFflagN_s(0); 
			myFflagH_s(0);

			PC++;
			return(4);
		}

	case 0x3f: /* ccf */
		{
			myFflagH_s(    myFflagC_r()); 
			myFflagN_s(0); 

			if (myFflagC_r())
				myFflagC_s(0);
			else
				myFflagC_s(1);

			PC++;
			return(4);

		}

	case 0xe3: /* ex (sp),hl */
		{
			pop(&XX);
			push(HL);
			HL=XX;

			PC++;
			return(19);
		}

	case 0x76: /* halt */
		{
			halted=on;

			PC++;

			return(4);
		}



	case 0x27: /* daa */
		{
			add = 0, carry = myFflagC_r();

			if( ( F&16 ) || ( (A & 0x0f)>9 ) ) add=6;
			if( carry || (A > 0x9f ) ) add|=0x60;
			if( A > 0x99 ) carry=1;

			if ( F&2 /* Flag N */ ) A-=add;
			else 
			{
				if( (A>0x90) && ( (A & 0x0f)>9) ) add|=0x60;
				A+=add;
			}

			if (carry==1)
				myFflagC_s(1);
			else
				myFflagC_s(0);

			ZeroA;

			ZnakA;
			ParityA;

			PC++;
			return(4);
		}

		/* S prefiksom */

	case 0xDD:
		{
			R++;
			PC++;
			return(DD());
		}

	case 0xFD:
		{
			R++;
			PC++;
			return(FD());
		}

	case 0xED:
		{
			R++;
			PC++;
			return(ED());
		}

	case 0xCB:
		{
			R++;
			PC++;
			return(CB());
		}
	}

	printf("\nZ80 : Unknown instruction %x at address %x.\n",io_readByte(PC),PC);
	ExitWithError(-1,"");

	return(0); /* eto chtob ne kvakalo */
}

# define direct_mic_max_len 9000000
unsigned int direct_mic_pos=0;
unsigned char direct_mic_buf[direct_mic_max_len];

void DirectMicDrop(void)
{
	direct_recT direct;
	unsigned int len;


	len=direct_mic_pos/8;

	direct.TS=79;
	direct.pause=0;

	direct.used=direct_mic_pos-len*8+1;

	len++;

	direct.l3=(len&0xFF0000)/65536;
	direct.l2=(len&0x00FF00)/256;
	direct.l1= len&0x0000FF;

	AddTapeBlock("", 0x15, len, direct_mic_buf, sizeof(direct), &direct, 1, tape_position++);

	direct_mic_pos=0;
}

int v44100_22050=0;
void tapeF (int arg)
{
	tape_rew_counter-=arg;

	if (tape_rew_counter<(-2))
	{
		tape_rew_counter=tape_rew_counter_const;

		if (!direct_mic)
		{
			if (v44100_22050)
			{
				tapeMIC[tapeMIC_pos++]=last_tape_out;

				if (tapeMIC_pos>=tapeMIC_max)
				{
					WorkWithBuffer2(tapeMIC, tapeMIC_pos);
					tapeMIC_pos=0;
					tapeMIC_pos_prev=0;
				}	
			}

			v44100_22050=1-v44100_22050;
		}
		else
		{
			b2bset(direct_mic_buf, direct_mic_pos, (last_tape_out<128)?0:1);
			direct_mic_pos++;
			if (direct_mic_pos>=(direct_mic_max_len*8))
			{
				direct_mic_pos--;
				DirectMicDrop();
			}
		}

		if (direct_recording)
		{
			if (direct_recording_buffer_pos==(DIRECT_RECORDING_BUFFER_SIZE-1))
			{
				io_read(audio3, direct_recording_buffer, DIRECT_RECORDING_BUFFER_SIZE);
				direct_recording_buffer_pos=0;


				return;
			}

			direct_recording_buffer_pos++;

			return;
		}

		if ((tape_pos>=tape_len)||(tape_paused)) return;

		tape_pos++;
		AYio_writeRegNV(BEEPER,b2bget(tape, tape_pos));

		if (tape_pos==tape_len)
		{
			if (!TapeNextNext())
				tapeFill_tape(0);
			else
			{
				tape_SetActiveAndPause(tapes);
			}
		}
	}
}


int z80b_vz80; 
int Z80NTtodo=0;
void z80NT (int todo, int interrupt)
{

	todo+=Z80NTtodo;

	if (interrupt)
	{
		if (Z80NTtodo>0) 
		{
			z80b_vz80=z80a(0);
			TC+=z80b_vz80;
			tapeF(z80b_vz80);
			tcounter+=z80b_vz80;
			todo-=z80b_vz80;
		}

		z80b_vz80=z80a(1);
		TC+=z80b_vz80;
		tapeF(z80b_vz80);
		tcounter+=z80b_vz80;
		todo-=z80b_vz80;
	}	

	while (TRUE)
	{
		if (todo<4) 
		{
			Z80NTtodo=todo;
			break;
		}

		z80b_vz80=z80a(0);
		TC+=z80b_vz80;
		tapeF(z80b_vz80);
		tcounter+=z80b_vz80;
		todo-=z80b_vz80;
	}
}



# define GetAddrInZXScreen48ByLine  ((line&192)*32+(line&7)*0x100+(line&56)*4)

# define ScreenNT_Single_source_razm_1 unsigned int
# define ScreenNT_Single_source_razm_2 unsigned long long

# define Sizeof 2

void ScreenNT_Double32(ScreenNT_Single_source_razm_1 * vs, ScreenNT_Single_source_razm_1 * XColors16)
{
	unsigned int i, line;
	int counter=0, counter1;


	p_ff_in=255;
	z80NT(NT_T_UP, 1); 

	/*verhnii border do 16384*/
	line=24;
	while (line--)	
	{
		counter=(23-line)*640*Sizeof;

		z80NT(NT_T_LP, 0);

		i=160;
		while (i--) 
		{
			z80NT(1,0); 

			*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
			*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
			*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
			*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];

			if (!scan)
			{
				counter1=counter+(320*Sizeof-4);

				*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
				*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
				*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
				*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
			}


		}	

		z80NT(NT_T_RP, 0); 
	}	

	/*ekran*/
	for (line=0; line<192; line++)
	{
		counter=(line+24)*640*Sizeof;

		z80NT(NT_T_LP, 0);

		i=16;
		while (i--) 
		{
			z80NT(1,0); 

			*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
			*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
			*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
			*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];

			if (!scan)
			{
				counter1=counter+(320*Sizeof-4);

				*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
				*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
				*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
				*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
			}


		}

		rb=GetAddrInZXScreen48ByLine;
		for (ri=0; ri<32; ri++) /*linia ekrana*/
		{
			rc=ri+32*(line/8); /* bait attributov ot nachala attributov_48 */
			p_ff_in=attrib48[rc];

			if (attrib48[rc]&64)
			{
				rt=(attrib48[rc]&7)+8;
				rf=((attrib48[rc]&56)/8)+8;
			}
			else
			{
				rt=attrib48[rc]&7;
				rf=(attrib48[rc]&56)/8;
			}

			if (attrib48[rc]&128)
			{
				if (flashcounter>15)
				{
					rr=rf;
					rf=rt;
					rt=rr;
				}
			}

			z80NT(1,0); 

			if (screen48[rb]&128)
			{
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				if (!scan)
				{
					counter1=counter+(320*Sizeof-2);
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				}

			}
			else
			{
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				if (!scan)
				{
					counter1=counter+(320*Sizeof-2);
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				}

			}

			if (screen48[rb]&64)
			{
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				if (!scan)
				{
					counter1=counter+(320*Sizeof-2);
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				}

			}
			else
			{
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				if (!scan)
				{
					counter1=counter+(320*Sizeof-2);
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				}

			}


			z80NT(1,0); 

			if (screen48[rb]&32)
			{
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				if (!scan)
				{
					counter1=counter+(320*Sizeof-2);
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				}

			}
			else
			{
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				if (!scan)
				{
					counter1=counter+(320*Sizeof-2);
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				}

			}			

			if (screen48[rb]&16)
			{
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				if (!scan)
				{
					counter1=counter+(320*Sizeof-2);
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				}

			}
			else
			{
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				if (!scan)
				{
					counter1=counter+(320*Sizeof-2);
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				}

			}		


			z80NT(1,0); 

			if (screen48[rb]&8)
			{
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				if (!scan)
				{
					counter1=counter+(320*Sizeof-2);
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				}

			}
			else
			{
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				if (!scan)
				{
					counter1=counter+(320*Sizeof-2);
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				}

			}			

			if (screen48[rb]&4)
			{
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				if (!scan)
				{
					counter1=counter+(320*Sizeof-2);
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				}

			}
			else
			{
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				if (!scan)
				{
					counter1=counter+(320*Sizeof-2);
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				}

			}			


			z80NT(1,0); 

			if (screen48[rb]&2)
			{
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				if (!scan)
				{
					counter1=counter+(320*Sizeof-2);
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				}

			}
			else
			{
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				if (!scan)
				{
					counter1=counter+(320*Sizeof-2);
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				}

			}			

			if (screen48[rb]&1)
			{
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				if (!scan)
				{
					counter1=counter+(320*Sizeof-2);
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rt];
				}

			}
			else
			{
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				if (!scan)
				{
					counter1=counter+(320*Sizeof-2);
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
					*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[rf];
				}

			}

			rb++;
		}

		i=16;
		while (i--) 
		{
			z80NT(1,0); 

			*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
			*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
			*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
			*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];

			if (!scan)
			{
				counter1=counter+(320*Sizeof-4);

				*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
				*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
				*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
				*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
			}


		}

		z80NT(NT_T_RP, 0); 
	}	

	/*nijniy border*/
	line=24;
	while (line--)	
	{
		counter=((23-line)+216)*640*Sizeof;

		z80NT(NT_T_LP, 0);

		i=160;
		while (i--) 
		{
			z80NT(1,0); 

			*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
			*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
			*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
			*(ScreenNT_Single_source_razm_1*)&vs[counter++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];

			if (!scan)
			{
				counter1=counter+(320*Sizeof-4);

				*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
				*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
				*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
				*(ScreenNT_Single_source_razm_1*)&vs[counter1++]=*(ScreenNT_Single_source_razm_1*)&XColors16[border];
			}


		}	

		z80NT(NT_T_RP, 0); 
	}	

	z80NT(NT_T_DP, 0);
}


int UL_colorA, UL_colorB, UL_colorC;
int UL_AVol, UL_BVol, UL_CVol;
int UL_skip=0;
int UL_AVol_max, UL_BVol_max, UL_CVol_max;

void UpdateLeds(void)
{
# define ledsWidth 3	


	if (!leds_global)
		return;

	avol_max&=15;
	bvol_max&=15;
	cvol_max&=15;

	if (((Atone | channelA_enabled) & (Anoice | noiseA_enabled)) | !GeneratorA_period)
	{
		if (Regs1[AY_AVOL]&0x10)
		{
			UL_AVol=15;
			UL_colorA=0;
		}
		else
		{
			UL_colorA=1;
			UL_AVol=avol_max;
		}
	}
	else
		UL_AVol=0;

	if (((Btone | channelB_enabled) & (Bnoice | noiseB_enabled)) | !GeneratorB_period)
	{
		if (Regs1[AY_BVOL]&0x10)
		{
			UL_BVol=15;
			UL_colorB=0;
		}
		else
		{
			UL_colorB=1;
			UL_BVol=bvol_max;
		}
	}
	else
		UL_BVol=0;

	if (((Ctone | channelC_enabled) & (Cnoice | noiseC_enabled)) | !GeneratorC_period)
	{
		if (Regs1[AY_CVOL]&0x10)
		{
			UL_CVol=15;
			UL_colorC=0;
		}
		else
		{
			UL_colorC=1;
			UL_CVol=cvol_max;
		}
	}		
	else
		UL_CVol=0;

	if (UL_AVol_max<UL_AVol)UL_AVol_max=UL_AVol;
	if (UL_BVol_max<UL_BVol)UL_BVol_max=UL_BVol;
	if (UL_CVol_max<UL_CVol)UL_CVol_max=UL_CVol;

	avol_max=bvol_max=cvol_max=0;

	if (UL_skip)
	{
		UL_skip--;
		return;
	}
	else
	{
		//SetLL(0, ledsY, UL_AVol_max, ledsWidth, 0, ledsY+3, UL_BVol_max, ledsWidth, 0, ledsY+6, UL_CVol_max, ledsWidth);

		if (UL_AVol_max)	UL_AVol_max--;
		if (UL_BVol_max)	UL_BVol_max--;
		if (UL_CVol_max)	UL_CVol_max--;

		if (UL_AVol_max)	UL_AVol_max--;
		if (UL_BVol_max)	UL_BVol_max--;
		if (UL_CVol_max)	UL_CVol_max--;


		UL_skip=2;
	}
}


void tape_show_rec_vol(unsigned char arg)
{
	int color=0;


	/*
	if (arg<=79)
	color=0;
	else
	if ((arg>=80)&&(arg<=127))
	color=1;
	else
	if ((arg>=128)&&(arg<=199))
	color=2;
	else
	if ((arg>=200)&&(arg<=239))
	color=1;
	else
	if ((arg>=240)&&(arg<=255))

	color=3;
	*/
	TODO ("tape_show_rec_vol");

	/*
	XClearWindow(display, tape_sc_lev_win);

	XSetForeground(display,gclev,palettelev[color]);
	XFillRectangle(display,tape_sc_lev_win,gclev,0,tape_sc_lev_y/6,tape_sc_lev_x*arg/255,tape_sc_lev_y*2/3);

	XSetForeground(display,gclev,palettelev[4]);
	XDrawRectangle(display,tape_sc_lev_win,gclev,0,tape_sc_lev_y/6,tape_sc_lev_x-1,tape_sc_lev_y*2/3);
	*/
}



int Pischit(char * arg, unsigned int from, unsigned int to)
{
	unsigned int i;


	from++;
	for (i=from; i<to; i++)
	{
		if (arg[i-1]!=arg[i])
			return 1;
	}

	return 0;
}


char PSG_file_name[2000];
int dumping = 0;
int timerfunc_counter = 0;


void Dump (void)
{
	unsigned char header[16] = {0x50, 0x53, 0x47, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
	unsigned char ff [1] = {0xff};
	unsigned char duo[2];

	int PSG_file;

	int len = 0;


	for (int i=0; i<A_Y.tcounter; i++)
	{		
		for (int j=0; j<A_Y.counter[i]; j++)
		{
			len ++;
		}
	}

	if (!len)
	{
		printf ("No AY sound!\n");
		goto LQ;
	}

	PSG_file = io_creat("", PSG_file_name);

	io_write (PSG_file, header, sizeof (header));

	for (int i=0; i<A_Y.tcounter; i++)
	{
		io_write (PSG_file, ff, sizeof (ff));

		for (int j=0; j<A_Y.counter[i]; j++)
		{
			duo[0] = A_Y.registers[j][i];
			duo[1] = A_Y.values[j][i];

			io_write (PSG_file, duo, sizeof (duo));
		}
	}

	io_close(PSG_file);

	timerfunc_counter ++;


LQ:
	A_Y.tcounter = 0;

	for (int i=0; i<MAX_AY_PER_FILE; i++)
		A_Y.counter[i] = 0;
}


void DumpPSG(char * filename, char * dir, int begin)
{
	char NNN[20];
	int len;

	if (begin)
	{
		if (dir && strlen (dir))
			sprintf(PSG_file_name, "%s/%s", dir, filename);
		else
			sprintf(PSG_file_name, "%s", filename);

		sprintf (NNN, "%03d", timerfunc_counter);
		len = strlen(PSG_file_name);
		strcpy (&PSG_file_name[len - 3], NNN);
		strcat (PSG_file_name, ".psg");


		A_Y.tcounter = 0;

		for (int i=0; i<MAX_AY_PER_FILE; i++)
			A_Y.counter[i] = 0;		

		dumping = 1;
	}
	else
	{
		Dump();

		dumping = 0;
	}

}

void timerfunc(void)
{
	char NNN[20];

	ScreenNT_Double32((unsigned int *)videomemory, XColors32);

	UpdateSoundBuffer();
	UpdateLeds();

	flashcounter++;

	if (flashcounter>32)
	{
		flashcounter=0;

		if (!tape_paused)
		{
			if (showQTape)
			{
				//ShowTape(1);

				if (showQTape==1)	
					showQTape=0;

				if (showQTape==2)
				{
					if (tape_len)
						sprintf(tstring,"Block %d/%d", tape_next->position, last_tape_p);
					else
						sprintf(tstring,"ERROR tape_len==0 !!");

					//TapeSetString(tstring, tape_pos*100/tape_len);
				}
			}
			else
			{
				//ShowTape(0);
				//TapeSetString("", 0);
			}
		}

		if (showFloppik)
		{
			//ShowDisk(1);
			showFloppik=0;
		}
		else
			//ShowDisk(0)
			;
	}


	if (dumping && disk_a)
	{
		Dump();


		int len = strlen(PSG_file_name);
		sprintf (NNN, "%03d", timerfunc_counter);
		memcpy (&PSG_file_name[len - 7], NNN, 3);

		disk_a = 0;
	}


	A_Y.tcounter ++;

	if (A_Y.tcounter==MAX_AY_PER_FILE)
		A_Y.tcounter--;
}	

void Zamolchi(void)
{
	PSGcounter=0;
	Regs1[AY_AVOL]=Regs1[AY_BVOL]=Regs1[AY_CVOL]=0;
}

void MessageBoxInfo(char * s)
{
	TODO ("MessageBoxInfo");
}

int Load48snap(char * filename, char * homedir)
{
	int fil;
	unsigned char buffer[27];


	MapROM1();
	Set48Screen();
	Zamolchi();

	fil=io_open(homedir, filename,O_RDONLY);

	if (fil==-1)
	{
		sprintf(tstring,"Unable to open %s", filename);
		MessageBoxErr(tstring);
		return(errors);
	}


	printf(".sna 48k\n");


	io_read(fil,buffer,27);

	I=buffer[0];
	L1=buffer[ 1];      H1=buffer[ 2];
	E1=buffer[ 3];      D1=buffer[ 4];
	C1=buffer[ 5];      B1=buffer[ 6];
	F1=buffer[ 7];      A1=buffer[ 8];
	L =buffer[ 9];      H =buffer[10];
	E =buffer[11];      D =buffer[12];
	C =buffer[13];      B =buffer[14];

	memcpy(&IY,&buffer[15],2);
	memcpy(&IX,&buffer[17],2);

#if defined BIGENDIAN
	byteswp ((unsigned char *)&IX); 
	byteswp ((unsigned char *)&IY);
#endif	

	F =buffer[21];    A  =buffer[22];

	memcpy(&SP,&buffer[23],2);

#if defined BIGENDIAN
	byteswp ((unsigned char *)&SP); 
#endif	

	border=buffer[26];
	interrupts=(buffer[19]&0x04)>>2;
	IM=buffer[25];

	io_read(fil,GiveAddrW1(16384),32768);
	io_read(fil,GiveAddrW1(49152),16384);

	pop(&PC);

	Set48kMode();
	Load48ROMs();

	io_close(fil);

	strcpy(Mode,"48");
	Set_z80times_per_line(35);

	return(no_errors);
}

void DecompressPage(unsigned char * s, unsigned short len, unsigned char *d)
{
	int is=0;
	int id=0;
	unsigned char n;
	unsigned char x;

	if (len==65535)

	{
		memcpy(d,s,16384);
		return;
	}

LB:
	if (s[is]!=0xed)
	{
		d[id]=s[is];
		is++;
		id++;
		goto LCE;
	}

	if ((s[is]==0xed)&&(s[is+1]!=0xed))
	{
		d[id]=s[is];
		is++;
		id++;
		goto LCE;
	}

	if ((s[is]==0xed)&&(s[is+1]==0xed))
	{
		n=s[is+2];
		x=s[is+3];
		memset(&d[id],x,n);
		is+=4;
		id+=n;
	}

LCE:
	if(is<len)goto LB;

	if(id!=16384)
	{
		sprintf(tstring,"DecompressPage failed !");
		TODO ("MessageBoxErr(tstring);");
	}
}


void Decompress48k(unsigned char * s, unsigned char *d)
{
	int is=0;
	int id=0;
	unsigned char n;
	unsigned char x;

LB:
	if ((s[is]==0x00) && (s[is+1]==0xed) && (s[is+2]==0xed) && (s[is+3]==0x00))
		goto LQ;

	if (s[is]!=0xed)
	{
		d[id]=s[is];
		is++;
		id++;
		goto LCE;
	}

	if ((s[is]==0xed)&&(s[is+1]!=0xed))
	{
		d[id]=s[is];
		is++;
		id++;
		goto LCE;
	}

	if ((s[is]==0xed)&&(s[is+1]==0xed))
	{
		n=s[is+2];
		x=s[is+3];
		memset(&d[id],x,n);
		is+=4;
		id+=n;
	}

LCE:
	goto LB;

LQ:
	if(id!=49152)
	{
		sprintf(tstring,"DecompressPage failed !");
		MessageBoxErr(tstring);
	}
}

void byteswp(unsigned char * arg)
{
	unsigned char tmp;


	tmp=arg[0];
	arg[0]=arg[1];
	arg[1]=tmp; 
}

int Loadz80(char * filename, char * startd = NULL, int pentagon = 0, unsigned char * Buffer=0, int Len=0)
{
	int fil;
	unsigned char buffer[200000];
	int len;

	int start=0;
	unsigned short b_len;
	unsigned char n;
	unsigned char v=0;

	unsigned char page[16384];
	unsigned char _48k[49152];
	int j;


	if (pentagon!=2)
	{
		strcpy (Mode, "Pentagon");
	}

	if (!Len)
	{
		fil=io_open(startd, filename,O_RDONLY);

		if (fil==-1)
		{
			sprintf(tstring,"Unable to open %s", filename);
			MessageBoxErr(tstring);

			return(errors);
		}

		len= (int)io_read(fil, buffer, sizeof(buffer));

		io_close(fil);
	}
	else
	{
		memcpy(buffer, Buffer, Len);
		len = Len;
	}

	A=buffer[0];
	F=buffer[1];
	C=buffer[2];
	B=buffer[3];
	L=buffer[4];
	H=buffer[5];

	*(short*)&PC=*(short*)&buffer[6];
	*(short*)&SP=*(short*)&buffer[8];

#if defined BIGENDIAN
	byteswp((unsigned char *)&PC);
	byteswp((unsigned char *)&SP);	
#endif

	I=buffer[10];
	if (buffer[12]==255)buffer[12]=1;
	border=(buffer[12]&0xe)>>1;
	E=buffer[13];
	D=buffer[14];
	C1=buffer[15];
	B1=buffer[16];
	E1=buffer[17];
	D1=buffer[18];
	L1=buffer[19];
	H1=buffer[20];
	A1=buffer[21];
	F1=buffer[22];

	*(short*)&IX=*(short*)&buffer[25];
	*(short*)&IY=*(short*)&buffer[23];

#if defined BIGENDIAN
	byteswp((unsigned char *)&IX);
	byteswp((unsigned char *)&IY);
#endif

	if (buffer[27]==0)interrupts=off; else interrupts=on;
	IM=buffer[29]&3;

	if (PC!=0)
	{

		printf(".z80 v1\n");


		MapROM1();
		Set48Screen();
		Set48kMode();
		Load48ROMs();
		Zamolchi();


		if ((buffer[12]&32)!=0)
			Decompress48k(&buffer[30],_48k);
		else

			memcpy(_48k,&buffer[30],49152);

		memcpy(&CPU12[16384],_48k,32768);
		memcpy(GiveAddrW1(49152),&_48k[32768],16384);

		goto LE;
	}
	else
	{
		if (buffer[30]==23)
		{
			v=2;
			goto LPCL;
		}

		if (buffer[30]==54)
		{
			v=3;
			goto LPCL;
		}

		if (buffer[30]==55)
		{
			v=4;
			goto LPCL;
		}


		sprintf(tstring,"Loadz80 : Unknown file format : buffer[30] value unknown.");
		MessageBoxErr(tstring);
		goto LE;


LPCL:

		*(short*)&PC=*(short*)&buffer[32];

#if defined BIGENDIAN
		byteswp((unsigned char *)&PC);
#endif

		register_latch=buffer[38];
		for (j=0; j<15; j++)
			AYio_writeRegNV(0,buffer[39+j]);


		if (v==2)
		{
			if (buffer[34]==2)buffer[34]=3;	
			if (buffer[34]>=3)buffer[34]=4;
		}

		switch (buffer[34])
		{
		case 0:
		case 1:
		case 2:
			{
				if (v==2)
				{

					printf(".z80 v2 48k\n");

					start=55;
				}

				if (v==3)
				{

					printf(".z80 v3 48k\n");

					start=86;
				}

				if (v==4)
				{

					printf(".z80 v3.X 48k\n");

					start=87;
				}

				MapROM1();
				Set48Screen();
				Set48kMode();
				Load48ROMs();
				Zamolchi();


LD48:
				*(short*)&b_len=*(short*)&buffer[start];

#if defined BIGENDIAN
				byteswp((unsigned char *) &b_len);
#endif					

				n=buffer[start+2];
				DecompressPage(&buffer[start+3], b_len, page);

				switch(n)
				{
				case 4 : memcpy(GiveAddrW1(32768),page,16384); break;
				case 5 : memcpy(GiveAddrW1(49152),page,16384);  break;

				case 8 : memcpy(GiveAddrW1(16384),page,16384); break;

				default:
					{
						sprintf(tstring,"Loadz80 : Unknown file format : page number %d unknown",n);
						MessageBoxErr(tstring);
					}
				}

				if (b_len==65535) b_len=16384;
				if((start+b_len+3)<len)
				{
					start+=(b_len+3);
					goto LD48;
				}

				break;
			}

		case 4:
		case 5:
		case 6:
			{
				Set128kMode();	

				if (pentagon!=2)
				Load128ROMs();

				Port7ffdOut(buffer[35]);
				PortbffdOut(buffer[38]);
				memcpy(Regs,&buffer[39],16);

				Zamolchi();


				if (v==2)
				{

					printf(".z80 v2 128k\n");

					start=55;
				}

				if (v==3)
				{

					printf(".z80 v3 128k\n");

					start=86;
				}

				if (v==4)
				{

					printf(".z80 v3.X 128k\n");

					start=87;
				}

LD:
				*(short*)&b_len=*(short*)&buffer[start];

#if defined BIGENDIAN
				byteswp((unsigned char *) &b_len);
#endif					

				n=buffer[start+2];
				DecompressPage(&buffer[start+3],b_len,page);

				switch(n)
				{
				case 3 : memcpy(RAM0,page,16384); break;
				case 4 : memcpy(RAM1,page,16384); break;
				case 5 : memcpy(RAM2,page,16384); break;
				case 6 : memcpy(RAM3,page,16384); break;
				case 7 : memcpy(RAM4,page,16384); break;
				case 8 : memcpy(RAM5,page,16384); break;
				case 9 : memcpy(RAM6,page,16384); break;
				case 10: memcpy(RAM7,page,16384); break;

				default:
					{
						sprintf(tstring,"Loadz80 : Unknown file format : page number %d unknown",n);
						MessageBoxErr(tstring);
					}	
				}

				if (b_len==65535) b_len=16384;
				if((start+b_len+3)<len)
				{
					start+=(b_len+3);

					goto LD;
				}

				break;
			}

		case 3 :
			{
				sprintf(tstring,"SamRam not supported.");
				MessageBoxErr(tstring);
				goto LE;
			}

		default :
			{
				sprintf(tstring,"Loadz80 : Unknown file format : unknown machine type %d",buffer[34]);
				MessageBoxErr(tstring);
				goto LE;
			}
		}

		goto LE;	
	}

LE:

	if (mode==m_128k)
	{
		if (!pentagon)
		strcpy(Mode,"128");
		if (pentagon==1)
		strcpy(Mode,"Pentagon");
		if (pentagon==2)
		strcpy(Mode,"Scorpion");
	}
	else
	{		
		strcpy(Mode,"48");		
	}
	

	Set_z80times_per_line(35);

	//Log =1;

	return(no_errors);
}

#if !defined bzero
#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
#endif

void reset_h(void)	
{
	Reset();
	tape_SetActiveAndPause(tapes);	
}

int Load128_131103_snap(char * filename, char * homedir)
{
	int fil;
	unsigned char buffer[27];

	fil=io_open(homedir, filename,O_RDONLY);

	if (fil==-1)
	{
		sprintf(tstring,"Unable to open %s", filename);
		MessageBoxErr(tstring);
		return(errors);
	}


	printf(".sna 128k\n");

	io_lseek(fil,49179,SEEK_SET);
	io_read(fil,buffer,4);


	Set128kMode();
	Load128ROMs();	

	Port7ffdOut(buffer[2]);

	memcpy(&PC,buffer,2);
#if defined BIGENDIAN
	byteswp ((unsigned char *)&PC); 
#endif	

	Zamolchi();


	io_lseek(fil,0,SEEK_SET);
	io_read(fil,buffer,27);

	I=buffer[0];
	L1=buffer[ 1];      H1=buffer[ 2];
	E1=buffer[ 3];      D1=buffer[ 4];
	C1=buffer[ 5];      B1=buffer[ 6];
	F1=buffer[ 7];      A1=buffer[ 8];
	L =buffer[ 9];      H =buffer[10];
	E =buffer[11];      D =buffer[12];
	C =buffer[13];      B =buffer[14];

	memcpy(&IY,&buffer[15],2);
	memcpy(&IX,&buffer[17],2);

#if defined BIGENDIAN
	byteswp ((unsigned char *)&IX); 
	byteswp ((unsigned char *)&IY);
#endif	

	F =buffer[21];    A  =buffer[22];

	memcpy(&SP,&buffer[23],2);

#if defined BIGENDIAN
	byteswp ((unsigned char *)&SP); 
#endif	
	border=buffer[26];
	interrupts=(buffer[19]&0x04)>>2;
	IM=buffer[25];

	io_read(fil,GiveAddrW1(16384),32768);
	io_read(fil,GiveAddrW1(49152),16384);

	io_lseek(fil,49183,SEEK_SET);

	if (new_ram!=RAM0)
		io_read(fil,RAM0,16384);

	if (new_ram!=RAM1)
		io_read(fil,RAM1,16384);

	if (new_ram!=RAM3)
		io_read(fil,RAM3,16384);

	if (new_ram!=RAM4)
		io_read(fil,RAM4,16384);

	if (new_ram!=RAM6)
		io_read(fil,RAM6,16384);

	if (new_ram!=RAM7)
		io_read(fil,RAM7,16384);

	io_close(fil);
	return(no_errors);
}



void SelectTRDFile(int num, char * arg, char * dir);
void SelectFDIFile(int num, char * arg, char * dir);
void OpenSCL(char * filename, int num, char *);

int * g_Enter (void);

void open_file(char * directory, char * filename)
{
	char ext[4];
	char extention[5]={0};


	if (strlen(filename)<5)
	{
		MessageBoxErr("Unknown file type !");
		return;
	}

	tape_stopF(0,0,0);

	sprintf(ext,"%s",&filename[strlen(filename)-3]);

	if (io_strcasecmp(ext,"sna")==0)
	{
		if (size(filename)==49179)
		{
			new_ram=RAM0;
			z80Reset();

			Load48snap(filename,  directory);
			goto LQ;
		}

		if (size(filename)==131103)
		{
			new_ram=RAM0;
			z80Reset();

			Load128_131103_snap(filename, directory);
			goto LQ;
		}

		if (size(filename)==147487)
		{
			new_ram=RAM0;
			z80Reset();

			Load128_131103_snap(filename, directory);
			goto LQ;
		}


		MessageBoxErr("Unknown .sna format !");
		return;
	}

	if (io_strcasecmp(ext, "z80")==0)
	{
		new_ram=RAM0;
		z80Reset();

		Loadz80(filename, directory);
		goto LQ;
	}

	if (io_strcasecmp(ext, "tzx")==0)
	{
		io_readTZX(filename, directory);

		Loadz80(NULL, NULL, 0, TapeLoad128, sizeof(TapeLoad128));
		goto LQ;
	}

	if (io_strcasecmp(ext, "tap")==0)
	{
		io_readTAP(filename, directory);
		Loadz80(NULL, NULL, 0, TapeLoad128, sizeof(TapeLoad128));
		goto LQ;
	}

	if (io_strcasecmp(ext, "wav")==0)
	{
		io_readWAV(filename, directory);
		tape_traps=off;
		Loadz80(NULL, NULL, 0, TapeLoad128, sizeof(TapeLoad128));
		goto LQ;
	}

	if (io_strcasecmp(ext, "trd")==0)
	{
		if (Mode[0]!='s' && Mode[0]!='S')
			SetMode("Pentagon");

		reset_h();
		
		SelectTRDFile(0, filename, directory);

		if (Mode[0]=='s' || Mode[0]=='S')
			Loadz80(NULL, NULL, 2, aaa_scorp, sizeof(aaaaa));
		else
			Loadz80(NULL, NULL, 1, aaaaa, sizeof(aaaaa));

		joystick(7, 0);

		timerfunc();

		joystick(7, 1);

		goto LQ;
	}

	if (io_strcasecmp(ext, "scl")==0)
	{
		if (Mode[0]!='s' && Mode[0]!='S')
			SetMode("Pentagon");

		OpenSCL(filename, 0, directory);

		if (Mode[0]=='s' || Mode[0]=='S')
			Loadz80(NULL, NULL, 2, aaa_scorp, sizeof(aaaaa));
		else
			Loadz80(NULL, NULL, 1, aaaaa, sizeof(aaaaa));

		joystick(7, 0);

		timerfunc();

		joystick(7, 1);

		goto LQ;
	}

	if (io_strcasecmp(ext, "fdi")==0)
	{
		if (Mode[0]!='s' && Mode[0]!='S')
			SetMode("Pentagon");

		SelectFDIFile(0, filename, directory);

		if (Mode[0]=='s' || Mode[0]=='S')
			Loadz80(NULL, NULL, 2, aaa_scorp, sizeof(aaaaa));
		else
			Loadz80(NULL, NULL, 1, aaaaa, sizeof(aaaaa));

		joystick(7, 0);

		timerfunc();

		joystick(7, 1);

		goto LQ;
	}

	MessageBoxErr("Unknown file type !");
	return;
LQ: ;
}

void toggled_mode(int widget, int which, int state)
{
	//if (which==0)
	sprintf(Mode,"48");
	//if (which==1)
	sprintf(Mode,"128");
	//if (which==2)
	sprintf(Mode,"Pentagon");
	//if (which==3)
	sprintf(Mode,"Scorpion");

	Reset();
}

void SelectTRDFile(int num, char * filename, char * dir)
{
	int fil;
	unsigned char * temp;


	char arg[2000];

	if (dir && strlen (dir))
		sprintf(arg, "%s/%s", dir, filename);
	else
		sprintf(arg, "%s", filename);

	int messagebox = 0;

	if (!io_strncasecmp(arg, "none", 4))
	{
		//printf("%s \n", arg);

		strcpy(discs[num].filename, arg);
		return;
	}

	if (!FileExists(arg))
	{
		sprintf(tstring,"%s - No such file. Creating it. (%d)", arg, num);

		if (messagebox)
			MessageBoxInfo(tstring);
		else
			printf("%s\n",tstring);


		fil=io_creat(NULL, arg);

		if(fil==-1)
		{
			strcpy(discs[num].filename,"none");

			sprintf(tstring, "Can't create %s. You must be able io_read and io_write this directory.", arg);

			if (messagebox)
				MessageBoxErr(tstring);
			else
				printf("%s\n",tstring);

			return;
		}

		temp= (unsigned char *)malloc(655360);
		bzero(temp,655360);

		io_write(fil, temp, 655360);
		free(temp);

		io_close(fil);
	}


	fil=io_open(NULL, arg, O_RDWR);

	if(fil==-1)
	{
		io_close (fil);
		fil=io_open(NULL, arg, O_RDONLY);

		if (fil==-1)
		{	
			strcpy(discs[num].filename, "none");
			sprintf(tstring,"Can't io_open %s.", arg);

			if (messagebox)
				MessageBoxErr(tstring);
			else
				printf("%s\n",tstring);

			return;
		}

		discs[num].ro=1;

		if (messagebox)
		{
			switch (num)
			{
			case 0:
				//XtVaSetValues(disk1ro,XmNset,1,NULL);
				break;
			case 1:
				//XtVaSetValues(disk2ro,XmNset,1,NULL);
				break;
			case 2:
				//XtVaSetValues(disk3ro,XmNset,1,NULL);
				break;
			case 3:
				//XtVaSetValues(disk4ro,XmNset,1,NULL);
				break;
			default: ;
				//ExitWithError(-1,"SelectTRDFile unknown value of num. This is bug. Report it.");
			}
		}

	}
	else
	{
		discs[num].ro=0;

		if (messagebox)
		{
			switch (num)
			{
			case 0:
				//XtVaSetValues(disk1ro,XmNset,0,NULL);
				break;
			case 1:
				//XtVaSetValues(disk2ro,XmNset,0,NULL);
				break;
			case 2:
				//XtVaSetValues(disk3ro,XmNset,0,NULL);
				break;
			case 3:
				//XtVaSetValues(disk4ro,XmNset,0,NULL);
				break;
			default: ;
				//ExitWithError(-1,"SelectTRDFile unknown value of num. This is bug. Report it.");
			}
		}
	}	

	strcpy(discs[num].filename,arg);

	for (int track=0; track<85; track++)
		for (int side=0; side<2; side++)
			for (int sec=0; sec<32; sec++)
				discs[num].sectors[(track*2+side)*32 + sec].present = 0;


	for (int track=0; track<80; track++)
	{
		for (int side=0; side<2; side++)
		{
			for (int sec=0; sec<16; sec++)
			{
				discs[num].sectors[(track*2+side)*32 + sec].present = 1;
				discs[num].sectors[(track*2+side)*32 + sec].size =  256;
				discs[num].sectors[(track*2+side)*32 + sec].num =  sec+1;
				discs[num].sectors[(track*2+side)*32 + sec].pos = ((track*2+side)*16 + sec) * 256;
			}
		}
	}





	io_close(fil);
}

void SelectFDIFile(int num, char * filename, char * dir)
{
	int fil;



	char arg[2000];

	if (dir && strlen (dir))
		sprintf(arg, "%s/%s", dir, filename);
	else
		sprintf(arg, "%s", filename);

	int messagebox = 0;


	fil=io_open(NULL, arg, O_RDWR);

	if(fil<0)
	{

		sprintf(tstring,"Can't io_open %s.", arg);

		if (messagebox)
			MessageBoxErr(tstring);
		else
			printf("%s\n",tstring);

		return;
	}


	strcpy(discs[num].filename,arg);

	for (int track=0; track<85; track++)
		for (int side=0; side<2; side++)
			for (int sec=0; sec<32; sec++)
				discs[num].sectors[(track*2+side)*32 + sec].present = 0;


	char wp;
	unsigned short c, h, data_offset, add_len;;

	io_lseek(fil, 0x03, SEEK_SET);
	io_read(fil, &wp, 1);
	io_read(fil, (char *)&c, 2);
	io_read(fil, (char *)&h, 2);

	io_lseek(fil, 0x0a, SEEK_SET);
	io_read(fil, (char *)&data_offset, 2);
	io_read(fil, (char *)&add_len, 2);


	if (h!=2)
	{
		MessageBoxErr("Heads!=2 is not Supported!");
		io_close(fil);
		return;
	}

	discs[num].ro = wp;


	int track_offset;
	char s;
	unsigned char nc, nh, nsec, ss;
	unsigned short sector_offset;
	unsigned short sss;

	io_lseek(fil, 0x0e + add_len, SEEK_SET);

	for (int i=0; i<c*2; i++)
	{
		io_read(fil, (char *)&track_offset, 4);
		io_lseek(fil, 2, SEEK_CUR);
		io_read(fil, &s, 1);

		//printf ("track offset = %d, nsec = %d \n", track_offset, s);

		for (int j=0; j<s; j++)
		{
			io_read(fil, &nc, 1);
			io_read(fil, &nh, 1);
			io_read(fil, &nsec, 1);
			io_read(fil, &ss, 1);
			io_lseek(fil, 1, SEEK_CUR);
			io_read(fil, (char *)&sector_offset, 2);

			if (ss==0) sss = 128;
			if (ss==1) sss = 256;
			if (ss==2) sss = 512;
			if (ss==3) sss = 1024;

			//printf ("i%d  c=%d h=%d s=%d (ss=%d) off = %d\n", i, nc, nh, nsec, sss, sector_offset);

			discs[num].sectors[i*32 + j].present = 1;
			discs[num].sectors[i*32 + j].size = sss;
			discs[num].sectors[i*32 + j].num = nsec;
			discs[num].sectors[i*32 + j].pos = sector_offset + track_offset + data_offset;
		}
	}





	io_close(fil);
}


int Boot(char * filename)
{
	int SCL;
	char signature[8];
	unsigned char blocks;
	char headers[256][14]; 


	if((SCL=io_open(NULL, filename, O_RDONLY))==-1)
	{
		printf("Can't open SCL file %s.\n", filename);
		return 0;
	}

	io_read(SCL, (char *)&signature, 8);

	if(io_strncasecmp(signature,"SINCLAIR", 8))
	{
		printf("Wrong signature=%s. \n", signature);
		io_close(SCL);
		return 0;
	}

	io_read(SCL,&blocks,1);

	for(int x=0; x<blocks;x++)
		io_read(SCL,&(headers[x][0]),14);

	for(int x=0;x<blocks;x++)
	{
		char aaa[10] = {0};
		strncpy(aaa, (char *)headers[x], 8);

		//printf("%s \n", aaa);

		if (!strncmp(aaa, "boot", 4))
		{
			io_close(SCL);
			return 1;
		}
	}

	io_close(SCL);
	return 0;
}


void Scl2Trd__Convert(char * oldname, char * newname)
{
#define TRD_NAMEOFFSET 0x08F5
#define TRD_DIRSTART 0x08E2
#define TRD_DIRLEN 32
#define TRD_MAXNAMELENGTH 8
#define BLOCKSIZE 10240

	int TRD,SCL, i;

	void *TRDh; 
	void *tmp;

	unsigned int *trd_free;  
	unsigned char *trd_fsec; 
	unsigned char *trd_ftrk; 
	unsigned char *trd_files; 
	unsigned char size;

	char signature[8];
	unsigned char blocks;
	char headers[256][14]; 
	void * tmpscl;
	unsigned long left;
	unsigned long fptr;
	int x;

	unsigned char template1[34] =	
	{ 	
		0x01,0x16,0x00,0xF0,
		0x09,0x10,0x00,0x00,
		0x20,0x20,0x20,0x20,
		0x20,0x20,0x20,0x20,
		0x20,0x00,0x00,0x64,
		0x69,0x73,0x6B,0x6E,
		0x61,0x6D,0x65,0x00,
		0x00,0x00,0x46,0x55
	};

	int fh;
	unsigned char *mem;


	if (Boot(oldname))
	{
LB:

		fh = io_open(NULL, newname, O_WRONLY);

		if (fh!=-1)
		{
			mem = (unsigned char *) malloc(BLOCKSIZE);		
			memset(mem,0,BLOCKSIZE);

			if (mem)
			{
				memcpy(&mem[TRD_DIRSTART],template1,TRD_DIRLEN);
				strncpy((char *)&mem[TRD_NAMEOFFSET], "Glukalka" ,TRD_MAXNAMELENGTH);
				io_write(fh, mem, BLOCKSIZE);
				memset(mem,0,BLOCKSIZE);

				for(i=0;i<63;i++)
					io_write(fh, mem, BLOCKSIZE);

				free(mem);		
				io_close(fh);
			}
		}	
		else
		{
			MessageBoxErr(newname);
			return;
		}
	}
	else
	{

		char buffer[655360];

		memcpy (buffer, disk048, 655360);

		int
			fil = io_open(NULL, newname, O_WRONLY);

		if (fil==-1)
		{
			MessageBoxErr(newname);
			goto LB;
		}

		io_write(fil, buffer, 655360);

		io_close(fil);
	}

	if( (TRD=io_open(NULL, newname, O_RDWR))== -1 )
	{
		printf("Error - cannot open TRD disk image %s !\n", newname);
		return;
	}

	TRDh=malloc(4096);
	io_read(TRD, (char *)TRDh, 4096);

	tmp=(char*) TRDh+0x8E5; trd_free=(unsigned int*) tmp;
	trd_files=(unsigned char*) TRDh+0x8E4;
	trd_fsec=(unsigned char*) TRDh+0x8E1;
	trd_ftrk=(unsigned char*) TRDh+0x8E2;

	if((SCL=io_open(NULL, oldname,O_RDONLY))==-1)
	{
		printf("Can't io_open SCL file %s.\n", oldname);
		io_close(TRD); io_close(SCL);
		return;
	}

	io_read(SCL, (char *)&signature, 8);

	if(io_strncasecmp(signature,"SINCLAIR", 8))
	{
		printf("Wrong signature=%s. \n", signature);
		io_close(TRD); io_close(SCL);
		return;
	}

	io_read(SCL,&blocks,1);

	for(x=0;x<blocks;x++)
		io_read(SCL,&(headers[x][0]),14);

	for(x=0;x<blocks;x++)
	{
		size=headers[x][13];
		if( *trd_free < size )
		{
			printf("file is too long to fit in the image *trd_free=%d < size=%d\n", *trd_free, size);
			io_close(SCL);
			goto Finish;
		}

		if( *trd_files >127)
		{
			printf("image is full\n");
			io_close(SCL);
			goto Finish;
		}

		memcpy( (void*) ((char*) TRDh + *trd_files*16),
			(void*) headers[x], 14);

		memcpy( (void*) ((char*) TRDh + *trd_files*16+0x0E),
			(void*) trd_fsec, 2);

		tmpscl = malloc(32000);

		left = (unsigned long) ((unsigned char)headers[x][13])*256L;
		fptr = (*trd_ftrk)*4096L + (*trd_fsec)*256L;
		io_lseek(TRD,fptr,SEEK_SET);

		while(left>32000)
		{
			io_read(SCL, (char *)tmpscl, 32000);
			io_write(TRD, (unsigned char *)tmpscl, 32000);
			left-=32000;
		}

		io_read(SCL, (char *)tmpscl,left);
		io_write(TRD, (unsigned char *)tmpscl,left);

		free(tmpscl);

		(*trd_files)++;

		(*trd_free)-=size;

		while(size>15) {(*trd_ftrk)++;size-=16;}

		(*trd_fsec)+=size;
		while((*trd_fsec)>15) {(*trd_fsec)-=16; (*trd_ftrk)++;}
	}

	io_close(SCL);


Finish:

	io_lseek(TRD,0L,SEEK_SET); 
	io_write(TRD, (unsigned char *)TRDh, 4096); 
	io_close(TRD);
	free(TRDh);
}

void OpenSCL(char * filename, int num, char * dir)
{
	int fil;
	char filenameNEW[1251];
	char filenameOLD[1251];


	if (dir && strlen (dir))
		sprintf(filenameNEW, "%s/%s", dir, filename);
	else
		sprintf(filenameNEW, "%s", filename);

	if (dir && strlen (dir))
		sprintf(filenameOLD, "%s/%s", dir, filename);
	else
		sprintf(filenameOLD, "%s", filename);

	strcat(filenameNEW, ".trd");

	if (FileExists(filenameNEW))
		SelectTRDFile(num, filenameNEW, "");
	else
	{
		fil=io_creat(NULL, filenameNEW);

		if (fil==-1) 
		{
			MessageBoxErr(filenameNEW);
			return;
		}

		io_close(fil);

		Scl2Trd__Convert(filenameOLD, filenameNEW);

		SelectTRDFile(num, filenameNEW, "");
	}
}


void disk_setio_readOnly(int w, int n, int state)
{
	int fil;


	if (!strcmp(discs[n].filename, "none"))
		return;

	if (!FileExists(discs[n].filename))
		return;

	//	if (state->set)
	{
		discs[n].ro=1;
		return;
	}

	fil=io_open("", discs[n].filename, O_RDONLY);

	if (fil<0)
	{
		MessageBoxErr("io_write protection.");
		//XtVaSetValues(w,XmNset,1,NULL);
		return;
	}

	io_close(fil);
	discs[n].ro=0;
}


void disk_Eject(int w, int n, int cbs)
{
	strcpy(discs[n].filename, "none");

	//XmTextSetString(dan,discs[0].filename);
	//XmTextSetString(dbn,discs[1].filename);
	//XmTextSetString(dcn,discs[2].filename);
	//XmTextSetString(ddn,discs[3].filename);
}


void SaveZ80(char * path, char * dir)
{
	int fil;	
	char message[400];
	int start;
	unsigned short b_len=65535;

	unsigned char buffer[200000]={0};

	fil=io_creat(dir, path);

	//printf("SaveZ80 fil = %d\n", fil);

	if (fil==-1)
	{
		sprintf(message,"Error creating %s", path);
		MessageBoxErr(message);
		return;
	}

	buffer[0]=A;
	buffer[1]=F;
	buffer[2]=C;
	buffer[3]=B;
	buffer[4]=L;

	buffer[5]=H;
	memset(&buffer[6],0,2);
	memcpy(&buffer[8],&SP,2);

#if defined BIGENDIAN
	byteswp (&buffer[8]);
#endif

	buffer[10]=I;

	buffer[13]=E;
	buffer[14]=D;
	buffer[15]=C1;
	buffer[16]=B1;
	buffer[17]=E1;
	buffer[18]=D1;
	buffer[19]=L1;
	buffer[20]=H1;
	buffer[21]=A1;
	buffer[22]=F1;

	memcpy(&buffer[25],&IX,2);
	memcpy(&buffer[23],&IY,2);


#if defined BIGENDIAN
	byteswp (&buffer[23]);
	byteswp (&buffer[25]);
#endif

	buffer[27]=interrupts;
	buffer[29]=IM;
	buffer[12]=border*2;

	buffer[30]=54;
	memcpy(&buffer[32], &PC, 2);

#if defined BIGENDIAN
	byteswp (&buffer[32]);
#endif

	buffer[38]=register_latch;
	memcpy(&buffer[39],Regs,15);

	start=86;

	if ((!io_strcasecmp(Mode,"128"))||(!io_strcasecmp(Mode,"Pentagon"))||(!io_strcasecmp(Mode,"Scorpion")))
	{	
		buffer[34]=4;
		buffer[35]=last7ffdout;

		memcpy(&buffer[start],&b_len,2);
		buffer[start+2]=3;
		memcpy(&buffer[start+3],RAM0,16384);
		start+=16387;

		memcpy(&buffer[start],&b_len,2);
		buffer[start+2]=4;
		memcpy(&buffer[start+3],RAM1,16384);
		start+=16387;

		memcpy(&buffer[start],&b_len,2);
		buffer[start+2]=5;
		memcpy(&buffer[start+3],RAM2,16384);
		start+=16387;

		memcpy(&buffer[start],&b_len,2);

		buffer[start+2]=6;
		memcpy(&buffer[start+3],RAM3,16384);
		start+=16387;


		memcpy(&buffer[start],&b_len,2);
		buffer[start+2]=7;

		memcpy(&buffer[start+3],RAM4,16384);
		start+=16387;

		memcpy(&buffer[start],&b_len,2);
		buffer[start+2]=8;
		memcpy(&buffer[start+3],RAM5,16384);
		start+=16387;

		memcpy(&buffer[start],&b_len,2);
		buffer[start+2]=9;
		memcpy(&buffer[start+3],RAM6,16384);
		start+=16387;

		memcpy(&buffer[start],&b_len,2);
		buffer[start+2]=10;
		memcpy(&buffer[start+3],RAM7,16384);
		start+=16387;
	}

	if (!io_strcasecmp(Mode,"48"))
	{	
		memcpy(&buffer[start],&b_len,2);
		buffer[start+2]=4;
		memcpy(&buffer[start+3],&CPU12[32768],16384);
		start+=16387;

		memcpy(&buffer[start],&b_len,2);
		buffer[start+2]=5;
		memcpy(&buffer[start+3],GiveAddrW1(49152),16384);
		start+=16387;

		memcpy(&buffer[start],&b_len,2);
		buffer[start+2]=8;
		memcpy(&buffer[start+3],&CPU12[16384],16384);
		start+=16387;
	}

	io_write(fil, buffer, start);
	io_close(fil);
}

void GetWH(int * x, int * y)
{
	*x=screen_w;
	*y=screen_h;
}

void LoadDefaults(void)
{
	screen_w=640;
	screen_h=480;

	sprintf(start_directory, "%s", homedir1);
	sprintf(Mode,"Pentagon");
	sprintf(joystick_type, "cursor");
	sprintf(joystick2_type, "kempston");

	sprintf(discs[0].filename, "none");
	sprintf(discs[1].filename, "none");
	sprintf(discs[2].filename, "none");
	sprintf(discs[3].filename, "none");
	beeper_volume=12;

#if defined LINUX
	sprintf(audio_name, "/dev/dsp");
#endif

#if defined SOLARIS
	sprintf(audio_name, "/dev/audio");
#endif

#if defined WIN32
	sprintf(audio_name, "-1");
#endif

	emulator_speed=100;
	sprintf(stereo_mode_string,"ABC");
	kempston_mouse= off;
	leds_global=on;
	scan=off;
	tape_traps=on;

	joy_type = 2;
}

void PixmapsAllocAndFill(void)
{
}

int * GetJ2();

void SaveIniFile(void)
{
	char string[300];
	int fil;

	//printf("saving %s %s\n", homedir, inifilepath);

	fil=io_creat(homedir1,  inifilepath);

	if (fil==-1)
	{
		printf("Error creating configuration file\n");
		return;
	}

	/*********** Zagolovok   ***********/
	sprintf(string,"%s\n\n",ini_file_version_string);
	io_write(fil, (unsigned char *)string, strlen(string));

	sprintf(string,"%s\n\n","; Do not modify first and last strings !\n; Parameters Disk1_FileName - Disk4_FileName, Tape_FileName, Quick_Snapshot_Name requires FULL path\n; You can use word 'none' if no file needed\n");
	io_write(fil, (unsigned char *)string,strlen(string));


	/************** Puti *********/
	sprintf(string,"#Paths\n");
	io_write(fil, (unsigned char *)string,strlen(string));

	sprintf(string,"Snapshots_path %s\n",start_directory);
	io_write(fil, (unsigned char *)string,strlen(string));


	sprintf(string,"\n");
	io_write(fil, (unsigned char *)string,strlen(string));


	/**************** Faili ******************/
	sprintf(string,"#Files\n");
	io_write(fil, (unsigned char *)string,strlen(string));

	sprintf(string,"Disk1_FileName %s\n",discs[0].filename);
	io_write(fil, (unsigned char *)string,strlen(string));

	sprintf(string,"Disk2_FileName %s\n",discs[1].filename);
	io_write(fil, (unsigned char *)string,strlen(string));

	sprintf(string,"Disk3_FileName %s\n",discs[2].filename);
	io_write(fil, (unsigned char *)string,strlen(string));

	sprintf(string,"Disk4_FileName %s\n",discs[3].filename);
	io_write(fil, (unsigned char *)string,strlen(string));

	sprintf(string,"\n");
	io_write(fil, (unsigned char *)string,strlen(string));


	/********************* HW  ************************/
	sprintf(string,"#Hardware\n");
	io_write(fil, (unsigned char *)string,strlen(string));

	sprintf(string,"Mode %s //48, 128, Pentagon, Scorpion \n",Mode);
	io_write(fil, (unsigned char *)string,strlen(string));

	if (joy_type==0)
		sprintf (joystick_type, "Kempston");
	if (joy_type==1)
		sprintf (joystick_type, "Sinclair");
	if (joy_type==2)
		sprintf (joystick_type, "Cursor");
	if (joy_type==3)
		sprintf (joystick_type, "OPQA");

# if !defined ANDROID
	if (* GetJ2()==0)
		sprintf (joystick2_type, "Kempston");
	if (* GetJ2()==1)
		sprintf (joystick2_type, "Sinclair");
	if (* GetJ2()==2)
		sprintf (joystick2_type, "Cursor");
#endif


	sprintf(string,"Joystick_Type %s // sinclair, kempston, cursor \n", joystick_type);
	io_write(fil, (unsigned char *)string,strlen(string));

	//printf("%s\n", string);

	sprintf(string,"Joystick2_Type %s // sinclair, kempston, cursor \n", joystick2_type);
	io_write(fil, (unsigned char *)string,strlen(string));

	sprintf(string,"Kempston_Mouse %d // 1=on, 0=off \n",kempston_mouse);
	io_write(fil, (unsigned char *)string,strlen(string));

	sprintf(string,"\n");
	io_write(fil, (unsigned char *)string,strlen(string));


	/********************** Video  ****************************/
	sprintf(string,"#Screen\n");
	io_write(fil, (unsigned char *)string,strlen(string));

	sprintf(string,"Scan %d // 1=on, 0=off \n",scan);
	io_write(fil, (unsigned char *)string,strlen(string));


# if !defined ANDROID
	sprintf(string,"Filtering %d // 1=on, 0=off \n", *GetSP());
	io_write(fil,string,strlen(string));

	sprintf(string,"OpenGL %d // 1=on, 0=off \n", *Get_opengl());
	io_write(fil,string,strlen(string));

	sprintf(string,"Keep_aspect %d // 1=on, 0=off \n", *Get_aspect());
	io_write(fil,string,strlen(string));

	sprintf(string,"5FPS %d // 1=on, 0=off \n",  *Get_slow());
	io_write(fil,string,strlen(string));
#endif


	sprintf(string,"Dimension_x %d  \n", screen_w);
	io_write(fil, (unsigned char *)string, strlen(string));

	sprintf(string,"Dimension_y %d  \n", screen_h);
	io_write(fil, (unsigned char *)string,strlen(string));


	sprintf(string,"\n");
	io_write(fil, (unsigned char *)string,strlen(string));


	/************************ Sound  **************************/
	sprintf(string,"#Sound\n");
	io_write(fil, (unsigned char *)string,strlen(string));

	if (stereo_mode == 0)
		strcpy(stereo_mode_string, "ACB")
		;

	if (stereo_mode == 1)
		strcpy(stereo_mode_string, "ABC")
		;

	if (stereo_mode == 2)
		strcpy(stereo_mode_string, "MONO")
		;


	sprintf(string,"Stereo_Mode %s // ACB, ABC, MONO \n", stereo_mode_string);
	io_write(fil, (unsigned char *)string,strlen(string));

	sprintf(string,"Beeper_Volume %d // 0-15 \n",beeper_volume);
	io_write(fil, (unsigned char *)string,strlen(string));

# if !defined ANDROID
	sprintf(string,"Audio_system %s\n", * Get_ss());
	io_write(fil, (unsigned char *)string, strlen(string));
#endif

	sprintf(string,"Sound_Device %s\n",audio_name);
	io_write(fil, (unsigned char *)string,strlen(string));

	sprintf(string,"\n");
	io_write(fil, (unsigned char *)string,strlen(string));


	/********************* kucha *********************/
	sprintf(string,"#Emulation\n");
	io_write(fil, (unsigned char *)string,strlen(string));

	sprintf(string,"Tape_traps %d // 1=on, 0=off \n", tape_traps);
	io_write(fil, (unsigned char *)string,strlen(string));

# if !defined ANDROID
	//sprintf(string,"Fast_tape %d \n", *Get_fast_tape());
	//io_write(fil,string,strlen(string));
#endif


	sprintf(string,"\n");
	io_write(fil, (unsigned char *)string,strlen(string));


	/******************* Interface *******************************/
	sprintf(string,"#Interface\n");
	io_write(fil, (unsigned char *)string,strlen(string));

	sprintf(string,"Leds %d // 1=on, 0=off \n",leds_global);
	io_write(fil, (unsigned char *)string,strlen(string));

	sprintf(string,"\n");
	io_write(fil, (unsigned char *)string,strlen(string));


	/***************** End  *****************/
	sprintf(string,"\nEnd of .glukalka file\n");
	io_write(fil, (unsigned char *)string,strlen(string));

	io_close(fil);
}

int CheckIniFile(void)
{
	int fil;
	char record[300];


	fil = io_open(homedir1, inifilepath, O_RDONLY);
	io_fgets(fil, record, 300);
	io_close(fil);

	record[strlen(record)-1]=0;

	if (strcmp(record, ini_file_version_string)==0)
		return(no_errors);
	else	
		return(errors);
}

int NeedIgnore(char * arg)
{
	if ( (arg[0]=='#')||(arg[0]==';')||(arg[0]=='/')||(arg[0]=='.')||(arg[0]==' ')||(arg[0]=='\n') )
		return(1);

	if (strlen(arg)==0)
		return(1);

	return(0);
}

void io_readLine(char * line)
{
	char parameter[100];
	char * value; 

	for (unsigned int i=0; i<strlen(line); i++)
		if ((line[i]=='\r') || (line[i]=='\n'))
			line[i]=0;

	sscanf(line, "%s", parameter);
	value = &line[strlen(parameter) +1];

	//printf("%s %d\n", parameter, value);

	if (io_strcasecmp(parameter,"glukalka")==0)
	{
		return;
	}

	if (io_strcasecmp(parameter,"Snapshots_path")==0)
	{
		strcpy(start_directory,value);
		return;
	}


	if (io_strcasecmp(parameter,"Disk1_FileName")==0)
	{
		strcpy(discs[0].filename,value);
		return;
	}

	if (io_strcasecmp(parameter,"Disk2_FileName")==0)
	{
		strcpy(discs[1].filename,value);
		return;
	}

	if (io_strcasecmp(parameter,"Disk3_FileName")==0)
	{
		strcpy(discs[2].filename,value);
		return;
	}

	if (io_strcasecmp(parameter,"Disk4_FileName")==0)
	{
		strcpy(discs[3].filename,value);
		return;
	}

	if (io_strcasecmp(parameter,"Sound_Device")==0)
	{
		strcpy(audio_name,value);
		return;
	}

	if (io_strcasecmp(parameter,"Kempston_Mouse")==0)
	{
		sscanf(value ,"%d", &kempston_mouse);
		return;
	}

	if (io_strcasecmp(parameter,"Dimension_x")==0)
	{
		sscanf(value,"%d", &screen_w);
		return;
	}

	if (io_strcasecmp(parameter,"Dimension_y")==0)
	{
		sscanf(value,"%d",&screen_h);
		return;
	}

	if (io_strcasecmp(parameter,"Tape_traps")==0)
	{
		sscanf(value,"%d",&tape_traps);
		return;
	}

	if (io_strcasecmp(parameter,"Leds")==0)
	{
		sscanf(value,"%d",&leds_global);
		return;
	}

	if (io_strcasecmp(parameter,"Scan")==0)
	{
		sscanf(value, "%d", &scan);		
		return;
	}

	if (io_strcasecmp(parameter,"Beeper_Volume")==0)
	{
		sscanf(value,"%d", (int*) &beeper_volume);
		return;
	}

# if !defined ANDROID
	if (io_strcasecmp(parameter,"Filtering")==0)
	{
		sscanf(value,"%d", GetSP());
		return;
	}

	if (io_strcasecmp(parameter,"OpenGL")==0)
	{
		sscanf(value,"%d", Get_opengl());
		return;
	}

	if (io_strcasecmp(parameter,"Keep_aspect")==0)
	{
		sscanf(value,"%d", Get_aspect());
		return;
	}

	if (io_strcasecmp(parameter,"5FPS")==0)
	{
		sscanf(value,"%d", Get_slow());
		return;
	}

	if (io_strcasecmp(parameter,"Fast_tape")==0)
	{
		//sscanf(value,"%d", Get_fast_tape());
		return;
	}

	if (io_strcasecmp(parameter,"Audio_system")==0)
	{
		SetSS(value);
		return;
	}
# endif

	if (io_strcasecmp(parameter,"Stereo_Mode")==0)
	{
		sscanf(value, "%s", stereo_mode_string);
		return;
	}

	if (io_strcasecmp(parameter,"Joystick_Type")==0)
	{
		sscanf(value,"%s",joystick_type);
		//printf("joystick_type = %s", joystick_type);
		return;
	}

	if (io_strcasecmp(parameter,"Joystick2_Type")==0)
	{
		sscanf(value,"%s", joystick2_type);
		return;
	}

	if (io_strcasecmp(parameter,"Mode")==0)
	{
		sscanf(value,"%s",Mode);
		return;
	}



	if (strcmp(parameter,"End")==0)
	{
		return;
	}

	printf("Unknown parameter %s in configuration file. Ignoring it.\n",parameter);
}



void io_readSettingsFromConfiguratonFile(void)
{
	int fil;
	char record[300];



	fil = io_open(homedir1, inifilepath, O_RDONLY);



	if (fil<0)
	{	
		printf ("Error opening Configuraton File \n");
		return;
	}

LB:
	if (io_feof(fil)!=0) goto LE;

	io_fgets(fil, record, 300);

	if (NeedIgnore(record)==1)
	{
		goto LB;
	}

	io_readLine(record);

	goto LB;

LE :
	io_close(fil);
}


void LookForIniFileEx (void)
{
	//	struct passwd * userinfo;
	int fil;

	sprintf(inifilepath, "%s", "");

#if defined WIN32
	strcat(inifilepath,"glukalka.ini");
#else
	strcat(inifilepath,".glukalka");
#endif

	fil = io_open(homedir1, inifilepath, O_RDONLY);

	if (fil != -1)
	{
		io_close(fil);

		if (CheckIniFile()==errors)
		{
			printf("Emulator's configuration file is old or invalid. Emulator will try to convert it.\nIf this fails, delete emulator's configuration file and restart the emulator.\n");
			io_readSettingsFromConfiguratonFile();
			SaveIniFile();
		}
		else
			io_readSettingsFromConfiguratonFile();
	}
	else
	{
		printf("No configuration file. Creating it.\n");
		SaveIniFile();
	}
}

void Set_z80times_per_line(unsigned int arg)
{
	if (io_strcasecmp(Mode,"128")==0)
	{
		NT_T_UP=(39*228)*arg/35;
		NT_T_LP=(8)*arg/35;
		NT_T_RP=(60)*arg/35;
		NT_T_DP=(32*228)*arg/35;
		NT_T_INT_LEN=70908*arg/35;
	}

	if (io_strcasecmp(Mode,"48")==0)
	{
		NT_T_UP=(40*224)*arg/35;
		NT_T_LP=(8)*arg/35;
		NT_T_RP=(56)*arg/35;
		NT_T_DP=(32*224)*arg/35;
		NT_T_INT_LEN=69888*arg/35;
	}

	if (io_strcasecmp(Mode,"Pentagon")==0)
	{
		NT_T_UP=((16+40)*224)*arg/35;
		NT_T_LP=(32+20)*arg/35;
		NT_T_RP=(12)*arg/35;
		NT_T_DP=(24*224)*arg/35;
		NT_T_INT_LEN=71680*arg/35;
	}

	if (io_strcasecmp(Mode,"Scorpion")==0)
	{
		NT_T_UP=(40*224)*arg/35;
		NT_T_LP=(40+8)*arg/35;
		NT_T_RP=(16)*arg/35;
		NT_T_DP=(32*224)*arg/35;
		NT_T_INT_LEN=69888*arg/35;
	}

	z80_spd_new=arg;	
}


void SetDisk(char * HOMEDIR, int n)
{
	char ext[4];

	sprintf(ext, "%s", &HOMEDIR[strlen(HOMEDIR) - 3]);

	if (io_strcasecmp(ext, "TRD") == 0)
	{
		SelectTRDFile(n, HOMEDIR, NULL);
	}

	if (io_strcasecmp(ext, "FDI") == 0)
	{
		SelectFDIFile(n, HOMEDIR, NULL);
	}
}

int ApplyParameters()
{
	Set_z80times_per_line(35);

	if ( (io_strcasecmp(joystick_type,"kempston")==0) || (io_strcasecmp(joystick_type,"sinclair")==0) || (io_strcasecmp(joystick_type,"cursor")==0)  || (io_strcasecmp(joystick_type,"OPQA")==0) )
	{
		if (io_strcasecmp(joystick_type,"kempston")==0) joy_type=0;
		if (io_strcasecmp(joystick_type,"sinclair")==0) joy_type=1;
		if (io_strcasecmp(joystick_type,"cursor")==0) joy_type=2;
		if (io_strcasecmp(joystick_type,"OPQA")==0) joy_type=3;
	}
	else
	{
		printf("Unknown joystick type %s ! Setting joystick type to kempston.\n",joystick_type);
		joy_type=0;
	}

	if ( (io_strcasecmp(joystick2_type,"kempston")==0) || (io_strcasecmp(joystick2_type,"sinclair")==0) || (io_strcasecmp(joystick2_type,"cursor")==0) )
	{
# if !defined ANDROID
		if (io_strcasecmp(joystick2_type,"kempston")==0) * GetJ2()=0;
		if (io_strcasecmp(joystick2_type,"sinclair")==0) * GetJ2()=1;
		if (io_strcasecmp(joystick2_type,"cursor")==0)   * GetJ2()=2;
#endif
	}

	UpdateStep = (unsigned int)(((double)STEP * (double)44100 * (double)8) / (double)1773400 * (double)2);

	if ( (io_strcasecmp(stereo_mode_string,"ACB")!=0) && (io_strcasecmp(stereo_mode_string,"ABC")!=0) && (io_strcasecmp(stereo_mode_string,"MONO")!=0) )
	{
		printf("Invalid value of parameter Stereo_Mode = %s. Setting it to ACB.\n", stereo_mode_string);
		stereo_mode=0;
	}
	else
	{
		if (io_strcasecmp(stereo_mode_string,"ACB")==0)	
			stereo_mode=0;

		if (io_strcasecmp(stereo_mode_string,"ABC")==0)	
			stereo_mode=1;

		if (io_strcasecmp(stereo_mode_string,"MONO")==0)	
			stereo_mode=2;
	}

	if ((emulator_speed<=0)||(emulator_speed>200))
	{
		printf("Wrong value = %d of parameter Emulator_Speed. Setting it to 100.\n", emulator_speed);
		emulator_speed=100;
	}

	timeout=TIMER_CONST*100/emulator_speed;	
	SetSOUND_TICKS_PER_FRAME();

	if (beeper_volume>15)
	{
		printf("Invalid value of Beeper_Volume=%d. Setting it to 12.\n",beeper_volume);
		beeper_volume=12;
	}

	SetDisk(discs[0].filename, 0);
	SetDisk(discs[1].filename, 1);
	SetDisk(discs[2].filename, 2);
	SetDisk(discs[3].filename, 3);

	if ((io_strcasecmp(Mode,"128")!=0)&&(io_strcasecmp(Mode,"48")!=0)&&(io_strcasecmp(Mode,"Pentagon")!=0)&&(io_strcasecmp(Mode,"Scorpion")!=0))
	{
		printf("Invalid value of Mode=%s. Setting it to '128'.\n",Mode);
		sprintf(Mode,"128");
	}

	/*** v kontse nado ! */
	return(Spectrum_Init());
}


void IncrementTrainersPositionValues(void)
{
	trainer_struct * t;


	t=trainers;

	if (t==NULL)
	{
		printf("IncrementTrainersPositionValues : trainers==NULL. This is bug. Report it.\n");
		return;
	}

	while (TRUE)
	{
		t->position++;

		t= (trainer_struct *) t->next;

		if (t==NULL) break;
	}
}

char * CheckBankAddrValueOld(int bank, int addr, int value, int old)
{
	if (bank<0)
		return("Invalid value of memory bank. Must be 0-8.");

	if ((addr<16384)||(addr>65535))
		return("Invalid value of address. Must be 16384-65535.");

	if ((value<0)||(value>256))
		return("Invalid poke value. Must be 0-256.");

	if ((old<0)||(old>255))
		return("Invalid poke original value. Must be 0-255.");

	switch (bank)
	{
	case 0:
	case 1:
	case 3:
	case 4:
	case 6:
	case 7:
		if (addr<49152)
			return("Improper using of memory bank and address. While bank==0,1,3,4,6,7 address must be >= 49152.");
		break;

	case 2:
		if (addr<32768)
			return("Improper using of memory bank and address. While bank==2 address must be >= 32768.");
		break;

	case 5:
		if ((addr>=32768)&&(addr<49152))
			return("Improper using of memory bank and address. While bank==5 address must be < 32768 or >= 49152.");
	}

	return(NULL);
}

void IncrementPOKEsPositionValues(POKE_type * first)
{
	POKE_type * p;

	p=first;

	if (p==NULL)
	{
		printf("NULL pointer passed to IncrementPOKEsPositionValues. This is bug. Report it.\n");
		return;
	}

	while (TRUE)
	{
		p->position++;


		p= (POKE_type *)p->next;

		if (p==NULL) break;
	}
}



POKE_type * FindPoke(POKE_type * start, int num)
{
	POKE_type * p;


	p=start;

	while (TRUE)
	{
		if (p==NULL)
		{
			printf("FindPoke failed. This is bug. Report it.\n");
			return(NULL);
		}

		if (p->position==num)
			return(p);

		p= (POKE_type *)p->next;
	}	
}

trainer_struct * FindTrainer(int num)
{
	trainer_struct * t;


	t=trainers;

	while (TRUE)
	{
		if (t==NULL)
		{
			printf("FindTrainer failed. This is bug. Report it.\n");
			return(NULL);
		}

		if (t->position==num)
			return(t);

		t= (trainer_struct *) t->next;
	}
}

void p_get(int w, int client_data, int  cbs)
{
	int bank = 0, addr=0;
	unsigned char old = 0;
	char st[10];


	/*
	bank=strtol(XmTextGetString(p_bank),NULL,0);
	addr=strtol(XmTextGetString(p_addr),NULL,0);

	if (CheckBankAddrValueOld(bank, addr, 0, 0)!=NULL)
	{
	MessageBoxErr(CheckBankAddrValueOld(bank, addr, 0, 0));
	return;
	}
	*/

	TODO ("p_get");

	switch (bank)
	{
	case 0:
		old=RAM0[addr-49152];
		break;
	case 1:
		old=RAM1[addr-49152];
		break;
	case 3:
		old=RAM3[addr-49152];

		break;
	case 4:
		old=RAM4[addr-49152];
		break;
	case 6:
		old=RAM6[addr-49152];
		break;
	case 7:
		old=RAM7[addr-49152];
		break;

	case 2:
		if (addr<49152)
			old=CPU12[addr];
		else 
			old=CPU12[addr-16384];
		break;

	case 5:
		if (addr<49152)
			old=CPU12[addr];
		else 
			old=CPU12[addr-32768];
		break;

	default:
		old=io_readByte(addr);
	}

	sprintf(st,"%d",old);
	///XmTextSetString(p_old,st);
}	




void DecrementTrainersPosition(trainer_struct * first)
{
	trainer_struct * t;


	t=first;

	if (t==NULL) return;

	while (TRUE)
	{
		t->position--;

		t= (trainer_struct *)t->next;

		if (t==NULL) break;
	}
}


void LoadPok(char * filename)
{

	FILE * fil;

	char tname[255];
	int type;
	int bank, addr, value, old;
	int i,j,tlen;


	fil=fopen(filename,"r");

	if (fil==NULL)
	{
		sprintf(tstring,"LoadPok : can't io_open %s for io_read.",filename);
		MessageBoxErr(tstring);
	}

	while (TRUE)
	{
		type=fgetc(fil);

		if ((type=='Y')||(type=='y')||(type==0x13))
		{
			fclose(fil);
			return;
		}

		if ((type=='N')||(type=='n'))
		{
			bzero(tname, sizeof(tname));
			fgets(tname,200,fil);

			for (i=0; i<sizeof(tname); i++)
				if ((tname[i]==0xa)||(tname[i]==0xd))
					tname[i]=0;

			if (strlen(tname)>30)
			{
				sprintf(tstring,"LoadPok :  Unknown file format : strlen(TRAINER_NAME)=%d. Must be <= 30", strlen(tname));
				//MessageBoxErr(tstring);
				fclose(fil);
				return;
			}

			tlen=strlen(tname);
			tlen--;

			for (j=tlen; j>=0; j--)
			{
				if (tname[j]==' ')
					tname[j]=0;
				else

					break;
			}

			TODO ("AddTrainer(tname);");

			continue;
		}

		if ((type=='M')||(type=='m')||(type=='Z')||(type=='z'))
		{
			fscanf(fil,"%d %d %d %d\n", &bank, &addr, &value, &old);

			if (CheckBankAddrValueOld(bank, addr, value, old)!=NULL)
			{
				sprintf(tstring,"LoadPok :  Unknown file format : %s",CheckBankAddrValueOld(bank, addr, value, old));
				//MessageBoxErr(tstring);
				fclose(fil);
				return;

			}

			TODO ("AddPOKE(trainers, bank, addr, value, old, 0);");

			continue;
		}

		//MessageBoxErr("LoadPok :  Unknown file format : Content of the line unknown.");
		break;
	}	

	fclose(fil);

}


void ApplyPoke1(POKE_type * p)
{
	switch (p->bank)
	{
	case 0:
		RAM0[p->addr-49152]=p->value;
		break;
	case 1:
		RAM1[p->addr-49152]=p->value;
		break;
	case 3:
		RAM3[p->addr-49152]=p->value;
		break;
	case 4:
		RAM4[p->addr-49152]=p->value;
		break;
	case 6:
		RAM6[p->addr-49152]=p->value;
		break;
	case 7:
		RAM7[p->addr-49152]=p->value;
		break;

	case 2:
		if (p->addr<49152)
			CPU12[p->addr]=p->value;
		else 
			CPU12[p->addr-16384]=p->value;
		break;

	case 5:
		if (p->addr<49152)
			CPU12[p->addr]=p->value;
		else 
			CPU12[p->addr-32768]=p->value;
		break;

	default:
		io_writeByte(p->addr,p->value);
	}
}

void RemovePoke(POKE_type * p)
{
	switch (p->bank)
	{
	case 0:
		RAM0[p->addr-49152]=p->old;
		break;
	case 1:
		RAM1[p->addr-49152]=p->old;
		break;
	case 3:
		RAM3[p->addr-49152]=p->old;
		break;
	case 4:
		RAM4[p->addr-49152]=p->old;
		break;
	case 6:
		RAM6[p->addr-49152]=p->old;
		break;
	case 7:
		RAM7[p->addr-49152]=p->old;
		break;

	case 2:
		if (p->addr<49152)
			CPU12[p->addr]=p->old;
		else 
			CPU12[p->addr-16384]=p->old;
		break;

	case 5:
		if (p->addr<49152)
			CPU12[p->addr]=p->old;
		else 
			CPU12[p->addr-32768]=p->old;
		break;

	default:
		io_writeByte(p->addr,p->old);
	}
}


void SavePok(char * filename)
{

	FILE * fil;

	trainer_struct * t;
	POKE_type * p;



	fil=fopen(filename,"w");

	if (fil==NULL)
	{
		sprintf(tstring,"Can't io_open %s for writing.", filename);
		MessageBoxErr(tstring);
		return;
	}

	t=trainers;

	if (t==NULL)
	{
		printf("SavePok : trainers==NULL. This is bug. Report it.");
		return;
	}

	while (TRUE) // prosmatrivaem traineri
	{
		if (t->POKEs==NULL)
		{
			printf("Because trainer %s contains no POKEs it can't be saved.\n",t->name);			
			goto LNT;
		}


		fprintf(fil,"N%-30s\r\n",t->name);

		p=t->POKEs;

		while (TRUE) // prosmatrivaem poki
		{
			if (p->next==NULL)
			{
				fprintf(fil,"Z%3d %5d %3d %3d\r\n",p->bank,p->addr,p->value,p->old);
				break;
			}

			fprintf(fil,"M%3d %5d %3d %3d\r\n",p->bank,p->addr,p->value,p->old);
			p= (POKE_type *)p->next;
		}


LNT:
		t= (trainer_struct *)t->next;
		if (t==NULL) 
		{
			fprintf(fil,"Y");
			break;
		}
	}

	fclose(fil);

}

void ApplyPoke(POKE_type * p, char * trainer_name)
{
	TODO ("ApplyPoke");
}

void p_apply_trainer(int w, int client_data, int cbs)

{
	int * selected[20] = {0};
	int num = 0;

	trainer_struct * t;
	POKE_type * p;

	TODO ("p_apply_trainer");

	//XmListGetSelectedPos(tdes,selected,&num);

	if (num!=1)
	{
		//MessageBoxErr("Nothing to apply. No trainer(s) selected.");
		return;
	}

	t=FindTrainer(*selected[0]);
	p=t->POKEs;

	if (p==NULL)
	{
		//MessageBoxErr("No POKEs in selected trainer. Nothing to apply.");
		return;	
	}

	while (TRUE)
	{
		ApplyPoke(p, t->name);

		p= (POKE_type *)p->next;
		if (p==NULL) break;
	}
}


POKE_type * DeletePokeFromRAM(trainer_struct * t, POKE_type * p)
{
	POKE_type * pp;
	POKE_type * rv;

	if (t->POKEs!=p) 
	{
		pp=t->POKEs;

		while (TRUE)
		{
			if (pp->next==p) break;
			pp= (POKE_type *)pp->next;

			if (pp==NULL)
			{
				MessageBoxErr("DeletePokeFromRAM : pp==NULL. This is bug. Report it.");
				return(NULL);
			}
		}

		pp->next=(POKE_type *)p->next;
		rv=(POKE_type *)p->next;
	}
	else
	{
		t->POKEs=(POKE_type *)p->next;
		rv=(POKE_type *)p->next;
	}

	free(p);
	return(rv);
}

void DecrementPokesPosition(POKE_type * first)
{
	POKE_type * p;


	p=first;

	if (p==NULL) return;

	while (TRUE)
	{
		p->position--;

		p=(POKE_type *)p->next;

		if (p==NULL) break;
	}
}

void p_get_orginal_values(int w, int  client_data, int cbs)

{
	//	int * selected[20];
	//int num;

	trainer_struct *t;
	POKE_type *p;

	int bank, addr;
	unsigned char old;


	TODO ("p_get_orginal_values");

	//XtVaGetValues(tdes, XmNitemCount, &n, NULL);

	//if (n<=0)
	{
		//MessageBoxErr("No trainer(s).");
		//return;
	}


	t=trainers;

	if (t==NULL)
	{
		//MessageBoxErr("p_get_orginal_values : t==NULL. This is bug. Report it.");
		return;
	}

	while (TRUE) /* prosmatrivaem traineri */
	{
		if (t->POKEs==NULL)
			goto LNT;

		p=t->POKEs;

		while (TRUE) /* prosmatrivaem poki */
		{
			bank=p->bank;
			addr=p->addr;

			if (CheckBankAddrValueOld(bank, addr, 0, 0)!=NULL)
			{
				//MessageBoxErr(CheckBankAddrValueOld(bank, addr, 0, 0));
				return;
			}

			switch (bank)
			{
			case 0:
				old=RAM0[addr-49152];
				break;
			case 1:
				old=RAM1[addr-49152];
				break;
			case 3:
				old=RAM3[addr-49152];
				break;
			case 4:
				old=RAM4[addr-49152];
				break;
			case 6:

				old=RAM6[addr-49152];
				break;
			case 7:
				old=RAM7[addr-49152];
				break;

			case 2:
				if (addr<49152)
					old=CPU12[addr];
				else 
					old=CPU12[addr-16384];
				break;

			case 5:
				if (addr<49152)

					old=CPU12[addr];
				else 
					old=CPU12[addr-32768];
				break;

			default:
				old=io_readByte(addr);
			}

			if(p->old!=old)
				printf("%s : POKE %d,%d : Old value chaged.\n",t->name,p->addr,p->value);

			p->old=old;


			p= (POKE_type *)p->next;
			if (p==NULL) break;
		}


LNT:
		t= (trainer_struct *)t->next;
		if (t==NULL) break;
	}

	SavePok("temp.pok");
	//ClearAllTrainers();
	LoadPok("temp.pok");
	//XmListDeleteAllItems(tdet);
	//unlink("temp.pok");
}

void p_check_orginal_values(int w, int client_data, int cbs)
{
	//int * selected[20];
	//	int num;

	trainer_struct *t;
	POKE_type *p;

	int bank, addr;
	unsigned char old;


	TODO ("p_check_orginal_values");

	//XtVaGetValues(tdes, XmNitemCount, &n, NULL);

	//if (n<=0)
	{
		//MessageBoxErr("No trainer(s).");

		//return;
	}


	t=trainers;

	if (t==NULL)
	{
		//MessageBoxErr("p_check_orginal_values : t==NULL. This is bug. Report it.");
		return;
	}

	while (TRUE) /* prosmatrivaem traineri */
	{
		if (t->POKEs==NULL)
			goto LNT;

		p=t->POKEs;

		while (TRUE) /* prosmatrivaem poki */
		{

			bank=p->bank;
			addr=p->addr;

			if (CheckBankAddrValueOld(bank, addr, 0, 0)!=NULL)
			{
				//MessageBoxErr(CheckBankAddrValueOld(bank, addr, 0, 0));

				return;
			}

			switch (bank)
			{
			case 0:
				old=RAM0[addr-49152];
				break;
			case 1:
				old=RAM1[addr-49152];
				break;
			case 3:
				old=RAM3[addr-49152];
				break;
			case 4:
				old=RAM4[addr-49152];
				break;
			case 6:
				old=RAM6[addr-49152];
				break;
			case 7:
				old=RAM7[addr-49152];
				break;

			case 2:
				if (addr<49152)
					old=CPU12[addr];
				else 
					old=CPU12[addr-16384];
				break;

			case 5:
				if (addr<49152)
					old=CPU12[addr];
				else 
					old=CPU12[addr-32768];
				break;

			default:
				old=io_readByte(addr);
			}

			if((p->old!=old)&&(p->old!=0)) /* !!! */
			{
				sprintf(tstring,"%s : POKE %d,%d - comparing failed.",t->name,p->addr,p->value);
				//MessageBoxInfo(tstring);
				return;
			}


			p= (POKE_type *)p->next;
			if (p==NULL) break;
		}


LNT:
		t= (trainer_struct *)t->next;
		if (t==NULL) break;
	}

	//MessageBoxInfo("No problems found.");
}

void FillParityTBL(void)
{
	unsigned char rp;
	unsigned char a=0;


	while(1)
	{
		rp=0;

		if (a&1) rp++;
		if (a&2) rp++;
		if (a&4) rp++;
		if (a&8) rp++;
		if (a&16) rp++;
		if (a&32) rp++;
		if (a&64) rp++;
		if (a&128) rp++;

		switch(rp)
		{
		case 0:
			ParityTBL[a]=1;
			break;
		case 1:
			ParityTBL[a]=0;
			break;
		case 2:
			ParityTBL[a]=1;
			break;
		case 3:
			ParityTBL[a]=0;
			break;
		case 4:
			ParityTBL[a]=1;
			break;
		case 5:
			ParityTBL[a]=0;
			break;
		case 6:
			ParityTBL[a]=1;
			break;
		case 7:
			ParityTBL[a]=0;
			break;
		case 8:
			ParityTBL[a]=1;
			break;
		}

		/* printf("%d \n", ParityTBL[a]); */

		if (a!=255)a++; 
		else break;
	}
}

void DumpAudioBegin(void)
{
	unsigned int temp=0;
	unsigned short temp16=0;


	sound_fil=io_creat(NULL, filenameT);

	if (sound_fil==-1)
	{
		sprintf(tstring, "DumpAudioBegin : can't io_create %s", filenameT);
		MessageBoxErr(tstring);
		return;
	}

	io_write(sound_fil,"RIFF",4);
	io_write(sound_fil, (char *)&temp,4);
	io_write(sound_fil,"WAVEfmt ",8);
	temp=0x10;
	io_write(sound_fil, (char *)&temp,4);
	temp16=2;
	io_write(sound_fil, (char *)&temp16,2);
	io_write(sound_fil, (char *)&temp16,2);
	temp=44100;
	io_write(sound_fil, (char *)&temp,4);
	io_write(sound_fil, (char *)&temp,4);
	io_write(sound_fil, (char *)&temp16,2);
	temp16=16;
	io_write(sound_fil, (char *)&temp16,2);
	io_write(sound_fil, "data",4);
	io_write(sound_fil, (char *)&temp,4);

	strcpy(DumpAudioFileName, filenameT);
	//XtManageChild(show_dump_s);
	TODO ("NajatKnopku(DumpAudioButton, True);");
}


int tape_NarisuiGromkostIEsliSlishkomTihoVerniErrors(unsigned char * array, int len)
{
# define kogda_vernut_errors 30

	unsigned char min=255;
	unsigned char max=0;
	int i;


	for (i=0; i<len; i+=5)
	{
		if (min>array[i])min=array[i];
		if (max<array[i])max=array[i];
	}

	//message.data1=(void*)(int)(max-min);
	//TODO ("kill(mainpid, SIGUSR2);");

	if ((max-min)<kogda_vernut_errors)
		return(errors);

	return(no_errors);
}

void lpf(signed short * b, int len)
{
	int i;
	signed short la,lb,lc;


	la=b[0];
	lb=b[1];

	for(i=2;i<len;i++)
	{
		lc=b[i];
		b[i]=(signed short)((lb*2+la+lc)/4);
		la=lb;
		lb=lc;
	}
}

void lpf(unsigned char * b, int len)
{
	int i;
	unsigned char la,lb,lc;


	la=b[0];
	lb=b[1];

	for(i=2;i<len;i++)
	{
		lc=b[i];
		b[i]=(unsigned char)((lb*2+la+lc)/4);
		la=lb;
		lb=lc;
	}
}

void inv (unsigned char * b, int len)
{
	int i;

	for(i=0;i<len;i++)
		b[i]=255-b[i];
}


/*  tapeTool */

# define one  1
# define c_zero 0
# define syn  2
# define head 3
# define none 4

# define crc_ok        0

# define crc_failed    1


unsigned char mark;
int g,b;
BOOL test;
int howmuch;
unsigned int new_len=0;
unsigned int new_nsyn=0;
unsigned char bitcounter;
unsigned char bait;
unsigned int bytecounter;
unsigned char prevbit;
unsigned int blockcounter=0;
unsigned char tmpblock[65540];
unsigned char crc;
int good=0;
int bad=0;
BOOL enablebits;
char infobuffer[255];
char msg[100];

unsigned long c_min_len_syn=6;
unsigned long c_max_len_syn=9;
unsigned long c_min_len_zero=10;
unsigned long c_max_len_zero=16;
unsigned long c_min_len_one=17;
unsigned long c_max_len_one=25;
unsigned long c_min_len_header=26;
unsigned long c_max_len_header=33;
unsigned long c_filter=5;

/* ~tapeTool */


char * Crc_Info(void)
{
	unsigned int i;
	unsigned char a;
	char * result="Crc_Info failed. This is bug. Report it.";


	a=tmpblock[2];
	for (i=3;i<=(bytecounter);i++)
		a^=tmpblock[i];

	if(a==tmpblock[bytecounter+1])
	{
		crc=crc_ok;
		if (mark==6)
			result="";
		if (mark==5)
			result="";
		if (mark==4)
			result="Inverted";
		if (mark==1)
			result="Good block";
		if (mark==2)

			result="Good block";
		if (mark==3)
		{
			if ((howmuch&1)>0)
				sprintf(msg,"%d passes",(howmuch+1)/2);
			else
				sprintf(msg,"%d passes, inverted",howmuch/2);
			result=msg;
		}
		g++;
	}
	else
	{
		crc=crc_failed;
		b++;
		if (mark!=6)
			result="Bad block";
		else
			result="Bad CRC !";
	}
	return(result);
}

char * Info(void)
{
	char * type="<UNKNOWN>";
	unsigned int start,leng;
	unsigned char i;
	char name[11]={0};


	if ((tmpblock[2]!=0)&&(tmpblock[2]!=255))
		sprintf(infobuffer,"%s %5d %s",
		"Non-standart block",bytecounter-2,Crc_Info());
	if (tmpblock[2]==0)
	{
		if((tmpblock[3]<=3)&&((bytecounter==19)||(bytecounter==20)||(bytecounter==22)||(bytecounter==21)))
		{
			if(tmpblock[3]==0)type="BASIC";
			if((tmpblock[3]==1)||(tmpblock[3]==2))type="DATA";
			if(tmpblock[3]==3)type="CODE";
			for(i=4;i<=13;i++)
			{
				if((tmpblock[i]>=32)&&(tmpblock[i]<=126))
					name[i-4]=tmpblock[i];
				else
					name[i-4]=63;

			}
			leng=tmpblock[14]+256*tmpblock[15];
			start=tmpblock[16]+256*tmpblock[17];
			sprintf(infobuffer,"%s %s %5d %5d %s",
				name,type,start,leng,Crc_Info());
		}
		else
		{
			sprintf(infobuffer,"%s %5d %s",
				"Non-standart block",bytecounter-2,Crc_Info());
		}
	}

	if (tmpblock[2]==255)
	{
		sprintf(infobuffer,"%s %5d %s","*DATA*",
			bytecounter-2,Crc_Info());
	}

	return((char *)infobuffer);
}

void AddBlock(void)
{
	unsigned char llen,hlen;
	ROM_bl_type * newB;


	new_nsyn=0;
	if (bytecounter>=4)
	{
		bytecounter--;
		bytecounter--;
		hlen=(unsigned char)((bytecounter)/256);
		llen=(unsigned char)(bytecounter-(hlen*256));
		tmpblock[0]=llen;
		tmpblock[1]=hlen;

		Info();

		if (test==FALSE)
		{
			if (crc==crc_ok)good++;
			else bad++;


			newB= (ROM_bl_type *)malloc(sizeof(ROM_bl_type));

			newB->pause=1000;
			newB->len=bytecounter;

			message.data=newB;
			message.data2=malloc(bytecounter);
			memcpy(message.data2, &tmpblock[2], bytecounter);

			TODO ("kill(mainpid, SIGUSR1);");
		}
		else	if (crc==crc_ok)new_len+=bytecounter;
	}
	bytecounter=2;
}

void AddBait(void)
{
	if(bitcounter==128)
	{
		tmpblock[bytecounter]=bait;
		bytecounter++;
	}
	else
	{
		bitcounter=128;
	}
	bait=0;
}

void AddBit(unsigned char data)
{
	/* printf("%d\n", data); */

	if (data==one)
	{
		if(prevbit==head)
		{
			prevbit=head;
			goto LL;
		}
		else
		{
			bait=(unsigned char)(bait+bitcounter);
			if (bitcounter>1)
			{
				bitcounter=(unsigned char)(bitcounter/2);
			}
			else
			{
				bitcounter=128;
				AddBait();
			}
		}
	}
	if ((data==c_zero)||(data==syn))
	{
		if(enablebits==FALSE)
		{
			goto LE;
		}
		else
		{
			if (prevbit==head)
				goto LE;
			if (bitcounter>1)
			{
				bitcounter=(unsigned char)(bitcounter/2);
			}
			else
			{
				bitcounter=128;
				AddBait();
			}
		}
	}
	if (data==head)
	{
		new_nsyn++;
		enablebits=TRUE;
		bitcounter=128;
		bait=0;
		if(prevbit!=head)
		{
			if (new_nsyn>50)
			{
				AddBlock();
				new_nsyn=0;
			}
		}
		bytecounter=2;
	}
	if (data==none)
	{
		enablebits=FALSE;
		bitcounter=128;
		bait=0;
		if (new_nsyn>50)
			AddBlock();
		new_nsyn=0;
		bytecounter=2;
	}
LE: prevbit=data;
LL: ;
}

void WorkWithBuffer(unsigned char * buffer,unsigned long filelen)
{
	unsigned long i,prevmax,max;
	unsigned char * farray;
	unsigned char tek1,tek2,tek3,tek4,tek5,bit;


	blockcounter=0;
	good=0; bad=0;

	enablebits=FALSE;
	bitcounter=128;
	bait=0;
	bytecounter=2;
	prevbit=0;
	farray=buffer;
	tek1=farray[0];
	tek2=farray[1];
	tek3=farray[2];
	tek4=farray[3];
	prevmax=0;
	for(i=4;i<filelen;i++){
		tek5=farray[i];
		if((tek2>=tek1)&&(tek3>tek1)&&(tek3>tek2)&&(tek3>=tek4)&&(tek3>=tek5)&&(tek4>=tek5))
		{
			max=i-2;

			if ((max-prevmax)<=c_filter)goto M1;
			if (((max-prevmax)<=c_max_len_header)&&((max-prevmax)>=c_min_len_header))
			{
				bit=head;
			}
			else
				if (((max-prevmax)<=c_max_len_one)&&((max-prevmax)>=c_min_len_one))
				{
					bit=one;
				}
				else
					if (((max-prevmax)<=c_max_len_zero)&&((max-prevmax)>=c_min_len_zero))
					{
						bit=c_zero;
					}
					else
						if (((max-prevmax)<=c_max_len_syn)&&((max-prevmax)>=c_min_len_syn))
						{
							bit=syn;
						}
						else bit=none;

						AddBit(bit);
						prevmax=max;
M1:  ;
		}
		tek1=tek2;
		tek2=tek3;
		tek3=tek4;
		tek4=tek5;
	}
	AddBit(none);
}

void WorkWithBuffer2(unsigned char * buffer, unsigned long filelen)
{
	unsigned long i,prevmax,max;

	unsigned char * farray;
	unsigned char tek1,tek2,tek3,tek4,tek5,bit;


	mark=6;
	test=FALSE; 


	blockcounter=0;
	good=0; bad=0;

	enablebits=FALSE;
	bitcounter=128;
	bait=0;
	bytecounter=2;

	prevbit=0;
	farray=buffer;
	tek1=farray[0];
	tek2=farray[1];
	tek3=farray[2];
	tek4=farray[3];
	prevmax=0;
	for(i=4;i<filelen;i++){
		tek5=farray[i];
		if((tek2>=tek1)&&(tek3>tek1)&&(tek3>tek2)&&(tek3>=tek4)&&(tek3>=tek5)&&(tek4>=tek5))
		{
			max=i-2;

			if ((max-prevmax)<=c_filter)goto M1;
			if (((max-prevmax)<=(c_max_len_header-2))&&((max-prevmax)>=(c_min_len_header-2)))
			{
				bit=head;
			}
			else
				if (((max-prevmax)<=(c_max_len_one-2))&&((max-prevmax)>=(c_min_len_one-2)))
				{
					bit=one;
				}
				else
					if (((max-prevmax)<=c_max_len_zero)&&((max-prevmax)>=c_min_len_zero))
					{
						bit=c_zero;
					}
					else
						if (((max-prevmax)<=c_max_len_syn)&&((max-prevmax)>=c_min_len_syn))
						{
							bit=syn;
						}
						else bit=none;

						AddBit(bit);
						prevmax=max;
M1:  ;
		}
		tek1=tek2;
		tek2=tek3;
		tek3=tek4;
		tek4=tek5;
	}
	AddBit(none);
}

void WorkWithBuffer1(unsigned char * buffer, unsigned long filelen)
{
	int l1=0,l2=0;
	unsigned char * my_buffer;


	my_buffer=(unsigned char *)malloc(filelen);
	memcpy(my_buffer,buffer,filelen); 	

	new_len=0;
	WorkWithBuffer(my_buffer,filelen);
	l1=new_len;

	new_len=0;

	lpf(my_buffer,filelen);
	WorkWithBuffer(my_buffer,filelen);
	l2=new_len;


	if (l1!=l2){b=1;g=0;}

	free(my_buffer);
}

void RecoveryTape(int tape_RAM, unsigned char * tape_buffer)
{
	int i;
	int fpasses=2; 
	int passes=7;

	unsigned char * buffer_normal;
	unsigned char * buffer_inverted;


	buffer_normal=(unsigned char *)malloc(tape_RAM);
	buffer_inverted=(unsigned char *)malloc(tape_RAM);

	memcpy(buffer_normal,tape_buffer,tape_RAM); 	
	memcpy(buffer_inverted,tape_buffer,tape_RAM); 	
	inv(buffer_inverted,tape_RAM);


	for (i=1;i<=fpasses;i++)
	{
		lpf(buffer_normal,tape_RAM);
		lpf(buffer_inverted,tape_RAM);
	}

	mark=5;
	g=0;b=0;
	test=TRUE; 
	WorkWithBuffer1(buffer_normal,tape_RAM);
	if((g>0)&&(b==0))
	{
		test=FALSE;

		WorkWithBuffer(buffer_normal,tape_RAM);
		goto LQ;
	}

	mark=4;
	g=0;b=0;
	test=TRUE; 
	WorkWithBuffer1(buffer_inverted,tape_RAM);
	if((g>0)&&(b==0))
	{
		test=FALSE;
		WorkWithBuffer(buffer_inverted,tape_RAM);
		goto LQ;
	}

	mark=3;
	for (i=1;i<=passes*2;i++)
	{
		lpf(buffer_normal,tape_RAM);
		lpf(buffer_inverted,tape_RAM);


		g=0;b=0;
		test=TRUE;
		WorkWithBuffer1(buffer_normal,tape_RAM);

		if((g>0)&&(b==0))
		{
			howmuch=i; 
			test=FALSE;
			WorkWithBuffer(buffer_normal,tape_RAM);
			goto LQ;
		}

		i++;

		g=0;b=0;
		test=TRUE;
		WorkWithBuffer1(buffer_inverted,tape_RAM);

		if((g>0)&&(b==0))
		{
			howmuch=i; 
			test=FALSE;
			WorkWithBuffer(buffer_inverted,tape_RAM);
			goto LQ;
		}
	}

	mark=1;
	lpf(buffer_normal,tape_RAM);
	test=FALSE;
	WorkWithBuffer(buffer_normal,tape_RAM);

LQ:
	/* io_createTapFileFromBlocksArray("temp.tap"); */


	free(buffer_normal);
	free(buffer_inverted);
}

# define size_bf (8*1024*1024)
char buffer[size_bf];
int pos=0;
int io_readed;

char rec_SC_stack[16384];

#define DirectFragLen 8820
#define DirectBufLen (65536*256)

unsigned char DirectFragBuffer[DirectFragLen];
unsigned char DirectBuffer[DirectBufLen/8];
unsigned int DirectPos=0;




char DescriptionUnknown [255];
char * Description(unsigned char id)
{
	switch (id)
	{
	case 0x10: return("ROM block");
	case 0x11: return("Turbo block");
	case 0x12: return("Pure tone");
	case 0x13: return("Pulses");
	case 0x14: return("Pure data");
	case 0x15: return("Direct rec");
	case 0x20: return("Pause");
	case 0x21: return("Group");
	case 0x22: return("Group End");
	case 0x23: return("Jump");
	case 0x24: return("Loop Start");
	case 0x25: return("Loop End");
	case 0x26: return("Call Seq");
	case 0x27: return("Ret from Seq");
	case 0x30: return("Description");
	case 0x31: return("Message");
	case 0x32: return("Archive Info");
	case 0x33: return("Hardware");
	case 0x35: return("Custom Info");
	case 'Z' : return("Version");
	}

	sprintf(DescriptionUnknown,"UNKNOWN=0x%X",id);
	return (DescriptionUnknown);
}

char DetailsS[255];
char * Details(unsigned char id, unsigned int ilen, void * info, unsigned int len, unsigned char * data)
{
	ROM_bl_type * ROM;
	Pure_toneT * tone;
	Pure_dataT * pd;
	turbo_block_type * turbo;
	zxtapeT * zxtape;
	char * info1;
	unsigned short * len16;
	direct_recT * direct;
	signed short * Signed;

	char string0x12[0x12];


	bzero(DetailsS, sizeof(DetailsS));

	switch (id)
	{
	case 0x10: 
		ROM= (ROM_bl_type *)info;

		mark=6;
		bytecounter=ROM->len;
		memcpy(&tmpblock[2], data, ROM->len);
		Info();

		sprintf(tstring, " Pa=%d", ROM->pause);
		sprintf(DetailsS, "%s%s", infobuffer, tstring);

		break;
	case 0x11: 
		turbo= (turbo_block_type *)info;

		sprintf(DetailsS,"P=%d SF=%d SS=%d Z=%d O=%d PT=%d U=%d Pa=%d", 
			turbo->pilotL,	
			turbo->syncFL,
			turbo->syncSL,
			turbo->zeroL,

			turbo->oneL,
			turbo->pilot_toneL_inPulses,
			turbo->used_bits,
			turbo->pause
			);

		break;
	case 0x12: 
		tone= (Pure_toneT *)info;
		sprintf(DetailsS, "Length of pulse=%d Number of pulses=%d", tone->len, tone->n);
		break;
	case 0x13:
		sprintf(DetailsS, "Number of pulses=%d", len/2);
		break;
	case 0x14: 
		pd= (Pure_dataT *)info;
		sprintf(DetailsS,"ZERO=%d ONE=%d Used=%d Pause=%d", 
			pd->z, pd->o, pd->used,	pd->pause);
		break;
	case 0x15: 
		direct= (direct_recT *)info;		
		sprintf(DetailsS, "T_states_per_sample=%d Pause=%d Used=%d", direct->TS, direct->pause, direct->used);
		break;
	case 0x20:
		len16= (unsigned short *)info;
		sprintf(DetailsS,"Value = %d", *len16);
		break;
	case 0x21:
		memcpy(DetailsS, data, len);
		break;
	case 0x22:
		return("<MUST BE HIDDEN>");
	case 0x23: 
		Signed= (short *)info;
		sprintf(DetailsS,"Value = %d", *Signed);
		break;
	case 0x24: 
		len16= (unsigned short *)info;
		sprintf(DetailsS,"Number of repetitions = %d", *len16);
		break;
	case 0x25:
		return("");
		/* case 0x26: */
		/* case 0x27: */
	case 0x30: 
		memcpy(DetailsS, data, len);
		break;
		/* case 0x31: */
	case 0x32: 
		info1=tape_GAInfo1st(data);
		strcpy(DetailsS, info1);
		free(info1);
		break;
	case 0x33: 
		return("Hardware Type");
	case 0x35:
		bzero(string0x12, sizeof(string0x12));
		memcpy(string0x12, info, 0x10);
		sprintf(DetailsS,"%s -   <IGNORED>", string0x12);
		break;
	case 'Z' :
		zxtape= (zxtapeT *)info;
		sprintf (DetailsS, ".TZX version %d.%d", zxtape->major, zxtape->minor);
		break;

	default :
		sprintf(DetailsS,"UNKNOWN=0x%X",id);
	}

	return (DetailsS);
}

void AddTapeBlock(char * arg1, unsigned char id, unsigned int len, unsigned char * data, int ilen, void * info, int show, int position)

{
# define des_len 12
# define det_len 55

	tape_struct * temp;

	char des[des_len+1]={0};
	char det[det_len+1]={0};
	char string[255];

	tape_struct * last;


	temp= (tape_struct *)malloc(sizeof(tape_struct));
	temp->id=id;
	temp->len=len;
	temp->data1= (unsigned char *)malloc(len);
	memcpy(temp->data1, data, len);
	temp->next=NULL;
	temp->ilen=ilen;
	temp->info=malloc(ilen);
	memcpy(temp->info, info, ilen);

	strncpy(des, Description(id), des_len);

	if (!strlen(arg1))
		strncpy(det, Details(id, ilen, info, len, data), det_len);
	else
		strncpy(det, arg1, det_len);

	sprintf(string, "%d", len);

	if (show)
		last_tape_p = temp->position = position; //AddIntoTapeLB(des, string, det);
	else
		temp->position=0;

	if (tapes==NULL)
		tapes=temp;
	else
	{
		last=tapes;
		while (TRUE)
		{
			if (last->next==NULL)
			{
				last->next=temp;
				return;
			}

			last= (tape_struct *)last->next;

			if (last==NULL)
				ExitWithError(-1, "AddTapeBlock : last==NULL. This bug. Report it.");
		}
	}
}

char * tape_GAInfo(unsigned char * arg)
{
	char * rv;
	int l=1;

	char tt[255];
	char * id2s;
	unsigned char id, lt;
	unsigned char n;
	char tts[100];


	rv= (char *)malloc(0xffff);
	bzero(rv, 0xffff);

	n=arg[0];


	while (n--)
	{
		id=arg[l];
		lt=arg[++l]; 

		bzero(tt,sizeof(tt));
		strncpy(tt, (char *)&arg[++l], lt);
		strcat(tt, "\n");
		l+=lt;

		switch(id)
		{
		case 0:   id2s="Full Title : "; break;
		case 1:   id2s="Software House / Publisher : "; break;
		case 2:   id2s="Author(s) : "; break;
		case 3:   id2s="Year of Publication : "; break;
		case 4:   id2s="Language : "; break;
		case 5:   id2s="Game/Utility Type : "; break;
		case 6:   id2s="Price : "; break;
		case 7:   id2s="Protection Scheme / Loader : "; break;
		case 8:   id2s="Origin : "; break;
		case 255: id2s="Comment(s) : "; break;

		default:  
			sprintf(tts, "<UNKNOWN (%x)> : ",id); 
			id2s=tts; 
			break;
		}

		strcat(rv, id2s);
		strcat(rv, tt);
	}	

	rv[strlen(rv)-1]=0;

	return(rv);
}

char * tape_GAInfo1st(unsigned char * arg)
{
	char * rv;
	int l=1;
	char tt[255];
	char * id2s;
	unsigned char id, lt;
	unsigned char n;
	char tts[100];


	rv= (char *)malloc(300);
	bzero(rv, 300);

	n=arg[0];

	id=arg[l];
	lt=arg[++l]; 


	bzero(tt,sizeof(tt));
	strncpy(tt, (char *)&arg[++l], lt);

	switch(id)
	{
	case 0:   id2s="Full Title : "; break;
	case 1:   id2s="Software House / Publisher : "; break;
	case 2:   id2s="Author(s) : "; break;
	case 3:   id2s="Year of Publication : "; break;
	case 4:   id2s="Language : "; break;
	case 5:   id2s="Game/Utility Type : "; break;
	case 6:   id2s="Price : "; break;
	case 7:   id2s="Protection Scheme / Loader : "; break;
	case 8:   id2s="Origin : "; break;
	case 255: id2s="Comment(s) : "; break;

	default:  
		sprintf(tts, "<UNKNOWN (%x)> : ",id); 
		id2s=tts; 
		break;
	}

	strcat(rv, id2s);
	strcat(rv, tt);

	if (n>1) strcat(rv, " ...");


	return(rv);
}


int GetTapePos(tape_struct * arg)
{
	tape_struct * tape;

	tape=tapes;

	while (TRUE)
	{
		if (tape==arg) return(tape->position);
		tape= (tape_struct *)tape->next;

		if (tape==NULL)
		{
			MessageBoxErr("GetTapePos failed. This is bug. Report it.");
			return(-1);
		}
	}
}

void tape_SetActiveAndPause(tape_struct * arg)
{
	int pos;


	if (!arg) return;

	pos=GetTapePos(arg);

	//	EnsureVisibleAndSelect(pos);

	tape_next=arg;

	//DisableWidget(tape_pause);
	//DisableWidget(tape_stop);

	tape_pos=tape_len=0;
	showQTape=0;
}

char hinfo[65536*2];
char * tape_hinfo(unsigned char len, hardwareT * h)
{
	unsigned short value;
	unsigned char i=0;
	char * hardware;
	char Uhardware[255];
	char string[512];
	char * vdecode;
	char Uvdecode[255];


	bzero(hinfo, sizeof(hinfo));

	while (TRUE)
	{
		if (len==0) return(hinfo);

		value=h[i].type*256+h[i].id;

		switch (value)
		{
		case 0x0000: hardware="ZX Spectrum 16k"; break;
		case 0x0001: hardware="ZX Spectrum 48k, Plus"; break;
		case 0x0002: hardware="ZX Spectrum 48k ISSUE 1";  break;	
		case 0x0003: hardware="ZX Spectrum 128k (Sinclair)"; break;
		case 0x0004: hardware="ZX Spectrum 128k +2 (Grey case)"; break;
		case 0x0005: hardware="ZX Spectrum 128k +2A, +3"; break;
		case 0x0006: hardware="Timex Sinclair TC-2048"; break;
		case 0x0007: hardware="Timex Sinclair TS-2068"; break;
		case 0x0008: hardware="Pentagon 128"; break;
		case 0x0009: hardware="Sam Coupe"; break;
		case 0x000a: hardware="Didaktik M"; break;
		case 0x000b: hardware="Didaktik Gama"; break;
		case 0x000c: hardware="ZX-81 or TS-1000 with  1k RAM"; break;
		case 0x000d: hardware="ZX-81 or TS-1000 with 16k RAM or more"; break;
		case 0x000e: hardware="ZX Spectrum 128k, Spanish version"; break;
		case 0x000f: hardware="ZX Spectrum, Arabic version"; break;
		case 0x0010: hardware="TK 90-X"; break;

		case 0x0011: hardware="TK 95"; break;
		case 0x0012: hardware="Byte"; break;
		case 0x0013: hardware="Elwro"; break;
		case 0x0014: hardware="ZS Scorpion"; break;
		case 0x0015: hardware="Amstrad CPC 464"; break;
		case 0x0016: hardware="Amstrad CPC 664"; break;
		case 0x0017: hardware="Amstrad CPC 6128"; break;
		case 0x0018: hardware="Amstrad CPC 464+"; break;
		case 0x0019: hardware="Amstrad CPC 6128+"; break;
		case 0x001a: hardware="Jupiter ACE"; break;
		case 0x001b: hardware="Enterprise"; break;
		case 0x001c: hardware="Commodore 64"; break;
		case 0x001d: hardware="Commodore 12"; break;

		case 0x0100: hardware="Microdrive"; break;
		case 0x0101: hardware="Opus Discovery"; break;
		case 0x0102: hardware="Disciple"; break;
		case 0x0103: hardware="Plus-D"; break;
		case 0x0104: hardware="Rotronics Wafadrive"; break;
		case 0x0105: hardware="TR-DOS (BetaDisk)"; break;
		case 0x0106: hardware="Byte Drive"; break;
		case 0x0107: hardware="Watsford"; break;
		case 0x0108: hardware="FIZ"; break;
		case 0x0109: hardware="Radofin"; break;
		case 0x010a: hardware="Didaktik disk drive"; break;
		case 0x010b: hardware="BS-DOS (MB-02)"; break;
		case 0x010c: hardware="ZX Spectrum +3 disk drive"; break;
		case 0x010d: hardware="JLO (Oliger) disk interface break;";
		case 0x010e: hardware="FDD3000"; break;
		case 0x010f: hardware="Zebra disk drive"; break;
		case 0x0110: hardware="Ramex Millenia"; break;
		case 0x0111: hardware="Larken"; break;

		case 0x0200: hardware="Sam Ram"; break;
		case 0x0201: hardware="Multiface"; break;
		case 0x0202: hardware="Multiface 128k"; break;
		case 0x0203: hardware="Multiface +3"; break;
		case 0x0204: hardware="MultiPrint"; break;
		case 0x0205: hardware="MB-02 ROM/RAM expansion"; break;

		case 0x0300: hardware="Classic AY hardware (compatible with 128k ZXs)"; break;
		case 0x0301: hardware="Fuller Box AY sound hardware"; break;
		case 0x0302: hardware="Currah microSpeech"; break;
		case 0x0303: hardware="SpecDrum"; break;
		case 0x0304: hardware="AY ACB stereo (A+C=left, B+C=right); Melodik"; break;
		case 0x0305: hardware="AY ABC stereo (A+B=left, B+C=right)"; break;

		case 0x0400: hardware="Kempston Joystick"; break;
		case 0x0401: hardware="Cursor, Protek, AGF Joysticks"; break;
		case 0x0402: hardware="Sinclair 2 Left  (keys 12345) Joystick"; break;
		case 0x0403: hardware="Sinclair 1 Right (keys 67890) Joystick"; break;
		case 0x0404: hardware="Fuller Joystick"; break;


		case 0x0500: hardware="AMX mouse"; break;
		case 0x0501: hardware="Kempston mouse"; break;

		case 0x0600: hardware="Trickstick"; break;
		case 0x0601: hardware="ZX Light Gun"; break;
		case 0x0602: hardware="Zebra Graphics Tablet"; break;

		case 0x0700: hardware="ZX Interface 1 Serial Port"; break;
		case 0x0701: hardware="ZX Spectrum 128k Serial Port"; break;

		case 0x0800: hardware="Kempston S Parallel Port"; break;
		case 0x0801: hardware="Kempston E Parallel Port"; break;
		case 0x0802: hardware="ZX Spectrum 128k +2A, +3 Parallel Port"; break;
		case 0x0803: hardware="Tasman Parallel Port"; break;
		case 0x0804: hardware="DK'Tronics Parallel Port"; break;
		case 0x0805: hardware="Hilderbay Parallel Port"; break;
		case 0x0806: hardware="INES Printerface Parallel Port"; break;
		case 0x0807: hardware="ZX LPrint Interface 3 Parallel Port"; break;
		case 0x0808: hardware="MultiPrint Parallel Port"; break;
		case 0x0809: hardware="Opus Discovery Parallel Port"; break;
		case 0x080a: hardware="Standard 8255 chip with ports 31,63,95 Parallel Port"; break;

		case 0x0900: hardware="ZX Printer, Alphacom 32 & compatibles"; break;
		case 0x0901: hardware="Generic Printer"; break;
		case 0x0902: hardware="EPSON Compatible Printer"; break;

		case 0x0a00: hardware="VTX 5000 modem"; break;
		case 0x0a01: hardware="T/S 2050 or Westridge 2050 modem"; break;

		case 0x0b00: hardware="RD Digital Tracer"; break;
		case 0x0b01: hardware="DK'Tronics Light Pen"; break;
		case 0x0b02: hardware="British MicroGraph Pad"; break;

		case 0x0c00: hardware="ZX Interface 1 Network adapter"; break;

		case 0x0d00: hardware="Keypad for ZX Spectrum 128k"; break;

		case 0x0e00: hardware="Harley Systems ADC 8.2 "; break;
		case 0x0e01: hardware="Blackboard Electronics AD/DA converter"; break;

		case 0x0f00: hardware="Orme Electronics EPROM Programmer"; break;


		default :
			sprintf (Uhardware, "UNKNOWN HARDWARE : Hardware Type =%d Hardware ID =%d", h[i].type, h[i].id);
			hardware = Uhardware;
		}

		switch (h[i].value)
		{
		case 0: vdecode = "00 - The tape RUNS on this machine or with this hardware,but may or\nmay not use the hardware or special features of the machine."; break ;
		case 1: vdecode = "01 - The tape USES the hardware or special features of the machine,\nsuch as extra memory or a sound chip."; break;
		case 2: vdecode = "02 - The tape RUNS but it DOESN'T use the hardware or special\nfeatures of the machine."; break;
		case 3: vdecode = "03 - The tape DOESN'T RUN on this machine or with this hardware."; break;

		default :
			sprintf (Uvdecode, "UNKNOWN VALUE = %d", h[i].value);
			vdecode = Uvdecode;
		}

		if (len!=1)
			sprintf(string, "%s :\n%s\n-----\n", hardware, vdecode);
		else
			sprintf(string, "%s :\n%s", hardware, vdecode);

		strcat(hinfo, string);

		len--; i++;
	}
}

void FreeTape(void)
{
	tape_struct * last;
	tape_struct * f;


	if (tapes==NULL) return;

	tape_pos=tape_len=0; 
	showQTape=0;

	last=tapes;

	while (TRUE)
	{
		if (last->len) free(last->data1);
		if (last->ilen) free(last->info);

		if (last->next==NULL)
		{
			free(last);
			tapes=NULL;

			//ClearTapeLB();

			tape_paused=0;

			return;
		}

		f=last;
		last=  (tape_struct *)f->next;
		free(f);
	}
}

void ByteSWP_32(void * arg)
{
	char * a = (char *) arg;
	char t, t1;

	t = a[0];
	a[0] = a[1];
	a[1] = t;

	t = a[2];
	a[2] = a[3];
	a[3] = t;

	t=a[0];
	t1=a[1];
	a[0]=a[2];
	a[1]=a[3];
	a[2]=t;
	a[3]=t1;
}

hardwareT hardware [255];
void io_readTZX(char * filename, char * dir)
{
	int fil;
	unsigned char id;
	int io_readed;

	char message[255];
	unsigned char len8;
	unsigned short len16;

	ROM_bl_type ROMb;
	unsigned char * ainfo;
	char * ainfop;

	int show=1;

	char temp[256];

	Pure_toneT pure_tone;
	Pure_dataT pd;
	turbo_block_type turbo;
	zxtapeT zxtape;
	direct_recT direct;

	int len;

	unsigned char * data;
	signed short jv;

	unsigned int len32;
	void * ignored;


	FreeTape();



	fil=io_open(dir, filename, O_RDONLY);

	if (fil==-1)
	{
		sprintf(tstring,"io_readTZX : %s - can't io_open file", filename);
		MessageBoxErr(tstring);
		return;

	}

	tape_position = 1;

	while (TRUE)
	{
		io_readed = (int) io_read(fil, &id, 1);
		if (io_readed==0) 
		{
			io_close(fil);
			tape_type="tzx";
			sprintf(tape_filename, "%s", filename);
			tape_SetActiveAndPause(tapes);
			return;
		}

		switch (id) 
		{
		case 0x30:
			io_read(fil, &len8, 1);
			bzero(message, sizeof(message));
			io_read(fil,message, len8);
			printf("%s\n", message);
			AddTapeBlock("", id, len8, (unsigned char *)message, 0, NULL, show, tape_position++);
			break;

		case 0x10:
			io_read(fil, (char *)&ROMb.pause, 2);
			io_read(fil, (char *)&ROMb.len, 2);

#if defined BIGENDIAN
			byteswp((unsigned char *)&ROMb.pause);
			byteswp((unsigned char *)&ROMb.len);
#endif
			data= (unsigned char *)malloc(ROMb.len);
			io_read(fil, data, ROMb.len);

			AddTapeBlock("", id, ROMb.len, data, sizeof(ROMb), &ROMb, show, tape_position++);
			break;

		case 0x11:
			io_read(fil, (char *)&turbo.pilotL, 2);
			io_read(fil, (char *)&turbo.syncFL, 2);
			io_read(fil, (char *)&turbo.syncSL, 2);
			io_read(fil, (char *)&turbo.zeroL, 2);
			io_read(fil, (char *)&turbo.oneL, 2);
			io_read(fil, (char *)&turbo.pilot_toneL_inPulses, 2);
			io_read(fil, (char *)&turbo.used_bits, 1);
			io_read(fil, (char *)&turbo.pause, 2);
			io_read(fil, (char *)&turbo.l1, 1);
			io_read(fil, (char *)&turbo.l2, 1);
			io_read(fil, (char *)&turbo.l3, 1);

#if defined BIGENDIAN
			byteswp((unsigned char *)&turbo.pilotL);
			byteswp((unsigned char *)&turbo.syncFL);
			byteswp((unsigned char *)&turbo.syncSL);
			byteswp((unsigned char *)&turbo.zeroL);
			byteswp((unsigned char *)&turbo.oneL);
			byteswp((unsigned char *)&turbo.pilot_toneL_inPulses);
			byteswp((unsigned char *)&turbo.pause);
#endif

			len=turbo.l1+turbo.l2*256+turbo.l3*65536;

			data= (unsigned char *)malloc(len);
			io_read(fil, data, len);

			AddTapeBlock("", id, len, data, sizeof(turbo), &turbo, show, tape_position++);
			break;

		case 0x32:
			io_read(fil, (char *)&len16,2);

#if defined BIGENDIAN
			byteswp((unsigned char *)&len16);
#endif

			ainfo= (unsigned char *)malloc(len16);
			io_read(fil, (char *)ainfo,len16);

			ainfop=tape_GAInfo(ainfo);
			printf("%s\n\n",ainfop);

			AddTapeBlock("", id, len16, ainfo, 0, NULL, show, tape_position++);

			free (ainfop);
			break;

		case 0x21:
			io_read(fil,&len8,1);

			bzero(temp, sizeof(temp));
			io_read(fil, (char *)&temp,len8);

			AddTapeBlock("", id, len8, (unsigned char *)temp, 0, NULL, show, tape_position++);

			show=0;
			break;

		case 0x22:
			AddTapeBlock("", id, 0, NULL, 0, NULL, show, tape_position++);

			show=1;
			break;

		case 0x12:
			io_read(fil, (char *) &pure_tone, sizeof(pure_tone));

			AddTapeBlock("", id, 0, NULL, sizeof(pure_tone), &pure_tone,  show, tape_position++);
			break;

		case 0x13:
			io_read(fil,&len8,1);

			data= (unsigned char *)malloc((unsigned short)(len8*2));
			io_read(fil, data, (unsigned short)(len8*2));

			AddTapeBlock("", id, (unsigned short)(len8*2), data, 0, NULL, show, tape_position++);

			break;

		case 0x14:
			io_read(fil, (char *)&pd.z, 2);
			io_read(fil, (char *)&pd.o, 2);
			io_read(fil, (char *)&pd.used, 1);
			io_read(fil, (char *)&pd.pause, 2);
			io_read(fil, (char *)&pd.l1, 1);
			io_read(fil, (char *)&pd.l2, 1);
			io_read(fil, (char *)&pd.l3, 1);

#if defined BIGENDIAN
			byteswp((unsigned char *)&pd.z);
			byteswp((unsigned char *)&pd.o);
			byteswp((unsigned char *)&pd.pause);
#endif

			len=pd.l1+pd.l2*256+pd.l3*65536;

			data= (unsigned char *)malloc(len); 
			io_read(fil, data, len);

			AddTapeBlock("", id, len, data, sizeof(pd), &pd, show, tape_position++);
			break;

		case 0x24:
			io_read(fil, (char *)&len16, 2);

#if defined BIGENDIAN
			byteswp((unsigned char *)&len16);
#endif

			AddTapeBlock("", id, 0, NULL, 2, &len16, show, tape_position++);
			break;

		case 0x25:
			AddTapeBlock("", id, 0, NULL, 0, NULL, show, tape_position++);
			break;

		case 0x20:
			io_read(fil, (char *)&len16, 2);

#if defined BIGENDIAN
			byteswp((unsigned char *)&len16);
#endif
			AddTapeBlock("", id, 0, NULL, 2, &len16, show, tape_position++);
			break;

		case 0x23:
			io_read(fil, (char *)&jv, 2);

#if defined BIGENDIAN
			byteswp((unsigned char *)&jv);
#endif
			AddTapeBlock("", id, 0, NULL, 2, &jv, show, tape_position++);
			break;

		case 0x35:
			bzero(temp, sizeof(temp));
			io_read(fil, (char *)temp, 0x10);
			io_read(fil, (char *)&len32,  4);

#if defined BIGENDIAN
			ByteSWP_32(&len32);
#endif

			ignored=malloc(len32);

			io_read(fil, (char *)ignored, len32);

			AddTapeBlock("", id, len32, (unsigned char *)ignored, 0x10, temp,  show, tape_position++);
			break;

		case 0x33:
			io_read(fil, (char *)&len8, 1);
			io_read(fil, (char *)hardware, len8*3);

			ainfo= (unsigned char *)tape_hinfo(len8, hardware);
			printf("%s\n\n",ainfo);

			AddTapeBlock("", id, len8*3, (unsigned char *)(void *)hardware, 0, NULL, show, tape_position++);
			break;

		case 'Z':
			io_lseek(fil,7,SEEK_CUR);
			io_read(fil, (char *)&zxtape, 2);

			sprintf (tstring, ".TZX version %d.%d", zxtape.major, zxtape.minor);
			printf("%s\n", tstring);

			AddTapeBlock("", id, 0, NULL, 2, &zxtape, show, tape_position++);
			break;

		case 0x15:
			io_read(fil, (unsigned char *)&direct.TS, 2);
			io_read(fil, (unsigned char *)&direct.pause, 2);
			io_read(fil, (unsigned char *)&direct.used, 1);
			io_read(fil, (unsigned char *)&direct.l1, 1);
			io_read(fil, (unsigned char *)&direct.l2, 1);
			io_read(fil, (unsigned char *)&direct.l3, 1);

#if defined BIGENDIAN
			byteswp((unsigned char *)&direct.TS);
			byteswp((unsigned char *)&direct.pause);
#endif

			len=direct.l1+direct.l2*256+direct.l3*65536;

			data=(unsigned char *)malloc(len);
			io_read(fil, data, len);

			if ((direct.TS!=158)&&(direct.TS!=79))
			{
				sprintf(tstring,"Number of T states per sample = %d unsupported. Supported values are 158 and 79.", direct.TS);
				TODO ("MessageBoxErr(tstring)");
			}
			else
				AddTapeBlock("", id, len, data, sizeof(direct), &direct, show, tape_position++);

			break;

		default : 
			sprintf(tstring,"io_readTZX : unknown block ID=#%X", id);
			MessageBoxErr(tstring);
			return;
		}
	}
}

void io_readTAP(char * filename, char * dir)
{
	unsigned short len;
	ROM_bl_type rom;
	unsigned int io_readed;
	unsigned char data[65536];

	int fil;


	FreeTape();

	fil=io_open(dir, filename, O_RDONLY);

	if (fil==-1)
	{
		sprintf(tstring,"io_readTAP : %s - can't io_open file", filename);
		MessageBoxErr(tstring);
		return;
	}

	tape_position=1;

	while (TRUE)
	{
		io_readed= (unsigned int) io_read(fil, (unsigned char *)&len, 2);

#if defined BIGENDIAN
		byteswp((unsigned char *)&len);
#endif

		if (io_readed<2)
		{
			io_close(fil);
			tape_type="tap";
			sprintf(tape_filename, "%s", filename);
			tape_SetActiveAndPause(tapes);

			//tape_traps = on;

			return;
		}

		io_readed = (unsigned int)io_read(fil, (unsigned char *)data, len);

		if (io_readed!=len)
		{
			io_close(fil);
			sprintf(tstring,"io_readTAP %s : Corrupted file !", filename);
			MessageBoxErr(tstring);
			return;
		}

		if (len)
		{
			rom.len=len;
			rom.pause=1000;

			AddTapeBlock("", 0x10, len, data, sizeof(rom), &rom, 1, tape_position++);
		}
		else
			printf("Zero-length Block !\n");
	}
}


typedef struct {                                                                                              

	unsigned short type;                                                         
	unsigned short channels;                                                             
	unsigned int SamplesPerSec;                                                        
	unsigned int AvgBytesPerSec;                                                       
	unsigned short align;                                                                             
	unsigned short bits;                                                              
} IDWave;  

void io_readWAV(char * filename, char * dir)
{
	IDWave id;
	int fil;
	unsigned int len32;

	signed short data16;
	unsigned char data8;
	unsigned int i;
	unsigned char * data;
	unsigned int true_len;

	signed short v161, v162;
	unsigned char v81,  v82;

	unsigned char bit;

	unsigned int counter=0;

	direct_recT direct;

	unsigned char used=0;


	FreeTape();

	fil=io_open(dir, filename, O_RDONLY);

	if (fil==-1)
	{
		sprintf(tstring,"io_readWAV : %s - can't io_open file", filename);
		MessageBoxErr(tstring);
		return;
	}

	tape_position = 1;

	io_lseek(fil, 0x14, SEEK_SET);
	io_read(fil, (unsigned char *)&id.type, sizeof(id.type));
	io_read(fil, (unsigned char *)&id.channels, sizeof(id.channels));
	io_read(fil, (unsigned char *)&id.SamplesPerSec, sizeof(id.SamplesPerSec));
	io_lseek(fil, 6, SEEK_CUR);
	io_read(fil, (unsigned char *)&id.bits, sizeof(id.bits));

#if defined BIGENDIAN
	byteswp((unsigned char *)&id.type);
	byteswp((unsigned char *)&id.channels);
	ByteSWP_32(&id.SamplesPerSec);
	byteswp((unsigned char *)&id.bits);
#endif


	if (id.type!=1)
	{
		MessageBoxErr("io_readWAV : Only PCM files supported !");
		io_close(fil);
		return;
	}

	if ((id.bits!=8)&&(id.bits!=16))
	{
		sprintf(tstring,"io_readWAV : bits = %d unsupported. Only 8 and 16 bit files supported !", id.bits);

		MessageBoxErr(tstring);
		io_close(fil);
		return;
	}

	if ((id.channels!=2)&&(id.channels!=1))
	{
		MessageBoxErr("io_readWAV : Only MONO and STEREO files supported !");
		io_close(fil);
		return;
	}

	if ((id.SamplesPerSec!=11025)&&(id.SamplesPerSec!=44100)&&(id.SamplesPerSec!=22050))
	{
		sprintf(tstring, "SamplesPerSec=%d unsupported. Supported SamplesPerSec are : 11025, 22050, 44100", id.SamplesPerSec);

		MessageBoxErr(tstring);
		io_close(fil);
		return;
	}

	io_lseek(fil, 4, SEEK_CUR);
	io_read(fil, (unsigned char *)&len32, sizeof(len32));

#if defined BIGENDIAN
	ByteSWP_32(&len32);
#endif

	true_len=len32;
	if (id.SamplesPerSec==11025) true_len*=2;
	if (id.bits==16) { true_len/=2; len32/=2; } 
	if (id.channels==2) { true_len/=2; len32/=2; } 

	true_len/=8;
	true_len++;


	data=(unsigned char *)malloc(true_len);
	if (data==NULL)
	{
		MessageBoxErr("io_readWAV : malloc failed. This is bug. Report it.");
		return;
	}

	for (i=0; i<len32; i++)
	{
		if (id.channels==1)
		{
			if (id.bits==16)
			{
				io_read (fil, (unsigned char *)&data16, 2);
#if defined BIGENDIAN
				byteswp((unsigned char *)&data16);
#endif
			}
			else io_read (fil, (unsigned char *)&data8, 1);
		}
		else
		{
			if (id.bits==16)
			{
				io_read (fil, (unsigned char *)&v161, 2);
				io_read (fil, (unsigned char *)&v162, 2);

#if defined BIGENDIAN
				byteswp((unsigned char *)&v161);
				byteswp((unsigned char *)&v162);
#endif

				data16=v161/2+v162/2;
			}
			else 
			{
				io_read (fil, (unsigned char *)&v81, 1);
				io_read (fil, (unsigned char *)&v82, 1);
				data8=v81/2+v82/2;
			}
		}

		if (id.bits==8)
		{
			if (data8>127) bit=1;
			else 				bit=0;
		}
		else
		{
			if (data16&0x8000) bit=0;
			else 			  		 bit=1;
		}

		if (id.SamplesPerSec==11025)

		{
			b2bset(data, counter++, bit);
			used++; if (used==9) used=1;
			b2bset(data, counter++, bit);
			used++; if (used==9) used=1;
		}
		else
		{
			b2bset(data, counter++, bit);
			used++; if (used==9) used=1;
		}

		if (((i/1000000*1000000)==i)||(!i))
			printf("io_reading %s. %d%c done...\n", filename, i*100/len32, '%');

	}

	printf("io_reading %s. 100%c done.\n", filename, '%');

	if (id.SamplesPerSec==44100) direct.TS=79;
	else 								  direct.TS=158;

	direct.pause=0;
	direct.used=used;
	direct.l3=(true_len&0xFF0000)/65536;
	direct.l2=(true_len&0x00FF00)/256;
	direct.l1= true_len&0x0000FF;

	AddTapeBlock("", 0x15, true_len, data, sizeof(direct), &direct, 1, tape_position++);

	io_close(fil);
	tape_type="wav";
	sprintf(tape_filename, "%s", filename);
	tape_SetActiveAndPause(tapes);
	return;
}




tape_struct * FindTapeByPosition(int p)
{
	tape_struct * r;


	r=tapes;

	if (r==NULL) return (NULL);

	while (TRUE)
	{
		if (r->position==p) return(r);
		r= (tape_struct *)r->next;

		if (r==NULL)
		{
			MessageBoxErr("FindTapeByPosition failed. This is bug. Report it. \n");
			return(NULL);
		}
	}
}


char tape_Group2TextT[65535];
char * tape_Group2Text(tape_struct * t)
{
	char string[256];



	t= (tape_struct *)t->next;
	bzero(tape_Group2TextT, sizeof(tape_Group2TextT));

	while (TRUE)
	{
		sprintf(string,"%-12s %8d %s\n", Description(t->id), t->len, Details(t->id, t->ilen, t->info, t->len, t->data1));
		strcat(tape_Group2TextT, string);

		t= (tape_struct *)t->next;
		if (t->id==0x22) break;
	}

	tape_Group2TextT[strlen(tape_Group2TextT)-1]=0;
	return(tape_Group2TextT);
}


void SaveTAP(char * filename)
{
	int fil;
	tape_struct * t;

	unsigned short len16;


	if (tapes==NULL) return;

	fil=io_creat(NULL, filename);

	if(fil==-1)
	{
		sprintf(tstring,"SaveTAP : Can't io_create %s. You must be able to io_write this directory.", filename);
		MessageBoxErr(tstring);
		return;
	}


	t=tapes;

	while (TRUE)
	{
		len16=t->len;
		if (t->id==0x10) 
		{
			io_write(fil, (unsigned char *)&len16,2);	
			io_write(fil, (unsigned char *)t->data1,len16);
		}

		t= (tape_struct *)t->next;
		if (!t) break;
	}

	io_close(fil);

	tape_type="tap";
	sprintf(tape_filename, "%s", filename);
}

void SaveTZX(char * filename)
{
	int fil;
	tape_struct * t;
	unsigned char eof=0x1a;
	unsigned char major=1, minor=13;

	direct_recT * direct;
	turbo_block_type * turbo;
	ROM_bl_type * rom;
	unsigned short * len16;
	Pure_toneT * tone;
	Pure_dataT * data;
	signed short * Signed;
	unsigned char len8;
	unsigned short Len16;
	zxtapeT * zx;


	if (tapes==NULL) return;

	fil=io_creat(NULL, filename);

	if(fil==-1)
	{
		sprintf(tstring,"SaveTZX : Can't io_create %s. You must be able to io_write this directory.", filename);
		MessageBoxErr(tstring);
		return;
	}

	if (tapes->id!='Z')
	{
		io_write(fil,"ZXTape!",7);	
		io_write(fil,&eof,1);
		io_write(fil,&major,1);
		io_write(fil,&minor,1);
	}

	t=tapes;

	while (TRUE)
	{
		io_write(fil, &t->id, 1);

		switch (t->id)
		{
		case 0x15:
			direct= (direct_recT *)t->info;
			io_write(fil, (unsigned char *)&direct->TS, 2);
			io_write(fil, (unsigned char *)&direct->pause, 2);
			io_write(fil, (unsigned char *)&direct->used, 1);
			io_write(fil, (unsigned char *)&direct->l1, 1);
			io_write(fil, (unsigned char *)&direct->l2, 1);
			io_write(fil, (unsigned char *)&direct->l3, 1);
			io_write(fil, (unsigned char *)t->data1, t->len);
			break;

		case 'Z':
			zx= (zxtapeT *)t->info;
			io_write(fil,"XTape!",6);	
			io_write(fil, (unsigned char *)&eof,1);
			io_write(fil, (unsigned char *)&zx->major,1);
			io_write(fil, (unsigned char *)&zx->minor,1);
			break;

		case 0x10:
			rom= (ROM_bl_type *)t->info;
			io_write(fil, (unsigned char *)&rom->pause, 2);
			io_write(fil, (unsigned char *)&rom->len, 2);
			io_write(fil, (unsigned char *)t->data1, t->len);
			break;

		case 0x11:
			turbo= (turbo_block_type *)t->info;
			io_write(fil, (unsigned char *)&turbo->pilotL, 2);
			io_write(fil, (unsigned char *)&turbo->syncFL, 2);
			io_write(fil, (unsigned char *)&turbo->syncSL, 2);
			io_write(fil, (unsigned char *)&turbo->zeroL, 2);
			io_write(fil, (unsigned char *)&turbo->oneL, 2);

			io_write(fil, (unsigned char *)&turbo->pilot_toneL_inPulses, 2);
			io_write(fil, (unsigned char *)&turbo->used_bits, 1);
			io_write(fil, (unsigned char *)&turbo->pause, 2);
			io_write(fil, (unsigned char *)&turbo->l1, 1);

			io_write(fil, (unsigned char *)&turbo->l2, 1);
			io_write(fil, (unsigned char *)&turbo->l3, 1);
			io_write(fil, (unsigned char *)t->data1, t->len);
			break;

		case 0x12:
			tone= (Pure_toneT *)t->info;
			io_write(fil, (unsigned char *)&tone->len, 2);
			io_write(fil, (unsigned char *)&tone->n, 2);

			break;

		case 0x13:
			len8=t->len/2;
			io_write(fil, (unsigned char *)&len8, 1);
			io_write(fil, (unsigned char *)t->data1, t->len);
			break;

		case 0x14:
			data= (Pure_dataT *)t->info;
			io_write(fil, (unsigned char *)&data->z, 2);
			io_write(fil, (unsigned char *)&data->o, 2);
			io_write(fil, (unsigned char *)&data->used, 1);
			io_write(fil, (unsigned char *)&data->pause, 2);
			io_write(fil, (unsigned char *)&data->l1, 1);
			io_write(fil, (unsigned char *)&data->l2, 1);
			io_write(fil, (unsigned char *)&data->l3, 1);
			io_write(fil, (unsigned char *)t->data1, t->len);
			break;

		case 0x20:
			len16= (unsigned short *)t->info;
			io_write(fil, (unsigned char *)len16, 2);
			break;

		case 0x21:
			len8=t->len;
			io_write(fil, (unsigned char *)&len8, 1);
			io_write(fil, (unsigned char *)t->data1, t->len);
			break;

		case 0x22:
			break;

		case 0x23:
			Signed= (short *)t->info;
			io_write(fil, (unsigned char *)Signed, 2);
			break;

		case 0x24:
			len16= (unsigned short *)t->info;
			io_write(fil, (unsigned char *)len16, 2);
			break;

		case 0x25:
			break;

		case 0x30:
			len8=t->len;
			io_write(fil, (unsigned char *)&len8, 1);
			io_write(fil, (unsigned char *)t->data1, t->len);
			break;

		case 0x32:
			Len16=t->len;
			io_write(fil, (unsigned char *)&Len16, 2);
			io_write(fil, (unsigned char *)t->data1, t->len);
			break;

		case 0x33:
			len8=t->len/3;
			io_write(fil, (unsigned char *)&len8, 1);
			io_write(fil, (unsigned char *)t->data1, t->len);
			break;

		case 0x35:
			io_write(fil, (unsigned char *) t->info, 0x16);
			io_write(fil, (unsigned char *)&t->len, 4);
			io_write(fil, (unsigned char *)t->data1, t->len);
			break;


		default:
			sprintf(tstring, "SaveTZX : Unknown ID=#%X. This is BUG. Report it.", t->id);
			//MessageBoxErr(tstring);
			io_close(fil);
			return;
		}

		t= (tape_struct *)t->next;
		if (!t) break;
	}

	io_close(fil);
}

void SaveWAV(char * filename)
{
	int fil;
	tape_struct * t;
	unsigned int len=0;
	unsigned int full_len;
	unsigned int temp;
	unsigned short temp16;
	unsigned int i;
	unsigned char byte;
	unsigned char Data=0;


	if (tapes==NULL) return;

	fil=io_creat(NULL, filename);

	if(fil==-1)
	{
		sprintf(tstring,"SaveWAV : Can't create %s. You must be able to io_write this directory.", filename);
		MessageBoxErr(tstring);
		return;
	}


	t=tapes;

	while (TRUE)
	{
		Fill(tapeS, &len, t);

		t= (tape_struct *)t->next;
		if (!t) break;
	}

	full_len=len/*dlina viborki*/+8/*zagolovok RIFF fajla*/+12/*Zagolovok kuska WAV*/+16/*kusok WAV*/+8/*identifikator vyborki*/;

	io_write(fil,"RIFF",4);
	temp=full_len-8;
	io_write(fil, (unsigned char *)&temp,4);
	io_write(fil, "WAVEfmt ",8);
	temp=0x10;
	io_write(fil, (unsigned char *)&temp,4);
	temp16=1;
	io_write(fil, (unsigned char *)&temp16,2);
	io_write(fil, (unsigned char *)&temp16,2);
	temp=44100;
	io_write(fil, (unsigned char *)&temp,4);
	io_write(fil, (unsigned char *)&temp,4);
	io_write(fil, (unsigned char *)&temp16,2);
	temp16=8;
	io_write(fil, (unsigned char *)&temp16,2);
	io_write(fil, "data",4);
	temp=len;
	io_write(fil, (unsigned char *)&temp,4);
	io_write(fil, (unsigned char *)&Data,1);

	for (i=0; i<len; i++)
	{
		byte=b2bget(tapeS, i);
		if (byte) byte=250;

		io_write(fil, &byte, 1);

		if (((i/1000000*1000000)==i)||(!i))
			printf("Writing %s. %d%c done...\n", filename, i*100/len, '%');
	}

	printf("Writing %s. 100%c done.\n", filename, '%');
	io_close (fil);

	tape_type="wav";
	sprintf(tape_filename, "%s", filename);

	/* chegoto ya tuta hotel. Chego imenno - me pomnu. !!! */
}


int VseBloki10(void)
{
	tape_struct * t;


	t=tapes;

	if (t==NULL) return (false);

	while (TRUE)
	{
		if ((t->id!=0x10)&&(t->id!='Z')&&(!NadoPropustitEtotTapeBlock(t)))return (false);
		t= (tape_struct *)t->next;
		if (!t) break;
	}

	return (true);
}

int MojnoPisatWAV(void)
{
	tape_struct * t;
	unsigned short * value;


	t=tapes;

	if (t==NULL) return (false);

	while (TRUE)
	{
		if ((t->id==0x23)||(t->id==0x25)||(t->id==0x24)) return(false);

		if (t->id==0x20)
		{
			value=(unsigned short * )t->info;

			if (!(*value)) 
				return (false);
		}

		t= (tape_struct *)t->next;
		if (!t) break;
	}

	return (true);
}


void uberi_diru_v_Teipah(int udalit, tape_struct * active)
{
	tape_struct * t;


	t=tapes;


	while (TRUE)
	{
		if ((t->position>udalit)&&(t->position))t->position--;

		t= (tape_struct *)t->next;
		if (!t) break;
	}

	TODO ("uberi_diru_v_Teipah");

	tape_next=active;
}

tape_struct * TapeFindParent(tape_struct * arg)
{
	tape_struct * t;


	t=tapes;

	while (TRUE)
	{
		if (t->next==arg)return(t);

		t= (tape_struct *)t->next;
		if (!t) break;
	}

	printf("TapeFindParent failed. This is bug. Report it.\n");
	ExitWithError(-1, "");
	return(NULL); /* :) */
}

void TapeDeleteBlock(tape_struct * t)
{
	int n;


	if (tapes==NULL) return;

	if ((t==tapes)&&(t->next==NULL))
	{
		FreeTape(); 
		return;
	}

	if (t==tapes)
	{
		n=t->position;
		tapes= (tape_struct *)t->next;

		if (t->len) free(t->data1);
		if (t->ilen) free(t->info);
		free(t);

		uberi_diru_v_Teipah(n, tapes);
		return;
	}

	if (t->next==NULL)
	{
		n=t->position;
		TapeFindParent(t)->next=NULL;


		if (t->len) free(t->data1);
		if (t->ilen) free(t->info);
		free(t);

		uberi_diru_v_Teipah(n, tapes);
		return;
	}

	n=t->position;
	TapeFindParent(t)->next=t->next;

	uberi_diru_v_Teipah(n, (tape_struct *)t->next);

	if (t->len) free(t->data1);
	if (t->ilen) free(t->info);
	free(t);
}



tape_struct * todelete;

void tape_deleteF_Confirmed(void)
{
	TapeDeleteBlock(todelete);
}


int init (unsigned char * memory)
{
	static int inited = 0;

	if (inited)
		return no_errors;

	inited = 1;

	FillParityTBL();
	LoadDefaults();

	PixmapsAllocAndFill();

	LookForIniFileEx();

	videomemory = memory;

	if (ApplyParameters()==errors) return errors;

	if (strcmp(Mode,"48")!=0)
		Set128kMode();
	else
		Set48kMode();

	for (int i=0; i<MAX_AY_PER_FILE; i++)
		A_Y.counter[i] = 0;

	A_Y.tcounter = 0;

	return  no_errors;
}

void ApplySoundRegister(int r, int v)
{
	if (r<=AY_ESHAPE)
		Regs1[r]=v;

	switch( r )
	{
	case AY_AFINE:
	case AY_ACOARSE:
		Regs1[AY_ACOARSE] &= 0x0f;
		GeneratorA_period = (Regs1[AY_AFINE] + 256 * Regs1[AY_ACOARSE]) * UpdateStep / STEP;
		if (GeneratorA_period == 0)GeneratorA_period=UpdateStep / STEP;
		break;

	case AY_BFINE:
	case AY_BCOARSE:
		Regs1[AY_BCOARSE] &= 0x0f;
		GeneratorB_period = (Regs1[AY_BFINE] + 256 * Regs1[AY_BCOARSE]) * UpdateStep / STEP;
		if (GeneratorB_period == 0)GeneratorB_period=UpdateStep / STEP;

		break;

	case AY_CFINE:
	case AY_CCOARSE:
		Regs1[AY_CCOARSE] &= 0x0f;
		GeneratorC_period = (Regs1[AY_CFINE] + 256 * Regs1[AY_CCOARSE]) * UpdateStep / STEP;
		if (GeneratorC_period == 0)GeneratorC_period=UpdateStep / STEP;
		break;

	case AY_AVOL:
		Regs1[AY_AVOL] &= 0x1f;

		if (avol_max<Regs1[AY_AVOL])avol_max=Regs1[AY_AVOL];

		break;

	case AY_BVOL:
		Regs1[AY_BVOL] &= 0x1f;

		if (bvol_max<Regs1[AY_BVOL])bvol_max=Regs1[AY_BVOL];

		break;

	case AY_CVOL:
		Regs1[AY_CVOL] &= 0x1f;

		if (cvol_max<Regs1[AY_CVOL])cvol_max=Regs1[AY_CVOL];

		break;

	case AY_ENABLE: 

		if ((Regs1[AY_ENABLE]&1))
			channelA_enabled=1;
		else
			channelA_enabled=0;

		if ((Regs1[AY_ENABLE]&2))
			channelB_enabled=1;
		else
			channelB_enabled=0;

		if ((Regs1[AY_ENABLE]&4))
			channelC_enabled=1;
		else
			channelC_enabled=0;

		if ((Regs1[AY_ENABLE]&8))
			noiseA_enabled=1;
		else
			noiseA_enabled=0;

		if ((Regs1[AY_ENABLE]&16))
			noiseB_enabled=1;
		else
			noiseB_enabled=0;

		if ((Regs1[AY_ENABLE]&32))
			noiseC_enabled=1;
		else
			noiseC_enabled=0;

		break;

	case AY_NOISEPER:                                                                          
		Regs1[AY_NOISEPER] &= 0x1f;                                                    
		PeriodN = Regs1[AY_NOISEPER] * UpdateStep / STEP;                           
		if (PeriodN == 0) PeriodN = UpdateStep / STEP;                             
		break;         

	case AY_EFINE:                                                                             
	case AY_ECOARSE:                                                                           
		periodE = ((Regs1[AY_EFINE] + 256 * Regs1[AY_ECOARSE])) * UpdateStep / STEP;                                                                                               
		if (periodE == 0) periodE = UpdateStep / STEP / 2;                         
		break;      


	case AY_ESHAPE: 
		Regs1[AY_ESHAPE] &= 0x0f;  

		switch(Regs1[AY_ESHAPE])
		{
		case 0 :
		case 1 :
		case 2 :
		case 3 :
			cont=0;
			att=0;
			break;

		case 4 :
		case 5 :
		case 6 :
		case 7 :
			cont=0;
			att=1;
			break;

		case 8:
			cont=1;
			att=0;
			alt=0;
			hold=0;
			break;

		case 9:
			cont=1;
			att=0;
			alt=0;
			hold=1;
			break;

		case 10:
			cont=1;
			att=0;
			alt=1;
			hold=0;
			break;

		case 11:
			cont=1;
			att=0;
			alt=1;
			hold=1;
			break;

		case 12:
			cont=1;
			att=1;
			alt=0;
			hold=0;
			break;


		case 13:
			cont=1;
			att=1;
			alt=0;
			hold=1;
			break;

		case 14:
			cont=1;
			att=1;
			alt=1;
			hold=0;
			break;

		case 15:
			cont=1;
			att=1;
			alt=1;
			hold=1;
			break;
		}

		Envelope_counter=0;

		if (att) env_volume=0;
		else env_volume=15;

		up=att;
		holded=0;

		break;


	case BEEPER :
		if (v) bpr=VolTable[beeper_volume];
		else bpr=0;
		break;
	}	
}



void Mix(unsigned short * sound_buffer, int Sound_Freq, int smezhenie, int n, unsigned short * mixing_ch0, unsigned short * mixing_ch1, unsigned short * mixing_ch2, unsigned short * mixing_ch3=NULL)
{
	int i,j;



	mixing_ch[0]=mixing_ch0;
	mixing_ch[1]=mixing_ch1;
	mixing_ch[2]=mixing_ch2;
	mixing_ch[3]=mixing_ch3;


	switch (Sound_Freq)
	{
	case 44100:
		for (i=0; i<SOUND_TICKS_PER_FRAME; i++)
		{
			sound_buffer[i*2+smezhenie]=0;

			for (j=0; j<n; j++)
				sound_buffer[i*2+smezhenie]+=mixing_ch[j][i]/n;
		}
		break;

	case 22050:
		for (i=0; i<(SOUND_TICKS_PER_FRAME_2); i++)
		{
			sound_buffer[i*2+smezhenie]=0;

			for (j=0; j<n; j++)
				sound_buffer[i*2+smezhenie]+=mixing_ch[j][i*2]/n;
		}
		break;

	case 11025:
		for (i=0; i<(SOUND_TICKS_PER_FRAME_4); i++)
		{
			sound_buffer[i*2+smezhenie]=0;

			for (j=0; j<n; j++)
				sound_buffer[i*2+smezhenie]+=mixing_ch[j][i*4]/n;
		}
		break;
	}		
}

void Envelope__Step(void)
{
	if (holded) return;

	/* is it correct ??? */
	if ((alt ? periodE : (periodE*2))>Envelope_counter)
		Envelope_counter++;
	else
	{
		Envelope_counter=0;

		if (up)
		{ 
			if (env_volume<15) env_volume++;
			else
			{
				if (cont==0) 
				{
					holded=1;
					env_volume=0;
					goto LQ;
				}
				if (hold)
				{
					if (alt)env_volume=0;
					holded=1;
					goto LQ;	
				}

				if (alt)up=0;
				else env_volume=0;
			}
		}
		else
		{
			if (env_volume>0) env_volume--;
			else
			{
				if (cont==0) 
				{
					holded=1;
					goto LQ;
				}
				if (hold)
				{
					if (alt)env_volume=15;
					holded=1;
					goto LQ;	
				}
				if (alt)up=1;
				else env_volume=15;
			}
		}
	}

LQ: ;
}

void UpdateSoundBuffer(void)
{
	int i;
	int j;


	/* zapolnyaem pole pos */
	if (PSGcounter>0)
	{
		if (tcounter==0)tcounter++;	

		for (i=0; i<PSGcounter; i++)
			PSGARRAY[i].pos=(SOUND_TICKS_PER_FRAME-1)*PSGARRAY[i].tcounter/tcounter;
	}	

	/* generim zvuk */
	j=0;
	for (i=0; i<SOUND_TICKS_PER_FRAME; i++)
	{	
		if (PSGcounter>0)
		{
			while (i==PSGARRAY[j].pos)
			{
				ApplySoundRegister(PSGARRAY[j].r,PSGARRAY[j].v);

				PSGARRAY[j].pos=SOUND_TICKS_PER_FRAME;

				j++;	

				if (j>=SOUND_ARRAY_LEN) break;
			}
		}	

		/* return; */

		Envelope__Step();


		/* Generator A step */
		if (GeneratorA_counter>=GeneratorA_period)	
			GeneratorA_counter=0;

		if (GeneratorA_counter<(GeneratorA_period/2))
			Atone=1;
		else
			Atone=0;

		GeneratorA_counter++;

		/* Noice A Step */
		if (NoiceA_counter>=PeriodN)	
		{
			NoiceA_counter=0;
			rndA=rand();
		}

		if (rndA&1)
			Anoice=1;
		else
			Anoice=0;

		NoiceA_counter++;

		soundA[i]=( ((Atone | channelA_enabled) & (Anoice | noiseA_enabled)) | !GeneratorA_period);
		soundA[i] = (soundA[i]) ? (Regs1[AY_AVOL]&0x10) ? VolTable[env_volume] : VolTable[Regs1[AY_AVOL]] : 0;

		/* Generator B step */
		if (GeneratorB_counter>=GeneratorB_period)	
			GeneratorB_counter=0;

		if (GeneratorB_counter<(GeneratorB_period/2))
			Btone=1;
		else
			Btone=0;

		GeneratorB_counter++;

		/* Noice B Step */
		if (NoiceB_counter>=PeriodN)	
		{
			NoiceB_counter=0;
			rndB=rand ();
		}

		if (rndB&1)
			Bnoice=1;
		else
			Bnoice=0;

		NoiceB_counter++;

		soundB[i]=( ((Btone | channelB_enabled) & (Bnoice | noiseB_enabled)) | !GeneratorB_period);
		soundB[i] = (soundB[i]) ? (Regs1[AY_BVOL]&0x10) ? VolTable[env_volume] : VolTable[Regs1[AY_BVOL]] : 0;

		/* Generator C step */
		if (GeneratorC_counter>=GeneratorC_period)	
			GeneratorC_counter=0;

		if (GeneratorC_counter<(GeneratorC_period/2))
			Ctone=1;
		else
			Ctone=0;

		GeneratorC_counter++;

		/* Noice C Step */
		if (NoiceC_counter>=PeriodN)	
		{
			NoiceC_counter=0;
			rndC=rand ();
		}

		if (rndC&1)
			Cnoice=1;
		else
			Cnoice=0;

		NoiceC_counter++;

		soundC[i]=( ((Ctone | channelC_enabled) & (Cnoice | noiseC_enabled)) | !GeneratorC_period);
		soundC[i] = (soundC[i]) ? (Regs1[AY_CVOL]&0x10) ? VolTable[env_volume] : VolTable[Regs1[AY_CVOL]] : 0;

		/* Beeper Step */
		beeper_buffer[i]=bpr;
	}

	/***** Mix & io_write *****/
	if (sound_fil!=-1)
	{
		if (stereo_mode==2)
		{
			Mix(sound_bufferD, 44100, 0,4,soundA,soundB,soundC,beeper_buffer);
			Mix(sound_bufferD, 44100, 1,4,soundA,soundB,soundC,beeper_buffer);
		}

		if (stereo_mode==1)
		{
			Mix(sound_bufferD, 44100, 0,3,soundA,soundB,beeper_buffer);
			Mix(sound_bufferD, 44100, 1,3,soundC,soundB,beeper_buffer);
		}	

		if (stereo_mode==0)
		{
			Mix(sound_bufferD, 44100, 0,3,soundA,soundC,beeper_buffer);
			Mix(sound_bufferD, 44100, 1,3,soundB,soundC,beeper_buffer);
		}

		TODO ("io_write(sound_fil, sound_bufferD, SOUND_TICKS_PER_FRAME*4);");
	}

	if (stereo_mode==2)
	{
		Mix(sound_buffer, 44100, 0,4,soundA,soundB,soundC,beeper_buffer);
		Mix(sound_buffer, 44100, 1,4,soundA,soundB,soundC,beeper_buffer);
	}

	if (stereo_mode==1)
	{
		Mix(sound_buffer, 44100, 0,3,soundA,soundB,beeper_buffer);
		Mix(sound_buffer, 44100, 1,3,soundC,soundB,beeper_buffer);
	}	

	if (stereo_mode==0)
	{
		Mix(sound_buffer, 44100, 0,3,soundA,soundC,beeper_buffer);
		Mix(sound_buffer, 44100, 1,3,soundB,soundC,beeper_buffer);
	}

	/****** Mix End *********/

	PSGcounter=0;
	tcounter=0;
}

// 0 UP DOWN LEFT RIGHT FIRE SC SS ENT
// 8 DELELE EXTM BREAK KAV POINT STAR
void joystick(int action, int up)
{
	//printf("joystick %d\n", joy_type);

	switch (action) 
	{

	case 8:
		fefe.d0=up;
		effe.d0=up;
		break;

	case 9:
		sffe.d1=up;
		fefe.d0=up;
		break;

	case  10:
		fefe.d0=up;
		sffe.d0=up;
		break;

	case 11:
		sffe.d1=up;
		dffe.d0=up;
		break;

	case  12:
		sffe.d1=up;
		sffe.d2=up;
		break;

	case  13:
		sffe.d1=up;
		sffe.d4=up;
		break;


	case 0: // UP
		if (joy_type == 0)
			kempston.bit.up = 1 - up;
		if (joy_type == 1)
			effe.d1 = up;
		if (joy_type == 2)
		{
			effe.d3 = up;
			fefe.d0 = up;
		}
		if (joy_type == 3)
			fbfe.d0=up;

		break;

	case 1: //DOWN
		if (joy_type == 0)
			kempston.bit.down = 1 - up;
		if (joy_type == 1)
			effe.d2 = up;
		if (joy_type == 2)
		{
			effe.d4 = up;
			fefe.d0 = up;
		}
		if (joy_type == 3)
			fdfe.d0=up;

		break;

	case 2: //LEFT
		if (joy_type == 0)
			kempston.bit.left = 1 - up;
		if (joy_type == 1)
			effe.d4 = up;
		if (joy_type == 2)
		{
			f7fe.d4 = up;
			fefe.d0 = up;
		}
		if (joy_type == 3)
			dffe.d1=up;

		break;

	case 3: //RIGHT
		if (joy_type == 0)
			kempston.bit.right = 1 - up;
		if (joy_type == 1)
			effe.d3 = up;
		if (joy_type == 2)
		{
			effe.d2 = up;
			fefe.d0 = up;
		}
		if (joy_type == 3)
			dffe.d0=up;

		break;

	case 4://FIRE
		if (joy_type == 0)
			kempston.bit.fire = 1 - up;
		if (joy_type == 1)
			effe.d0 = up;
		if (joy_type == 2)
		{
			effe.d0=up;
		}
		if (joy_type == 3)
			sffe.d0=up;
		break;



	case 'Q':
		fbfe.d0=up;
		break;

	case 'W':
		fbfe.d1=up;
		break;

	case 'E':
		fbfe.d2=up;
		break;

	case 'R':
		fbfe.d3=up;
		break;

	case 'T':
		fbfe.d4=up;
		break;

	case 'A':
		fdfe.d0=up;
		break;

	case 'S':
		fdfe.d1=up;
		break;

	case 'D':
		fdfe.d2=up;
		break;

	case 'F':
		fdfe.d3=up;
		break;

	case 'G':
		fdfe.d4=up;
		break;

	case 5:
		fefe.d0=up;
		break;

	case 'Z':
		fefe.d1=up;
		break;

	case 'X':
		fefe.d2=up;
		break;

	case 'C':
		fefe.d3=up;
		break;

	case 'V':
		fefe.d4=up;
		break;

	case 'Y':
		dffe.d4=up;
		break;

	case 'U':
		dffe.d3=up;
		break;

	case 'I':
		dffe.d2=up;
		break;

	case 'O':
		dffe.d1=up;
		break;

	case 'P':
		dffe.d0=up;
		break;

	case 'H':
		bffe.d4=up;
		break;

	case 'J':
		bffe.d3=up;
		break;

	case 'K':
		bffe.d2=up;
		break;

	case 'L':
		bffe.d1=up;
		break;

	case 7:
		bffe.d0=up;
		break;

	case 'B':
		sffe.d4=up;
		break;

	case 'N':
		sffe.d3=up;
		break;

	case 'M':
		sffe.d2=up;
		break;

	case 6:
		sffe.d1=up;
		break;

	case ' ':
		sffe.d0=up;
		break;


	case '1':
		f7fe.d0=up;
		break;

	case '2':
		f7fe.d1=up;
		break;

	case '3':
		f7fe.d2=up;
		break;

	case '4':
		f7fe.d3=up;
		break;

	case '5':
		f7fe.d4=up;
		break;

	case '6':
		effe.d4=up;
		break;

	case '7':
		effe.d3=up;
		break;

	case '8':
		effe.d2=up;
		break;

	case '9':
		effe.d1=up;
		break;

	case '0':
		effe.d0=up;
		//Log=1;
		break;

	}
}

void SetHomeDir(char * arg)
{
	strcpy(homedir1, arg);
}

void SetHomeDer(char * arg)
{
	strcpy (start_directory, arg);
}

char * GetHomeDer(void)
{
	return start_directory;
}

char GetBorder(void)
{
	return (border);
}

char * GetDisk1(int n)
{
	return (discs[n].filename);
}