Compare commits

..
11 Commits
Author SHA1 Message Date
RuiFPB 3ee3a7e300 Add release action
Build and Test / build (push) Successful in 1m5s
Release / release (push) Successful in 1m6s
2026-09-29 13:44:53 +01:00
RuiFPB b2810fa062 Add missing mike42 machine flag to run options
Build and Test / build (push) Successful in 1m3s
2026-09-29 12:15:37 +01:00
RuiFPB c9f9121477 Add install maven step (gitea actions
Build and Test / build (push) Successful in 1m2s
2026-09-29 01:05:01 +01:00
RuiFPB 91ef70fe4e Disable maven cache on jdk setup (gitea actions)
Build and Test / build (push) Failing after 22s
2026-09-29 01:02:24 +01:00
RuiFPB 69bf418f43 Set container image to use to run the pipeline
Build and Test / build (push) Canceled after 10m40s
2026-09-29 00:51:56 +01:00
RuiFPB 540f0dff58 Add gitea action build pipeline 2026-09-29 00:46:42 +01:00
RuiFPB 17668e2c3c Only run X11 resource reader if on Linux 2026-09-28 10:24:02 +01:00
RuiFPB 3353b8436c Implement UI for the VIA/PIA 2026-09-26 19:47:15 +01:00
RuiFPB e635d0a608 Add binary converter to Utils 2026-09-26 19:46:54 +01:00
RuiFPB 558af36cd5 Start implementation of the VIA6522
Only PA and PB implemented, not tested
2026-09-26 19:14:20 +01:00
RuiFPB 5fa6fa0fc0 Clean up imports on the Mike42 machine 2026-09-26 19:13:24 +01:00
8 changed files with 201 additions and 6 deletions

No files matched your search

+36
View File
@@ -0,0 +1,36 @@
name: Build and Test
on:
push:
branches:
- master
pull_request:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
container:
image: catthehacker/ubuntu:act-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup JDK
uses: actions/setup-java@v6
with:
distribution: temurin
java-version: '21'
#cache: maven
- name: Install Maven
run: apt-get update && apt-get install -y maven
- name: Test and package
run: mvn -B verify
- name: Upload jar
uses: actions/upload-artifact@v3
with:
name: package
path: target/*.jar
+33
View File
@@ -0,0 +1,33 @@
name: Release
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: ubuntu-latest
container:
image: catthehacker/ubuntu:act-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup JDK
uses: actions/setup-java@v6
with:
distribution: temurin
java-version: '21'
- name: Install Maven
run: apt-get update && apt-get install -y maven
- name: Package
run: mvn -B verify
- name: Create release
uses: https://gitea.com/actions/gitea-release-action@v1
with:
files: |-
target/symon*.jar
@@ -86,6 +86,9 @@ public class Main {
case "beneater":
machineClass = BenEaterMachine.class;
break;
case "mike42":
machineClass = MichaelBillingtonMachine.class;
break;
default:
logger.error("Could not start Symon. Unknown machine type {}", machine);
return;
@@ -25,6 +25,7 @@ package com.loomcom.symon.devices;
import com.loomcom.symon.exceptions.MemoryAccessException;
import com.loomcom.symon.exceptions.MemoryRangeException;
import com.loomcom.symon.util.Utils;
/**
* Skeleton for future implementation of a MOS 6522 VIA.
@@ -32,18 +33,82 @@ import com.loomcom.symon.exceptions.MemoryRangeException;
public class Via6522 extends Pia {
public static final int VIA_SIZE = 16;
static final int IOB_REG = 0; // Output Register B / Input Register B
static final int IOA_REG = 1; // Output Register A / Input Register A
static final int DDRB_REG = 2; // Data Direction Register B
static final int DDRA_REG = 3; // Data Direction Register A
static final int T1CL_REG = 4; // T1 Low-Order Counter / Latches
static final int T1CH_REG = 5; // T1 High-Order Counter
static final int T1LL_REG = 6; // T1 Low-Order Latches
static final int T1LH_REG = 7; // T1 High-Order Latches
static final int T2CL_REG = 8; // T2 Low-Order Counter / Latches
static final int T2CH_REG = 9; // T2 High-Order Counter
static final int SR_REG = 10; // Shift Register
static final int AuxC_REG = 11; // Auxiliary Control Register
static final int PerC_REG = 12; // Peripheral Control Register
static final int IntF_REG = 13; // Interrupt Flag Register
static final int IntE_REG = 14; // Interrupt Enable Register
static final int IOANH_REG = 15; // Same as Register 1 (IOA), but no Handshake
private int outputRegisterB, inputRegisterB;
private int outputRegisterA, inputRegisterA;
private int dataDirectionB, dataDirectionA;
public Via6522(int address) throws MemoryRangeException {
super(address, address + VIA_SIZE - 1, "MOS 6522 VIA");
outputRegisterA = outputRegisterB = 0;
dataDirectionA = dataDirectionB = 0;
}
@Override
public void write(int address, int data) throws MemoryAccessException {
// TODO: Implement write.
switch (address) {
case IOB_REG -> outputRegisterB = data & 0xFF;
case IOA_REG -> outputRegisterA = data & 0xFF;
case DDRB_REG -> dataDirectionB = data & 0xFF;
case DDRA_REG -> dataDirectionA = data & 0xFF;
case IOANH_REG -> outputRegisterA = data & 0xFF;
default -> throw new MemoryAccessException("No Register or Not Implemented!");
}
}
@Override
public int read(int address, boolean cpuAccess) throws MemoryAccessException {
// TODO: Implement read.
return 0;
return switch (address) {
case IOB_REG -> pbRead();
case IOA_REG -> paRead();
case DDRB_REG -> dataDirectionB;
case DDRA_REG -> dataDirectionA;
case IOANH_REG -> paRead();
default -> throw new MemoryAccessException("No Register or Not Implemented!");
};
}
public void setInputRegisterB(int data) {
inputRegisterB = data & 0xFF;
}
public void setInputRegisterA(int data) {
inputRegisterA = data & 0xFF;
}
public String getPBStatus() {
return "%" + Utils.byteToBin(pbRead());
}
public String getPAStatus() {
return "%" + Utils.byteToBin(paRead());
}
private int pbRead() {
// Return bits of output register where DDRB is 1 and input register where DDRB is 0
return (outputRegisterB & dataDirectionB) | (inputRegisterB & ~dataDirectionB);
}
private int paRead() {
// Return bits of output register where DDRB is 1 and input register where DDRB is 0
return (outputRegisterA & dataDirectionA) | (inputRegisterA & ~dataDirectionA);
}
}
@@ -2,7 +2,6 @@ package com.loomcom.symon.machines;
import com.loomcom.symon.Bus;
import com.loomcom.symon.Cpu;
import com.loomcom.symon.InstructionTable;
import com.loomcom.symon.devices.*;
import com.loomcom.symon.exceptions.MemoryRangeException;
import org.slf4j.Logger;
@@ -26,12 +26,13 @@ package com.loomcom.symon.ui;
import com.formdev.flatlaf.util.UIScale;
import com.loomcom.symon.Cpu;
import com.loomcom.symon.CpuState;
import com.loomcom.symon.devices.Pia;
import com.loomcom.symon.devices.Via6522;
import com.loomcom.symon.machines.Machine;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.swing.plaf.metal.MetalTextFieldUI;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -71,6 +72,8 @@ public class StatusPanel extends JPanel {
private JTextField aField;
private JTextField xField;
private JTextField yField;
private JTextField piaBField;
private JTextField piaAField;
private final Machine machine;
@@ -153,6 +156,10 @@ public class StatusPanel extends JPanel {
JLabel xLabel = makeLabel("X");
JLabel yLabel = makeLabel("Y");
// PIA/VIA labels
JLabel piaBLabel = makeLabel("PB");
JLabel piaALabel = makeLabel("PA");
statusFlagsLabel.setToolTipText("6502 Processor Status Flags");
opcodeLabel.setToolTipText("Instruction Register");
pcLabel.setToolTipText("Program Counter");
@@ -165,6 +172,9 @@ public class StatusPanel extends JPanel {
xField = makeTextField(SMALL_TEXT_FIELD_SIZE, true);
yField = makeTextField(SMALL_TEXT_FIELD_SIZE, true);
piaBField = makeTextField(LARGE_TEXT_FIELD_SIZE, false);
piaAField = makeTextField(LARGE_TEXT_FIELD_SIZE, false);
// Make fields editable
pcField.addActionListener(new ActionListener() {
@Override
@@ -287,6 +297,25 @@ public class StatusPanel extends JPanel {
add(xField, constraints);
constraints.gridx = 1;
add(yField, constraints);
constraints.insets = new Insets(5, 0, 0, 0);
constraints.gridx = 0;
constraints.gridwidth = 2;
constraints.gridy = 10;
add(piaBLabel, constraints);
constraints.insets = new Insets(2, 2, 2, 2);
constraints.gridy = 11;
add(piaBField, constraints);
constraints.insets = new Insets(5, 0, 0, 0);
constraints.gridy = 12;
add(piaALabel, constraints);
constraints.insets = new Insets(2, 2, 2, 2);
constraints.gridy = 13;
add(piaAField, constraints);
}
/**
@@ -296,6 +325,8 @@ public class StatusPanel extends JPanel {
Cpu cpu = machine.getCpu();
CpuState cpuState = cpu.getCpuState();
Pia pia = machine.getPia();
// Update the Processor Status Flag display
int status = cpuState.getStatusFlag();
@@ -317,6 +348,12 @@ public class StatusPanel extends JPanel {
xField.setText(cpu.getXRegisterStatus());
yField.setText(cpu.getYRegisterStatus());
// Update the Pia Variables
if (pia instanceof Via6522) {
piaBField.setText(((Via6522) pia).getPBStatus());
piaAField.setText(((Via6522) pia).getPAStatus());
}
repaint();
}
+3 -1
View File
@@ -132,7 +132,9 @@ public final class Ui {
}
private static void applyDetectedUiScale() {
Double rawScale = X11ResourceReader.readXftDpiScale(); // ex: 1.5, 2.0, 2.5...
Double rawScale = null;
if (SystemInfo.isLinux) rawScale = X11ResourceReader.readXftDpiScale(); // ex: 1.5, 2.0, 2.5...
if (rawScale != null && rawScale > 1.0) {
// flatlaf.uiScale aceita frações — mantém a precisão original
@@ -76,6 +76,16 @@ public class Utils {
"F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7",
"F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF"};
private static final String[] BIN_CONSTANTS = new String[256];
static {
for (int i = 0; i < 256; i++) {
String bin = Integer.toBinaryString(i);
// Left-pad to 8 digits with zeros
BIN_CONSTANTS[i] = "00000000".substring(bin.length()) + bin;
}
}
/**
* Very fast 8-bit int to ASCII conversion.
*
@@ -116,4 +126,14 @@ public class Utils {
public static int address(int lowByte, int hiByte) {
return ((hiByte << 8) | lowByte) & 0xffff;
}
/**
* Very fast 8-bit int to binary conversion, with zero-padded output.
*
* @param val The unsigned 8-bit value to convert to a zero padded binary string.
* @return Eight digit, zero padded binary string.
*/
public static String byteToBin(int val) {
return BIN_CONSTANTS[val & 0xff];
}
}