mirror of
https://github.com/felipecsl/6502Android.git
synced 2024-06-01 06:41:32 +00:00
Adds jump instructions
This commit is contained in:
parent
4f9f9c4b9b
commit
df2e9fac8f
|
@ -41,7 +41,10 @@ class CPU(val memory: Memory) {
|
||||||
Pair(Instruction.ORA, ORA(this)),
|
Pair(Instruction.ORA, ORA(this)),
|
||||||
Pair(Instruction.CPX, CPX(this)),
|
Pair(Instruction.CPX, CPX(this)),
|
||||||
Pair(Instruction.BRK, BRK(this)),
|
Pair(Instruction.BRK, BRK(this)),
|
||||||
Pair(Instruction.BNE, BNE(this))
|
Pair(Instruction.BNE, BNE(this)),
|
||||||
|
Pair(Instruction.JMP, JMP(this)),
|
||||||
|
Pair(Instruction.JSR, JSR(this)),
|
||||||
|
Pair(Instruction.RTS, RTS(this))
|
||||||
// Pair(Instruction.BPL, BPL(this)),
|
// Pair(Instruction.BPL, BPL(this)),
|
||||||
// Pair(Instruction.BMI, BMI(this)),
|
// Pair(Instruction.BMI, BMI(this)),
|
||||||
// Pair(Instruction.BVC, BVC(this)),
|
// Pair(Instruction.BVC, BVC(this)),
|
||||||
|
@ -61,8 +64,6 @@ class CPU(val memory: Memory) {
|
||||||
// Pair(Instruction.CLD, CLD(this)),
|
// Pair(Instruction.CLD, CLD(this)),
|
||||||
// Pair(Instruction.SED, SED(this)),
|
// Pair(Instruction.SED, SED(this)),
|
||||||
// Pair(Instruction.INC, INC(this)),
|
// Pair(Instruction.INC, INC(this)),
|
||||||
// Pair(Instruction.JMP, JMP(this)),
|
|
||||||
// Pair(Instruction.JSR, JSR(this)),
|
|
||||||
// Pair(Instruction.LSR, LSR(this)),
|
// Pair(Instruction.LSR, LSR(this)),
|
||||||
// Pair(Instruction.NOP, NOP(this)),
|
// Pair(Instruction.NOP, NOP(this)),
|
||||||
// Pair(Instruction.TXA, TXA(this)),
|
// Pair(Instruction.TXA, TXA(this)),
|
||||||
|
@ -73,7 +74,6 @@ class CPU(val memory: Memory) {
|
||||||
// Pair(Instruction.ROR, ROR(this)),
|
// Pair(Instruction.ROR, ROR(this)),
|
||||||
// Pair(Instruction.ROL, ROL(this)),
|
// Pair(Instruction.ROL, ROL(this)),
|
||||||
// Pair(Instruction.RTI, RTI(this)),
|
// Pair(Instruction.RTI, RTI(this)),
|
||||||
// Pair(Instruction.RTS, RTS(this)),
|
|
||||||
// Pair(Instruction.SBC, SBC(this)),
|
// Pair(Instruction.SBC, SBC(this)),
|
||||||
// Pair(Instruction.TXS, TXS(this)),
|
// Pair(Instruction.TXS, TXS(this)),
|
||||||
// Pair(Instruction.TSX, TSX(this)),
|
// Pair(Instruction.TSX, TSX(this)),
|
||||||
|
@ -248,6 +248,24 @@ class CPU(val memory: Memory) {
|
||||||
P = P.or(0x40)
|
P = P.or(0x40)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun stackPush(value: Int) {
|
||||||
|
memory.set(SP.and(0xff) + 0x100, value.and(0xff))
|
||||||
|
SP--
|
||||||
|
if (SP < 0) {
|
||||||
|
SP = SP.and(0xff)
|
||||||
|
Log.i(TAG, "6502 Stack filled! Wrapping...")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stackPop(): Int {
|
||||||
|
SP++;
|
||||||
|
if (SP >= 0x100) {
|
||||||
|
SP = SP.and(0xff)
|
||||||
|
Log.i(TAG, "6502 Stack emptied! Wrapping...")
|
||||||
|
}
|
||||||
|
return memory.get(SP + 0x100)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* http://nesdev.com/6502.txt
|
* http://nesdev.com/6502.txt
|
||||||
* Returns the processor flags in the format SV-BDIZC
|
* Returns the processor flags in the format SV-BDIZC
|
||||||
|
|
|
@ -18,38 +18,62 @@ open class BaseInstruction(private val instruction: Instruction,
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun immediate() {
|
open fun immediate() {
|
||||||
|
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||||
|
" with immediate addressing")
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun zeroPage() {
|
open fun zeroPage() {
|
||||||
|
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||||
|
" with zeroPage addressing")
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun zeroPageX() {
|
open fun zeroPageX() {
|
||||||
|
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||||
|
" with zeroPageX addressing")
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun zeroPageY() {
|
open fun zeroPageY() {
|
||||||
|
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||||
|
" with zeroPageY addressing")
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun absolute() {
|
open fun absolute() {
|
||||||
|
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||||
|
" with absolute addressing")
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun absoluteX() {
|
open fun absoluteX() {
|
||||||
|
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||||
|
" with absoluteX addressing")
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun absoluteY() {
|
open fun absoluteY() {
|
||||||
|
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||||
|
" with absoluteY addressing")
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun indirect() {
|
open fun indirect() {
|
||||||
|
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||||
|
" with indirect addressing")
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun indirectX() {
|
open fun indirectX() {
|
||||||
|
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||||
|
" with indirectX addressing")
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun indirectY() {
|
open fun indirectY() {
|
||||||
|
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||||
|
" with indirectY addressing")
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun single() {
|
open fun single() {
|
||||||
|
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||||
|
" with single addressing")
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun branch() {
|
open fun branch() {
|
||||||
|
throw IllegalStateException("Instruction " + javaClass.getSimpleName() + " not implemented" +
|
||||||
|
" with branch addressing")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
12
app/src/main/kotlin/android/emu6502/instructions/impl/JMP.kt
Normal file
12
app/src/main/kotlin/android/emu6502/instructions/impl/JMP.kt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package android.emu6502.instructions.impl
|
||||||
|
|
||||||
|
import android.emu6502.CPU
|
||||||
|
import android.emu6502.instructions.BaseInstruction
|
||||||
|
import android.emu6502.instructions.Instruction
|
||||||
|
|
||||||
|
/** JuMP */
|
||||||
|
class JMP(private val cpu: CPU) : BaseInstruction(Instruction.JMP, cpu.instructionList) {
|
||||||
|
override fun absolute() {
|
||||||
|
cpu.PC = cpu.popWord()
|
||||||
|
}
|
||||||
|
}
|
17
app/src/main/kotlin/android/emu6502/instructions/impl/JSR.kt
Normal file
17
app/src/main/kotlin/android/emu6502/instructions/impl/JSR.kt
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package android.emu6502.instructions.impl
|
||||||
|
|
||||||
|
import android.emu6502.CPU
|
||||||
|
import android.emu6502.instructions.BaseInstruction
|
||||||
|
import android.emu6502.instructions.Instruction
|
||||||
|
|
||||||
|
/** Jump to SubRoutine */
|
||||||
|
class JSR(private val cpu: CPU) : BaseInstruction(Instruction.JSR, cpu.instructionList) {
|
||||||
|
override fun absolute() {
|
||||||
|
val addr = cpu.popWord()
|
||||||
|
val currAddr = cpu.PC - 1
|
||||||
|
cpu.stackPush(currAddr.shr(8).and(0xff))
|
||||||
|
cpu.stackPush(currAddr.and(0xff))
|
||||||
|
cpu.PC = addr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
13
app/src/main/kotlin/android/emu6502/instructions/impl/RTS.kt
Normal file
13
app/src/main/kotlin/android/emu6502/instructions/impl/RTS.kt
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
package android.emu6502.instructions.impl
|
||||||
|
|
||||||
|
import android.emu6502.CPU
|
||||||
|
import android.emu6502.instructions.BaseInstruction
|
||||||
|
import android.emu6502.instructions.Instruction
|
||||||
|
|
||||||
|
/** ReTurn from Subroutine */
|
||||||
|
class RTS(private val cpu: CPU) : BaseInstruction(Instruction.RTS, cpu.instructionList) {
|
||||||
|
override fun single() {
|
||||||
|
cpu.PC = cpu.stackPop().or(cpu.stackPop().shl(8)) + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package android.emu6502;
|
package android.emu6502;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
|
|
||||||
import android.emu6502.instructions.Symbols;
|
import android.emu6502.instructions.Symbols;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ public class CPUTest {
|
||||||
@Test public void testBranchAndLabel() {
|
@Test public void testBranchAndLabel() {
|
||||||
List<String> lines = ImmutableList.of(
|
List<String> lines = ImmutableList.of(
|
||||||
"LDX #$08",
|
"LDX #$08",
|
||||||
|
|
||||||
"decrement:",
|
"decrement:",
|
||||||
"DEX",
|
"DEX",
|
||||||
"STX $0200",
|
"STX $0200",
|
||||||
|
@ -77,4 +78,52 @@ public class CPUTest {
|
||||||
assertThat(cpu.getPC(), equalTo(0x060e));
|
assertThat(cpu.getPC(), equalTo(0x060e));
|
||||||
assertThat(cpu.flags(), equalTo("00110011"));
|
assertThat(cpu.flags(), equalTo("00110011"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test public void testJump() {
|
||||||
|
List<String> lines = ImmutableList.of(
|
||||||
|
"LDA #$03",
|
||||||
|
"JMP there",
|
||||||
|
"BRK",
|
||||||
|
"BRK",
|
||||||
|
"BRK",
|
||||||
|
|
||||||
|
"there:",
|
||||||
|
"STA $0200");
|
||||||
|
assembler.assembleCode(lines);
|
||||||
|
cpu.execute();
|
||||||
|
assertThat(cpu.getA(), equalTo(0x03));
|
||||||
|
assertThat(cpu.getX(), equalTo(0x00));
|
||||||
|
assertThat(cpu.getY(), equalTo(0x00));
|
||||||
|
assertThat(cpu.getSP(), equalTo(0xFF));
|
||||||
|
assertThat(cpu.getPC(), equalTo(0x060c));
|
||||||
|
assertThat(cpu.flags(), equalTo("00110000"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void testJumpToSubroutines() {
|
||||||
|
List<String> lines = ImmutableList.of(
|
||||||
|
"JSR init",
|
||||||
|
"JSR loop",
|
||||||
|
"JSR end",
|
||||||
|
|
||||||
|
"init:",
|
||||||
|
"LDX #$00",
|
||||||
|
"RTS",
|
||||||
|
|
||||||
|
"loop:",
|
||||||
|
"INX",
|
||||||
|
"CPX #$05",
|
||||||
|
"BNE loop",
|
||||||
|
"RTS",
|
||||||
|
|
||||||
|
"end:",
|
||||||
|
"BRK");
|
||||||
|
assembler.assembleCode(lines);
|
||||||
|
cpu.execute();
|
||||||
|
assertThat(cpu.getA(), equalTo(0x00));
|
||||||
|
assertThat(cpu.getX(), equalTo(0x05));
|
||||||
|
assertThat(cpu.getY(), equalTo(0x00));
|
||||||
|
assertThat(cpu.getSP(), equalTo(0xFD));
|
||||||
|
assertThat(cpu.getPC(), equalTo(0x0613));
|
||||||
|
assertThat(cpu.flags(), equalTo("00110011"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user