diff --git a/Ghidra/Processors/6805/certification.manifest b/Ghidra/Processors/6805/certification.manifest index b31dfa76a8..24fed509bd 100644 --- a/Ghidra/Processors/6805/certification.manifest +++ b/Ghidra/Processors/6805/certification.manifest @@ -5,3 +5,10 @@ data/languages/6805.cspec||GHIDRA||||END| data/languages/6805.ldefs||GHIDRA||||END| data/languages/6805.pspec||GHIDRA||reviewed||END| data/languages/6805.slaspec||GHIDRA||||END| +data/languages/6809.cspec||GHIDRA||||END| +data/languages/6809.pspec||GHIDRA||||END| +data/languages/6809.slaspec||GHIDRA||||END| +data/languages/6x09.sinc||GHIDRA||||END| +data/languages/6x09_exg_tfr.sinc||GHIDRA||||END| +data/languages/6x09_pull.sinc||GHIDRA||||END| +data/languages/6x09_push.sinc||GHIDRA||||END| diff --git a/Ghidra/Processors/6805/data/languages/6805.ldefs b/Ghidra/Processors/6805/data/languages/6805.ldefs index 1f0acee862..cef485ed5b 100644 --- a/Ghidra/Processors/6805/data/languages/6805.ldefs +++ b/Ghidra/Processors/6805/data/languages/6805.ldefs @@ -16,6 +16,17 @@ - + + + 6809 Microprocessor + + diff --git a/Ghidra/Processors/6805/data/languages/6809.cspec b/Ghidra/Processors/6805/data/languages/6809.cspec new file mode 100644 index 0000000000..6368f91cd9 --- /dev/null +++ b/Ghidra/Processors/6805/data/languages/6809.cspec @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Ghidra/Processors/6805/data/languages/6809.pspec b/Ghidra/Processors/6805/data/languages/6809.pspec new file mode 100644 index 0000000000..0256affbe9 --- /dev/null +++ b/Ghidra/Processors/6805/data/languages/6809.pspec @@ -0,0 +1,5 @@ + + + + + diff --git a/Ghidra/Processors/6805/data/languages/6809.slaspec b/Ghidra/Processors/6805/data/languages/6809.slaspec new file mode 100644 index 0000000000..ddd1a870af --- /dev/null +++ b/Ghidra/Processors/6805/data/languages/6809.slaspec @@ -0,0 +1,8 @@ +# sleigh specification file for Motorola 6809 + +@define M6809 + +@include "6x09.sinc" +@include "6x09_push.sinc" +@include "6x09_pull.sinc" +@include "6x09_exg_tfr.sinc" diff --git a/Ghidra/Processors/6805/data/languages/6x09.sinc b/Ghidra/Processors/6805/data/languages/6x09.sinc new file mode 100644 index 0000000000..568505ac16 --- /dev/null +++ b/Ghidra/Processors/6805/data/languages/6x09.sinc @@ -0,0 +1,1272 @@ +# sleigh specification file for Motorola 6809/Hitachi 6309 + +define endian=big; +define alignment=1; + +@define SWI3_VECTOR "0xFFF2" +@define SWI2_VECTOR "0xFFF4" +@define FIRQ_VECTOR "0xFFF6" +@define IRQ_VECTOR "0xFFF8" +@define SWI_VECTOR "0xFFFA" +@define NMI_VECTOR "0xFFFC" +@define RST_VECTOR "0xFFFE" + +define space RAM type=ram_space size=2 default; +define space register type=register_space size=1; + +@ifdef H6309 +# 8-bit registers A, B, E, F, MD +define register offset=0 size=1 [ A B E F MD ]; +# 16-bit registers D, W +define register offset=0 size=2 [ D W ]; +# 16-bit register V +define register offset=12 size=2 [ V ]; +# 32-bit register Q +define register offset=0 size=4 [ Q ]; +@else +# 8-bit registers A, B +define register offset=0 size=1 [ A B ]; +# 16-bit register D +define register offset=0 size=2 [ D ]; +@endif + +# 8-bit condition code register, direct page register +define register offset=8 size=1 [ CC DP ]; +# 16-bit registers: +# PC: Program counter +# S: Stack pointer +# U: alternate stack pointer/index register +# X,Y: index register +define register offset=16 size=2 [ PC X Y U S ]; + +# Pseudo registers used for EXG instruction. +define register offset=32 size=2 [ exg16_r0 exg16_r1 ]; +define register offset=32 size=1 [ exg8h_r0 exg8l_r0 exg8h_r1 exg8l_r1 ]; + +# define status bits: (See also 8051/z80). +@define C "CC[0,1]" # C: Carry (or borrow) flag +@define V "CC[1,1]" # V: Overflow flag +@define Z "CC[2,1]" # Z: Zero result +@define N "CC[3,1]" # N: Negative result (twos complement) +@define I "CC[4,1]" # I: IRQ interrupt masked +@define H "CC[5,1]" # H: Half carry flag +@define F "CC[6,1]" # F: FIRQ interrupt masked +@define E "CC[7,1]" # E: Entire register state stacked + +define token opbyte (8) + op = (0,7) + op45 = (4,5) + op47 = (4,7) +; + +define token data8 (8) + imm8 = (0,7) + simm8 = (0,7) signed + simm5 = (0,4) signed + idxMode = (0,4) + noOffset5 = (7,7) + idxReg = (5,6) + imm80 = (0,0) + imm81 = (1,1) + imm82 = (2,2) + imm83 = (3,3) + imm84 = (4,4) + imm85 = (5,5) + imm86 = (6,6) + imm87 = (7,7) + reg0_exg = (4,7) + reg1_exg = (0,3) +; + +define token data (16) + imm16 = (0,15) + simm16 = (0,15) signed +; + +attach variables [ idxReg ] [ X Y U S ]; + +EA: simm5,idxReg is simm5 & idxReg & noOffset5=0 +{ + local offset:1 = simm5; + local addr:2 = idxReg + sext(offset); + export addr; +} +EA: ","idxReg is idxReg & noOffset5=1 & idxMode=4 # no offset +{ + local addr:2 = idxReg; + export addr; +} +EA: simm8,idxReg is idxReg & noOffset5=1 & idxMode=8; simm8 # 8-bit offset +{ + local addr:2 = idxReg + simm8; + export addr; +} +EA: simm16,idxReg is idxReg & noOffset5=1 & idxMode=9; simm16 # 16-bit offset +{ + local addr:2 = idxReg + simm16; + export addr; +} +EA: "B,"idxReg is idxReg & noOffset5=1 & idxMode=5 # B,R +{ + local addr:2 = idxReg + sext(B); + export addr; +} +EA: "A,"idxReg is idxReg & noOffset5=1 & idxMode=6 # A,R +{ + local addr:2 = idxReg + sext(A); + export addr; +} +EA: D,idxReg is D & idxReg & noOffset5=1 & idxMode=11 # D,R +{ + local addr:2 = idxReg + D; + export addr; +} +EA: ","idxReg"+" is idxReg & noOffset5=1 & idxMode=0 # ,R+ +{ + addr:2 = idxReg; + idxReg = idxReg + 1; + export addr; +} +EA: ","idxReg"++" is idxReg & noOffset5=1 & idxMode=1 # ,R++ +{ + local addr:2 = idxReg; + idxReg = idxReg + 2; + export addr; +} +EA: ",-"idxReg is idxReg & noOffset5=1 & idxMode=2 # ,-R +{ + idxReg = idxReg - 1; + local addr:2 = idxReg; + export addr; +} +EA: ",--"idxReg is idxReg & noOffset5=1 & idxMode=3 # ,--R +{ + idxReg = idxReg - 2; + local addr:2 = idxReg; + export addr; +} +EA: addr",PCR" is noOffset5=1 & idxMode=12; simm8 [ addr = inst_next + simm8; ] +{ + export addr; +} +EA: addr",PCR" is noOffset5=1 & idxMode=13; simm16 [ addr = inst_next + simm16; ] +{ + export addr; +} +EA: "[,"idxReg"]" is idxReg & noOffset5=1 & idxMode=20 +{ + local addr:2 = *:2 idxReg; + export addr; +} +EA: "["simm8,idxReg"]" is idxReg & noOffset5=1 & idxMode=24; simm8 +{ + local offset:1 = simm8; + local addr:2 = idxReg + sext(offset); + addr = *:2 addr; + export addr; +} +EA: "["simm16,idxReg"]" is idxReg & noOffset5=1 & idxMode=25; simm16 +{ + local addr:2 = idxReg + simm16; + addr = *:2 addr; + export addr; +} +EA: "[B,"idxReg"]" is idxReg & noOffset5=1 & idxMode=21 +{ + local addr:2 = idxReg + sext(B); + addr = *:2 addr; + export addr; +} +EA: "[A,"idxReg"]" is idxReg & noOffset5=1 & idxMode=22 +{ + local addr:2 = idxReg + sext(A); + addr = *:2 addr; + export addr; +} +EA: "["D,idxReg"]" is D & idxReg & noOffset5=1 & idxMode=27 +{ + local addr:2 = idxReg + D; + addr = *:2 addr; + export addr; +} +EA: "[,"idxReg"++]" is idxReg & noOffset5=1 & idxMode=17 +{ + local addr:2 = idxReg; + addr = *:2 addr; + idxReg = idxReg + 2; + export addr; +} +EA: "[,--"idxReg"]" is idxReg & noOffset5=1 & idxMode=19 +{ + idxReg = idxReg - 2; + local addr:2 = idxReg; + addr = *:2 addr; + export addr; +} +EA: "["addr",PCR]" is noOffset5=1 & idxMode=28; simm8 [ addr = inst_next + simm8; ] +{ + local eaddr:2 = inst_next + simm8; + eaddr = *:2 eaddr; + export eaddr; +} +EA: "["addr",PCR]" is noOffset5=1 & idxMode=29; simm16 [ addr = inst_next + simm16; ] +{ + local eaddr:2 = inst_next + simm16; + eaddr = *:2 eaddr; + export eaddr; +} +EA: "["addr"]" is imm8=0x9F; simm16 [ addr = inst_next; ] +{ + local eaddr:2 = inst_next; + eaddr = *:2 eaddr; + export eaddr; +} + +################################################################ +# Constructors +################################################################ + +PAGE2: is op=0x10 { } # PAGE2 opcode prefix (0x10) +PAGE3: is op=0x11 { } # PAGE3 opcode prefix (0x11) + +IMMED1: "#"imm8 is imm8 { tmp:1 = imm8; export tmp; } + +REL: addr is simm8 [ addr = inst_next + simm8; ] { export *:2 addr; } +REL2: addr is simm16 [ addr = inst_next + simm16; ] { export *:2 addr; } + +# 1-byte operand, immediate/direct/indexed/extended addressing mode +OP1: "#"imm8 is op45=0; imm8 +{ + export imm8; +} +OP1: "<"imm8 is (op47=0 | op47=9 | op47=0xD); imm8 +{ + local tmp:2 = (zext(DP) << 8) + imm8; + export *:1 tmp; +} +OP1: EA is op45=2; EA +{ + local tmp:2 = EA; + export *:1 tmp; +} +OP1: imm16 is op45=3; imm16 +{ + export *:1 imm16; +} + +# 2-byte operand, direct/indexed/extended addressing mode +OP2: "#"imm16 is (op47=8 | op47=0xC); imm16 +{ + export imm16; +} +OP2: "<"imm8 is (op47=0 | op47=9 | op47=0xD); imm8 +{ + local tmp:2 = (zext(DP) << 8) + imm8; + export *:2 tmp; +} +OP2: EA is (op47=3 | op47=6 | op47=0xA | op47=0xE); EA +{ + local tmp:2 = EA; + export *:2 tmp; +} +OP2: imm16 is (op47=7 | op47=0xB | op47=0xF); imm16 +{ + export *:2 imm16; +} + +################################################################ +# Macros +################################################################ + +macro setNZFlags(result) +{ + $(Z) = (result == 0); + $(N) = (result s< 0); +} + +macro setHFlag(reg, op) +{ + local mask = 0x0F; # Low nibble mask + + $(H) = (((reg & mask) + (op & mask)) >> 4) & 1; +} + +# Negate twos complement value in op. +# P-code INT_2COMP. +macro negate(op) +{ + $(V) = (op == 0x80); + $(C) = (op != 0); + op = -op; + setNZFlags(op); +} + +# Logical complement of op. (0 => 1; 1 => 0) +# P-code INT_NEGATE. +macro complement(op) +{ + $(V) = 0; + $(C) = 1; + A = ~A; + setNZFlags(op); +} + +macro logicalShiftRight(op) +{ + $(C) = op & 1; + op = op >> 1; + $(Z) = (op == 0); + $(N) = 0; +} + +macro rotateRightWithCarry(op) +{ + local carryOut = $(C) << 7; + $(C) = op & 1; + op = (op s>> 1) | carryOut; + setNZFlags(op); +} + +macro rotateLeftWithCarry(op) +{ + local carryIn = $(C); + $(C) = op >> 7; + op = (op << 1) | carryIn; + setNZFlags(op); +} + +# Signed shift right. +# P-code INT_SRIGHT. +macro arithmeticShiftRight(op) +{ + $(C) = op & 1; + op = (op s>> 1); + setNZFlags(op); +} + +macro logicalShiftLeft(op) +{ + $(C) = (op >> 7); + op = op << 1; + $(Z) = (op == 0); + $(N) = (op >> 7); +} + +macro increment(op) +{ + $(V) = (op == 0x7F); + op = op + 1; + setNZFlags(op); +} + +macro decrement(op) +{ + $(V) = (op == 0x80); + op = op - 1; + setNZFlags(op); +} + +macro test(op) +{ + $(V) = 0; + setNZFlags(op); +} + +macro clear(op) +{ + $(V) = 0; + op = 0; + $(Z) = 1; + $(N) = 0; +} + +macro addition(reg, op) +{ + $(C) = carry(reg, op); + $(V) = scarry(reg, op); + + reg = reg + op; + + setNZFlags(reg); +} + +macro additionWithCarry(reg, op) +{ + local carryIn = zext($(C)); + local mask = 0x0F; # Low nibble mask + local tmpResult = reg + op; + + $(H) = (((reg & mask) + (op & mask) + carryIn) >> 4) & 1; + $(C) = carry(reg, op) || carry(tmpResult, carryIn); + $(V) = scarry(reg, op) ^^ scarry(tmpResult, carryIn); + + reg = tmpResult + carryIn; + + setNZFlags(reg); +} + +macro subtraction(reg, op) +{ + $(V) = sborrow(reg, op); + reg = reg - op; + setNZFlags(reg); + $(C) = (reg < op); +} + +macro subtractionWithCarry(reg, op) +{ + local carryIn = zext($(C)); + local tmpResult = reg - op; + + $(C) = (reg < op) || (tmpResult < carryIn); + $(V) = sborrow(reg, op) ^^ sborrow(tmpResult, carryIn); + + reg = tmpResult - carryIn; + + setNZFlags(reg); +} + +macro compare(reg, op) +{ + $(V) = sborrow(reg, op); + local tmp = reg - op; + setNZFlags(tmp); + $(C) = (tmp < op); +} + +macro logicalAnd(reg, op) +{ + reg = reg & op; + setNZFlags(reg); + $(V) = 0; +} + +macro logicalOr(reg, op) +{ + reg = reg | op; + setNZFlags(reg); + $(V) = 0; +} + +macro logicalExclusiveOr(reg, op) +{ + reg = reg ^ op; + setNZFlags(reg); + $(V) = 0; +} + +macro bitTest(reg, op) +{ + local tmp = reg & op; + setNZFlags(tmp); + $(V) = 0; +} + +macro loadRegister(reg, op) +{ + reg = op; + setNZFlags(reg); + $(V) = 0; +} + +macro storeRegister(reg, op) +{ + op = reg; + setNZFlags(reg); + $(V) = 0; +} + +# Push 1 byte operand op1 +macro Push1(reg, op) +{ + *:1 reg = op; + reg = reg - 1; +} + +# Push 2 byte operand op2 +macro Push2(reg, op) +{ + reg = reg - 1; + *:2 reg = op; + reg = reg - 1; +} + +# Pull 1 byte operand op1 +macro Pull1(reg, op) +{ + op = *:1 reg; + reg = reg + 1; +} + +# Pull 2 byte operand op2 +macro Pull2(reg, op) +{ + reg = reg + 1; + op = *:2 reg; + reg = reg + 1; +} + +macro PushUYXDpD() +{ + Push2(S, U); + Push2(S, Y); + Push2(S, X); + Push1(S, DP); + Push2(S, D); +} + +macro PullDDpXYU() +{ + Pull2(S, D); + Pull1(S, DP); + Pull2(S, X); + Pull2(S, Y); + Pull2(S, U); +} + +macro PushEntireState() +{ + local tmp:2 = inst_next; + + $(E) = 1; + Push2(S, tmp); # return PC address + PushUYXDpD(); + Push1(S, CC); +} + +################################################################ +# Instructions +################################################################ + +################################################################ +# Opcode 0x00 - 0x0F, relative addressing +# Opcode 0x40 - 0x4F, register A addressing +# Opcode 0x50 - 0x5F, register B addressing +# Opcode 0x60 - 0x6F, indexed addressing +# Opcode 0x70 - 0x7F, extended addressing +################################################################ + +:NEGA is op=0x40 +{ + negate(A); +} + +:NEGB is op=0x50 +{ + negate(B); +} + +:NEG OP1 is (op=0x00 | op=0x60 | op=0x70) ... & OP1 +{ + negate(OP1); +} + +:COMA is op=0x43 +{ + complement(A); +} + +:COMB is op=0x53 +{ + complement(B); +} + +:COM OP1 is (op=0x03 | op=0x63 | op=0x73) ... & OP1 +{ + complement(OP1); +} + +:LSRA is op=0x44 +{ + logicalShiftRight(A); +} + +:LSRB is op=0x54 +{ + logicalShiftRight(B); +} + +:LSR OP1 is (op=0x04 | op=0x64 | op=0x74) ... & OP1 +{ + logicalShiftRight(OP1); +} + +:RORA is op=0x46 +{ + rotateRightWithCarry(A); +} + +:RORB is op=0x56 +{ + rotateRightWithCarry(B); +} + +:ROR OP1 is (op=0x06 | op=0x66 | op=0x76) ... & OP1 +{ + rotateRightWithCarry(OP1); +} + +:ASRA is op=0x47 +{ + arithmeticShiftRight(A); +} + +:ASRB is op=0x57 +{ + arithmeticShiftRight(B); +} + +:ASR OP1 is (op=0x07 | op=0x67 | op=0x77) ... & OP1 +{ + arithmeticShiftRight(OP1); +} + +:LSLA is op=0x48 +{ + logicalShiftLeft(A); +} + +:LSLB is op=0x58 +{ + logicalShiftLeft(B); +} + +:LSL OP1 is (op=0x08 | op=0x68 | op=0x78) ... & OP1 +{ + logicalShiftLeft(OP1); +} + +:ROLA is op=0x49 +{ + rotateLeftWithCarry(A); +} + +:ROLB is op=0x59 +{ + rotateLeftWithCarry(B); +} + +:ROL OP1 is (op=0x09 | op=0x69 | op=0x79) ... & OP1 +{ + rotateLeftWithCarry(OP1); +} + +:DECA is op=0x4A +{ + decrement(A); +} + +:DECB is op=0x5A +{ + decrement(B); +} + +:DEC OP1 is (op=0x0A | op=0x6A | op=0x7A) ... & OP1 +{ + decrement(OP1); +} + +:INCA is op=0x4C +{ + increment(A); +} + +:INCB is op=0x5C +{ + increment(B); +} + +:INC OP1 is (op=0x0C | op=0x6C | op=0x7C) ... & OP1 +{ + increment(OP1); +} + +:TSTA is op=0x4D +{ + test(A); +} + +:TSTB is op=0x5D +{ + test(B); +} + +:TST OP1 is (op=0x0D | op=0x6D | op=0x7D) ... & OP1 +{ + test(OP1); +} + +:JMP OP2 is (op=0x0E | op=0x6E | op=0x7E) ... & OP2 +{ + goto OP2; +} + +:CLRA is op=0x4F +{ + clear(A); +} + +:CLRB is op=0x5F +{ + clear(B); +} + +:CLR OP1 is (op=0x0F | op=0x6F | op=0x7F) ... & OP1 +{ + clear(OP1); +} + +################################################################ +# Opcode 0x10 - 0x1F, misc. addressing +################################################################ + +:NOP is op=0x12 +{ +} + +:SYNC is op=0x13 +{ +} + +:LBRA REL2 is op=0x16; REL2 +{ + goto REL2; +} + +:LBSR REL2 is op=0x17; REL2 +{ + local tmp:2 = inst_next; + Push2(S, tmp); + call REL2; +} + +:DAA is op=0x19 +{ + local highA:1 = A >> 4; + local lowA:1 = A & 0x0F; + local cc1 = ($(C) == 1 | highA > 9 | (highA > 8) & (lowA > 9)); + local cc2 = ($(H) == 1 | lowA > 9); + + if ( cc1 & cc2 ) + goto ; + if ( cc1 ) + goto ; + if ( cc2 ) + goto ; + goto ; + + + $(C) = carry(A, 0x66); + A = A + 0x66; + goto ; + + $(C) = carry(A, 0x60); + A = A + 0x60; + goto ; + + $(C) = carry(A, 0x06); + A = A + 0x06; + goto ; + + + setNZFlags(A); +} + +:ORCC IMMED1 is op=0x1A; IMMED1 +{ + CC = CC | IMMED1; +} + +:ANDCC IMMED1 is op=0x1C; IMMED1 +{ + CC = CC & IMMED1; +} + +:SEX is op=0x1D +{ + D = sext(B); +} + +################################################################ +# Opcode 0x20 - 0x2F, relative addressing +################################################################ + +:BRA REL is op=0x20; REL +{ + goto REL; +} + +:BRN REL is op=0x21; REL +{ +} + +:BHI REL is op=0x22; REL +{ + local tmp = $(C) + $(Z); + if (tmp == 0) goto REL; +} + +:BLS REL is op=0x23; REL +{ + local tmp = $(C) + $(Z); + if (tmp) goto REL; +} + +#:BHS REL is op=0x24; REL # See BCC + +:BCC REL is op=0x24; REL +{ + if ($(C) == 0) goto REL; +} + +#:BLO REL is op=0x25; REL # see BCS + +:BCS REL is op=0x25; REL +{ + if ($(C)) goto REL; +} + +:BNE REL is op=0x26; REL +{ + if ($(Z) == 0) goto REL; +} + +:BEQ REL is op=0x27; REL +{ + if ($(Z)) goto REL; +} + +:BVC REL is op=0x28; REL +{ + if ($(V) == 0) goto REL; +} + +:BVS REL is op=0x29; REL +{ + if ($(V)) goto REL; +} + +:BPL REL is op=0x2A; REL +{ + if ($(N) == 0) goto REL; +} + +:BMI REL is op=0x2B; REL +{ + if ($(N)) goto REL; +} + +:BGE REL is op=0x2C; REL +{ + if ($(N) == $(V)) goto REL; +} + +:BLT REL is op=0x2D; REL +{ + local tmp = $(C) ^ $(Z); + if (tmp) goto REL; +} + +:BGT REL is op=0x2E; REL +{ + if (($(N) == $(V)) & $(C)) goto REL; +} + +:BLE REL is op=0x2F; REL +{ + local tmp = $(N) ^ $(V); + if (tmp | $(Z)) goto REL; +} + +################################################################ +# Opcode 0x30 - 0x3F, misc. addressing +################################################################ + +:LEAX EA is op=0x30; EA +{ + X = EA; +} + +:LEAY EA is op=0x31; EA +{ + Y = EA; +} + +:LEAS EA is op=0x32; EA +{ + S = EA; +} + +:LEAU EA is op=0x33; EA +{ + U = EA; +} + +:RTS is op=0x39 +{ + local addr:2; + Pull2(S, addr); + return [addr]; +} + +:ABX is op=0x3A +{ + X = X + zext(B); +} + +:RTI is op=0x3B +{ + local addr:2; + Pull1(S, CC); + if ($(E)==0) goto ; + PullDDpXYU(); + + Pull2(S, addr); + return [addr]; +} + +:CWAI IMMED1 is op=0x3C; IMMED1 +{ + CC = CC & IMMED1; + PushEntireState(); +} + +:MUL is op=0x3D +{ + D = zext(A) * zext(B); + $(Z) = (D == 0); + $(C) = B >> 7; +} + +:SWI is op=0x3F +{ + PushEntireState(); + $(I) = 1; + $(F) = 1; + tmp:2 = $(SWI_VECTOR); + call[tmp]; +} + +################################################################ +# Opcode 0x80 - 0x8F, immediate addressing +# Opcode 0x90 - 0x9F, direct addressing +# Opcode 0xA0 - 0xAF, indexed addressing +# Opcode 0xB0 - 0xBF, extended addressing +# Opcode 0xC0 - 0xCF, immediate addressing +# Opcode 0xD0 - 0xDF, direct addressing +# Opcode 0xE0 - 0xEF, indexed addressing +# Opcode 0xF0 - 0xFF, extended addressing +################################################################ + +:SUBA OP1 is (op=0x80 | op=0x90 | op=0xA0 | op=0xB0) ... & OP1 +{ + subtraction(A, OP1); +} + +:SUBB OP1 is (op=0xC0 | op=0xD0 | op=0xE0 | op=0xF0) ... & OP1 +{ + subtraction(B, OP1); +} + +:CMPA OP1 is (op=0x81 | op=0x91 | op=0xA1 | op=0xB1) ... & OP1 +{ + compare(A, OP1); +} + +:CMPB OP1 is (op=0xC1 | op=0xD1 | op=0xE1 | op=0xF1) ... & OP1 +{ + compare(B, OP1); +} + +:SBCA OP1 is (op=0x82 | op=0x92 | op=0xA2 | op=0xB2) ... & OP1 +{ + subtractionWithCarry(A, OP1); +} + +:SBCB OP1 is (op=0xC2 | op=0xD2 | op=0xE2 | op=0xF2) ... & OP1 +{ + subtractionWithCarry(B, OP1); +} + +:SUBD OP2 is (op=0x83 | op=0x93 | op=0xA3 | op=0xB3) ... & OP2 +{ + subtraction(D, OP2); +} + +:ADDD OP2 is (op=0xC3 | op=0xD3 | op=0xE3 | op=0xF3) ... & OP2 +{ + addition(D, OP2); +} + +:ANDA OP1 is (op=0x84 | op=0x94 | op=0xA4 | op=0xB4) ... & OP1 +{ + logicalAnd(A, OP1); +} + +:ANDB OP1 is (op=0xC4 | op=0xD4 | op=0xE4 | op=0xF4) ... & OP1 +{ + logicalAnd(B, OP1); +} + +:BITA OP1 is (op=0x85 | op=0x95 | op=0xA5 | op=0xB5) ... & OP1 +{ + bitTest(A, OP1); +} + +:BITB OP1 is (op=0xC5 | op=0xD5 | op=0xE5 | op=0xF5) ... & OP1 +{ + bitTest(B, OP1); +} + +:LDA OP1 is (op=0x86 | op=0x96 | op=0xA6 | op=0xB6) ... & OP1 +{ + loadRegister(A, OP1); +} + +:LDB OP1 is (op=0xC6 | op=0xD6 | op=0xE6 | op=0xF6) ... & OP1 +{ + loadRegister(B, OP1); +} + +:STA OP1 is (op=0x97 | op=0xA7 | op=0xB7) ... & OP1 +{ + storeRegister(A, OP1); +} + +:STB OP1 is (op=0xD7 | op=0xE7 | op=0xF7) ... & OP1 +{ + storeRegister(B, OP1); +} + +:EORA OP1 is (op=0x88 | op=0x98 | op=0xA8 | op=0xB8) ... & OP1 +{ + logicalExclusiveOr(A, OP1); +} + +:EORB OP1 is (op=0xC8 | op=0xD8 | op=0xE8 | op=0xF8) ... & OP1 +{ + logicalExclusiveOr(B, OP1); +} + +:ADCA OP1 is (op=0x89 | op=0x99 | op=0xA9 | op=0xB9) ... & OP1 +{ + additionWithCarry(A, OP1); +} + +:ADCB OP1 is (op=0xC9 | op=0xD9 | op=0xE9 | op=0xF9) ... & OP1 +{ + additionWithCarry(B, OP1); +} + +:ORA OP1 is (op=0x8A | op=0x9A | op=0xAA | op=0xBA) ... & OP1 +{ + logicalOr(A, OP1); +} + +:ORB OP1 is (op=0xCA | op=0xDA | op=0xEA | op=0xFA) ... & OP1 +{ + logicalOr(B, OP1); +} + +:ADDA OP1 is (op=0x8B | op=0x9B | op=0xAB | op=0xBB) ... & OP1 +{ + setHFlag(A, OP1); + addition(A, OP1); +} + +:ADDB OP1 is (op=0xCB | op=0xDB | op=0xEB | op=0xFB) ... & OP1 +{ + setHFlag(A, OP1); + addition(B, OP1); +} + +:CMPX OP2 is (op=0x8C | op=0x9C | op=0xAC | op=0xBC) ... & OP2 +{ + compare(X, OP2); +} + +:LDD OP2 is (op=0xCC | op=0xDC | op=0xEC | op=0xFC) ... & OP2 +{ + loadRegister(D, OP2); +} + +:BSR REL is op=0x8D; REL +{ + local addr:2 = inst_next; + Push2(S, addr); + call REL; +} + +:JSR OP2 is (op=0x9D | op=0xAD | op=0xBD) ... & OP2 +{ + local addr:2 = inst_next; + Push2(S, addr); + call OP2; +} + +:STD OP2 is (op=0xDD | op=0xED | op=0xFD) ... & OP2 +{ + storeRegister(D, OP2); +} + +:LDX OP2 is (op=0x8E | op=0x9E | op=0xAE | op=0xBE) ... & OP2 +{ + loadRegister(X, OP2); +} + +:LDU OP2 is (op=0xCE | op=0xDE | op=0xEE | op=0xFE) ... & OP2 +{ + loadRegister(U, OP2); +} + +:STX OP2 is (op=0x9F | op=0xAF | op=0xBF) ... & OP2 +{ + storeRegister(X, OP2); +} + +:STU OP2 is (op=0xDF | op=0xEF | op=0xFF) ... & OP2 +{ + storeRegister(X, OP2); +} + +################################################################ +# Page 2 Opcodes (prefix 0x10) +################################################################ +:LBRN REL2 is PAGE2; op=0x21; REL2 +{ +} + +:LBHI REL2 is PAGE2; op=0x22; REL2 +{ + local tmp = $(C) + $(Z); + if (tmp == 0) goto REL2; +} + +:LBLS REL2 is PAGE2; op=0x23; REL2 +{ + local tmp = $(C) + $(Z); + if (tmp) goto REL2; +} + +:LBCC REL2 is PAGE2; op=0x24; REL2 +{ + if ($(C) == 0) goto REL2; +} + +#:LBLO REL2 is PAGE2; op=0x25; REL2 # see LBCS + +:LBCS REL2 is PAGE2; op=0x25; REL2 +{ + if ($(C)) goto REL2; +} + +:LBNE REL2 is PAGE2; op=0x26; REL2 +{ + if ($(Z) == 0) goto REL2; +} + +:LBEQ REL2 is PAGE2; op=0x27; REL2 +{ + if ($(Z)) goto REL2; +} + +:LBVC REL2 is PAGE2; op=0x28; REL2 +{ + if ($(V) == 0) goto REL2; +} + +:LBVS REL2 is PAGE2; op=0x29; REL2 +{ + if ($(V)) goto REL2; +} + +:LBPL REL2 is PAGE2; op=0x2A; REL2 +{ + if ($(N) == 0) goto REL2; +} + +:LBMI REL2 is PAGE2; op=0x2B; REL2 +{ + if ($(N)) goto REL2; +} + +:LBGE REL2 is PAGE2; op=0x2C; REL2 +{ + if ($(N) == $(V)) goto REL2; +} + +:LBLT REL2 is PAGE2; op=0x2D; REL2 +{ + local tmp = $(C) ^ $(Z); + if (tmp) goto REL2; +} + +:LBGT REL2 is PAGE2; op=0x2E; REL2 +{ + if (($(N) == $(V)) & $(C)) goto REL2; +} + +:LBLE REL2 is PAGE2; op=0x2F; REL2 +{ + local tmp = $(N) ^ $(V); + if (tmp | $(Z)) goto REL2; +} + +:SWI2 is PAGE2; op=0x3F +{ + PushEntireState(); + tmp:2 = $(SWI2_VECTOR); + call[tmp]; +} + +:CMPD OP2 is PAGE2; (op=0x83 | op=0x93 | op=0xA3 | op=0xB3) ... & OP2 +{ + compare(D, OP2); +} + +:CMPY OP2 is PAGE2; (op=0x8C | op=0x9C | op=0xAC | op=0xBC) ... & OP2 +{ + compare(Y, OP2); +} + +:LDY OP2 is PAGE2; (op=0x8E | op=0x9E | op=0xAE | op=0xBE) ... & OP2 +{ + loadRegister(Y, OP2); +} + +:STY OP2 is PAGE2; (op=0x9F | op=0xAF | op=0xBF) ... & OP2 +{ + storeRegister(Y, OP2); +} + +:LDS OP2 is PAGE2; (op=0xCE | op=0xDE | op=0xEE | op=0xFE) ... & OP2 +{ + loadRegister(S, OP2); +} + +:STS OP2 is PAGE2; (op=0xDF | op=0xEF | op=0xFF) ... & OP2 +{ + storeRegister(S, OP2); +} + +################################################################ +# Page 3 Opcodes (prefix 0x11) +################################################################ + +:SWI3 is PAGE3; op=0x3F +{ + PushEntireState(); + tmp:2 = $(SWI3_VECTOR); + call[tmp]; +} + +:CMPU OP2 is PAGE3; (op=0x83 | op=0x93 | op=0xA3 | op=0xB3) ... & OP2 +{ + compare(U, OP2); +} + +:CMPS OP2 is PAGE3; (op=0x8C | op=0x9C | op=0xAC | op=0xBC) ... & OP2 +{ + compare(S, OP2); +} + diff --git a/Ghidra/Processors/6805/data/languages/6x09_exg_tfr.sinc b/Ghidra/Processors/6805/data/languages/6x09_exg_tfr.sinc new file mode 100644 index 0000000000..4bc87f06d0 --- /dev/null +++ b/Ghidra/Processors/6805/data/languages/6x09_exg_tfr.sinc @@ -0,0 +1,170 @@ +# sleigh specification file for Motorola 6809/Hitachi 6309 + +################################################################ +# EXG, TFR helper +################################################################ + +@ifdef H6309 +EXG_r0Tmp: D is reg0_exg=0 & D { exg16_r0 = D; } +EXG_r0Tmp: X is reg0_exg=1 & X { exg16_r0 = X; } +EXG_r0Tmp: Y is reg0_exg=2 & Y { exg16_r0 = Y; } +EXG_r0Tmp: U is reg0_exg=3 & U { exg16_r0 = U; } +EXG_r0Tmp: S is reg0_exg=4 & S { exg16_r0 = S; } +EXG_r0Tmp: PC is reg0_exg=5 & PC { exg16_r0 = inst_next; } +EXG_r0Tmp: W is reg0_exg=6 & W { exg16_r0 = 0x0; } +EXG_r0Tmp: V is reg0_exg=7 & V { exg16_r0 = 0x0; } +EXG_r0Tmp: A is reg0_exg=8 & A { exg8l_r0 = A; exg8h_r0 = A; } +EXG_r0Tmp: B is reg0_exg=9 & B { exg8l_r0 = B; exg8h_r0 = B; } +EXG_r0Tmp: CC is reg0_exg=10 & CC { exg8l_r0 = CC; exg8h_r0 = CC;} +EXG_r0Tmp: DP is reg0_exg=12 & DP { exg8l_r0 = DP; exg8h_r0 = DP;} +EXG_r0Tmp: 0 is reg0_exg=13 { exg16_r0 = 0x0; } +EXG_r0Tmp: 0 is reg0_exg=14 { exg16_r0 = 0x0; } +EXG_r0Tmp: E is reg0_exg=15 & E { exg8l_r0 = E; exg8h_r0 = E; } +EXG_r0Tmp: F is reg0_exg=16 & F { exg8l_r0 = F; exg8h_r0 = F; } + +EXG_r1Tmp: D is reg1_exg=0 & D { exg16_r1 = D; } +EXG_r1Tmp: X is reg1_exg=1 & X { exg16_r1 = X; } +EXG_r1Tmp: Y is reg1_exg=2 & Y { exg16_r1 = Y; } +EXG_r1Tmp: U is reg1_exg=3 & U { exg16_r1 = U; } +EXG_r1Tmp: S is reg1_exg=4 & S { exg16_r1 = S; } +EXG_r1Tmp: PC is reg1_exg=5 & PC { exg16_r1 = inst_next; } +EXG_r1Tmp: W is reg1_exg=6 & W { exg16_r1 = 0x0; } +EXG_r1Tmp: V is reg1_exg=7 & V { exg16_r1 = 0x0; } +EXG_r1Tmp: A is reg1_exg=8 & A { exg8l_r1 = A; exg8h_r1 = A; } +EXG_r1Tmp: B is reg1_exg=9 & B { exg8l_r1 = B; exg8h_r1 = B; } +EXG_r1Tmp: CC is reg1_exg=10 & CC { exg8l_r1 = CC; exg8h_r1 = CC;} +EXG_r1Tmp: DP is reg1_exg=12 & DP { exg8l_r1 = DP; exg8h_r1 = DP;} +EXG_r1Tmp: 0 is reg1_exg=13 { exg16_r1 = 0x0; } +EXG_r1Tmp: 0 is reg1_exg=14 { exg16_r1 = 0x0; } +EXG_r1Tmp: E is reg1_exg=15 & E { exg8l_r1 = E; exg8h_r1 = E; } +EXG_r1Tmp: F is reg1_exg=16 & F { exg8l_r1 = F; exg8h_r1 = F; } + +EXG_r0Set: D is reg0_exg=0 & D { D = exg16_r1; } +EXG_r0Set: X is reg0_exg=1 & X { X = exg16_r1; } +EXG_r0Set: Y is reg0_exg=2 & Y { Y = exg16_r1; } +EXG_r0Set: U is reg0_exg=3 & U { U = exg16_r1; } +EXG_r0Set: S is reg0_exg=4 & S { S = exg16_r1; } +EXG_r0Set: PC is reg0_exg=5 & PC { PC = exg16_r1; } # must GOTO +EXG_r0Set: W is reg0_exg=6 & W { W = exg16_r1; } +EXG_r0Set: V is reg0_exg=7 & V { V = exg16_r1; } +EXG_r0Set: A is reg0_exg=8 & A { A = exg8h_r1; } +EXG_r0Set: B is reg0_exg=9 & B { B = exg8l_r1; } +EXG_r0Set: CC is reg0_exg=10 & CC { CC = exg8l_r1; } +EXG_r0Set: DP is reg0_exg=11 & DP { DP = exg8h_r1; } +EXG_r0Set: 0 is reg0_exg=12 { } +EXG_r0Set: 0 is reg0_exg=13 { } +EXG_r0Set: E is reg0_exg=14 & E { E = exg8h_r1; } +EXG_r0Set: F is reg0_exg=15 & F { F = exg8l_r1; } + +EXG_r1Set: D is reg1_exg=0 & D { D = exg16_r0; } +EXG_r1Set: X is reg1_exg=1 & X { X = exg16_r0; } +EXG_r1Set: Y is reg1_exg=2 & Y { Y = exg16_r0; } +EXG_r1Set: U is reg1_exg=3 & U { U = exg16_r0; } +EXG_r1Set: S is reg1_exg=4 & S { S = exg16_r0; } +EXG_r1Set: PC is reg1_exg=5 & PC { PC = exg16_r0; } # must GOTO +EXG_r1Set: W is reg1_exg=6 & W { W = exg16_r0; } +EXG_r1Set: V is reg1_exg=7 & V { V = exg16_r0; } +EXG_r1Set: A is reg1_exg=8 & A { A = exg8h_r0; } +EXG_r1Set: B is reg1_exg=9 & B { B = exg8l_r0; } +EXG_r1Set: CC is reg1_exg=10 & CC { CC = exg8l_r0; } +EXG_r1Set: DP is reg1_exg=11 & DP { DP = exg8h_r0; } +EXG_r1Set: 0 is reg1_exg=12 { } +EXG_r1Set: 0 is reg1_exg=13 { } +EXG_r1Set: E is reg1_exg=14 & E { E = exg8h_r0; } +EXG_r1Set: F is reg1_exg=15 & F { F = exg8l_r0; } +@endif + +@ifdef M6809 +EXG_r0Tmp: D is reg0_exg=0 & D { exg16_r0 = D; } +EXG_r0Tmp: X is reg0_exg=1 & X { exg16_r0 = X; } +EXG_r0Tmp: Y is reg0_exg=2 & Y { exg16_r0 = Y; } +EXG_r0Tmp: U is reg0_exg=3 & U { exg16_r0 = U; } +EXG_r0Tmp: S is reg0_exg=4 & S { exg16_r0 = S; } +EXG_r0Tmp: PC is reg0_exg=5 & PC { exg16_r0 = inst_next; } +EXG_r0Tmp: "inv" is reg0_exg=6 { exg16_r0 = 0xFFFF; } +EXG_r0Tmp: "inv" is reg0_exg=7 { exg16_r0 = 0xFFFF; } +EXG_r0Tmp: A is reg0_exg=8 & A { exg8l_r0 = A; exg8h_r0 = 0xFF; } +EXG_r0Tmp: B is reg0_exg=9 & B { exg8l_r0 = B; exg8h_r0 = 0xFF; } +EXG_r0Tmp: CC is reg0_exg=10 & CC { exg8l_r0 = CC; exg8h_r0 = CC;} +EXG_r0Tmp: DP is reg0_exg=11 & DP { exg8l_r0 = DP; exg8h_r0 = DP;} +EXG_r0Tmp: "inv" is reg0_exg=12 { exg16_r0 = 0xFFFF; } +EXG_r0Tmp: "inv" is reg0_exg=13 { exg16_r0 = 0xFFFF; } +EXG_r0Tmp: "inv" is reg0_exg=14 { exg16_r0 = 0xFFFF; } +EXG_r0Tmp: "inv" is reg0_exg=15 { exg16_r0 = 0xFFFF; } + +EXG_r1Tmp: D is reg1_exg=0 & D { exg16_r1 = D; } +EXG_r1Tmp: X is reg1_exg=1 & X { exg16_r1 = X; } +EXG_r1Tmp: Y is reg1_exg=2 & Y { exg16_r1 = Y; } +EXG_r1Tmp: U is reg1_exg=3 & U { exg16_r1 = U; } +EXG_r1Tmp: S is reg1_exg=4 & S { exg16_r1 = S; } +EXG_r1Tmp: PC is reg1_exg=5 & PC { exg16_r1 = inst_next; } +EXG_r1Tmp: "inv" is reg1_exg=6 { exg16_r1 = 0xFFFF; } +EXG_r1Tmp: "inv" is reg1_exg=7 { exg16_r1 = 0xFFFF; } +EXG_r1Tmp: A is reg1_exg=8 & A { exg8l_r1 = A; exg8h_r1 = 0xFF; } +EXG_r1Tmp: B is reg1_exg=9 & B { exg8l_r1 = B; exg8h_r1 = 0xFF; } +EXG_r1Tmp: CC is reg1_exg=10 & CC { exg8l_r1 = CC; exg8h_r1 = 0xFF;} +EXG_r1Tmp: DP is reg1_exg=11 & DP { exg8l_r1 = DP; exg8h_r1 = 0xFF;} +EXG_r1Tmp: "inv" is reg1_exg=12 { exg16_r1 = 0xFFFF; } +EXG_r1Tmp: "inv" is reg1_exg=13 { exg16_r1 = 0xFFFF; } +EXG_r1Tmp: "inv" is reg1_exg=14 { exg16_r1 = 0xFFFF; } +EXG_r1Tmp: "inv" is reg1_exg=15 { exg16_r1 = 0xFFFF; } + +EXG_r0Set: D is reg0_exg=0 & D { D = exg16_r1; } +EXG_r0Set: X is reg0_exg=1 & X { X = exg16_r1; } +EXG_r0Set: Y is reg0_exg=2 & Y { Y = exg16_r1; } +EXG_r0Set: U is reg0_exg=3 & U { U = exg16_r1; } +EXG_r0Set: S is reg0_exg=4 & S { S = exg16_r1; } +EXG_r0Set: PC is reg0_exg=5 & PC { PC = exg16_r1; } # must GOTO +EXG_r0Set: "inv" is reg0_exg=6 { } +EXG_r0Set: "inv" is reg0_exg=7 { } +EXG_r0Set: A is reg0_exg=8 & A { A = exg8l_r1; } +EXG_r0Set: B is reg0_exg=9 & B { B = exg8l_r1; } +EXG_r0Set: CC is reg0_exg=10 & CC { CC = exg8l_r1; } +EXG_r0Set: DP is reg0_exg=11 & DP { DP = exg8l_r1; } +EXG_r0Set: "inv" is reg0_exg=12 { } +EXG_r0Set: "inv" is reg0_exg=13 { } +EXG_r0Set: "inv" is reg0_exg=14 { } +EXG_r0Set: "inv" is reg0_exg=15 { } + +EXG_r1Set: D is reg1_exg=0 & D { D = exg16_r0; } # Must to r1 set first so A,D = A,B switch +EXG_r1Set: X is reg1_exg=1 & X { X = exg16_r0; } +EXG_r1Set: Y is reg1_exg=2 & Y { Y = exg16_r0; } +EXG_r1Set: U is reg1_exg=3 & U { U = exg16_r0; } +EXG_r1Set: S is reg1_exg=4 & S { S = exg16_r0; } +EXG_r1Set: PC is reg1_exg=5 & PC { PC = exg16_r0; } # must GOTO +EXG_r1Set: "inv" is reg1_exg=6 { } +EXG_r1Set: "inv" is reg1_exg=7 { } +EXG_r1Set: A is reg1_exg=8 & A { A = exg8l_r0; } +EXG_r1Set: B is reg1_exg=9 & B { B = exg8l_r0; } +EXG_r1Set: CC is reg1_exg=10 & CC { CC = exg8l_r0; } +EXG_r1Set: DP is reg1_exg=11 & DP { DP = exg8l_r0; } +EXG_r1Set: "inv" is reg1_exg=12 { } +EXG_r1Set: "inv" is reg1_exg=13 { } +EXG_r1Set: "inv" is reg1_exg=14 { } +EXG_r1Set: "inv" is reg1_exg=15 { } +@endif + +EXG_GOTO: is reg0_exg=5 | reg1_exg=5 { goto [PC]; } +EXG_GOTO: is reg0_exg & reg1_exg { } # PC not set + +TFR_GOTO: is reg1_exg=5 { goto [PC]; } +TFR_GOTO: is reg1_exg { } # PC not set + +# Exchange two registers +:EXG EXG_r0Set,EXG_r1Set is op=0x1E; EXG_r0Set & EXG_r1Set & EXG_r0Tmp & EXG_r1Tmp & EXG_GOTO +{ + build EXG_r0Tmp; + build EXG_r1Tmp; + build EXG_r1Set; + build EXG_r0Set; + build EXG_GOTO; +} + +# Transfer register to another register +:TFR EXG_r0Set,EXG_r1Set is op=0x1F; EXG_r0Set & EXG_r1Set & EXG_r0Tmp & TFR_GOTO +{ + build EXG_r0Tmp; + build EXG_r1Set; + build TFR_GOTO; +} + diff --git a/Ghidra/Processors/6805/data/languages/6x09_pull.sinc b/Ghidra/Processors/6805/data/languages/6x09_pull.sinc new file mode 100644 index 0000000000..f4814e0599 --- /dev/null +++ b/Ghidra/Processors/6805/data/languages/6x09_pull.sinc @@ -0,0 +1,48 @@ +# sleigh specification file for Motorola 6809/Hitachi 6309 + +################################################################# +# PULS helper +################################################################ + +puls0: CC is CC & imm80=1 { Pull1(S, CC); } +puls0: is imm80=0 { } +puls1: puls0" "A is A & imm81=1 & puls0 { Pull1(S, A); } +puls1: puls0 is imm81=0 & puls0 { } +puls2: puls1" "B is B & imm82=1 & puls1 { Pull1(S, B); } +puls2: puls1 is imm82=0 & puls1 { } +puls3: puls2" "DP is DP & imm83=1 & puls2 { Pull1(S, DP); } +puls3: puls2 is imm83=0 & puls2 { } +puls4: puls3" "X is X & imm84=1 & puls3 { Pull2(S, X); } +puls4: puls3 is imm84=0 & puls3 { } +puls5: puls4" "Y is Y & imm85=1 & puls4 { Pull2(S, Y); } +puls5: puls4 is imm85=0 & puls4 { } +puls6: puls5" "U is U & imm86=1 & puls5 { Pull2(S, U); } +puls6: puls5 is imm86=0 & puls5 { } +puls7: puls6" "PC is PC & imm87=1 & puls6 { local t:2 = inst_next; Pull2(S, t); } +puls7: puls6 is imm87=0 & puls6 { } + +:PULS puls7 is op=0x35; puls7 { } + +################################################################ +# PULU helper +################################################################ + +pulu0: CC is CC & imm80=1 { Pull1(U, CC); } +pulu0: is imm80=0 { } +pulu1: pulu0" "A is A & imm81=1 & pulu0 { Pull1(U, A); } +pulu1: pulu0 is imm81=0 & pulu0 { } +pulu2: pulu1" "B is B & imm82=1 & pulu1 { Pull1(U, B); } +pulu2: pulu1 is imm82=0 & pulu1 { } +pulu3: pulu2" "DP is DP & imm83=1 & pulu2 { Pull1(U, DP); } +pulu3: pulu2 is imm83=0 & pulu2 { } +pulu4: pulu3" "X is X & imm84=1 & pulu3 { Pull2(U, X); } +pulu4: pulu3 is imm84=0 & pulu3 { } +pulu5: pulu4" "Y is Y & imm85=1 & pulu4 { Pull2(U, Y); } +pulu5: pulu4 is imm85=0 & pulu4 { } +pulu6: pulu5" "S is S & imm86=1 & pulu5 { Pull2(U, S); } +pulu6: pulu5 is imm86=0 & pulu5 { } +pulu7: pulu6" "PC is PC & imm87=1 & pulu6 { local t:2 = inst_next; Pull2(U, t); } +pulu7: pulu6 is imm87=0 & pulu6 { } + +:PULU pulu7 is op=0x37; pulu7 { } + diff --git a/Ghidra/Processors/6805/data/languages/6x09_push.sinc b/Ghidra/Processors/6805/data/languages/6x09_push.sinc new file mode 100644 index 0000000000..4c1a3d1094 --- /dev/null +++ b/Ghidra/Processors/6805/data/languages/6x09_push.sinc @@ -0,0 +1,47 @@ +# sleigh specification file for Motorola 6809/Hitachi 6309 + +################################################################ +# PSHS helper +################################################################ + +pshs0: CC is CC & imm80=1 { Push1(S, CC); } +pshs0: is imm80=0 { } +pshs1: pshs0" "A is A & imm81=1 & pshs0 { Push1(S, A); } +pshs1: pshs0 is imm81=0 & pshs0 { } +pshs2: pshs1" "B is B & imm82=1 & pshs1 { Push1(S, B); } +pshs2: pshs1 is imm82=0 & pshs1 { } +pshs3: pshs2" "DP is DP & imm83=1 & pshs2 { Push1(S, DP); } +pshs3: pshs2 is imm83=0 & pshs2 { } +pshs4: pshs3" "X is X & imm84=1 & pshs3 { Push2(S, X); } +pshs4: pshs3 is imm84=0 & pshs3 { } +pshs5: pshs4" "Y is Y & imm85=1 & pshs4 { Push2(S, Y); } +pshs5: pshs4 is imm85=0 & pshs4 { } +pshs6: pshs5" "U is U & imm86=1 & pshs5 { Push2(S, U); } +pshs6: pshs5 is imm86=0 & pshs5 { } +pshs7: pshs6" "PC is PC & imm87=1 & pshs6 { local t:2 = inst_next; Push2(S, t); } +pshs7: pshs6 is imm87=0 & pshs6 { } + +:PSHS pshs7 is op=0x34; pshs7 { } +################################################################ +# PSHU helper +################################################################ + +pshu0: CC is CC & imm80=1 { Push1(S, CC); } +pshu0: is imm80=0 { } +pshu1: pshu0" "A is A & imm81=1 & pshu0 { Push1(S, A); } +pshu1: pshu0 is imm81=0 & pshu0 { } +pshu2: pshu1" "B is B & imm82=1 & pshu1 { Push1(S, B); } +pshu2: pshu1 is imm82=0 & pshu1 { } +pshu3: pshu2" "DP is DP & imm83=1 & pshu2 { Push1(U, DP); } +pshu3: pshu2 is imm83=0 & pshu2 { } +pshu4: pshu3" "X is X & imm84=1 & pshu3 { Push2(U, X); } +pshu4: pshu3 is imm84=0 & pshu3 { } +pshu5: pshu4" "Y is Y & imm85=1 & pshu4 { Push2(U, Y); } +pshu5: pshu4 is imm85=0 & pshu4 { } +pshu6: pshu5" "S is S & imm86=1 & pshu5 { Push2(U, S); } +pshu6: pshu5 is imm86=0 & pshu5 { } +pshu7: pshu6" "PC is PC & imm87=1 & pshu6 { local t:2 = inst_next; Push2(U, t); } +pshu7: pshu6 is imm87=0 & pshu6 { } + +:PSHU pshu7 is op=0x36; pshu7 { } +