예제 #1
0
        public void EncodeOp(List<Byte> rom, OpEncodeOptions opt)
        {
            switch (op)
            {
                case Instructions.LD:
                    //No pattern given to some LOAD inst
                    if (src.isMem)
                    {
                        switch (src.loc)
                        {
                            case Locations.BC:
                                rom.Add(0x02);
                                break;
                            case Locations.DE:
                                rom.Add(0x12);
                                break;
                            case Locations.HL:
                                if (dst.loc >= Locations.B && dst.loc <= Locations.A)
                                {
                                    rom.Add(GetLinearOffset(dst, 0x70));
                                }
                                else
                                {
                                    rom.Add(0x36);
                                }
                                break;
                            case Locations.SP:
                                if (dst.loc == Locations.HL)
                                {
                                    rom.Add(0xF9);
                                }
                                else
                                {
                                    //encode_dst = true;
                                    rom.Add(0x31);
                                }
                                break;
                            case Locations.C:
                                rom.Add(0xE2);
                                break;
                            case Locations.WIDE_IMM:
                                src.isWide = true;
                                if (dst.loc == Locations.SP)
                                {
                                    rom.Add(0x08);
                                }
                                break;
                            case Locations.IMM:
                                rom.Add(0xEA);
                                break;
                            default:
                                break;
                        }
                    }
                    else
                    {
                        //Not loading into memory
                        if (dst.loc >= Locations.B && dst.loc <= Locations.A)
                        {
                            switch (src.loc)
                            {
                                case Locations.B:
                                    rom.Add(GetLinearOffset(dst, 0x40));
                                    break;
                                case Locations.C:
                                    rom.Add(GetLinearOffset(dst, 0x48));
                                    break;
                                case Locations.D:
                                    rom.Add(GetLinearOffset(dst, 0x50));
                                    break;
                                case Locations.E:
                                    rom.Add(GetLinearOffset(dst, 0x58));
                                    break;
                                case Locations.H:
                                    rom.Add(GetLinearOffset(dst, 0x60));
                                    break;
                                case Locations.L:
                                    rom.Add(GetLinearOffset(dst, 0x68));
                                    break;
                                case Locations.A:
                                    if (dst.isMem && dst.loc == Locations.C)
                                    {
                                        rom.Add(0xF2);
                                    }
                                    else
                                    {
                                        rom.Add(GetLinearOffset(dst, 0x78));
                                    }
                                    break;
                                case Locations.SP:
                                    if(dst.loc == Locations.HL)
                                    {
                                        rom.Add(0xF9);
                                    }
                                    else
                                    {
                                        rom.Add(0x31);
                                    }
                                    break;
                                default:
                                    break;
                            }
                        }
                        else
                        {
                            switch (src.loc)
                            {
                                case Locations.B:
                                    rom.Add(0x06);
                                    break;
                                case Locations.C:
                                    rom.Add(0x0E);
                                    break;
                                case Locations.D:
                                    rom.Add(0x16);
                                    break;
                                case Locations.E:
                                    rom.Add(0x1E);
                                    break;
                                case Locations.H:
                                    rom.Add(0x26);
                                    break;
                                case Locations.L:
                                    rom.Add(0x2E);
                                    break;
                                case Locations.A:
                                    if (dst.isMem)
                                    {
                                        switch (dst.loc)
                                        {
                                            case Locations.BC:
                                                rom.Add(0x0A);
                                                break;
                                            case Locations.DE:
                                                rom.Add(0x1A);
                                                break;
                                            case Locations.HL:
                                                rom.Add(0x7E);
                                                break;
                                            case Locations.WIDE_IMM:
                                            case Locations.IMM:
                                                rom.Add(0xFA);
                                                break;
                                            case Locations.C:
                                                rom.Add(0xF2);
                                                break;
                                            default:
                                                break;
                                        }
                                    }
                                    else
                                    {
                                        rom.Add(0x3E);
                                    }
                                    break;
                                case Locations.BC:
                                    rom.Add(0x01);
                                    dst.isWide = true;

                                    break;
                                case Locations.DE:
                                    rom.Add(0x11);
                                    dst.isWide = true;
                                    break;
                                case Locations.HL:
                                    if (dst.loc != Locations.OFFSET)
                                    {
                                        rom.Add(0x21);
                                        dst.isWide = true;
                                    }
                                    else
                                    {
                                        rom.Add(0xF8);
                                        opt.encode_dst = true;
                                        dst.isWide = false;
                                    }
                                    break;
                                case Locations.SP:
                                    rom.Add(0x31);
                                    dst.isWide = true;
                                    break;
                            }
                        }

                    }

                    break;
                case Instructions.JR:
                    if (src.isFlag || src.loc == Locations.C)
                    {
                        dst.isWide = false;
                        switch (src.loc)
                        {
                            case Locations.NZ:
                                rom.Add(0x20);
                                break;
                            case Locations.NC:
                                rom.Add(0x30);
                                break;
                            case Locations.C:
                                rom.Add(0x38);
                                break;
                            case Locations.Z:
                                rom.Add(0x28);
                                break;
                            default:
                                break;
                        }
                    }
                    else
                    {
                        rom.Add(0x18);
                        src.isWide = false;
                    }
                    break;
                case Instructions.JP:
                    if (src.isFlag || src.loc == Locations.C)
                    {
                        dst.isWide = true;
                        switch (src.loc)
                        {
                            case Locations.NZ:
                                rom.Add(0xC2);
                                break;
                            case Locations.NC:
                                rom.Add(0xD2);
                                break;
                            case Locations.C:
                                rom.Add(0xDA);
                                break;
                            case Locations.Z:
                                rom.Add(0xCA);
                                break;
                            default:
                                break;
                        }
                    }
                    else if (src.isMem)
                    {
                        rom.Add(0xE9);
                    }
                    else
                    {
                        src.isWide = true;
                        rom.Add(0xC3);
                    }
                    break;
                case Instructions.OR:
                    switch (src.loc)
                    {
                        case Locations.B:
                        case Locations.C:
                        case Locations.D:
                        case Locations.E:
                        case Locations.H:
                        case Locations.L:
                        case Locations.HL:
                        case Locations.A:
                            rom.Add(GetLinearOffset(src, 0xB0));
                            break;
                        case Locations.IMM:
                            rom.Add(0xF6);
                            break;

                    }
                    break;
                case Instructions.CP:
                    switch (src.loc)
                    {
                        case Locations.B:
                        case Locations.C:
                        case Locations.D:
                        case Locations.E:
                        case Locations.H:
                        case Locations.L:
                        case Locations.HL:
                        case Locations.A:
                            rom.Add(GetLinearOffset(src, 0xB8));
                            break;
                        case Locations.IMM:
                            rom.Add(0xFE);
                            break;

                    }
                    break;
                case Instructions.RL:
                    rom.Add(0xCB);
                    rom.Add(GetLinearOffset(src, 0x10));
                    break;
                case Instructions.RR:
                    rom.Add(0xCB);
                    rom.Add(GetLinearOffset(src, 0x18));
                    break;
                case Instructions.DI:
                    rom.Add(0xF3);
                    break;
                case Instructions.EI:
                    rom.Add(0xFB);
                    break;
                case Instructions.LDD:
                    if (src.loc == Locations.A)
                    {
                        rom.Add(0x3A);
                    }
                    else
                    {
                        rom.Add(0x32);
                    }
                    break;
                case Instructions.LDI:
                    if (src.loc == Locations.A)
                    {
                        rom.Add(0x2A);
                    }
                    else
                    {
                        rom.Add(0x22);
                    }
                    break;
                case Instructions.ADD:
                    if (src.loc != Locations.HL && dst.isMem)
                    {
                        rom.Add(0x86);
                        break;
                    }
                    else
                    {
                        switch (dst.loc)
                        {
                            case Locations.B:
                            case Locations.C:
                            case Locations.D:
                            case Locations.E:
                            case Locations.H:
                            case Locations.L:
                            case Locations.A:
                                rom.Add(GetLinearOffset(dst, 0x80));
                                break;
                            case Locations.IMM:
                            case Locations.WIDE_IMM:
                                if (src.loc == Locations.A)
                                {
                                    rom.Add(0xC6);
                                }
                                else if (src.loc == Locations.SP)
                                {
                                    rom.Add(0xE8);
                                }
                                opt.encode_dst = true;
                                break;

                            case Locations.SP:
                                rom.Add(0x39);
                                break;
                            case Locations.HL:
                                rom.Add(0x29);
                                break;
                            case Locations.DE:
                                rom.Add(0x19);
                                break;
                            case Locations.BC:
                                rom.Add(0x09);
                                break;

                        }
                    }

                    break;
                case Instructions.ADC:
                    switch (dst.loc)
                    {
                        case Locations.B:
                        case Locations.C:
                        case Locations.D:
                        case Locations.E:
                        case Locations.H:
                        case Locations.L:
                        case Locations.HL:
                        case Locations.A:
                            rom.Add(GetLinearOffset(dst, 0x88));
                            break;
                        case Locations.IMM:
                            rom.Add(0xCE);
                            break;

                    }
                    break;
                case Instructions.SBC:
                    switch (dst.loc)
                    {
                        case Locations.B:
                        case Locations.C:
                        case Locations.D:
                        case Locations.E:
                        case Locations.H:
                        case Locations.L:
                        case Locations.HL:
                        case Locations.A:
                            rom.Add(GetLinearOffset(dst, 0x98));
                            break;
                        case Locations.IMM:
                            rom.Add(0xDE);
                            break;

                    }
                    break;
                case Instructions.BIT:
                    rom.Add(0xCB);
                    rom.Add(GetTableOffset(src, dst, 0x40));
                    opt.encode_src = false;
                    break;
                case Instructions.RES:
                    rom.Add(0xCB);
                    rom.Add(GetTableOffset(src, dst, 0x80));
                    opt.encode_src = false;
                    break;
                case Instructions.SET:
                    rom.Add(0xCB);
                    rom.Add(GetTableOffset(src, dst, 0xC0));
                    opt.encode_src = false;
                    break;
                case Instructions.RET:
                    if (src.isFlag || src.loc == Locations.C)
                    {
                        switch (src.loc)
                        {
                            case Locations.NC:
                                rom.Add(0xD0);
                                break;
                            case Locations.NZ:
                                rom.Add(0xC0);
                                break;
                            case Locations.C:
                                rom.Add(0xD8);
                                break;
                            case Locations.Z:
                                rom.Add(0xC8);
                                break;
                            default:
                                break;
                        }
                    }
                    else
                    {
                        rom.Add(0xC9);
                    }
                    break;
                case Instructions.INC:
                    if (src.isMem)
                    {
                        rom.Add(0x34);
                    }
                    else
                    {
                        switch (src.loc)
                        {
                            case Locations.BC:
                                rom.Add(0x03);
                                break;
                            case Locations.DE:
                                rom.Add(0x13);
                                break;
                            case Locations.HL:
                                rom.Add(0x23);
                                break;
                            case Locations.SP:
                                rom.Add(0x33);
                                break;
                            case Locations.B:
                                rom.Add(0x04);
                                break;
                            case Locations.D:
                                rom.Add(0x14);
                                break;
                            case Locations.H:
                                rom.Add(0x24);
                                break;
                            case Locations.C:
                                rom.Add(0x0C);
                                break;
                            case Locations.L:
                                rom.Add(0x2C);
                                break;
                            case Locations.E:
                                rom.Add(0x1C);
                                break;
                            case Locations.A:
                                rom.Add(0x3C);
                                break;
                            default:
                                break;
                        }
                    }
                    break;
                case Instructions.DEC:
                    if (src.isMem)
                    {
                        rom.Add(0x35);
                    }
                    else
                    {
                        switch (src.loc)
                        {
                            case Locations.BC:

                                rom.Add(0x0B);
                                break;
                            case Locations.DE:
                                rom.Add(0x1B);
                                break;
                            case Locations.HL:
                                rom.Add(0x2B);
                                break;
                            case Locations.SP:
                                rom.Add(0x3B);
                                break;
                            case Locations.B:
                                rom.Add(0x05);
                                break;
                            case Locations.D:
                                rom.Add(0x15);
                                break;
                            case Locations.H:
                                rom.Add(0x25);
                                break;
                            case Locations.C:
                                rom.Add(0x0D);
                                break;
                            case Locations.L:
                                rom.Add(0x2D);
                                break;
                            case Locations.E:
                                rom.Add(0x1D);
                                break;
                            case Locations.A:
                                rom.Add(0x3D);
                                break;
                            default:
                                break;
                        }
                    }
                    break;
                case Instructions.SUB:
                    switch (src.loc)
                    {
                        case Locations.B:
                        case Locations.C:
                        case Locations.D:
                        case Locations.E:
                        case Locations.H:
                        case Locations.L:
                        case Locations.HL:
                        case Locations.A:
                            rom.Add(GetLinearOffset(src, 0x90));
                            break;
                        case Locations.IMM:
                            rom.Add(0xD6);
                            break;

                    }
                    break;
                case Instructions.AND:
                    switch (src.loc)
                    {
                        case Locations.B:
                        case Locations.C:
                        case Locations.D:
                        case Locations.E:
                        case Locations.H:
                        case Locations.L:
                        case Locations.HL:
                        case Locations.A:
                            rom.Add(GetLinearOffset(src, 0xA0));
                            break;
                        case Locations.IMM:
                            rom.Add(0xE6);
                            break;

                    }
                    break;
                case Instructions.XOR:
                    switch (src.loc)
                    {
                        case Locations.B:
                        case Locations.C:
                        case Locations.D:
                        case Locations.E:
                        case Locations.H:
                        case Locations.L:
                        case Locations.HL:
                        case Locations.A:
                            rom.Add(GetLinearOffset(src, 0xA8));
                            break;
                        case Locations.IMM:
                            rom.Add(0xEE);
                            break;

                    }
                    break;
                case Instructions.RLC:
                    rom.Add(0xCB);
                    rom.Add(GetLinearOffset(src, 0x00));
                    break;
                case Instructions.RRC:
                    rom.Add(0xCB);
                    rom.Add(GetLinearOffset(src, 0x08));
                    break;
                case Instructions.POP:
                    rom.Add(GetBlockOffset(src, 0xC1));
                    break;
                case Instructions.SLA:
                    rom.Add(0xCB);
                    rom.Add(GetLinearOffset(src, 0x20));
                    break;
                case Instructions.SRA:
                    rom.Add(0xCB);
                    rom.Add(GetLinearOffset(src, 0x28));
                    break;
                case Instructions.SRL:
                    rom.Add(0xCB);
                    rom.Add(GetLinearOffset(src, 0x38));
                    break;
                case Instructions.NOP:
                    rom.Add(0x00);
                    break;
                case Instructions.RLA:
                    rom.Add(0x17);
                    break;
                case Instructions.RRA:
                    rom.Add(0x1F);
                    break;
                case Instructions.DAA:
                    rom.Add(0x27);
                    break;
                case Instructions.CPL:
                    rom.Add(0x2F);
                    break;
                case Instructions.SCF:
                    rom.Add(0x37);
                    break;
                case Instructions.CCF:
                    rom.Add(0x3F);
                    break;
                case Instructions.LDH:
                    if (src.loc == Locations.A)
                    {
                        rom.Add(0xF0);
                    }
                    else
                    {
                        rom.Add(0xE0);
                    }
                    break;
                case Instructions.RST:
                    if (src.val % 0x10 == 0)
                    {
                        rom.Add((Byte)(0xC7 + src.val));
                    }
                    else
                    {
                        rom.Add((Byte)(0xCF + src.val - 0x08));
                    }
                    opt.encode_src = false;
                    break;
                case Instructions.CALL:
                    {
                        if (src.loc == Locations.NZ)
                        {
                            dst.isWide = true;
                            rom.Add(0xC4);
                        }
                        else if (src.loc == Locations.NC)
                        {
                            dst.isWide = true;
                            rom.Add(0xD4);
                        }
                        else if (src.loc == Locations.Z)
                        {
                            dst.isWide = true;
                            rom.Add(0xCC);
                        }
                        else if (src.loc == Locations.C)
                        {
                            dst.isWide = true;
                            rom.Add(0xDC);
                        }
                        else
                        {
                            rom.Add(0xCD);
                            src.isWide = true;
                        }
                    }
                    break;
                case Instructions.PUSH:
                    rom.Add(GetBlockOffset(src, 0xC5));
                    break;
                case Instructions.SWAP:
                    rom.Add(0xCB);
                    rom.Add(GetLinearOffset(src, 0x30));
                    break;
                case Instructions.RLCA:
                    rom.Add(0x07);
                    break;
                case Instructions.RRCA:
                    rom.Add(0x0F);
                    break;
                case Instructions.STOP:
                    rom.Add(0x10);
                    opt.encode_src = false;
                    break;
                case Instructions.HALT:
                    rom.Add(0x76);
                    break;
                case Instructions.RETI:
                    rom.Add(0xD9);
                    break;
                default:
                    break;
            }
        }
예제 #2
0
 public OffsetInfo GetCurrentOffset()
 {
     OffsetInfo offset = new OffsetInfo();
     List<Byte> nullrom = new List<byte>();
     OpEncodeOptions opt = new OpEncodeOptions();
     opt.encode_dst = (dst.loc == Locations.WIDE_IMM) || (dst.loc == Locations.IMM) || (dst.loc == Locations.OFFSET);
     opt.encode_src = (src.loc == Locations.WIDE_IMM) || (src.loc == Locations.IMM) || (src.loc == Locations.OFFSET);
     EncodeOp(nullrom, opt);
     offset.src = nullrom.Count;
     if (opt.encode_src)
     {
         InsertLocationInfo(nullrom, src);
     }
     offset.dst = nullrom.Count;
     if (opt.encode_dst)
     {
         InsertLocationInfo(nullrom, dst);
     }
     offset.total = nullrom.Count;
     return offset; ;
 }
예제 #3
0
        public void AppendTo(List<Byte> rom)
        {
            //Compile instruction to opcode
            if (this.op <= Instructions.NUM_INSTRUCTIONS)
            {
                OpEncodeOptions opt = new OpEncodeOptions();
                opt.encode_dst = (dst.loc == Locations.WIDE_IMM) || (dst.loc == Locations.IMM) || (dst.loc == Locations.OFFSET);
                opt.encode_src = (src.loc == Locations.WIDE_IMM) || (src.loc == Locations.IMM) || (src.loc == Locations.OFFSET);
                EncodeOp(rom, opt);
                if (opt.encode_src)
                {
                    InsertLocationInfo(rom, src);
                }

                if (opt.encode_dst)
                {
                    InsertLocationInfo(rom, dst);
                }
            }
        }