Update code to work with Kotlin 1.1
This commit is contained in:
parent
56135cbd14
commit
e1e26aebae
|
@ -2,45 +2,37 @@ apply plugin: 'com.android.application'
|
|||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
compileSdkVersion 22
|
||||
buildToolsVersion "21.1.2"
|
||||
compileSdkVersion 25
|
||||
buildToolsVersion "25.0.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'
|
||||
}
|
||||
testOptions {
|
||||
unitTests.returnDefaultValues = true
|
||||
}
|
||||
defaultConfig {
|
||||
applicationId "android.emu6502"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 25
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
}
|
||||
testOptions {
|
||||
unitTests.returnDefaultValues = true
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile 'com.android.support:design:22.2.1'
|
||||
compile 'com.android.support:appcompat-v7:22.2.1'
|
||||
compile 'com.android.support:cardview-v7:22.2.1'
|
||||
compile 'org.jetbrains.kotlin:kotlin-stdlib:0.12.1218'
|
||||
compile "org.jetbrains.kotlin:kotlin-android-sdk-annotations:0.12.1218"
|
||||
compile "org.jetbrains.kotlin:kotlin-reflect:0.12.1218"
|
||||
compile 'com.jakewharton:kotterknife:0.1.0-SNAPSHOT'
|
||||
compile 'com.facebook.stetho:stetho:1.1.1'
|
||||
compile 'com.google.guava:guava:18.0'
|
||||
compile 'com.android.support:design:25.2.0'
|
||||
compile 'com.android.support:appcompat-v7:25.2.0'
|
||||
compile 'com.android.support:cardview-v7:25.2.0'
|
||||
compile 'org.jetbrains.kotlin:kotlin-stdlib:1.1.0'
|
||||
compile "org.jetbrains.kotlin:kotlin-reflect:1.1.0"
|
||||
compile 'com.jakewharton:kotterknife:0.1.0-SNAPSHOT'
|
||||
compile 'com.facebook.stetho:stetho:1.3.1'
|
||||
compile 'com.google.guava:guava:20.0'
|
||||
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'org.mockito:mockito-core:1.10.19'
|
||||
testCompile 'org.hamcrest:hamcrest-integration:1.3'
|
||||
testCompile 'org.hamcrest:hamcrest-core:1.3'
|
||||
testCompile 'org.hamcrest:hamcrest-library:1.3'
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'org.mockito:mockito-core:1.10.19'
|
||||
testCompile 'org.hamcrest:hamcrest-integration:1.3'
|
||||
testCompile 'org.hamcrest:hamcrest-core:1.3'
|
||||
testCompile 'org.hamcrest:hamcrest-library:1.3'
|
||||
}
|
||||
|
|
|
@ -3,12 +3,9 @@ package android.emu6502
|
|||
import android.emu6502.instructions.Instruction
|
||||
import android.emu6502.instructions.Opcodes
|
||||
import android.emu6502.instructions.Symbols
|
||||
import java.util.HashMap
|
||||
import java.util.regex.Pattern
|
||||
import kotlin.text.Regex
|
||||
|
||||
class Assembler(private var memory: Memory, private val symbols: Symbols) {
|
||||
|
||||
var codeLen = 0
|
||||
val BOOTSTRAP_ADDRESS = 0x600
|
||||
var defaultCodePC = BOOTSTRAP_ADDRESS
|
||||
|
@ -35,7 +32,7 @@ class Assembler(private var memory: Memory, private val symbols: Symbols) {
|
|||
private fun preprocess(lines: List<String>): List<String> {
|
||||
val pattern = Pattern.compile("^define\\s+(\\w+)\\s+(\\S+)", Pattern.CASE_INSENSITIVE)
|
||||
|
||||
var sanitizedLines = lines.map { sanitize(it) }
|
||||
val sanitizedLines = lines.map { sanitize(it) }
|
||||
|
||||
sanitizedLines
|
||||
.map { pattern.matcher(it) }
|
||||
|
@ -53,7 +50,7 @@ class Assembler(private var memory: Memory, private val symbols: Symbols) {
|
|||
var input = line
|
||||
var command: String
|
||||
var param: String
|
||||
var addr: Int
|
||||
val addr: Int
|
||||
|
||||
// Find command or label
|
||||
if (input.matches("^\\w+:".toRegex())) {
|
||||
|
@ -68,7 +65,7 @@ class Assembler(private var memory: Memory, private val symbols: Symbols) {
|
|||
}
|
||||
|
||||
// Nothing to do for blank lines
|
||||
if (command.equals("")) {
|
||||
if (command == "") {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -77,7 +74,7 @@ class Assembler(private var memory: Memory, private val symbols: Symbols) {
|
|||
if (input.matches("^\\*\\s*=\\s*\\$?[0-9a-f]*$".toRegex())) {
|
||||
// equ spotted
|
||||
param = input.replace("^\\s*\\*\\s*=\\s*".toRegex(), "")
|
||||
if (param[0].equals("$")) {
|
||||
if (param[0] == '$') {
|
||||
param = param.replace("^\\$".toRegex(), "")
|
||||
addr = Integer.parseInt(param, 16)
|
||||
} else {
|
||||
|
@ -202,7 +199,7 @@ class Assembler(private var memory: Memory, private val symbols: Symbols) {
|
|||
}
|
||||
|
||||
private fun innerCheckWordOperand(param: String, opcode: Int): Boolean {
|
||||
var operand = tryParseWordOperand(param)
|
||||
val operand = tryParseWordOperand(param)
|
||||
if (operand < 0) {
|
||||
return false
|
||||
}
|
||||
|
@ -220,7 +217,7 @@ class Assembler(private var memory: Memory, private val symbols: Symbols) {
|
|||
}
|
||||
|
||||
private fun innerCheckByteOperand(param: String, opcode: Int): Boolean {
|
||||
var operand = tryParseByteOperand(param)
|
||||
val operand = tryParseByteOperand(param)
|
||||
if (operand < 0) {
|
||||
return false
|
||||
}
|
||||
|
@ -233,7 +230,7 @@ class Assembler(private var memory: Memory, private val symbols: Symbols) {
|
|||
if (param.matches(regex)) {
|
||||
val finalParam = param.replace(",Y", "", true).replace(",X", "", true)
|
||||
pushByte(opcode)
|
||||
val addr = labels.get(finalParam)
|
||||
val addr = labels[finalParam]
|
||||
if (addr != -1) {
|
||||
if (addr < 0 || addr > 0xffff) {
|
||||
return false
|
||||
|
@ -316,8 +313,8 @@ class Assembler(private var memory: Memory, private val symbols: Symbols) {
|
|||
|
||||
// Label lo/hi
|
||||
if (param.matches("^#[<>]\\w+$".toRegex())) {
|
||||
var label = param.replace("^#[<>](\\w+)$".toRegex(), "$1")
|
||||
var hilo = param.replace("^#([<>]).*$".toRegex(), "$1")
|
||||
val label = param.replace("^#[<>](\\w+)$".toRegex(), "$1")
|
||||
val hilo = param.replace("^#([<>]).*$".toRegex(), "$1")
|
||||
pushByte(opcode)
|
||||
val addr = labels.get(label)
|
||||
if (addr != -1) {
|
||||
|
@ -346,7 +343,7 @@ class Assembler(private var memory: Memory, private val symbols: Symbols) {
|
|||
var parameter = param
|
||||
|
||||
if (parameter.matches("^\\w+$".toRegex())) {
|
||||
var lookupVal = symbols.get(parameter) // Substitute symbol by actual value, then proceed
|
||||
val lookupVal = symbols[parameter] // Substitute symbol by actual value, then proceed
|
||||
if (lookupVal != null) {
|
||||
parameter = lookupVal
|
||||
}
|
||||
|
@ -367,7 +364,7 @@ class Assembler(private var memory: Memory, private val symbols: Symbols) {
|
|||
}
|
||||
|
||||
// Validate range
|
||||
if (value >= 0 && value <= 0xff) {
|
||||
if (value in 0..0xff) {
|
||||
return value
|
||||
}
|
||||
return -1
|
||||
|
@ -378,7 +375,7 @@ class Assembler(private var memory: Memory, private val symbols: Symbols) {
|
|||
var parameter = param
|
||||
|
||||
if (parameter.matches("^\\w+$".toRegex())) {
|
||||
var lookupVal = symbols.get(parameter) // Substitute symbol by actual value, then proceed
|
||||
val lookupVal = symbols.get(parameter) // Substitute symbol by actual value, then proceed
|
||||
if (lookupVal != null) {
|
||||
parameter = lookupVal
|
||||
}
|
||||
|
@ -399,7 +396,7 @@ class Assembler(private var memory: Memory, private val symbols: Symbols) {
|
|||
}
|
||||
|
||||
// Validate range
|
||||
if (value >= 0 && value <= 0xffff) {
|
||||
if (value in 0..0xffff) {
|
||||
return value
|
||||
}
|
||||
return -1
|
||||
|
@ -418,7 +415,7 @@ class Assembler(private var memory: Memory, private val symbols: Symbols) {
|
|||
|
||||
private fun checkSingle(param: String, opcode: Int): Boolean {
|
||||
// Accumulator instructions are counted as single-byte opcodes
|
||||
if (!param.equals("") && !param.equals("A")) {
|
||||
if (param != "" && param != "A") {
|
||||
return false
|
||||
}
|
||||
pushByte(opcode)
|
||||
|
|
|
@ -8,7 +8,7 @@ import android.emu6502.instructions.impl.*
|
|||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.util.Log
|
||||
import java.util.HashMap
|
||||
import java.util.*
|
||||
import java.util.concurrent.CountDownLatch
|
||||
|
||||
class CPU(val memory: Memory) : Display.Callbacks {
|
||||
|
@ -18,7 +18,7 @@ class CPU(val memory: Memory) : Display.Callbacks {
|
|||
|
||||
init {
|
||||
bgHandlerThread.start()
|
||||
bgHandler = Handler(bgHandlerThread.getLooper())
|
||||
bgHandler = Handler(bgHandlerThread.looper)
|
||||
}
|
||||
|
||||
var A: Int = 0 // Accumulator
|
||||
|
@ -105,17 +105,16 @@ class CPU(val memory: Memory) : Display.Callbacks {
|
|||
|
||||
private fun executeNextInstruction() {
|
||||
val instruction = popByte()
|
||||
val target = instructionList.get(instruction)
|
||||
val target = instructionList[instruction]
|
||||
if (target != null) {
|
||||
val function = target.method
|
||||
target.operation.function()
|
||||
target.method.invoke()
|
||||
} else {
|
||||
val candidate = Opcodes.MAP.entrySet()
|
||||
val candidate = Opcodes.MAP.entries
|
||||
.first { it.value.any { opcode -> opcode == instruction } }
|
||||
|
||||
throw Exception(
|
||||
"Address $${PC.toHexString()} - unknown opcode 0x${instruction.toHexString()} " +
|
||||
"(instruction ${candidate.getKey().name()})")
|
||||
"(instruction ${candidate.key.name})")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,7 +247,7 @@ class CPU(val memory: Memory) : Display.Callbacks {
|
|||
}
|
||||
|
||||
fun stackPop(): Int {
|
||||
SP++;
|
||||
SP++
|
||||
if (SP >= 0x100) {
|
||||
SP = SP.and(0xff)
|
||||
Log.i(TAG, "6502 Stack emptied! Wrapping...")
|
||||
|
|
|
@ -4,17 +4,12 @@ import android.content.Context
|
|||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Point
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import java.util
|
||||
import java.util.*
|
||||
|
||||
open class Display : View {
|
||||
open class Display(context: Context, attrs: AttributeSet) : View(context, attrs) {
|
||||
private val numX = 32
|
||||
private val numY = 32
|
||||
|
||||
private val matrix = Array(32, { IntArray(32) })
|
||||
|
||||
private val palette = arrayOf(
|
||||
|
@ -23,17 +18,10 @@ open class Display : View {
|
|||
"#dd8855", "#664400", "#ff7777", "#333333",
|
||||
"#777777", "#aaff66", "#0088ff", "#bbbbbb")
|
||||
|
||||
private val paint: Paint
|
||||
private val bgPaint: Paint
|
||||
private val TAG = "Display"
|
||||
private val paint: Paint = Paint()
|
||||
private val bgPaint: Paint = Paint()
|
||||
private var listener: Callbacks? = null
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
|
||||
paint = Paint()
|
||||
bgPaint = Paint()
|
||||
bgPaint.setColor(Color.BLACK);
|
||||
}
|
||||
|
||||
fun setOnDisplayCallback(callback: Callbacks) {
|
||||
listener = callback;
|
||||
}
|
||||
|
@ -58,7 +46,7 @@ open class Display : View {
|
|||
val right = (i * pixelSizeX).toFloat()
|
||||
val top = (j * pixelSizeY).toFloat()
|
||||
if (color != 0) {
|
||||
paint.setColor(color)
|
||||
paint.color = color
|
||||
canvas.drawRect(right, top, right + pixelSizeX, top + pixelSizeY, paint)
|
||||
} else {
|
||||
canvas.drawRect(right, top, right + pixelSizeX, top + pixelSizeY, bgPaint)
|
||||
|
@ -81,4 +69,8 @@ open class Display : View {
|
|||
}
|
||||
postInvalidate()
|
||||
}
|
||||
|
||||
init {
|
||||
bgPaint.color = Color.BLACK
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package android.emu6502
|
|||
import android.app.Application
|
||||
import com.facebook.stetho.Stetho
|
||||
|
||||
public class Emu6502Application : Application() {
|
||||
class Emu6502Application : Application() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
Stetho.initialize(Stetho.newInitializerBuilder(this)
|
||||
|
|
|
@ -2,7 +2,7 @@ package android.emu6502
|
|||
|
||||
import android.emu6502.instructions.Symbols
|
||||
|
||||
final class Emulator(val display: Display) {
|
||||
class Emulator(val display: Display) {
|
||||
val memory = Memory(display)
|
||||
val cpu = CPU(memory)
|
||||
val assembler = Assembler(memory, Symbols())
|
||||
|
|
|
@ -3,7 +3,8 @@ package android.emu6502
|
|||
import android.emu6502.instructions.Symbols
|
||||
import java.util.*
|
||||
|
||||
class Labels(private val assembler: Assembler, private val symbols: Symbols) : HashMap<String, Int>() {
|
||||
class Labels(private val assembler: Assembler,
|
||||
private val symbols: Symbols) : HashMap<String, Int>() {
|
||||
private val labelIndex: ArrayList<String> = ArrayList()
|
||||
|
||||
fun indexLines(lines: List<String>) {
|
||||
|
@ -12,7 +13,7 @@ class Labels(private val assembler: Assembler, private val symbols: Symbols) : H
|
|||
}
|
||||
}
|
||||
|
||||
fun get(label: String): Int {
|
||||
override fun get(label: String): Int {
|
||||
return super.get(label) ?: -1
|
||||
}
|
||||
|
||||
|
@ -20,20 +21,20 @@ class Labels(private val assembler: Assembler, private val symbols: Symbols) : H
|
|||
// Return false if label already exists.
|
||||
private fun indexLine(input: String) {
|
||||
// Figure out how many bytes this instruction takes
|
||||
val currentPC = assembler.defaultCodePC;
|
||||
val currentPC = assembler.defaultCodePC
|
||||
// TODO: find a better way for Labels to have access to assembler
|
||||
assembler.assembleLine(input);
|
||||
|
||||
// Find command or label
|
||||
if (input.matches("^\\w+:".toRegex())) {
|
||||
val label = input.replace("(^\\w+):.*$".toRegex(), "$1");
|
||||
val label = input.replace("(^\\w+):.*$".toRegex(), "$1")
|
||||
|
||||
if (symbols.get(label) != null) {
|
||||
throw RuntimeException(
|
||||
"**Label " + label + "is already used as a symbol; please rename one of them**");
|
||||
"**Label ${label}is already used as a symbol; please rename one of them**")
|
||||
}
|
||||
|
||||
put(label, currentPC);
|
||||
put(label, currentPC)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
package android.emu6502
|
||||
|
||||
import java.util.concurrent.CountDownLatch
|
||||
|
||||
class Memory(private val display: Display) {
|
||||
private val mem = IntArray(65536)
|
||||
|
||||
|
@ -19,7 +17,7 @@ class Memory(private val display: Display) {
|
|||
|
||||
fun storeByte(addr: Int, value: Int) {
|
||||
set(addr, value.and(0xff))
|
||||
if (addr >= 0x200 && addr <= 0x5ff) {
|
||||
if (addr in 0x200..0x5ff) {
|
||||
display.updatePixel(addr, mem[addr].and(0x0f))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
package android.emu6502
|
||||
|
||||
fun Int.toHexString(): String {
|
||||
return java.lang.String.format("%02X", this);
|
||||
return java.lang.String.format("%02X", this)
|
||||
}
|
|
@ -18,8 +18,7 @@ import android.widget.FrameLayout
|
|||
import android.widget.TextView
|
||||
import butterknife.bindView
|
||||
|
||||
public class MainActivity : AppCompatActivity() {
|
||||
|
||||
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)
|
||||
|
@ -43,17 +42,15 @@ public class MainActivity : AppCompatActivity() {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
setSupportActionBar(toolbar)
|
||||
|
||||
var ab: ActionBar = getSupportActionBar()
|
||||
val ab: ActionBar = supportActionBar!!
|
||||
ab.setDisplayHomeAsUpEnabled(true)
|
||||
|
||||
fabRun.setOnClickListener {
|
||||
displayWrapper.setVisibility(View.VISIBLE)
|
||||
displayWrapper.visibility = View.VISIBLE
|
||||
emulator = Emulator(display)
|
||||
val emu: Emulator = emulator as Emulator
|
||||
emu.assembler.assembleCode(txtInstructions.getText().toString().splitBy("\n"))
|
||||
emu.assembler.assembleCode(txtInstructions.text.toString().split("\n"))
|
||||
Snackbar.make(layoutContent,
|
||||
"Code assembled successfully, ${emu.assembler.codeLen} bytes.",
|
||||
Snackbar.LENGTH_SHORT).show()
|
||||
|
@ -79,7 +76,7 @@ public class MainActivity : AppCompatActivity() {
|
|||
|
||||
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)
|
||||
menuInflater.inflate(R.menu.menu_main, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -87,13 +84,11 @@ public class MainActivity : AppCompatActivity() {
|
|||
// 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
|
||||
val id = item!!.itemId
|
||||
if (id == R.id.action_settings) {
|
||||
return true
|
||||
} else {
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,21 @@ package android.emu6502.instructions
|
|||
import android.emu6502.CPU
|
||||
|
||||
open class BaseInstruction(val instruction: Instruction, private val cpu: CPU) {
|
||||
|
||||
init {
|
||||
val opcodes: IntArray = Opcodes.MAP[instruction] as IntArray
|
||||
val methods = arrayOf(::immediate, ::zeroPage, ::zeroPageX, ::zeroPageY, ::absolute,
|
||||
::absoluteX, ::absoluteY, ::indirect, ::indirectX, ::indirectY, ::single, ::branch)
|
||||
val methods = arrayOf(
|
||||
this::immediate,
|
||||
this::zeroPage,
|
||||
this::zeroPageX,
|
||||
this::zeroPageY,
|
||||
this::absolute,
|
||||
this::absoluteX,
|
||||
this::absoluteY,
|
||||
this::indirect,
|
||||
this::indirectX,
|
||||
this::indirectY,
|
||||
this::single,
|
||||
this::branch)
|
||||
|
||||
opcodes.forEachIndexed { i, opcode ->
|
||||
if (opcode != 0xff) {
|
||||
|
@ -17,62 +27,62 @@ open class BaseInstruction(val instruction: Instruction, private val cpu: CPU) {
|
|||
}
|
||||
|
||||
open fun immediate() {
|
||||
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||
throw IllegalStateException("Instruction " + javaClass.simpleName + " not implemented" +
|
||||
" with immediate addressing")
|
||||
}
|
||||
|
||||
open fun zeroPage() {
|
||||
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||
throw IllegalStateException("Instruction " + javaClass.simpleName + " not implemented" +
|
||||
" with zeroPage addressing")
|
||||
}
|
||||
|
||||
open fun zeroPageX() {
|
||||
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||
throw IllegalStateException("Instruction " + javaClass.simpleName + " not implemented" +
|
||||
" with zeroPageX addressing")
|
||||
}
|
||||
|
||||
open fun zeroPageY() {
|
||||
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||
throw IllegalStateException("Instruction " + javaClass.simpleName + " not implemented" +
|
||||
" with zeroPageY addressing")
|
||||
}
|
||||
|
||||
open fun absolute() {
|
||||
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||
throw IllegalStateException("Instruction " + javaClass.simpleName + " not implemented" +
|
||||
" with absolute addressing")
|
||||
}
|
||||
|
||||
open fun absoluteX() {
|
||||
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||
throw IllegalStateException("Instruction " + javaClass.simpleName + " not implemented" +
|
||||
" with absoluteX addressing")
|
||||
}
|
||||
|
||||
open fun absoluteY() {
|
||||
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||
throw IllegalStateException("Instruction " + javaClass.simpleName + " not implemented" +
|
||||
" with absoluteY addressing")
|
||||
}
|
||||
|
||||
open fun indirect() {
|
||||
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||
throw IllegalStateException("Instruction " + javaClass.simpleName + " not implemented" +
|
||||
" with indirect addressing")
|
||||
}
|
||||
|
||||
open fun indirectX() {
|
||||
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||
throw IllegalStateException("Instruction " + javaClass.simpleName + " not implemented" +
|
||||
" with indirectX addressing")
|
||||
}
|
||||
|
||||
open fun indirectY() {
|
||||
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||
throw IllegalStateException("Instruction " + javaClass.simpleName + " not implemented" +
|
||||
" with indirectY addressing")
|
||||
}
|
||||
|
||||
open fun single() {
|
||||
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||
throw IllegalStateException("Instruction " + javaClass.simpleName + " not implemented" +
|
||||
" with single addressing")
|
||||
}
|
||||
|
||||
open fun branch() {
|
||||
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||
throw IllegalStateException("Instruction " + javaClass.simpleName + " not implemented" +
|
||||
" with branch addressing")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
package android.emu6502.instructions
|
||||
|
||||
import kotlin.reflect.KMemberFunction0
|
||||
|
||||
class InstructionTarget(val operation: BaseInstruction,
|
||||
val method: KMemberFunction0<BaseInstruction, Unit>) {
|
||||
}
|
||||
data class InstructionTarget(val operation: BaseInstruction, val method: () -> Unit)
|
|
@ -1,8 +1,8 @@
|
|||
package android.emu6502.instructions
|
||||
|
||||
final class Opcodes {
|
||||
class Opcodes {
|
||||
companion object {
|
||||
public val MAP: Map<Instruction, IntArray> = hashMapOf(
|
||||
val MAP: Map<Instruction, IntArray> = 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)),
|
||||
|
@ -61,6 +61,6 @@ final class Opcodes {
|
|||
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))
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,5 +5,4 @@ import android.emu6502.instructions.BaseInstruction
|
|||
import android.emu6502.instructions.Instruction
|
||||
|
||||
/** Arithmetic Shift Left */
|
||||
class ASL(private val cpu: CPU) : BaseInstruction(Instruction.ASL, cpu) {
|
||||
}
|
||||
class ASL(private val cpu: CPU) : BaseInstruction(Instruction.ASL, cpu)
|
||||
|
|
|
@ -5,7 +5,7 @@ import android.emu6502.instructions.BaseInstruction
|
|||
import android.emu6502.instructions.Instruction
|
||||
|
||||
/** Branch on Carry Clear */
|
||||
final class BCC(private val cpu: CPU) : BaseInstruction(Instruction.BCC, cpu) {
|
||||
class BCC(private val cpu: CPU) : BaseInstruction(Instruction.BCC, cpu) {
|
||||
override fun branch() {
|
||||
val offset = cpu.popByte()
|
||||
if (!cpu.carry()) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import android.emu6502.instructions.BaseInstruction
|
|||
import android.emu6502.instructions.Instruction
|
||||
|
||||
/** Branch on Carry Set */
|
||||
final class BCS(private val cpu: CPU) : BaseInstruction(Instruction.BCS, cpu) {
|
||||
class BCS(private val cpu: CPU) : BaseInstruction(Instruction.BCS, cpu) {
|
||||
override fun branch() {
|
||||
val offset = cpu.popByte()
|
||||
if (cpu.carry()) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import android.emu6502.instructions.BaseInstruction
|
|||
import android.emu6502.instructions.Instruction
|
||||
|
||||
/** Branch on Not Equal */
|
||||
final class BNE(private val cpu: CPU) : BaseInstruction(Instruction.BNE, cpu) {
|
||||
class BNE(private val cpu: CPU) : BaseInstruction(Instruction.BNE, cpu) {
|
||||
override fun branch() {
|
||||
val offset = cpu.popByte()
|
||||
if (!cpu.zero()) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import android.emu6502.instructions.BaseInstruction
|
|||
import android.emu6502.instructions.Instruction
|
||||
|
||||
/** Branch on PLus */
|
||||
final class BPL(private val cpu: CPU) : BaseInstruction(Instruction.BPL, cpu) {
|
||||
class BPL(private val cpu: CPU) : BaseInstruction(Instruction.BPL, cpu) {
|
||||
override fun branch() {
|
||||
val offset = cpu.popByte()
|
||||
if (!cpu.negative()) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import android.emu6502.instructions.BaseInstruction
|
|||
import android.emu6502.instructions.Instruction
|
||||
|
||||
/** BRreaK */
|
||||
final class BRK(private val cpu: CPU) : BaseInstruction(Instruction.BRK, cpu) {
|
||||
class BRK(private val cpu: CPU) : BaseInstruction(Instruction.BRK, cpu) {
|
||||
override fun single() {
|
||||
cpu.stop()
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import android.emu6502.instructions.BaseInstruction
|
|||
import android.emu6502.instructions.Instruction
|
||||
|
||||
/** CLear Carry */
|
||||
final class CLC(private val cpu: CPU) : BaseInstruction(Instruction.CLC, cpu) {
|
||||
class CLC(private val cpu: CPU) : BaseInstruction(Instruction.CLC, cpu) {
|
||||
override fun single() {
|
||||
cpu.CLC()
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import android.emu6502.instructions.BaseInstruction
|
|||
import android.emu6502.instructions.Instruction
|
||||
|
||||
/** CoMPare accumulator */
|
||||
final class CMP(private val cpu: CPU) : BaseInstruction(Instruction.CMP, cpu) {
|
||||
class CMP(private val cpu: CPU) : BaseInstruction(Instruction.CMP, cpu) {
|
||||
override fun immediate() {
|
||||
cpu.doCompare(cpu.A, cpu.popByte())
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import android.emu6502.instructions.BaseInstruction
|
|||
import android.emu6502.instructions.Instruction
|
||||
|
||||
/** INCrement memory */
|
||||
final class INC(private val cpu: CPU) : BaseInstruction(Instruction.INC, cpu) {
|
||||
class INC(private val cpu: CPU) : BaseInstruction(Instruction.INC, cpu) {
|
||||
override fun zeroPage() {
|
||||
inc(cpu.popByte())
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import android.emu6502.instructions.BaseInstruction
|
|||
import android.emu6502.instructions.Instruction
|
||||
|
||||
/** Logical Shift Right */
|
||||
final class LSR(private val cpu: CPU) : BaseInstruction(Instruction.LSR, cpu) {
|
||||
class LSR(private val cpu: CPU) : BaseInstruction(Instruction.LSR, cpu) {
|
||||
override fun single() {
|
||||
cpu.setCarryFlagFromBit0(cpu.A)
|
||||
cpu.A = cpu.A.shr(1)
|
||||
|
|
|
@ -27,8 +27,8 @@ class STA(private val memory: Memory, private val cpu: CPU)
|
|||
}
|
||||
|
||||
override fun indirectX() {
|
||||
var zp = (cpu.popByte() + cpu.X).and(0xff)
|
||||
var addr = memory.getWord(zp)
|
||||
val zp = (cpu.popByte() + cpu.X).and(0xff)
|
||||
val addr = memory.getWord(zp)
|
||||
memory.storeByte(addr, cpu.A)
|
||||
}
|
||||
}
|
||||
|
|
26
build.gradle
26
build.gradle
|
@ -1,21 +1,21 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.2.3'
|
||||
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:0.12.1218'
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.3.0'
|
||||
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
jcenter()
|
||||
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
|
||||
}
|
||||
repositories {
|
||||
jcenter()
|
||||
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#Sun Jun 07 17:48:47 PDT 2015
|
||||
#Tue Mar 07 20:34:27 PST 2017
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
|
||||
|
|
Loading…
Reference in New Issue