Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup JDK 11
- name: Setup JDK 17
uses: actions/setup-java@v3
with:
java-version: '11'
java-version: '17'
distribution: 'adopt'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
Expand Down
17 changes: 11 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,20 @@ plugins {
id 'java'
id 'jacoco'
id 'application'
id 'com.github.johnrengelman.shadow' version '8.1.1'
id 'com.gradleup.shadow' version '8.3.5'
id 'org.sonarqube' version '6.0.1.5171'
}

group 'ca.craigthomas'
version '1.0'
group = 'ca.craigthomas'
version = '1.0'

mainClassName = 'ca.craigthomas.yacoco3e.runner.Runner'
java {
sourceCompatibility = 1.8
}

sourceCompatibility = 1.8
application {
mainClass.set("ca.craigthomas.yacoco3e.runner.Runner")
}

repositories {
mavenCentral()
Expand All @@ -26,7 +31,7 @@ dependencies {
implementation 'commons-io:commons-io:2.18.0'
implementation 'org.apache.commons:commons-lang3:3.17.0'
implementation 'com.beust:jcommander:1.82'
implementation 'org.yaml:snakeyaml:2.3'
implementation 'org.yaml:snakeyaml:2.4'
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-core:5.15.2'
}
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/ca/craigthomas/yacoco3e/common/IO.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
/*
* Copyright (C) 2017-2019 Craig Thomas
* Copyright (C) 2017-2025 Craig Thomas
* This project uses an MIT style license - see LICENSE for details.
*/
package ca.craigthomas.yacoco3e.common;

import ca.craigthomas.yacoco3e.components.Memory;
import org.apache.commons.io.IOUtils;

import java.io.*;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2022 Craig Thomas
* Copyright (C) 2022-2025 Craig Thomas
* This project uses an MIT style license - see LICENSE for details.
*/
package ca.craigthomas.yacoco3e.components;
Expand All @@ -8,7 +8,6 @@

import java.util.function.Function;

import static ca.craigthomas.yacoco3e.datatypes.AddressingMode.IMMEDIATE;
import static ca.craigthomas.yacoco3e.datatypes.RegisterSet.*;

/**
Expand All @@ -19,185 +18,152 @@
*/
public class BranchInstruction extends Instruction
{
protected Function<InstructionBundle, Boolean> operation;
protected Function<IOController, Boolean> operation;

public BranchInstruction(int opcode,
int ticks,
String mnemonic,
Function<InstructionBundle, Boolean> operation
Function<IOController, Boolean> operation
) {
this.opcodeValue = opcode;
this.mnemonic = mnemonic;
this.ticks = ticks;
this.operation = operation;
this.addressingMode = IMMEDIATE;
this.immediateByte = true;
this.addressingMode = AddressingMode.IMMEDIATE;
this.isByteSized = true;
this.isValidInstruction = true;
this.addressRead = new UnsignedWord();
}

public int call(MemoryResult memoryResult, IOController io) {
if (operation.apply(new InstructionBundle(memoryResult, io)).equals(true)) {
UnsignedByte offset = memoryResult.value.getHigh();
io.regs.pc.add(offset.isNegative() ? offset.getSignedShort() : offset.getShort());
public int call(IOController io) {
if (operation.apply(io).equals(true)) {
io.regs.pc.add(byteRead.isNegative() ? byteRead.getSignedShort() : byteRead.getShort());
}
return ticks;
}

/**
* Branches to the specified address, pushing the value of the PC onto the S
* stack before branching.
*
* @param bundle the InstructionBundle that contains information to process
*/
public static Boolean branchToSubroutine(InstructionBundle bundle) {
bundle.io.pushStack(Register.S, bundle.io.regs.pc);
public static Boolean branchToSubroutine(IOController io) {
io.pushStack(Register.S, io.regs.pc);
return true;
}

/**
* Branch always will always return true when called.
*
* @param bundle the InstructionBundle with the information to process.
*/
public static Boolean branchAlways(InstructionBundle bundle) {
public static Boolean branchAlways(IOController io) {
return true;
}

/**
* Branch never will always return false when called.
*
* @param bundle the InstructionBundle with the information to process.
*/
public static Boolean branchNever(InstructionBundle bundle) {
public static Boolean branchNever(IOController io) {
return false;
}

/**
* Branch on high will return true if carry is not set, and zero is not set.
*
* @param bundle the InstructionBundle with the information to process.
*/
public static Boolean branchOnHigh(InstructionBundle bundle) {
return !bundle.io.regs.cc.isMasked(CC_C) && !bundle.io.regs.cc.isMasked(CC_Z);
public static Boolean branchOnHigh(IOController io) {
return !io.regs.cc.isMasked(CC_C) && !io.regs.cc.isMasked(CC_Z);
}

/**
* Branch on lower will return true if carry is set or zero is set.
*
* @param bundle the InstructionBundle with the information to process.
*/
public static Boolean branchOnLower(InstructionBundle bundle) {
return bundle.io.regs.cc.isMasked(CC_C) || bundle.io.regs.cc.isMasked(CC_Z);
public static Boolean branchOnLower(IOController io) {
return io.regs.cc.isMasked(CC_C) || io.regs.cc.isMasked(CC_Z);
}

/**
* Branch on carry clear will return true if carry is not set.
*
* @param bundle the InstructionBundle with the information to process.
*/
public static Boolean branchOnCarryClear(InstructionBundle bundle) {
return !bundle.io.regs.cc.isMasked(CC_C);
public static Boolean branchOnCarryClear(IOController io) {
return !io.regs.cc.isMasked(CC_C);
}

/**
* Branch on carry set will return true if carry is set.
*
* @param bundle the InstructionBundle with the information to process.
*/
public static Boolean branchOnCarrySet(InstructionBundle bundle) {
return bundle.io.regs.cc.isMasked(CC_C);
public static Boolean branchOnCarrySet(IOController io) {
return io.regs.cc.isMasked(CC_C);
}

/**
* Branch on not equal will return true if the zero flag is set.
*
* @param bundle the InstructionBundle with the information to process.
*/
public static Boolean branchOnNotEqual(InstructionBundle bundle) {
return !bundle.io.regs.cc.isMasked(CC_Z);
public static Boolean branchOnNotEqual(IOController io) {
return !io.regs.cc.isMasked(CC_Z);
}

/**
* Branch on equal will return true if the zero flag is set.
*
* @param bundle the InstructionBundle with the information to process.
*/
public static Boolean branchOnEqual(InstructionBundle bundle) {
return bundle.io.regs.cc.isMasked(CC_Z);
public static Boolean branchOnEqual(IOController io) {
return io.regs.cc.isMasked(CC_Z);
}

/**
* Branch on overflow clear will return true if the overflow flag is clear.
*
* @param bundle the InstructionBundle with the information to process.
*/
public static Boolean branchOnOverflowClear(InstructionBundle bundle) {
return !bundle.io.regs.cc.isMasked(CC_V);
public static Boolean branchOnOverflowClear(IOController io) {
return !io.regs.cc.isMasked(CC_V);
}

/**
* Branch on overflow set will return true if the overflow flag is set.
*
* @param bundle the InstructionBundle with the information to process.
*/
public static Boolean branchOnOverflowSet(InstructionBundle bundle) {
return bundle.io.regs.cc.isMasked(CC_V);
public static Boolean branchOnOverflowSet(IOController io) {
return io.regs.cc.isMasked(CC_V);
}

/**
* Branch on plus will return true if the negative flag is clear.
*
* @param bundle the InstructionBundle with the information to process.
*/
public static Boolean branchOnPlus(InstructionBundle bundle) {
return !bundle.io.regs.cc.isMasked(CC_N);
public static Boolean branchOnPlus(IOController io) {
return !io.regs.cc.isMasked(CC_N);
}

/**
* Branch on minus will return true if the negative flag is set.
*
* @param bundle the InstructionBundle with the information to process.
*/
public static Boolean branchOnMinus(InstructionBundle bundle) {
return bundle.io.regs.cc.isMasked(CC_N);
public static Boolean branchOnMinus(IOController io) {
return io.regs.cc.isMasked(CC_N);
}

/**
* Branch on greater than equal to zero will return true if the negative and overflow
* flags are both set or both clear.
*
* @param bundle the InstructionBundle with the information to process.
*/
public static Boolean branchOnGreaterThanEqualZero(InstructionBundle bundle) {
return bundle.io.regs.cc.isMasked(CC_N) == bundle.io.regs.cc.isMasked(CC_V);
public static Boolean branchOnGreaterThanEqualZero(IOController io) {
return io.regs.cc.isMasked(CC_N) == io.regs.cc.isMasked(CC_V);
}

/**
* Branch on less than zero will return true if the negative and overflow are not equal.
*
* @param bundle the InstructionBundle with the information to process.
*/
public static Boolean branchOnLessThanZero(InstructionBundle bundle) {
return bundle.io.regs.cc.isMasked(CC_N) != bundle.io.regs.cc.isMasked(CC_V);
public static Boolean branchOnLessThanZero(IOController io) {
return io.regs.cc.isMasked(CC_N) != io.regs.cc.isMasked(CC_V);
}

/**
* Branch on greater than zero will return true if the zero flag is clear,
* and if negative and overflow are both set or both clear.
*
* @param bundle the InstructionBundle with the information to process.
*/
public static Boolean branchOnGreaterThanZero(InstructionBundle bundle) {
return !bundle.io.regs.cc.isMasked(CC_Z) && (bundle.io.regs.cc.isMasked(CC_N) == bundle.io.regs.cc.isMasked(CC_V));
public static Boolean branchOnGreaterThanZero(IOController io) {
return !io.regs.cc.isMasked(CC_Z) && (io.regs.cc.isMasked(CC_N) == io.regs.cc.isMasked(CC_V));
}

/**
* Branch on less than equal to zero will return true if the zero flag is set,
* or if overflow and negative are not equal.
*
* @param bundle the InstructionBundle with the information to process.
*/
public static Boolean branchOnLessThanEqualZero(InstructionBundle bundle) {
return bundle.io.regs.cc.isMasked(CC_Z) || (bundle.io.regs.cc.isMasked(CC_N) != bundle.io.regs.cc.isMasked(CC_V));
public static Boolean branchOnLessThanEqualZero(IOController io) {
return io.regs.cc.isMasked(CC_Z) || (io.regs.cc.isMasked(CC_N) != io.regs.cc.isMasked(CC_V));
}

}
Loading
Loading