Skip to content

Commit

Permalink
Version 4.4.1
Browse files Browse the repository at this point in the history
  • Loading branch information
informedcitizenry committed Oct 18, 2024
1 parent 2ab57c3 commit 6f5aba2
Show file tree
Hide file tree
Showing 14 changed files with 759 additions and 376 deletions.
33 changes: 29 additions & 4 deletions Sixty502DotNet.Shared/CodeGen/Encoders/CpuEncoderBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,23 @@ protected bool RegisterIsSymbol(SyntaxParser.RegisterContext register)
return Services.State.Symbols.Lookup(register.GetText()) is IValueResolver || Services.State.InFirstPass;
}

protected bool EmitOpcode(int opcodeHex, SyntaxParser.CpuInstructionContext context, SyntaxParser.ExprContext operand)
protected bool EmitOpcode(int opcodeHex, SyntaxParser.CpuInstructionContext context, SyntaxParser.ExprContext operand, bool signed8 = false)
{
return EmitOpcode(opcodeHex, context, null, new SyntaxParser.ExprContext[] { operand }, 1);
if (!signed8)
{
return EmitOpcode(opcodeHex, context, null, new SyntaxParser.ExprContext[] { operand }, 1);
}
context.opcode = opcodeHex;
context.opcodeSize = opcodeHex.Size();
int operandVal = Services.Evaluator.SafeEvalAddress(operand);
if ((operandVal < sbyte.MinValue || operandVal > sbyte.MaxValue) &&
!Services.State.PassNeeded && Services.State.CurrentPass > 4)
{
throw new Error(operand, "Operand must be a signed eight-bit value");
}
context.operand = operandVal & 0xff;
context.operandSize = 1;
return true;
}

protected bool EmitOpcode(int opcodeHex, SyntaxParser.CpuInstructionContext context, SyntaxParser.ExprContext operand, int operandSize)
Expand Down Expand Up @@ -206,11 +220,12 @@ protected bool EmitOpcode(int opcodeHex, SyntaxParser.CpuInstructionContext cont
operandValue <<= size * 8;
if (i > 0 || context is not SyntaxParser.CpuInstructionImmmediateContext)
{
operandValue |= (long)Services.Evaluator.SafeEvalAddress(operands[i]);
if (operandValue.Size() > 2 && !Services.State.PassNeeded)
long component = Services.Evaluator.SafeEvalAddress(operands[i]);
if (component.Size() > 2 && !Services.State.PassNeeded)
{
return false;
}
operandValue |= component;
}
else
{
Expand Down Expand Up @@ -302,6 +317,16 @@ protected bool EmitRelative(int opcode, SyntaxParser.CpuInstructionContext conte

protected bool EmitRelative(M6xxOpcode opcode, SyntaxParser.CpuInstructionContext context, SyntaxParser.ExprContext expr)
{
if (opcode.relative != Bad && opcode.relativeAbs != Bad)
{
int from = Cpuid.Equals("65816") ? 3 : 2;
int operand = Services.Evaluator.SafeEvalAddress(expr);
int offs = operand - (Services.State.Output.LogicalPC + from);
if (offs < -128 || offs > 127)
{
return EmitRelative(opcode.relativeAbs, context, expr, 2);
}
}
int opcodeHex = opcode.relative != Bad ? opcode.relative : opcode.relativeAbs;
return EmitRelative(opcodeHex, context, expr, opcodeHex == opcode.relative ? 1 : 2);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,11 +303,14 @@ public override bool VisitCpuInstructionImmmediate([NotNull] SyntaxParser.CpuIns
int size = 1;
if (context.expr().Length == 1)
{
int immZpHex = opcode.immediate;
int immAbshex = opcode.immediateAbs;
if ((s_accumulators.Contains(mnemonic) && _a16) || (s_indexes.Contains(mnemonic) && _x16))
{
size = 2;
immZpHex = Bad;
immAbshex = opcode.immediate;
}
bool emitted = EmitOpcode(opcode.immediate, context, context.bitwidthModifier(), context.imm, size);
bool emitted = EmitOpcodeVariant(immZpHex, immAbshex, Bad, context, context.bitwidthModifier(), context.imm);
if (!emitted)
{
return false;
Expand Down Expand Up @@ -472,6 +475,7 @@ protected override void OnSetCpu(string cpuid)
{
case "45GS02":
_opcodes = s_45gs02Opcodes;
_disassembly.Add(s_45gs02Disassembly);
_disassembly.Add(s_65c02Disassembly);
_disassembly.Add(s_rc6502Diassembly);
_disassembly.Add(s_65ce02Disassembly);
Expand Down Expand Up @@ -534,6 +538,7 @@ protected override void OnSetCpu(string cpuid)
{
_opcodes.Add(SyntaxParser.BRA, new M6xxOpcode(Bad, Bad, Bad, 0x50, Bad, Bad, Bad, Bad, Bad, Bad, Bad, Bad, Bad));
}
Services.ArchitectureOptions.LongAddressing = cpuid.Equals("65816");

_dp = -1;
}
Expand Down
486 changes: 303 additions & 183 deletions Sixty502DotNet.Shared/CodeGen/Encoders/M65xxInstructionEncoderMembers.cs

Large diffs are not rendered by default.

31 changes: 27 additions & 4 deletions Sixty502DotNet.Shared/CodeGen/Encoders/Z80InstructionEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,16 @@ private bool EmitSingleOperand(SyntaxParser.MnemonicContext mnemonicContext, Syn
}
else
{
int rst = Evaluator.EvalIntegerLiteral(primary.primaryExpr(), 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38);
int rst;
if (Cpuid[0] == 'i')
{
rst = Evaluator.EvalIntegerLiteral(primary.primaryExpr(), "3-bit constant expected", 0, 8);
rst *= 8;
}
else
{
rst = Evaluator.EvalIntegerLiteral(primary.primaryExpr(), 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38);
}
opcode = 0xc7 + rst;
}
instructionContext.opcode = opcode;
Expand Down Expand Up @@ -322,18 +331,32 @@ public override bool VisitCpuInstructionZ80Immediate([NotNull] SyntaxParser.CpuI
int regType = context.register().Start.Type;
int operandSize = 2;
uint exprMode = Z80Modes.N161;
if ((s_R8s.Contains(regType) && !s_Z80ConditionalJumps.Contains(context.Start.Type)) ||
(Cpuid[0] == 'g' && context.Start.Type == SyntaxParser.ADD && regType == SyntaxParser.SP))
bool signed8 = Cpuid[0] == 'g' && context.Start.Type == SyntaxParser.ADD && regType == SyntaxParser.SP;
bool is16BitLxi = context.Start.Type == SyntaxParser.LXI && regType.IsOneOf(SyntaxParser.B, SyntaxParser.D, SyntaxParser.H);
if ((s_R8s.Contains(regType) && !is16BitLxi && !s_Z80ConditionalJumps.Contains(context.Start.Type)) || signed8)
{
operandSize = 1;
exprMode = Z80Modes.N81;
}
uint regMode = GetRegisterMode(context.register(), false);
if (is16BitLxi)
{
regMode = regMode switch
{
Z80Modes.B0 => Z80Modes.BC0,
Z80Modes.D0 => Z80Modes.DE0,
_ => Z80Modes.HL0
};
}
int code = GetOpcode(context.Start.Type, exprMode | regMode);
if (context.Start.Type.IsOneOf(SyntaxParser.DJNZ, SyntaxParser.JR))
{
return EmitRelative(code, context, context.expr(), 1);
}
if (signed8)
{
return EmitOpcode(code, context, context.expr(), true);
}
return EmitOpcode(code, context, context.expr(), operandSize);
}

Expand Down Expand Up @@ -475,7 +498,7 @@ public override bool VisitCpuInstructionZ80Index([NotNull] SyntaxParser.CpuInstr
}
context.opcode = displ;
context.opcodeSize = opcode.Size() + 1;
if (opcode == 0xcbdd)
if (opcode == 0xcbdd || opcode == 0xcbfd)
{
context.opcodeSize++;
}
Expand Down
Loading

0 comments on commit 6f5aba2

Please sign in to comment.