Skip to content

Commit

Permalink
add asic regs, support CDD interrupt
Browse files Browse the repository at this point in the history
  • Loading branch information
Federico Berti committed Dec 19, 2023
1 parent fce50e1 commit 01714c3
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 28 deletions.
20 changes: 18 additions & 2 deletions src/main/java/omegadrive/bus/megacd/MegaCdDict.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class MegaCdDict {

public enum McdRegCpuType {REG_MAIN, REG_SUB, REG_BOTH}

public enum McdRegType {NONE, SYS, COMM, CD}
public enum McdRegType {NONE, SYS, COMM, CD, ASIC}

public static RegSpecMcd[][] mcdRegMapping = new RegSpecMcd[McdRegCpuType.values().length][MDC_SUB_GATE_REGS_MASK];

Expand All @@ -46,7 +46,7 @@ public enum McdRegType {NONE, SYS, COMM, CD}
public enum RegSpecMcd {
MCD_RESET(SYS, 0, 0x103, 0xFFFF), //Reset
MCD_MEM_MODE(SYS, 2, 0xFFC2, 0xFFFF), //Memory Mode, write protect
MCD_CDC_MODE(SYS, 4, 0, 0xFFFF), //CDC Mode, MAIN read-only
MCD_CDC_MODE(CD, 4, 0, 0xFFFF), //CDC Mode, MAIN read-only

MCD_HINT_VECTOR(SYS, 6, 0xFFFF, 0xFFFF), //CDC Mode, MAIN read-only

Expand Down Expand Up @@ -86,6 +86,21 @@ public enum RegSpecMcd {
MCD_FONT_DATA1(SYS, 0x52, 0, 0), //Font data
MCD_FONT_DATA2(SYS, 0x54, 0, 0), //Font data
MCD_FONT_DATA3(SYS, 0x56, 0, 0), //Font data

MCD_IMG_STAMP_SIZE(ASIC, 0x58, 0, 0x7), //Image Stamp Size

//TODO valid bits depend on setup
MCD_IMG_STAMP_MAP_ADDR(ASIC, 0x5A, 0, 0xFFE0), //Image Stamp map base address
MCD_IMG_VCELL(ASIC, 0x5C, 0, 0x1F), //Image buffer V cell size (0-32 cells)
MCD_IMG_START_ADDR(ASIC, 0x5E, 0, 0xFFF8), //Image buffer start address

MCD_IMG_OFFSET(ASIC, 0x60, 0, 0x3F), //Image buffer offset
MCD_IMG_HDOT(ASIC, 0x62, 0, 0x1FF), //Image buffer H dot size (horizontal dot size overwritten in the buffer)

MCD_IMG_VDOT(ASIC, 0x64, 0, 0xFF), //Image buffer V dot size (vertical dot size overwritten in the buffer)

MCD_IMG_TRACE_VECTOR_ADDR(ASIC, 0x66, 0, 0xFFFE),
//vector base address(Xstart, Ystart, (Dtita)X, <Del ta), table base address)
INVALID(NONE, -1);

public final RegSpec regSpec;
Expand Down Expand Up @@ -156,6 +171,7 @@ public static RegSpecMcd getRegSpec(CpuDeviceAccess cpu, int address) {
if (r == null) {
LOG.error("{} unknown register at address: {}", cpu, th(address));
r = RegSpecMcd.INVALID;
assert false;
}
}
return r;
Expand Down
5 changes: 1 addition & 4 deletions src/main/java/omegadrive/bus/megacd/MegaCdMainCpuBus.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,7 @@ private void handleMegaCdExpWrite(int address, int data, Size size) {
return;
}
switch (regSpec.deviceType) {
case SYS -> {
handleSysRegWrite(regSpec, address, data, size);
return;
}
case SYS -> handleSysRegWrite(regSpec, address, data, size);
case COMM -> handleCommWrite(regSpec, address, data, size);
default -> LOG.error("M illegal write MEGA_CD_EXP reg: {} ({}), {} {}", th(address), regSpec, data, size);
}
Expand Down
14 changes: 3 additions & 11 deletions src/main/java/omegadrive/bus/megacd/MegaCdMemoryContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import java.io.Serial;
import java.io.Serializable;

import static omegadrive.util.Util.th;
import static omegadrive.util.LogHelper.logWarnOnceSh;
import static s32x.util.S32xUtil.CpuDeviceAccess.M68K;
import static s32x.util.S32xUtil.CpuDeviceAccess.SUB_M68K;

Expand Down Expand Up @@ -65,15 +65,15 @@ public void writeWordRam(CpuDeviceAccess cpu, int address, int value, Size size)
if (cpu == wramSetup.cpu) {
writeWordRam(address & MCD_WORD_RAM_2M_MASK >> 17, address, value, size);
} else {
LOG.warn("{} writing WRAM but setup is: {}", cpu, wramSetup);
logWarnOnceSh(LOG, "{} writing WRAM but setup is: {}", cpu, wramSetup);
}
}

public int readWordRam(CpuDeviceAccess cpu, int address, Size size) {
if (cpu == wramSetup.cpu) {
return readWordRam(address & MCD_WORD_RAM_2M_MASK >> 17, address, size);
} else {
LOG.warn("{} reading WRAM but setup is: {}", cpu, wramSetup);
logWarnOnceSh(LOG, "{} reading WRAM but setup is: {}", cpu, wramSetup);
return size.getMask();
}
}
Expand Down Expand Up @@ -101,12 +101,4 @@ public WramSetup update(CpuDeviceAccess c, int reg2) {
}
return wramSetup;
}

public static void main(String[] args) {
int base = 0x600_000;
int start = base + MCD_WORD_RAM_1M_SIZE - 5;
for (int i = start; i < start + 10; i++) {
System.out.println(th(i) + "," + ((i & MCD_WORD_RAM_2M_MASK) >> 17));
}
}
}
36 changes: 25 additions & 11 deletions src/main/java/omegadrive/bus/megacd/MegaCdSubCpuBus.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package omegadrive.bus.megacd;

import omegadrive.bus.md.BusArbiter;
import omegadrive.bus.md.GenesisBus;
import omegadrive.cpu.m68k.M68kProvider;
import omegadrive.cpu.m68k.MC68000Wrapper;
Expand Down Expand Up @@ -38,6 +39,8 @@ public MegaCdSubCpuBus(MegaCdMemoryContext ctx) {
memCtx = ctx;
cpu = S32xUtil.CpuDeviceAccess.SUB_M68K;
writeBuffer(gateRegs, 1, 1, Size.BYTE); //not reset

attachDevice(BusArbiter.NO_OP);
}

@Override
Expand Down Expand Up @@ -142,12 +145,15 @@ private void handleSysRegWrite(MegaCdDict.RegSpecMcd regSpec, int address, int d
}

private void handleCdRegWrite(MegaCdDict.RegSpecMcd regSpec, int address, int data, Size size) {
LOG.warn("S Write CDD {} : {}, {}, {}", regSpec, th(address), th(data), size);
writeBuffer(gateRegs, address & SUB_CPU_REGS_MASK, data, size);
switch (regSpec) {
case MCD_CDD_CONTROL:
LOG.warn("S Write CDD control: {}, {}, {}", th(address), th(data), size);
break;
default:
LOG.error("S write unknown MEGA_CD_EXP reg: {} ({}), {} {}", th(address), regSpec, th(data), size);
case MCD_CDD_CONTROL -> {
int v = readBuffer(gateRegs, regSpec.addr, Size.WORD);
if (((v & 4) > 0) && checkInterruptEnabled(4)) { //HOCK set
m68kInterrupt(4); //trigger CDD interrupt
}
}
}
}

Expand Down Expand Up @@ -179,16 +185,24 @@ public void onVdpEvent(BaseVdpProvider.VdpEvent event, Object value) {
super.onVdpEvent(event, value);
if (event == BaseVdpAdapterEventSupport.VdpEvent.V_BLANK_CHANGE) {
boolean val = (boolean) value;
if (val) {
if ((Util.readBufferByte(gateRegs, 0x33) & 4) > 0) {
LOG.info("S VBlank On, int#2");
MC68000Wrapper m68k = (MC68000Wrapper) getBusDeviceIfAny(M68kProvider.class).get();
m68k.raiseInterrupt(2);
}
if (val && checkInterruptEnabled(2)) {
LOG.info("S VBlank On, int#2");
m68kInterrupt(2);
}
}
}

private boolean checkInterruptEnabled(int m68kLevel) {
int reg = Util.readBufferByte(gateRegs, 0x33);
if (reg == 0) return false;
return (reg & (m68kLevel << 1)) > 0;
}

private void m68kInterrupt(int num) {
MC68000Wrapper m68k = (MC68000Wrapper) getBusDeviceIfAny(M68kProvider.class).get();
m68k.raiseInterrupt(num);
}

public void logAccess(RegSpecMcd regSpec, S32xUtil.CpuDeviceAccess cpu, int address, int value, Size size, boolean read) {
logHelper.logWarnOnce(LOG, "{} MCD reg {} {} ({}) {} {}", cpu, read ? "read" : "write",
size, regSpec.getName(), th(address), !read ? ": " + th(value) : "");
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/omegadrive/util/LogHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public class LogHelper {

private RepeaterDetector rd = new RepeaterDetector();

private static Set<String> msgCacheShared = new HashSet<>();

public static Logger getLogger(String name) {
return LoggerFactory.getLogger(name);
}
Expand All @@ -30,6 +32,13 @@ public static String formatMessage(String s, Object... o) {
return MessageFormatter.arrayFormat(s, o).getMessage();
}

public static void logWarnOnceSh(Logger log, String str, Object... o) {
String msg = formatMessage(str, o);
if (msgCacheShared.add(msg)) {
log.warn(msg + " (ONCE)");
}
}

public void logWarnOnce(Logger log, String str, Object... o) {
String msg = formatMessage(str, o);
if (msgCache.add(msg)) {
Expand Down

0 comments on commit 01714c3

Please sign in to comment.