question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Help for Motorola 6809 EXG instruction

See original GitHub issue

I am currently defining a slaspec for the Motorola 6809 CPU. I would need some help for the EXG instruction (It exchanges the contents of two registers). A good documentation for EXG instruction You will find here: 6x09 Instruction Sets on page 66.

There are three challenges I can find no solution accepted by sleigh parser:

  • The two registers are defined in a separate data byte.
  • The two registers may have 8- or 16-bit which may not be mixed. If mixed => invalid instr.
  • There are “invalid” registers possible. If used => invalid instr.

Here my current approach:

# sleigh specification file for Motorola 6809
define endian=big;
define alignment=1;

define space RAM     type=ram_space      size=2  default;
define space register type=register_space size=1;

define register offset=0 size=1 [ A B DP ]; # 8-bit registers A, B, DP
define register offset=0 size=2 [ D ]; # 16-bit D reg. (Same addr. as A/B)
define register offset=8 size=1 [ CC ]; # 8-bit condition code register
define register offset=16 size=2 [ PC X Y U S ]; # 16-bit registers:

define token opbyte (8)
   op    = (0,7)
;

define token data8 (8)
    reg01= (4,7)                                                                
    reg02= (4,7)
    reg11= (0,3)
    reg12= (0,3)
;

# register set for EXG instruction 8-bit registers
attach variables [ reg01 ] [ _ _ _ _ _ _  _ _ A B CC DP _ _ _ _ ];
attach variables [ reg11 ] [ _ _ _ _ _ _  _ _ A B CC DP _ _ _ _ ];
# register set for EXG instruction 16-bit registers
attach variables [ reg02 ] [ D X Y U S PC _ _ _ _ _  _  _ _ _ _ ];
attach variables [ reg12 ] [ D X Y U S PC _ _ _ _ _  _  _ _ _ _ ];

# Exchange two 8-bit registers
# Test with registers A, B
:EXG reg01,reg11    is op=0x1E; (reg01=8 | reg01=9) & (reg11=8 | reg11=9)
{
    local tmp = reg01;
    reg01 = reg11;
    reg11 = tmp;
}

# Exchange two 16-bit registers
# Test with registers D, X
:EXG reg02,reg12    is op=0x1E; (reg02=0 | reg02=1) & (reg12=0 | reg12=1)
{
    local tmp = reg02;
    reg02 = reg12;
    reg12 = tmp;
}

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
emteerecommented, Mar 17, 2019

This should do what you want. Also for the 6309 which has a slightly different set of semantics. The approach is a little brute force and there are probably other clever ways, but this lays out all the subtle cases, and the cases when an operand is invalid which have specifically called out semantics.

Also note the GOTO semantics when the PC is one of the targets.

Looking forward to the full language!

# sleigh specification file for Motorola 6809
define endian=big;
define alignment=1;

define space RAM     type=ram_space      size=2  default;
define space register type=register_space size=1;

define register offset=0 size=1 [ A B DP ]; # 8-bit registers A, B, DP
define register offset=0 size=2 [ D ]; # 16-bit D reg. (Same addr. as A/B)
define register offset=8 size=1 [ CC ]; # 8-bit condition code register
define register offset=16 size=2 [ PC X Y U S ]; # 16-bit registers:

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 token opbyte (8)
   op    = (0,7)
;

@define M6809 ""

define token data8 (8)
    reg01= (4,7)                                                                
    reg02= (4,7)
    reg11= (0,3)
    reg12= (0,3)
    reg0_exg = (4,7)
    reg1_exg = (0,3)
;

@ifdef M6309
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; } # TODO 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; } # TODO 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; } # TODO 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; } # TODO 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

# 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;
}
0reactions
aladurcommented, Nov 2, 2019

Now there is a PR #1201 for M6809 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

6x09 Instruction Sets - Color Computer Archive
The EXG instruction requires a postbyte in which the two registers that are involved are encoded into the upper and lower nibbles. See...
Read more >
MC6809-MC6809E Microprocessor Programming Manual ...
This section contains a general description of the Motorola MC6809 and MC6809E Microprocessor Units (MPU). Pin assignments and a brief description of each...
Read more >
M6809PM.rev0_May83.pdf - Bitsavers.org
MOTOROLA. (3). MC6809-MC6809E. Microprocessor Programming Manual. 8 BIT. M6809. M6809PM/AD ... Postbyte Usage for EXG/TFR, PSH/PUL Instructions.
Read more >
The MC6809 CookBook.pdf
defined by Motorola. (For further information, consult the M6800 microprocesor applications manual). • The 6809, µP, housed in a 40-pin package, ...
Read more >
MC6809 MC6809E Microprocessor Programming Manuial 1981
manual to refer to both the MC6809 and MC6809E processors. When a topic relates to ... assembled using the Motorola MC6809 Macro Assembler....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found