private PDS SetReplyMode(byte[] buffer, int bufferLength)
        {
            byte partition;
            int  i;
            var  comma = "(";

            if (bufferLength < 5)
            {
                telnet.Trace.trace_ds(" error: wrong field length %d\n", bufferLength);
                return(PDS.BadCommand);
            }

            partition = buffer[3];
            telnet.Trace.trace_ds("(0x%02x)", partition);

            if (partition != 0x00)
            {
                telnet.Trace.trace_ds(" error: illegal partition\n");
                return(PDS.BadCommand);
            }

            switch (buffer[4])
            {
            case Codes.Field:
                telnet.Trace.trace_ds(" Field\n");
                break;

            case Codes.ExtendedField:
                telnet.Trace.trace_ds(" ExtendedField\n");
                break;

            case Codes.Character:
                telnet.Trace.trace_ds(" Character");
                break;

            default:
                telnet.Trace.trace_ds(" unknown mode 0x%02x\n", buffer[4]);
                return(PDS.BadCommand);
            }

            replyMode = buffer[4];
            if (buffer[4] == Codes.Character)
            {
                telnet.Controller.CrmnAttribute = bufferLength - 5;
                for (i = 5; i < bufferLength; i++)
                {
                    telnet.Controller.CrmAttributes[i - 5] = buffer[i];
                    telnet.Trace.trace_ds("%s%s", comma, See.GetEfaOnly(buffer[i]));
                    comma = ",";
                }
                telnet.Trace.trace_ds("%s\n", telnet.Controller.CrmnAttribute != 0 ? ")" : "");
            }
            return(PDS.OkayNoOutput);
        }
        private void DoQueryReplay(NetBuffer obptr, byte code)
        {
            int i;
            var comma = "";
            var obptr0 = obptr.Index;
            int num, denom;

            if (QrInProgress)
            {
                telnet.Trace.trace_ds("> StructuredField\n");
                QrInProgress = false;
            }

            obptr.Add16(0);
            obptr.Add(See.SFID_QREPLY);
            obptr.Add(code);

            switch (code)
            {
            case See.QR_CHARSETS:
            {
                telnet.Trace.trace_ds("> QueryReply(CharacterSets)\n");

                obptr.Add(0x82);  /* flags: GE, CGCSGID present */
                obptr.Add(0x00);  /* more flags */
                obptr.Add(7);     /* SDW */
                obptr.Add(7);     /* SDH */
                obptr.Add(0x00);  /* Load PS format types */
                obptr.Add(0x00);
                obptr.Add(0x00);
                obptr.Add(0x00);
                obptr.Add(0x07);      /* DL */
                obptr.Add(0x00);      /* SET 0: */
                obptr.Add(0x10);      /*  FLAGS: non-loadable, single-plane, single-byte, no compare */
                obptr.Add(0x00);      /*  LCID */
                obptr.Add32(cgcsgid); /*  CGCSGID */

                // TODO: Missing font stuff for extended font information
                break;
            }

            case See.QR_IMP_PART:
            {
                telnet.Trace.trace_ds("> QueryReply(ImplicitPartition)\n");
                obptr.Add(0x0);                            /* reserved */
                obptr.Add(0x0);
                obptr.Add(0x0b);                           /* length of display size */
                obptr.Add(0x01);                           /* "implicit partition size" */
                obptr.Add(0x00);                           /* reserved */
                obptr.Add16(80);                           /* implicit partition width */
                obptr.Add16(24);                           /* implicit partition height */
                obptr.Add16(telnet.Controller.MaxColumns); /* alternate height */
                obptr.Add16(telnet.Controller.MaxRows);    /* alternate width */
                break;
            }

            case See.QR_NULL:
            {
                telnet.Trace.trace_ds("> QueryReply(Null)\n");
                break;
            }

            case See.QR_SUMMARY:
            {
                telnet.Trace.trace_ds("> QueryReply(Summary(");
                for (i = 0; i < NSR; i++)
                {
                    telnet.Trace.trace_ds("%s%s", comma, See.GetQCodeode(SupportedReplies[i]));
                    comma = ",";
                    obptr.Add(SupportedReplies[i]);
                }
                telnet.Trace.trace_ds("))\n");
                break;
            }

            case See.QR_USABLE_AREA:
            {
                telnet.Trace.trace_ds("> QueryReply(UsableArea)\n");
                obptr.Add(0x01);                           /* 12/14-bit addressing */
                obptr.Add(0x00);                           /* no special character features */
                obptr.Add16(telnet.Controller.MaxColumns); /* usable width */
                obptr.Add16(telnet.Controller.MaxRows);    /* usable height */
                obptr.Add(0x01);                           /* units (mm) */
                num   = 100;
                denom = 1;
                while (0 == num % 2 && 0 == denom % 2)
                {
                    num   /= 2;
                    denom /= 2;
                }
                obptr.Add16(num);     /* Xr numerator */
                obptr.Add16(denom);   /* Xr denominator */
                num   = 100;
                denom = 1;
                while (0 == num % 2 && 0 == denom % 2)
                {
                    num   /= 2;
                    denom /= 2;
                }
                obptr.Add16(num);                                                      /* Yr numerator */
                obptr.Add16(denom);                                                    /* Yr denominator */
                obptr.Add(7);                                                          /* AW */
                obptr.Add(7);                                                          /* AH */
                obptr.Add16(telnet.Controller.MaxColumns * telnet.Controller.MaxRows); /* buffer, questionable */
                break;
            }

            case See.QR_COLOR:
            {
                telnet.Trace.trace_ds("> QueryReply(Color)\n");
                obptr.Add(0x00);                          /* no options */
                obptr.Add(telnet.Appres.color8 ? 8 : 16); /* report on 8 or 16 colors */
                obptr.Add(0x00);                          /* default color: */
                obptr.Add(0xf0 + See.COLOR_GREEN);        /*  green */
                for (i = 0xf1; i <= (telnet.Appres.color8 ? 0xf8 : 0xff); i++)
                {
                    obptr.Add(i);
                    if (telnet.Appres.m3279)
                    {
                        obptr.Add(i);
                    }
                    else
                    {
                        obptr.Add(0x00);
                    }
                }
                break;
            }

            case See.QR_HIGHLIGHTING:
            {
                telnet.Trace.trace_ds("> QueryReply(Highlighting)\n");
                obptr.Add(5);                  /* report on 5 pairs */
                obptr.Add(See.XAH_DEFAULT);    /* default: */
                obptr.Add(See.XAH_NORMAL);     /*  normal */
                obptr.Add(See.XAH_BLINK);      /* blink: */
                obptr.Add(See.XAH_BLINK);      /*  blink */
                obptr.Add(See.XAH_REVERSE);    /* reverse: */
                obptr.Add(See.XAH_REVERSE);    /*  reverse */
                obptr.Add(See.XAH_UNDERSCORE); /* underscore: */
                obptr.Add(See.XAH_UNDERSCORE); /*  underscore */
                obptr.Add(See.XAH_INTENSIFY);  /* intensify: */
                obptr.Add(See.XAH_INTENSIFY);  /*  intensify */
                break;
            }

            case See.QR_REPLY_MODES:
            {
                telnet.Trace.trace_ds("> QueryReply(ReplyModes)\n");
                obptr.Add(Codes.Field);
                obptr.Add(Codes.ExtendedField);
                obptr.Add(Codes.Character);
                break;
            }

            case See.QR_ALPHA_PART:
            {
                telnet.Trace.trace_ds("> QueryReply(AlphanumericPartitions)\n");
                obptr.Add(0);                                                          /* 1 partition */
                obptr.Add16(telnet.Controller.MaxRows * telnet.Controller.MaxColumns); /* buffer space */
                obptr.Add(0);                                                          /* no special features */
                break;
            }

            default:
            {
                // Internal error
                return;
            }
            }
            obptr.Add16At(obptr0, obptr.Index - obptr0);
        }
        private PDS ReadPart(byte[] buffer, int bufferLength)
        {
            byte partition;

            var       any   = 0;
            var       comma = "";
            NetBuffer obptr = null;

            if (bufferLength < 5)
            {
                telnet.Trace.trace_ds(" error: field length %d too small\n", bufferLength);
                return(PDS.BadCommand);
            }

            partition = buffer[3];
            telnet.Trace.trace_ds("(0x%02x)", partition);

            switch (buffer[4])
            {
            case Codes.Query:
            {
                telnet.Trace.trace_ds(" Query");

                if (partition != 0xff)
                {
                    telnet.Trace.trace_ds(" error: illegal partition\n");
                    return(PDS.BadCommand);
                }

                telnet.Trace.trace_ds("\n");
                obptr = QueryReplyStart();

                for (var i = 0; i < NSR; i++)
                {
                    DoQueryReplay(obptr, SupportedReplies[i]);
                }

                QueryReplyEnd(obptr);

                break;
            }

            case Codes.QueryList:
            {
                telnet.Trace.trace_ds(" QueryList ");

                if (partition != 0xff)
                {
                    telnet.Trace.trace_ds("error: illegal partition\n");
                    return(PDS.BadCommand);
                }

                if (bufferLength < 6)
                {
                    telnet.Trace.trace_ds("error: missing request type\n");
                    return(PDS.BadCommand);
                }

                obptr = QueryReplyStart();

                switch (buffer[5])
                {
                case Codes.QCodeList:
                {
                    telnet.Trace.trace_ds("List(");

                    if (bufferLength < 7)
                    {
                        telnet.Trace.trace_ds(")\n");
                        DoQueryReplay(obptr, See.QR_NULL);
                    }
                    else
                    {
                        for (var i = 6; i < bufferLength; i++)
                        {
                            telnet.Trace.trace_ds("%s%s", comma, See.GetQCodeode(buffer[i]));
                            comma = ",";
                        }

                        telnet.Trace.trace_ds(")\n");

                        for (var i = 0; i < NSR; i++)
                        {
                            var found = false;

                            for (var pos = 0; pos < bufferLength - 6; pos++)
                            {
                                if (buffer[pos + 6] == SupportedReplies[i])
                                {
                                    found = true;
                                }
                            }

                            if (found)
                            {
                                DoQueryReplay(obptr, SupportedReplies[i]);
                                any++;
                            }
                        }

                        if (any == 0)
                        {
                            DoQueryReplay(obptr, See.QR_NULL);
                        }
                    }
                    break;
                }

                case Codes.EquivQCodeList:
                {
                    telnet.Trace.trace_ds("Equivlent+List(");
                    for (var i = 6; i < bufferLength; i++)
                    {
                        telnet.Trace.trace_ds("%s%s", comma, See.GetQCodeode(buffer[i]));
                        comma = ",";
                    }
                    telnet.Trace.trace_ds(")\n");
                    for (var i = 0; i < NSR; i++)
                    {
                        DoQueryReplay(obptr, SupportedReplies[i]);
                    }
                    break;
                }

                case Codes.All:
                {
                    telnet.Trace.trace_ds("All\n");
                    for (var i = 0; i < NSR; i++)
                    {
                        DoQueryReplay(obptr, SupportedReplies[i]);
                    }
                    break;
                }

                default:
                {
                    telnet.Trace.trace_ds("unknown request type 0x%02x\n", buffer[5]);
                    return(PDS.BadCommand);
                }
                }
                QueryReplyEnd(obptr);
                break;
            }

            case ControllerConstant.SNA_CMD_RMA:
            {
                telnet.Trace.trace_ds(" ReadModifiedAll");
                if (partition != 0x00)
                {
                    telnet.Trace.trace_ds(" error: illegal partition\n");
                    return(PDS.BadCommand);
                }
                telnet.Trace.trace_ds("\n");
                telnet.Controller.ProcessReadModifiedCommand(AID.QReply, true);
                break;
            }

            case ControllerConstant.SNA_CMD_RB:
            {
                telnet.Trace.trace_ds(" ReadBuffer");
                if (partition != 0x00)
                {
                    telnet.Trace.trace_ds(" error: illegal partition\n");
                    return(PDS.BadCommand);
                }
                telnet.Trace.trace_ds("\n");
                telnet.Controller.ProcessReadBufferCommand(AID.QReply);
                break;
            }

            case ControllerConstant.SNA_CMD_RM:
            {
                telnet.Trace.trace_ds(" ReadModified");
                if (partition != 0x00)
                {
                    telnet.Trace.trace_ds(" error: illegal partition\n");
                    return(PDS.BadCommand);
                }
                telnet.Trace.trace_ds("\n");
                telnet.Controller.ProcessReadModifiedCommand(AID.QReply, false);
                break;
            }

            default:
            {
                telnet.Trace.trace_ds(" unknown type 0x%02x\n", buffer[4]);
                return(PDS.BadCommand);
            }
            }
            return(PDS.OkayOutput);
        }