From 676df5fc02f54ebd16b64f7e25c58e31bf1d49e4 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Sun, 26 Jul 2020 18:47:14 +0200 Subject: [PATCH] Moved 6502 family instruction set to separate java package. --- .../fragment/cache/fragment-cache-mos6502.asm | 2 +- .../cpufamily6502/AsmAddressingMode.java | 140 +++++++ .../asm => cpufamily6502}/AsmClobber.java | 2 +- .../cpufamily6502/AsmInstructionSet.java | 396 ++++++++++++++++++ .../dk/camelot64/cpufamily6502/AsmOpcode.java | 81 ++++ .../kickc/asm/AsmAddressingMode.java | 47 --- .../java/dk/camelot64/kickc/asm/AsmChunk.java | 6 +- .../camelot64/kickc/asm/AsmInstruction.java | 24 +- .../kickc/asm/AsmInstructionSet.java | 381 ----------------- .../kickc/asm/AsmInstructionType.java | 66 --- .../dk/camelot64/kickc/asm/AsmProgram.java | 12 +- .../asm/AsmProgramStaticRegisterValues.java | 30 +- .../kickc/fragment/AsmFragmentClobber.java | 2 +- .../kickc/fragment/AsmFragmentInstance.java | 24 +- .../kickc/fragment/AsmFragmentTemplate.java | 2 +- .../kickc/model/statements/StatementAsm.java | 2 +- .../model/statements/StatementKickAsm.java | 2 +- .../Pass0GenerateStatementSequence.java | 2 +- .../kickc/passes/Pass4AssertNoCpuClobber.java | 2 +- .../kickc/passes/Pass4CodeGeneration.java | 4 +- .../passes/Pass4InterruptClobberFix.java | 2 +- ...gisterUpliftPotentialRegisterAnalysis.java | 2 +- .../kickc/passes/Pass5AddMainRts.java | 8 +- .../passes/Pass5DoubleJumpElimination.java | 19 +- .../kickc/passes/Pass5FixLongBranches.java | 37 +- .../passes/Pass5NextJumpElimination.java | 2 +- .../Pass5RedundantLabelElimination.java | 2 +- .../kickc/passes/Pass5RelabelLongLabels.java | 2 +- .../kickc/passes/Pass5SkipBegin.java | 2 +- .../Pass5UnnecesaryLoadElimination.java | 37 +- .../Pass5UnreachableCodeElimination.java | 2 +- .../passes/Pass5UnusedLabelElimination.java | 5 +- 32 files changed, 745 insertions(+), 602 deletions(-) create mode 100644 src/main/java/dk/camelot64/cpufamily6502/AsmAddressingMode.java rename src/main/java/dk/camelot64/{kickc/asm => cpufamily6502}/AsmClobber.java (98%) create mode 100644 src/main/java/dk/camelot64/cpufamily6502/AsmInstructionSet.java create mode 100644 src/main/java/dk/camelot64/cpufamily6502/AsmOpcode.java delete mode 100644 src/main/java/dk/camelot64/kickc/asm/AsmAddressingMode.java delete mode 100644 src/main/java/dk/camelot64/kickc/asm/AsmInstructionSet.java delete mode 100644 src/main/java/dk/camelot64/kickc/asm/AsmInstructionType.java diff --git a/src/main/fragment/cache/fragment-cache-mos6502.asm b/src/main/fragment/cache/fragment-cache-mos6502.asm index d6f11bca6..2aeed552a 100644 --- a/src/main/fragment/cache/fragment-cache-mos6502.asm +++ b/src/main/fragment/cache/fragment-cache-mos6502.asm @@ -1,4 +1,4 @@ -//KICKC FRAGMENT CACHE 161ce03ba6 +//KICKC FRAGMENT CACHE 15c356fca7 //FRAGMENT vbuz1=vbuc1 lda #{c1} sta {z1} diff --git a/src/main/java/dk/camelot64/cpufamily6502/AsmAddressingMode.java b/src/main/java/dk/camelot64/cpufamily6502/AsmAddressingMode.java new file mode 100644 index 000000000..8f5f9bab0 --- /dev/null +++ b/src/main/java/dk/camelot64/cpufamily6502/AsmAddressingMode.java @@ -0,0 +1,140 @@ +package dk.camelot64.cpufamily6502; + +/** 6502 Family Addressing Modes. */ +public enum AsmAddressingMode { + + /** + * None / Implied / Accumulator + * IMPLIED ADDRESSING — In the implied addressing mode, the address containing the operand is implicitly stated in + * the operation code of the instruction. + * ACCUMULATOR ADDRESSING — This form of addressing is represented with a one byte instruction, implying an operation + * on the accumulator" + */ + NON("", "%i", 1), + /** + * Immediate + * IMMEDIATE ADDRESSING — In immediate addressing, the operand is contained in the second byte of the instruction, + * with no further memory addressing required. + */ + IMM("#imm", "%i #%p", 2), + /** + * Zeropage + * ZERO PAGE ADDRESSING — The zero page instructions allow for shorter code and execution times by only fetching the + * second byte of the instruction and assuming a zero high address byte. Careful use of the zero page can result in + * significant increase in code efficiency. + */ + ZP("zp", "%i.z %p", 2), + /** + * X Indexed Zeropage + * INDEXED ZERO PAGE ADDRESSING - (X, Y indexing) — This form of addressing is used in conjunction with the index + * register and is referred to as “Zero Page, X" or "Zero Page, Y.” The effective address is calculated by adding the + * second byte to the contents of the index register. Since this is a form of "Zero Page" addressing, the content of + * the second byte references a location in page zero. Additionally, due to the “Zero Page" addressing nature of this + * mode, no carry is added to the high order 8 bits of memory and crossing of page boundaries does not occur. + */ + ZPX("zp,x", "%i.z %p,x", 2), + /** + * Y Indexed Zeropage + * INDEXED ZERO PAGE ADDRESSING - (X, Y indexing) — This form of addressing is used in coniunction with the index + * register and is referred to as “Zero Page, X" or "Zero Page, Y.” The effective address is calculated by adding + * the second byte to the contents of the index register. Since this is a form of "Zero Page" addressing, the content + * of the second byte references a location in page zero. Additionally, due to the “Zero Page" addressing nature of + * this mode, no carry is added to the high order 8 bits of memory and crossing of page boundaries does not occur. + */ + ZPY("zp,y", "%i.z %p,y", 2), + /** + * Absolute + * ABSOLUTE ADDRESSING — In absolute addressing, the second byte of the instruction specifies the eight low order + * bits of the effective address while the third byte specifies the eight high order bits. Thus, the absolute + * addressing mode allows access to the entire 65 K bytes of addressable memory. + */ + ABS("abs", "%i %p", 3), + /** + * Absolute X + * INDEX ABSOLUTE ADDRESSING — (X, Y indexing) — This form of addressing is used in conjunction with X and Y index + * register and is referred to as "Absolute. X," and “Absolute. Y." The effective address is formed by adding the + * contents of X and Y to the address contained in the second and third bytes of the instruction. This mode allows + * the index register to contain the index or count value and the instruction to contain the base address. This type + * of indexing allows any location referencing and the index to modify multiple fields resulting in reduced coding + * and execution time. + */ + ABX("abs,x", "%i %p,x", 3), + /** + * Absolute Y + * INDEX ABSOLUTE ADDRESSING — (X, Y indexing) — This form of addressing is used in conjunction with X and Y index + * register and is referred to as "Absolute. X," and “Absolute. Y." The effective address is formed by adding the + * contents of X and Y to the address contained in the second and third bytes of the instruction. This mode allows the + * index register to contain the index or count value and the instruction to contain the base address. This type of + * indexing allows any location referencing and the index to modify multiple fields resulting in reduced coding and + * execution time. + */ + ABY("abs,y", "%i %p,y", 4), + /** + * Indirect Zeropage X + * INDEXED INDIRECT ADDRESSING - In indexed indirect addressing (referred to as [Indirect, X]), the second byte of + * the instruction is added to the contents of the.X index register, discarding the carry. The result of this + * addition points to a memory + * location on page zero whose contents is the low order eight bits of the effective address. The next memory + * location in page zero contains the high order eight bits of the effective address. Both memory locations + * specifying the high and low order bytes of the effective address must be in page zero." + */ + IZX("(zp,x)", "%i (%p,x)", 2), + /** + * Indirect Zeropage Y + * INDIRECT INDEXED ADDRESSING — In indirect indexed addressing (referred to as (Indirect, Y]), the second byte of + * the instruction points to a memory location in page zero. The contents of this memory location is added to the + * contents of the Y index register, the result being the low order eight bits of the effective + * address. The carry from this addition is added to the contents of the next page zero memory location, the result + * being the high order eight bits of the effective address." + */ + IZY("(zp),y", "%i (%p),y", 2), + /** + * Relative + * RELATIVE ADDRESSING — Relative addressing is used only with branch instructions and establishes a destination for + * the conditional branch. The second byte of-the instruction becomes the operand which is an “Offset"" added to the + * contents of the lower eight bits of the program counter when the counter is set at the next instruction. The range + * of the offset is — 128 to + 127 bytes from the next instruction." + */ + REL("rel", "%i %p", 2), + /** + * Indirect Absolute + * ABSOLUTE INDIRECT — The second byte of the instruction contains the low order eight bits of a memory location. + * The high order eight bits of that memory location is contained in the third byte of the instruction. + * The contents of the fully specified memory location is the low order byte of the effective address. + * The next memory location contains the high order byte of the effective address which is loaded into the sixteen + * bits of the program counter. + */ + IND("(ind)", "%i (%p)", 3); + + /** The short name of the addressing mode. */ + private String name; + + /** The template for an instruction using the addressing mode. */ + private String template; + + /** The number of bytes that an instruction takes up when using the addressing mode. This includes both opcode and operands. */ + private int bytes; + + AsmAddressingMode(String name, String template, int bytes) { + this.bytes = bytes; + this.template = template; + this.name = name; + } + + public int getBytes() { + return bytes; + } + + public String getName() { + return name; + } + + public String getAsm(String mnemnonic, String parameter) { + String replaced = template.replace("%i", mnemnonic); + if(parameter != null) { + replaced = replaced.replace("%p", parameter); + } + return replaced; + } + +} diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmClobber.java b/src/main/java/dk/camelot64/cpufamily6502/AsmClobber.java similarity index 98% rename from src/main/java/dk/camelot64/kickc/asm/AsmClobber.java rename to src/main/java/dk/camelot64/cpufamily6502/AsmClobber.java index 41aa2be00..4b92a22cc 100644 --- a/src/main/java/dk/camelot64/kickc/asm/AsmClobber.java +++ b/src/main/java/dk/camelot64/cpufamily6502/AsmClobber.java @@ -1,4 +1,4 @@ -package dk.camelot64.kickc.asm; +package dk.camelot64.cpufamily6502; import java.io.Serializable; diff --git a/src/main/java/dk/camelot64/cpufamily6502/AsmInstructionSet.java b/src/main/java/dk/camelot64/cpufamily6502/AsmInstructionSet.java new file mode 100644 index 000000000..43dd9a064 --- /dev/null +++ b/src/main/java/dk/camelot64/cpufamily6502/AsmInstructionSet.java @@ -0,0 +1,396 @@ +package dk.camelot64.cpufamily6502; + +import java.util.*; + +/** + * The set of all 6502 assembler instructions + */ +public class AsmInstructionSet { + + private static AsmInstructionSet set = new AsmInstructionSet(); + + /** All instructions in the instruction set. */ + private List instructions; + + /** Maps mnemonic_addressingMode to the instruction opcode information */ + private Map instructionsMap; + + public AsmInstructionSet() { + this.instructions = new ArrayList<>(); + this.instructionsMap = new HashMap<>(); + add(0x00, "brk", AsmAddressingMode.NON, 7.0); + add(0x01, "ora", AsmAddressingMode.IZX, 6.0); + add(0x01, "ora", AsmAddressingMode.IZX, 6.0); + add(0x02, "kil", AsmAddressingMode.NON, 0.0); + add(0x03, "slo", AsmAddressingMode.IZX, 8.0); + add(0x04, "nop", AsmAddressingMode.ZP, 3.0); + add(0x05, "ora", AsmAddressingMode.ZP, 3.0); + add(0x06, "asl", AsmAddressingMode.ZP, 5.0); + add(0x07, "slo", AsmAddressingMode.ZP, 5.0); + add(0x08, "php", AsmAddressingMode.NON, 3.0); + add(0x09, "ora", AsmAddressingMode.IMM, 2.0); + add(0x0a, "asl", AsmAddressingMode.NON, 2.0); + add(0x0b, "anc", AsmAddressingMode.IMM, 2.0); + add(0x0c, "nop", AsmAddressingMode.ABS, 4.0); + add(0x0d, "ora", AsmAddressingMode.ABS, 4.0); + add(0x0e, "asl", AsmAddressingMode.ABS, 6.0); + add(0x0f, "slo", AsmAddressingMode.ABS, 6.0); + add(0x10, "bpl", AsmAddressingMode.REL, 2.5); + add(0x11, "ora", AsmAddressingMode.IZY, 5.5); + add(0x12, "kil", AsmAddressingMode.NON, 0.0); + add(0x13, "slo", AsmAddressingMode.IZY, 8.0); + add(0x14, "nop", AsmAddressingMode.ZPX, 4.0); + add(0x15, "ora", AsmAddressingMode.ZPX, 4.0); + add(0x16, "asl", AsmAddressingMode.ZPX, 6.0); + add(0x17, "slo", AsmAddressingMode.ZPX, 6.0); + add(0x18, "clc", AsmAddressingMode.NON, 2.0); + add(0x19, "ora", AsmAddressingMode.ABY, 4.5); + add(0x1a, "nop", AsmAddressingMode.NON, 2.0); + add(0x1b, "slo", AsmAddressingMode.ABY, 7.0); + add(0x1c, "nop", AsmAddressingMode.ABX, 4.5); + add(0x1d, "ora", AsmAddressingMode.ABX, 4.5); + add(0x1e, "asl", AsmAddressingMode.ABX, 7.0); + add(0x1f, "slo", AsmAddressingMode.ABX, 7.0); + add(0x20, "jsr", AsmAddressingMode.ABS, 6.0); + add(0x21, "and", AsmAddressingMode.IZX, 6.0); + add(0x22, "kil", AsmAddressingMode.NON, 0.0); + add(0x23, "rla", AsmAddressingMode.IZX, 8.0); + add(0x24, "bit", AsmAddressingMode.ZP, 3.0); + add(0x25, "and", AsmAddressingMode.ZP, 3.0); + add(0x26, "rol", AsmAddressingMode.ZP, 5.0); + add(0x27, "rla", AsmAddressingMode.ZP, 5.0); + add(0x28, "plp", AsmAddressingMode.NON, 4.0); + add(0x29, "and", AsmAddressingMode.IMM, 2.0); + add(0x2a, "rol", AsmAddressingMode.NON, 2.0); + add(0x2b, "anc", AsmAddressingMode.IMM, 2.0); + add(0x2c, "bit", AsmAddressingMode.ABS, 4.0); + add(0x2d, "and", AsmAddressingMode.ABS, 4.0); + add(0x2e, "rol", AsmAddressingMode.ABS, 6.0); + add(0x2f, "rla", AsmAddressingMode.ABS, 6.0); + add(0x30, "bmi", AsmAddressingMode.REL, 2.5); + add(0x31, "and", AsmAddressingMode.IZY, 5.5); + add(0x32, "kil", AsmAddressingMode.NON, 0.0); + add(0x33, "rla", AsmAddressingMode.IZY, 8.0); + add(0x34, "nop", AsmAddressingMode.ZPX, 4.0); + add(0x35, "and", AsmAddressingMode.ZPX, 4.0); + add(0x36, "rol", AsmAddressingMode.ZPX, 6.0); + add(0x37, "rla", AsmAddressingMode.ZPX, 6.0); + add(0x38, "sec", AsmAddressingMode.NON, 2.0); + add(0x39, "and", AsmAddressingMode.ABY, 4.5); + add(0x3a, "nop", AsmAddressingMode.NON, 2.0); + add(0x3b, "rla", AsmAddressingMode.ABY, 7.0); + add(0x3c, "nop", AsmAddressingMode.ABX, 4.5); + add(0x3d, "and", AsmAddressingMode.ABX, 4.5); + add(0x3e, "rol", AsmAddressingMode.ABX, 7.0); + add(0x3f, "rla", AsmAddressingMode.ABX, 7.0); + add(0x40, "rti", AsmAddressingMode.NON, 6.0); + add(0x41, "eor", AsmAddressingMode.IZX, 6.0); + add(0x42, "kil", AsmAddressingMode.NON, 0.0); + add(0x43, "sre", AsmAddressingMode.IZX, 8.0); + add(0x44, "nop", AsmAddressingMode.ZP, 3.0); + add(0x45, "eor", AsmAddressingMode.ZP, 3.0); + add(0x46, "lsr", AsmAddressingMode.ZP, 5.0); + add(0x47, "sre", AsmAddressingMode.ZP, 5.0); + add(0x48, "pha", AsmAddressingMode.NON, 3.0); + add(0x49, "eor", AsmAddressingMode.IMM, 2.0); + add(0x4a, "lsr", AsmAddressingMode.NON, 2.0); + add(0x4b, "alr", AsmAddressingMode.IMM, 2.0); + add(0x4c, "jmp", AsmAddressingMode.ABS, 3.0); + add(0x4d, "eor", AsmAddressingMode.ABS, 4.0); + add(0x4e, "lsr", AsmAddressingMode.ABS, 6.0); + add(0x4f, "sre", AsmAddressingMode.ABS, 6.0); + add(0x50, "bvc", AsmAddressingMode.REL, 2.5); + add(0x51, "eor", AsmAddressingMode.IZY, 5.5); + add(0x52, "kil", AsmAddressingMode.NON, 0.0); + add(0x53, "sre", AsmAddressingMode.IZY, 8.0); + add(0x54, "nop", AsmAddressingMode.ZPX, 4.0); + add(0x55, "eor", AsmAddressingMode.ZPX, 4.0); + add(0x56, "lsr", AsmAddressingMode.ZPX, 6.0); + add(0x57, "sre", AsmAddressingMode.ZPX, 6.0); + add(0x58, "cli", AsmAddressingMode.NON, 2.0); + add(0x59, "eor", AsmAddressingMode.ABY, 4.5); + add(0x5a, "nop", AsmAddressingMode.NON, 2.0); + add(0x5b, "sre", AsmAddressingMode.ABY, 7.0); + add(0x5c, "nop", AsmAddressingMode.ABX, 4.5); + add(0x5d, "eor", AsmAddressingMode.ABX, 4.5); + add(0x5e, "lsr", AsmAddressingMode.ABX, 7.0); + add(0x5f, "sre", AsmAddressingMode.ABX, 7.0); + add(0x60, "rts", AsmAddressingMode.NON, 6.0); + add(0x61, "adc", AsmAddressingMode.IZX, 6.0); + add(0x62, "kil", AsmAddressingMode.NON, 0.0); + add(0x63, "rra", AsmAddressingMode.IZX, 8.0); + add(0x64, "nop", AsmAddressingMode.ZP, 3.0); + add(0x65, "adc", AsmAddressingMode.ZP, 3.0); + add(0x66, "ror", AsmAddressingMode.ZP, 5.0); + add(0x67, "rra", AsmAddressingMode.ZP, 5.0); + add(0x68, "pla", AsmAddressingMode.NON, 4.0); + add(0x69, "adc", AsmAddressingMode.IMM, 2.0); + add(0x6a, "ror", AsmAddressingMode.NON, 2.0); + add(0x6b, "arr", AsmAddressingMode.IMM, 2.0); + add(0x6c, "jmp", AsmAddressingMode.IND, 5.0); + add(0x6d, "adc", AsmAddressingMode.ABS, 4.0); + add(0x6e, "ror", AsmAddressingMode.ABS, 6.0); + add(0x6f, "rra", AsmAddressingMode.ABS, 6.0); + add(0x70, "bvs", AsmAddressingMode.REL, 2.5); + add(0x71, "adc", AsmAddressingMode.IZY, 5.5); + add(0x72, "kil", AsmAddressingMode.NON, 0.0); + add(0x73, "rra", AsmAddressingMode.IZY, 8.0); + add(0x74, "nop", AsmAddressingMode.ZPX, 4.0); + add(0x75, "adc", AsmAddressingMode.ZPX, 4.0); + add(0x76, "ror", AsmAddressingMode.ZPX, 6.0); + add(0x77, "rra", AsmAddressingMode.ZPX, 6.0); + add(0x78, "sei", AsmAddressingMode.NON, 2.0); + add(0x79, "adc", AsmAddressingMode.ABY, 4.5); + add(0x7a, "nop", AsmAddressingMode.NON, 2.0); + add(0x7b, "rra", AsmAddressingMode.ABY, 7.0); + add(0x7c, "nop", AsmAddressingMode.ABX, 4.5); + add(0x7d, "adc", AsmAddressingMode.ABX, 4.5); + add(0x7e, "ror", AsmAddressingMode.ABX, 7.0); + add(0x7f, "rra", AsmAddressingMode.ABX, 7.0); + add(0x80, "nop", AsmAddressingMode.IMM, 2.0); + add(0x81, "sta", AsmAddressingMode.IZX, 6.0); + add(0x82, "nop", AsmAddressingMode.IMM, 2.0); + add(0x83, "sax", AsmAddressingMode.IZX, 6.0); + add(0x84, "sty", AsmAddressingMode.ZP, 3.0); + add(0x85, "sta", AsmAddressingMode.ZP, 3.0); + add(0x86, "stx", AsmAddressingMode.ZP, 3.0); + add(0x87, "sax", AsmAddressingMode.ZP, 3.0); + add(0x88, "dey", AsmAddressingMode.NON, 2.0); + add(0x89, "nop", AsmAddressingMode.IMM, 2.0); + add(0x8a, "txa", AsmAddressingMode.NON, 2.0); + add(0x8b, "xaa", AsmAddressingMode.IMM, 2.0); + add(0x8c, "sty", AsmAddressingMode.ABS, 4.0); + add(0x8d, "sta", AsmAddressingMode.ABS, 4.0); + add(0x8e, "stx", AsmAddressingMode.ABS, 4.0); + add(0x8f, "sax", AsmAddressingMode.ABS, 4.0); + add(0x90, "bcc", AsmAddressingMode.REL, 2.5); + add(0x91, "sta", AsmAddressingMode.IZY, 6.0); + add(0x92, "kil", AsmAddressingMode.NON, 0.0); + add(0x93, "ahx", AsmAddressingMode.IZY, 6.0); + add(0x94, "sty", AsmAddressingMode.ZPX, 4.0); + add(0x95, "sta", AsmAddressingMode.ZPX, 4.0); + add(0x96, "stx", AsmAddressingMode.ZPY, 4.0); + add(0x97, "sax", AsmAddressingMode.ZPY, 4.0); + add(0x98, "tya", AsmAddressingMode.NON, 2.0); + add(0x99, "sta", AsmAddressingMode.ABY, 5.0); + add(0x9a, "txs", AsmAddressingMode.NON, 2.0); + add(0x9b, "tas", AsmAddressingMode.ABY, 5.0); + add(0x9c, "shy", AsmAddressingMode.ABX, 5.0); + add(0x9d, "sta", AsmAddressingMode.ABX, 5.0); + add(0x9e, "shx", AsmAddressingMode.ABY, 5.0); + add(0x9f, "ahx", AsmAddressingMode.ABY, 5.0); + add(0xa0, "ldy", AsmAddressingMode.IMM, 2.0); + add(0xa1, "lda", AsmAddressingMode.IZX, 6.0); + add(0xa2, "ldx", AsmAddressingMode.IMM, 2.0); + add(0xa3, "lax", AsmAddressingMode.IZX, 6.0); + add(0xa4, "ldy", AsmAddressingMode.ZP, 3.0); + add(0xa5, "lda", AsmAddressingMode.ZP, 3.0); + add(0xa6, "ldx", AsmAddressingMode.ZP, 3.0); + add(0xa7, "lax", AsmAddressingMode.ZP, 3.0); + add(0xa8, "tay", AsmAddressingMode.NON, 2.0); + add(0xa9, "lda", AsmAddressingMode.IMM, 2.0); + add(0xaa, "tax", AsmAddressingMode.NON, 2.0); + add(0xab, "lax", AsmAddressingMode.IMM, 2.0); + add(0xac, "ldy", AsmAddressingMode.ABS, 4.0); + add(0xad, "lda", AsmAddressingMode.ABS, 4.0); + add(0xae, "ldx", AsmAddressingMode.ABS, 4.0); + add(0xaf, "lax", AsmAddressingMode.ABS, 4.0); + add(0xb0, "bcs", AsmAddressingMode.REL, 2.5); + add(0xb1, "lda", AsmAddressingMode.IZY, 5.5); + add(0xb2, "kil", AsmAddressingMode.NON, 0.0); + add(0xb3, "lax", AsmAddressingMode.IZY, 5.5); + add(0xb4, "ldy", AsmAddressingMode.ZPX, 4.0); + add(0xb5, "lda", AsmAddressingMode.ZPX, 4.0); + add(0xb6, "ldx", AsmAddressingMode.ZPY, 4.0); + add(0xb7, "lax", AsmAddressingMode.ZPY, 4.0); + add(0xb8, "clv", AsmAddressingMode.NON, 2.0); + add(0xb9, "lda", AsmAddressingMode.ABY, 4.5); + add(0xba, "tsx", AsmAddressingMode.NON, 2.0); + add(0xbb, "las", AsmAddressingMode.ABY, 4.5); + add(0xbc, "ldy", AsmAddressingMode.ABX, 4.5); + add(0xbd, "lda", AsmAddressingMode.ABX, 4.5); + add(0xbe, "ldx", AsmAddressingMode.ABY, 4.5); + add(0xbf, "lax", AsmAddressingMode.ABY, 4.5); + add(0xc0, "cpy", AsmAddressingMode.IMM, 2.0); + add(0xc1, "cmp", AsmAddressingMode.IZX, 6.0); + add(0xc2, "nop", AsmAddressingMode.IMM, 2.0); + add(0xc3, "dcp", AsmAddressingMode.IZX, 8.0); + add(0xc4, "cpy", AsmAddressingMode.ZP, 3.0); + add(0xc5, "cmp", AsmAddressingMode.ZP, 3.0); + add(0xc6, "dec", AsmAddressingMode.ZP, 5.0); + add(0xc7, "dcp", AsmAddressingMode.ZP, 5.0); + add(0xc8, "iny", AsmAddressingMode.NON, 2.0); + add(0xc9, "cmp", AsmAddressingMode.IMM, 2.0); + add(0xca, "dex", AsmAddressingMode.NON, 2.0); + add(0xcb, "axs", AsmAddressingMode.IMM, 2.0); + add(0xcc, "cpy", AsmAddressingMode.ABS, 4.0); + add(0xcd, "cmp", AsmAddressingMode.ABS, 4.0); + add(0xce, "dec", AsmAddressingMode.ABS, 6.0); + add(0xcf, "dcp", AsmAddressingMode.ABS, 6.0); + add(0xd0, "bne", AsmAddressingMode.REL, 2.5); + add(0xd1, "cmp", AsmAddressingMode.IZY, 5.5); + add(0xd2, "kil", AsmAddressingMode.NON, 0.0); + add(0xd3, "dcp", AsmAddressingMode.IZY, 8.0); + add(0xd4, "nop", AsmAddressingMode.ZPX, 4.0); + add(0xd5, "cmp", AsmAddressingMode.ZPX, 4.0); + add(0xd6, "dec", AsmAddressingMode.ZPX, 6.0); + add(0xd7, "dcp", AsmAddressingMode.ZPX, 6.0); + add(0xd8, "cld", AsmAddressingMode.NON, 2.0); + add(0xd9, "cmp", AsmAddressingMode.ABY, 4.5); + add(0xda, "nop", AsmAddressingMode.NON, 2.0); + add(0xdb, "dcp", AsmAddressingMode.ABY, 7.0); + add(0xdc, "nop", AsmAddressingMode.ABX, 4.5); + add(0xdd, "cmp", AsmAddressingMode.ABX, 4.5); + add(0xde, "dec", AsmAddressingMode.ABX, 7.0); + add(0xef, "cpx", AsmAddressingMode.IMM, 2.0); + add(0xe0, "sbc", AsmAddressingMode.IZX, 6.0); + add(0xe1, "nop", AsmAddressingMode.IMM, 2.0); + add(0xe2, "isc", AsmAddressingMode.IZX, 8.0); + add(0xe3, "cpx", AsmAddressingMode.ZP, 3.0); + add(0xe4, "sbc", AsmAddressingMode.ZP, 3.0); + add(0xe5, "inc", AsmAddressingMode.ZP, 5.0); + add(0xe6, "isc", AsmAddressingMode.ZP, 5.0); + add(0xe7, "inx", AsmAddressingMode.NON, 2.0); + add(0xe8, "sbc", AsmAddressingMode.IMM, 2.0); + add(0xe9, "nop", AsmAddressingMode.NON, 2.0); + add(0xea, "sbc", AsmAddressingMode.IMM, 2.0); + add(0xeb, "cpx", AsmAddressingMode.ABS, 4.0); + add(0xec, "sbc", AsmAddressingMode.ABS, 4.0); + add(0xed, "inc", AsmAddressingMode.ABS, 6.0); + add(0xee, "isc", AsmAddressingMode.ABS, 6.0); + add(0xef, "dcp", AsmAddressingMode.ABX, 7.0); + add(0xf0, "beq", AsmAddressingMode.REL, 2.5); + add(0xf1, "sbc", AsmAddressingMode.IZY, 5.5); + add(0xf2, "kil", AsmAddressingMode.NON, 0.0); + add(0xf3, "isc", AsmAddressingMode.IZY, 8.0); + add(0xf4, "nop", AsmAddressingMode.ZPX, 4.0); + add(0xf5, "sbc", AsmAddressingMode.ZPX, 4.0); + add(0xf6, "inc", AsmAddressingMode.ZPX, 6.0); + add(0xf7, "isc", AsmAddressingMode.ZPX, 6.0); + add(0xf8, "sed", AsmAddressingMode.NON, 2.0); + add(0xf9, "sbc", AsmAddressingMode.ABY, 4.5); + add(0xfa, "nop", AsmAddressingMode.NON, 2.0); + add(0xfb, "isc", AsmAddressingMode.ABY, 7.0); + add(0xfc, "nop", AsmAddressingMode.ABX, 4.5); + add(0xfd, "sbc", AsmAddressingMode.ABX, 4.5); + add(0xfe, "inc", AsmAddressingMode.ABX, 7.0); + add(0xff, "isc", AsmAddressingMode.ABX, 7.0); + + // 65c02 instructions + // TODO: create instruction set model that knows the different CPU's + add(0x1a, "inc", AsmAddressingMode.NON, 2.0); + + List jumps = Arrays.asList("jmp", "beq", "bne", "bcc", "bcs", "bvs", "bvc", "bmi", "bpl", "jsr"); + for(AsmOpcode instruction : instructions) { + if(jumps.contains(instruction.getMnemnonic())) { + instruction.setJump(true); + } + } + List cxs = Arrays.asList("dex", "inx", "ldx", "tax", "tsx", "las", "lax", "axs"); + for(AsmOpcode instruction : instructions) { + if(cxs.contains(instruction.getMnemnonic())) { + instruction.getClobber().setClobberX(true); + } + } + List cys = Arrays.asList("dey", "iny", "ldy", "tay"); + for(AsmOpcode instruction : instructions) { + if(cys.contains(instruction.getMnemnonic())) { + instruction.getClobber().setClobberY(true); + } + } + List cas = Arrays.asList("ora", "and", "eor", "adc", "sbc", "lda", "txa", "tya", "pla", "slo", "rla", "sre", "rra", "isc", "anc", "alr", "arr", "xaa", "lax", "las"); + for(AsmOpcode instruction : instructions) { + if(cas.contains(instruction.getMnemnonic())) { + instruction.getClobber().setClobberA(true); + } else if(instruction.getOpcode()==0x0a) { + // Special handling of ASL A + instruction.getClobber().setClobberA(true); + } else if(instruction.getOpcode()==0x2a) { + // Special handling of ROL A + instruction.getClobber().setClobberA(true); + } else if(instruction.getOpcode()==0x4a) { + // Special handling of LSR A + instruction.getClobber().setClobberA(true); + } else if(instruction.getOpcode()==0x6a) { + // Special handling of ROR A + instruction.getClobber().setClobberA(true); + } + + } + List ccs = Arrays.asList("adc", "sbc", "cmp", "cpx", "cpy", "asl", "rol", "lsr", "ror", "plp", "rti", "clc", "sec", "slo", "rla", "sre", "rra", "dcp", "isc", "anc", "alr", "arr", "axs"); + for(AsmOpcode instruction : instructions) { + if(ccs.contains(instruction.getMnemnonic())) { + instruction.getClobber().setClobberC(true); + } + } + List cvs = Arrays.asList("adc", "sbc", "plp", "rti", "bit", "rra", "isc", "arr"); + for(AsmOpcode instruction : instructions) { + if(cvs.contains(instruction.getMnemnonic())) { + instruction.getClobber().setClobberV(true); + } + } + List czs = Arrays.asList("ora", "and", "eor", "adc", "sbc", "cmp", "cpx", "cpy", "dec", "dex", "dey", "inc", "inx", "iny", "asl", "rol", "lsr", "ror", "lda", "ldx", "ldy", "tax", "txa", "tay", "tya", "tsx", "txs", "pla", "plp", "rti", "bit", "slo", "rla", "sre", "rra", "lax", "dcp", "isc", "anc", "alr", "arr", "xaa", "lax", "axs", "las"); + for(AsmOpcode instruction : instructions) { + if(czs.contains(instruction.getMnemnonic())) { + instruction.getClobber().setClobberZ(true); + instruction.getClobber().setClobberN(true); + } + } + } + + + /** + * Add an instruction to the instruction set. + * @param opcode The numeric opcode + * @param mnemonic The lower case mnemonic + * @param addressingmMode The addressing mode + * @param cycles The number of cycles + */ + private void add(int opcode, String mnemonic, AsmAddressingMode addressingmMode, double cycles) { + AsmOpcode instructionType = new AsmOpcode(opcode, mnemonic, addressingmMode, cycles); + instructions.add(instructionType); + instructionsMap.put(mnemonic + "_" + addressingmMode.getName(), instructionType); + } + + /** + * Get a specific instruction opcode form the instruction set + * @param mnemonic The mnemonic + * @param addressingMode The addressing mode + * @return The opcode, if is exists. Null if the instruction set does not have the opcode. + */ + public AsmOpcode getOpcode(String mnemonic, AsmAddressingMode addressingMode) { + String key = mnemonic.toLowerCase() + "_" + addressingMode.getName(); + return instructionsMap.get(key); + } + + /** + * Get an opcode from the instruction set in either absolute or zeropage form. + * This will try to find a zeropage-based addressing mode if you indicate that you are interested in that. + * @param mnemonic The mnemonic + * @param mode The addressing mode you want. + * @param isZp Indicates whether you are interested in a zeropage-based opcode. + * @return The opcode, if it exists. If you have requested an absolute addressing mode passed isZp as true the resulting opcode will have zeropage-based addressing the instruction set offers that. + */ + public static AsmOpcode getOpcode(String mnemonic, AsmAddressingMode mode, boolean isZp) { + AsmOpcode type = null; + if(AsmAddressingMode.ABS.equals(mode) && isZp) { + type = set.getOpcode(mnemonic, AsmAddressingMode.ZP); + } + if(AsmAddressingMode.ABX.equals(mode) && isZp) { + type = set.getOpcode(mnemonic, AsmAddressingMode.ZPX); + } + if(AsmAddressingMode.ABY.equals(mode) && isZp) { + type = set.getOpcode(mnemonic, AsmAddressingMode.ZPY); + } + if(type == null) { + type = set.getOpcode(mnemonic, mode); + } + if(type == null && AsmAddressingMode.ABS.equals(mode)) { + type = set.getOpcode(mnemonic, AsmAddressingMode.REL); + } + return type; + } + + + +} diff --git a/src/main/java/dk/camelot64/cpufamily6502/AsmOpcode.java b/src/main/java/dk/camelot64/cpufamily6502/AsmOpcode.java new file mode 100644 index 000000000..d66b07274 --- /dev/null +++ b/src/main/java/dk/camelot64/cpufamily6502/AsmOpcode.java @@ -0,0 +1,81 @@ +package dk.camelot64.cpufamily6502; + +/** A specific opcode in the instruction set of a 6502 family CPU. */ +public class AsmOpcode { + + /** The opcode of the instruction. */ + private final int opcode; + + /** The mnemonic of the instruction. */ + private final String mnemnonic; + + /** The addressing mode of the instruction. */ + private final AsmAddressingMode addressingMode; + + /** + * The number of cycles that executing the instruction takes. + * Some instructions use different number of cycles under different calling conditions, in that case this is an + * estimate of the average cycles cost. + */ + private final double cycles; + + /** + * True if the instruction is a jump or a branch. + * A jump is any instruction that can modify the program counter in a way that is not just incrementing it to the + * next instruction in memory. This includes JSR and RTS. + */ + private boolean jump; + + /** Which registers/flags of the CPU are clobbered by the instruction. */ + private final AsmClobber clobber; + + public AsmOpcode(int opcode, String mnemnonic, AsmAddressingMode addressingMode, double cycles) { + this.opcode = opcode; + this.mnemnonic = mnemnonic; + this.addressingMode = addressingMode; + this.cycles = cycles; + this.clobber = new AsmClobber(); + } + + public String getMnemnonic() { + return mnemnonic; + } + + public AsmAddressingMode getAddressingMode() { + return addressingMode; + } + + public double getCycles() { + return cycles; + } + + public int getBytes() { + return addressingMode.getBytes(); + } + + public int getOpcode() { + return opcode; + } + + public String getAsm(String parameter) { + return addressingMode.getAsm(mnemnonic, parameter); + } + + /** + * Tells if the instruction is a jump or a branch + * + * @return true if the instruction is a jump/branch + */ + public boolean isJump() { + return jump; + } + + void setJump(boolean jump) { + this.jump = jump; + } + + public AsmClobber getClobber() { + return clobber; + } + +} diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmAddressingMode.java b/src/main/java/dk/camelot64/kickc/asm/AsmAddressingMode.java deleted file mode 100644 index 0ef19dff9..000000000 --- a/src/main/java/dk/camelot64/kickc/asm/AsmAddressingMode.java +++ /dev/null @@ -1,47 +0,0 @@ -package dk.camelot64.kickc.asm; - -/** 6502 Assembler Instruction Addressing Modes. */ -public enum AsmAddressingMode { - NON("", "%i", 1), - IMM("#imm", "%i #%p", 2), - ZP("zp", "%i.z %p", 2), - ZPX("zp,x", "%i.z %p,x", 2), - ZPY("zp,y", "%i.z %p,y", 2), - ABS("abs", "%i %p", 3), - ABX("abs,x", "%i %p,x", 3), - ABY("abs,y", "%i %p,y", 4), - IZX("(zp,x)", "%i (%p,x)", 2), - IZY("(zp),y", "%i (%p),y", 2), - REL("rel", "%i %p", 2), - IND("(ind)", "%i (%p)", 3); - - - private String name; - - private String template; - - private int bytes; - - AsmAddressingMode(String name, String template, int bytes) { - this.bytes = bytes; - this.template = template; - this.name = name; - } - - public int getBytes() { - return bytes; - } - - public String getName() { - return name; - } - - public String getAsm(String mnemnonic, String parameter) { - String replaced = template.replace("%i", mnemnonic); - if(parameter != null) { - replaced = replaced.replace("%p", parameter); - } - return replaced; - } - -} diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmChunk.java b/src/main/java/dk/camelot64/kickc/asm/AsmChunk.java index a3367cc55..5e31e430a 100644 --- a/src/main/java/dk/camelot64/kickc/asm/AsmChunk.java +++ b/src/main/java/dk/camelot64/kickc/asm/AsmChunk.java @@ -1,5 +1,7 @@ package dk.camelot64.kickc.asm; +import dk.camelot64.cpufamily6502.AsmClobber; +import dk.camelot64.cpufamily6502.AsmOpcode; import dk.camelot64.kickc.model.PhiTransitions; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.statements.Statement; @@ -176,8 +178,8 @@ public class AsmChunk { for(AsmLine line : lines) { if(line instanceof AsmInstruction) { AsmInstruction asmInstruction = (AsmInstruction) line; - AsmInstructionType asmInstructionType = asmInstruction.getType(); - AsmClobber asmClobber = asmInstructionType.getClobber(); + AsmOpcode asmOpcode = asmInstruction.getAsmOpcode(); + AsmClobber asmClobber = asmOpcode.getClobber(); clobber.add(asmClobber); } } diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmInstruction.java b/src/main/java/dk/camelot64/kickc/asm/AsmInstruction.java index 7c777b68c..eec22794d 100644 --- a/src/main/java/dk/camelot64/kickc/asm/AsmInstruction.java +++ b/src/main/java/dk/camelot64/kickc/asm/AsmInstruction.java @@ -1,9 +1,11 @@ package dk.camelot64.kickc.asm; -/** An assembler instruction */ +import dk.camelot64.cpufamily6502.AsmOpcode; + +/** A specific assembler instruction line (opcode, addressing mode and specific parameter value)*/ public class AsmInstruction implements AsmLine { - private AsmInstructionType type; + private AsmOpcode asmOpcode; private String parameter; @@ -11,8 +13,8 @@ public class AsmInstruction implements AsmLine { private boolean dontOptimize; - public AsmInstruction(AsmInstructionType type, String parameter) { - this.type = type; + public AsmInstruction(AsmOpcode asmOpcode, String parameter) { + this.asmOpcode = asmOpcode; this.parameter = parameter; } @@ -24,27 +26,27 @@ public class AsmInstruction implements AsmLine { this.parameter = parameter; } - public AsmInstructionType getType() { - return type; + public AsmOpcode getAsmOpcode() { + return asmOpcode; } - public void setType(AsmInstructionType type) { - this.type = type; + public void setAsmOpcode(AsmOpcode type) { + this.asmOpcode = type; } @Override public int getLineBytes() { - return type.getBytes(); + return asmOpcode.getBytes(); } @Override public double getLineCycles() { - return type.getCycles(); + return asmOpcode.getCycles(); } @Override public String getAsm() { - return type.getAsm(parameter); + return asmOpcode.getAsm(parameter); } @Override diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmInstructionSet.java b/src/main/java/dk/camelot64/kickc/asm/AsmInstructionSet.java deleted file mode 100644 index b35ebf7b5..000000000 --- a/src/main/java/dk/camelot64/kickc/asm/AsmInstructionSet.java +++ /dev/null @@ -1,381 +0,0 @@ -package dk.camelot64.kickc.asm; - -import java.util.*; - -/** - * The set of all 6502 assembler instructions - */ -public class AsmInstructionSet { - - private static AsmInstructionSet set = new AsmInstructionSet(); - private List instructions; - /** Maps mnemonic_addressingmMode to the instruction type */ - private Map instructionsMap; - - public AsmInstructionSet() { - this.instructions = new ArrayList<>(); - this.instructionsMap = new HashMap<>(); - AsmAddressingMode non = AsmAddressingMode.NON; - AsmAddressingMode zp = AsmAddressingMode.ZP; - AsmAddressingMode zpx = AsmAddressingMode.ZPX; - AsmAddressingMode zpy = AsmAddressingMode.ZPY; - AsmAddressingMode imm = AsmAddressingMode.IMM; - AsmAddressingMode abs = AsmAddressingMode.ABS; - AsmAddressingMode abx = AsmAddressingMode.ABX; - AsmAddressingMode aby = AsmAddressingMode.ABY; - AsmAddressingMode izx = AsmAddressingMode.IZX; - AsmAddressingMode izy = AsmAddressingMode.IZY; - AsmAddressingMode rel = AsmAddressingMode.REL; - AsmAddressingMode ind = AsmAddressingMode.IND; - add(0x00, "brk", non, 7.0); - add(0x01, "ora", izx, 6.0); - add(0x01, "ora", izx, 6.0); - add(0x02, "kil", non, 0.0); - add(0x03, "slo", izx, 8.0); - add(0x04, "nop", zp, 3.0); - add(0x05, "ora", zp, 3.0); - add(0x06, "asl", zp, 5.0); - add(0x07, "slo", zp, 5.0); - add(0x08, "php", non, 3.0); - add(0x09, "ora", imm, 2.0); - add(0x0a, "asl", non, 2.0); - add(0x0b, "anc", imm, 2.0); - add(0x0c, "nop", abs, 4.0); - add(0x0d, "ora", abs, 4.0); - add(0x0e, "asl", abs, 6.0); - add(0x0f, "slo", abs, 6.0); - add(0x10, "bpl", rel, 2.5); - add(0x11, "ora", izy, 5.5); - add(0x12, "kil", non, 0.0); - add(0x13, "slo", izy, 8.0); - add(0x14, "nop", zpx, 4.0); - add(0x15, "ora", zpx, 4.0); - add(0x16, "asl", zpx, 6.0); - add(0x17, "slo", zpx, 6.0); - add(0x18, "clc", non, 2.0); - add(0x19, "ora", aby, 4.5); - add(0x1a, "nop", non, 2.0); - add(0x1b, "slo", aby, 7.0); - add(0x1c, "nop", abx, 4.5); - add(0x1d, "ora", abx, 4.5); - add(0x1e, "asl", abx, 7.0); - add(0x1f, "slo", abx, 7.0); - add(0x20, "jsr", abs, 6.0); - add(0x21, "and", izx, 6.0); - add(0x22, "kil", non, 0.0); - add(0x23, "rla", izx, 8.0); - add(0x24, "bit", zp, 3.0); - add(0x25, "and", zp, 3.0); - add(0x26, "rol", zp, 5.0); - add(0x27, "rla", zp, 5.0); - add(0x28, "plp", non, 4.0); - add(0x29, "and", imm, 2.0); - add(0x2a, "rol", non, 2.0); - add(0x2b, "anc", imm, 2.0); - add(0x2c, "bit", abs, 4.0); - add(0x2d, "and", abs, 4.0); - add(0x2e, "rol", abs, 6.0); - add(0x2f, "rla", abs, 6.0); - add(0x30, "bmi", rel, 2.5); - add(0x31, "and", izy, 5.5); - add(0x32, "kil", non, 0.0); - add(0x33, "rla", izy, 8.0); - add(0x34, "nop", zpx, 4.0); - add(0x35, "and", zpx, 4.0); - add(0x36, "rol", zpx, 6.0); - add(0x37, "rla", zpx, 6.0); - add(0x38, "sec", non, 2.0); - add(0x39, "and", aby, 4.5); - add(0x3a, "nop", non, 2.0); - add(0x3b, "rla", aby, 7.0); - add(0x3c, "nop", abx, 4.5); - add(0x3d, "and", abx, 4.5); - add(0x3e, "rol", abx, 7.0); - add(0x3f, "rla", abx, 7.0); - add(0x40, "rti", non, 6.0); - add(0x41, "eor", izx, 6.0); - add(0x42, "kil", non, 0.0); - add(0x43, "sre", izx, 8.0); - add(0x44, "nop", zp, 3.0); - add(0x45, "eor", zp, 3.0); - add(0x46, "lsr", zp, 5.0); - add(0x47, "sre", zp, 5.0); - add(0x48, "pha", non, 3.0); - add(0x49, "eor", imm, 2.0); - add(0x4a, "lsr", non, 2.0); - add(0x4b, "alr", imm, 2.0); - add(0x4c, "jmp", abs, 3.0); - add(0x4d, "eor", abs, 4.0); - add(0x4e, "lsr", abs, 6.0); - add(0x4f, "sre", abs, 6.0); - add(0x50, "bvc", rel, 2.5); - add(0x51, "eor", izy, 5.5); - add(0x52, "kil", non, 0.0); - add(0x53, "sre", izy, 8.0); - add(0x54, "nop", zpx, 4.0); - add(0x55, "eor", zpx, 4.0); - add(0x56, "lsr", zpx, 6.0); - add(0x57, "sre", zpx, 6.0); - add(0x58, "cli", non, 2.0); - add(0x59, "eor", aby, 4.5); - add(0x5a, "nop", non, 2.0); - add(0x5b, "sre", aby, 7.0); - add(0x5c, "nop", abx, 4.5); - add(0x5d, "eor", abx, 4.5); - add(0x5e, "lsr", abx, 7.0); - add(0x5f, "sre", abx, 7.0); - add(0x60, "rts", non, 6.0); - add(0x61, "adc", izx, 6.0); - add(0x62, "kil", non, 0.0); - add(0x63, "rra", izx, 8.0); - add(0x64, "nop", zp, 3.0); - add(0x65, "adc", zp, 3.0); - add(0x66, "ror", zp, 5.0); - add(0x67, "rra", zp, 5.0); - add(0x68, "pla", non, 4.0); - add(0x69, "adc", imm, 2.0); - add(0x6a, "ror", non, 2.0); - add(0x6b, "arr", imm, 2.0); - add(0x6c, "jmp", ind, 5.0); - add(0x6d, "adc", abs, 4.0); - add(0x6e, "ror", abs, 6.0); - add(0x6f, "rra", abs, 6.0); - add(0x70, "bvs", rel, 2.5); - add(0x71, "adc", izy, 5.5); - add(0x72, "kil", non, 0.0); - add(0x73, "rra", izy, 8.0); - add(0x74, "nop", zpx, 4.0); - add(0x75, "adc", zpx, 4.0); - add(0x76, "ror", zpx, 6.0); - add(0x77, "rra", zpx, 6.0); - add(0x78, "sei", non, 2.0); - add(0x79, "adc", aby, 4.5); - add(0x7a, "nop", non, 2.0); - add(0x7b, "rra", aby, 7.0); - add(0x7c, "nop", abx, 4.5); - add(0x7d, "adc", abx, 4.5); - add(0x7e, "ror", abx, 7.0); - add(0x7f, "rra", abx, 7.0); - add(0x80, "nop", imm, 2.0); - add(0x81, "sta", izx, 6.0); - add(0x82, "nop", imm, 2.0); - add(0x83, "sax", izx, 6.0); - add(0x84, "sty", zp, 3.0); - add(0x85, "sta", zp, 3.0); - add(0x86, "stx", zp, 3.0); - add(0x87, "sax", zp, 3.0); - add(0x88, "dey", non, 2.0); - add(0x89, "nop", imm, 2.0); - add(0x8a, "txa", non, 2.0); - add(0x8b, "xaa", imm, 2.0); - add(0x8c, "sty", abs, 4.0); - add(0x8d, "sta", abs, 4.0); - add(0x8e, "stx", abs, 4.0); - add(0x8f, "sax", abs, 4.0); - add(0x90, "bcc", rel, 2.5); - add(0x91, "sta", izy, 6.0); - add(0x92, "kil", non, 0.0); - add(0x93, "ahx", izy, 6.0); - add(0x94, "sty", zpx, 4.0); - add(0x95, "sta", zpx, 4.0); - add(0x96, "stx", zpy, 4.0); - add(0x97, "sax", zpy, 4.0); - add(0x98, "tya", non, 2.0); - add(0x99, "sta", aby, 5.0); - add(0x9a, "txs", non, 2.0); - add(0x9b, "tas", aby, 5.0); - add(0x9c, "shy", abx, 5.0); - add(0x9d, "sta", abx, 5.0); - add(0x9e, "shx", aby, 5.0); - add(0x9f, "ahx", aby, 5.0); - add(0xa0, "ldy", imm, 2.0); - add(0xa1, "lda", izx, 6.0); - add(0xa2, "ldx", imm, 2.0); - add(0xa3, "lax", izx, 6.0); - add(0xa4, "ldy", zp, 3.0); - add(0xa5, "lda", zp, 3.0); - add(0xa6, "ldx", zp, 3.0); - add(0xa7, "lax", zp, 3.0); - add(0xa8, "tay", non, 2.0); - add(0xa9, "lda", imm, 2.0); - add(0xaa, "tax", non, 2.0); - add(0xab, "lax", imm, 2.0); - add(0xac, "ldy", abs, 4.0); - add(0xad, "lda", abs, 4.0); - add(0xae, "ldx", abs, 4.0); - add(0xaf, "lax", abs, 4.0); - add(0xb0, "bcs", rel, 2.5); - add(0xb1, "lda", izy, 5.5); - add(0xb2, "kil", non, 0.0); - add(0xb3, "lax", izy, 5.5); - add(0xb4, "ldy", zpx, 4.0); - add(0xb5, "lda", zpx, 4.0); - add(0xb6, "ldx", zpy, 4.0); - add(0xb7, "lax", zpy, 4.0); - add(0xb8, "clv", non, 2.0); - add(0xb9, "lda", aby, 4.5); - add(0xba, "tsx", non, 2.0); - add(0xbb, "las", aby, 4.5); - add(0xbc, "ldy", abx, 4.5); - add(0xbd, "lda", abx, 4.5); - add(0xbe, "ldx", aby, 4.5); - add(0xbf, "lax", aby, 4.5); - add(0xc0, "cpy", imm, 2.0); - add(0xc1, "cmp", izx, 6.0); - add(0xc2, "nop", imm, 2.0); - add(0xc3, "dcp", izx, 8.0); - add(0xc4, "cpy", zp, 3.0); - add(0xc5, "cmp", zp, 3.0); - add(0xc6, "dec", zp, 5.0); - add(0xc7, "dcp", zp, 5.0); - add(0xc8, "iny", non, 2.0); - add(0xc9, "cmp", imm, 2.0); - add(0xca, "dex", non, 2.0); - add(0xcb, "axs", imm, 2.0); - add(0xcc, "cpy", abs, 4.0); - add(0xcd, "cmp", abs, 4.0); - add(0xce, "dec", abs, 6.0); - add(0xcf, "dcp", abs, 6.0); - add(0xd0, "bne", rel, 2.5); - add(0xd1, "cmp", izy, 5.5); - add(0xd2, "kil", non, 0.0); - add(0xd3, "dcp", izy, 8.0); - add(0xd4, "nop", zpx, 4.0); - add(0xd5, "cmp", zpx, 4.0); - add(0xd6, "dec", zpx, 6.0); - add(0xd7, "dcp", zpx, 6.0); - add(0xd8, "cld", non, 2.0); - add(0xd9, "cmp", aby, 4.5); - add(0xda, "nop", non, 2.0); - add(0xdb, "dcp", aby, 7.0); - add(0xdc, "nop", abx, 4.5); - add(0xdd, "cmp", abx, 4.5); - add(0xde, "dec", abx, 7.0); - add(0xef, "cpx", imm, 2.0); - add(0xe0, "sbc", izx, 6.0); - add(0xe1, "nop", imm, 2.0); - add(0xe2, "isc", izx, 8.0); - add(0xe3, "cpx", zp, 3.0); - add(0xe4, "sbc", zp, 3.0); - add(0xe5, "inc", zp, 5.0); - add(0xe6, "isc", zp, 5.0); - add(0xe7, "inx", non, 2.0); - add(0xe8, "sbc", imm, 2.0); - add(0xe9, "nop", non, 2.0); - add(0xea, "sbc", imm, 2.0); - add(0xeb, "cpx", abs, 4.0); - add(0xec, "sbc", abs, 4.0); - add(0xed, "inc", abs, 6.0); - add(0xee, "isc", abs, 6.0); - add(0xef, "dcp", abx, 7.0); - add(0xf0, "beq", rel, 2.5); - add(0xf1, "sbc", izy, 5.5); - add(0xf2, "kil", non, 0.0); - add(0xf3, "isc", izy, 8.0); - add(0xf4, "nop", zpx, 4.0); - add(0xf5, "sbc", zpx, 4.0); - add(0xf6, "inc", zpx, 6.0); - add(0xf7, "isc", zpx, 6.0); - add(0xf8, "sed", non, 2.0); - add(0xf9, "sbc", aby, 4.5); - add(0xfa, "nop", non, 2.0); - add(0xfb, "isc", aby, 7.0); - add(0xfc, "nop", abx, 4.5); - add(0xfd, "sbc", abx, 4.5); - add(0xfe, "inc", abx, 7.0); - add(0xff, "isc", abx, 7.0); - - // 65c02 instructions - // TODO: create instruction set model that knows the different CPU's - add(0x1a, "inc", non, 2.0); - - List jumps = Arrays.asList("jmp", "beq", "bne", "bcc", "bcs", "bvs", "bvc", "bmi", "bpl", "jsr"); - for(AsmInstructionType instruction : instructions) { - if(jumps.contains(instruction.getMnemnonic())) { - instruction.setJump(true); - } - } - List cxs = Arrays.asList("dex", "inx", "ldx", "tax", "tsx", "las", "lax", "axs"); - for(AsmInstructionType instruction : instructions) { - if(cxs.contains(instruction.getMnemnonic())) { - instruction.getClobber().setClobberX(true); - } - } - List cys = Arrays.asList("dey", "iny", "ldy", "tay"); - for(AsmInstructionType instruction : instructions) { - if(cys.contains(instruction.getMnemnonic())) { - instruction.getClobber().setClobberY(true); - } - } - List cas = Arrays.asList("ora", "and", "eor", "adc", "sbc", "lda", "txa", "tya", "pla", "slo", "rla", "sre", "rra", "isc", "anc", "alr", "arr", "xaa", "lax", "las"); - for(AsmInstructionType instruction : instructions) { - if(cas.contains(instruction.getMnemnonic())) { - instruction.getClobber().setClobberA(true); - } else if(instruction.getOpcode()==0x0a) { - // Special handling of ASL A - instruction.getClobber().setClobberA(true); - } else if(instruction.getOpcode()==0x2a) { - // Special handling of ROL A - instruction.getClobber().setClobberA(true); - } else if(instruction.getOpcode()==0x4a) { - // Special handling of LSR A - instruction.getClobber().setClobberA(true); - } else if(instruction.getOpcode()==0x6a) { - // Special handling of ROR A - instruction.getClobber().setClobberA(true); - } - - } - List ccs = Arrays.asList("adc", "sbc", "cmp", "cpx", "cpy", "asl", "rol", "lsr", "ror", "plp", "rti", "clc", "sec", "slo", "rla", "sre", "rra", "dcp", "isc", "anc", "alr", "arr", "axs"); - for(AsmInstructionType instruction : instructions) { - if(ccs.contains(instruction.getMnemnonic())) { - instruction.getClobber().setClobberC(true); - } - } - List cvs = Arrays.asList("adc", "sbc", "plp", "rti", "bit", "rra", "isc", "arr"); - for(AsmInstructionType instruction : instructions) { - if(cvs.contains(instruction.getMnemnonic())) { - instruction.getClobber().setClobberV(true); - } - } - List czs = Arrays.asList("ora", "and", "eor", "adc", "sbc", "cmp", "cpx", "cpy", "dec", "dex", "dey", "inc", "inx", "iny", "asl", "rol", "lsr", "ror", "lda", "ldx", "ldy", "tax", "txa", "tay", "tya", "tsx", "txs", "pla", "plp", "rti", "bit", "slo", "rla", "sre", "rra", "lax", "dcp", "isc", "anc", "alr", "arr", "xaa", "lax", "axs", "las"); - for(AsmInstructionType instruction : instructions) { - if(czs.contains(instruction.getMnemnonic())) { - instruction.getClobber().setClobberZ(true); - instruction.getClobber().setClobberN(true); - } - } - } - - public static AsmInstructionType getInstructionType(String mnemonic, AsmAddressingMode mode, boolean isZp) { - AsmInstructionType type = null; - if(AsmAddressingMode.ABS.equals(mode) && isZp) { - type = set.getType(mnemonic, AsmAddressingMode.ZP); - } - if(AsmAddressingMode.ABX.equals(mode) && isZp) { - type = set.getType(mnemonic, AsmAddressingMode.ZPX); - } - if(AsmAddressingMode.ABY.equals(mode) && isZp) { - type = set.getType(mnemonic, AsmAddressingMode.ZPY); - } - if(type == null) { - type = set.getType(mnemonic, mode); - } - if(type == null && AsmAddressingMode.ABS.equals(mode)) { - type = set.getType(mnemonic, AsmAddressingMode.REL); - } - return type; - } - - private void add(int opcode, String mnemonic, AsmAddressingMode addressingmMode, double cycles) { - AsmInstructionType instructionType = new AsmInstructionType(opcode, mnemonic, addressingmMode, cycles); - instructions.add(instructionType); - instructionsMap.put(mnemonic + "_" + addressingmMode.getName(), instructionType); - } - - public AsmInstructionType getType(String mnemonic, AsmAddressingMode addressingMode) { - String key = mnemonic.toLowerCase() + "_" + addressingMode.getName(); - return instructionsMap.get(key); - } - -} diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmInstructionType.java b/src/main/java/dk/camelot64/kickc/asm/AsmInstructionType.java deleted file mode 100644 index 7319151c7..000000000 --- a/src/main/java/dk/camelot64/kickc/asm/AsmInstructionType.java +++ /dev/null @@ -1,66 +0,0 @@ -package dk.camelot64.kickc.asm; - -/** The instructions of the 6502 assembler instruction set */ -public class AsmInstructionType { - - private int opcode; - - private String mnemnonic; - - private AsmAddressingMode addressingMode; - - private double cycles; - - private boolean jump; - - private AsmClobber clobber; - - public AsmInstructionType(int opcode, String mnemnonic, AsmAddressingMode addressingMode, double cycles) { - this.opcode = opcode; - this.mnemnonic = mnemnonic; - this.addressingMode = addressingMode; - this.cycles = cycles; - this.clobber = new AsmClobber(); - } - - public String getMnemnonic() { - return mnemnonic; - } - - public AsmAddressingMode getAddressingMode() { - return addressingMode; - } - - public double getCycles() { - return cycles; - } - - public int getBytes() { - return addressingMode.getBytes(); - } - - public int getOpcode() { - return opcode; - } - - public String getAsm(String parameter) { - return addressingMode.getAsm(mnemnonic, parameter); - } - - /** - * Tells if the instruction is a jump or a branch (and the parameter is therefore a label or destination address). - * - * @return true if the instruction is a jump/branch - */ - public boolean isJump() { - return jump; - } - - void setJump(boolean jump) { - this.jump = jump; - } - - public AsmClobber getClobber() { - return clobber; - } -} diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmProgram.java b/src/main/java/dk/camelot64/kickc/asm/AsmProgram.java index 14aa10f3d..5864fdb77 100644 --- a/src/main/java/dk/camelot64/kickc/asm/AsmProgram.java +++ b/src/main/java/dk/camelot64/kickc/asm/AsmProgram.java @@ -1,5 +1,9 @@ package dk.camelot64.kickc.asm; +import dk.camelot64.cpufamily6502.AsmAddressingMode; +import dk.camelot64.cpufamily6502.AsmClobber; +import dk.camelot64.cpufamily6502.AsmInstructionSet; +import dk.camelot64.cpufamily6502.AsmOpcode; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.values.ScopeRef; @@ -100,10 +104,10 @@ public class AsmProgram { } public AsmInstruction addInstruction(String mnemonic, AsmAddressingMode addressingMode, String parameter, boolean zp) { - AsmInstructionType instructionType = AsmInstructionSet.getInstructionType(mnemonic, addressingMode, zp); - AsmInstruction instruction = new AsmInstruction(instructionType, parameter); - addLine(instruction); - return instruction; + AsmOpcode asmOpcode = AsmInstructionSet.getOpcode(mnemonic, addressingMode, zp); + AsmInstruction asmInstruction = new AsmInstruction(asmOpcode, parameter); + addLine(asmInstruction); + return asmInstruction; } public void addLabelDecl(String name, String value) { diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmProgramStaticRegisterValues.java b/src/main/java/dk/camelot64/kickc/asm/AsmProgramStaticRegisterValues.java index bb28a445e..860bfcd00 100644 --- a/src/main/java/dk/camelot64/kickc/asm/AsmProgramStaticRegisterValues.java +++ b/src/main/java/dk/camelot64/kickc/asm/AsmProgramStaticRegisterValues.java @@ -1,5 +1,9 @@ package dk.camelot64.kickc.asm; +import dk.camelot64.cpufamily6502.AsmAddressingMode; +import dk.camelot64.cpufamily6502.AsmClobber; +import dk.camelot64.cpufamily6502.AsmOpcode; + import java.util.LinkedHashMap; import java.util.Map; @@ -83,37 +87,37 @@ public class AsmProgramStaticRegisterValues { AsmInstruction instruction = (AsmInstruction) line; values.put(instruction, current); current = new AsmRegisterValues(current); - AsmInstructionType instructionType = instruction.getType(); - AsmClobber clobber = instructionType.getClobber(); - if(instruction.getType().getMnemnonic().equals("jsr")) { - clobber = AsmClobber.CLOBBER_ALL; + AsmOpcode asmOpcode = instruction.getAsmOpcode(); + AsmClobber asmClobber = asmOpcode.getClobber(); + if(instruction.getAsmOpcode().getMnemnonic().equals("jsr")) { + asmClobber = AsmClobber.CLOBBER_ALL; } - if(clobber.isClobberA()) { + if(asmClobber.isClobberA()) { current.setA(null); current.setaMem(null); } - if(clobber.isClobberX()) { + if(asmClobber.isClobberX()) { current.setX(null); current.setxMem(null); } - if(clobber.isClobberY()) { + if(asmClobber.isClobberY()) { current.setY(null); current.setyMem(null); } - if(clobber.isClobberC()) { + if(asmClobber.isClobberC()) { current.setC(null); } - if(clobber.isClobberN()) { + if(asmClobber.isClobberN()) { current.setN(null); } - if(clobber.isClobberV()) { + if(asmClobber.isClobberV()) { current.setV(null); } - if(clobber.isClobberZ()) { + if(asmClobber.isClobberZ()) { current.setZ(null); } - String mnemnonic = instructionType.getMnemnonic(); - AsmAddressingMode addressingMode = instructionType.getAddressingMode(); + String mnemnonic = asmOpcode.getMnemnonic(); + AsmAddressingMode addressingMode = asmOpcode.getAddressingMode(); if((mnemnonic.equals("inc") || mnemnonic.equals("dec") || mnemnonic.equals("ror") || mnemnonic.equals("rol") || mnemnonic.equals("lsr") || mnemnonic.equals("asl")) && (addressingMode.equals(AsmAddressingMode.ZP) || addressingMode.equals(AsmAddressingMode.ABS))) { String modParam = instruction.getParameter(); if(current.getaMem() != null && current.getaMem().equals(modParam)) { diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentClobber.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentClobber.java index 31fde9a92..7b41ee6cf 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentClobber.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentClobber.java @@ -1,6 +1,6 @@ package dk.camelot64.kickc.fragment; -import dk.camelot64.kickc.asm.AsmClobber; +import dk.camelot64.cpufamily6502.AsmClobber; /** The clobber profile for a fragment template. Only distinguishes the 3 registers A/X/Y and not the flags. */ public class AsmFragmentClobber implements Comparable { diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java index 974f8bfeb..9a01cfc86 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java @@ -1,5 +1,8 @@ package dk.camelot64.kickc.fragment; +import dk.camelot64.cpufamily6502.AsmAddressingMode; +import dk.camelot64.cpufamily6502.AsmInstructionSet; +import dk.camelot64.cpufamily6502.AsmOpcode; import dk.camelot64.kickc.NumberParser; import dk.camelot64.kickc.asm.*; import dk.camelot64.kickc.model.ConstantNotLiteral; @@ -80,7 +83,7 @@ public class AsmFragmentInstance { Registers.Register register = boundVar.getAllocation(); if(register != null && register instanceof Registers.RegisterZpMem) { return new AsmParameter(AsmFormat.getAsmSymbolName(program, boundVar, codeScopeRef), true); - } else if(register!=null && register instanceof Registers.RegisterMainMem) { + } else if(register != null && register instanceof Registers.RegisterMainMem) { return new AsmParameter(AsmFormat.getAsmSymbolName(program, boundVar, codeScopeRef), false); } else { throw new RuntimeException("Register Type not implemented " + register); @@ -109,6 +112,7 @@ public class AsmFragmentInstance { /** * Determine whether a constant value representing an address in memory is located on zeropage. + * * @param boundConst The constant value * @return true if the address represented by the constant is 0<=val<=255 */ @@ -224,14 +228,11 @@ public class AsmFragmentInstance { AsmInstruction instruction; if(paramModeCtx == null) { final String mnemonic = ctx.ASM_MNEMONIC().getText(); - AsmInstructionType type = AsmInstructionSet.getInstructionType( - mnemonic, - AsmAddressingMode.NON, - false); - if(type == null) { + AsmOpcode asmOpcode = AsmInstructionSet.getOpcode(mnemonic, AsmAddressingMode.NON, false); + if(asmOpcode == null) { throw new InternalError("Error in " + name + ".asm line " + ctx.getStart().getLine() + " - Instruction type unknown " + mnemonic + " " + AsmAddressingMode.NON); } - instruction = new AsmInstruction(type, null); + instruction = new AsmInstruction(asmOpcode, null); } else { instruction = (AsmInstruction) this.visit(paramModeCtx); } @@ -297,14 +298,11 @@ public class AsmFragmentInstance { KickCParser.AsmInstructionContext instructionCtx = (KickCParser.AsmInstructionContext) ctx.getParent(); AsmParameter parameter = (AsmParameter) this.visit(exprCtx); String mnemonic = instructionCtx.ASM_MNEMONIC().getSymbol().getText(); - AsmInstructionType type = AsmInstructionSet.getInstructionType( - mnemonic, - addressingMode, - parameter.isZp()); - if(type == null) { + AsmOpcode asmOpcode = AsmInstructionSet.getOpcode(mnemonic, addressingMode, parameter.isZp()); + if(asmOpcode == null) { throw new InternalError("Error in " + name + ".asm line " + instructionCtx.getStart().getLine() + " - Instruction type unknown " + mnemonic + " " + addressingMode + " " + parameter); } - return new AsmInstruction(type, parameter.getParam()); + return new AsmInstruction(asmOpcode, parameter.getParam()); } @Override diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentTemplate.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentTemplate.java index 8b05eb6c2..b50a75707 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentTemplate.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentTemplate.java @@ -1,6 +1,6 @@ package dk.camelot64.kickc.fragment; -import dk.camelot64.kickc.asm.AsmClobber; +import dk.camelot64.cpufamily6502.AsmClobber; import dk.camelot64.kickc.asm.AsmProgram; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.Registers; diff --git a/src/main/java/dk/camelot64/kickc/model/statements/StatementAsm.java b/src/main/java/dk/camelot64/kickc/model/statements/StatementAsm.java index b338224e8..15db234bd 100644 --- a/src/main/java/dk/camelot64/kickc/model/statements/StatementAsm.java +++ b/src/main/java/dk/camelot64/kickc/model/statements/StatementAsm.java @@ -1,6 +1,6 @@ package dk.camelot64.kickc.model.statements; -import dk.camelot64.kickc.asm.AsmClobber; +import dk.camelot64.cpufamily6502.AsmClobber; import dk.camelot64.kickc.model.Comment; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.values.SymbolRef; diff --git a/src/main/java/dk/camelot64/kickc/model/statements/StatementKickAsm.java b/src/main/java/dk/camelot64/kickc/model/statements/StatementKickAsm.java index c96a7615e..106b3482f 100644 --- a/src/main/java/dk/camelot64/kickc/model/statements/StatementKickAsm.java +++ b/src/main/java/dk/camelot64/kickc/model/statements/StatementKickAsm.java @@ -1,6 +1,6 @@ package dk.camelot64.kickc.model.statements; -import dk.camelot64.kickc.asm.AsmClobber; +import dk.camelot64.cpufamily6502.AsmClobber; import dk.camelot64.kickc.model.Comment; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.values.RValue; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java index 8e801d70e..702d73b90 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java @@ -2,7 +2,7 @@ package dk.camelot64.kickc.passes; import dk.camelot64.kickc.NumberParser; import dk.camelot64.kickc.SourceLoader; -import dk.camelot64.kickc.asm.AsmClobber; +import dk.camelot64.cpufamily6502.AsmClobber; import dk.camelot64.kickc.model.InternalError; import dk.camelot64.kickc.model.*; import dk.camelot64.kickc.model.operators.*; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4AssertNoCpuClobber.java b/src/main/java/dk/camelot64/kickc/passes/Pass4AssertNoCpuClobber.java index bdf1c3358..11ff7795e 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4AssertNoCpuClobber.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4AssertNoCpuClobber.java @@ -1,7 +1,7 @@ package dk.camelot64.kickc.passes; import dk.camelot64.kickc.asm.AsmChunk; -import dk.camelot64.kickc.asm.AsmClobber; +import dk.camelot64.cpufamily6502.AsmClobber; import dk.camelot64.kickc.asm.AsmProgram; import dk.camelot64.kickc.model.*; import dk.camelot64.kickc.model.statements.*; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java index cacadc860..9dba69da9 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java @@ -1,5 +1,7 @@ package dk.camelot64.kickc.passes; +import dk.camelot64.cpufamily6502.AsmAddressingMode; +import dk.camelot64.cpufamily6502.AsmClobber; import dk.camelot64.kickc.asm.*; import dk.camelot64.kickc.fragment.*; import dk.camelot64.kickc.model.InternalError; @@ -914,7 +916,7 @@ public class Pass4CodeGeneration { for(AsmLine asmLine : currentChunk.getLines()) { if(asmLine instanceof AsmInstruction) { AsmInstruction asmInstruction = (AsmInstruction) asmLine; - if(asmInstruction.getType().getMnemnonic().equals("jsr")) { + if(asmInstruction.getAsmOpcode().getMnemnonic().equals("jsr")) { currentChunk.setClobberOverwrite(AsmClobber.CLOBBER_ALL); } } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4InterruptClobberFix.java b/src/main/java/dk/camelot64/kickc/passes/Pass4InterruptClobberFix.java index fe5f437bb..6a91289c4 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4InterruptClobberFix.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4InterruptClobberFix.java @@ -1,7 +1,7 @@ package dk.camelot64.kickc.passes; import dk.camelot64.kickc.asm.AsmChunk; -import dk.camelot64.kickc.asm.AsmClobber; +import dk.camelot64.cpufamily6502.AsmClobber; import dk.camelot64.kickc.asm.AsmLine; import dk.camelot64.kickc.asm.AsmProgram; import dk.camelot64.kickc.model.CallGraph; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftPotentialRegisterAnalysis.java b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftPotentialRegisterAnalysis.java index 75a52e81f..ff34d1b79 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftPotentialRegisterAnalysis.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftPotentialRegisterAnalysis.java @@ -1,6 +1,6 @@ package dk.camelot64.kickc.passes; -import dk.camelot64.kickc.asm.AsmClobber; +import dk.camelot64.cpufamily6502.AsmClobber; import dk.camelot64.kickc.asm.AsmProgram; import dk.camelot64.kickc.fragment.AsmFragmentInstance; import dk.camelot64.kickc.fragment.AsmFragmentTemplateSynthesizer; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass5AddMainRts.java b/src/main/java/dk/camelot64/kickc/passes/Pass5AddMainRts.java index bd737a32c..cb7d610a5 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass5AddMainRts.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass5AddMainRts.java @@ -1,5 +1,7 @@ package dk.camelot64.kickc.passes; +import dk.camelot64.cpufamily6502.AsmAddressingMode; +import dk.camelot64.cpufamily6502.AsmInstructionSet; import dk.camelot64.kickc.asm.*; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.values.ScopeRef; @@ -25,7 +27,7 @@ public class Pass5AddMainRts extends Pass5AsmOptimization { AsmLine line = lineIterator.next(); if(line instanceof AsmInstruction) { AsmInstruction instruction = (AsmInstruction) line; - if(instruction.getType().getMnemnonic().equals("jsr")) { + if(instruction.getAsmOpcode().getMnemnonic().equals("jsr")) { if(instruction.getParameter().equals(SymbolRef.MAIN_PROC_NAME)) { // Add RTS if it is missing if(!lineIterator.hasNext()) { @@ -38,7 +40,7 @@ public class Pass5AddMainRts extends Pass5AsmOptimization { return true; } AsmInstruction nextInstruction = (AsmInstruction) nextLine; - if(!nextInstruction.getType().getMnemnonic().equals("rts")) { + if(!nextInstruction.getAsmOpcode().getMnemnonic().equals("rts")) { addRts(lineIterator); return true; } @@ -52,7 +54,7 @@ public class Pass5AddMainRts extends Pass5AsmOptimization { } private void addRts(ListIterator lineIterator) { - lineIterator.add(new AsmInstruction(AsmInstructionSet.getInstructionType("rts", AsmAddressingMode.NON, false), null)); + lineIterator.add(new AsmInstruction(AsmInstructionSet.getOpcode("rts", AsmAddressingMode.NON, false), null)); getLog().append("Adding RTS to root block "); } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass5DoubleJumpElimination.java b/src/main/java/dk/camelot64/kickc/passes/Pass5DoubleJumpElimination.java index 536db5585..9860f3111 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass5DoubleJumpElimination.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass5DoubleJumpElimination.java @@ -1,5 +1,8 @@ package dk.camelot64.kickc.passes; +import dk.camelot64.cpufamily6502.AsmAddressingMode; +import dk.camelot64.cpufamily6502.AsmInstructionSet; +import dk.camelot64.cpufamily6502.AsmOpcode; import dk.camelot64.kickc.asm.*; import dk.camelot64.kickc.model.Program; @@ -39,12 +42,12 @@ public class Pass5DoubleJumpElimination extends Pass5AsmOptimization { } else if(line instanceof AsmInstruction) { if(currentLabel != null) { AsmInstruction asmInstruction = (AsmInstruction) line; - AsmInstructionType jmpType = AsmInstructionSet.getInstructionType("jmp", AsmAddressingMode.ABS, false); - AsmInstructionType rtsType = AsmInstructionSet.getInstructionType("rts", AsmAddressingMode.NON, false); - if(asmInstruction.getType().equals(jmpType)) { + AsmOpcode jmpOpcode = AsmInstructionSet.getOpcode("jmp", AsmAddressingMode.ABS, false); + AsmOpcode rtsOpcode = AsmInstructionSet.getOpcode("rts", AsmAddressingMode.NON, false); + if(asmInstruction.getAsmOpcode().equals(jmpOpcode)) { immediateJumps.put(currentScope + "::" + currentLabel, asmInstruction.getParameter()); } - if(asmInstruction.getType().equals(rtsType)) { + if(asmInstruction.getAsmOpcode().equals(rtsOpcode)) { immediateJumps.put(currentScope + "::" + currentLabel, "rts"); } } @@ -64,12 +67,12 @@ public class Pass5DoubleJumpElimination extends Pass5AsmOptimization { currentScope = ""; } else if(line instanceof AsmInstruction) { AsmInstruction asmInstruction = (AsmInstruction) line; - if(asmInstruction.getType().isJump()) { + if(asmInstruction.getAsmOpcode().isJump()) { String immediateJmpTarget = immediateJumps.get(currentScope + "::" + asmInstruction.getParameter()); - if(immediateJmpTarget == "rts" && asmInstruction.getType().getMnemnonic() == "jmp") { + if(immediateJmpTarget == "rts" && asmInstruction.getAsmOpcode().getMnemnonic() == "jmp") { getLog().append("Replacing jump to rts with rts in " + asmInstruction.toString()); - AsmInstructionType rtsType = AsmInstructionSet.getInstructionType("rts", AsmAddressingMode.NON, false); - asmInstruction.setType(rtsType); + AsmOpcode rtsOpcode = AsmInstructionSet.getOpcode("rts", AsmAddressingMode.NON, false); + asmInstruction.setAsmOpcode(rtsOpcode); optimized = true; } else if(immediateJmpTarget != null && immediateJmpTarget != "rts" && !immediateJmpTarget.equals(asmInstruction.getParameter())) { getLog().append("Skipping double jump to " + immediateJmpTarget + " in " + asmInstruction.toString()); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass5FixLongBranches.java b/src/main/java/dk/camelot64/kickc/passes/Pass5FixLongBranches.java index e610c92a0..a3f08d245 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass5FixLongBranches.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass5FixLongBranches.java @@ -1,5 +1,8 @@ package dk.camelot64.kickc.passes; +import dk.camelot64.cpufamily6502.AsmAddressingMode; +import dk.camelot64.cpufamily6502.AsmInstructionSet; +import dk.camelot64.cpufamily6502.AsmOpcode; import dk.camelot64.kickc.asm.*; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.Program; @@ -157,17 +160,17 @@ public class Pass5FixLongBranches extends Pass5AsmOptimization { if(asmLine != null && asmLine instanceof AsmInstruction) { //getLog().append("Found ASM line "+asmLine); AsmInstruction asmInstruction = (AsmInstruction) asmLine; - AsmInstructionType asmInstructionType = asmInstruction.getType(); - AsmInstructionType inverseType = invertBranch(asmInstructionType); - if(inverseType != null) { + AsmOpcode asmOpcode = asmInstruction.getAsmOpcode(); + AsmOpcode inverseAsmOpcode = invertBranch(asmOpcode); + if(inverseAsmOpcode != null) { //getLog().append("Inversed branch instruction "+asmInstructionType.getMnemnonic()+" -> "+inverseType.getMnemnonic()); - getLog().append("Fixing long branch [" + idx + "] " + asmLine.toString() + " to " + inverseType.getMnemnonic()); + getLog().append("Fixing long branch [" + idx + "] " + asmLine.toString() + " to " + inverseAsmOpcode.getMnemnonic()); String branchDest = asmInstruction.getParameter(); - asmInstruction.setType(inverseType); + asmInstruction.setAsmOpcode(inverseAsmOpcode); String newLabel = AsmFormat.asmFix("!" + branchDest); asmInstruction.setParameter(newLabel+"+"); - AsmInstructionType jmpType = AsmInstructionSet.getInstructionType("jmp", AsmAddressingMode.ABS, false); - AsmInstruction jmpInstruction = new AsmInstruction(jmpType, branchDest); + AsmOpcode jmpOpcode = AsmInstructionSet.getOpcode("jmp", AsmAddressingMode.ABS, false); + AsmInstruction jmpInstruction = new AsmInstruction(jmpOpcode, branchDest); asmChunk.addLineAfter(asmInstruction, jmpInstruction); asmChunk.addLineAfter(jmpInstruction, new AsmLabel(newLabel)); return true; @@ -177,24 +180,24 @@ public class Pass5FixLongBranches extends Pass5AsmOptimization { return false; } - private AsmInstructionType invertBranch(AsmInstructionType type) { - switch(type.getMnemnonic()) { + private AsmOpcode invertBranch(AsmOpcode asmOpcode) { + switch(asmOpcode.getMnemnonic()) { case "bcc": - return AsmInstructionSet.getInstructionType("bcs", AsmAddressingMode.REL, false); + return AsmInstructionSet.getOpcode("bcs", AsmAddressingMode.REL, false); case "bcs": - return AsmInstructionSet.getInstructionType("bcc", AsmAddressingMode.REL, false); + return AsmInstructionSet.getOpcode("bcc", AsmAddressingMode.REL, false); case "beq": - return AsmInstructionSet.getInstructionType("bne", AsmAddressingMode.REL, false); + return AsmInstructionSet.getOpcode("bne", AsmAddressingMode.REL, false); case "bne": - return AsmInstructionSet.getInstructionType("beq", AsmAddressingMode.REL, false); + return AsmInstructionSet.getOpcode("beq", AsmAddressingMode.REL, false); case "bpl": - return AsmInstructionSet.getInstructionType("bmi", AsmAddressingMode.REL, false); + return AsmInstructionSet.getOpcode("bmi", AsmAddressingMode.REL, false); case "bmi": - return AsmInstructionSet.getInstructionType("bpl", AsmAddressingMode.REL, false); + return AsmInstructionSet.getOpcode("bpl", AsmAddressingMode.REL, false); case "bvs": - return AsmInstructionSet.getInstructionType("bvc", AsmAddressingMode.REL, false); + return AsmInstructionSet.getOpcode("bvc", AsmAddressingMode.REL, false); case "bvc": - return AsmInstructionSet.getInstructionType("bvs", AsmAddressingMode.REL, false); + return AsmInstructionSet.getOpcode("bvs", AsmAddressingMode.REL, false); default: return null; } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass5NextJumpElimination.java b/src/main/java/dk/camelot64/kickc/passes/Pass5NextJumpElimination.java index f8f80fb19..4afda9d95 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass5NextJumpElimination.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass5NextJumpElimination.java @@ -33,7 +33,7 @@ public class Pass5NextJumpElimination extends Pass5AsmOptimization { if(line instanceof AsmInstruction) { candidate = null; AsmInstruction instruction = (AsmInstruction) line; - if(instruction.getType().isJump() && !instruction.getType().getMnemnonic().equals("jsr")) { + if(instruction.getAsmOpcode().isJump() && !instruction.getAsmOpcode().getMnemnonic().equals("jsr")) { candidate = instruction; } } else if(line instanceof AsmDataString || line instanceof AsmDataNumeric || line instanceof AsmDataFill || line instanceof AsmInlineKickAsm ) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass5RedundantLabelElimination.java b/src/main/java/dk/camelot64/kickc/passes/Pass5RedundantLabelElimination.java index 4da06c5fd..04154f072 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass5RedundantLabelElimination.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass5RedundantLabelElimination.java @@ -38,7 +38,7 @@ public class Pass5RedundantLabelElimination extends Pass5AsmOptimization { } } else if(line instanceof AsmInstruction) { AsmInstruction instruction = (AsmInstruction) line; - if(instruction.getType().isJump()) { + if(instruction.getAsmOpcode().isJump()) { String labelStr = instruction.getParameter(); String labelReplacementStr = getLabelReplacement(redundantLabelSet, currentScope, labelStr); if(labelReplacementStr!=null) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass5RelabelLongLabels.java b/src/main/java/dk/camelot64/kickc/passes/Pass5RelabelLongLabels.java index 7963f61c1..7e44270c5 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass5RelabelLongLabels.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass5RelabelLongLabels.java @@ -95,7 +95,7 @@ public class Pass5RelabelLongLabels extends Pass5AsmOptimization { } } else if(asmLine instanceof AsmInstruction) { AsmInstruction asmInstruction = (AsmInstruction) asmLine; - if(asmInstruction.getType().isJump()) { + if(asmInstruction.getAsmOpcode().isJump()) { String parameter = asmInstruction.getParameter(); Map scopeRelabels = relabels.get(currentScope); if(scopeRelabels != null) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass5SkipBegin.java b/src/main/java/dk/camelot64/kickc/passes/Pass5SkipBegin.java index d4c53b5ab..ab2cdb598 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass5SkipBegin.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass5SkipBegin.java @@ -41,7 +41,7 @@ public class Pass5SkipBegin extends Pass5AsmOptimization { } } else if(line instanceof AsmInstruction) { AsmInstruction instruction = (AsmInstruction) line; - if(instruction.getType().getMnemnonic().equals("jsr")) { + if(instruction.getAsmOpcode().getMnemnonic().equals("jsr")) { if(instruction.getParameter().equals(SymbolRef.MAIN_PROC_NAME)) { lineIterator.remove(); optimized = true; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass5UnnecesaryLoadElimination.java b/src/main/java/dk/camelot64/kickc/passes/Pass5UnnecesaryLoadElimination.java index f4e96c3a3..48067fca6 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass5UnnecesaryLoadElimination.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass5UnnecesaryLoadElimination.java @@ -1,5 +1,8 @@ package dk.camelot64.kickc.passes; +import dk.camelot64.cpufamily6502.AsmAddressingMode; +import dk.camelot64.cpufamily6502.AsmInstructionSet; +import dk.camelot64.cpufamily6502.AsmOpcode; import dk.camelot64.kickc.asm.*; import dk.camelot64.kickc.model.Program; @@ -30,89 +33,89 @@ public class Pass5UnnecesaryLoadElimination extends Pass5AsmOptimization { if(instruction.isDontOptimize()) { continue; } - AsmInstructionType instructionType = instruction.getType(); + AsmOpcode asmOpcode = instruction.getAsmOpcode(); - if(instructionType.getMnemnonic().equals("lda") && instructionType.getAddressingMode().equals(AsmAddressingMode.IMM)) { + if(asmOpcode.getMnemnonic().equals("lda") && asmOpcode.getAddressingMode().equals(AsmAddressingMode.IMM)) { String immValue = instruction.getParameter(); AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction); if(AsmProgramStaticRegisterValues.matchImm(instructionValues.getA(), immValue)) { modified = remove(lineIt); } else if(AsmProgramStaticRegisterValues.matchImm(instructionValues.getX(), immValue)) { getLog().append("Replacing instruction " + instruction + " with TXA"); - instruction.setType(AsmInstructionSet.getInstructionType("txa", AsmAddressingMode.NON, false)); + instruction.setAsmOpcode(AsmInstructionSet.getOpcode("txa", AsmAddressingMode.NON, false)); instruction.setParameter(null); } else if(AsmProgramStaticRegisterValues.matchImm(instructionValues.getY(), immValue)) { getLog().append("Replacing instruction " + instruction + " with TYA"); - instruction.setType(AsmInstructionSet.getInstructionType("tya", AsmAddressingMode.NON, false)); + instruction.setAsmOpcode(AsmInstructionSet.getOpcode("tya", AsmAddressingMode.NON, false)); instruction.setParameter(null); } } - if(instructionType.getMnemnonic().equals("lda") && (instructionType.getAddressingMode().equals(AsmAddressingMode.ZP) || instructionType.getAddressingMode().equals(AsmAddressingMode.ABS))) { + if(asmOpcode.getMnemnonic().equals("lda") && (asmOpcode.getAddressingMode().equals(AsmAddressingMode.ZP) || asmOpcode.getAddressingMode().equals(AsmAddressingMode.ABS))) { String memValue = instruction.getParameter(); AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction); if(instructionValues.getaMem() != null && instructionValues.getaMem().equals(memValue)) { modified = remove(lineIt); } else if(instructionValues.getxMem() != null && instructionValues.getxMem().equals(memValue)) { getLog().append("Replacing instruction " + instruction + " with TXA"); - instruction.setType(AsmInstructionSet.getInstructionType("txa", AsmAddressingMode.NON, false)); + instruction.setAsmOpcode(AsmInstructionSet.getOpcode("txa", AsmAddressingMode.NON, false)); instruction.setParameter(null); } else if(instructionValues.getyMem() != null && instructionValues.getyMem().equals(memValue)) { getLog().append("Replacing instruction " + instruction + " with TYA"); - instruction.setType(AsmInstructionSet.getInstructionType("tya", AsmAddressingMode.NON, false)); + instruction.setAsmOpcode(AsmInstructionSet.getOpcode("tya", AsmAddressingMode.NON, false)); instruction.setParameter(null); } } - if(instructionType.getMnemnonic().equals("ldx") && instructionType.getAddressingMode().equals(AsmAddressingMode.IMM)) { + if(asmOpcode.getMnemnonic().equals("ldx") && asmOpcode.getAddressingMode().equals(AsmAddressingMode.IMM)) { String immValue = instruction.getParameter(); AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction); if(AsmProgramStaticRegisterValues.matchImm(instructionValues.getX(), immValue)) { modified = remove(lineIt); } else if(AsmProgramStaticRegisterValues.matchImm(instructionValues.getA(), immValue)) { getLog().append("Replacing instruction " + instruction + " with TAX"); - instruction.setType(AsmInstructionSet.getInstructionType("tax", AsmAddressingMode.NON, false)); + instruction.setAsmOpcode(AsmInstructionSet.getOpcode("tax", AsmAddressingMode.NON, false)); instruction.setParameter(null); } } - if(instructionType.getMnemnonic().equals("ldx") && (instructionType.getAddressingMode().equals(AsmAddressingMode.ZP) || instructionType.getAddressingMode().equals(AsmAddressingMode.ABS))) { + if(asmOpcode.getMnemnonic().equals("ldx") && (asmOpcode.getAddressingMode().equals(AsmAddressingMode.ZP) || asmOpcode.getAddressingMode().equals(AsmAddressingMode.ABS))) { String memValue = instruction.getParameter(); AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction); if(instructionValues.getxMem() != null && instructionValues.getxMem().equals(memValue)) { modified = remove(lineIt); } else if(instructionValues.getaMem() != null && instructionValues.getaMem().equals(memValue)) { getLog().append("Replacing instruction " + instruction + " with TAX"); - instruction.setType(AsmInstructionSet.getInstructionType("tax", AsmAddressingMode.NON, false)); + instruction.setAsmOpcode(AsmInstructionSet.getOpcode("tax", AsmAddressingMode.NON, false)); instruction.setParameter(null); } } - if(instructionType.getMnemnonic().equals("ldy") && instructionType.getAddressingMode().equals(AsmAddressingMode.IMM)) { + if(asmOpcode.getMnemnonic().equals("ldy") && asmOpcode.getAddressingMode().equals(AsmAddressingMode.IMM)) { String immValue = instruction.getParameter(); AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction); if(AsmProgramStaticRegisterValues.matchImm(instructionValues.getY(), immValue)) { modified = remove(lineIt); } else if(AsmProgramStaticRegisterValues.matchImm(instructionValues.getA(), immValue)) { getLog().append("Replacing instruction " + instruction + " with TAY"); - instruction.setType(AsmInstructionSet.getInstructionType("tay", AsmAddressingMode.NON, false)); + instruction.setAsmOpcode(AsmInstructionSet.getOpcode("tay", AsmAddressingMode.NON, false)); instruction.setParameter(null); } } - if(instructionType.getMnemnonic().equals("ldy") && (instructionType.getAddressingMode().equals(AsmAddressingMode.ZP) || instructionType.getAddressingMode().equals(AsmAddressingMode.ABS))) { + if(asmOpcode.getMnemnonic().equals("ldy") && (asmOpcode.getAddressingMode().equals(AsmAddressingMode.ZP) || asmOpcode.getAddressingMode().equals(AsmAddressingMode.ABS))) { String memValue = instruction.getParameter(); AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction); if(instructionValues.getyMem() != null && instructionValues.getyMem().equals(memValue)) { modified = remove(lineIt); } else if(instructionValues.getaMem() != null && instructionValues.getaMem().equals(memValue)) { getLog().append("Replacing instruction " + instruction + " with TAY"); - instruction.setType(AsmInstructionSet.getInstructionType("tay", AsmAddressingMode.NON, false)); + instruction.setAsmOpcode(AsmInstructionSet.getOpcode("tay", AsmAddressingMode.NON, false)); instruction.setParameter(null); } } - if(instructionType.getMnemnonic().equals("clc")) { + if(asmOpcode.getMnemnonic().equals("clc")) { AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction); if(Boolean.FALSE.equals(instructionValues.getC())) { modified = remove(lineIt); } } - if(instructionType.getMnemnonic().equals("sec")) { + if(asmOpcode.getMnemnonic().equals("sec")) { AsmProgramStaticRegisterValues.AsmRegisterValues instructionValues = staticValues.getValues(instruction); if(Boolean.TRUE.equals(instructionValues.getC())) { modified = remove(lineIt); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass5UnreachableCodeElimination.java b/src/main/java/dk/camelot64/kickc/passes/Pass5UnreachableCodeElimination.java index 08137899f..17875e343 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass5UnreachableCodeElimination.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass5UnreachableCodeElimination.java @@ -34,7 +34,7 @@ public class Pass5UnreachableCodeElimination extends Pass5AsmOptimization { optimized = true; } else { AsmInstruction asmInstruction = (AsmInstruction) line; - if(asmInstruction.getType().getMnemnonic().equals("rts") || asmInstruction.getType().getMnemnonic().equals("jmp")) { + if(asmInstruction.getAsmOpcode().getMnemnonic().equals("rts") || asmInstruction.getAsmOpcode().getMnemnonic().equals("jmp")) { afterExit = true; } } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass5UnusedLabelElimination.java b/src/main/java/dk/camelot64/kickc/passes/Pass5UnusedLabelElimination.java index dbf5fd0d7..07f5a714a 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass5UnusedLabelElimination.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass5UnusedLabelElimination.java @@ -1,12 +1,9 @@ package dk.camelot64.kickc.passes; import dk.camelot64.kickc.asm.*; -import dk.camelot64.kickc.model.ControlFlowBlock; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.statements.StatementAsm; -import dk.camelot64.kickc.model.values.LabelRef; -import dk.camelot64.kickc.model.values.SymbolRef; import java.util.ArrayList; import java.util.LinkedHashSet; @@ -44,7 +41,7 @@ public class Pass5UnusedLabelElimination extends Pass5AsmOptimization { usedLabels.add(labelStr); } else if(line instanceof AsmInstruction) { AsmInstruction instruction = (AsmInstruction) line; - if(instruction.getType().isJump()) { + if(instruction.getAsmOpcode().isJump()) { String labelStr = currentScope + "::" + instruction.getParameter(); usedLabels.add(labelStr); }