Fix a few bugs

This commit is contained in:
Felipe Lima 2015-06-13 02:19:42 -07:00
parent 053d7b267d
commit 25cfd99dd2
3 changed files with 35 additions and 28 deletions

View File

@ -5,22 +5,22 @@ import android.emu6502.instructions.Opcodes
import java.util.regex.Pattern import java.util.regex.Pattern
import kotlin.text.Regex import kotlin.text.Regex
class Assembler(private var labels: Labels, class Assembler(private var labels: Labels, private var memory: Memory,
private var memory: Memory,
private var symbols: Symbols) { private var symbols: Symbols) {
private var defaultCodePC = 0 var codeLen = 0
private var codeLen = 0 val BOOTSTRAP_ADDRESS = 0x600
private var codeAssembledOK = false var defaultCodePC = BOOTSTRAP_ADDRESS
private var BOOTSTRAP_ADDRESS = 0x600
fun assembleCode(lines: List<String>): Boolean { fun assembleCode(lines: List<String>) {
lines.forEach { line -> lines.forEachIndexed { i, line ->
if (!assembleLine(line)) { if (!assembleLine(line)) {
return false val str = line.replace("<", "&lt;").replace(">", "&gt;")
throw RuntimeException("**Syntax error line " + (i + 1) + ": " + str + "**")
} }
} }
return true // set a null byte at the end of the code
memory.set(defaultCodePC, 0x00)
} }
private fun assembleLine(line: String): Boolean { private fun assembleLine(line: String): Boolean {
@ -48,11 +48,11 @@ class Assembler(private var labels: Labels,
command = command.toUpperCase() command = command.toUpperCase()
if (input.matches("^\\*\\s*=\\s*\$?[0-9a-f]*$".toRegex())) { if (input.matches("^\\*\\s*=\\s*\\$?[0-9a-f]*$".toRegex())) {
// equ spotted // equ spotted
param = input.replace("^\\s*\\*\\s*=\\s*".toRegex(), "") param = input.replace("^\\s*\\*\\s*=\\s*".toRegex(), "")
if (param[0].equals("$")) { if (param[0].equals("$")) {
param = param.replace("^\$".toRegex(), "") param = param.replace("^\\$".toRegex(), "")
addr = Integer.parseInt(param, 16) addr = Integer.parseInt(param, 16)
} else { } else {
addr = Integer.parseInt(param, 10) addr = Integer.parseInt(param, 10)
@ -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(param, opcode, "^([\\w\$]+)$")) { if (checkWordOperand(param, opcode, "^([\\w\\$]+)$")) {
return true return true
} }
@ -199,28 +199,28 @@ class Assembler(private var labels: Labels,
if (opcode == 0xff) { if (opcode == 0xff) {
return false 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) { if (opcode == 0xff) {
return false 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) { if (opcode == 0xff) {
return false 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) { if (opcode == 0xff) {
return false 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())
} }
@ -228,7 +228,7 @@ class Assembler(private var labels: Labels,
if (opcode == 0xff) { if (opcode == 0xff) {
return false 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())
} }
@ -236,14 +236,14 @@ class Assembler(private var labels: Labels,
if (opcode == 0xff) { if (opcode == 0xff) {
return false 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) { if (opcode == 0xff) {
return false 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 {
@ -257,7 +257,7 @@ class Assembler(private var labels: Labels,
if (opcode == 0xff) { if (opcode == 0xff) {
return false return false
} }
if (checkByteOperand(param, opcode, "^#([\\w\$]+)$")) { if (checkByteOperand(param, opcode, "^#([\\w\\$]+)$")) {
return true return true
} }
@ -300,13 +300,13 @@ class Assembler(private var labels: Labels,
} }
// Is it a hexadecimal operand? // Is it a hexadecimal operand?
var pattern = Pattern.compile("^\$([0-9a-f]{1,2})$") var pattern = Pattern.compile("^\\$([0-9a-f]{1,2})$", Pattern.CASE_INSENSITIVE)
var matcher = pattern.matcher(parameter) var matcher = pattern.matcher(parameter)
if (matcher.find()) { if (matcher.find()) {
value = Integer.parseInt(matcher.group(1), 16) value = Integer.parseInt(matcher.group(1), 16)
} else { } else {
// Is it a decimal operand? // Is it a decimal operand?
pattern = Pattern.compile("^([0-9]{1,3})$") pattern = Pattern.compile("^([0-9]{1,3})$", Pattern.CASE_INSENSITIVE)
matcher = pattern.matcher(parameter) matcher = pattern.matcher(parameter)
if (matcher.find()) { if (matcher.find()) {
value = Integer.parseInt(matcher.group(1), 10) value = Integer.parseInt(matcher.group(1), 10)
@ -332,13 +332,13 @@ class Assembler(private var labels: Labels,
} }
// Is it a hexadecimal operand? // Is it a hexadecimal operand?
var pattern = Pattern.compile("^\$([0-9a-f]{3,4})$") var pattern = Pattern.compile("^\\$([0-9a-f]{3,4})$", Pattern.CASE_INSENSITIVE)
var matcher = pattern.matcher(parameter) var matcher = pattern.matcher(parameter)
if (matcher.find()) { if (matcher.find()) {
value = Integer.parseInt(matcher.group(1), 16) value = Integer.parseInt(matcher.group(1), 16)
} else { } else {
// Is it a decimal operand? // Is it a decimal operand?
pattern = Pattern.compile("^([0-9]{1,5})$") pattern = Pattern.compile("^([0-9]{1,5})$", Pattern.CASE_INSENSITIVE)
matcher = pattern.matcher(parameter) matcher = pattern.matcher(parameter)
if (matcher.find()) { if (matcher.find()) {
value = Integer.parseInt(matcher.group(1), 10) value = Integer.parseInt(matcher.group(1), 10)

View File

@ -90,7 +90,7 @@ class CPU(private val memory: Memory) {
if (PC == 0 || !isRunning) { if (PC == 0 || !isRunning) {
stop() stop()
Log.i(TAG, "Program end at PC=$" + (PC - 1)) Log.i(TAG, "Program end at PC=$" + (PC - 1).toHexString())
} }
} }
@ -105,7 +105,7 @@ class CPU(private val memory: Memory) {
val function = target.method val function = target.method
target.operation.function() target.operation.function()
} else { } else {
Log.e(TAG, "Address $" + PC + " - unknown opcode") Log.e(TAG, "Address $" + PC.toHexString() + " - unknown opcode " + instruction.toHexString())
} }
} }
@ -137,4 +137,8 @@ class CPU(private val memory: Memory) {
fun popWord(): Int { fun popWord(): Int {
return popByte() + popByte().shl(8) return popByte() + popByte().shl(8)
} }
fun Int.toHexString(): String {
return Integer.toHexString(this)
}
} }

View File

@ -37,7 +37,10 @@ public class MainActivity : AppCompatActivity() {
fabRun.setOnClickListener { fabRun.setOnClickListener {
emulator.assembler.assembleCode(txtInstructions.getText().toString().splitBy("\n")) emulator.assembler.assembleCode(txtInstructions.getText().toString().splitBy("\n"))
Toast.makeText(fabRun.getContext(), "Code assembled", Toast.LENGTH_SHORT).show() Toast.makeText(fabRun.getContext(),
"Code assembled successfully, " + emulator.assembler.codeLen + " bytes.",
Toast.LENGTH_SHORT).show()
emulator.cpu.execute()
} }
} }