Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ ASFLAGS := $(INC) -D_MIPS_SZLONG=32 -D_LANGUAGE_ASSEMBLY -DBBPLAYER -nostdinc -f
OPTFLAGS := -Os
MIPS_VERSION := -mips2

CHECK_WARNINGS := -Wall -Wextra -Wno-format-security -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-variable -Wno-missing-braces
CHECK_WARNINGS += -Werror=implicit-int -Werror=implicit-function-declaration -Werror=int-conversion -Werror=incompatible-pointer-types
MIPS_BUILTIN_DEFS := -D_MIPS_ISA_MIPS2=2 -D_MIPS_ISA=_MIPS_ISA_MIPS2 -D_ABIO32=1 -D_MIPS_SIM=_ABIO32 -D_MIPS_SZINT=32 -D_MIPS_SZLONG=32 -D_MIPS_SZPTR=32
CC_CHECK = COMPILER_PATH="" gcc -m32 -nostdinc -fno-builtin -fsyntax-only -funsigned-char -std=gnu90 -DNON_MATCHING -D_LANGUAGE_C -D_MIPS_SZLONG=32 -DBBPLAYER -DF3D_GBI $(MIPS_BUILTIN_DEFS) $(INC) $(CHECK_WARNINGS)

build/src/libultra/reg/_getcount.o: MIPS_VERSION := -mips3
build/src/libultra/reg/_setcompare.o: MIPS_VERSION := -mips3
build/src/libz/%.o: MIPS_VERSION := -mips3
Expand All @@ -43,7 +48,7 @@ O_FILES := $(foreach f,$(C_FILES:.c=.o),build/$f) \
# Create build directories
$(shell mkdir -p build $(foreach dir,$(SRC_DIRS) $(ASM_DIRS) $(DATA_DIRS),build/$(dir)))

.PHONY: all clean distclean disasm setup
.PHONY: all clean distclean disasm expected setup

all: $(TARGET)
ifeq ($(COMPARE),1)
Expand All @@ -65,11 +70,15 @@ disasm:
$(SPLAT) sa1.yaml --modes code data bin
$(RM) asm/header.s

expected:
$(RM) -r expected
mkdir -p expected && cp -r build expected/build

setup:
$(MAKE) -C tools
$(MAKE) disasm
$(MAKE) all COMPARE=1
mkdir -p expected && cp -r build expected/build
$(MAKE) expected

$(TARGET): $(ELF)
$(OBJCOPY) -O binary $< $(@:.bin=.tmp)
Expand All @@ -94,6 +103,7 @@ build/src/%.o: src/%.s
@$(OBJDUMP) -drz $@ > $(@:.o=.s)

build/src/%.o: src/%.c
$(CC_CHECK) $<
$(CC) $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -c $< -o $@
@$(STRIP) -N dummy_symbol_ $@
$(ELFPATCH) $@
Expand Down
191 changes: 108 additions & 83 deletions src/sa1/1050.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,29 @@

void __osBbVideoPllInit(s32 tvType);
void osBbPowerOff(void);

void func_80003A28(void*);

void func_80002248(void*);
void func_8000234C(void*);

void func_80003094(void);
void osBbUsbInit(void);
u32 osBbUsbGetResetCount(s32 which);
void osBbSetErrorLed(s32);
void __osDisableInt(void);
s32 osBbUsbSetCtlrModes(s32 which, u32 mask);

void fbInit(u32);
void fbSetBg(u16);
void fbClear(void);

void sa1InitRDP(void);
void sa1ConfigureVI(void*);
void sa1IdleThread(void*);
void sa1MainThread(void*);
s32 sa1CheckIdSys(void);
void sa1BootSA2(void (*entrypoint)(u32), u32 arg);
void* sa1AuthenticateAndLoadSA2(void);
s32 sa1DisplayImage(void*, size_t);
void sa1CommandLoop(void);

extern u8 framebuffer[];
extern u32 D_8001AF40;
extern u32 D_800163A0;
extern u32 D_80016398;
extern u8 D_8001B0F8[0x8000];
extern u8 D_800232A8[0x8000];
extern OSThread D_8001AF48;
extern OSMesg prenmiMesgBuf[1];
extern OSMesgQueue prenmiMesgQueue;
extern OSThread D_800230F8;
extern OSMesgQueue piMesgQueue;
extern OSMesgQueue siMesgQueue;
extern OSMesgQueue siMesgQueue;
Expand All @@ -31,61 +36,68 @@ extern OSMesg viMesgBuf[1];
extern OSMesg piMesgBuf[200];
extern OSMesg siMesgBuf[200];
extern OSMesg viRetraceMesg;
extern OSThread D_8002B2A8;
extern u8 D_8002B458[0x8000];
extern u32 D_80016390;
extern u32 D_80016394;
extern u32 D_80016398;
extern u32 D_8001639C;
extern s32 D_80016490;
extern s32 D_800164A0;
extern s32 D_800178A0;
extern s32 D_800178B0;

extern OSThread idleThread;
extern u8 idleThreadStack[0x8000];
extern OSThread mainThread;
extern u8 mainThreadStack[0x8000];
extern OSThread eventThread;
extern u8 eventThreadStack[0x8000];

extern u32 skBootValue;
extern u32 powerBtnPressed;
extern u32 usbNum;
extern u32 usbTypeA;
extern u32 usbLineUnstable;
extern u32 usbNotConnected;
extern s32 sa1Image1Size;
extern s32 sa1Image1Data;
extern s32 sa1Image2Size;
extern s32 sa1Image2Data;
typedef struct {
u8 data[0x100];
} Struct_Unk;
extern Struct_Unk appSavedState;

extern Struct_Unk D_80033458;

void func_80002050(u32 arg0) {
D_80033458 = *(Struct_Unk*)PHYS_TO_K1(0x04A80100);
func_80003094();
void sa1Setup(u32 arg0) {
appSavedState = *(Struct_Unk*)PHYS_TO_K1(0x04A80100);
sa1CheckIdSys();
}

void func_80002114(s32 arg0) {
D_8001AF40 = arg0;
void sa1Entrypoint(u32 arg) {
skBootValue = arg;

IO_WRITE(MI_3C_REG, 0x01000000);

if (!(arg0 & 0x4C)) {
if (!(arg & 0x4C)) {
// Cold boot
__osBbVideoPllInit(OS_TV_NTSC);
func_80003A28(framebuffer);
sa1ConfigureVI(framebuffer);
} else {
// Warm boot
IO_WRITE(VI_H_VIDEO_REG, 0);
}
osInitialize();
osCreateThread(&D_8001AF48, 1, func_80002248, 0, D_8001B0F8 + sizeof(D_8001B0F8), 0x14);
osStartThread(&D_8001AF48);
osCreateThread(&idleThread, 1, sa1IdleThread, 0, idleThreadStack + sizeof(idleThreadStack), 0x14);
osStartThread(&idleThread);
}

void func_800021C8(void) {
if (D_800163A0 != 0) {
void sa1Event(void) {
if (powerBtnPressed) {
if (osRecvMesg(&prenmiMesgQueue, NULL, OS_MESG_NOBLOCK) == 0) {
osBbPowerOff();
}
} else if (!(IO_READ(MI_38_REG) & 0x01000000)) {
IO_WRITE(MI_3C_REG, 0x02000000);
D_800163A0 = 1;
powerBtnPressed = TRUE;
}
}

void func_80002248(void* arg0) {
osCreatePiManager(0x96, &piMesgQueue, piMesgBuf, ARRLEN(piMesgBuf));
void sa1IdleThread(void* arg) {
osCreatePiManager(OS_PRIORITY_PIMGR, &piMesgQueue, piMesgBuf, ARRLEN(piMesgBuf));
osCreateMesgQueue(&siMesgQueue, siMesgBuf, ARRLEN(siMesgBuf));
osSetEventMesg(OS_EVENT_SI, &siMesgQueue, (OSMesg)200);
osCreateThread(&D_800230F8, 3, func_8000234C, arg0, D_800232A8 + sizeof(D_800232A8), 0x12);
osStartThread(&D_800230F8);
osCreateThread(&mainThread, 3, sa1MainThread, arg, mainThreadStack + sizeof(mainThreadStack), 0x12);
osStartThread(&mainThread);
osCreateMesgQueue(&prenmiMesgQueue, prenmiMesgBuf, ARRLEN(prenmiMesgBuf));
osSetEventMesg(OS_EVENT_PRENMI, &prenmiMesgQueue, (OSMesg)1);
osSetThreadPri(NULL, 0);
Expand All @@ -95,83 +107,96 @@ void func_80002248(void* arg0) {
}
}

void func_80002320(void) {
void sa1EventThread(void* arg) {
while (TRUE) {
osRecvMesg(&viMesgQueue, NULL, OS_MESG_BLOCK);
func_800021C8();
sa1Event();
}
}

#ifdef NON_MATCHING
// Needs data imported
void func_8000234C(void* arg0) {
s32 temp_s3;
u64 temp_s0;
u32 temp_s2;
void sa1MainThread(void* arg) {
void* sa2Entrypoint;
OSTime thresholdTime;
u32 usbResetCount;

osCreateViManager(0xFE);
osCreateViManager(OS_PRIORITY_VIMGR);
fbInit(0);
osCreateMesgQueue(&viMesgQueue, viMesgBuf, 1);
osViSetEvent(&viMesgQueue, viRetraceMesg, 1);
osViBlack(1);
osViBlack(TRUE);
osViSwapBuffer(framebuffer);
fbSetBg(0);
fbClear();
osViBlack(0);
osViBlack(FALSE);
osWritebackDCacheAll();
osViSwapBuffer(framebuffer);
fbClear();
func_80003C20();
func_80002050(D_8001AF40);
osCreateThread(&D_8002B2A8, 5, func_80002320, arg0, D_8002B458 + sizeof(D_8002B458), 0xF);
osStartThread(&D_8002B2A8);
D_80016398 = 1;
osBbUsbSetCtlrModes(D_80016398 ^ 1, 0);
osBbUsbSetCtlrModes(D_80016398 ^ 0, 2);
sa1InitRDP();
sa1Setup(skBootValue);
osCreateThread(&eventThread, 5, sa1EventThread, arg, eventThreadStack + sizeof(eventThreadStack), 0xF);
osStartThread(&eventThread);

// Start with USB1
usbNum = 1;
osBbUsbSetCtlrModes(usbNum ^ 1, 0);
osBbUsbSetCtlrModes(usbNum ^ 0, 2);
osBbUsbInit();
temp_s3 = func_80002DCC();

D_80016390 = (D_80016398 == 0) ? !(IO_READ(0x04900018) & (1 << 7)) : 0;
sa2Entrypoint = sa1AuthenticateAndLoadSA2();

// No ID pin on USB1, always assume Type B / Unconnected
usbTypeA = (usbNum == 0) ? !(IO_READ(0x04900018) & (1 << 7)) : 0;
// Line state is unstable
usbLineUnstable = !(IO_READ((usbNum == 0) ? 0x04900018 : 0x04A00018) & (1 << 5));

D_80016394 = !(IO_READ((D_80016398 == 0) ? 0x04900018 : 0x04A00018) & (1 << 5));
if (!usbLineUnstable) {
// If USB1 line state stable, it isn't connected?

if (D_80016394 == 0) {
D_80016398 = ~D_80016398 & 1;
osBbUsbSetCtlrModes(D_80016398 ^ 1, 0);
osBbUsbSetCtlrModes(D_80016398 ^ 0, 2);
// Flip to USB0
usbNum = ~usbNum & 1;
osBbUsbSetCtlrModes(usbNum ^ 1, 0);
osBbUsbSetCtlrModes(usbNum ^ 0, 2);
osBbUsbInit();

D_80016390 = (D_80016398 == 0) ? !(IO_READ(0x04900018) & (1 << 7)) : 0;
D_80016394 = 0;
temp_s2 = osBbUsbGetResetCount(D_80016398);
temp_s0 = OS_CYCLES_TO_USEC(osGetCount()) + 2000000;
while (OS_CYCLES_TO_USEC(osGetCount()) < temp_s0) {
if (temp_s2 < osBbUsbGetResetCount(D_80016398)) {
D_80016394 = 1;
// USB0 has ID pin detection, use it to differentiate Type A or Type B / Unconnected
usbTypeA = (usbNum == 0) ? !(IO_READ(0x04900018) & (1 << 7)) : 0;
// Determine line stability by reset count over the next 2 seconds
usbLineUnstable = 0;
usbResetCount = osBbUsbGetResetCount(usbNum);
thresholdTime = OS_CYCLES_TO_USEC(osGetCount()) + 2000000; // +2 seconds
while (OS_CYCLES_TO_USEC(osGetCount()) < thresholdTime) {
if (osBbUsbGetResetCount(usbNum) > usbResetCount) {
usbLineUnstable = 1;
break;
}
}
}

D_8001639C = (D_80016390 != 0) || (D_80016394 == 0);
// Type A or stable
usbNotConnected = usbTypeA || !usbLineUnstable;
osBbSetErrorLed(0);
if (D_8001639C != 0) {
if (temp_s3 != 0) {
if (usbNotConnected) {
if (sa2Entrypoint != NULL) {
// No USB, SA2
__osDisableInt();

*(Struct_Unk*)PHYS_TO_K1(0x04A80100) = D_80033458;
*(Struct_Unk*)PHYS_TO_K1(0x04A80100) = appSavedState;

func_80002D94(temp_s3, D_8001AF40);
sa1BootSA2(sa2Entrypoint, skBootValue);
} else {
func_80004390(&D_800178B0, D_800178A0);
func_800033CC();
// No USB, no SA2
sa1DisplayImage(&sa1Image2Data, sa1Image2Size);
sa1CommandLoop();
}
} else {
func_80004390(&D_800164A0, D_80016490);
func_800033CC();
// USB
sa1DisplayImage(&sa1Image1Data, sa1Image1Size);
sa1CommandLoop();
}
osBbPowerOff();
}
#else
INCLUDE_ASM("asm/nonmatchings/sa1/1050", func_8000234C);
INCLUDE_ASM("asm/nonmatchings/sa1/1050", sa1MainThread);
#endif
Loading