Skip to content

Commit

Permalink
Enhancement: more 6502 love
Browse files Browse the repository at this point in the history
Added support for more 6502 instructions.

Fixed bugs in 6502 emulator.
  • Loading branch information
uxmal committed Aug 12, 2024
1 parent 51a09c6 commit c941db6
Show file tree
Hide file tree
Showing 3 changed files with 650 additions and 42 deletions.
114 changes: 106 additions & 8 deletions src/Arch/Mos6502/Assembler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,15 @@
*/
#endregion

using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.IO;
using System.Text;
using Reko.Core;
using Reko.Core.Assemblers;
using Reko.Core.Expressions;
using Reko.Core.Loading;
using Reko.Core.Memory;
using Reko.Core.Types;
using System;
using System.Collections.Generic;
using System.IO;

namespace Reko.Arch.Mos6502
{
Expand All @@ -38,7 +36,6 @@ public class Assembler : IAssembler
{
private static readonly Dictionary<Mnemonic, InstrOpcodes> instrOpcodes;

private readonly IServiceProvider services;
private readonly Mos6502Architecture arch;
private readonly Address addrBase;
private readonly IEmitter m;
Expand All @@ -47,14 +44,26 @@ public class Assembler : IAssembler

public Assembler(IServiceProvider services, Mos6502Architecture arch, Address addrBase, List<ImageSymbol> symbols)
{
this.services = services;
this.arch = arch;
this.addrBase = addrBase;
this.symbols = symbols;
this.m = new Emitter();
this.symtab = new SymbolTable();
}

public Assembler(Program program, Address addrStart)
{
this.addrBase = addrStart;
this.symbols = new();
this.symtab = new SymbolTable();
this.arch = (Mos6502Architecture) program.Architecture;
if (!program.SegmentMap.TryFindSegment(addrStart, out var segmentToMutate))
throw new InvalidOperationException($"Address {addrStart} is not a valid location in the program.");
var offset = addrStart - segmentToMutate.MemoryArea.BaseAddress;
this.m = new Emitter(segmentToMutate.MemoryArea);
m.Position = (int) offset;
}

public Program GetImage()
{
var mem = new ByteMemoryArea(addrBase, m.GetBytes());
Expand Down Expand Up @@ -177,11 +186,21 @@ public void Clc()
m.EmitByte(0x18);
}

public void Cld()
{
m.EmitByte(0xD8);
}

public void Cmp(ParsedOperand op)
{
EmitOpcodeOperand(Mnemonic.cmp, op.Operand);
}

public void Cpx(ParsedOperand op)
{
EmitOpcodeOperand(Mnemonic.cpx, op.Operand);
}

public void Cpy(ParsedOperand op)
{
EmitOpcodeOperand(Mnemonic.cpy, op.Operand);
Expand All @@ -197,6 +216,11 @@ public void Dey()
m.EmitByte(0x88);
}

public void Eor(ParsedOperand op)
{
EmitOpcodeOperand(Mnemonic.eor, op.Operand);
}

public void Inc(ParsedOperand op)
{
EmitOpcodeOperand(Mnemonic.inc, op.Operand);
Expand Down Expand Up @@ -248,6 +272,34 @@ public void Ldy(ParsedOperand op)
EmitOpcodeOperand(Mnemonic.ldy, op.Operand);
}

public void Lsr()
{
m.EmitByte(0x4A);
}

public void Lsr(ParsedOperand op)
{
EmitOpcodeOperand(Mnemonic.lsr, op.Operand);
}

public void Org(ushort uAddr)
{
var newOffset = uAddr - (int) addrBase.Offset;
if (newOffset < m.Position)
throw new InvalidOperationException("org directive has a lower address than the current address.");
m.EmitBytes(0, newOffset - m.Position);
}

public void Ora(ParsedOperand op)
{
EmitOpcodeOperand(Mnemonic.ora, op.Operand);
}

public void Pha()
{
m.EmitByte(0x48);
}

public void Rol(RegisterStorage reg)
{
if (reg != Registers.a)
Expand All @@ -260,6 +312,16 @@ public void Rol(ParsedOperand op)
EmitOpcodeOperand(Mnemonic.rol, op.Operand);
}

public void Ror()
{
m.EmitByte(0x6A);
}

public void Rti()
{
m.EmitByte(0x40);
}

public void Rts()
{
m.EmitByte(0x60);
Expand All @@ -270,6 +332,16 @@ public void Sbc(ParsedOperand op)
EmitOpcodeOperand(Mnemonic.sbc, op.Operand);
}

public void Sec()
{
m.EmitByte(0x38);
}

public void Sed()
{
m.EmitByte(0xF8);
}

public void Sei()
{
m.EmitByte(0x78);
Expand Down Expand Up @@ -400,7 +472,6 @@ public int AssembleFragmentAt(Program program, Address addr, string asm)
throw new NotImplementedException();
}


public class ParsedOperand
{
public Operand Operand;
Expand Down Expand Up @@ -470,6 +541,17 @@ static Assembler()
Zp = 0xC4,
Abs = 0xCC,
}},
{ Mnemonic.eor, new InstrOpcodes
{
Imm = 0x49,
Abs = 0x4D,
AbsX = 0x5D,
AbsY = 0x59,
Zp = 0x45,
ZpX = 0x55,
IndX = 0x41,
IndY = 0x51,
}},
{ Mnemonic.inc, new InstrOpcodes{
Zp = 0xE6,
ZpX = 0xF6,
Expand Down Expand Up @@ -500,6 +582,22 @@ static Assembler()
Abs = 0xAC,
AbsX = 0xBC,
} },
{ Mnemonic.lsr, new InstrOpcodes {
Abs = 0x4E,
AbsX = 0x5E,
Zp = 0x46,
ZpX = 0x56,
} },
{ Mnemonic.ora, new InstrOpcodes {
Imm = 0x09,
Abs = 0x0D,
AbsX = 0x1D,
AbsY = 0x19,
Zp = 0x05,
ZpX = 0x15,
IndX = 0x01,
IndY = 0x11,
} },
{ Mnemonic.rol, new InstrOpcodes
{
Zp = 0x26,
Expand Down
Loading

0 comments on commit c941db6

Please sign in to comment.