예제 #1
0
        /// <summary>
        /// Returns VAT and VATless fees
        /// </summary>
        /// <returns></returns>
        public string ToString(ShowFormat fmt)
        {
            if (fmt == ShowFormat.withoutVAT)
            {
                return(String.Format(new NumberFormatInfo(), $"{VATLess,10:C2}"));
            }
            else if (fmt == ShowFormat.withVAT)
            {
                return(String.Format(new NumberFormatInfo(), $"{WithVAT,10:C2}"));
            }

            return(String.Format(new NumberFormatInfo(), $"{VATLess,10:C2} / {WithVAT,10:C2}"));
        }
예제 #2
0
        /// <summary>
        /// Main execution
        /// </summary>
        public string Disassemble(ref ushort OpCodeAddress)
        {
            ushort     Address;
            ushort     IOAddress;
            byte       opcode;
            ShowFormat DataFormat = ShowFormat.Decimal;

            // Fetch next instruction
            opcode = _Memory.ReadByte(OpCodeAddress++);


            if (opcode == 0x76)                         // HALT
            {
                // The first check is for HALT otherwise it could be
                // interpreted as LD (HL),(HL)
                return("HALT");
            }
            else if ((opcode & 0xC0) == 0x40)                   // LD r,r
            {
                string reg1 = GetHalfRegister((byte)(opcode >> 3));
                string reg2 = GetHalfRegister(opcode);

                return(string.Format("LD {0},{1}", reg1, reg2));
            }
            else if ((opcode & 0xC0) == 0x80)
            {
                // Operation beetween accumulator and other registers
                // Usually are identified by 10 ooo rrr where ooo is the operation and rrr is the source register
                string reg = GetHalfRegister(opcode);

                switch (opcode & 0xF8)
                {
                case 0x80:                              // ADD A,r
                    return(string.Format("ADD A,{0}", reg));

                case 0x88:                              // ADC A,r
                    return(string.Format("ADC A,{0}", reg));

                case 0x90:                              // SUB r
                    return(string.Format("SUB {0}", reg));

                case 0x98:                              // SBC A,r
                    return(string.Format("SBC A,{0}", reg));

                case 0xA0:                              // AND r
                    return(string.Format("AND {0}", reg));

                case 0xA8:                              // XOR r
                    return(string.Format("XOR {0}", reg));

                case 0xB0:                          // OR r
                    return(string.Format("OR {0}", reg));

                case 0xB8:                              // CP r
                    return(string.Format("CP {0}", reg));

                default:
                    throw new Exception("Wrong place in the right time...");
                }
            }
            else if ((opcode & 0xC7) == 0x04)             // INC r
            {
                string reg = GetHalfRegister((byte)(opcode >> 3));
                return(string.Format("INC {0}", reg));
            }
            else if ((opcode & 0xC7) == 0x05)             // DEC r
            {
                string reg = GetHalfRegister((byte)(opcode >> 3));
                return(string.Format("DEC {0}", reg));
            }
            else if ((opcode & 0xC7) == 0x06)             // LD r,nn
            {
                string reg   = GetHalfRegister((byte)(opcode >> 3));
                byte   Value = _Memory.ReadByte(OpCodeAddress++);
                return(string.Format("LD {0},{1}", reg, ShowData(Value)));
            }
            else if ((opcode & 0xC7) == 0xC0)             // RET cc
            {
                return(string.Format("RET {0}", CheckFlag(opcode)));
            }
            else if ((opcode & 0xC7) == 0xC2)             // JP cc,nn
            {
                Address = _Memory.ReadWord(OpCodeAddress);
                string retValue = string.Format("JP {0},{1}", CheckFlag(opcode), ShowData(Address));
                OpCodeAddress += 2;
                return(retValue);
            }
            else if ((opcode & 0xC7) == 0xC4)             // CALL cc,nn
            {
                Address = _Memory.ReadWord(OpCodeAddress);
                string retValue = string.Format("JP {0},{1}", CheckFlag(opcode), ShowData(Address));
                OpCodeAddress += 2;
                return(retValue);
            }
            else if ((opcode & 0xC7) == 0xC7)             // RST p
            {
                return(string.Format("RST {0}", ShowData((opcode & 0x38))));
            }
            else if ((opcode & 0xCF) == 0x01)             // LD dd,nn
            {
                string reg   = GetRegister(opcode, true);
                ushort Value = _Memory.ReadWord(OpCodeAddress);
                OpCodeAddress += 2;
                return(string.Format("LD {0},{1}", reg, ShowData(Value)));
            }
            else if ((opcode & 0xCF) == 0x03)             // INC ss
            {
                string reg = GetRegister(opcode, true);
                return(string.Format("INC {0}", reg));
            }
            else if ((opcode & 0xCF) == 0x09)             // ADD HL,ss
            {
                string reg = GetRegister(opcode, true);
                return(string.Format("ADD HL,{0}", reg));
            }
            else if ((opcode & 0xCF) == 0x0B)             // DEC ss
            {
                string reg = GetRegister(opcode, true);
                return(string.Format("DEC {0}", reg));
            }
            else if ((opcode & 0xCF) == 0xC5)             // PUSH qq
            {
                string reg = GetRegister(opcode, false);
                return(string.Format("PUSH {0}", reg));
            }

            else if ((opcode & 0xCF) == 0xC1)             // POP qq
            {
                string reg = GetRegister(opcode, false);
                return(string.Format("POP {0}", reg));
            }
            else
            {
                switch (opcode)
                {
                case 0x00:                                      // NOP
                    return("NOP");

                case 0x02:                                      // LD (BC),A
                    return("LD (BC),A");

                case 0x07:                                      // RLCA
                    return("RLCA");

                case 0x08:                                      // EX AF,AF'
                    return("EX AF,AF'");

                case 0x0A:                                      // LD A,(BC)
                    return("LD A,(BC)");

                case 0x0F:                                      // RRCA
                    return("RRCA");

                case 0x10:                                      // DJNZ offset
                    return(string.Format("DJNZ {0}", ShowData((sbyte)_Memory.ReadByte(OpCodeAddress++) + OpCodeAddress)));

                case 0x12:                                      // LD (DE),A
                    return("LD (DE),A");

                case 0x17:                                      // RLA
                    return("RLA");

                case 0x18:                                      // JR offset
                    return(string.Format("JR {0}", ShowData((sbyte)_Memory.ReadByte(OpCodeAddress++) + OpCodeAddress)));

                case 0x1A:                                      // LD A,(DE)
                    return("LD A,(DE)");

                case 0x1F:                                      // RRA
                    return("RRA");

                case 0x20:                                      // JR NZ,offset
                    return(string.Format("JR NZ,{0}", ShowData((sbyte)_Memory.ReadByte(OpCodeAddress++) + OpCodeAddress)));

                case 0x22:                                      // LD (nnnn),HL
                    Address        = _Memory.ReadWord(OpCodeAddress);
                    OpCodeAddress += 2;
                    return(string.Format("LD ({0}),HL", ShowData(Address)));

                case 0x27:                                      // DAA
                    return("DAA");

                case 0x28:                                      // JR Z,offset
                    return(string.Format("JR Z,{0}", ShowData((sbyte)_Memory.ReadByte(OpCodeAddress++) + OpCodeAddress)));

                case 0x2A:                                      // LD HL,(nnnn)
                    Address        = _Memory.ReadWord(OpCodeAddress);
                    OpCodeAddress += 2;
                    return(string.Format("LD HL,({0})", ShowData(Address)));

                case 0x2F:                                      // CPL
                    return("CPL");

                case 0x30:                                      // JR NC,offset
                    return(string.Format("JR NC,{0}", ShowData((sbyte)_Memory.ReadByte(OpCodeAddress++) + OpCodeAddress)));

                case 0x32:                                      // LD (nnnn),A
                    Address        = _Memory.ReadWord(OpCodeAddress);
                    OpCodeAddress += 2;
                    return(string.Format("LD ({0}),A", ShowData(Address)));

                case 0x37:                                      // SCF
                    return("SCF");

                case 0x38:                                      // JR C,offset
                    return(string.Format("JR C,{0}", ShowData((sbyte)_Memory.ReadByte(OpCodeAddress++) + OpCodeAddress)));

                case 0x3A:                                      // LD A,(nnnn)
                    Address        = _Memory.ReadWord(OpCodeAddress);
                    OpCodeAddress += 2;
                    return(string.Format("LD A,({0})", ShowData(Address)));

                case 0x3F:                                      // CCF
                    return("CCF");

                case 0xC3:                                      // JP nnnn
                    Address        = _Memory.ReadWord(OpCodeAddress);
                    OpCodeAddress += 2;
                    return(string.Format("JP {0}", ShowData(Address)));

                case 0xC6:                                      // ADD A,nn
                    return(string.Format("ADD A,{0}", ShowData(_Memory.ReadByte(OpCodeAddress++))));

                case 0xC9:                                      // RET
                    return("RET");

                case 0xCB:                                      // CBxx opcodes
                    return(Disassemble_CB(_Memory.ReadByte(OpCodeAddress++)));

                case 0xCD:                                      // CALL nnnn
                    Address        = _Memory.ReadWord(OpCodeAddress);
                    OpCodeAddress += 2;
                    return(string.Format("CALL {0}", ShowData(Address)));

                case 0xCE:                                      // ADC A,nn
                    return(string.Format("ADC A,{0}", ShowData(_Memory.ReadByte(OpCodeAddress++))));

                case 0xD3:                                      // OUT (nn),A
                    IOAddress = _Memory.ReadByte(OpCodeAddress++);
                    return(string.Format("OUT ({0}),A", ShowData(IOAddress)));

                case 0xD6:                                      // SUB nn
                    return(string.Format("SUB {0}", _Memory.ReadByte(OpCodeAddress++)));

                case 0xD9:                                      // EXX
                    // Each 2-byte value in register pairs BC, DE, and HL is exchanged with the
                    // 2-byte value in BC', DE', and HL', respectively.
                    return("EXX");

                case 0xDB:                                      // IN A,(nn)
                    // The operand n is placed on the bottom half (A0 through A7) of the address
                    // bus to select the I/O device at one of 256 possible ports. The contents of the
                    // Accumulator also appear on the top half (A8 through A15) of the address
                    // bus at this time. Then one byte from the selected port is placed on the data
                    // bus and written to the Accumulator (register A) in the CPU.
                    IOAddress = _Memory.ReadByte(OpCodeAddress++);
                    return(string.Format("IN A,({0})", ShowData(IOAddress)));

                case 0xDD:                                      // DDxx opcodes
                    return(Disassemble_DDFD("IX", ref OpCodeAddress));

                case 0xDE:                                      // SBC A,nn
                    return(string.Format("SBC A,{0}", _Memory.ReadByte(OpCodeAddress++)));

                case 0xE3:                                      // EX (SP),HL
                    return("EX (SP),HL");

                case 0xE6:                                      // AND nn
                    return(string.Format("AND {0}", _Memory.ReadByte(OpCodeAddress++)));

                case 0xE9:                                      // JP HL
                    return("JP HL");

                case 0xEB:                                      // EX DE,HL
                    return("EX DE,HL");

                case 0xed:                                      // EDxx opcodes
                    return(Disassemble_ED(ref OpCodeAddress));

                case 0xEE:                                      // XOR A,nn
                    return(string.Format("XOR A,{0}", _Memory.ReadByte(OpCodeAddress++)));

                case 0xF3:                                      // DI
                    return("DI");

                case 0xF6:                                      // OR nn
                    return(string.Format("OR {0}", _Memory.ReadByte(OpCodeAddress++)));

                case 0xF9:                                      // LD SP,HL
                    return("LD SP,HL");

                case 0xFB:                                      // EI
                    return("EI");

                case 0xFD:                                      // FDxx opcodes
                    return(Disassemble_DDFD("IY", ref OpCodeAddress));

                case 0xFE:                                      // CP nn
                    return(string.Format("CP {0}", _Memory.ReadByte(OpCodeAddress++)));

                default:
                    throw new Exception(string.Format("Internal disassembler error. Opcode {0} not implemented.", opcode));
                }
            }
        }