diff --git a/BIOS/ee/kernel/hw.h b/BIOS/ee/kernel/hw.h new file mode 100644 index 0000000..61b46bf --- /dev/null +++ b/BIOS/ee/kernel/hw.h @@ -0,0 +1,72 @@ +#pragma once + +#include + +typedef volatile uint32_t vu32; +typedef volatile uint64_t vu64; + +#define GIF_CTRL (*(vu32*)0x10003000) +#define GIF_STAT (*(vu32*)0x10003020) +#define GIF_FIFO0 (*(vu32*)0x10006000) +#define GIF_FIFO1 (*(vu32*)0x10006004) +#define GIF_FIFO2 (*(vu32*)0x10006008) +#define GIF_FIFO3 (*(vu32*)0x1000600C) + +#define DMAC_CTRL (*(vu32*)0x1000e000) +#define DMAC_STAT (*(vu32*)0x1000e010) +#define DMAC_PCR (*(vu32*)0x1000e020) +#define DMAC_SQWC (*(vu32*)0x1000e030) +#define DMAC_RBSR (*(vu32*)0x1000e040) +#define DMAC_RBOR (*(vu32*)0x1000e050) + +#define GS_SMODE1 (*(vu64*)0x12000010) +#define GS_SYNCH1 (*(vu64*)0x12000040) +#define GS_SYNCH2 (*(vu64*)0x12000050) +#define GS_SYNCV (*(vu64*)0x12000060) +#define GS_SMODE2 (*(vu64*)0x12000020) +#define GS_SRFSH (*(vu64*)0x12000030) + +#define INTC_STAT (*(vu32*)0xB000F000) +#define INTC_MASK (*(vu32*)0xB000F010) + +#define TIMER0_COUNT (*(vu32*)0x10000000) +#define TIMER0_MODE (*(vu32*)0x10000010) +#define TIMER0_COMP (*(vu32*)0x10000020) +#define TIMER0_HOLD (*(vu32*)0x10000030) + +#define TIMER1_COUNT (*(vu32*)0x10000800) +#define TIMER1_MODE (*(vu32*)0x10000810) +#define TIMER1_COMP (*(vu32*)0x10000820) +#define TIMER1_HOLD (*(vu32*)0x10000830) + +#define TIMER2_COUNT (*(vu32*)0x10001000) +#define TIMER2_MODE (*(vu32*)0x10001010) +#define TIMER2_COMP (*(vu32*)0x10001020) +#define TIMER2_HOLD (*(vu32*)0x10001030) + +#define TIMER3_COUNT (*(vu32*)0x10018000) +#define TIMER3_MODE (*(vu32*)0x10018010) +#define TIMER3_COMP (*(vu32*)0x10018020) +#define TIMER3_HOLD (*(vu32*)0x10018030) + +#define VU1_CODE ((vu32*)0x11008000) +#define VU1_DATA ((vu32*)0x1100c000) + +#define VIF1_STAT (*(vu32*)0x10003c00) +#define VIF1_FBRST (*(vu32*)0x10003c10) +#define VIF1_FIFO0 (*(vu32*)0x10005000) +#define VIF1_FIFO1 (*(vu32*)0x10005004) +#define VIF1_FIFO2 (*(vu32*)0x10005008) +#define VIF1_FIFO3 (*(vu32*)0x1000500C) + +#define VIF0_FBRST (*(vu32*)0x10003810) +#define VIF0_ERR (*(vu32*)0x10003820) +#define VIF0_MARK (*(vu32*)0x10003830) +#define VIF0_FIFO0 (*(vu32*)0x10004000) +#define VIF0_FIFO1 (*(vu32*)0x10004004) +#define VIF0_FIFO2 (*(vu32*)0x10004008) +#define VIF0_FIFO3 (*(vu32*)0x1000400C) + +#define GS_CSR (*(vu32*)0x12001000) + +#define GS_MODE_NTSC 0x02 \ No newline at end of file diff --git a/BIOS/ee/kernel/kernel_start.c b/BIOS/ee/kernel/kernel_start.c new file mode 100644 index 0000000..020adda --- /dev/null +++ b/BIOS/ee/kernel/kernel_start.c @@ -0,0 +1,516 @@ +#include +#include +#include "hw.h" +#include "reset.h" +#include "vif1.h" + +// TODO: Split this into multiple files to clean up a bit + +// TODO: This sets up a bunch of virtual -> physical mappings +long InitTLB() +{ + int kernelBitPos = 0xD + 0x12; + printf("# TLB spad=0 kernel=1:%d default=%d:%d extended=%d:%d\n", kernelBitPos-1, kernelBitPos, kernelBitPos+0x7); +} + +void ClearInterrupt(int index) +{ + // Clear all pending interrupts + index, except SBUS and Timer 3 interrupts + INTC_MASK = INTC_MASK & index & 0xdffd; + INTC_STAT = INTC_STAT & index & 0xdffd; +} + +uint32_t GsInitRegList[] = +{ + 0x1A, + 0x1B, + 0x0A, + 0x01, + 0x02, + 0x03, + 0x18, + 0x19, + 0x22, + 0x06, + 0x07, + 0x14, + 0x15, + 0x16, + 0x17, + 0x1C, + 0x34, + 0x35, + 0x36, + 0x37, + 0x3B, + 0x08, + 0x09, + 0x3D, + 0x40, + 0x41, + 0x47, + 0x48, + 0x42, + 0x43, + 0x49, + 0x44 +}; + +void InitGS() +{ + // Reset GIF bit + GIF_CTRL = 1; + // Reset GS bit + GS_CSR = 0x200; + + + // GIF Tag settings: + // NLOOP: 0x2c + // EOP: 1 + // PRIM enable: 0 + // PRIM data: 0 + // Data format: PACKED + // NREGS: 1 + // Reg list: A+D + GIF_FIFO0 = 0x802c; + GIF_FIFO1 = 0x10000000; + GIF_FIFO2 = 0xe; + GIF_FIFO3 = 0; + + int listIndex = 0; + + int j = 0; + for (int i = 0; i < 11; i++) + { + uint32_t* curRegListSlice = &GsInitRegList[i]; + j = 3; + for (; j >= 0; j--) + { + // Register field + // First 64 bits are the register data + // Last 64 bits are the register + // This is technically a 128-bit store + GIF_FIFO0 = 0; + GIF_FIFO1 = 0; + GIF_FIFO2 = *curRegListSlice; + GIF_FIFO3 = 0; + curRegListSlice++; + } + // Wait for the GIF to finish processing this data + // Read the GIF FIFO count and wait for it to be 0 + while ((GIF_STAT & 0x1f000000) != 0) + ; + j = i * 0x10; + } + + // Ack any GS interrupts + ClearInterrupt(1); +} + +uint64_t GS_Settings = 0x90B27D0000000000ULL; + +void SetGsCrt(int interlaced, int display_mode, int frame) +{ + if (display_mode == 0) + { + display_mode = 2; + if ((((GS_Settings << 0x1d) >> 32) & 7) == 2) + display_mode = 3; + } + + int delay = 9999; + do + { + delay--; + } while (delay >= 0); + + if (display_mode == 2) + { + if (interlaced == 0) + { + unsigned int VHP = (((GS_Settings << 0x1f) >> 0x20 & 1) << 0x24); + unsigned int GCONT = (GS_Settings & 1) << 0x19; + GS_SMODE1 = GCONT | VHP | 0x740834504; + // Horizontal front porch: 64 + // Horizontal back porch: 222 + // HSEQ: 124 + // HSVS: 1462 + // HS: 254 + GS_SYNCH1 = 0x7f5b61f06f040; + // HB: 1652 + // HF: 1240 + GS_SYNCH2 = 0x33a4d8; + // Vertical front porch: two halflines + // Vertical front porch, no color burst: 6 halflines + // Vertical back porch, color burst: 13 halflines + // Vertical back porch, no color burst: 3 halflines + // Half lines with video data: 240 + // Half lines with VSYNC: 3 + GS_SYNCV = 0xc7800601a01802; + // Non-interlaced, field mode, power mode = 0 = ON + GS_SMODE2 = 0; + // Undocumented and unknown + GS_SRFSH = 8; + GS_SMODE1 = GCONT | 0x740814504; + return; + } + } +} + +int CheckAndSetINTMask(int index) +{ + int bit = 1 << (index & 0x1f); + int ret = (INTC_MASK & bit) == 0; + if (!ret) + bit = INTC_MASK; + INTC_MASK = bit; + return ret; +} + +void InitTimers() +{ + // Bus clock, gate disabled, do not clear counter, timer disabled, interrupts disabled, clear interrupts + TIMER0_MODE = 0xc00; + // Reset counter + TIMER0_COUNT = 0; + // Trigger interrupt just before overflow + TIMER0_COMP = 0xffff; + TIMER0_HOLD = 0; + + TIMER1_MODE = 0xc00; + TIMER1_COUNT = 0; + TIMER1_COMP = 0xffff; + TIMER1_HOLD = 0; + + TIMER2_MODE = 0xc00; + TIMER2_COUNT = 0; + TIMER2_COMP = 0xffff; + TIMER2_HOLD = 0; + + TIMER3_MODE = 0xc00; + TIMER3_COUNT = 0; + TIMER3_COMP = 0xffff; + TIMER3_HOLD = 0; + + // Clear pending timer interrupts + ClearInterrupt(0x1e00); + // Unmask timer interrupts + CheckAndSetINTMask(0xc); +} + +uint32_t ChannelAddrList[] = +{ + 0xB0008000, 0xB0009000, 0xB000A000, 0xB000B000, + 0xB000B400, 0xB000C000, 0xB000C400, 0xB000C800, + 0xB000D000, 0xB000D400 +}; + +void ResetDMAC(int channel_mask) +{ + for (int i = 0; i < 11; i++) + { + int channelBit = i & 0x1f; + if ((channel_mask >> channelBit) & 1) + { + uint32_t* addr = ChannelAddrList[i]; + addr[0x20] = 0; + addr[0x00] = 0; + addr[0x0C] = 0; + addr[0x04] = 0; + addr[0x14] = 0; + addr[0x10] = 0; + } + } + + // Clear all newly initialized channel's interrupts + // Also clear DMA stall, MFIFO empty, and BUSERR interrupts + DMAC_STAT = channel_mask & 0xffff | 0xe000; + int stat = DMAC_STAT; + // If interrupts are enabled, disable them + // + DMAC_STAT = stat & 0xffff0000 & (channel_mask | 0x6000); + // If all channels are being reset and bits 5 & 6 are set, then also reset CTRL and PCR + if ((channel_mask & 0x7f) == 0x7f) + { + DMAC_CTRL = 0; + DMAC_PCR = 0; + } + else + { + // Enable DMA, and set all newly enabled channels to priority 0 + DMAC_CTRL = 1; + int pcr = DMAC_PCR; + DMAC_PCR = pcr & (~channel_mask << 16 | ~channel_mask); + } + + DMAC_SQWC = 0; + DMAC_RBSR = 0; + DMAC_RBOR = 0; +} + +void ClearVU0MemWord(int offs) +{ + // Write offs to VI1 + // Store VI0 to VI1 + // Restore VI1 +} + +void ClearVU0Mem128(int offs) +{ + // Save VI1 + // Save VF1 + // Zero out VF1 + // Set VI1 to offs + // Zero 128-bits of memory at VI1 + // Restore VI1 + // Restore VF1 +} + +void ResetVU1() +{ + // Here, control VI12 has bit 0x200 set in VU0 + for (int i = 1; i < 0x10; i++) + { + ClearVU0MemWord(0x420 + i); + } + + ClearVU0MemWord(0x434); + ClearVU0MemWord(0x435); + ClearVU0MemWord(0x436); + ClearVU0MemWord(0x437); + + for (int i = 1; i < 0x20; i++) + { + ClearVU0Mem128(0x400 + i); + } + + // Clear VU1 data memory + for (int i = 0x3ff; i >= 0; i--) + { + VU1_DATA[i+0] = 0; + VU1_DATA[i+1] = 0; + VU1_DATA[i+2] = 0; + VU1_DATA[i+3] = 0; + } + + // Clear VU1 instruction memory + uint64_t* memPtr = VU1_CODE; + for (int i = 0x7ff; i >= 0; i--) + { + // Upper instruction: nop, lower instruction: ilw vi0, vi0(0x2FF) + *memPtr = 0x8000033c080002ff; + memPtr++; + } + + // Clear VU1 interrupts + ClearInterrupt(0x80); +} + +void ResetVIF1() +{ + // Reset VIF1 + VIF1_FBRST = 1; + VIF1_STAT = 0; + // Initialize VIF1 registers + VIF1_FIFO0 = VIF_STCYCL(4, 4); + VIF1_FIFO1 = VIF_STMOD(0); + VIF1_FIFO2 = VIF_MSKPATH3(0); + VIF1_FIFO3 = VIF_MARK(0); + + VIF1_FIFO0 = VIF_BASE(0); + VIF1_FIFO1 = VIF_OFFSET(0); + VIF1_FIFO2 = VIF_ITOP(0); + VIF1_FIFO3 = VIF_NOP; + + VIF1_FIFO0 = VIF_OFFSET(0); + VIF1_FIFO1 = VIF_NOP; + VIF1_FIFO2 = VIF_BASE(0); + VIF1_FIFO3 = VIF_NOP; + + VIF1_FIFO0 = VIF_NOP; + VIF1_FIFO1 = VIF_NOP; + VIF1_FIFO2 = VIF_NOP; + VIF1_FIFO3 = VIF_STCOL; + + VIF1_FIFO0 = VIF_NOP; + VIF1_FIFO1 = VIF_NOP; + VIF1_FIFO2 = VIF_NOP; + VIF1_FIFO3 = VIF_NOP; + + // Acknowledge VIF1 interrupts + ClearInterrupt(0x20); +} + +void ResetGIF() +{ + // Reset GIF + GIF_CTRL = 1; + // Clear GIF FIFO + GIF_FIFO0 = 0; + GIF_FIFO1 = 0; + GIF_FIFO2 = 0; + GIF_FIFO3 = 0; +} + +void ResetVU0Watchdog() +{ + *(vu32*)0x1000F510 = 0; + ClearInterrupt(0x4000); +} + +void ClearVU0Mem() +{ + vu32* data = (vu32*)0x11000000; + vu32* code = (vu32*)0x11004000; + + for (int i = 0xff; i >= 0; i--) + { + data[0] = 0; + data[1] = 0; + data[2] = 0; + data[3] = 0; + code[0] = 0; + code[1] = 0; + code[2] = 0; + code[3] = 0; + } +} + +void ResetVU0Registers() +{ + // vsub vf0..31, vf0, vf0 + // viadd vi0..31, vi0, vi0 + // ctc2 zero,vc0 + // ctc2 zero,vc2 + // ctc2 zero,vc4 + // ctc2 zero,vc5 + // ctc2 zero,vc6 + // ctc2 zero,vc11 +} + +void ResetVU0() +{ + ResetVU0Watchdog(); + ClearVU0Mem(); + ResetVU0Registers(); + ClearInterrupt(0x40); +} + +void ResetVIF0() +{ + VIF0_MARK = 0; + VIF0_ERR = 0; + VIF0_FBRST = 1; + + VIF0_FIFO0 = VIF_STCYCL(4, 4); + VIF0_FIFO1 = VIF_OFFSET(0); + VIF0_FIFO2 = VIF_NOP; + VIF0_FIFO3 = VIF_STMOD(0); + + VIF0_FIFO0 = VIF_ITOP(0); + VIF0_FIFO1 = VIF_NOP; + VIF0_FIFO2 = VIF_NOP; + VIF0_FIFO3 = VIF_NOP; + ClearInterrupt(0x10); +} + +void ResetEE(int mask) +{ + if (mask & RESET_DMAC) + { + printf("# Initialize DMAC ...\n"); + // Reset all channels + ResetDMAC(0x31F); + } + if (mask & RESET_VU1) + { + printf("# Initialize VU1 ...\n"); + ResetVU1(); + } + if (mask & RESET_VIF) + { + printf("# Initialize VIF1 ...\n"); + ResetVIF1(); + } + if (mask & RESET_GIF) + { + printf("# Initialize GIF ...\n"); + ResetGIF(); + } + if (mask & RESET_VU0) + { + printf("# Initialize VU0 ...\n"); + ResetVU0(); + } + if (mask & RESET_VIF) + { + printf("# Initialize VIF0 ...\n"); + ResetVIF0(); + } + // TODO: IPU Reset + ClearInterrupt(0xc); +} + +void ResetFPU() +{ + // Clear f0...f31 + // clear fcsr +} + +uint32_t* GetUserMemEnd() +{ + +} + +void ResetUserMem(uint32_t* begin) +{ + uint32_t* end = GetUserMemEnd(); + if (begin < end) + { + while (begin < end) + { + *begin = 0; + begin[1] = 0; + begin[2] = 0; + begin[3] = 0; + begin += 4; + } + } +} + +void ClearScratchpad() +{ + uint32_t* sp = (uint32_t*)0x70000000; + + while (sp < (uint32_t*)0x70004000) + { + sp[0] = sp[1] = sp[2] = sp[3] = 0; + sp += 4; + } +} + +void InitHardware() +{ + printf("Initialize Start.\n"); + printf("Initiailize GS ..."); + InitGS(); + SetGsCrt(1, GS_MODE_NTSC, 1); + printf("\n"); + printf("# Initialize INTC ...\n"); + ClearInterrupt(0xffff); + printf("# Initialize TIMER ...\n"); + InitTimers(); + ResetEE(RESET_ALL); + printf("# Initialize FPU ...\n"); + ResetFPU(); + printf("# Initialize User Memory ...\n"); + ResetUserMem(0x80000); + printf("# Initialize Scratch Pad ...\n"); + ClearScratchpad(); + printf("# Initialize Done.\n"); +} + +void main() +{ + InitTLB(); +} \ No newline at end of file diff --git a/BIOS/ee/kernel/reset.h b/BIOS/ee/kernel/reset.h new file mode 100644 index 0000000..d7d879e --- /dev/null +++ b/BIOS/ee/kernel/reset.h @@ -0,0 +1,10 @@ +#pragma once + +#define RESET_DMAC 1 +#define RESET_VU1 2 +#define RESET_VIF 4 +#define RESET_GIF 8 +#define RESET_VU0 16 +#define RESET_IPU 64 + +#define RESET_ALL (RESET_DMAC | RESET_VU1 | RESET_VIF | RESET_GIF | RESET_VU0 | RESET_IPU) \ No newline at end of file diff --git a/BIOS/ee/kernel/threading.c b/BIOS/ee/kernel/threading.c new file mode 100644 index 0000000..b5241f9 --- /dev/null +++ b/BIOS/ee/kernel/threading.c @@ -0,0 +1,37 @@ +#include "threading.h" +#include + +typedef struct LinkedList +{ + LinkedList* next; + LinkedList* last; +} LinkedList; + +struct unknown0 +{ + uint32_t unk32; + char unk[72]; +} unknown0[256]; + +LinkedList lists[128]; + +int DAT_800125ec, DAT_800125f0, DAT_80016fe0; + +void InitEENULL() +{ + for (int i = 0x80; i >= 0; i--) + { + lists[i].next = &lists[i]; + lists[i].last = &lists[i]; + } + + DAT_80016fe0 = 0; + DAT_800125ec = 0; + DAT_800125f0 = 0; + + for (int i = 0; i < 256; i++) + { + unknown0[i].unk32 = 0; + + } +} \ No newline at end of file diff --git a/BIOS/ee/kernel/threading.h b/BIOS/ee/kernel/threading.h new file mode 100644 index 0000000..695e216 --- /dev/null +++ b/BIOS/ee/kernel/threading.h @@ -0,0 +1,3 @@ +#pragma once + +void InitEENULL(); \ No newline at end of file diff --git a/BIOS/ee/kernel/vif1.h b/BIOS/ee/kernel/vif1.h new file mode 100644 index 0000000..baaf6fc --- /dev/null +++ b/BIOS/ee/kernel/vif1.h @@ -0,0 +1,11 @@ +#pragma once + +#define VIF_NOP 0 +#define VIF_STCYCL(wl, cl) ((1 << 24) | ((wl & 0xff) << 8) | ((cl & 0xff))) +#define VIF_OFFSET(offs) ((2 << 24) | (offs&0x3FF)) +#define VIF_BASE(base) ((3 << 24) | (base&0x3FF)) +#define VIF_ITOP(itop) ((4 << 24) | (itop&0x3FF)) +#define VIF_STMOD(mode) ((5 << 24) | (mode & 3)) +#define VIF_MSKPATH3(mask) ((6 << 24) | ((mask & 1) << 15)) +#define VIF_MARK(mark) ((7 << 24) | (mark&0xffff)) +#define VIF_STCOL (0x31 << 24) \ No newline at end of file diff --git a/BIOS/iop/loadcore/global.h b/BIOS/iop/loadcore/global.h index cb16560..159a65a 100644 --- a/BIOS/iop/loadcore/global.h +++ b/BIOS/iop/loadcore/global.h @@ -15,4 +15,6 @@ void RegisterLibraryEntries(ExportTable_t* table); static void ExportStub() { // Do nothing export stub for placeholder slots -} \ No newline at end of file +} + +int* QueryBootMode(int mode); \ No newline at end of file diff --git a/BIOS/iop/sifcmd/exports.c b/BIOS/iop/sifcmd/exports.c new file mode 100644 index 0000000..97a49b8 --- /dev/null +++ b/BIOS/iop/sifcmd/exports.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include + +void sceSifCmdInit() +{ + // Send SIFCMD initialized to EE + sceSetSMFLAG(0x20000); + // TODO: Some kind of event wait happens here +} + +int sifRpcInited = 0; + +typedef struct SifCmdHandler +{ + void* func; + void* harg; +} SifCmdHandler; + +SifCmdHandler handlers[32]; +char dmaDest[32]; + +void RegisterCommandHandler(unsigned int cid, void* func, void* harg) +{ + handlers[cid].func = func; + handlers[cid].harg = harg; +} + +unsigned int sceSifSendCmd_Internal(unsigned int cmd, int disableIntrs, SifCmdHdr* packet, int packet_size, void *src_extra,void *dest_extra, int size_extra) +{ + SifDmaTransfer transfers[2]; + int disableIntrs; + + int ret = 1; + + if (packet_size - 0x10 < 0x61) + { + if (size_extra < 1) + { + packet->dest = NULL; + packet->size &= 0xff; + } + else + { + transfers[0].src = src_extra; + transfers[0].size = size_extra; + transfers[0].attr = 0; + transfers[0].dst = dest_extra; + } + int index = (size_extra != 0); + packet->size = packet_size; + packet->cid = cmd; + transfers[index].src = packet; + transfers[index].attr = 4; + transfers[index].size = packet_size; + transfers[index].dst = dmaDest; + + ret = disableIntrs; + + if (disableIntrs) + { + CpuSuspendIntr(&disableIntrs); + sceQueueTransfer(transfers, index+1); + CpuResumeIntr(disableIntrs); + } + else + sceQueueTransfer(transfers, index+1); + } + else + ret = 0; + return ret; +} + +unsigned int sceSifSendCmd(unsigned int cmd, void* packet, int packet_size, void *src_extra,void *dest_extra, int size_extra) +{ + sceSifSendCmd_Internal(cmd, 0, packet, packet_size, src_extra, dest_extra, size_extra); +} + +void sceSifRpcInit(int mode) +{ + int intr; + + sceSifCmdInit(); + CpuSuspendIntr(&intr); + + if (!sifRpcInited) + { + sifRpcInited = 1; + sceSifSendCmd(0x80000001, (void*)0x1a40, 0x18, NULL, NULL, 0); + } + CpuResumeIntr(intr); +} \ No newline at end of file diff --git a/BIOS/iop/sifcmd/global.h b/BIOS/iop/sifcmd/global.h new file mode 100644 index 0000000..81c43e1 --- /dev/null +++ b/BIOS/iop/sifcmd/global.h @@ -0,0 +1,9 @@ +#pragma once + +typedef struct +{ + unsigned int size; + void* dest; + int cid; + unsigned int opt; +} SifCmdHdr; \ No newline at end of file diff --git a/BIOS/iop/sifcmd/sifcmd.c b/BIOS/iop/sifcmd/sifcmd.c new file mode 100644 index 0000000..b299490 --- /dev/null +++ b/BIOS/iop/sifcmd/sifcmd.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include + +typedef volatile uint32_t vu32; + +#define SIF_SMCOM (*(vu32*)0xbd000010) + +int IrqHandler(void* arg) +{ + +} + +ExportTable_t exportTable = +{ + .magic = 0x41C00000, + .next = NULL, + .version = 0x101, + .mode = 0, + .name = "sifman", + .exports = + { + + } +}; + +char RecvBuf[80]; + +int main(int argc, char** argv) +{ + int* bootMode = QueryBootMode(3); + if (bootMode == NULL) + { + int sifCmdInited = sceSifCheckInit(); + if (!sifCmdInited) + sifCmdInit(); + + RegisterLibraryEntries(&exportTable); + + if (!sifCmdInited) + { + RegisterIntrHandler(0x2b, 1, &IrqHandler, NULL); + EnableIntr(0x22b); + SIF_SMCOM = &RecvBuf; + } + } + + return 0; +} \ No newline at end of file diff --git a/BIOS/iop/sifman/exports.c b/BIOS/iop/sifman/exports.c index 2fddd23..c8c0205 100644 --- a/BIOS/iop/sifman/exports.c +++ b/BIOS/iop/sifman/exports.c @@ -2,15 +2,21 @@ #include #include #include +#include typedef volatile uint32_t vu32; #define DMA_DPCR (*(vu32*)0xbf8010f0) #define DMA_DPCR2 (*(vu32*)0xbf801570) + +#define DMA_SIF0_BCR (*(vu32*)0xbf801524) #define DMA_SIF0_CTRL (*(vu32*)0xbf801528) +#define DMA_SIF0_TADR (*(vu32*)0xbf80152C) + #define DMA_SIF1_CTRL (*(vu32*)0xbf801538) #define DMA_SIF1_BCR (*(vu32*)0xbf801534) #define DMA_SIF2_CTRL (*(vu32*)0xbf8010A8) + #define SIF_SMCOM (*(vu32*)0xbd000010) #define SIF_MSFLG (*(vu32*)0xbd000020) #define SIF_SMFLG (*(vu32*)0xbd000030) @@ -99,4 +105,75 @@ void sifCmdInit() sifCmdInited = true; } +} + +int sceSifCheckInit() +{ + return sifCmdInited; +} + +typedef struct +{ + uint32_t addr_flags; + uint32_t size; + uint32_t tword1; + uint32_t tword2; +} SIF0Pkt; + +void WriteTransferPacket(SifDmaTransfer* transfer) +{ + SIF0Pkt* curTransferPkt = (SIF0Pkt*)(transferBufBase + transferBufOffs * 0x10); + + uint32_t srcAddr = (uint32_t)transfer->src & 0xffffff; + uint32_t unAlignedSize = transfer->size + 3; + + curTransferPkt->addr_flags = srcAddr; + + uint32_t alignedSize = unAlignedSize >> 2; + + if (transfer->attr & 2) + curTransferPkt->addr_flags |= 0x40000000; + + curTransferPkt->size = alignedSize & 0xffffff; + unAlignedSize = unAlignedSize >> 4; + + if (alignedSize & 3) + unAlignedSize = unAlignedSize + 1; + + curTransferPkt->tword1 = unAlignedSize | 0x10000000; + if (transfer->attr & 4) + curTransferPkt->tword1 |= 0x80000000; + + curTransferPkt->tword2 = (uint32_t)transfer->dst & 0x1fffffff; + transferBufOffs++; +} + +int sceQueueTransfer(SifDmaTransfer* transfer, int count) +{ + int offs = transferBufOffs; + + if (count <= (0x20 - transferBufOffs)) + { + if (count > 0) + { + for (int i = 0; i < count; i++) + { + WriteTransferPacket(&transfer[i]); + } + } + } + + // No transfer running, send previously queued transfers + if ((DMA_SIF0_CTRL & 0x1000000) == 0) + { + DMA_SIF0_TADR = transferBufBase; + if ((SIF_CTRL & 0x20) == 0) + SIF_CTRL = 0x20; + DMA_SIF0_BCR = 0x20; + transferBufOffs = 0; + curTransferId = curTransferId + 1; + DMA_SIF0_CTRL = 0x1000701; + transferBufBase = 0xf8c; + } + return (offs & 0xff) << 8 | count & 0xff; } \ No newline at end of file diff --git a/BIOS/iop/sifman/global.h b/BIOS/iop/sifman/global.h index 8e3641f..835edaa 100644 --- a/BIOS/iop/sifman/global.h +++ b/BIOS/iop/sifman/global.h @@ -1,3 +1,14 @@ #pragma once -extern void sifCmdInit(); \ No newline at end of file +typedef struct +{ + void* src; + void* dst; + int size; + int attr; +} SifDmaTransfer; + +extern void sifCmdInit(); +extern int sceSifCheckInit(); +extern void sceSetSMFLAG(unsigned int value); +int sceQueueTransfer(SifDmaTransfer* transfer, int count); \ No newline at end of file diff --git a/BIOS/iop/sifman/sifman.c b/BIOS/iop/sifman/sifman.c index 683b60d..3bf1575 100644 --- a/BIOS/iop/sifman/sifman.c +++ b/BIOS/iop/sifman/sifman.c @@ -15,6 +15,31 @@ ExportTable_t table = ExportStub, ExportStub, sifCmdInit, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + ExportStub, + sceSifCheckInit, } }; diff --git a/a.out b/a.out new file mode 100755 index 0000000..43764ec Binary files /dev/null and b/a.out differ diff --git a/src/emu/cpu/ee/EmotionEngine.cpp b/src/emu/cpu/ee/EmotionEngine.cpp index f43d82b..4dd056b 100644 --- a/src/emu/cpu/ee/EmotionEngine.cpp +++ b/src/emu/cpu/ee/EmotionEngine.cpp @@ -235,11 +235,6 @@ void ClearIp1Pending() EmotionEngine::GetState()->cop0_regs[13] = cause.value; } -void CheckForInterrupt() -{ - -} - void SetIp0Pending() { COP0CAUSE cause; diff --git a/tst.o b/tst.o new file mode 100644 index 0000000..8dc9934 Binary files /dev/null and b/tst.o differ diff --git a/tst.s b/tst.s new file mode 100644 index 0000000..bc3e896 --- /dev/null +++ b/tst.s @@ -0,0 +1,21 @@ +.intel_syntax noprefix + +.data +LC0: + .asciz "0x%08lx, 0x%08lx\n" +.text +foo: + sub rsp, 8 + mov rdx, rsi + mov rsi, rdi + lea rdi, [rip+LC0] + mov eax, 0 + call printf + add rsp, 8 + ret +.global main +main: + mov rdi, 0xABABABAB + mov rsi, 0xBEEFBEEF + call foo + ret \ No newline at end of file