Skip to content

Commit

Permalink
helios: default to padding roms to a reasonable size
Browse files Browse the repository at this point in the history
  • Loading branch information
Federico Berti committed Apr 17, 2022
1 parent ec1e29f commit 2260df5
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 51 deletions.
12 changes: 4 additions & 8 deletions res/conf
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
#linux
sudo usermod -a -G audio <user>
sudo usermod -a -G pulse-rt <user>
sudo usermod -a -G jackuser <user>
sudo usermod -a -G pipewire <user>

#set Pulse latency
export PULSE_LATENCY_MSEC=50

#show current latency
pactl list sinks | grep Lat

run visudo
add: <user> ALL=NOPASSWD:/usr/bin/nice
start the process: nice -n -5 <cmdLine>

#see /etc/pulse/daemon.conf
default-fragments = 2
default-fragment-size-msec = 25
#
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
4 changes: 1 addition & 3 deletions src/main/java/omegadrive/cart/MdCartInfoProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
import java.util.Arrays;
import java.util.Optional;

import static omegadrive.util.Util.th;

public class MdCartInfoProvider extends CartridgeInfoProvider {

public static final int ROM_HEADER_START = 0x100;
Expand Down Expand Up @@ -89,7 +87,7 @@ protected void init() {
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(systemType + ", serial: " + serial);
sb.append(", ROM size: " + th(romSize) + ", ROM mask: " + th(memoryProvider.getRomMask()));
sb.append(", " + memoryProvider.getRomHolder().toString());
sb.append(", SRAM flag: " + sramEnabled).append("\n");
sb.append(super.toString());
if (sramEnabled) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
public class MC68000WrapperFastDebug extends MC68000Wrapper implements CpuFastDebug.CpuDebugInfoProvider {

private static final Logger LOG = LogManager.getLogger(MC68000WrapperFastDebug.class.getSimpleName());

//see CpuFastDebug.DebugMode
private static final int debugMode = Integer.parseInt(System.getProperty("helios.68k.debug.mode", "0"));

private CpuFastDebug fastDebug;
Expand Down Expand Up @@ -67,7 +69,6 @@ public int runInstruction() {

private void printDebugMaybe() {
currentPC = m68k.getPC(); //needs to be set
opcode = getOpcode();
fastDebug.printDebugMaybe();
}

Expand Down
15 changes: 15 additions & 0 deletions src/main/java/omegadrive/memory/IMemoryProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,24 @@

package omegadrive.memory;

import omegadrive.util.RomHolder;

public interface IMemoryProvider extends IMemoryRam, IMemoryRom {

void setChecksumRomValue(long value);

void setRomData(int[] data);

RomHolder getRomHolder();

@Override
default int[] getRomData() {
return getRomHolder().data;
}

@Override
default int getRomMask() {
return getRomHolder().romMask;
}

}
54 changes: 22 additions & 32 deletions src/main/java/omegadrive/memory/MemoryProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

package omegadrive.memory;

import omegadrive.util.RomHolder;
import omegadrive.util.Size;
import omegadrive.util.Util;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand All @@ -38,49 +40,45 @@ public class MemoryProvider implements IMemoryProvider {
public static final int SMS_Z80_RAM_SIZE = 0x2000;
public static final int CHECKSUM_START_ADDRESS = 0x18E;

private int[] rom;
private int[] ram;

private int romMask;
private int romSize;
private int ramSize = M68K_RAM_SIZE;

private RomHolder romHolder;

private MemoryProvider() {
}


public static IMemoryProvider createGenesisInstance() {
return createInstance(new int[1], M68K_RAM_SIZE);
return createInstance(RomHolder.EMPTY_ROM, M68K_RAM_SIZE);
}

public static IMemoryProvider createSg1000Instance() {
return createInstance(new int[1], SG1K_Z80_RAM_SIZE);
return createInstance(RomHolder.EMPTY_ROM, SG1K_Z80_RAM_SIZE);
}

public static IMemoryProvider createMsxInstance() {
return createInstance(new int[1], MSX_Z80_RAM_SIZE);
return createInstance(RomHolder.EMPTY_ROM, MSX_Z80_RAM_SIZE);
}

public static IMemoryProvider createSmsInstance() {
return createInstance(new int[1], SMS_Z80_RAM_SIZE);
return createInstance(RomHolder.EMPTY_ROM, SMS_Z80_RAM_SIZE);
}

public static IMemoryProvider createInstance(RomHolder romHolder, int ramSize) {
MemoryProvider m = new MemoryProvider();
m.romHolder = romHolder;
m.ram = Util.initMemoryRandomBytes(new int[ramSize]);
m.ramSize = ramSize;
return m;
}

public static IMemoryProvider createInstance(int[] rom, int ramSize) {
MemoryProvider memory = new MemoryProvider();
memory.setRomData(rom);
memory.ram = Util.initMemoryRandomBytes(new int[ramSize]);
memory.ramSize = ramSize;
return memory;
return createInstance(new RomHolder(rom), ramSize);
}

@Override
public int readRomByte(int address) {
if (address > romSize - 1) {
address &= romMask;
address = address > romSize - 1 ? address - (romSize) : address;
}
return rom[address];
return (int) Util.readDataMask(romHolder.data, Size.BYTE, address, romHolder.romMask);
}

@Override
Expand All @@ -103,21 +101,13 @@ public void writeRamByte(int address, int data) {

@Override
public void setRomData(int[] data) {
this.rom = data;
this.romSize = data.length;
this.romMask = Util.getRomMask(romSize);
this.romHolder = new RomHolder(data);
}

@Override
public void setChecksumRomValue(long value) {
this.rom[CHECKSUM_START_ADDRESS] = (byte) ((value >> 8) & 0xFF);
this.rom[CHECKSUM_START_ADDRESS + 1] = (byte) (value & 0xFF);
}


@Override
public int[] getRomData() {
return rom;
Util.writeDataMask(romHolder.data, Size.BYTE, CHECKSUM_START_ADDRESS, (byte) ((value >> 8) & 0xFF), romHolder.romMask);
Util.writeDataMask(romHolder.data, Size.BYTE, CHECKSUM_START_ADDRESS + 1, (byte) (value & 0xFF), romHolder.romMask);
}

@Override
Expand All @@ -126,8 +116,8 @@ public int[] getRamData() {
}

@Override
public int getRomMask() {
return romMask;
public RomHolder getRomHolder() {
return romHolder;
}

@Override
Expand Down
41 changes: 41 additions & 0 deletions src/main/java/omegadrive/util/RomHolder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package omegadrive.util;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import static omegadrive.util.Util.th;

/**
* Federico Berti
* <p>
* Copyright 2022
*/
public class RomHolder {

private final static Logger LOG = LogManager.getLogger(RomHolder.class.getSimpleName());

public static final RomHolder EMPTY_ROM = new RomHolder(new int[1]);

public int baseSize, size, romMask;
public int[] data;

public RomHolder(int[] rom) {
this.data = Util.getPaddedRom(rom);
this.size = data.length;
this.baseSize = rom.length;
this.romMask = Util.getRomMask(size);
assert romMask == size - 1;
if (baseSize != size) {
LOG.info(this::toString);
}
}

@Override
public String toString() {
return "RomHolder{" +
"romSize=" + th(baseSize) +
", paddedSize=" + th(size) +
", romMask=" + th(romMask) +
'}';
}
}
16 changes: 14 additions & 2 deletions src/main/java/omegadrive/util/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,12 @@ public static long readDataMask(int[] src, Size size, int address, final int mas
long data;
address &= mask;
if (size == Size.WORD) {
data = ((src[address] & 0xFF) << 8) | (src[address + 1] & 0xFF);
data = ((src[address] & 0xFF) << 8) | (src[(address + 1) & mask] & 0xFF);
} else if (size == Size.BYTE) {
data = src[address];
} else {
data = ((src[address] & 0xFF) << 24) |
((src[address + 1] & 0xFF) << 16) |
((src[(address + 1) & mask] & 0xFF) << 16) |
((src[(address + 2) & mask] & 0xFF) << 8) |
(src[(address + 3) & mask] & 0xFF);
}
Expand Down Expand Up @@ -342,6 +342,18 @@ public static String th(long pos) {
return Long.toHexString(pos);
}

public static int[] getPaddedRom(int[] data) {
int romSize = data.length;
int mask = getRomMask(romSize);
if (mask >= romSize) {
int[] newrom = new int[mask + 1];
Arrays.fill(newrom, 0xFF);
System.arraycopy(data, 0, newrom, 0, romSize);
return newrom;
}
return data;
}

public static int getRomMask(int size) {
int log2 = Util.log2(size);
int pow2 = (int) Math.pow(2, log2);
Expand Down
52 changes: 47 additions & 5 deletions src/test/java/omegadrive/util/RomMaskTest.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package omegadrive.util;

import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -26,10 +27,10 @@ public class RomMaskTest {
public static Path datFile;

// <size>:<mask>
private Map<Integer, Integer> maskMap;
private static Map<Integer, Integer> maskMap;

@Before
public void loadFile() {
@BeforeClass
public static void loadFile() {
datFile = resFolder.resolve(datFileName);
List<String> lines = FileUtil.readFileContent(datFile);
maskMap = new HashMap<>();
Expand All @@ -51,4 +52,45 @@ public void testRomMask() {
}
}
}
}

@Test
public void testRomPadding() {
int romVal = 0x22;
int padVal = 0xFF;
for (Map.Entry<Integer, Integer> entry : maskMap.entrySet()) {
int romSize = entry.getKey();
int mask = entry.getValue();
int[] baseRom = new int[romSize];
Arrays.fill(baseRom, romVal);
RomHolder h = new RomHolder(baseRom);
int[] rom = h.data;
int size = h.size;
boolean isPadded = size > romSize;
// System.out.println(th(entry.getKey()) + "," + th(entry.getValue()) + "," + th(size) + "," + isPadded);

int b1 = (int) Util.readDataMask(rom, Size.BYTE, size - 1, mask);
Assert.assertEquals(isPadded ? padVal : romVal, b1);
int b2 = (int) Util.readDataMask(rom, Size.BYTE, size, mask); //this maps to address 0
Assert.assertEquals(romVal, b2);
int w1 = (int) Util.readDataMask(rom, Size.WORD, size - 1, mask);
Assert.assertEquals(isPadded ? 0xFF22 : 0x2222, w1);
int w2 = (int) Util.readDataMask(rom, Size.WORD, size, mask);
Assert.assertEquals(0x2222, w2);
int ln = (int) Util.readDataMask(rom, Size.LONG, size, mask);
Assert.assertEquals(0x22222222, ln);
if (size - romSize <= 4) { //TODO corner case
continue;
}
int w3 = (int) Util.readDataMask(rom, Size.WORD, size - 2, mask);
Assert.assertEquals(isPadded ? 0xFFFF : 0x2222, w3);
int l0 = (int) Util.readDataMask(rom, Size.LONG, size - 4, mask);
Assert.assertEquals(isPadded ? 0xFFFFFFFF : 0x22222222, l0);
int l1 = (int) Util.readDataMask(rom, Size.LONG, size - 3, mask);
Assert.assertEquals(isPadded ? 0xFFFFFF22 : 0x22222222, l1);
int l2 = (int) Util.readDataMask(rom, Size.LONG, size - 2, mask);
Assert.assertEquals(isPadded ? 0xFFFF2222 : 0x22222222, l2);
int l3 = (int) Util.readDataMask(rom, Size.LONG, size - 1, mask);
Assert.assertEquals(isPadded ? 0xFF222222 : 0x22222222, l3);
}
}
}

0 comments on commit 2260df5

Please sign in to comment.