From 558af36cd55d0d20c5c4056829c0757e8aaeea69 Mon Sep 17 00:00:00 2001 From: Rui Barbosa Date: Sat, 26 Sep 2026 19:14:20 +0100 Subject: [PATCH] Start implementation of the VIA6522 Only PA and PB implemented, not tested --- .../com/loomcom/symon/devices/Via6522.java | 67 ++++++++++++++++++- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/loomcom/symon/devices/Via6522.java b/src/main/java/com/loomcom/symon/devices/Via6522.java index 5eb3e50..ed1e118 100644 --- a/src/main/java/com/loomcom/symon/devices/Via6522.java +++ b/src/main/java/com/loomcom/symon/devices/Via6522.java @@ -32,18 +32,79 @@ 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"); } @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(cpuAccess); + case IOA_REG -> paRead(cpuAccess); + case DDRB_REG -> dataDirectionB; + case DDRA_REG -> dataDirectionA; + case IOANH_REG -> paRead(cpuAccess); + 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 int getOutputRegisterB() { + return outputRegisterB; + } + + public int getOutputRegisterA() { + return outputRegisterA; + } + + private int pbRead(boolean cpuAccess) { + // Return bits of output register where DDRB is 1 and input register where DDRB is 0 + return (outputRegisterB & dataDirectionB) | (inputRegisterB & ~dataDirectionB); + } + + private int paRead(boolean cpuAccess) { + // Return bits of output register where DDRB is 1 and input register where DDRB is 0 + return (outputRegisterA & dataDirectionA) | (inputRegisterA & ~dataDirectionA); } }