diff --git a/cube/patches/Makefile b/cube/patches/Makefile index b84ebd66..1a15188d 100644 --- a/cube/patches/Makefile +++ b/cube/patches/Makefile @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/cube/patches/bba/enc28j60.c b/cube/patches/bba/enc28j60.c index 6a13d484..3140561f 100644 --- a/cube/patches/bba/enc28j60.c +++ b/cube/patches/bba/enc28j60.c @@ -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) @@ -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) @@ -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); + } } diff --git a/cube/reservedarea.h b/cube/reservedarea.h index 6abe36d1..97f48352 100644 --- a/cube/reservedarea.h +++ b/cube/reservedarea.h @@ -28,7 +28,7 @@ .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 @@ -36,6 +36,8 @@ .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 @@ -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 @@ -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 diff --git a/cube/reservedarea.ld b/cube/reservedarea.ld index 8c982f8e..def4ed28 100644 --- a/cube/reservedarea.ld +++ b/cube/reservedarea.ld @@ -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 */ @@ -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 */ diff --git a/cube/swiss/source/bba.c b/cube/swiss/source/bba.c index 231b80ab..46059dc7 100644 --- a/cube/swiss/source/bba.c +++ b/cube/swiss/source/bba.c @@ -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; diff --git a/cube/swiss/source/devices/deviceHandler.c b/cube/swiss/source/devices/deviceHandler.c index 7b39ad88..3b4f7314 100644 --- a/cube/swiss/source/devices/deviceHandler.c +++ b/cube/swiss/source/devices/deviceHandler.c @@ -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) { diff --git a/cube/swiss/source/devices/deviceHandler.h b/cube/swiss/source/devices/deviceHandler.h index 32c9be60..a53527ba 100644 --- a/cube/swiss/source/devices/deviceHandler.h +++ b/cube/swiss/source/devices/deviceHandler.h @@ -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 diff --git a/cube/swiss/source/swiss.c b/cube/swiss/source/swiss.c index 099b9408..e22a67c8 100644 --- a/cube/swiss/source/swiss.c +++ b/cube/swiss/source/swiss.c @@ -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;