mirror of
https://github.com/felipecsl/6502Android.git
synced 2025-02-13 01:30:47 +00:00
Adds CLC and Snake test
This commit is contained in:
parent
1f4f9278dd
commit
6816980fda
@ -3,10 +3,10 @@ package android.emu6502
|
||||
import android.emu6502.instructions.BaseInstruction
|
||||
import android.emu6502.instructions.Instruction
|
||||
import android.emu6502.instructions.InstructionTarget
|
||||
import android.emu6502.instructions.Opcodes
|
||||
import android.emu6502.instructions.impl.*
|
||||
import android.util.Log
|
||||
import java.util.HashMap
|
||||
import kotlin.reflect.KMemberFunction0
|
||||
|
||||
class CPU(val memory: Memory) {
|
||||
// Accumulator
|
||||
@ -46,7 +46,8 @@ class CPU(val memory: Memory) {
|
||||
Pair(Instruction.JSR, JSR(this)),
|
||||
Pair(Instruction.RTS, RTS(this)),
|
||||
Pair(Instruction.SEI, SEI(this)),
|
||||
Pair(Instruction.DEY, DEY(this))
|
||||
Pair(Instruction.DEY, DEY(this)),
|
||||
Pair(Instruction.CLC, CLC(this))
|
||||
// Pair(Instruction.BPL, BPL(this)),
|
||||
// Pair(Instruction.BMI, BMI(this)),
|
||||
// Pair(Instruction.BVC, BVC(this)),
|
||||
@ -58,7 +59,6 @@ class CPU(val memory: Memory) {
|
||||
// Pair(Instruction.CPY, CPY(this)),
|
||||
// Pair(Instruction.DEC, DEC(this)),
|
||||
// Pair(Instruction.EOR, EOR(this)),
|
||||
// Pair(Instruction.CLC, CLC(this)),
|
||||
// Pair(Instruction.SEC, SEC(this)),
|
||||
// Pair(Instruction.CLI, CLI(this)),
|
||||
// Pair(Instruction.CLV, CLV(this)),
|
||||
@ -106,8 +106,12 @@ class CPU(val memory: Memory) {
|
||||
val function = target.method
|
||||
target.operation.function()
|
||||
} else {
|
||||
val candidate = Opcodes.MAP.entrySet()
|
||||
.first { it.value.any { opcode -> opcode == instruction } }
|
||||
|
||||
throw Exception(
|
||||
"Address $" + PC.toHexString() + " - unknown opcode " + instruction.toHexString())
|
||||
"Address $${PC.toHexString()} - unknown opcode 0x${instruction.toHexString()} " +
|
||||
"(instruction ${candidate.getKey().name()})")
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,7 +238,7 @@ class CPU(val memory: Memory) {
|
||||
}
|
||||
|
||||
/** CLear Carry */
|
||||
private fun CLC() {
|
||||
fun CLC() {
|
||||
P = P.and(0xfe)
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ package android.emu6502.instructions
|
||||
|
||||
import java.util.HashMap
|
||||
|
||||
open class BaseInstruction(private val instruction: Instruction,
|
||||
open class BaseInstruction(val instruction: Instruction,
|
||||
private val instructionList: HashMap<Int, InstructionTarget>) {
|
||||
|
||||
init {
|
||||
|
@ -5,6 +5,5 @@ import android.emu6502.instructions.BaseInstruction
|
||||
import android.emu6502.instructions.Instruction
|
||||
|
||||
/** Arithmetic Shift Left */
|
||||
class ASL(cpu: CPU)
|
||||
: BaseInstruction(Instruction.ASL, cpu.instructionList) {
|
||||
class ASL(private val cpu: CPU) : BaseInstruction(Instruction.ASL, cpu.instructionList) {
|
||||
}
|
||||
|
13
app/src/main/kotlin/android/emu6502/instructions/impl/CLC.kt
Normal file
13
app/src/main/kotlin/android/emu6502/instructions/impl/CLC.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
|
||||
|
||||
/** CLear Carry */
|
||||
final class CLC(private val cpu: CPU) : BaseInstruction(Instruction.CLC, cpu.instructionList) {
|
||||
override fun single() {
|
||||
cpu.CLC()
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import org.junit.Test;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.text.IsEqualIgnoringCase.equalToIgnoringCase;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
@ -138,4 +139,256 @@ public class AssemblerTest {
|
||||
assembler.assembleCode(lines);
|
||||
assertThat(assembler.hexdump(), equalTo("0600: A5 FE A2 0C"));
|
||||
}
|
||||
|
||||
@Test public void testSnake() {
|
||||
List<String> lines = ImmutableList.of(
|
||||
"define appleL $00 ; screen location of apple, low byte",
|
||||
"define appleH $01 ; screen location of apple, high byte",
|
||||
"define snakeHeadL $10 ; screen location of snake head, low byte",
|
||||
"define snakeHeadH $11 ; screen location of snake head, high byte",
|
||||
"define snakeBodyStart $12 ; start of snake body byte pairs",
|
||||
"define snakeDirection $02 ; direction (possible values are below)",
|
||||
"define snakeLength $03 ; snake length, in bytes",
|
||||
"; Directions (each using a separate bit)",
|
||||
"define movingUp 1",
|
||||
"define movingRight 2",
|
||||
"define movingDown 4",
|
||||
"define movingLeft 8",
|
||||
"; ASCII values of keys controlling the snake",
|
||||
"define ASCII_w $77",
|
||||
"define ASCII_a $61",
|
||||
"define ASCII_s $73",
|
||||
"define ASCII_d $64",
|
||||
"; System variables",
|
||||
"define sysRandom $fe",
|
||||
"define sysLastKey $ff",
|
||||
" jsr init",
|
||||
" jsr loop",
|
||||
"init:",
|
||||
" jsr initSnake",
|
||||
" jsr generateApplePosition",
|
||||
" rts",
|
||||
"initSnake:",
|
||||
" lda #movingRight ;start direction",
|
||||
" sta snakeDirection",
|
||||
" lda #4 ;start length (2 segments)",
|
||||
" sta snakeLength",
|
||||
" ",
|
||||
" lda #$11",
|
||||
" sta snakeHeadL",
|
||||
" ",
|
||||
" lda #$10",
|
||||
" sta snakeBodyStart",
|
||||
" ",
|
||||
" lda #$0f",
|
||||
" sta $14 ; body segment 1",
|
||||
" ",
|
||||
" lda #$04",
|
||||
" sta snakeHeadH",
|
||||
" sta $13 ; body segment 1",
|
||||
" sta $15 ; body segment 2",
|
||||
" rts",
|
||||
"generateApplePosition:",
|
||||
" ;load a new random byte into $00",
|
||||
" lda sysRandom",
|
||||
" sta appleL",
|
||||
" ;load a new random number from 2 to 5 into $01",
|
||||
" lda sysRandom",
|
||||
" and #$03 ;mask out lowest 2 bits",
|
||||
" clc",
|
||||
" adc #2",
|
||||
" sta appleH",
|
||||
" rts",
|
||||
"loop:",
|
||||
" jsr readKeys",
|
||||
" jsr checkCollision",
|
||||
" jsr updateSnake",
|
||||
" jsr drawApple",
|
||||
" jsr drawSnake",
|
||||
" jsr spinWheels",
|
||||
" jmp loop",
|
||||
"readKeys:",
|
||||
" lda sysLastKey",
|
||||
" cmp #ASCII_w",
|
||||
" beq upKey",
|
||||
" cmp #ASCII_d",
|
||||
" beq rightKey",
|
||||
" cmp #ASCII_s",
|
||||
" beq downKey",
|
||||
" cmp #ASCII_a",
|
||||
" beq leftKey",
|
||||
" rts",
|
||||
"upKey:",
|
||||
" lda #movingDown",
|
||||
" bit snakeDirection",
|
||||
" bne illegalMove",
|
||||
|
||||
" lda #movingUp",
|
||||
" sta snakeDirection",
|
||||
" rts",
|
||||
"rightKey:",
|
||||
" lda #movingLeft",
|
||||
" bit snakeDirection",
|
||||
" bne illegalMove",
|
||||
" lda #movingRight",
|
||||
" sta snakeDirection",
|
||||
" rts",
|
||||
"downKey:",
|
||||
" lda #movingUp",
|
||||
" bit snakeDirection",
|
||||
" bne illegalMove",
|
||||
" lda #movingDown",
|
||||
" sta snakeDirection",
|
||||
" rts",
|
||||
"leftKey:",
|
||||
" lda #movingRight",
|
||||
" bit snakeDirection",
|
||||
" bne illegalMove",
|
||||
" lda #movingLeft",
|
||||
" sta snakeDirection",
|
||||
" rts",
|
||||
"illegalMove:",
|
||||
" rts",
|
||||
"checkCollision:",
|
||||
" jsr checkAppleCollision",
|
||||
" jsr checkSnakeCollision",
|
||||
" rts",
|
||||
"checkAppleCollision:",
|
||||
" lda appleL",
|
||||
" cmp snakeHeadL",
|
||||
" bne doneCheckingAppleCollision",
|
||||
" lda appleH",
|
||||
" cmp snakeHeadH",
|
||||
" bne doneCheckingAppleCollision",
|
||||
" ;eat apple",
|
||||
" inc snakeLength",
|
||||
" inc snakeLength ;increase length",
|
||||
" jsr generateApplePosition",
|
||||
"doneCheckingAppleCollision:",
|
||||
" rts",
|
||||
"checkSnakeCollision:",
|
||||
" ldx #2 ;start with second segment",
|
||||
"snakeCollisionLoop:",
|
||||
" lda snakeHeadL,x",
|
||||
" cmp snakeHeadL",
|
||||
" bne continueCollisionLoop",
|
||||
"maybeCollided:",
|
||||
" lda snakeHeadH,x",
|
||||
" cmp snakeHeadH",
|
||||
" beq didCollide",
|
||||
"continueCollisionLoop:",
|
||||
" inx",
|
||||
" inx",
|
||||
" cpx snakeLength ;got to last section with no collision",
|
||||
" beq didntCollide",
|
||||
" jmp snakeCollisionLoop",
|
||||
"didCollide:",
|
||||
" jmp gameOver",
|
||||
"didntCollide:",
|
||||
" rts",
|
||||
"updateSnake:",
|
||||
" ldx snakeLength",
|
||||
" dex",
|
||||
" txa",
|
||||
"updateloop:",
|
||||
" lda snakeHeadL,x",
|
||||
" sta snakeBodyStart,x",
|
||||
" dex",
|
||||
" bpl updateloop",
|
||||
" lda snakeDirection",
|
||||
" lsr",
|
||||
" bcs up",
|
||||
" lsr",
|
||||
" bcs right",
|
||||
" lsr",
|
||||
" bcs down",
|
||||
" lsr",
|
||||
" bcs left",
|
||||
"up:",
|
||||
" lda snakeHeadL",
|
||||
" sec",
|
||||
" sbc #$20",
|
||||
" sta snakeHeadL",
|
||||
" bcc upup",
|
||||
" rts",
|
||||
"upup:",
|
||||
" dec snakeHeadH",
|
||||
" lda #$1",
|
||||
" cmp snakeHeadH",
|
||||
" beq collision",
|
||||
" rts",
|
||||
"right:",
|
||||
" inc snakeHeadL",
|
||||
" lda #$1f",
|
||||
" bit snakeHeadL",
|
||||
" beq collision",
|
||||
" rts",
|
||||
"down:",
|
||||
" lda snakeHeadL",
|
||||
" clc",
|
||||
" adc #$20",
|
||||
" sta snakeHeadL",
|
||||
" bcs downdown",
|
||||
" rts",
|
||||
"downdown:",
|
||||
" inc snakeHeadH",
|
||||
" lda #$6",
|
||||
" cmp snakeHeadH",
|
||||
" beq collision",
|
||||
" rts",
|
||||
"left:",
|
||||
" dec snakeHeadL",
|
||||
" lda snakeHeadL",
|
||||
" and #$1f",
|
||||
" cmp #$1f",
|
||||
" beq collision",
|
||||
" rts",
|
||||
"collision:",
|
||||
" jmp gameOver",
|
||||
"drawApple:",
|
||||
" ldy #0",
|
||||
" lda sysRandom",
|
||||
" sta (appleL),y",
|
||||
" rts",
|
||||
"drawSnake:",
|
||||
" ldx #0",
|
||||
" lda #1",
|
||||
" sta (snakeHeadL,x) ; paint head",
|
||||
" ",
|
||||
" ldx snakeLength",
|
||||
" lda #0",
|
||||
" sta (snakeHeadL,x) ; erase end of tail",
|
||||
" rts",
|
||||
"spinWheels:",
|
||||
" ldx #0",
|
||||
"spinloop:",
|
||||
" nop",
|
||||
" nop",
|
||||
" dex",
|
||||
" bne spinloop",
|
||||
" rts",
|
||||
"gameOver:", "\n");
|
||||
assembler.assembleCode(lines);
|
||||
assertThat(assembler.hexdump(), equalToIgnoringCase(
|
||||
"0600: 20 06 06 20 38 06 20 0d 06 20 2a 06 60 a9 02 85 \n" +
|
||||
"0610: 02 a9 04 85 03 a9 11 85 10 a9 10 85 12 a9 0f 85 \n" +
|
||||
"0620: 14 a9 04 85 11 85 13 85 15 60 a5 fe 85 00 a5 fe \n" +
|
||||
"0630: 29 03 18 69 02 85 01 60 20 4d 06 20 8d 06 20 c3 \n" +
|
||||
"0640: 06 20 19 07 20 20 07 20 2d 07 4c 38 06 a5 ff c9 \n" +
|
||||
"0650: 77 f0 0d c9 64 f0 14 c9 73 f0 1b c9 61 f0 22 60 \n" +
|
||||
"0660: a9 04 24 02 d0 26 a9 01 85 02 60 a9 08 24 02 d0 \n" +
|
||||
"0670: 1b a9 02 85 02 60 a9 01 24 02 d0 10 a9 04 85 02 \n" +
|
||||
"0680: 60 a9 02 24 02 d0 05 a9 08 85 02 60 60 20 94 06 \n" +
|
||||
"0690: 20 a8 06 60 a5 00 c5 10 d0 0d a5 01 c5 11 d0 07 \n" +
|
||||
"06a0: e6 03 e6 03 20 2a 06 60 a2 02 b5 10 c5 10 d0 06 \n" +
|
||||
"06b0: b5 11 c5 11 f0 09 e8 e8 e4 03 f0 06 4c aa 06 4c \n" +
|
||||
"06c0: 35 07 60 a6 03 ca 8a b5 10 95 12 ca 10 f9 a5 02 \n" +
|
||||
"06d0: 4a b0 09 4a b0 19 4a b0 1f 4a b0 2f a5 10 38 e9 \n" +
|
||||
"06e0: 20 85 10 90 01 60 c6 11 a9 01 c5 11 f0 28 60 e6 \n" +
|
||||
"06f0: 10 a9 1f 24 10 f0 1f 60 a5 10 18 69 20 85 10 b0 \n" +
|
||||
"0700: 01 60 e6 11 a9 06 c5 11 f0 0c 60 c6 10 a5 10 29 \n" +
|
||||
"0710: 1f c9 1f f0 01 60 4c 35 07 a0 00 a5 fe 91 00 60 \n" +
|
||||
"0720: a2 00 a9 01 81 10 a6 03 a9 00 81 10 60 a2 00 ea \n" +
|
||||
"0730: ea ca d0 fb 60"));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user