implement 45GS02 compound instrictions in the disassembler

This commit is contained in:
mrdudz
2025-06-21 20:37:31 +02:00
parent 37144ed014
commit 3321910848
7 changed files with 866 additions and 10 deletions

View File

@@ -226,6 +226,82 @@ void OH_Implicit (const OpcDesc* D)
void OH_Implicit_ea_45GS02 (const OpcDesc* D)
/* handle disassembling EOM prefixed opcodes, $ea $xx */
{
/* Get byte after EOM */
unsigned opc = GetCodeByte (PC+1);
static const char *mnemonics[8] = {
"ora", "and", "eor", "adc", "sta", "lda", "cmp", "sbc"
};
if ((opc & 0x1f) == 0x12) {
unsigned zp = GetCodeByte (PC+2);
Indent (MCol);
Output ("%s", mnemonics[(opc >> 5) & 7]);
Indent (ACol);
Output ("[$%02X],z", zp);
/* Add the code stuff as comment */
LineComment (PC, 3);
/* End the line */
LineFeed ();
} else {
OH_Implicit (D);
}
}
void OH_Implicit_42_45GS02 (const OpcDesc* D)
/* handle disassembling NEG NEG prefixed opcodes, $42 42 ($ea) $xx */
{
/* Get bytes after NEG */
unsigned n1 = GetCodeByte (PC+1);
unsigned opc = GetCodeByte (PC+2);
/* NEG:NEG:NOP (42 42 ea) prefix */
static const char *mnemonics[8] = {
"orq", "andq", "eorq", "adcq", "stq", "ldq", "cmpq", "sbcq"
};
if (n1 == 0x42) {
/* detected 0x42 0x42 */
if (opc == 0xea) {
/* detected 0x42 0x42 0xea */
unsigned opc = GetCodeByte (PC+3);
if ((opc & 0x1f) == 0x12) {
unsigned zp = GetCodeByte (PC+4);
Indent (MCol);
Output ("%s", mnemonics[(opc >> 5) & 7]);
Indent (ACol);
Output ("[$%02X]", zp); /* with or without ,z ? */
/* Add the code stuff as comment */
LineComment (PC, 5);
/* End the line */
LineFeed ();
return;
}
} else {
/* use another table for these */
OpcDesc* NewDesc = &OpcTable_45GS02_extended[opc];
NewDesc->Handler (NewDesc);
return;
}
}
/* no prefix detected */
OH_Implicit (D);
}
void OH_Immediate (const OpcDesc* D)
{
OneLine (D, "#$%02X", GetCodeByte (PC+1));
@@ -276,6 +352,20 @@ void OH_Direct (const OpcDesc* D)
void OH_Direct_Q (const OpcDesc* D)
{
/* Get the operand */
unsigned Addr = GetCodeByte (PC+3);
/* Generate a label in pass 1 */
GenerateLabel (D->Flags, Addr);
/* Output the line */
OneLine (D, "%s", GetAddrArg (D->Flags, Addr));
}
void OH_DirectX (const OpcDesc* D)
{
/* Get the operand */
@@ -290,6 +380,20 @@ void OH_DirectX (const OpcDesc* D)
void OH_DirectX_Q (const OpcDesc* D)
{
/* Get the operand */
unsigned Addr = GetCodeByte (PC+3);
/* Generate a label in pass 1 */
GenerateLabel (D->Flags, Addr);
/* Output the line */
OneLine (D, "%s,x", GetAddrArg (D->Flags, Addr));
}
void OH_DirectY (const OpcDesc* D)
{
/* Get the operand */
@@ -318,6 +422,20 @@ void OH_Absolute (const OpcDesc* D)
void OH_Absolute_Q (const OpcDesc* D)
{
/* Get the operand */
unsigned Addr = GetCodeWord (PC+3);
/* Generate a label in pass 1 */
GenerateLabel (D->Flags, Addr);
/* Output the line */
OneLine (D, "%s%s", GetAbsOverride (D->Flags, Addr), GetAddrArg (D->Flags, Addr));
}
void OH_AbsoluteX (const OpcDesc* D)
{
/* Get the operand */
@@ -332,6 +450,20 @@ void OH_AbsoluteX (const OpcDesc* D)
void OH_AbsoluteX_Q (const OpcDesc* D)
{
/* Get the operand */
unsigned Addr = GetCodeWord (PC+3);
/* Generate a label in pass 1 */
GenerateLabel (D->Flags, Addr);
/* Output the line */
OneLine (D, "%s%s,x", GetAbsOverride (D->Flags, Addr), GetAddrArg (D->Flags, Addr));
}
void OH_AbsoluteY (const OpcDesc* D)
{
/* Get the operand */
@@ -472,6 +604,20 @@ void OH_DirectIndirectZ (const OpcDesc* D)
void OH_DirectIndirectZ_Q (const OpcDesc* D)
{
/* Get the operand */
unsigned Addr = GetCodeByte (PC+3);
/* Generate a label in pass 1 */
GenerateLabel (D->Flags, Addr);
/* Output the line */
OneLine (D, "(%s),z", GetAddrArg (D->Flags, Addr));
}
void OH_DirectXIndirect (const OpcDesc* D)
{
/* Get the operand */
@@ -531,6 +677,41 @@ void OH_BitBranch (const OpcDesc* D)
xfree (BranchLabel);
}
void OH_BitBranch_Q (const OpcDesc* D)
{
char* BranchLabel;
/* Get the operands */
unsigned char TestAddr = GetCodeByte (PC+3);
signed char BranchOffs = GetCodeByte (PC+4);
/* Calculate the target address for the branch */
unsigned BranchAddr = (((int) PC+5) + BranchOffs) & 0xFFFF;
/* Generate labels in pass 1. The bit branch codes are special in that
** they don't really match the remainder of the 6502 instruction set (they
** are a Rockwell addon), so we must pass additional flags as direct
** value to the second GenerateLabel call.
*/
GenerateLabel (D->Flags, TestAddr);
GenerateLabel (flLabel, BranchAddr);
/* Make a copy of an operand, so that
** the other operand can't overwrite it.
** [GetAddrArg() uses a statically-stored buffer.]
*/
BranchLabel = xstrdup (GetAddrArg (flLabel, BranchAddr));
/* Output the line */
OneLine (D, "%s,%s", GetAddrArg (D->Flags, TestAddr), BranchLabel);
xfree (BranchLabel);
}
void OH_BitBranch_m740 (const OpcDesc* D)
/* <bit> zp, rel
** NOTE: currently <bit> is part of the instruction