Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Text;
- using GBHL;
- namespace GameBoy_Assembler_Plus
- {
- public class Assembler
- {
- char[] splits = { '\n', ',', ' ', '.', '/', ';', '{', '}', '\t' };
- private byte[] ERR_SYNTAX = new byte[4];
- private byte[] ERR_OPCODE = new byte[5];
- private byte[] ERR_LABEL = new byte[7];
- private byte[] ERR_OUTOFSCOPE = new byte[8];
- public byte[] CompileLine(string s, List<CodeLabel> labels, int thisOffset)
- {
- GBFile gb = new GBFile(new byte[3]);
- string[] parts = s.ToLower().Split(splits);
- if (parts.Length == 0)
- return null;
- try
- {
- switch (parts[0])
- {
- //8-BIT VALUE LOADS
- case "ld":
- if (IsSingleRegister(parts[1]) || parts[1] == "(hl)" || parts[1] == "(de)" || parts[1] == "(bc)") //LD R,n
- {
- int value = GetByte(parts[2]);
- if (value != -1 && (value > 0xF || parts[2].StartsWith("0") || value < 0xA))
- {
- switch (parts[1])
- {
- case "a":
- WriteOpcode(ref gb, 0x3E, value);
- break;
- case "b":
- WriteOpcode(ref gb, 0x06, value);
- break;
- case "c":
- WriteOpcode(ref gb, 0x0E, value);
- break;
- case "d":
- WriteOpcode(ref gb, 0x16, value);
- break;
- case "e":
- WriteOpcode(ref gb, 0x1E, value);
- break;
- case "h":
- WriteOpcode(ref gb, 0x26, value);
- break;
- case "l":
- WriteOpcode(ref gb, 0x2E, value);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0x36, value);
- break;
- }
- if (gb.BufferLocation > 0)
- break;
- }
- else if ((IsSingleRegister(parts[2]) && IsSingleRegister(parts[1])) || (parts[2] == "(hl)" && IsSingleRegister(parts[1])) || (parts[1] == "a" && (parts[2] == "(bc)" || parts[2] == "(de)"))) //LD REGISTER,REGISTER and LD REGISTER,(HL)
- {
- switch (parts[1]) //LD R,R and LD R,(HL) and LD A,(BC) and LD A,(DE)
- {
- case "a":
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0x7F);
- break;
- case "b":
- WriteOpcode(ref gb, 0x78);
- break;
- case "c":
- WriteOpcode(ref gb, 0x79);
- break;
- case "d":
- WriteOpcode(ref gb, 0x7A);
- break;
- case "e":
- WriteOpcode(ref gb, 0x7B);
- break;
- case "h":
- WriteOpcode(ref gb, 0x7C);
- break;
- case "l":
- WriteOpcode(ref gb, 0x7D);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0x7E);
- break;
- case "(bc)":
- WriteOpcode(ref gb, 0x0A);
- break;
- case "(de)":
- WriteOpcode(ref gb, 0x1A);
- break;
- }
- break;
- case "b":
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0x47);
- break;
- case "b":
- WriteOpcode(ref gb, 0x40);
- break;
- case "c":
- WriteOpcode(ref gb, 0x41);
- break;
- case "d":
- WriteOpcode(ref gb, 0x42);
- break;
- case "e":
- WriteOpcode(ref gb, 0x43);
- break;
- case "h":
- WriteOpcode(ref gb, 0x44);
- break;
- case "l":
- WriteOpcode(ref gb, 0x45);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0x46);
- break;
- default:
- return ERR_OPCODE;
- }
- break;
- case "c":
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0x4F);
- break;
- case "b":
- WriteOpcode(ref gb, 0x48);
- break;
- case "c":
- WriteOpcode(ref gb, 0x49);
- break;
- case "d":
- WriteOpcode(ref gb, 0x4A);
- break;
- case "e":
- WriteOpcode(ref gb, 0x4B);
- break;
- case "h":
- WriteOpcode(ref gb, 0x4C);
- break;
- case "l":
- WriteOpcode(ref gb, 0x4D);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0x4E);
- break;
- default:
- return ERR_OPCODE;
- }
- break;
- case "d":
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0x57);
- break;
- case "b":
- WriteOpcode(ref gb, 0x50);
- break;
- case "c":
- WriteOpcode(ref gb, 0x51);
- break;
- case "d":
- WriteOpcode(ref gb, 0x52);
- break;
- case "e":
- WriteOpcode(ref gb, 0x53);
- break;
- case "h":
- WriteOpcode(ref gb, 0x54);
- break;
- case "l":
- WriteOpcode(ref gb, 0x55);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0x56);
- break;
- default:
- return ERR_OPCODE;
- }
- break;
- case "e":
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0x5F);
- break;
- case "b":
- WriteOpcode(ref gb, 0x58);
- break;
- case "c":
- WriteOpcode(ref gb, 0x59);
- break;
- case "d":
- WriteOpcode(ref gb, 0x5A);
- break;
- case "e":
- WriteOpcode(ref gb, 0x5B);
- break;
- case "h":
- WriteOpcode(ref gb, 0x5C);
- break;
- case "l":
- WriteOpcode(ref gb, 0x5D);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0x5E);
- break;
- default:
- return ERR_OPCODE;
- }
- break;
- case "h":
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0x67);
- break;
- case "b":
- WriteOpcode(ref gb, 0x60);
- break;
- case "c":
- WriteOpcode(ref gb, 0x61);
- break;
- case "d":
- WriteOpcode(ref gb, 0x62);
- break;
- case "e":
- WriteOpcode(ref gb, 0x63);
- break;
- case "h":
- WriteOpcode(ref gb, 0x64);
- break;
- case "l":
- WriteOpcode(ref gb, 0x65);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0x66);
- break;
- default:
- return ERR_OPCODE;
- }
- break;
- case "l":
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0x6F);
- break;
- case "b":
- WriteOpcode(ref gb, 0x68);
- break;
- case "c":
- WriteOpcode(ref gb, 0x69);
- break;
- case "d":
- WriteOpcode(ref gb, 0x6A);
- break;
- case "e":
- WriteOpcode(ref gb, 0x6B);
- break;
- case "h":
- WriteOpcode(ref gb, 0x6C);
- break;
- case "l":
- WriteOpcode(ref gb, 0x6D);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0x6E);
- break;
- default:
- return ERR_OPCODE;
- }
- break;
- }
- }
- else if (s.ToLower().StartsWith("ld a,(ff00+c)"))
- {
- WriteOpcode(ref gb, 0xF2);
- }
- else if (s.ToLower().StartsWith("ld a,(ff00 + c)"))
- {
- WriteOpcode(ref gb, 0xF2);
- }
- else if (s.ToLower().StartsWith("ld a,(ff00+"))
- {
- value = GetByte(parts[2].Substring(6, parts[2].IndexOf(")") - 6));
- if (value == -1)
- return ERR_SYNTAX;
- WriteOpcode(ref gb, 0xF0, value);
- }
- else if (s.ToLower().StartsWith("ld a,(ff00 + "))
- {
- value = GetByte(s.Substring(13, s.IndexOf(")") - 13));
- if (value == -1)
- return ERR_SYNTAX;
- WriteOpcode(ref gb, 0xF0, value);
- }
- else if (parts[1] == "a" && parts[2].StartsWith("(") && parts[2].EndsWith(")"))
- {
- value = GetByte(parts[2].Substring(1, parts[2].IndexOf(")") - 1));
- if (value == -1)
- return ERR_SYNTAX;
- WriteOpcode(ref gb, 0xFA, (value & 0xFF), (value >> 8));
- }
- else if (parts[1] == "(hl)" && IsSingleRegister(parts[2]))
- {
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0x77);
- break;
- case "b":
- WriteOpcode(ref gb, 0x70);
- break;
- case "c":
- WriteOpcode(ref gb, 0x71);
- break;
- case "d":
- WriteOpcode(ref gb, 0x72);
- break;
- case "e":
- WriteOpcode(ref gb, 0x73);
- break;
- case "h":
- WriteOpcode(ref gb, 0x74);
- break;
- case "l":
- WriteOpcode(ref gb, 0x75);
- break;
- default:
- return ERR_OPCODE;
- }
- }
- else if (parts[1] == "(bc)" && parts[2] == "a")
- {
- WriteOpcode(ref gb, 0x02);
- }
- else if (parts[1] == "(de)" && parts[2] == "a")
- {
- WriteOpcode(ref gb, 0x12);
- }
- else
- {
- return ERR_OPCODE;
- }
- }
- else if (IsRegisterPair(parts[1]) || parts[1] == "sp") //"LD RR,nn"
- {
- if (parts[1] == "sp" && parts[2] == "hl")
- {
- WriteOpcode(ref gb, 0xF9);
- break;
- }
- int value;
- if (s.StartsWith("ld hl,sp+"))
- {
- value = GetByte(parts[2].Substring(3));
- if (value == -1)
- return ERR_SYNTAX;
- WriteOpcode(ref gb, 0xF8, (value & 0xFF));
- break;
- }
- if (s.StartsWith("ld hl,sp + "))
- {
- value = GetByte(s.Substring(11));
- if (value == -1)
- return ERR_SYNTAX;
- WriteOpcode(ref gb, 0xF8, (value & 0xFF));
- break;
- }
- value = GetByte(parts[2]);
- if (value == -1)
- return ERR_SYNTAX;
- switch (parts[1])
- {
- case "bc":
- WriteOpcode(ref gb, 0x01, (value & 0xFF), ((value >> 8) & 0xFF));
- break;
- case "de":
- WriteOpcode(ref gb, 0x11, (value & 0xFF), ((value >> 8) & 0xFF));
- break;
- case "hl":
- WriteOpcode(ref gb, 0x21, (value & 0xFF), ((value >> 8) & 0xFF));
- break;
- case "sp":
- WriteOpcode(ref gb, 0x31, (value & 0xFF), ((value >> 8) & 0xFF));
- break;
- }
- }
- else if (s.ToLower().StartsWith("ld (ff00+c),a"))
- {
- WriteOpcode(ref gb, 0xE2);
- }
- else if (s.ToLower().StartsWith("ld (ff00 + c),a"))
- {
- WriteOpcode(ref gb, 0xE2);
- }
- else if (s.ToLower().StartsWith("ld (ff00+"))
- {
- int value = GetByte(parts[1].Substring(6, parts[1].IndexOf(")") - 6));
- if (value == -1)
- return ERR_SYNTAX;
- if (parts[2] != "a")
- return ERR_OPCODE;
- WriteOpcode(ref gb, 0xE0, value);
- }
- else if (s.ToLower().StartsWith("ld (ff00 + "))
- {
- int value = GetByte(s.Substring(11, s.IndexOf(")") - 11));
- if (value == -1)
- return ERR_SYNTAX;
- if (parts[4] != "a")
- return ERR_OPCODE;
- WriteOpcode(ref gb, 0xE0, value);
- }
- else if (parts[1].StartsWith("(") && parts[1].EndsWith(")")) //LD (nn),A
- {
- if (parts[2] == "a")
- {
- int value = GetByte(parts[1].Substring(1, parts[1].IndexOf(")") - 1));
- if (value == -1)
- return ERR_SYNTAX;
- WriteOpcode(ref gb, 0xEA, (value & 0xFF), (value >> 8));
- }
- else if (parts[2] == "sp")
- {
- int value = GetByte(parts[1].Substring(1, parts[1].IndexOf(")") - 1));
- if (value == -1)
- return ERR_SYNTAX;
- WriteOpcode(ref gb, 0x08, (value & 0xFF), (value >> 8));
- }
- else
- return ERR_OPCODE;
- }
- else
- {
- return ERR_OPCODE;
- }
- break;
- case "ldi":
- if (parts[1] == "a" && parts[2] == "(hl)")
- {
- WriteOpcode(ref gb, 0x2A);
- }
- else if (parts[1] == "(hl)" && parts[2] == "a")
- {
- WriteOpcode(ref gb, 0x22);
- }
- else
- {
- return ERR_OPCODE;
- }
- break;
- case "ldd":
- if (parts[1] == "a" && parts[2] == "(hl)")
- {
- WriteOpcode(ref gb, 0x3A);
- }
- else if (parts[1] == "(hl)" && parts[2] == "a")
- {
- WriteOpcode(ref gb, 0x32);
- }
- else
- {
- return ERR_OPCODE;
- }
- break;
- case "push":
- if (IsRegisterPair(parts[1]))
- {
- if (parts[1] == "af")
- WriteOpcode(ref gb, 0xF5);
- else if (parts[1] == "bc")
- WriteOpcode(ref gb, 0xC5);
- else if (parts[1] == "de")
- WriteOpcode(ref gb, 0xD5);
- else if (parts[1] == "hl")
- WriteOpcode(ref gb, 0xE5);
- }
- else
- return ERR_OPCODE;
- break;
- case "pop":
- if (IsRegisterPair(parts[1]))
- {
- if (parts[1] == "af")
- WriteOpcode(ref gb, 0xF1);
- else if (parts[1] == "bc")
- WriteOpcode(ref gb, 0xC1);
- else if (parts[1] == "de")
- WriteOpcode(ref gb, 0xD1);
- else if (parts[1] == "hl")
- WriteOpcode(ref gb, 0xE1);
- }
- else
- return ERR_OPCODE;
- break;
- case "add":
- if (parts[1] == "a")
- {
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0x87);
- break;
- case "b":
- WriteOpcode(ref gb, 0x80);
- break;
- case "c":
- WriteOpcode(ref gb, 0x81);
- break;
- case "d":
- WriteOpcode(ref gb, 0x82);
- break;
- case "e":
- WriteOpcode(ref gb, 0x83);
- break;
- case "h":
- WriteOpcode(ref gb, 0x84);
- break;
- case "l":
- WriteOpcode(ref gb, 0x85);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0x86);
- break;
- default:
- int value = GetByte(parts[2]);
- if (value == -1)
- return ERR_SYNTAX;
- WriteOpcode(ref gb, 0xC6, (value & 0xFF));
- break;
- }
- }
- else if (parts[1] == "hl")
- {
- switch (parts[2])
- {
- case "bc":
- WriteOpcode(ref gb, 0x09);
- break;
- case "de":
- WriteOpcode(ref gb, 0x19);
- break;
- case "hl":
- WriteOpcode(ref gb, 0x29);
- break;
- case "sp":
- WriteOpcode(ref gb, 0x39);
- break;
- default:
- return ERR_OPCODE;
- }
- }
- else if (parts[1] == "sp")
- {
- int value = GetByte(parts[2]);
- if (value == -1)
- return ERR_SYNTAX;
- WriteOpcode(ref gb, 0xE8, (value & 0xFF));
- }
- else
- {
- return ERR_OPCODE;
- }
- break;
- case "adc":
- if (parts[1] == "a")
- {
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0x8F);
- break;
- case "b":
- WriteOpcode(ref gb, 0x88);
- break;
- case "c":
- WriteOpcode(ref gb, 0x89);
- break;
- case "d":
- WriteOpcode(ref gb, 0x8A);
- break;
- case "e":
- WriteOpcode(ref gb, 0x8B);
- break;
- case "h":
- WriteOpcode(ref gb, 0x8C);
- break;
- case "l":
- WriteOpcode(ref gb, 0x8D);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0x8E);
- break;
- default:
- int value = GetByte(parts[2]);
- if (value == -1)
- return ERR_SYNTAX;
- WriteOpcode(ref gb, 0xCE, (value & 0xFF));
- break;
- }
- }
- break;
- case "sub":
- if (parts[1] == "a")
- {
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0x97);
- break;
- case "b":
- WriteOpcode(ref gb, 0x90);
- break;
- case "c":
- WriteOpcode(ref gb, 0x91);
- break;
- case "d":
- WriteOpcode(ref gb, 0x92);
- break;
- case "e":
- WriteOpcode(ref gb, 0x93);
- break;
- case "h":
- WriteOpcode(ref gb, 0x94);
- break;
- case "l":
- WriteOpcode(ref gb, 0x95);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0x96);
- break;
- default:
- int value = GetByte(parts[2]);
- if (value == -1)
- return ERR_SYNTAX;
- WriteOpcode(ref gb, 0xD6, (value & 0xFF));
- break;
- }
- }
- break;
- case "sbc":
- if (parts[1] == "a")
- {
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0x9F);
- break;
- case "b":
- WriteOpcode(ref gb, 0x98);
- break;
- case "c":
- WriteOpcode(ref gb, 0x99);
- break;
- case "d":
- WriteOpcode(ref gb, 0x9A);
- break;
- case "e":
- WriteOpcode(ref gb, 0x9B);
- break;
- case "h":
- WriteOpcode(ref gb, 0x9C);
- break;
- case "l":
- WriteOpcode(ref gb, 0x9D);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0x9E);
- break;
- default:
- return ERR_SYNTAX;
- }
- }
- break;
- case "and":
- if (parts[1] == "a")
- {
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0xA7);
- break;
- case "b":
- WriteOpcode(ref gb, 0xA0);
- break;
- case "c":
- WriteOpcode(ref gb, 0xA1);
- break;
- case "d":
- WriteOpcode(ref gb, 0xA2);
- break;
- case "e":
- WriteOpcode(ref gb, 0xA3);
- break;
- case "h":
- WriteOpcode(ref gb, 0xA4);
- break;
- case "l":
- WriteOpcode(ref gb, 0xA5);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0xA6);
- break;
- default:
- int value = GetByte(parts[2]);
- if (value == -1)
- return ERR_SYNTAX;
- WriteOpcode(ref gb, 0xE6, (value & 0xFF));
- break;
- }
- }
- break;
- case "or":
- if (parts[1] == "a")
- {
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0xB7);
- break;
- case "b":
- WriteOpcode(ref gb, 0xB0);
- break;
- case "c":
- WriteOpcode(ref gb, 0xB1);
- break;
- case "d":
- WriteOpcode(ref gb, 0xB2);
- break;
- case "e":
- WriteOpcode(ref gb, 0xB3);
- break;
- case "h":
- WriteOpcode(ref gb, 0xB4);
- break;
- case "l":
- WriteOpcode(ref gb, 0xB5);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0xB6);
- break;
- default:
- int value = GetByte(parts[2]);
- if (value == -1)
- return ERR_SYNTAX;
- WriteOpcode(ref gb, 0xF6, (value & 0xFF));
- break;
- }
- }
- break;
- case "xor":
- if (parts[1] == "a")
- {
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0xAF);
- break;
- case "b":
- WriteOpcode(ref gb, 0xA8);
- break;
- case "c":
- WriteOpcode(ref gb, 0xA9);
- break;
- case "d":
- WriteOpcode(ref gb, 0xAA);
- break;
- case "e":
- WriteOpcode(ref gb, 0xAB);
- break;
- case "h":
- WriteOpcode(ref gb, 0xAC);
- break;
- case "l":
- WriteOpcode(ref gb, 0xAD);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0xAE);
- break;
- default:
- int value = GetByte(parts[2]);
- if (value == -1)
- return ERR_SYNTAX;
- WriteOpcode(ref gb, 0xEE, (value & 0xFF));
- break;
- }
- }
- break;
- case "cp":
- if (parts[1] == "a")
- {
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0xBF);
- break;
- case "b":
- WriteOpcode(ref gb, 0xB8);
- break;
- case "c":
- WriteOpcode(ref gb, 0xB9);
- break;
- case "d":
- WriteOpcode(ref gb, 0xBA);
- break;
- case "e":
- WriteOpcode(ref gb, 0xBB);
- break;
- case "h":
- WriteOpcode(ref gb, 0xBC);
- break;
- case "l":
- WriteOpcode(ref gb, 0xBD);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0xBE);
- break;
- default:
- int value = GetByte(parts[2]);
- if (value == -1)
- return ERR_SYNTAX;
- WriteOpcode(ref gb, 0xFE, (value & 0xFF));
- break;
- }
- }
- break;
- case "inc":
- switch (parts[1])
- {
- case "a":
- WriteOpcode(ref gb, 0x3C);
- break;
- case "b":
- WriteOpcode(ref gb, 0x04);
- break;
- case "c":
- WriteOpcode(ref gb, 0x0C);
- break;
- case "d":
- WriteOpcode(ref gb, 0x14);
- break;
- case "e":
- WriteOpcode(ref gb, 0x1C);
- break;
- case "h":
- WriteOpcode(ref gb, 0x24);
- break;
- case "l":
- WriteOpcode(ref gb, 0x2C);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0x34);
- break;
- //16-Bit
- case "bc":
- WriteOpcode(ref gb, 0x03);
- break;
- case "de":
- WriteOpcode(ref gb, 0x13);
- break;
- case "hl":
- WriteOpcode(ref gb, 0x23);
- break;
- case "sp":
- WriteOpcode(ref gb, 0x33);
- break;
- default:
- return ERR_OPCODE;
- }
- break;
- case "dec":
- switch (parts[1])
- {
- case "a":
- WriteOpcode(ref gb, 0x3D);
- break;
- case "b":
- WriteOpcode(ref gb, 0x05);
- break;
- case "c":
- WriteOpcode(ref gb, 0x0D);
- break;
- case "d":
- WriteOpcode(ref gb, 0x15);
- break;
- case "e":
- WriteOpcode(ref gb, 0x1D);
- break;
- case "h":
- WriteOpcode(ref gb, 0x25);
- break;
- case "l":
- WriteOpcode(ref gb, 0x2D);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0x35);
- break;
- //16-Bit
- case "bc":
- WriteOpcode(ref gb, 0x0B);
- break;
- case "de":
- WriteOpcode(ref gb, 0x1B);
- break;
- case "hl":
- WriteOpcode(ref gb, 0x2B);
- break;
- case "sp":
- WriteOpcode(ref gb, 0x3B);
- break;
- default:
- return ERR_OPCODE;
- }
- break;
- case "swap":
- switch (parts[1])
- {
- case "a":
- WriteOpcode(ref gb, 0xCB, 0x37);
- break;
- case "b":
- WriteOpcode(ref gb, 0xCB, 0x30);
- break;
- case "c":
- WriteOpcode(ref gb, 0xCB, 0x31);
- break;
- case "d":
- WriteOpcode(ref gb, 0xCB, 0x32);
- break;
- case "e":
- WriteOpcode(ref gb, 0xCB, 0x33);
- break;
- case "h":
- WriteOpcode(ref gb, 0xCB, 0x34);
- break;
- case "l":
- WriteOpcode(ref gb, 0xCB, 0x35);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0xCB, 0x36);
- break;
- }
- break;
- case "daa":
- WriteOpcode(ref gb, 0x27);
- break;
- case "cpl":
- WriteOpcode(ref gb, 0x2F);
- break;
- case "ccf":
- WriteOpcode(ref gb, 0x3F);
- break;
- case "scf":
- WriteOpcode(ref gb, 0x37);
- break;
- case "nop":
- WriteOpcode(ref gb, 0x00);
- break;
- case "halt":
- WriteOpcode(ref gb, 0x76);
- break;
- case "stop":
- WriteOpcode(ref gb, 0x10, 0x00);
- break;
- case "di":
- WriteOpcode(ref gb, 0xF3);
- break;
- case "ei":
- WriteOpcode(ref gb, 0xFB);
- break;
- case "rlca":
- WriteOpcode(ref gb, 0x07);
- break;
- case "rla":
- WriteOpcode(ref gb, 0x17);
- break;
- case "rrca":
- WriteOpcode(ref gb, 0x0F);
- break;
- case "rra":
- WriteOpcode(ref gb, 0x1F);
- break;
- case "rlc":
- switch (parts[1])
- {
- case "a":
- WriteOpcode(ref gb, 0xCB, 0x07);
- break;
- case "b":
- WriteOpcode(ref gb, 0xCB, 0x00);
- break;
- case "c":
- WriteOpcode(ref gb, 0xCB, 0x01);
- break;
- case "d":
- WriteOpcode(ref gb, 0xCB, 0x02);
- break;
- case "e":
- WriteOpcode(ref gb, 0xCB, 0x03);
- break;
- case "h":
- WriteOpcode(ref gb, 0xCB, 0x04);
- break;
- case "l":
- WriteOpcode(ref gb, 0xCB, 0x05);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0xCB, 0x06);
- break;
- }
- break;
- case "rl":
- switch (parts[1])
- {
- case "a":
- WriteOpcode(ref gb, 0xCB, 0x17);
- break;
- case "b":
- WriteOpcode(ref gb, 0xCB, 0x10);
- break;
- case "c":
- WriteOpcode(ref gb, 0xCB, 0x11);
- break;
- case "d":
- WriteOpcode(ref gb, 0xCB, 0x12);
- break;
- case "e":
- WriteOpcode(ref gb, 0xCB, 0x13);
- break;
- case "h":
- WriteOpcode(ref gb, 0xCB, 0x14);
- break;
- case "l":
- WriteOpcode(ref gb, 0xCB, 0x15);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0xCB, 0x16);
- break;
- }
- break;
- case "rrc":
- switch (parts[1])
- {
- case "a":
- WriteOpcode(ref gb, 0xCB, 0x0F);
- break;
- case "b":
- WriteOpcode(ref gb, 0xCB, 0x08);
- break;
- case "c":
- WriteOpcode(ref gb, 0xCB, 0x09);
- break;
- case "d":
- WriteOpcode(ref gb, 0xCB, 0x0A);
- break;
- case "e":
- WriteOpcode(ref gb, 0xCB, 0x0B);
- break;
- case "h":
- WriteOpcode(ref gb, 0xCB, 0x0C);
- break;
- case "l":
- WriteOpcode(ref gb, 0xCB, 0x0D);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0xCB, 0x0E);
- break;
- }
- break;
- case "rr":
- switch (parts[1])
- {
- case "a":
- WriteOpcode(ref gb, 0xCB, 0x1F);
- break;
- case "b":
- WriteOpcode(ref gb, 0xCB, 0x18);
- break;
- case "c":
- WriteOpcode(ref gb, 0xCB, 0x19);
- break;
- case "d":
- WriteOpcode(ref gb, 0xCB, 0x1A);
- break;
- case "e":
- WriteOpcode(ref gb, 0xCB, 0x1B);
- break;
- case "h":
- WriteOpcode(ref gb, 0xCB, 0x1C);
- break;
- case "l":
- WriteOpcode(ref gb, 0xCB, 0x1D);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0xCB, 0x1E);
- break;
- }
- break;
- case "sla":
- switch (parts[1])
- {
- case "a":
- WriteOpcode(ref gb, 0xCB, 0x27);
- break;
- case "b":
- WriteOpcode(ref gb, 0xCB, 0x20);
- break;
- case "c":
- WriteOpcode(ref gb, 0xCB, 0x21);
- break;
- case "d":
- WriteOpcode(ref gb, 0xCB, 0x22);
- break;
- case "e":
- WriteOpcode(ref gb, 0xCB, 0x23);
- break;
- case "h":
- WriteOpcode(ref gb, 0xCB, 0x24);
- break;
- case "l":
- WriteOpcode(ref gb, 0xCB, 0x25);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0xCB, 0x26);
- break;
- }
- break;
- case "sra":
- switch (parts[1])
- {
- case "a":
- WriteOpcode(ref gb, 0xCB, 0x2F);
- break;
- case "b":
- WriteOpcode(ref gb, 0xCB, 0x28);
- break;
- case "c":
- WriteOpcode(ref gb, 0xCB, 0x29);
- break;
- case "d":
- WriteOpcode(ref gb, 0xCB, 0x2A);
- break;
- case "e":
- WriteOpcode(ref gb, 0xCB, 0x2B);
- break;
- case "h":
- WriteOpcode(ref gb, 0xCB, 0x2C);
- break;
- case "l":
- WriteOpcode(ref gb, 0xCB, 0x2D);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0xCB, 0x2E);
- break;
- }
- break;
- case "slr":
- switch (parts[1])
- {
- case "a":
- WriteOpcode(ref gb, 0xCB, 0x3F);
- break;
- case "b":
- WriteOpcode(ref gb, 0xCB, 0x38);
- break;
- case "c":
- WriteOpcode(ref gb, 0xCB, 0x39);
- break;
- case "d":
- WriteOpcode(ref gb, 0xCB, 0x3A);
- break;
- case "e":
- WriteOpcode(ref gb, 0xCB, 0x3B);
- break;
- case "h":
- WriteOpcode(ref gb, 0xCB, 0x3C);
- break;
- case "l":
- WriteOpcode(ref gb, 0xCB, 0x3D);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0xCB, 0x3E);
- break;
- }
- break;
- case "bit":
- int bas = GetByte(parts[1]);
- if (bas < 0 || bas > 7)
- return ERR_SYNTAX;
- bas *= 8;
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0xCB, 0x47 + bas);
- break;
- case "b":
- WriteOpcode(ref gb, 0xCB, 0x40 + bas);
- break;
- case "c":
- WriteOpcode(ref gb, 0xCB, 0x41 + bas);
- break;
- case "d":
- WriteOpcode(ref gb, 0xCB, 0x42 + bas);
- break;
- case "e":
- WriteOpcode(ref gb, 0xCB, 0x43 + bas);
- break;
- case "h":
- WriteOpcode(ref gb, 0xCB, 0x44 + bas);
- break;
- case "l":
- WriteOpcode(ref gb, 0xCB, 0x45 + bas);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0xCB, 0x46 + bas);
- break;
- }
- break;
- case "set":
- bas = GetByte(parts[1]);
- if (bas < 0 || bas > 7)
- return ERR_SYNTAX;
- bas *= 8;
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0xCB, 0xC7 + bas);
- break;
- case "b":
- WriteOpcode(ref gb, 0xCB, 0xC0 + bas);
- break;
- case "c":
- WriteOpcode(ref gb, 0xCB, 0xC1 + bas);
- break;
- case "d":
- WriteOpcode(ref gb, 0xCB, 0xC2 + bas);
- break;
- case "e":
- WriteOpcode(ref gb, 0xCB, 0xC3 + bas);
- break;
- case "h":
- WriteOpcode(ref gb, 0xCB, 0xC4 + bas);
- break;
- case "l":
- WriteOpcode(ref gb, 0xCB, 0xC5 + bas);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0xCB, 0xC6 + bas);
- break;
- }
- break;
- case "res":
- bas = GetByte(parts[1]);
- if (bas < 0 || bas > 7)
- return ERR_SYNTAX;
- bas *= 8;
- switch (parts[2])
- {
- case "a":
- WriteOpcode(ref gb, 0xCB, 0x87 + bas);
- break;
- case "b":
- WriteOpcode(ref gb, 0xCB, 0x80 + bas);
- break;
- case "c":
- WriteOpcode(ref gb, 0xCB, 0x81 + bas);
- break;
- case "d":
- WriteOpcode(ref gb, 0xCB, 0x82 + bas);
- break;
- case "e":
- WriteOpcode(ref gb, 0xCB, 0x83 + bas);
- break;
- case "h":
- WriteOpcode(ref gb, 0xCB, 0x84 + bas);
- break;
- case "l":
- WriteOpcode(ref gb, 0xCB, 0x85 + bas);
- break;
- case "(hl)":
- WriteOpcode(ref gb, 0xCB, 0x86 + bas);
- break;
- }
- break;
- case "jp":
- if (parts[1] == "(hl)")
- {
- WriteOpcode(ref gb, 0xE9);
- }
- else if (parts[1] != "nz" && parts[1] != "z" && parts[1] != "nc" && parts[1] != "c")
- {
- if (parts[1] == "")
- return ERR_SYNTAX;
- int jumpto = GetByte(parts[1]);
- if (jumpto == -1)
- {
- string label = parts[1];
- foreach (CodeLabel c in labels)
- {
- if (c.Label == label)
- {
- int jp = c.Offset;
- WriteOpcode(ref gb, 0xC3, (jp & 0xFF), ((jp >> 8) & 0xFF));
- break;
- }
- }
- if (gb.BufferLocation == 0)
- return ERR_LABEL;
- }
- else
- {
- WriteOpcode(ref gb, 0xC3, (jumpto & 0xFF), ((jumpto >> 8) & 0xFF));
- }
- }
- else
- {
- if (parts[2] == "")
- return ERR_SYNTAX;
- int jumpto = GetByte(parts[2]);
- byte opcode = 0xC2;
- if (parts[1] == "z")
- opcode = 0xCA;
- else if (parts[1] == "nc")
- opcode = 0xD2;
- else if (parts[1] == "c")
- opcode = 0xDA;
- if (jumpto == -1)
- {
- string label = parts[2];
- foreach (CodeLabel c in labels)
- {
- if (c.Label == label)
- {
- int jp = c.Offset;
- WriteOpcode(ref gb, opcode, (jp & 0xFF), ((jp >> 8) & 0xFF));
- break;
- }
- }
- if (gb.BufferLocation == 0)
- return ERR_LABEL;
- }
- else
- {
- WriteOpcode(ref gb, opcode, (jumpto & 0xFF), ((jumpto >> 8) & 0xFF));
- }
- }
- break;
- case "jr":
- if (parts[1] != "nz" && parts[1] != "z" && parts[1] != "nc" && parts[1] != "c")
- {
- if (parts[1] == "")
- return ERR_SYNTAX;
- int jumpto = GetByte(parts[1]);
- if (jumpto == -1)
- {
- string label = parts[1];
- foreach (CodeLabel c in labels)
- {
- if (c.Label == label)
- {
- int jp = 0;
- if (c.Offset < thisOffset)
- {
- if ((byte)(c.StartOffset + (c.Offset - c.StartOffset) - (thisOffset + 2)) < 0x80)
- {
- return ERR_OUTOFSCOPE;
- }
- jp = (byte)(c.StartOffset + (c.Offset - c.StartOffset) - (thisOffset + 2));
- }
- else
- {
- if ((byte)(c.StartOffset + (c.Offset - c.StartOffset) - (thisOffset + 2)) > 0x7F)
- {
- return ERR_OUTOFSCOPE;
- }
- jp = (byte)(c.StartOffset + (c.Offset - c.StartOffset) - (thisOffset + 2));
- if (jp > 0x7F)
- return ERR_OUTOFSCOPE;
- }
- WriteOpcode(ref gb, 0x18, (jp & 0xFF));
- break;
- }
- }
- if (gb.BufferLocation == 0)
- return ERR_LABEL;
- }
- else
- {
- WriteOpcode(ref gb, 0x18, (jumpto & 0xFF));
- }
- }
- else
- {
- if (parts[2] == "")
- return ERR_SYNTAX;
- int jumpto = GetByte(parts[2]);
- byte opcode = 0x20;
- if (parts[1] == "z")
- opcode = 0x28;
- else if (parts[1] == "nc")
- opcode = 0x30;
- else if (parts[1] == "c")
- opcode = 0x38;
- if (jumpto == -1)
- {
- string label = parts[2];
- foreach (CodeLabel c in labels)
- {
- if (c.Label == label)
- {
- int jp = 0;
- if (c.Offset < thisOffset)
- {
- if ((byte)(c.StartOffset + (c.Offset - c.StartOffset) - (thisOffset + 2)) < 0x80)
- {
- return ERR_OUTOFSCOPE;
- }
- jp = (byte)(c.StartOffset + (c.Offset - c.StartOffset) - (thisOffset + 2));
- }
- else
- {
- if ((byte)(c.StartOffset + (c.Offset - c.StartOffset) - (thisOffset + 2)) > 0x7F)
- {
- return ERR_OUTOFSCOPE;
- }
- jp = (byte)(c.StartOffset + (c.Offset - c.StartOffset) - (thisOffset + 2));
- }
- WriteOpcode(ref gb, opcode, (jp & 0xFF));
- break;
- }
- }
- if (gb.BufferLocation == 0)
- return ERR_LABEL;
- }
- else
- {
- WriteOpcode(ref gb, opcode, (jumpto & 0xFF));
- }
- }
- break;
- case "call":
- if (parts[1] != "nz" && parts[1] != "z" && parts[1] != "nc" && parts[1] != "c")
- {
- int call = GetByte(parts[1]);
- if (call == -1)
- {
- foreach (CodeLabel c in labels)
- {
- if (c.Label == parts[1])
- {
- WriteOpcode(ref gb, 0xCD, (c.Offset & 0xFF), ((c.Offset >> 8) & 0xFF));
- }
- }
- if (gb.BufferLocation == 0)
- return ERR_LABEL;
- }
- else
- {
- WriteOpcode(ref gb, 0xCD, (call & 0xFF), ((call >> 8) & 0xFF));
- }
- }
- else
- {
- int call = GetByte(parts[2]);
- byte opcode = 0xC4;
- if (parts[1] == "z")
- opcode = 0xCC;
- else if (parts[1] == "nc")
- opcode = 0xD4;
- else if (parts[1] == "c")
- opcode = 0xDC;
- if (call == -1)
- {
- foreach (CodeLabel c in labels)
- {
- if (c.Label == parts[2])
- {
- WriteOpcode(ref gb, opcode, (c.Offset & 0xFF), ((c.Offset >> 8) & 0xFF));
- }
- }
- if (gb.BufferLocation == 0)
- return ERR_LABEL;
- }
- else
- {
- WriteOpcode(ref gb, opcode, (call & 0xFF), ((call >> 8) & 0xFF));
- }
- }
- break;
- case "rst":
- int rst = GetByte(parts[1]);
- switch (rst)
- {
- case 0x00:
- WriteOpcode(ref gb, 0xC7);
- break;
- case 0x08:
- WriteOpcode(ref gb, 0xCF);
- break;
- case 0x10:
- WriteOpcode(ref gb, 0xD7);
- break;
- case 0x18:
- WriteOpcode(ref gb, 0xDF);
- break;
- case 0x20:
- WriteOpcode(ref gb, 0xE7);
- break;
- case 0x28:
- WriteOpcode(ref gb, 0xEF);
- break;
- case 0x30:
- WriteOpcode(ref gb, 0xF7);
- break;
- case 0x38:
- WriteOpcode(ref gb, 0xFF);
- break;
- }
- break;
- case "ret":
- if (parts.Length < 2)
- {
- WriteOpcode(ref gb, 0xC9);
- }
- else if (parts[1] == "nz")
- {
- WriteOpcode(ref gb, 0xC0);
- }
- else if (parts[1] == "z")
- {
- WriteOpcode(ref gb, 0xC8);
- }
- else if (parts[1] == "nc")
- {
- WriteOpcode(ref gb, 0xD0);
- }
- else if (parts[1] == "c")
- {
- WriteOpcode(ref gb, 0xD8);
- }
- break;
- case "reti":
- WriteOpcode(ref gb, 0xD9);
- break;
- case "raw":
- for (int i = 1; i < parts.Length; i++)
- {
- int b = GetByte(parts[i]);
- if (b != -1)
- WriteOpcode(ref gb, (byte)b);
- }
- break;
- default:
- return ERR_OPCODE;
- }
- }
- catch (Exception)
- {
- return ERR_SYNTAX;
- }
- if (gb.BufferLocation == 0)
- return ERR_OPCODE;
- byte[] output = new byte[gb.BufferLocation];
- Array.Copy(gb.Buffer, output, gb.BufferLocation);
- return output;
- }
- private bool IsRegister(string s)
- {
- switch (s)
- {
- case "a":
- case "b":
- case "c":
- case "d":
- case "e":
- case "f":
- case "h":
- case "l":
- case "af":
- case "bc":
- case "de":
- case "hl":
- return true;
- }
- return false;
- }
- private bool IsSingleRegister(string s)
- {
- switch (s)
- {
- case "a":
- case "b":
- case "c":
- case "d":
- case "e":
- case "f":
- case "h":
- case "l":
- return true;
- }
- return false;
- }
- private bool IsRegisterPair(string s)
- {
- switch (s)
- {
- //SP is excluded because it doesn't usually appear with common register pair opcodes
- case "af":
- case "bc":
- case "de":
- case "hl":
- return true;
- }
- return false;
- }
- public int GetByte(string s)
- {
- int o;
- if (!int.TryParse(s, System.Globalization.NumberStyles.HexNumber, null, out o))
- return -1;
- return o;
- }
- public void WriteOpcode(ref GBFile g, byte opcode)
- {
- g.WriteByte(opcode);
- }
- public void WriteOpcode(ref GBFile g, byte opcode, int value)
- {
- g.WriteByte(opcode);
- g.WriteByte((byte)value);
- }
- public void WriteOpcode(ref GBFile g, byte opcode, int value, int value2)
- {
- g.WriteByte(opcode);
- g.WriteByte((byte)value);
- g.WriteByte((byte)value2);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement