//Read a 32 bit value from kernel. note: address must be all in endianness of sending platform
        public UInt32 peek_kern(UInt32 address)
        {
            //value = send [address in big endian] [value in big endian]
            address = ByteSwap.Swap(address);

            //Send read
            if (this.RawCommand(cmd_readkern) != FTDICommand.CMD_OK)
            {
                throw new ETCPGeckoException(ETCPErrorCode.FTDICommandSendError);
            }

            //write value
            if (this.GeckoWrite(BitConverter.GetBytes(address), 4) != FTDICommand.CMD_OK)
            {
                throw new ETCPGeckoException(ETCPErrorCode.FTDICommandSendError);
            }

            Byte[] buffer = new Byte[4];
            if (this.GeckoRead(buffer, 4) != FTDICommand.CMD_OK)
            {
                throw new ETCPGeckoException(ETCPErrorCode.FTDICommandSendError);
            }

            return(ByteSwap.Swap(BitConverter.ToUInt32(buffer, 0)));
        }
        public UInt32 OsVersionRequest()
        {
            if (this.RawCommand(cmd_os_version) != FTDICommand.CMD_OK)
            {
                throw new ETCPGeckoException(ETCPErrorCode.FTDICommandSendError);
            }

            Byte[] buffer = new Byte[4];

            if (this.GeckoRead(buffer, 4) != FTDICommand.CMD_OK)
            {
                throw new ETCPGeckoException(ETCPErrorCode.FTDICommandSendError);
            }

            return(ByteSwap.Swap(BitConverter.ToUInt32(buffer, 0)));
        }
        public UInt32 peek(UInt32 address)
        {
            if (!ValidMemory.ValidAddress(address))
            {
                return(0);
            }

            //address will be alligned to 4
            UInt32 paddress = address & 0xFFFFFFFC;

            //Create a memory stream for the actual dump
            MemoryStream stream = new MemoryStream();

            //make sure to not send data to the output
            GeckoProgress oldUpdate = this.PChunkUpdate;

            this.PChunkUpdate = null;

            try
            {
                //dump data
                this.Dump(paddress, paddress + 4, stream);

                //go to beginning
                stream.Seek(0, SeekOrigin.Begin);
                Byte[] buffer = new Byte[4];
                stream.Read(buffer, 0, 4);

                //Read buffer
                UInt32 result = BitConverter.ToUInt32(buffer, 0);

                //Swap to machine endianness and return
                result = ByteSwap.Swap(result);

                return(result);
            }
            finally
            {
                this.PChunkUpdate = oldUpdate;

                //make sure the Stream is properly closed
                stream.Close();
            }
        }
        //Poke a 32 bit value to kernel. note: address and value must be all in endianness of sending platform
        public void poke_kern(UInt32 address, UInt32 value)
        {
            //value = send [address in big endian] [value in big endian]
            UInt64 PokeVal = (((UInt64)address) << 32) | ((UInt64)value);

            PokeVal = ByteSwap.Swap(PokeVal);

            //Send poke
            if (this.RawCommand(cmd_writekern) != FTDICommand.CMD_OK)
            {
                throw new ETCPGeckoException(ETCPErrorCode.FTDICommandSendError);
            }

            //write value
            if (this.GeckoWrite(BitConverter.GetBytes(PokeVal), 8) != FTDICommand.CMD_OK)
            {
                throw new ETCPGeckoException(ETCPErrorCode.FTDICommandSendError);
            }
        }
        public void Dump(UInt32 startdump, UInt32 enddump, Stream[] saveStream)
        {
            //Reset connection
            this.InitGecko();

            if (ValidMemory.RangeCheckId(startdump) != ValidMemory.RangeCheckId(enddump))
            {
                enddump = ValidMemory.ValidAreas[ValidMemory.RangeCheckId(startdump)].High;
            }

            if (!ValidMemory.ValidAddress(startdump))
            {
                return;
            }

            //How many bytes of data have to be transferred
            UInt32 memlength = enddump - startdump;

            //How many chunks do I need to split this data into
            //How big ist the last chunk
            UInt32 fullchunks = memlength / packetsize;
            UInt32 lastchunk  = memlength % packetsize;

            //How many chunks do I need to transfer
            UInt32 allchunks = fullchunks;

            if (lastchunk > 0)
            {
                allchunks++;
            }

            UInt64 GeckoMemRange = ByteSwap.Swap((UInt64)(((UInt64)startdump << 32) + ((UInt64)enddump)));

            if (this.GeckoWrite(BitConverter.GetBytes(cmd_readmem), 1) != FTDICommand.CMD_OK)
            {
                throw new ETCPGeckoException(ETCPErrorCode.FTDICommandSendError);
            }

            //Read reply - expcecting GCACK -- nope, too slow, TCP is reliable!
            Byte retry = 0;

            //Now let's send the dump information
            if (this.GeckoWrite(BitConverter.GetBytes(GeckoMemRange), 8) != FTDICommand.CMD_OK)
            {
                throw new ETCPGeckoException(ETCPErrorCode.FTDICommandSendError);
            }

            //We start with chunk 0
            UInt32 chunk = 0;

            retry = 0;

            // Reset cancel flag
            bool done = false;

            this.CancelDump = false;

            Byte[] buffer = new Byte[packetsize]; //read buffer
            while (chunk < fullchunks && !done)
            {
                //No output yet availible
                this.SendUpdate(startdump + chunk * packetsize, chunk, allchunks, chunk * packetsize, memlength, retry == 0, true);
                //Set buffer
                Byte[] response = new Byte[1];
                if (this.GeckoRead(response, 1) != FTDICommand.CMD_OK)
                {
                    //Major fail, give it up
                    this.GeckoWrite(BitConverter.GetBytes(GCFAIL), 1);
                    throw new ETCPGeckoException(ETCPErrorCode.FTDIReadDataError);
                }
                Byte reply = response[0];
                if (reply == BlockZero)
                {
                    for (int i = 0; i < packetsize; i++)
                    {
                        buffer[i] = 0;
                    }
                }
                else
                {
                    FTDICommand returnvalue = this.GeckoRead(buffer, packetsize);
                    if (returnvalue == FTDICommand.CMD_ResultError)
                    {
                        retry++;
                        if (retry >= 3)
                        {
                            //Give up, too many retries
                            this.GeckoWrite(BitConverter.GetBytes(GCFAIL), 1);
                            throw new ETCPGeckoException(ETCPErrorCode.TooManyRetries);
                        }
                        //GeckoWrite(BitConverter.GetBytes(GCRETRY), 1);
                        continue;
                    }
                    else if (returnvalue == FTDICommand.CMD_FatalError)
                    {
                        //Major fail, give it up
                        this.GeckoWrite(BitConverter.GetBytes(GCFAIL), 1);
                        throw new ETCPGeckoException(ETCPErrorCode.FTDIReadDataError);
                    }
                }
                //write received package to output stream
                foreach (Stream stream in saveStream)
                {
                    stream.Write(buffer, 0, ((Int32)packetsize));
                }

                //reset retry counter
                retry = 0;
                //next chunk
                chunk++;

                if (!this.CancelDump)
                {
                    //ackowledge package -- nope, too slow, TCP is reliable!
                    //GeckoWrite(BitConverter.GetBytes(GCACK), 1);
                }
                else
                {
                    // User requested a cancel
                    this.GeckoWrite(BitConverter.GetBytes(GCFAIL), 1);
                    done = true;
                }
            }

            //Final package?
            while (!done && lastchunk > 0)
            {
                //No output yet availible
                this.SendUpdate(startdump + chunk * packetsize, chunk, allchunks, chunk * packetsize, memlength, retry == 0, true);
                //Set buffer
                // buffer = new Byte[lastchunk];
                Byte[] response = new Byte[1];
                if (this.GeckoRead(response, 1) != FTDICommand.CMD_OK)
                {
                    //Major fail, give it up
                    this.GeckoWrite(BitConverter.GetBytes(GCFAIL), 1);
                    throw new ETCPGeckoException(ETCPErrorCode.FTDIReadDataError);
                }
                Byte reply = response[0];
                if (reply == BlockZero)
                {
                    for (int i = 0; i < lastchunk; i++)
                    {
                        buffer[i] = 0;
                    }
                }
                else
                {
                    FTDICommand returnvalue = this.GeckoRead(buffer, lastchunk);
                    if (returnvalue == FTDICommand.CMD_ResultError)
                    {
                        retry++;
                        if (retry >= 3)
                        {
                            //Give up, too many retries
                            this.GeckoWrite(BitConverter.GetBytes(GCFAIL), 1);
                            throw new ETCPGeckoException(ETCPErrorCode.TooManyRetries);
                        }
                        //GeckoWrite(BitConverter.GetBytes(GCRETRY), 1);
                        continue;
                    }
                    else if (returnvalue == FTDICommand.CMD_FatalError)
                    {
                        //Major fail, give it up
                        this.GeckoWrite(BitConverter.GetBytes(GCFAIL), 1);
                        throw new ETCPGeckoException(ETCPErrorCode.FTDIReadDataError);
                    }
                }
                //write received package to output stream
                foreach (Stream stream in saveStream)
                {
                    stream.Write(buffer, 0, ((Int32)lastchunk));
                }
                //reset retry counter
                retry = 0;
                //cancel while loop
                done = true;
                //ackowledge package -- nope, too slow, TCP is reliable!
                //GeckoWrite(BitConverter.GetBytes(GCACK), 1);
            }
            this.SendUpdate(enddump, allchunks, allchunks, memlength, memlength, true, true);
        }