From 1678927978684167819ec4ac2c4f9182676863fb Mon Sep 17 00:00:00 2001 From: Felipe Lima Date: Tue, 9 Jun 2015 10:21:49 -0700 Subject: [PATCH] Initial commit --- .gitignore | 18 ++ app/.gitignore | 1 + app/build.gradle | 36 +++ app/proguard-rules.pro | 17 ++ .../com/emu6502/ApplicationTest.java | 14 + app/src/main/AndroidManifest.xml | 21 ++ .../android/emu6502/Emu6502Application.java | 16 ++ .../main/kotlin/android/emu6502/Assembler.kt | 259 ++++++++++++++++++ app/src/main/kotlin/android/emu6502/CPU.kt | 56 ++++ app/src/main/kotlin/android/emu6502/Labels.kt | 13 + app/src/main/kotlin/android/emu6502/Memory.kt | 13 + .../main/kotlin/android/emu6502/Symbols.kt | 13 + .../android/emu6502/app/MainActivity.kt | 54 ++++ .../emu6502/instructions/AddressingMode.kt | 5 + .../emu6502/instructions/BaseInstruction.kt | 55 ++++ .../emu6502/instructions/Instruction.kt | 7 + .../android/emu6502/instructions/ORA.kt | 8 + .../android/emu6502/instructions/Opcodes.kt | 66 +++++ .../ic_play_arrow_white_48dp.png | Bin 0 -> 605 bytes app/src/main/res/layout/activity_main.xml | 156 +++++++++++ app/src/main/res/layout/toolbar.xml | 8 + app/src/main/res/menu/menu_main.xml | 6 + app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3418 bytes .../mipmap-hdpi/ic_play_arrow_white_48dp.png | Bin 0 -> 283 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2206 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4842 bytes .../mipmap-xhdpi/ic_play_arrow_white_48dp.png | Bin 0 -> 343 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7718 bytes .../ic_play_arrow_white_48dp.png | Bin 0 -> 461 bytes app/src/main/res/values-w820dp/dimens.xml | 6 + app/src/main/res/values/colors.xml | 9 + app/src/main/res/values/dimens.xml | 7 + app/src/main/res/values/strings.xml | 4 + app/src/main/res/values/styles.xml | 11 + build.gradle | 21 ++ gradle.properties | 18 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 49896 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 164 +++++++++++ gradlew.bat | 90 ++++++ settings.gradle | 1 + 41 files changed, 1179 insertions(+) create mode 100644 .gitignore create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/felipecsl/com/emu6502/ApplicationTest.java create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/android/emu6502/Emu6502Application.java create mode 100644 app/src/main/kotlin/android/emu6502/Assembler.kt create mode 100644 app/src/main/kotlin/android/emu6502/CPU.kt create mode 100644 app/src/main/kotlin/android/emu6502/Labels.kt create mode 100644 app/src/main/kotlin/android/emu6502/Memory.kt create mode 100644 app/src/main/kotlin/android/emu6502/Symbols.kt create mode 100644 app/src/main/kotlin/android/emu6502/app/MainActivity.kt create mode 100644 app/src/main/kotlin/android/emu6502/instructions/AddressingMode.kt create mode 100644 app/src/main/kotlin/android/emu6502/instructions/BaseInstruction.kt create mode 100644 app/src/main/kotlin/android/emu6502/instructions/Instruction.kt create mode 100644 app/src/main/kotlin/android/emu6502/instructions/ORA.kt create mode 100644 app/src/main/kotlin/android/emu6502/instructions/Opcodes.kt create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_48dp.png create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/layout/toolbar.xml create mode 100644 app/src/main/res/menu/menu_main.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_play_arrow_white_48dp.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_play_arrow_white_48dp.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_play_arrow_white_48dp.png create mode 100644 app/src/main/res/values-w820dp/dimens.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/dimens.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..488ba1d --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# ant +bin +build +gen +out +lib + +# intellij +.idea +*.iml + +# eclipse +.classpath +.project +.settings +.DS_Store +local.properties +.gradle \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..a49ff61 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,36 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' + +android { + compileSdkVersion 22 + buildToolsVersion "21.1.2" + + defaultConfig { + applicationId "android.emu6502" + minSdkVersion 16 + targetSdkVersion 22 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.android.support:design:22.2.0' + compile 'com.android.support:appcompat-v7:22.2.0' + compile 'com.android.support:cardview-v7:22.2.0' + compile 'org.jetbrains.kotlin:kotlin-stdlib:0.12.213' + compile "org.jetbrains.kotlin:kotlin-android-sdk-annotations:0.12.213" + compile "org.jetbrains.kotlin:kotlin-reflect:0.12.213" + compile 'com.jakewharton:kotterknife:0.1.0-SNAPSHOT' + compile 'com.facebook.stetho:stetho:1.1.1' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..db2163b --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/felipe_lima/Library/Android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/src/androidTest/java/felipecsl/com/emu6502/ApplicationTest.java b/app/src/androidTest/java/felipecsl/com/emu6502/ApplicationTest.java new file mode 100644 index 0000000..336f7f7 --- /dev/null +++ b/app/src/androidTest/java/felipecsl/com/emu6502/ApplicationTest.java @@ -0,0 +1,14 @@ +package felipecsl.com.emu6502; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7e2c488 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + diff --git a/app/src/main/java/android/emu6502/Emu6502Application.java b/app/src/main/java/android/emu6502/Emu6502Application.java new file mode 100644 index 0000000..31d5dbb --- /dev/null +++ b/app/src/main/java/android/emu6502/Emu6502Application.java @@ -0,0 +1,16 @@ +package android.emu6502; + +import android.app.Application; + +import com.facebook.stetho.Stetho; + +public class Emu6502Application extends Application { + + @Override public void onCreate() { + super.onCreate(); + Stetho.initialize( + Stetho.newInitializerBuilder(this) + .enableWebKitInspector(Stetho.defaultInspectorModulesProvider(this)) + .build()); + } +} diff --git a/app/src/main/kotlin/android/emu6502/Assembler.kt b/app/src/main/kotlin/android/emu6502/Assembler.kt new file mode 100644 index 0000000..8fd573f --- /dev/null +++ b/app/src/main/kotlin/android/emu6502/Assembler.kt @@ -0,0 +1,259 @@ +package android.emu6502 + +import android.emu6502.instructions.Instruction +import android.emu6502.instructions.Opcodes +import java.util.regex.Pattern + +class Assembler(private var labels: Labels, + private var memory: Memory, + private var symbols: Symbols) { + + private var defaultCodePC = 0 + private var codeLen = 0 + private var codeAssembledOK = false + private var BOOTSTRAP_ADDRESS = 0x600 + + fun assembleCode(lines: Array): Boolean { + lines.forEach { line -> + if (!assembleLine(line)) { + return false + } + } + return true + } + + private fun assembleLine(line: String): Boolean { + var input = line + var command: String + var param: String + var addr: Int + + // Find command or label + if (input.matches("^\\w+:".toRegex())) { + if (line.matches("^\\w+:[\\s]*\\w+.*$".toRegex())) { + input = input.replace("^\\w+:[\\s]*(.*)$".toRegex(), "$1") + command = input.replace("^(\\w+).*$".toRegex(), "$1") + } else { + command = "" + } + } else { + command = input.replace("^(\\w+).*$".toRegex(), "$1") + } + + // Nothing to do for blank lines + if (command.equals("")) { + return true + } + + command = command.toUpperCase() + + if (input.matches("^\\*\\s*=\\s*\$?[0-9a-f]*$".toRegex())) { + // equ spotted + param = input.replace("^\\s*\\*\\s*=\\s*".toRegex(), "") + if (param[0].equals("$")) { + param = param.replace("^\$".toRegex(), "") + addr = Integer.parseInt(param, 16) + } else { + addr = Integer.parseInt(param, 10) + } + if ((addr < 0) || (addr > 0xffff)) { + throw IllegalStateException("Unable to relocate code outside 64k memory") + } + defaultCodePC = addr + return true + } + + if (input.matches("^\\w+\\s+.*?$".toRegex())) { + param = input.replace("^\\w+\\s+(.*?)".toRegex(), "$1") + } else if (input.matches("^\\w+$".toRegex())) { + param = "" + } else { + return false + } + + param = param.replace("[ ]".toRegex(), "") + + if (command === "DCB") { + return DCB(param) + } + + val opcode = Opcodes.MAP.get(Instruction.valueOf(command)) + + if (opcode != null) { + if (checkImmediate(param, opcode[0])) { + return true + } + if (checkZeroPage(param, opcode[1])) { + return true + } + if (checkZeroPageX(param, opcode[2])) { + return true + } + if (checkZeroPageY(param, opcode[3])) { + return true + } + if (checkAbsolute(param, opcode[4])) { + return true + } + if (checkAbsoluteX(param, opcode[5])) { + return true + } + if (checkAbsoluteY(param, opcode[6])) { + return true + } + if (checkIndirect(param, opcode[7])) { + return true + } + if (checkIndirectX(param, opcode[8])) { + return true + } + if (checkIndirectY(param, opcode[9])) { + return true + } + if (checkSingle(param, opcode[10])) { + return true + } + if (checkBranch(param, opcode[11])) { + return true + } + } + return false + } + + private fun DCB(param: String): Boolean { + throw UnsupportedOperationException( + "not implemented") //To change body of created functions use File | Settings | File Templates. + } + + private fun checkBranch(param: String, opcode: Int): Boolean { + throw UnsupportedOperationException( + "not implemented") //To change body of created functions use File | Settings | File Templates. + } + + private fun checkAbsolute(param: String, opcode: Int): Boolean { + throw UnsupportedOperationException( + "not implemented") //To change body of created functions use File | Settings | File Templates. + } + + private fun checkIndirectY(param: String, opcode: Int): Boolean { + throw UnsupportedOperationException( + "not implemented") //To change body of created functions use File | Settings | File Templates. + } + + private fun checkIndirectX(param: String, opcode: Int): Boolean { + throw UnsupportedOperationException( + "not implemented") //To change body of created functions use File | Settings | File Templates. + } + + private fun checkIndirect(param: String, opcode: Int): Boolean { + throw UnsupportedOperationException( + "not implemented") //To change body of created functions use File | Settings | File Templates. + } + + private fun checkAbsoluteY(param: String, opcode: Int): Boolean { + throw UnsupportedOperationException( + "not implemented") //To change body of created functions use File | Settings | File Templates. + } + + private fun checkAbsoluteX(param: String, opcode: Int): Boolean { + throw UnsupportedOperationException( + "not implemented") //To change body of created functions use File | Settings | File Templates. + } + + private fun checkZeroPageY(param: String, opcode: Int): Boolean { + throw UnsupportedOperationException( + "not implemented") //To change body of created functions use File | Settings | File Templates. + } + + private fun checkZeroPageX(param: String, opcode: Int): Boolean { + throw UnsupportedOperationException( + "not implemented") //To change body of created functions use File | Settings | File Templates. + } + + private fun checkZeroPage(param: String, opcode: Int): Boolean { + throw UnsupportedOperationException( + "not implemented") //To change body of created functions use File | Settings | File Templates. + } + + private fun checkImmediate(param: String, opcode: Int): Boolean { + val pattern = Pattern.compile("^#([\\w\$]+)$") + val matcher = pattern.matcher(param) + if (matcher.find()) { + var operand = tryParseByteOperand(matcher.group(1)) + if (operand >= 0) { + pushByte(opcode) + pushByte(operand) + return true + } + } + + // Label lo/hi + if (param.matches("^#[<>]\\w+$".toRegex())) { + var label = param.replace("^#[<>](\\w+)$".toRegex(), "$1") + var hilo = param.replace("^#([<>]).*$".toRegex(), "$1") + pushByte(opcode) + if (labels.find(label)) { + var addr = labels.getPC(label) + when (hilo) { + ">" -> { + pushByte(addr.shr(8).and(0xFF)) + } + "<" -> { + pushByte(addr.and(0xFF)) + } + else -> return false + } + } else { + pushByte(0x00) + return true + } + } + + return false + } + + // Try to parse the given parameter as a byte operand. + // Returns the (positive) value if successful, otherwise -1 + private fun tryParseByteOperand(param: String): Int { + var value: Int = 0 + var parameter = param; + + if (parameter.matches("^\\w+$".toRegex())) { + var lookupVal = symbols.lookup(parameter) // Substitute symbol by actual value, then proceed + if (lookupVal != null) { + parameter = lookupVal + } + } + + // Is it a hexadecimal operand? + var pattern = Pattern.compile("^\$([0-9a-f]{1,2})$") + var matcher = pattern.matcher(parameter) + if (matcher.find()) { + value = Integer.parseInt(matcher.group(1), 16) + } else { + // Is it a decimal operand? + pattern = Pattern.compile("^([0-9]{1,3})$") + matcher = pattern.matcher(parameter) + if (matcher.find()) { + value = Integer.parseInt(matcher.group(1), 10) + } + } + + // Validate range + if (value >= 0 && value <= 0xff) { + return value + } + return -1 + } + + private fun pushByte(value: Int) { + memory.set(defaultCodePC, value.and(0xFF)) + defaultCodePC++ + codeLen++ + } + + private fun checkSingle(param: String, opcode: Int): Boolean { + throw UnsupportedOperationException( + "not implemented") //To change body of created functions use File | Settings | File Templates. + } +} diff --git a/app/src/main/kotlin/android/emu6502/CPU.kt b/app/src/main/kotlin/android/emu6502/CPU.kt new file mode 100644 index 0000000..8654597 --- /dev/null +++ b/app/src/main/kotlin/android/emu6502/CPU.kt @@ -0,0 +1,56 @@ +package android.emu6502 + +import android.emu6502.instructions.BaseInstruction +import android.emu6502.instructions.ORA +import java.util.HashMap +import kotlin.reflect.KMemberFunction0 + +class CPU(private val memory: Memory) { + // Accumulator + private var A: Byte = 0 + // Registers + private var X: Byte = 0 + private var Y: Byte = 0 + // Program counter + private var PC = 0x600 + // Stack pointer + private var SP = 0xFF + private var flags: Byte = 0 + private var isRunning = false + private var debug = false + private var monitoring = false + + private val instructionList: HashMap> = HashMap() + + fun execute() { + setRandomByte() + executeNextInstruction() + + if (PC == 0 || !isRunning) { + stop() +// message("Program end at PC=$" + addr2hex(regPC - 1)) +// ui.stop() + } + } + + private fun stop() { + isRunning = false + } + + private fun executeNextInstruction() { + val instruction = Integer.valueOf(popByte().toInt().toString(), 16) + val function = instructionList.get(instruction) + ORA(instructionList).function() +// else { +// instructions.ierr() +// } + } + + private fun popByte(): Byte { + return memory.get((PC++).and(0xff)); + } + + private fun setRandomByte() { + memory.set(0xfe, Math.floor(Math.random() * 256).toInt()) + } +} diff --git a/app/src/main/kotlin/android/emu6502/Labels.kt b/app/src/main/kotlin/android/emu6502/Labels.kt new file mode 100644 index 0000000..ecfe75b --- /dev/null +++ b/app/src/main/kotlin/android/emu6502/Labels.kt @@ -0,0 +1,13 @@ +package android.emu6502 + +class Labels { + fun getPC(label: String): Int { + throw UnsupportedOperationException( + "not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun find(label: String): Boolean { + throw UnsupportedOperationException( + "not implemented") //To change body of created functions use File | Settings | File Templates. + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/android/emu6502/Memory.kt b/app/src/main/kotlin/android/emu6502/Memory.kt new file mode 100644 index 0000000..f9030c6 --- /dev/null +++ b/app/src/main/kotlin/android/emu6502/Memory.kt @@ -0,0 +1,13 @@ +package android.emu6502 + +class Memory { + private val mem = ByteArray(65536) + + public fun get(addr: Int): Byte { + return mem[addr] + } + + public fun set(addr: Int, value: Int) { + mem[addr] = value.toByte() + } +} diff --git a/app/src/main/kotlin/android/emu6502/Symbols.kt b/app/src/main/kotlin/android/emu6502/Symbols.kt new file mode 100644 index 0000000..bc84ce1 --- /dev/null +++ b/app/src/main/kotlin/android/emu6502/Symbols.kt @@ -0,0 +1,13 @@ +package android.emu6502 + +class Symbols { + private val table: Map = emptyMap() + + fun lookup(key: String): String? { + return null + } + + fun add(key: String, value: String) { + + } +} diff --git a/app/src/main/kotlin/android/emu6502/app/MainActivity.kt b/app/src/main/kotlin/android/emu6502/app/MainActivity.kt new file mode 100644 index 0000000..714cbe1 --- /dev/null +++ b/app/src/main/kotlin/android/emu6502/app/MainActivity.kt @@ -0,0 +1,54 @@ +package android.emu6502.app + +import android.emu6502.R +import android.os.Bundle +import android.support.design.widget.FloatingActionButton +import android.support.v7.app.ActionBar +import android.support.v7.app.AppCompatActivity +import android.support.v7.widget.Toolbar +import android.view.Menu +import android.view.MenuItem +import android.widget.TextView +import butterknife.bindView + +public class MainActivity : AppCompatActivity() { + + val toolbar: Toolbar by bindView(R.id.toolbar) + val txtA: TextView by bindView(R.id.A) + val txtX: TextView by bindView(R.id.X) + val txtY: TextView by bindView(R.id.Y) + val txtSP: TextView by bindView(R.id.SP) + val txtPC: TextView by bindView(R.id.PC) + val txtFlags: TextView by bindView(R.id.PC) + val fab: FloatingActionButton by bindView(R.id.fab) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + setSupportActionBar(toolbar) + + var ab: ActionBar = getSupportActionBar() + ab.setDisplayHomeAsUpEnabled(true) + } + + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_main, menu) + return true + } + + override fun onOptionsItemSelected(item: MenuItem?): Boolean { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + val id = item!!.getItemId() + + //noinspection SimplifiableIfStatement + if (id == R.id.action_settings) { + return true + } + + return super.onOptionsItemSelected(item) + } +} diff --git a/app/src/main/kotlin/android/emu6502/instructions/AddressingMode.kt b/app/src/main/kotlin/android/emu6502/instructions/AddressingMode.kt new file mode 100644 index 0000000..7a75dbd --- /dev/null +++ b/app/src/main/kotlin/android/emu6502/instructions/AddressingMode.kt @@ -0,0 +1,5 @@ +package android.emu6502.instructions + +enum class AddressingMode { + IMMEDIATE, ZERO_PAGE, ZERO_PAGE_X, ABSOLUTE, ABSOLUTE_X, ABSOLUTE_Y, INDIRECT_X, INDIRECT_Y +} diff --git a/app/src/main/kotlin/android/emu6502/instructions/BaseInstruction.kt b/app/src/main/kotlin/android/emu6502/instructions/BaseInstruction.kt new file mode 100644 index 0000000..0f21610 --- /dev/null +++ b/app/src/main/kotlin/android/emu6502/instructions/BaseInstruction.kt @@ -0,0 +1,55 @@ +package android.emu6502.instructions + +import java.util.HashMap + +open class BaseInstruction(private val instruction: Instruction, + private val instructionList: HashMap>) { + + init { + val opcodes: IntArray = Opcodes.MAP[instruction] as IntArray + val methods = arrayOf(::immediate, ::zeroPage, ::zeroPageX, ::zeroPageY, ::absolute, + ::absoluteX, ::absoluteY, ::indirect, ::indirectX, ::indirectY, ::single, ::branch) + + opcodes.forEachIndexed { i, opcode -> + if (opcode != 0xff) { + instructionList.put(opcodes[i], methods[i]) + } + } + } + + fun immediate() { + } + + fun zeroPage() { + } + + fun zeroPageX() { + } + + fun zeroPageY() { + } + + fun absolute() { + } + + fun absoluteX() { + } + + fun absoluteY() { + } + + fun indirect() { + } + + fun indirectX() { + } + + fun indirectY() { + } + + fun single() { + } + + fun branch() { + } +} diff --git a/app/src/main/kotlin/android/emu6502/instructions/Instruction.kt b/app/src/main/kotlin/android/emu6502/instructions/Instruction.kt new file mode 100644 index 0000000..d867a99 --- /dev/null +++ b/app/src/main/kotlin/android/emu6502/instructions/Instruction.kt @@ -0,0 +1,7 @@ +package android.emu6502.instructions + +enum class Instruction { + ADC, AND, ASL, BIT, BPL, BMI, BVC, BVS, BCC, BCS, BNE, BEQ, BRK, CMP, CPX, CPY, DEC, EOR, CLC, + SEC, CLI, SEI, CLV, CLD, SED, INC, JMP, JSR, LDA, LDX, LDY, LSR, NOP, ORA, TAX, TXA, DEX, INX, + TAY, TYA, DEY, INY, ROR, ROL, RTI, RTS, SBC, STA, TXS, TSX, PHA, PLA, PHP, PLP, STX, STY, XXX +} diff --git a/app/src/main/kotlin/android/emu6502/instructions/ORA.kt b/app/src/main/kotlin/android/emu6502/instructions/ORA.kt new file mode 100644 index 0000000..9971058 --- /dev/null +++ b/app/src/main/kotlin/android/emu6502/instructions/ORA.kt @@ -0,0 +1,8 @@ +package android.emu6502.instructions + +import java.util.HashMap + +/** bitwise OR with Accumulator */ +class ORA(instructionList: HashMap>) + : BaseInstruction(Instruction.ORA, instructionList) { +} diff --git a/app/src/main/kotlin/android/emu6502/instructions/Opcodes.kt b/app/src/main/kotlin/android/emu6502/instructions/Opcodes.kt new file mode 100644 index 0000000..89721d5 --- /dev/null +++ b/app/src/main/kotlin/android/emu6502/instructions/Opcodes.kt @@ -0,0 +1,66 @@ +package android.emu6502.instructions + +final class Opcodes { + companion object { + public val MAP: Map = hashMapOf( + /* Name, Imm, ZP, ZPX, ZPY, ABS, ABSX, ABSY, IND, INDX, INDY, SNGL, BRA */ + Pair(Instruction.ADC, intArrayOf(0x69, 0x65, 0x75, 0xff, 0x6d, 0x7d, 0x79, 0xff, 0x61, 0x71, 0xff, 0xff)), + Pair(Instruction.AND, intArrayOf(0x29, 0x25, 0x35, 0xff, 0x2d, 0x3d, 0x39, 0xff, 0x21, 0x31, 0xff, 0xff)), + Pair(Instruction.ASL, intArrayOf(0xff, 0x06, 0x16, 0xff, 0x0e, 0x1e, 0xff, 0xff, 0xff, 0xff, 0x0a, 0xff)), + Pair(Instruction.BIT, intArrayOf(0xff, 0x24, 0xff, 0xff, 0x2c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)), + Pair(Instruction.BPL, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x10)), + Pair(Instruction.BMI, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30)), + Pair(Instruction.BVC, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x50)), + Pair(Instruction.BVS, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70)), + Pair(Instruction.BCC, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90)), + Pair(Instruction.BCS, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0)), + Pair(Instruction.BNE, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0)), + Pair(Instruction.BEQ, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0)), + Pair(Instruction.BRK, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff)), + Pair(Instruction.CMP, intArrayOf(0xc9, 0xc5, 0xd5, 0xff, 0xcd, 0xdd, 0xd9, 0xff, 0xc1, 0xd1, 0xff, 0xff)), + Pair(Instruction.CPX, intArrayOf(0xe0, 0xe4, 0xff, 0xff, 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)), + Pair(Instruction.CPY, intArrayOf(0xc0, 0xc4, 0xff, 0xff, 0xcc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)), + Pair(Instruction.DEC, intArrayOf(0xff, 0xc6, 0xd6, 0xff, 0xce, 0xde, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)), + Pair(Instruction.EOR, intArrayOf(0x49, 0x45, 0x55, 0xff, 0x4d, 0x5d, 0x59, 0xff, 0x41, 0x51, 0xff, 0xff)), + Pair(Instruction.CLC, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x18, 0xff)), + Pair(Instruction.SEC, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x38, 0xff)), + Pair(Instruction.CLI, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x58, 0xff)), + Pair(Instruction.SEI, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0xff)), + Pair(Instruction.CLV, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb8, 0xff)), + Pair(Instruction.CLD, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0xff)), + Pair(Instruction.SED, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff)), + Pair(Instruction.INC, intArrayOf(0xff, 0xe6, 0xf6, 0xff, 0xee, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)), + Pair(Instruction.JMP, intArrayOf(0xff, 0xff, 0xff, 0xff, 0x4c, 0xff, 0xff, 0x6c, 0xff, 0xff, 0xff, 0xff)), + Pair(Instruction.JSR, intArrayOf(0xff, 0xff, 0xff, 0xff, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)), + Pair(Instruction.LDA, intArrayOf(0xa9, 0xa5, 0xb5, 0xff, 0xad, 0xbd, 0xb9, 0xff, 0xa1, 0xb1, 0xff, 0xff)), + Pair(Instruction.LDX, intArrayOf(0xa2, 0xa6, 0xff, 0xb6, 0xae, 0xff, 0xbe, 0xff, 0xff, 0xff, 0xff, 0xff)), + Pair(Instruction.LDY, intArrayOf(0xa0, 0xa4, 0xb4, 0xff, 0xac, 0xbc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)), + Pair(Instruction.LSR, intArrayOf(0xff, 0x46, 0x56, 0xff, 0x4e, 0x5e, 0xff, 0xff, 0xff, 0xff, 0x4a, 0xff)), + Pair(Instruction.NOP, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xea, 0xff)), + Pair(Instruction.ORA, intArrayOf(0x09, 0x05, 0x15, 0xff, 0x0d, 0x1d, 0x19, 0xff, 0x01, 0x11, 0xff, 0xff)), + Pair(Instruction.TAX, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xff)), + Pair(Instruction.TXA, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8a, 0xff)), + Pair(Instruction.DEX, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xca, 0xff)), + Pair(Instruction.INX, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe8, 0xff)), + Pair(Instruction.TAY, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa8, 0xff)), + Pair(Instruction.TYA, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x98, 0xff)), + Pair(Instruction.DEY, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x88, 0xff)), + Pair(Instruction.INY, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc8, 0xff)), + Pair(Instruction.ROR, intArrayOf(0xff, 0x66, 0x76, 0xff, 0x6e, 0x7e, 0xff, 0xff, 0xff, 0xff, 0x6a, 0xff)), + Pair(Instruction.ROL, intArrayOf(0xff, 0x26, 0x36, 0xff, 0x2e, 0x3e, 0xff, 0xff, 0xff, 0xff, 0x2a, 0xff)), + Pair(Instruction.RTI, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0xff)), + Pair(Instruction.RTS, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0xff)), + Pair(Instruction.SBC, intArrayOf(0xe9, 0xe5, 0xf5, 0xff, 0xed, 0xfd, 0xf9, 0xff, 0xe1, 0xf1, 0xff, 0xff)), + Pair(Instruction.STA, intArrayOf(0xff, 0x85, 0x95, 0xff, 0x8d, 0x9d, 0x99, 0xff, 0x81, 0x91, 0xff, 0xff)), + Pair(Instruction.TXS, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9a, 0xff)), + Pair(Instruction.TSX, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xba, 0xff)), + Pair(Instruction.PHA, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x48, 0xff)), + Pair(Instruction.PLA, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x68, 0xff)), + Pair(Instruction.PHP, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0xff)), + Pair(Instruction.PLP, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x28, 0xff)), + Pair(Instruction.STX, intArrayOf(0xff, 0x86, 0xff, 0x96, 0x8e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)), + Pair(Instruction.STY, intArrayOf(0xff, 0x84, 0x94, 0xff, 0x8c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)), + Pair(Instruction.XXX, intArrayOf(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff)) + ); + } +} diff --git a/app/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_48dp.png b/app/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_48dp.png new file mode 100644 index 0000000000000000000000000000000000000000..8dbc4ea7c14058ce91746c5bc1767f49389f769e GIT binary patch literal 605 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE1xWt5x}=AJfl0;F#WAFU@y$U)Mg|5B<^@kT z{Lei)^PoHjPze$^5Wf9#jCFYqPauO^;0%`)d|3glS}&TkG%~6$G}Z*4jB7NM?mjo; z@4x6n=7&E%tDL@j_0`*b)%Q#rvh2%m*fyl?|GxG5T?P$?bKf_zGpHUYyY)MdQH0_7 z?>ov3EDvf5=PxJW*4R(HvUkbSv^anH4(o|{!&@Kx<#v_GX3Vp#0 zKxcFSoguTF;gJQa0E$%Z943Yj@$a^n+c)WbnZALicH+XjvSrWtH@@nt{-kl}utoo3 zMwNq{3cP*{i3Lm^&B6{6a~Sr_dhs-d!Lfje1IU-0!|>< + + + + + + + + + + + + + + + + + + + + + +