Adds instructions, display, instructiontarget, etc
This commit is contained in:
parent
54fa43a893
commit
053d7b267d
|
@ -14,7 +14,7 @@ class Assembler(private var labels: Labels,
|
||||||
private var codeAssembledOK = false
|
private var codeAssembledOK = false
|
||||||
private var BOOTSTRAP_ADDRESS = 0x600
|
private var BOOTSTRAP_ADDRESS = 0x600
|
||||||
|
|
||||||
fun assembleCode(lines: Array<String>): Boolean {
|
fun assembleCode(lines: List<String>): Boolean {
|
||||||
lines.forEach { line ->
|
lines.forEach { line ->
|
||||||
if (!assembleLine(line)) {
|
if (!assembleLine(line)) {
|
||||||
return false
|
return false
|
||||||
|
@ -132,7 +132,7 @@ class Assembler(private var labels: Labels,
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkAbsolute(param: String, opcode: Int): Boolean {
|
private fun checkAbsolute(param: String, opcode: Int): Boolean {
|
||||||
if (checkWordOperand("^([\\w\$]+)$")) {
|
if (checkWordOperand(param, opcode, "^([\\w\$]+)$")) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,40 +196,67 @@ class Assembler(private var labels: Labels,
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkIndirectY(param: String, opcode: Int): Boolean {
|
private fun checkIndirectY(param: String, opcode: Int): Boolean {
|
||||||
|
if (opcode == 0xff) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return checkByteOperand(param, opcode, "^\\(([\\w\$]+)\\),Y$")
|
return checkByteOperand(param, opcode, "^\\(([\\w\$]+)\\),Y$")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkIndirectX(param: String, opcode: Int): Boolean {
|
private fun checkIndirectX(param: String, opcode: Int): Boolean {
|
||||||
|
if (opcode == 0xff) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return checkByteOperand(param, opcode, "^\\(([\\w\$]+)\\),X$")
|
return checkByteOperand(param, opcode, "^\\(([\\w\$]+)\\),X$")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkIndirect(param: String, opcode: Int): Boolean {
|
private fun checkIndirect(param: String, opcode: Int): Boolean {
|
||||||
|
if (opcode == 0xff) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return checkWordOperand(param, opcode, "^\\(([\\w\$]+)\\)$")
|
return checkWordOperand(param, opcode, "^\\(([\\w\$]+)\\)$")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkAbsoluteY(param: String, opcode: Int): Boolean {
|
private fun checkAbsoluteY(param: String, opcode: Int): Boolean {
|
||||||
|
if (opcode == 0xff) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return checkWordOperand(param, opcode, "^([\\w\$]+),Y$") ||
|
return checkWordOperand(param, opcode, "^([\\w\$]+),Y$") ||
|
||||||
checkLabel(param, opcode, "^\\w+,Y$".toRegex())
|
checkLabel(param, opcode, "^\\w+,Y$".toRegex())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkAbsoluteX(param: String, opcode: Int): Boolean {
|
private fun checkAbsoluteX(param: String, opcode: Int): Boolean {
|
||||||
|
if (opcode == 0xff) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return checkWordOperand(param, opcode, "^([\\w\$]+),X$") ||
|
return checkWordOperand(param, opcode, "^([\\w\$]+),X$") ||
|
||||||
checkLabel(param, opcode, "^\\w+,X$".toRegex())
|
checkLabel(param, opcode, "^\\w+,X$".toRegex())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkZeroPageY(param: String, opcode: Int): Boolean {
|
private fun checkZeroPageY(param: String, opcode: Int): Boolean {
|
||||||
|
if (opcode == 0xff) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return checkByteOperand(param, opcode, "^([\\w\$]+),Y")
|
return checkByteOperand(param, opcode, "^([\\w\$]+),Y")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkZeroPageX(param: String, opcode: Int): Boolean {
|
private fun checkZeroPageX(param: String, opcode: Int): Boolean {
|
||||||
|
if (opcode == 0xff) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return checkByteOperand(param, opcode, "^([\\w\$]+),X")
|
return checkByteOperand(param, opcode, "^([\\w\$]+),X")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkZeroPage(param: String, opcode: Int): Boolean {
|
private fun checkZeroPage(param: String, opcode: Int): Boolean {
|
||||||
|
if (opcode == 0xff) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return innerCheckByteOperand(param, opcode)
|
return innerCheckByteOperand(param, opcode)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkImmediate(param: String, opcode: Int): Boolean {
|
private fun checkImmediate(param: String, opcode: Int): Boolean {
|
||||||
|
if (opcode == 0xff) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if (checkByteOperand(param, opcode, "^#([\\w\$]+)$")) {
|
if (checkByteOperand(param, opcode, "^#([\\w\$]+)$")) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,83 +1,87 @@
|
||||||
package android.emu6502
|
package android.emu6502
|
||||||
|
|
||||||
import android.emu6502.instructions.*
|
import android.emu6502.instructions.BaseInstruction
|
||||||
|
import android.emu6502.instructions.Instruction
|
||||||
|
import android.emu6502.instructions.InstructionTarget
|
||||||
|
import android.emu6502.instructions.impl.*
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import java.util.HashMap
|
import java.util.HashMap
|
||||||
import kotlin.reflect.KMemberFunction0
|
import kotlin.reflect.KMemberFunction0
|
||||||
|
|
||||||
class CPU(private val memory: Memory) {
|
class CPU(private val memory: Memory) {
|
||||||
// Accumulator
|
// Accumulator
|
||||||
private var A: Byte = 0
|
var A: Int = 0
|
||||||
// Registers
|
// Registers
|
||||||
private var X: Byte = 0
|
var X: Int = 0
|
||||||
private var Y: Byte = 0
|
var Y: Int = 0
|
||||||
// Program counter
|
// Program counter
|
||||||
private var PC = 0x600
|
var PC: Int = 0x600
|
||||||
// Stack pointer
|
// Stack pointer
|
||||||
private var SP = 0xFF
|
var SP: Int = 0xFF
|
||||||
private var flags: Byte = 0
|
// Processor flags
|
||||||
|
var P: Int = 0
|
||||||
private var isRunning = false
|
private var isRunning = false
|
||||||
private var debug = false
|
private var debug = false
|
||||||
private var monitoring = false
|
private var monitoring = false
|
||||||
private var TAG = "CPU"
|
private var TAG = "CPU"
|
||||||
private val instructionList: HashMap<Int, KMemberFunction0<BaseInstruction, Unit>> = HashMap()
|
val instructionList: HashMap<Int, InstructionTarget> = HashMap()
|
||||||
private val operationList: HashMap<Instruction, BaseInstruction> = hashMapOf(
|
private val operationList: HashMap<Instruction, BaseInstruction> = hashMapOf(
|
||||||
Pair(Instruction.ADC, ADC(instructionList)),
|
Pair(Instruction.ADC, ADC(this)),
|
||||||
Pair(Instruction.AND, AND(instructionList)),
|
Pair(Instruction.AND, AND(this)),
|
||||||
Pair(Instruction.ASL, ASL(instructionList)),
|
Pair(Instruction.ASL, ASL(this)),
|
||||||
Pair(Instruction.BIT, BIT(instructionList)),
|
Pair(Instruction.BIT, BIT(this)),
|
||||||
Pair(Instruction.BPL, BPL(instructionList)),
|
Pair(Instruction.LDA, LDA(this)),
|
||||||
Pair(Instruction.BMI, BMI(instructionList)),
|
Pair(Instruction.LDX, LDX(this)),
|
||||||
Pair(Instruction.BVC, BVC(instructionList)),
|
Pair(Instruction.LDY, LDY(this)),
|
||||||
Pair(Instruction.BVS, BVS(instructionList)),
|
Pair(Instruction.STA, STA(memory, this)),
|
||||||
Pair(Instruction.BCC, BCC(instructionList)),
|
Pair(Instruction.STX, STX(this)),
|
||||||
Pair(Instruction.BCS, BCS(instructionList)),
|
Pair(Instruction.ORA, ORA(this))
|
||||||
Pair(Instruction.BNE, BNE(instructionList)),
|
// Pair(Instruction.BPL, BPL(this)),
|
||||||
Pair(Instruction.BEQ, BEQ(instructionList)),
|
// Pair(Instruction.BMI, BMI(this)),
|
||||||
Pair(Instruction.BRK, BRK(instructionList)),
|
// Pair(Instruction.BVC, BVC(this)),
|
||||||
Pair(Instruction.CMP, CMP(instructionList)),
|
// Pair(Instruction.BVS, BVS(this)),
|
||||||
Pair(Instruction.CPX, CPX(instructionList)),
|
// Pair(Instruction.BCC, BCC(this)),
|
||||||
Pair(Instruction.CPY, CPY(instructionList)),
|
// Pair(Instruction.BCS, BCS(this)),
|
||||||
Pair(Instruction.DEC, DEC(instructionList)),
|
// Pair(Instruction.BNE, BNE(this)),
|
||||||
Pair(Instruction.EOR, EOR(instructionList)),
|
// Pair(Instruction.BEQ, BEQ(this)),
|
||||||
Pair(Instruction.CLC, CLC(instructionList)),
|
// Pair(Instruction.BRK, BRK(this)),
|
||||||
Pair(Instruction.SEC, SEC(instructionList)),
|
// Pair(Instruction.CMP, CMP(this)),
|
||||||
Pair(Instruction.CLI, CLI(instructionList)),
|
// Pair(Instruction.CPX, CPX(this)),
|
||||||
Pair(Instruction.SEI, SEI(instructionList)),
|
// Pair(Instruction.CPY, CPY(this)),
|
||||||
Pair(Instruction.CLV, CLV(instructionList)),
|
// Pair(Instruction.DEC, DEC(this)),
|
||||||
Pair(Instruction.CLD, CLD(instructionList)),
|
// Pair(Instruction.EOR, EOR(this)),
|
||||||
Pair(Instruction.SED, SED(instructionList)),
|
// Pair(Instruction.CLC, CLC(this)),
|
||||||
Pair(Instruction.INC, INC(instructionList)),
|
// Pair(Instruction.SEC, SEC(this)),
|
||||||
Pair(Instruction.JMP, JMP(instructionList)),
|
// Pair(Instruction.CLI, CLI(this)),
|
||||||
Pair(Instruction.JSR, JSR(instructionList)),
|
// Pair(Instruction.SEI, SEI(this)),
|
||||||
Pair(Instruction.LDA, LDA(instructionList)),
|
// Pair(Instruction.CLV, CLV(this)),
|
||||||
Pair(Instruction.LDX, LDX(instructionList)),
|
// Pair(Instruction.CLD, CLD(this)),
|
||||||
Pair(Instruction.LDY, LDY(instructionList)),
|
// Pair(Instruction.SED, SED(this)),
|
||||||
Pair(Instruction.LSR, LSR(instructionList)),
|
// Pair(Instruction.INC, INC(this)),
|
||||||
Pair(Instruction.NOP, NOP(instructionList)),
|
// Pair(Instruction.JMP, JMP(this)),
|
||||||
Pair(Instruction.ORA, ORA(instructionList)),
|
// Pair(Instruction.JSR, JSR(this)),
|
||||||
Pair(Instruction.TAX, TAX(instructionList)),
|
// Pair(Instruction.LSR, LSR(this)),
|
||||||
Pair(Instruction.TXA, TXA(instructionList)),
|
// Pair(Instruction.NOP, NOP(this)),
|
||||||
Pair(Instruction.DEX, DEX(instructionList)),
|
// Pair(Instruction.TAX, TAX(this)),
|
||||||
Pair(Instruction.INX, INX(instructionList)),
|
// Pair(Instruction.TXA, TXA(this)),
|
||||||
Pair(Instruction.TAY, TAY(instructionList)),
|
// Pair(Instruction.DEX, DEX(this)),
|
||||||
Pair(Instruction.TYA, TYA(instructionList)),
|
// Pair(Instruction.INX, INX(this)),
|
||||||
Pair(Instruction.DEY, DEY(instructionList)),
|
// Pair(Instruction.TAY, TAY(this)),
|
||||||
Pair(Instruction.INY, INY(instructionList)),
|
// Pair(Instruction.TYA, TYA(this)),
|
||||||
Pair(Instruction.ROR, ROR(instructionList)),
|
// Pair(Instruction.DEY, DEY(this)),
|
||||||
Pair(Instruction.ROL, ROL(instructionList)),
|
// Pair(Instruction.INY, INY(this)),
|
||||||
Pair(Instruction.RTI, RTI(instructionList)),
|
// Pair(Instruction.ROR, ROR(this)),
|
||||||
Pair(Instruction.RTS, RTS(instructionList)),
|
// Pair(Instruction.ROL, ROL(this)),
|
||||||
Pair(Instruction.SBC, SBC(instructionList)),
|
// Pair(Instruction.RTI, RTI(this)),
|
||||||
Pair(Instruction.STA, STA(instructionList)),
|
// Pair(Instruction.RTS, RTS(this)),
|
||||||
Pair(Instruction.TXS, TXS(instructionList)),
|
// Pair(Instruction.SBC, SBC(this)),
|
||||||
Pair(Instruction.TSX, TSX(instructionList)),
|
// Pair(Instruction.TXS, TXS(this)),
|
||||||
Pair(Instruction.PHA, PHA(instructionList)),
|
// Pair(Instruction.TSX, TSX(this)),
|
||||||
Pair(Instruction.PLA, PLA(instructionList)),
|
// Pair(Instruction.PHA, PHA(this)),
|
||||||
Pair(Instruction.PHP, PHP(instructionList)),
|
// Pair(Instruction.PLA, PLA(this)),
|
||||||
Pair(Instruction.PLP, PLP(instructionList)),
|
// Pair(Instruction.PHP, PHP(this)),
|
||||||
Pair(Instruction.STX, STX(instructionList)),
|
// Pair(Instruction.PLP, PLP(this)),
|
||||||
Pair(Instruction.STY, STY(instructionList))
|
// Pair(Instruction.STY, STY(this))
|
||||||
)
|
)
|
||||||
|
|
||||||
fun execute() {
|
fun execute() {
|
||||||
|
@ -96,19 +100,41 @@ class CPU(private val memory: Memory) {
|
||||||
|
|
||||||
private fun executeNextInstruction() {
|
private fun executeNextInstruction() {
|
||||||
val instruction = Integer.valueOf(popByte().toInt().toString(), 16)
|
val instruction = Integer.valueOf(popByte().toInt().toString(), 16)
|
||||||
val function = instructionList.get(instruction)
|
val target = instructionList.get(instruction)
|
||||||
if (function != null) {
|
if (target != null) {
|
||||||
ORA(instructionList).function()
|
val function = target.method
|
||||||
|
target.operation.function()
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "Address $" + PC + " - unknown opcode")
|
Log.e(TAG, "Address $" + PC + " - unknown opcode")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun popByte(): Byte {
|
fun popByte(): Int {
|
||||||
return memory.get((PC++).and(0xff));
|
return memory.get((PC++).and(0xff));
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setRandomByte() {
|
private fun setRandomByte() {
|
||||||
memory.set(0xfe, Math.floor(Math.random() * 256).toInt())
|
memory.set(0xfe, Math.floor(Math.random() * 256).toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setSZFlagsForRegA() {
|
||||||
|
setSZFlagsForValue(A)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setSZFlagsForValue(value: Int) {
|
||||||
|
if (value != 0) {
|
||||||
|
P = P.and(0xfd);
|
||||||
|
} else {
|
||||||
|
P = P.or(0x02);
|
||||||
|
}
|
||||||
|
if (value.and(0x80) != 0) {
|
||||||
|
P = P.or(0x80);
|
||||||
|
} else {
|
||||||
|
P = P.and(0x7f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun popWord(): Int {
|
||||||
|
return popByte() + popByte().shl(8)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package android.emu6502
|
||||||
|
|
||||||
|
final class Display {
|
||||||
|
fun updatePixel(addr: Int) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package android.emu6502
|
||||||
|
|
||||||
|
final class Emulator {
|
||||||
|
val display = Display()
|
||||||
|
val memory = Memory(display)
|
||||||
|
val cpu = CPU(memory)
|
||||||
|
val assembler = Assembler(Labels(), memory, Symbols())
|
||||||
|
}
|
|
@ -1,13 +1,20 @@
|
||||||
package android.emu6502
|
package android.emu6502
|
||||||
|
|
||||||
class Memory {
|
class Memory(private val display: Display) {
|
||||||
private val mem = ByteArray(65536)
|
private val mem = IntArray(65536)
|
||||||
|
|
||||||
public fun get(addr: Int): Byte {
|
fun get(addr: Int): Int {
|
||||||
return mem[addr]
|
return mem[addr]
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun set(addr: Int, value: Int) {
|
fun set(addr: Int, value: Int) {
|
||||||
mem[addr] = value.toByte()
|
mem[addr] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
fun storeByte(addr: Int, value: Int) {
|
||||||
|
set(addr, value.and(0xff))
|
||||||
|
if ((addr >= 0x200) && (addr <= 0x5ff)) {
|
||||||
|
display.updatePixel(addr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package android.emu6502.app
|
package android.emu6502.app
|
||||||
|
|
||||||
|
import android.emu6502.Emulator
|
||||||
import android.emu6502.R
|
import android.emu6502.R
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.design.widget.FloatingActionButton
|
import android.support.design.widget.FloatingActionButton
|
||||||
|
@ -9,6 +10,7 @@ import android.support.v7.widget.Toolbar
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
import butterknife.bindView
|
import butterknife.bindView
|
||||||
|
|
||||||
public class MainActivity : AppCompatActivity() {
|
public class MainActivity : AppCompatActivity() {
|
||||||
|
@ -20,7 +22,9 @@ public class MainActivity : AppCompatActivity() {
|
||||||
val txtSP: TextView by bindView(R.id.SP)
|
val txtSP: TextView by bindView(R.id.SP)
|
||||||
val txtPC: TextView by bindView(R.id.PC)
|
val txtPC: TextView by bindView(R.id.PC)
|
||||||
val txtFlags: TextView by bindView(R.id.PC)
|
val txtFlags: TextView by bindView(R.id.PC)
|
||||||
val fab: FloatingActionButton by bindView(R.id.fab)
|
val txtInstructions: TextView by bindView(R.id.txtInstructions)
|
||||||
|
val fabRun: FloatingActionButton by bindView(R.id.fabRun)
|
||||||
|
val emulator = Emulator()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -30,6 +34,11 @@ public class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
var ab: ActionBar = getSupportActionBar()
|
var ab: ActionBar = getSupportActionBar()
|
||||||
ab.setDisplayHomeAsUpEnabled(true)
|
ab.setDisplayHomeAsUpEnabled(true)
|
||||||
|
|
||||||
|
fabRun.setOnClickListener {
|
||||||
|
emulator.assembler.assembleCode(txtInstructions.getText().toString().splitBy("\n"))
|
||||||
|
Toast.makeText(fabRun.getContext(), "Code assembled", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
package android.emu6502.instructions
|
|
||||||
|
|
||||||
import java.util.*
|
|
||||||
import kotlin.reflect.KMemberFunction0
|
|
||||||
|
|
||||||
/** ADd with Carry */
|
|
||||||
class ADC(instructionList: HashMap<Int, KMemberFunction0<BaseInstruction, Unit>>)
|
|
||||||
: BaseInstruction(Instruction.ADC, instructionList) {
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package android.emu6502.instructions
|
|
||||||
|
|
||||||
import java.util.*
|
|
||||||
import kotlin.reflect.KMemberFunction0
|
|
||||||
|
|
||||||
/** bitwise AND with accumulator */
|
|
||||||
class AND(instructionList: HashMap<Int, KMemberFunction0<BaseInstruction, Unit>>)
|
|
||||||
: BaseInstruction(Instruction.AND, instructionList) {
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package android.emu6502.instructions
|
|
||||||
|
|
||||||
import java.util.*
|
|
||||||
import kotlin.reflect.KMemberFunction0
|
|
||||||
|
|
||||||
/** Arithmetic Shift Left */
|
|
||||||
class ASL(instructionList: HashMap<Int, KMemberFunction0<BaseInstruction, Unit>>)
|
|
||||||
: BaseInstruction(Instruction.ASL, instructionList) {
|
|
||||||
}
|
|
|
@ -3,7 +3,7 @@ package android.emu6502.instructions
|
||||||
import java.util.HashMap
|
import java.util.HashMap
|
||||||
|
|
||||||
open class BaseInstruction(private val instruction: Instruction,
|
open class BaseInstruction(private val instruction: Instruction,
|
||||||
private val instructionList: HashMap<Int, kotlin.reflect.KMemberFunction0<BaseInstruction, Unit>>) {
|
private val instructionList: HashMap<Int, InstructionTarget>) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val opcodes: IntArray = Opcodes.MAP[instruction] as IntArray
|
val opcodes: IntArray = Opcodes.MAP[instruction] as IntArray
|
||||||
|
@ -12,44 +12,44 @@ open class BaseInstruction(private val instruction: Instruction,
|
||||||
|
|
||||||
opcodes.forEachIndexed { i, opcode ->
|
opcodes.forEachIndexed { i, opcode ->
|
||||||
if (opcode != 0xff) {
|
if (opcode != 0xff) {
|
||||||
instructionList.put(opcodes[i], methods[i])
|
instructionList.put(opcodes[i], InstructionTarget(this, methods[i]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun immediate() {
|
open fun immediate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun zeroPage() {
|
open fun zeroPage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun zeroPageX() {
|
open fun zeroPageX() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun zeroPageY() {
|
open fun zeroPageY() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun absolute() {
|
open fun absolute() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun absoluteX() {
|
open fun absoluteX() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun absoluteY() {
|
open fun absoluteY() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun indirect() {
|
open fun indirect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun indirectX() {
|
open fun indirectX() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun indirectY() {
|
open fun indirectY() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun single() {
|
open fun single() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun branch() {
|
open fun branch() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package android.emu6502.instructions
|
||||||
|
|
||||||
|
import kotlin.reflect.KMemberFunction0
|
||||||
|
|
||||||
|
class InstructionTarget(val operation: BaseInstruction,
|
||||||
|
val method: KMemberFunction0<BaseInstruction, Unit>) {
|
||||||
|
}
|
|
@ -1,9 +0,0 @@
|
||||||
package android.emu6502.instructions
|
|
||||||
|
|
||||||
import java.util.*
|
|
||||||
import kotlin.reflect.KMemberFunction0
|
|
||||||
|
|
||||||
/** LoaD X register */
|
|
||||||
class LDX(instructionList: HashMap<Int, KMemberFunction0<BaseInstruction, Unit>>)
|
|
||||||
: BaseInstruction(Instruction.LDX, instructionList) {
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package android.emu6502.instructions
|
|
||||||
|
|
||||||
import java.util.HashMap
|
|
||||||
|
|
||||||
/** bitwise OR with Accumulator */
|
|
||||||
class ORA(instructionList: HashMap<Int, kotlin.reflect.KMemberFunction0<BaseInstruction, Unit>>)
|
|
||||||
: BaseInstruction(Instruction.ORA, instructionList) {
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
package android.emu6502.instructions
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.*
|
|
||||||
import kotlin.reflect.KMemberFunction0
|
|
||||||
|
|
||||||
/** STore X register */
|
|
||||||
class STX(instructionList: HashMap<Int, KMemberFunction0<BaseInstruction, Unit>>)
|
|
||||||
: BaseInstruction(Instruction.STX, instructionList) {
|
|
||||||
}
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package android.emu6502.instructions.impl
|
||||||
|
|
||||||
|
import android.emu6502.CPU
|
||||||
|
import android.emu6502.instructions.BaseInstruction
|
||||||
|
import android.emu6502.instructions.Instruction
|
||||||
|
|
||||||
|
/** ADd with Carry */
|
||||||
|
class ADC(cpu: CPU)
|
||||||
|
: BaseInstruction(Instruction.ADC, cpu.instructionList) {
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package android.emu6502.instructions.impl
|
||||||
|
|
||||||
|
import android.emu6502.CPU
|
||||||
|
import android.emu6502.instructions.BaseInstruction
|
||||||
|
import android.emu6502.instructions.Instruction
|
||||||
|
|
||||||
|
/** bitwise AND with accumulator */
|
||||||
|
class AND(cpu: CPU)
|
||||||
|
: BaseInstruction(Instruction.AND, cpu.instructionList) {
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package android.emu6502.instructions.impl
|
||||||
|
|
||||||
|
import android.emu6502.CPU
|
||||||
|
import android.emu6502.instructions.BaseInstruction
|
||||||
|
import android.emu6502.instructions.Instruction
|
||||||
|
|
||||||
|
/** Arithmetic Shift Left */
|
||||||
|
class ASL(cpu: CPU)
|
||||||
|
: BaseInstruction(Instruction.ASL, cpu.instructionList) {
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package android.emu6502.instructions.impl
|
||||||
|
|
||||||
|
import android.emu6502.CPU
|
||||||
|
import android.emu6502.instructions.BaseInstruction
|
||||||
|
import android.emu6502.instructions.Instruction
|
||||||
|
|
||||||
|
/** test BITs */
|
||||||
|
class BIT(cpu: CPU)
|
||||||
|
: BaseInstruction(Instruction.BIT, cpu.instructionList) {
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package android.emu6502.instructions.impl
|
||||||
|
|
||||||
|
import android.emu6502.CPU
|
||||||
|
import android.emu6502.instructions.BaseInstruction
|
||||||
|
import android.emu6502.instructions.Instruction
|
||||||
|
|
||||||
|
/** LoaD Accumulator */
|
||||||
|
class LDA(private val cpu: CPU)
|
||||||
|
: BaseInstruction(Instruction.LDA, cpu.instructionList) {
|
||||||
|
|
||||||
|
override fun immediate() {
|
||||||
|
cpu.A = cpu.popByte()
|
||||||
|
cpu.setSZFlagsForRegA()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package android.emu6502.instructions.impl
|
||||||
|
|
||||||
|
import android.emu6502.CPU
|
||||||
|
import android.emu6502.instructions.BaseInstruction
|
||||||
|
import android.emu6502.instructions.Instruction
|
||||||
|
|
||||||
|
/** LoaD X register */
|
||||||
|
class LDX(cpu: CPU) : BaseInstruction(Instruction.LDX, cpu.instructionList) {
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package android.emu6502.instructions.impl
|
||||||
|
|
||||||
|
import android.emu6502.CPU
|
||||||
|
import android.emu6502.instructions.BaseInstruction
|
||||||
|
import android.emu6502.instructions.Instruction
|
||||||
|
|
||||||
|
/** LoaD Y register */
|
||||||
|
class LDY(cpu: CPU)
|
||||||
|
: BaseInstruction(Instruction.LDY, cpu.instructionList) {
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package android.emu6502.instructions.impl
|
||||||
|
|
||||||
|
import android.emu6502.CPU
|
||||||
|
import android.emu6502.instructions.BaseInstruction
|
||||||
|
import android.emu6502.instructions.Instruction
|
||||||
|
|
||||||
|
/** bitwise OR with Accumulator */
|
||||||
|
class ORA(cpu: CPU)
|
||||||
|
: BaseInstruction(Instruction.ORA, cpu.instructionList) {
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package android.emu6502.instructions.impl
|
||||||
|
|
||||||
|
import android.emu6502.CPU
|
||||||
|
import android.emu6502.Memory
|
||||||
|
import android.emu6502.instructions.BaseInstruction
|
||||||
|
import android.emu6502.instructions.Instruction
|
||||||
|
|
||||||
|
/** STore Accumulator */
|
||||||
|
class STA(private val memory: Memory, private val cpu: CPU)
|
||||||
|
: BaseInstruction(Instruction.STA, cpu.instructionList) {
|
||||||
|
|
||||||
|
override fun absolute() {
|
||||||
|
memory.storeByte(cpu.popWord(), cpu.A);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package android.emu6502.instructions.impl
|
||||||
|
|
||||||
|
import android.emu6502.CPU
|
||||||
|
import android.emu6502.instructions.BaseInstruction
|
||||||
|
import android.emu6502.instructions.Instruction
|
||||||
|
|
||||||
|
/** STore X register */
|
||||||
|
class STX(cpu: CPU)
|
||||||
|
: BaseInstruction(Instruction.STX, cpu.instructionList) {
|
||||||
|
}
|
|
@ -39,7 +39,7 @@
|
||||||
android:id="@+id/txtInstructions"
|
android:id="@+id/txtInstructions"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:text="LDA #$80\nSTA $01\nADC $01"
|
android:text="LDA #$01\nSTA $0200\nLDA #$05\nSTA $0201\nLDA #$08\nSTA $0202"
|
||||||
android:fontFamily="monospace"
|
android:fontFamily="monospace"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:gravity="top" />
|
android:gravity="top" />
|
||||||
|
@ -145,7 +145,7 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<android.support.design.widget.FloatingActionButton
|
<android.support.design.widget.FloatingActionButton
|
||||||
android:id="@+id/fab"
|
android:id="@+id/fabRun"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="end|bottom"
|
android:layout_gravity="end|bottom"
|
||||||
|
|
Loading…
Reference in New Issue