I'm working on creating a processor definition for the Motorola / NXP HC11 using the Sleigh language for Ghidra. A definition for the HC12 already exists, so I'm working off of that.
The HC12 organizes its instructions into two pages: Page 1 with no prefix, and Page 2 with a prefix of 0x18:
The HC11, on the other hand, has two more pages of registers:
The HC12 processor definition uses a context variable and a recursive constructor to determine if an instruction resides on page 2:
define context contextreg
Prefix18 = (0,0) # 1 if 0x18 is the first byte
PrefixHCS12X = (0,0) # 1 if first byte is 0x18 so that HCS12X to use GPAGE for memory access
UseGPAGE = (1,1) # 1 if should use GPAGE concatenated to lower 16-bit EA
XGATE = (2,2) # 1 if in xgate instruction decode mode
;
-
:^instruction is XGATE=0 & op8=0x18; instruction [ Prefix18=1; ] {}
-
:ABA is XGATE=0 & (Prefix18=1 & op8=0x06)
{
result:1 = A + B;
addition_flags1(A, B, result);
A = result;
}
Another user, also defining an HC11 processor, just used 16-bit instructions instead:
define token withprebyte(16)
pre = (0,16);
define token byte(8)
op8 = (0,7);
OFF: op8 is op8 { export *[const]:2 op8; }
IMM8: op8 is op8 { export *[const]:1 op8; }
:bsetY OFF,IMM8 is pre=0x181C; OFF; IMM8
{
local temp = *:1 (Y+OFF);
temp = temp | (IMM8);
*:1 (Y+OFF) = temp;
}
:bclrY OFF,IMM8 is pre=0x181D; OFF; IMM8
{
local temp = *:1 (Y+OFF);
temp = temp & (~IMM8);
*:1 (Y+OFF) = temp;
}
The approach used on the HC12 seems bizarre and complicated to me. I also don't see how it will work for more than one page. Is there a reason I shouldn't just use 16-bit tokens for those instructions which reside on other pages? Is using the context variable, as the HC12 implementation does, more elegant in some way that I'm not seeing?