Skip to content

Commit

Permalink
- Enable support for Memory Slot A & B in hypervisor.
Browse files Browse the repository at this point in the history
  • Loading branch information
Extrems committed Apr 14, 2024
1 parent a1f26e6 commit 09538fe
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 32 deletions.
8 changes: 4 additions & 4 deletions cube/patches/Makefile
Expand Up @@ -166,7 +166,7 @@ sd.eth.bin:
@$(CC) -Os $(OPTS) -c base/emulator.c -DASYNC_READ -DBBA -DETH_EMULATOR -DNO_VIDEO
@$(CC) -Os $(OPTS) -c base/emulator_eth.c
@$(CC) -Os $(OPTS) -c base/frag.c
@$(CC) -Os $(OPTS) -c base/interrupt.c -DIRQ_MASK=0b00000000001001001000000001000000
@$(CC) -Os $(OPTS) -c base/interrupt.c -DIRQ_MASK=0b00000000011011001000000001000000
@$(CC) -Os $(OPTS) -c base/ipl.c
@$(CC) -Os $(OPTS) -c base/blockdevice.c -DASYNC_READ
@$(CC) -Os $(OPTS) -c sdgecko/sd.c -DISR_READ=1 -DWRITE=0
Expand Down Expand Up @@ -255,7 +255,7 @@ ideexi-v1.eth.bin:
@$(CC) -Os $(OPTS) -c base/emulator.c -DASYNC_READ -DBBA -DETH_EMULATOR -DNO_VIDEO
@$(CC) -Os $(OPTS) -c base/emulator_eth.c
@$(CC) -Os $(OPTS) -c base/frag.c
@$(CC) -Os $(OPTS) -c base/interrupt.c -DIRQ_MASK=0b00000000001001000000000001000000
@$(CC) -Os $(OPTS) -c base/interrupt.c -DIRQ_MASK=0b00000000011011000000000001000000
@$(CC) -Os $(OPTS) -c base/ipl.c
@$(CC) -Os $(OPTS) -c base/blockdevice.c -DASYNC_READ
@$(CC) -Os $(OPTS) -c ide-exi/ata.c -DDMA_READ=0 -DISR_READ=1 -DWRITE=0
Expand Down Expand Up @@ -344,7 +344,7 @@ ideexi-v2.eth.bin:
@$(CC) -Os $(OPTS) -c base/emulator.c -DASYNC_READ -DBBA -DETH_EMULATOR -DNO_VIDEO
@$(CC) -Os $(OPTS) -c base/emulator_eth.c
@$(CC) -Os $(OPTS) -c base/frag.c
@$(CC) -Os $(OPTS) -c base/interrupt.c -DIRQ_MASK=0b00000000001001000000000001000000
@$(CC) -Os $(OPTS) -c base/interrupt.c -DIRQ_MASK=0b00000000011011000000000001000000
@$(CC) -Os $(OPTS) -c base/ipl.c
@$(CC) -Os $(OPTS) -c base/blockdevice.c -DASYNC_READ
@$(CC) -Os $(OPTS) -c ide-exi/ata.c -DDMA_READ=1 -DISR_READ=1 -DWRITE=0
Expand Down Expand Up @@ -658,7 +658,7 @@ gcloader-v2.eth.bin:
@$(CC) -Os $(OPTS) -c base/emulator.c -DASYNC_READ -DBBA -DETH_EMULATOR -DGCODE -DNO_VIDEO
@$(CC) -Os $(OPTS) -c base/emulator_eth.c
@$(CC) -Os $(OPTS) -c base/frag.c -DDEVICE_PATCHES=1
@$(CC) -Os $(OPTS) -c base/interrupt.c -DIRQ_MASK=0b00000000000000000000010001000000
@$(CC) -Os $(OPTS) -c base/interrupt.c -DIRQ_MASK=0b00000000010010000000010001000000
@$(CC) -Os $(OPTS) -c base/ipl.c
@$(CC) -Os $(OPTS) -c gcloader/gcloader.c
@$(CC) -Os $(OPTS) -c bba/enc28j60.c
Expand Down
68 changes: 45 additions & 23 deletions cube/patches/bba/enc28j60.c
Expand Up @@ -29,50 +29,57 @@
#include "enc28j60.h"
#include "interrupt.h"

#define exi_regs (*(volatile uint32_t **)VAR_EXI2_REGS)

static struct {
uint8_t bank;
bba_page_t (*page)[8];
} _bba;

static void exi_clear_interrupts(bool exi, bool tc, bool ext)
{
exi_regs[0] = (exi_regs[0] & (0x3FFF & ~0x80A)) | (ext << 11) | (tc << 3) | (exi << 1);
}

static void exi_select(void)
{
EXI[EXI_CHANNEL_2][0] = (EXI[EXI_CHANNEL_2][0] & 0x405) | ((1 << EXI_DEVICE_0) << 7) | (EXI_SPEED_32MHZ << 4);
exi_regs[0] = (exi_regs[0] & 0x405) | ((1 << EXI_DEVICE_0) << 7) | (EXI_SPEED_32MHZ << 4);
}

static void exi_deselect(void)
{
EXI[EXI_CHANNEL_2][0] &= 0x405;
exi_regs[0] &= 0x405;
}

static uint32_t exi_imm_read(uint32_t len)
{
EXI[EXI_CHANNEL_2][3] = ((len - 1) << 4) | (EXI_READ << 2) | 0b01;
while (EXI[EXI_CHANNEL_2][3] & 0b01);
return EXI[EXI_CHANNEL_2][4] >> ((4 - len) * 8);
exi_regs[3] = ((len - 1) << 4) | (EXI_READ << 2) | 0b01;
while (exi_regs[3] & 0b01);
return exi_regs[4] >> ((4 - len) * 8);
}

static uint32_t exi_imm_read_write(uint32_t data, uint32_t len)
{
EXI[EXI_CHANNEL_2][4] = data;
EXI[EXI_CHANNEL_2][3] = ((len - 1) << 4) | (EXI_READ_WRITE << 2) | 0b01;
while (EXI[EXI_CHANNEL_2][3] & 0b01);
return EXI[EXI_CHANNEL_2][4] >> ((4 - len) * 8);
exi_regs[4] = data;
exi_regs[3] = ((len - 1) << 4) | (EXI_READ_WRITE << 2) | 0b01;
while (exi_regs[3] & 0b01);
return exi_regs[4] >> ((4 - len) * 8);
}

static void exi_dma_write(const void *buf, uint32_t len, bool sync)
{
EXI[EXI_CHANNEL_2][1] = (uint32_t)buf;
EXI[EXI_CHANNEL_2][2] = OSRoundUp32B(len);
EXI[EXI_CHANNEL_2][3] = (EXI_WRITE << 2) | 0b11;
while (sync && (EXI[EXI_CHANNEL_2][3] & 0b01));
exi_regs[1] = (uint32_t)buf;
exi_regs[2] = OSRoundUp32B(len);
exi_regs[3] = (EXI_WRITE << 2) | 0b11;
while (sync && (exi_regs[3] & 0b01));
}

static void exi_dma_read(void *buf, uint32_t len, bool sync)
{
EXI[EXI_CHANNEL_2][1] = (uint32_t)buf;
EXI[EXI_CHANNEL_2][2] = OSRoundUp32B(len);
EXI[EXI_CHANNEL_2][3] = (EXI_READ << 2) | 0b11;
while (sync && (EXI[EXI_CHANNEL_2][3] & 0b01));
exi_regs[1] = (uint32_t)buf;
exi_regs[2] = OSRoundUp32B(len);
exi_regs[3] = (EXI_READ << 2) | 0b11;
while (sync && (exi_regs[3] & 0b01));
}

static uint8_t enc28j60_read_cmd(uint32_t cmd)
Expand Down Expand Up @@ -168,18 +175,25 @@ static void enc28j60_interrupt(void)
enc28j60_set_bits(ENC28J60_EIE, ENC28J60_EIE_INTIE);
}

static void exi_callback()
static void exi_callback(int32_t chan, OSContext *context)
{
if (EXILock(EXI_CHANNEL_2, EXI_DEVICE_0, exi_callback)) {
if (EXILock(chan, EXI_DEVICE_0, exi_callback)) {
enc28j60_interrupt();
EXIUnlock(EXI_CHANNEL_2);
EXIUnlock(chan);
}
}

static void exi_interrupt_handler(OSInterrupt interrupt, OSContext *context)
{
int32_t chan = (interrupt - OS_INTERRUPT_EXI_0_EXI) / 3;
exi_clear_interrupts(true, false, false);
exi_callback(chan, context);
}

static void debug_interrupt_handler(OSInterrupt interrupt, OSContext *context)
{
PI[0] = 1 << 12;
exi_callback();
exi_callback(EXI_CHANNEL_2, context);
}

void bba_transmit_fifo(const void *data, size_t size)
Expand All @@ -204,6 +218,14 @@ void bba_init(void **arenaLo, void **arenaHi)
{
*arenaHi -= sizeof(*_bba.page); _bba.page = *arenaHi;

set_interrupt_handler(OS_INTERRUPT_PI_DEBUG, debug_interrupt_handler);
unmask_interrupts(OS_INTERRUPTMASK_PI_DEBUG);
int32_t chan = ((uintptr_t)exi_regs & 0x3C) / 0x14;

if (chan < EXI_CHANNEL_2) {
OSInterrupt interrupt = OS_INTERRUPT_EXI_0_EXI + (3 * chan);
set_interrupt_handler(interrupt, exi_interrupt_handler);
unmask_interrupts(OS_INTERRUPTMASK(interrupt) & (OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_1_EXI));
} else {
set_interrupt_handler(OS_INTERRUPT_PI_DEBUG, debug_interrupt_handler);
unmask_interrupts(OS_INTERRUPTMASK_PI_DEBUG);
}
}
9 changes: 6 additions & 3 deletions cube/reservedarea.h
Expand Up @@ -28,14 +28,16 @@
.set VAR_FRAG_LIST, 0x09BC # pointer to fragments (u32 offset, u32 size, u32 rawsector)

.set VAR_DISC_1_ID, 0x09CC # disc 1 header
.set VAR_DISC_2_ID, 0x09D6 # disc 2 header
.set VAR_DISC_2_ID, 0x09D4 # disc 2 header

.set VAR_CLIENT_MAC, 0x09C0 # client MAC address
.set VAR_ROUTER_MAC, 0x09C6 # router MAC address
.set VAR_CLIENT_IP, 0x09CC # client IPv4 address
.set VAR_ROUTER_IP, 0x09D0 # router IPv4 address
.set VAR_SERVER_IP, 0x09D4 # server IPv4 address
.set VAR_SERVER_PORT, 0x09D8 # server UDP port
.set VAR_SERVER_PMTU, 0x09DA # server MTU
.set VAR_EXI2_REGS, 0x09DC # pointer to EXI2 registers

.set VAR_FLOAT1_6, 0x09E0 # constant 1/6
.set VAR_FLOAT9_16, 0x09E4 # constant 9/16
Expand Down Expand Up @@ -87,8 +89,8 @@ extern char VAR_ATA_LBA48[1]; // Is the HDD in use a 48 bit LBA supported HDD?
extern char VAR_IGR_TYPE[1]; // IGR exit type
extern char VAR_FRAG_LIST[4]; // pointer to fragments (u32 offset, u32 size, u32 rawsector)

extern char VAR_DISC_1_ID[10]; // disc 1 header
extern char VAR_DISC_2_ID[10]; // disc 2 header
extern char VAR_DISC_1_ID[8]; // disc 1 header
extern char VAR_DISC_2_ID[8]; // disc 2 header

extern char VAR_NETWORK_ENV[0x20]; // network environment variables
extern char VAR_CLIENT_MAC[6]; // client MAC address
Expand All @@ -98,6 +100,7 @@ extern char VAR_ROUTER_IP[4]; // router IPv4 address
extern char VAR_SERVER_IP[4]; // server IPv4 address
extern char VAR_SERVER_PORT[2]; // server UDP port
extern char VAR_SERVER_PMTU[2]; // server MTU
extern char VAR_EXI2_REGS[4]; // pointer to EXI2 registers

extern char VAR_FLOAT1_6[4]; // constant 1/6
extern char VAR_FLOAT9_16[4]; // constant 9/16
Expand Down
3 changes: 2 additions & 1 deletion cube/reservedarea.ld
Expand Up @@ -14,7 +14,7 @@ VAR_IGR_TYPE = VAR_AREA + 0x09BB; /* IGR exit type */
VAR_FRAG_LIST = VAR_AREA + 0x09BC; /* pointer to fragments (u32 offset, u32 size, u32 rawsector) */

VAR_DISC_1_ID = VAR_AREA + 0x09CC; /* disc 1 header */
VAR_DISC_2_ID = VAR_AREA + 0x09D6; /* disc 2 header */
VAR_DISC_2_ID = VAR_AREA + 0x09D4; /* disc 2 header */

VAR_NETWORK_ENV = VAR_AREA + 0x09C0; /* network environment variables */
VAR_CLIENT_MAC = VAR_AREA + 0x09C0; /* client MAC address */
Expand All @@ -24,6 +24,7 @@ VAR_ROUTER_IP = VAR_AREA + 0x09D0; /* router IPv4 address */
VAR_SERVER_IP = VAR_AREA + 0x09D4; /* server IPv4 address */
VAR_SERVER_PORT = VAR_AREA + 0x09D8; /* server UDP port */
VAR_SERVER_PMTU = VAR_AREA + 0x09DA; /* server MTU */
VAR_EXI2_REGS = VAR_AREA + 0x09DC; /* pointer to EXI2 registers */

VAR_FLOAT1_6 = VAR_AREA + 0x09E0; /* constant 1/6 */
VAR_FLOAT9_16 = VAR_AREA + 0x09E4; /* constant 9/16 */
Expand Down
4 changes: 3 additions & 1 deletion cube/swiss/source/bba.c
Expand Up @@ -34,7 +34,9 @@ void init_network(void *args) {
net_initialized = 0;
}

if(if_nametoindex("E20") == 1) {
if(if_nametoindex("E20") == 1
|| if_nametoindex("EA0") == 1
|| if_nametoindex("EB0") == 1) {
if(__device_gcloader.features & FEAT_PATCHES)
__device_gcloader.emulable |= EMU_ETHERNET;
__device_ata_c.emulable |= EMU_ETHERNET;
Expand Down
8 changes: 8 additions & 0 deletions cube/swiss/source/devices/deviceHandler.c
Expand Up @@ -125,6 +125,14 @@ bool getExiDeviceByLocation(u32 location, s32 *chan, s32 *dev) {
return false;
}

vu32* getExiRegsByLocation(u32 location) {
s32 chan;
if(getExiDeviceByLocation(location, &chan, NULL)) {
return ((vu32(*)[5])0xCC006800)[chan];
}
return NULL;
}

const char* getHwNameByLocation(u32 location) {
DEVICEHANDLER_INTERFACE *device = getDeviceByLocation(location);
if(device != NULL) {
Expand Down
1 change: 1 addition & 0 deletions cube/swiss/source/devices/deviceHandler.h
Expand Up @@ -233,6 +233,7 @@ extern DEVICEHANDLER_INTERFACE* getDeviceByUniqueId(u8 id);
extern DEVICEHANDLER_INTERFACE* getDeviceByLocation(u32 location);
extern DEVICEHANDLER_INTERFACE* getDeviceFromPath(char *path);
extern bool getExiDeviceByLocation(u32 location, s32 *chan, s32 *dev);
extern vu32* getExiRegsByLocation(u32 location);
extern const char* getHwNameByLocation(u32 location);

#define MAX_FRAGS 40
Expand Down
1 change: 1 addition & 0 deletions cube/swiss/source/swiss.c
Expand Up @@ -2139,6 +2139,7 @@ void load_game() {
*(vu8*)VAR_IGR_TYPE = swissSettings.igrType | (tgcFile.magic == TGC_MAGIC ? 0x80:0x00);
*(vu32**)VAR_FRAG_LIST = NULL;
net_get_mac_address(VAR_CLIENT_MAC);
*(vu32**)VAR_EXI2_REGS = getExiRegsByLocation(__device_fsp.location);
*(vu8*)VAR_TRIGGER_LEVEL = swissSettings.triggerLevel;
*(vu8*)VAR_CARD_A_ID = 0x00;
*(vu8*)VAR_CARD_B_ID = 0x00;
Expand Down

0 comments on commit 09538fe

Please sign in to comment.