New and improved make build system and other cleanups (#13)

* Remove unused C versions of gu functions which will conflict with ASM versions under the new build system
This is a holdover from the decomp, as it must support older libultra versions which used these functions; as we're basing this project off of the final 2.0L, they gotta go

* Comment out bugged unused debug code
Will be removed completely by #12 soon enough anyway, but this will break CI if I don't remove this

* C++ fix in ultra64.h

* New build system
Based off my personal "template" featuring makedepend and support for automatically building and installing all 3 library versions, along with colors
Still needs cleanup to make sure I've brought over everything from the previous makefile

* Fix clang_format

* CI fixes to account for the non-decomp build system

* Remove old makefile

* Remove decomp tools

* Accidentally removed format checker

* Change VERSION to TARGET

* Fix install target by removing unused files and bring back ZSort header

* Fix CI typo

* gzsort header removed, I will figure out how to add it in modsdk later

* just copy the whole PR folder instead and remove install.mk, unnecessary

* SDK installation shall be handled seperately

* Remove RMON and a few leftover KMC things

* Remove MODERN_CC, as everyone is gonna be building this on a modern compiler anyway
This commit is contained in:
CrashOveride95
2025-08-23 22:58:24 -04:00
committed by GitHub
parent dba3265aac
commit b742894b55
50 changed files with 193 additions and 10865 deletions

View File

@@ -1,6 +1,6 @@
# CI file for GCC builds
name: Build GCC libgultra
name: Build GCC libultra
# Build on every branch push, tag push, and pull request change:
on: [push, pull_request_target]
@@ -13,8 +13,7 @@ jobs:
strategy:
fail-fast: false
matrix:
version: [L] # [H, I, I_patch, J, K, L]
suffix: [~, _d, _rom]
version: [libultra, libultra_d, libultra_rom]
steps:
- name: Checkout repository
@@ -28,11 +27,8 @@ jobs:
- name: Verify formatting on all files
run: python3 tools/check_format.py --verbose
- name: Setup
run: make setup -j $(nproc) TARGET=libgultra${{ matrix.suffix }} VERSION=${{ matrix.version }}
- name: Build libgultra${{ matrix.suffix }} ${{ matrix.version }}
run: make -j $(nproc) TARGET=libgultra${{ matrix.suffix }} VERSION=${{ matrix.version }}
- name: Build ${{ matrix.version }}
run: make -j $(nproc) VERSION=${{ matrix.version }}
- name: 'Upload Artifact'
uses: actions/upload-artifact@v4

232
Makefile
View File

@@ -1,18 +1,41 @@
# One of:
# libgultra_rom, libgultra_d, libgultra
TARGET ?= libgultra_rom
VERSION ?= L
VERBOSE ?= 0
# Use handwritten ASM implementations of select `gu` functions
MGU_ASM ?= 1
# Makefile to build libultra
include util.mk
ifeq ($(VERBOSE), 0)
V=@
else
V=
# Preprocessor definitions
WORKING_DIR := $(shell pwd)
DEFINES :=
SRC_DIRS :=
# Whether to hide commands or not
VERBOSE ?= 0
ifeq ($(VERBOSE),0)
V := @
endif
# Whether to colorize build messages
COLOR ?= 1
# TARGET - selects the version of the library to build
# libultra - standard library
# libultra_d - debug library
# libultra_rom - final ROM library
TARGET ?= libultra_rom
$(eval $(call validate-option,TARGET,libultra libultra_d libultra_rom))
ifeq ($(TARGET),libultra)
OPT_FLAGS := -Os -ggdb3 -ffast-math -fno-unsafe-math-optimizations
DEFINES += NDEBUG=1
else ifeq ($(TARGET),libultra_d)
OPT_FLAGS := -Og -ggdb3 -ffast-math -fno-unsafe-math-optimizations
DEFINES += _DEBUG=1
else ifeq ($(TARGET),libultra_rom)
OPT_FLAGS := -Os -ggdb3 -ffast-math -fno-unsafe-math-optimizations
DEFINES += NDEBUG=1
DEFINES += _FINALROM=1
endif
# detect prefix for MIPS toolchain
@@ -36,98 +59,149 @@ else
$(error Unable to detect a suitable MIPS toolchain installed)
endif
BUILD_ROOT := build
BUILD_DIR := $(BUILD_ROOT)/
BUILD_AR := $(BUILD_DIR)/$(TARGET).a
WORKING_DIR := $(shell pwd)
CPP := cpp -P
AR := $(CROSS)ar
VERSION_DEFINE := -DBUILD_VERSION_STRING=\"2.0$(VERSION)\"
ifeq ($(findstring _d,$(TARGET)),_d)
DEBUGFLAG := -D_DEBUG
else
DEBUGFLAG := -DNDEBUG
ifeq ($(filter clean,$(MAKECMDGOALS)),)
$(info ==== Build Options ====)
$(info Version: $(TARGET))
$(info =======================)
endif
AS := $(CROSS)gcc -x assembler-with-cpp
CC := $(CROSS)gcc
#==============================================================================#
# Target Executable and Sources #
#==============================================================================#
BUILD_DIR_BASE := build
# BUILD_DIR is the location where all build artifacts are placed
BUILD_DIR := $(BUILD_DIR_BASE)/$(TARGET)
LIB := $(BUILD_DIR)/$(TARGET).a
# Directories containing source files
SRC_DIRS += $(shell find src -type d)
C_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c))
S_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.s))
# Object files
O_FILES := $(foreach file,$(C_FILES),$(BUILD_DIR)/$(file:.c=.o)) \
$(foreach file,$(S_FILES),$(BUILD_DIR)/$(file:.s=.o))
# Automatic dependency files
DEP_FILES := $(O_FILES:.o=.d)
#==============================================================================#
# Compiler Options #
#==============================================================================#
AS := $(CROSS)as
CC := $(CROSS)gcc
CPP := $(CROSS)cpp
LD := $(CROSS)ld
AR := $(CROSS)ar
# Do NOT depend on system-installed headers! If you need to make a header change,
# test it in your source first!
INCLUDE_DIRS += $(WORKING_DIR)/include $(WORKING_DIR)/include/PR $(WORKING_DIR)/include/compiler/modern_gcc $(BUILD_DIR) $(BUILD_DIR)/include $(WORKING_DIR)/src $(WORKING_DIR)
GBIDEFINE := -DF3DEX_GBI_2
C_DEFINES = $(foreach d,$(DEFINES),-D$(d))
DEF_INC_CFLAGS = $(foreach i,$(INCLUDE_DIRS),-I$(i)) $(C_DEFINES)
WARNINGS := -Wall -Wextra -Wno-format-security -Wno-unused-function -Wno-unused-parameter -Wno-unused-variable -Wno-builtin-declaration-mismatch
WARNINGS += -Wno-int-conversion -Wno-incompatible-pointer-types -Wno-implicit-function-declaration # TODO: Try adjusting code to remove these
CFLAGS := -G 0 -c -nostdinc -march=vr4300 -mfix4300 -mabi=32 -mno-abicalls -mdivide-breaks -fno-PIC -fno-common -ffreestanding -fbuiltin -fno-builtin-sinf -fno-builtin-cosf -funsigned-char $(WARNINGS)
CFLAGS := -G 0 -c -nostdinc -march=vr4300 -mfix4300 -mabi=32 -mips3 -mno-abicalls -mdivide-breaks -fno-PIC -fno-common -ffreestanding -fbuiltin -fno-builtin-sinf -fno-builtin-cosf -funsigned-char $(WARNINGS)
CFLAGS += -fno-strict-aliasing # TODO: Try adjusting code to remove this
ASFLAGS := -w -nostdinc -c -G 0 -march=vr4300 -mabi=32 -mgp32 -mfp32 -DMIPSEB -D_LANGUAGE_ASSEMBLY -D_MIPS_SIM=1 -D_ULTRA64
CPPFLAGS = -DMODERN_CC -D_MIPS_SZLONG=32 -D__USE_ISOC99 $(GBIDEFINE) $(VERSION_DEFINE) $(DEBUGFLAG)
IINC = -I . -I $(WORKING_DIR)/include -I $(WORKING_DIR)/include/compiler/modern_gcc -I $(WORKING_DIR)/include/PR
MIPS_VERSION := -mips3
ASOPTFLAGS :=
CFLAGS += -D_MIPS_SZLONG=32 -D__USE_ISOC99 $(C_DEFINES) $(DEF_INC_CFLAGS)
ifeq ($(findstring _d,$(TARGET)),_d)
OPTFLAGS := -Og -ggdb3 -ffast-math -fno-unsafe-math-optimizations
else
OPTFLAGS := -Os -ggdb3 -ffast-math -fno-unsafe-math-optimizations
# C preprocessor flags
CPPFLAGS := -P -Wno-trigraphs $(DEF_INC_CFLAGS)
# tools
PRINT = printf
ifeq ($(COLOR),1)
NO_COL := \033[0m
RED := \033[0;31m
GREEN := \033[0;32m
BLUE := \033[0;34m
YELLOW := \033[0;33m
BLINK := \033[33;5m
endif
ifeq ($(findstring _rom,$(TARGET)),_rom)
CPPFLAGS += -D_FINALROM
endif
# Common build print status function
define print
@$(PRINT) "$(GREEN)$(1) $(YELLOW)$(2)$(GREEN) -> $(BLUE)$(3)$(NO_COL)\n"
endef
SRC_DIRS := $(shell find src -type d)
C_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c))
S_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.s))
#==============================================================================#
# Main Targets #
#==============================================================================#
# Versions J and below used the C matrix math implementations
MGU_MATRIX_FILES := mtxcatf normalize scale translate
ifeq ($(MGU_ASM), 1)
C_FILES := $(filter-out $(addprefix src/gu/,$(MGU_MATRIX_FILES:=.c)),$(C_FILES))
else
S_FILES := $(filter-out $(addprefix src/mgu/,$(MGU_MATRIX_FILES:=.s)),$(S_FILES))
endif
C_O_FILES := $(foreach f,$(C_FILES:.c=.o),$(BUILD_DIR)/$f)
S_O_FILES := $(foreach f,$(S_FILES:.s=.o),$(BUILD_DIR)/$f)
O_FILES := $(S_O_FILES) $(C_O_FILES)
$(shell mkdir -p src $(foreach dir,$(SRC_DIRS),$(BUILD_DIR)/$(dir)))
.PHONY: all clean distclean setup
all: $(BUILD_AR)
$(BUILD_AR): $(O_FILES)
@printf " [AR] $@\n"
$(V)$(AR) rcs $@ $^
# Default target
default: $(LIB)
clean:
$(RM) -rf $(BUILD_DIR)
$(RM) -r $(BUILD_DIR_BASE)
distclean:
$(RM) -rf extracted/ $(BUILD_ROOT)
ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS))
GBIDEFINE := -DF3DEX_GBI
# Make sure build directory exists before compiling anything
$(shell mkdir -p $(ALL_DIRS))
$(BUILD_DIR)/src/voice/%.o: CFLAGS += -I$(WORKING_DIR)/src/voice
$(BUILD_DIR)/src/voice/%.o: DEFINES += LANG_JAPANESE=1
$(BUILD_DIR)/src/gu/parse_gbi.o: GBIDEFINE := -DF3D_GBI
$(BUILD_DIR)/src/gu/us2dex_emu.o: GBIDEFINE :=
$(BUILD_DIR)/src/gu/us2dex2_emu.o: GBIDEFINE :=
$(BUILD_DIR)/src/sp/sprite.o: GBIDEFINE := -DF3D_GBI
$(BUILD_DIR)/src/sp/spriteex.o: GBIDEFINE :=
$(BUILD_DIR)/src/sp/spriteex2.o: GBIDEFINE :=
$(BUILD_DIR)/src/voice/%.o: OPTFLAGS += -DLANG_JAPANESE -I$(WORKING_DIR)/src -I$(WORKING_DIR)/src/voice
$(BUILD_DIR)/src/voice/%.o: CC := $(WORKING_DIR)/tools/compile_sjis.py -D__CC=$(CC) -D__BUILD_DIR=$(BUILD_DIR)
#==============================================================================#
# Compilation Recipes #
#==============================================================================#
# Compile C code
$(BUILD_DIR)/src/voice/%.o: src/voice/%.c
$(call print,Compiling:,$<,$@)
$(V)tools/compile_sjis.py -D__CC=$(CC) -D__BUILD_DIR=$(BUILD_DIR) -c $(CFLAGS) -MMD -MP -o $@ $<
$(BUILD_DIR)/%.o: %.c
@printf " [CC] $<\n"
$(V)$(CC) $(CFLAGS) $(MIPS_VERSION) $(CPPFLAGS) $(OPTFLAGS) $< $(IINC) -o $@
$(V)tools/set_o32abi_bit.py $@
$(call print,Compiling:,$<,$@)
$(V)$(CC) -c $(CFLAGS) $(GBIDEFINE) -MMD -MP -o $@ $<
$(BUILD_DIR)/%.o: $(BUILD_DIR)/%.c
$(call print,Compiling:,$<,$@)
$(V)$(CC) -c $(CFLAGS) $(GBIDEFINE) -MMD -MP -o $@ $<
# Assemble assembly code
$(BUILD_DIR)/%.o: %.s
@printf " [AS] $<\n"
$(V)$(AS) $(ASFLAGS) $(MIPS_VERSION) $(CPPFLAGS) $(ASOPTFLAGS) $< $(IINC) -o $@
$(V)tools/set_o32abi_bit.py $@
$(call print,Assembling:,$<,$@)
$(V)$(CC) -c $(CFLAGS) $(foreach i,$(INCLUDE_DIRS),-Wa,-I$(i)) -x assembler-with-cpp -DMIPSEB -D_LANGUAGE_ASSEMBLY -D_ULTRA64 -MMD -MP -o $@ $<
# Creating final library file
$(LIB): $(O_FILES)
@$(PRINT) "$(GREEN)Creating $(TARGET): $(BLUE)$@ $(NO_COL)\n"
$(V)$(AR) rcs -o $@ $(O_FILES)
all: $(BUILD_DIR_BASE)/libultra.a $(BUILD_DIR_BASE)/libultra_d.a $(BUILD_DIR_BASE)/libultra_rom.a
$(BUILD_DIR_BASE)/libultra.a:
$(V)$(MAKE) TARGET=libultra
$(V)cp $(BUILD_DIR_BASE)/libultra/libultra.a $(BUILD_DIR_BASE)
$(BUILD_DIR_BASE)/libultra_d.a:
$(V)$(MAKE) TARGET=libultra_d
$(V)cp $(BUILD_DIR_BASE)/libultra_d/libultra_d.a $(BUILD_DIR_BASE)
$(BUILD_DIR_BASE)/libultra_rom.a:
$(V)$(MAKE) TARGET=libultra_rom
$(V)cp $(BUILD_DIR_BASE)/libultra_rom/libultra_rom.a $(BUILD_DIR_BASE)
.PHONY: clean default all install pkginstall
# with no prerequisites, .SECONDARY causes no intermediate target to be removed
.SECONDARY:
# Remove built-in rules, to improve performance
MAKEFLAGS += --no-builtin-rules
-include $(DEP_FILES)
# Disable built-in rules
.SUFFIXES:
print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true

12
include/PR/gtoff.h Normal file
View File

@@ -0,0 +1,12 @@
/* GENERATED FILE, DO NOT EDIT! */
/* gtState_t structure offsets for assembly language: */
#define GT_STATE_SIZE 88
#define GT_STATE_OFF_RENDSTATE 0x00
#define GT_STATE_OFF_TEXSTATE 0x04
#define GT_STATE_OFF_VTXCOUNT 0x08
#define GT_STATE_OFF_VTXV0 0x09
#define GT_STATE_OFF_TRICOUNT 0x0a
#define GT_STATE_OFF_RDPCMDS 0x0c
#define GT_STATE_OFF_OTHERMODE 0x10
#define GT_STATE_OFF_TRANSFORM 0x18

View File

@@ -76,15 +76,9 @@ extern "C" {
/* byte string operations */
#ifndef MODERN_CC
extern void bcopy(const void*, void*, int);
extern int bcmp(const void*, const void*, int);
extern void bzero(void*, int);
#else
extern void bcopy(const void*, void*, size_t);
extern int bcmp(const void*, const void*, size_t);
extern void bzero(void*, size_t);
#endif
/* Printf */

View File

@@ -29,7 +29,6 @@ extern "C" {
#define RMON_DBG_BUF_SIZE 2048
#define RMON_STACKSIZE 0x1000
extern void rmonMain(void*);
extern void rmonPrintf(const char*, ...);
#ifdef _LANGUAGE_C_PLUS_PLUS

17
include/PR/sptaskoff.h Normal file
View File

@@ -0,0 +1,17 @@
#define OS_TASK_SIZE 64
#define OS_TASK_OFF_TYPE 0
#define OS_TASK_OFF_FLAGS 4
#define OS_TASK_OFF_UBOOT 8
#define OS_TASK_OFF_UBOOT_SZ 12
#define OS_TASK_OFF_UCODE 16
#define OS_TASK_OFF_UCODE_SZ 20
#define OS_TASK_OFF_UDATA 24
#define OS_TASK_OFF_UDATA_SZ 28
#define OS_TASK_OFF_STACK 32
#define OS_TASK_OFF_STACK_SZ 36
#define OS_TASK_OFF_OUTBUFF 40
#define OS_TASK_OFF_OUTBUFF_SZ 44
#define OS_TASK_OFF_DATA 48
#define OS_TASK_OFF_DATA_SZ 52
#define OS_TASK_OFF_YIELD 56
#define OS_TASK_OFF_YIELD_SZ 60

View File

@@ -1,168 +0,0 @@
#ifndef _RMONINT_H
#define _RMONINT_H
#include "PRinternal/dbgproto.h"
#include "PR/os_internal.h"
/* mips */
#define MIPS_LWC2_OPCODE 50
#define MIPS_SWC2_OPCODE 58
#define MIPS_LW_OPCODE 35
#define MIPS_SW_OPCODE 43
#define MIPS_BREAK_OPCODE 0xD
#define MIPS_BREAK_MASK 0xFC00003F
#define MIPS_BREAK(code) ((((code) & 0xFFFFF) << 6) | MIPS_BREAK_OPCODE)
/* R4300 General Purpose Register Indices */
#define GREG_IDX_ZERO 0
#define GREG_IDX_AT 1
#define GREG_IDX_T9 25
#define GREG_IDX_K0 26
#define GREG_IDX_GP 28
#define GREG_IDX_RA 31
#define GREG_IDX_LO 32
#define GREG_IDX_HI 33
#define GREG_IDX_CAUSE 34
#define GREG_IDX_PC 35
#define GREG_IDX_SR 36
/* RSP Scalar Register Indices */
#define SREG_IDX_ZERO 0
#define SREG_IDX_RA 31
#define SREG_IDX_DRAM_ADDR (32 + 0)
#define SREG_IDX_MEM_ADDR (32 + 1)
#define SREG_IDX_RD_LEN (32 + 2)
#define SREG_IDX_PC (32 + 3)
#define SREG_IDX_WR_LEN (32 + 4)
#define SREG_IDX_STATUS (32 + 5)
#define SREG_IDX_DMA_FULL (32 + 6)
#define SREG_IDX_DMA_BUSY (32 + 7)
/* RSP Vector Register Properties */
#define VREG_NUM 32
#define VREG_SIZE 0x10
/* rmon */
#define RMON_MESG_CPU_BREAK 2
#define RMON_MESG_SP_BREAK 4
#define RMON_MESG_FAULT 8
#define RMON_CPU 0
#define RMON_RSP 1
/* "thread id" for rsp */
#define RMON_TID_RSP 1000
/* "thread priority" for rsp */
#define RMON_PRI_RSP 42
/* "thread id" for no thread running */
#define RMON_TID_NOTHREAD 1003
#define RMON_PID_CPU 1002
#define RMON_PID_RSP 1001
/* Largest serviceable read/write memory request */
#define RMON_MAX_XFER_SIZE 1024
/* rmonmain */
void __rmonSendHeader(KKHeader* const block, u32 blockSize, u32 type);
void __rmonSendReply(KKHeader* const block, u32 blockSize, u32 replyType);
void __rmonSendData(char* const block, unsigned int blockSize);
extern int __rmonActive;
/* rmonmisc */
void __rmonInit(void);
void __rmonPanic(void);
extern OSMesgQueue __rmonMQ;
/* rmonmem */
void __rmonWriteWordTo(u32* addr, u32 val);
u32 __rmonReadWordAt(u32* addr);
void __rmonMemcpy(u8* dest, u8* srce, u32 count);
void __rmonCopyWords(u32* dest, u32* srce, u32 count);
extern u8 __rmonUtilityBuffer[];
/* rmonsio */
void __rmonSendFault(OSThread* thread);
void __rmonIOflush(void);
void __rmonIOputw(u32 word);
void __rmonIOhandler(void);
extern void* __osRdb_DbgRead_Buf;
extern u8 rmonRdbReadBuf[];
/* rmonrcp */
int __rmonRCPrunning(void);
void __rmonIdleRCP(void);
void __rmonStepRCP(void);
void __rmonRunRCP(void);
/* rmonbrk */
u32 __rmonGetBranchTarget(int method, int thread, char* addr);
int __rmonSetSingleStep(int thread, u32* instptr);
void __rmonGetExceptionStatus(KKStatusEvent* reply);
void __rmonHitBreak(void);
void __rmonHitSpBreak(void);
void __rmonHitCpuFault(void);
extern u8 __rmonRcpAtBreak;
/* rmonregs */
u32 __rmonGetRegisterContents(int method, int threadNumber, int regNumber);
/* rmontask */
void __rmonMaskIdleThreadInts(void);
OSThread* __rmonGetTCB(int threadNumber);
int __rmonStopUserThreads(int whichThread);
int __rmonGetThreadStatus(int method, int id, KKStatusEvent* reply);
/* rmoncmds */
int __rmonExecute(KKHeader* request);
/* commands */
typedef int (*FUNPTR)();
int __rmonLoadProgram(KKHeader* req);
int __rmonListProcesses(KKHeader* req);
int __rmonGetExeName(KKHeader* req);
int __rmonListThreads(KKHeader* req);
int __rmonThreadStatus(KKHeader* req);
int __rmonStopThread(KKHeader* req);
int __rmonRunThread(KKHeader* req);
int __rmonSetFault(KKHeader* req);
int __rmonGetRegionCount(KKHeader* req);
int __rmonGetRegions(KKHeader* req);
int __rmonGetGRegisters(KKHeader* req);
int __rmonSetGRegisters(KKHeader* req);
int __rmonGetFRegisters(KKHeader* req);
int __rmonSetFRegisters(KKHeader* req);
int __rmonReadMem(KKHeader* req);
int __rmonWriteMem(KKHeader* req);
int __rmonSetBreak(KKHeader* req);
int __rmonClearBreak(KKHeader* req);
int __rmonListBreak(KKHeader* req);
int __rmonSetComm(KKHeader* req);
int __rmonGetSRegs(KKHeader* req);
int __rmonSetSRegs(KKHeader* req);
int __rmonGetVRegs(KKHeader* req);
int __rmonSetVRegs(KKHeader* req);
#endif

View File

@@ -22,6 +22,9 @@
#ifndef _ULTRA64_H_
#define _ULTRA64_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <PR/ultratypes.h>
#include <PR/rcp.h>
#include <PR/os.h>
@@ -36,5 +39,8 @@
#include <PR/ucode.h>
#include <PR/ultraerror.h>
#include <PR/ultralog.h>
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,245 +0,0 @@
// This file was added in 2.0J and removed in 2.0K
#include "stdarg.h"
#include "PR/os.h"
#include "PR/rcp.h"
#include "PR/rdb.h"
#include "ultraerror.h"
#include "../libc/xstdio.h"
extern u32 __kmc_pt_mode;
static void* proutSyncPrintf(void* str, const char* buf, size_t n) {
size_t sent = 0;
while (sent < n) {
sent += __osRdbSend(buf + sent, n - sent, RDB_TYPE_GtoH_PRINT);
}
return 1;
}
static volatile unsigned int* stat = (unsigned*)0xbff08004;
static volatile unsigned int* wport = (unsigned*)0xbff08000;
static volatile unsigned int* piok = (unsigned*)PHYS_TO_K1(PI_STATUS_REG);
static void rmonPutchar(char c) {
while (*piok & (PI_STATUS_DMA_BUSY | PI_STATUS_IO_BUSY)) {
}
while (!(*stat & 4)) {
}
*wport = c;
}
static void* kmc_proutSyncPrintf(void* str, const char* buf, int n) {
int i;
char c;
char* p;
char* q;
char xbuf[128];
static int column = 0;
p = &xbuf;
for (i = 0; i < n; i++) {
c = *buf++;
switch (c) {
case '\n':
*p++ = '\n';
column = 0;
break;
case '\t':
do {
*p++ = ' ';
} while (++column % 8);
break;
default:
column++;
*p++ = c;
break;
}
if (c == '\n' || (p - xbuf) > 100) {
rmonPutchar((p - xbuf) - 1);
q = xbuf;
while (q != p) {
rmonPutchar(*q++);
}
p = xbuf;
}
}
if (p != xbuf) {
rmonPutchar((p - xbuf) - 1);
q = xbuf;
while (q != p) {
rmonPutchar(*q++);
}
}
return (void*)1;
}
char NULSTR[] = "";
const char* __os_error_message[] = {
NULSTR,
"osCreateThread: stack pointer not aligned to 8 bytes (0x%x)",
"osCreateThread: priority not in range [0-255] (%d)",
"osStartThread: thread has bad state (running/runnable/other)",
"osSetThreadPri: priority not in range [0-255] (%d)",
"osCreateMesgQueue: message count not > 0 (%d)",
"osSendMesg: flag not OS_MESG_NOBLOCK or OS_MESG_BLOCK (%d)",
"osJamMesg: flag not OS_MESG_NOBLOCK or OS_MESG_BLOCK (%d)",
"osRecvMesg: flag not OS_MESG_NOBLOCK or OS_MESG_BLOCK (%d)",
"osSetEventMesg: unknown event type (%d)",
"osMapTLB: index not in range [0-30] (%d)",
"osMapTLB: asid argument not -1 or in range [0-255] (%d)",
"osUnmapTLB: index not in range [0-30] (%d)",
"osSetTLBASID: asid not in range [0-255] (%d)",
"osAiSetFrequency: freq not in range [%d-%d] (%d)",
"osAiSetNextBuffer: address not aligned to 8 bytes (0x%x)",
"osAiSetNextBuffer: size not aligned to 8 bytes (0x%x)",
"osDpSetNextBuffer: address not aligned to 8 bytes (0x%x)",
"osDpSetNextBuffer: size not aligned to 8 bytes (0x%x)",
"osPiRawReadIo: address not aligned to 4 bytes (0x%x)",
"osPiRawWriteIo: address not aligned to 4 bytes (0x%x)",
"osPiRawStartDma: direction not OS_READ or OS_WRITE (%d)",
"osPiRawStartDma: device address not aligned to 2 bytes (0x%x)",
"osPiRawStartDma: DRAM address not aligned to 8 bytes (0x%x)",
"osPiRawStartDma: size not aligned to 2 bytes (%d)",
"osPiRawStartDma: size not in range [0,16777216] (%d)",
"osPiReadIo: address not aligned to 4 bytes (0x%x)",
"osPiWriteIo: address not aligned to 4 bytes (0x%x)",
"osPiStartDma: PI Manager not yet begun by osCreatePiManager",
"osPiStartDma: priority not OS_MESG_PRI_[NORMAL|HIGH] (%d)",
"osPiStartDma: direction not OS_READ or OS_WRITE (%d)",
"osPiStartDma: device address not aligned to 2 bytes (0x%x)",
"osPiStartDma: DRAM address not aligned to 8 bytes (0x%x)",
"osPiStartDma: size not aligned to 2 bytes (%d)",
"osPiStartDma: size not in range [0,16777216] (%d)",
"osCreatePiManager: priority not in range [0-255] (%d)",
"osViGetCurrentMode: VI Manager not yet begun",
"osViGetCurrentFramebuffer: VI Manager not yet begun",
"osViGetNextFramebuffer: VI Manager not yet begun",
"osViSetXScale: value not in range [0.25,1.0] (%f)",
"osViSetXScale: VI Manager not yet begun by osCreateViManager",
"osViSetYScale: value not in range [0.05,1.0] (%f)",
"osViSetYScale: VI Manager not yet begun by osCreateViManager",
"osViSetSpecialFeatures: not a known feature value (%d)",
"osViSetSpecialFeatures: VI Manager not yet begun",
"osViSetMode: VI Manager not yet begun by osCreateViManager",
"osViSetEvent: VI Manager not yet begun by osCreateViManager",
"osViSwapBuffer: frame buffer not aligned to 64 bytes (0x%x)",
"osViSwapBuffer: VI Manager not yet begun",
"osCreateViManager: priority not in range [0-255] (%d)",
"osCreateRegion: not a known alignment (%d)",
"osCreateRegion: length (%d) too small for buffer size (%d)",
"osMalloc: invalid or corrupt region (0x%x)",
"osFree: invalid or corrupt region (0x%x)",
"osFree: invalid address (0x%x) or\n corrupt region (0x%x)",
"osGetRegionBufCount: invalid or corrupt region (0x%x)",
"osGetRegionBufSize: invalid or corrupt region (0x%x)",
"osSpTaskLoad: dram_stack not aligned to 16 bytes (0x%x)",
"osSpTaskLoad: output_buff not aligned to 16 bytes (0x%x)",
"osSpTaskLoad: output_buff_size not aligned to 16 bytes (0x%x)",
"osSpTaskLoad: yield_data_ptr not aligned to 16 bytes (0x%x)",
"osProfileInit: profile counter is running, call osProfileStop before init",
"osProfileInit: profcnt is %d",
"osProfileInit: histo_base pointer must be 32-bit aligned (%x)",
"osProfileInit: text_start (%x) >= text_end (%x)",
"osProfileInit: histo_size is an illegal size (%d)",
"osProfileStart: microseconds is < PROF_MIN_INTERVAL (%d)",
"osProfileStart: profiling has already been started",
"osProfileStop: profiling has already been stopped",
"osProfileStop: no profile timer to stop",
"osReadHost: address not aligned to 8 bytes (0x%x)",
"osReadHost: size either 0 or not aligned to 4 bytes (0x%x)",
"osWriteHost: address not aligned to 8 bytes (0x%x)",
"osWriteHost: size either 0 or not aligned to 4 bytes (0x%x)",
"osGetTime: VI manager not yet begun by osCreateViManager",
"osSetTime: VI manager not yet begun by osCreateViManager",
"osSetTimer: VI manager not yet begun by osCreateViManager",
"osStopTimer: VI manager not yet begun by osCreateViManager",
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
NULSTR,
"_handleMIDIMsg: no sound mapped",
"_handleMIDIMsg: no free voices",
"_handleMIDIMsg: couldn't map voice",
"_handleMIDIMsg: note off - couldn't find voice",
"_handleMIDIMsg: poly pressure - couldn't find voice",
"_handleEvent: no free voices",
"Synthesizer: no free updates",
"alSndPDeallocate: attempt to deallocate a sound which is playing",
"alSndpDelete: attempt to delete player with playing sounds",
"alSndpPlay: attempt to play a sound which is playing",
"alSndpSetSound: sound id (%d) out of range (0 - %d)",
"alSndpSetPriority: sound id (%d) out of range (0 - %d)",
"alSndpSet Parameter: target (%d) out of range (0 - %d)",
"alBnkfNew: bank file out of date",
"alSeqNew: 0x%x is not a midi file",
"alSeqNew: 0x%x is not a type 0 midi file",
"alSeqNew: 0x%x has more than 1 track",
"alSeqNew: SMPTE delta times not supported",
"alSeqNew: Error parsing file 0x%x (no track header)",
"alSeqNextEvent: Unsupported system exclusive",
"alSeqNextEvent: Unsupported midi meta event 0x%x",
"_handleMIDIMsg: Invalid program change to %d, max instruments %d",
"_handleMIDIMsg: Unknown midi message 0x%x",
"_unmapVoice: Couldn't unmap voice 0x%x",
"alEvtqPostEvent: Out of free events",
"alHeapAlloc: Can't allocate %d bytes",
"alHeapCheck: Heap corrupt",
"alHeapCheck: Heap corrupt - first block is bad",
"alCSeqGetTrackEvent: Running status of zero on track %d",
"alCSeqGetTrackEvent: Note on velocity of zero on track %d",
"alCSPVoiceHandler: Stopping sequence but voice not free chan %d, key %d",
"alSeqNextEvent: Read past end of sequence",
"osAiSetNextBuffer: DMA buffer location may cause audio clicks (0x%x)",
"_loadOutputBuffer: Modulated delay greater than total delay by %d samples",
"osViExtendVStart: VI Manager not yet begun by osCreateViManager",
"osViExtendVStart: value not in range [0-48] %d",
NULSTR,
};
static void kmcErrorHandler(s16 code, s16 numArgs, ...);
OSErrorHandler __kmcErrorHandler = kmcErrorHandler;
static void kmcErrorHandler(s16 code, s16 numArgs, ...) {
va_list ap;
const char* fmt;
fmt = __os_error_message[code];
va_start(ap, numArgs);
if (__kmc_pt_mode) {
_Printf(kmc_proutSyncPrintf, NULL, fmt, ap);
} else {
_Printf(proutSyncPrintf, NULL, fmt, ap);
}
osSyncPrintf("\n");
va_end(ap);
}

View File

@@ -1,60 +0,0 @@
/*
* Copyright 1995, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
*
* UNPUBLISHED -- Rights reserved under the copyright laws of the United
* States. Use of a copyright notice is precautionary only and does not
* imply publication or disclosure.
*
* U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
* in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
* in similar or successor clauses in the FAR, or the DOD or NASA FAR
* Supplement. Contractor/manufacturer is Silicon Graphics, Inc.,
* 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
*
* THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
* INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
* DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
* PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
* GRAPHICS, INC.
*
*/
/*
* File: mtxcatf.c
* Creator: hsa@sgi.com
* Create Date: Thu Nov 2 13:03:02 PST 1995
*
*/
#include "guint.h"
void guMtxCatF(float mf[4][4], float nf[4][4], float res[4][4]) {
int i, j, k;
float temp[4][4];
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
temp[i][j] = 0.0;
for (k = 0; k < 4; k++) {
temp[i][j] += mf[i][k] * nf[k][j];
}
}
}
/* make sure we handle case where result is an input */
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
res[i][j] = temp[i][j];
}
}
}
void guMtxXFMF(float mf[4][4], float x, float y, float z, float* ox, float* oy, float* oz) {
*ox = mf[0][0] * x + mf[1][0] * y + mf[2][0] * z + mf[3][0];
*oy = mf[0][1] * x + mf[1][1] * y + mf[2][1] * z + mf[3][1];
*oz = mf[0][2] * x + mf[1][2] * y + mf[2][2] * z + mf[3][2];
}

View File

@@ -1,22 +0,0 @@
/**************************************************************************
* *
* Copyright (C) 1994, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#include "guint.h"
void guNormalize(float* x, float* y, float* z) {
float m;
m = 1 / sqrtf((*x) * (*x) + (*y) * (*y) + (*z) * (*z));
*x *= m;
*y *= m;
*z *= m;
}

View File

@@ -1,30 +0,0 @@
/**************************************************************************
* *
* Copyright (C) 1994, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#include "guint.h"
void guScaleF(float mf[4][4], float x, float y, float z) {
guMtxIdentF(mf);
mf[0][0] = x;
mf[1][1] = y;
mf[2][2] = z;
mf[3][3] = 1;
}
void guScale(Mtx* m, float x, float y, float z) {
Matrix mf;
guScaleF(mf, x, y, z);
guMtxF2L(mf, m);
}

View File

@@ -1,29 +0,0 @@
/**************************************************************************
* *
* Copyright (C) 1994, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#include "guint.h"
void guTranslateF(float mf[4][4], float x, float y, float z) {
guMtxIdentF(mf);
mf[3][0] = x;
mf[3][1] = y;
mf[3][2] = z;
}
void guTranslate(Mtx* m, float x, float y, float z) {
Matrix mf;
guTranslateF(mf, x, y, z);
guMtxF2L(mf, m);
}

View File

@@ -1,6 +1,4 @@
#ifdef MODERN_CC
.set gp=64
#endif
#include "PR/R4300.h"
#include "sys/asm.h"

View File

@@ -6,8 +6,4 @@
LEAF(__osGetFpcCsr)
CFC1( v0, fcr31)
jr ra
#ifndef MODERN_CC
END(__osGetSR) # @bug: Should be __osGetFpcCsr
#else
END(__osGetFpcCsr)
#endif

View File

@@ -21,7 +21,6 @@ u32 __OSGlobalIntMask = OS_IM_ALL;
#ifdef _FINALROM
u32 __osFinalrom;
#else
u32 __kmc_pt_mode;
void* __printfunc = NULL;
#endif

View File

@@ -7,8 +7,4 @@ LEAF(__osSetFpcCsr)
CFC1( v0, fcr31)
CTC1( a0, fcr31)
jr ra
#ifndef MODERN_CC
END(__osSetSR) # @bug: Should be __osSetFpcCsr
#else
END(__osSetFpcCsr)
#endif
END(__osSetFpcCsr)

View File

@@ -1,424 +0,0 @@
#ifndef _FINALROM
#include "PR/os_internal.h"
#include "PRinternal/dbgproto.h"
#include "PR/rcp.h"
#include "PR/sptask.h"
#include "PRinternal/rmonint.h"
#include "PRinternal/macros.h"
// TODO: this comes from a header
#ident "$Revision: 1.4 $"
#define TMP_BP 0
#define NUM_BREAKPOINTS 16
typedef struct {
TVushort type;
TVushort response;
TVid threadID;
void* pc;
} TVExceptionReplyMsg;
typedef struct {
u32* breakAddress;
u32 oldInstruction;
} BREAKINFO;
/* first breakpoint is reserved for implementing single-stepping */
static BREAKINFO breakpoints[NUM_BREAKPOINTS] ALIGNED(0x8);
/* breakpoint for alternate branch target */
static BREAKINFO altBreak;
static BREAKINFO RCPbreakpoints[NUM_BREAKPOINTS] ALIGNED(0x8);
u8 __rmonRcpAtBreak;
static void rmonFindFaultedThreads(void);
static void SetTempBreakpoint(u32* addr1, u32* addr2) {
STUBBED_PRINTF(("Set temp BP at %08x", addr1));
if (addr2 != NULL) {
STUBBED_PRINTF((" and %08x", addr2));
}
STUBBED_PRINTF(("\n"));
/* Save the word at the target address to be restored later */
breakpoints[TMP_BP].oldInstruction = *addr1;
/* Install a break instruction at the target address */
*addr1 = MIPS_BREAK(16);
osWritebackDCache(addr1, sizeof(*addr1));
osInvalICache(addr1, sizeof(*addr1));
breakpoints[TMP_BP].breakAddress = addr1;
/* Also do so for an alt address if required */
if (addr2 != NULL) {
altBreak.oldInstruction = *addr2;
*addr2 = MIPS_BREAK(16);
osWritebackDCache(addr2, sizeof(*addr2));
osInvalICache(addr2, sizeof(*addr2));
altBreak.breakAddress = addr2;
}
}
static void ClearTempBreakpoint(void) {
u32 inst;
if (breakpoints[TMP_BP].breakAddress != NULL) {
inst = *breakpoints[TMP_BP].breakAddress;
if ((inst & MIPS_BREAK_MASK) == MIPS_BREAK_OPCODE) {
STUBBED_PRINTF(("ClearTempBreak @ %08x\n", breakpoints[TMP_BP].breakAddress));
/* After confirming that there is a break instruction with code at the target
address, restore the original contents of the word at the target address */
*breakpoints[TMP_BP].breakAddress = breakpoints[TMP_BP].oldInstruction;
osWritebackDCache(breakpoints[TMP_BP].breakAddress, sizeof(*breakpoints[TMP_BP].breakAddress));
osInvalICache(breakpoints[TMP_BP].breakAddress, sizeof(*breakpoints[TMP_BP].breakAddress));
}
breakpoints[TMP_BP].breakAddress = NULL;
}
/* Same as above for the alt breakpoint */
if (altBreak.breakAddress != NULL) {
inst = *altBreak.breakAddress;
if ((inst & MIPS_BREAK_MASK) == MIPS_BREAK_OPCODE) {
STUBBED_PRINTF(("ClearTempBreak @ %08x\n", altBreak.breakAddress));
*altBreak.breakAddress = altBreak.oldInstruction;
osWritebackDCache(altBreak.breakAddress, sizeof(*altBreak.breakAddress));
osInvalICache(altBreak.breakAddress, sizeof(*altBreak.breakAddress));
}
altBreak.breakAddress = NULL;
}
}
int __rmonSetBreak(KKHeader* req) {
register KKSetBkptRequest* request = (KKSetBkptRequest*)req;
register BREAKINFO* breakBase;
register BREAKINFO* whichBreak;
register BREAKINFO* lastBreak;
KKBkptEvent reply;
STUBBED_PRINTF(("SetBreak at %08x, method %d\n", request->addr, req->method));
/* Select breakpoint list */
if (req->method == RMON_RSP) {
breakBase = RCPbreakpoints;
whichBreak = &RCPbreakpoints[1];
lastBreak = &RCPbreakpoints[NUM_BREAKPOINTS];
} else {
breakBase = breakpoints;
whichBreak = &breakpoints[1];
lastBreak = &breakpoints[NUM_BREAKPOINTS];
}
/* Find breakpoint slot */
for (; whichBreak < lastBreak; whichBreak++) {
if (whichBreak->breakAddress != NULL) {
if (whichBreak->breakAddress == (u32*)request->addr) {
/* Breakpoint already set here */
break;
}
continue;
} else {
/* Empty slot */
break;
}
}
/* No breakpoints available */
if (whichBreak == lastBreak) {
return TV_ERROR_NO_MORE_IDS;
}
/* Set breakpoint if not already set */
if (whichBreak->breakAddress == NULL) {
if (req->method == RMON_RSP) {
whichBreak->oldInstruction = __rmonReadWordAt((u32*)request->addr);
__rmonWriteWordTo((u32*)request->addr, MIPS_BREAK((whichBreak - breakBase) + NUM_BREAKPOINTS));
} else {
whichBreak->oldInstruction = *(u32*)request->addr;
*(u32*)request->addr = MIPS_BREAK((whichBreak - breakBase) + NUM_BREAKPOINTS);
osWritebackDCache((void*)request->addr, sizeof(whichBreak->oldInstruction));
osInvalICache((void*)request->addr, sizeof(whichBreak->oldInstruction));
}
whichBreak->breakAddress = (u32*)request->addr;
STUBBED_PRINTF(("* (%08x) = %08x (was %08x)\n", whichBreak->breakAddress, *whichBreak->breakAddress,
whichBreak->oldInstruction));
}
/* Send reply */
reply.header.code = request->header.code;
reply.header.error = TV_ERROR_NO_ERROR;
reply.object = request->object;
reply.bp = whichBreak - breakBase;
reply.instruction = whichBreak->oldInstruction;
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
return TV_ERROR_NO_ERROR;
}
int __rmonListBreak(KKHeader* request UNUSED) {
STUBBED_PRINTF(("ListBreak\n"));
return TV_ERROR_ILLEGAL_CALL;
}
int __rmonClearBreak(KKHeader* req) {
register KKClrBkptRequest* request = (KKClrBkptRequest*)req;
register BREAKINFO* whichBreak;
KKBkptEvent reply;
u32 inst;
STUBBED_PRINTF(("ClearBreak\n"));
/* Check valid breakpoint index */
if (request->bp >= NUM_BREAKPOINTS) {
return TV_ERROR_INVALID_ID;
}
/* Clear the breakpoint, restore whatever was there before */
if (req->method == RMON_RSP) {
whichBreak = &RCPbreakpoints[request->bp];
if (whichBreak->breakAddress == NULL) {
return TV_ERROR_INVALID_ID;
}
inst = __rmonReadWordAt(whichBreak->breakAddress);
if ((inst & MIPS_BREAK_MASK) == MIPS_BREAK_OPCODE) {
__rmonWriteWordTo(whichBreak->breakAddress, whichBreak->oldInstruction);
}
} else {
whichBreak = &breakpoints[request->bp];
if (whichBreak->breakAddress == NULL) {
return TV_ERROR_INVALID_ID;
}
inst = *whichBreak->breakAddress;
if ((inst & MIPS_BREAK_MASK) == MIPS_BREAK_OPCODE) {
*whichBreak->breakAddress = whichBreak->oldInstruction;
osWritebackDCache(whichBreak->breakAddress, sizeof(*whichBreak->breakAddress));
osInvalICache(whichBreak->breakAddress, sizeof(*whichBreak->breakAddress));
}
}
whichBreak->breakAddress = NULL;
/* Send reply */
reply.header.code = request->header.code;
reply.header.error = TV_ERROR_NO_ERROR;
reply.object = request->object;
reply.bp = request->bp;
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
return TV_ERROR_NO_ERROR;
}
u32 __rmonGetBranchTarget(int method, int thread, char* addr) {
int inst;
if (method == RMON_RSP) {
inst = __rmonReadWordAt((u32*)addr);
} else {
inst = *(u32*)addr;
}
switch ((inst >> 26) & 0x3F) {
case 0: /* SPECIAL */
if (((inst >> 5) & 0x7FFF) == 0 && (inst & 0x3F) == 8) {
/* JR */
return __rmonGetRegisterContents(method, thread, (inst >> 21) & 0x1F);
}
if (((inst >> 16) & 0x1F) == 0 && (inst & 0x7FF) == 9) {
/* JALR */
return __rmonGetRegisterContents(method, thread, (inst >> 21) & 0x1F);
}
break;
case 1: /* REGIMM */
switch ((inst >> 16) & 0x1F) {
case 0: /* BLTZ */
case 1: /* BGEZ */
case 2: /* BLTZL */
case 3: /* BGEZL */
case 16: /* BLTZAL */
case 17: /* BGEZAL */
case 18: /* BLTZALL */
case 19: /* BGEZALL */
return (((inst << 0x10) >> 0xE) + addr + 4);
}
break;
case 2: /* J */
case 3: /* JAL */
return (((u32)inst << 6) >> 4) + (((s32)((u32)addr + 4) >> 0x1C) << 0x1C);
case 4: /* BEQ */
case 5: /* BNE */
case 20: /* BEQL */
case 21: /* BNEL */
return (((inst << 0x10) >> 0xE) + addr + 4);
case 6: /* BLEZ */
case 7: /* BGTZ */
case 22: /* BLEZL */
case 23: /* BGTZL */
if (((inst >> 16) & 0x1F) == 0) {
return (((inst << 0x10) >> 0xE) + addr + 4);
}
break;
case 16: /* COP0 */
case 17: /* COP1 */
case 18: /* COP2 */
case 19: /* COP3 */
if (((inst >> 21) & 0x1F) == 8) {
switch ((inst >> 16) & 0x1F) {
case 0: /* BCzF */
case 1: /* BCzT */
case 2: /* BCzFL */
case 3: /* BCzTL */
return (((inst << 0x10) >> 0xE) + addr + 4);
}
}
break;
}
return -1;
}
static int IsJump(u32 inst) {
switch ((inst >> 26) & 0x3F) {
case 0: /* SPECIAL */
if (((inst >> 5) & 0x7FFF) == 0 && (inst & 0x3F) == 8) {
/* JR */
return TRUE;
}
if (((inst >> 16) & 0x1F) == 0 && (inst & 0x7FF) == 9) {
/* JALR */
return TRUE;
}
break;
case 2: /* J */
case 3: /* JAL */
return TRUE;
}
return FALSE;
}
int __rmonSetSingleStep(int thread, u32* instptr) {
u32 branchTarget = __rmonGetBranchTarget(RMON_CPU, thread, (void*)instptr);
STUBBED_PRINTF(("SingleStep\n"));
if ((branchTarget & 3) != 0) {
/* no branch target, set breakpoint at next pc */
SetTempBreakpoint(instptr + 1, NULL);
} else if (branchTarget == (u32)instptr) {
/* branch target is this instruction, can't single step here */
return FALSE;
} else if (IsJump(*instptr) || branchTarget == (u32)(instptr + 2)) {
/* unconditional branch, set at branch target */
SetTempBreakpoint((u32*)branchTarget, NULL);
} else {
/* set two breakpoints for handling conditional branches */
SetTempBreakpoint((u32*)branchTarget, instptr + 2);
}
return TRUE;
}
void __rmonGetExceptionStatus(KKStatusEvent* reply) {
reply->status.flags = OS_STATE_STOPPED;
reply->status.why = 2;
reply->status.what = 0;
reply->status.rv = 0;
reply->status.info.major = 2;
reply->status.info.minor = 4;
reply->header.code = KK_CODE_THREAD_STATUS;
reply->header.error = TV_ERROR_NO_ERROR;
reply->header.length = sizeof(*reply);
}
#define FAULT_BREAKNUM (NUM_BREAKPOINTS - 1)
static void rmonSendBreakMessage(s32 whichThread, int breakNumber) {
KKStatusEvent reply;
STUBBED_PRINTF(("Break %d in thread %d\n", breakNumber, whichThread));
/* Build thread exception status */
__rmonGetThreadStatus(RMON_CPU, (whichThread != 0) ? whichThread : RMON_TID_NOTHREAD, &reply);
__rmonGetExceptionStatus(&reply);
if (breakNumber == FAULT_BREAKNUM) {
/* Hit fault */
reply.status.info.major = 1;
reply.status.info.minor = 2;
}
if (breakNumber < NUM_BREAKPOINTS) {
breakNumber = 0;
} else {
breakNumber -= NUM_BREAKPOINTS;
}
if (breakNumber != 0) {
/* Break not set by debugger, or set during single-step */
reply.status.instr = MIPS_BREAK_OPCODE;
}
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_EXCEPTION);
}
void __rmonHitBreak(void) {
STUBBED_PRINTF(("HitBreak\n"));
/* Stop all user threads and report faulted threads */
ClearTempBreakpoint();
__rmonStopUserThreads(0);
rmonFindFaultedThreads();
}
void __rmonHitSpBreak(void) {
KKStatusEvent exceptionReply;
STUBBED_PRINTF(("Hit SP Break\n"));
/* Rewind RSP PC by one instruction to return to the location of the break instruction */
__rmonWriteWordTo((u32*)SP_PC_REG, __rmonReadWordAt((u32*)SP_PC_REG) - 4);
/* Report RSP break event */
__rmonGetThreadStatus(RMON_RSP, RMON_TID_RSP, &exceptionReply);
__rmonGetExceptionStatus(&exceptionReply);
__rmonSendReply(&exceptionReply.header, sizeof(exceptionReply), KK_TYPE_EXCEPTION);
__rmonRcpAtBreak = TRUE;
}
void __rmonHitCpuFault(void) {
STUBBED_PRINTF(("HitCpuFault\n"));
/* Stop all user threads and report faulted threads */
__rmonMaskIdleThreadInts();
__rmonStopUserThreads(0);
rmonFindFaultedThreads();
}
static void rmonFindFaultedThreads(void) {
register OSThread* tptr = __osGetActiveQueue();
while (tptr->priority != -1) {
if (tptr->priority > OS_PRIORITY_IDLE && tptr->priority <= OS_PRIORITY_APPMAX) {
if (tptr->flags & OS_FLAG_CPU_BREAK) {
int inst = *(u32*)tptr->context.pc;
STUBBED_PRINTF(("Brk in thread %d @ %08x, inst %08x\r\n", tptr->id, tptr->context.pc, inst));
if ((inst & MIPS_BREAK_MASK) == MIPS_BREAK_OPCODE) {
rmonSendBreakMessage(tptr->id, inst >> 6);
} else {
rmonSendBreakMessage(tptr->id, 0);
}
}
if (tptr->flags & OS_FLAG_FAULT) {
__rmonSendFault(tptr);
rmonSendBreakMessage(tptr->id, FAULT_BREAKNUM);
}
}
tptr = tptr->tlnext;
}
}
#endif

View File

@@ -1,46 +0,0 @@
#ifndef _FINALROM
#include "PRinternal/dbgproto.h"
#include "PRinternal/rmonint.h"
#include "PRinternal/macros.h"
// TODO: this comes from a header
#ident "$Revision: 1.4 $"
static int NotImplemented(KKHeader* dummy UNUSED) {
return TV_ERROR_ILLEGAL_CALL;
}
static FUNPTR dispatchTable[] = {
__rmonLoadProgram, __rmonListProcesses, __rmonGetExeName, __rmonListThreads, __rmonThreadStatus,
NotImplemented, __rmonStopThread, __rmonRunThread, NotImplemented, NotImplemented,
__rmonSetFault, NotImplemented, __rmonGetRegionCount, __rmonGetRegions, __rmonGetGRegisters,
__rmonSetGRegisters, __rmonGetFRegisters, __rmonSetFRegisters, __rmonReadMem, __rmonWriteMem,
__rmonSetBreak, __rmonClearBreak, __rmonListBreak, NotImplemented, NotImplemented,
NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented,
__rmonSetComm, NotImplemented, NotImplemented, NotImplemented, NotImplemented,
NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented,
NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented,
NotImplemented, NotImplemented, NotImplemented, NotImplemented, __rmonGetSRegs,
__rmonSetSRegs, __rmonGetVRegs, __rmonSetVRegs, NotImplemented,
};
int __rmonExecute(KKHeader* request) {
int retval;
KKHeader reply;
if (request->code >= ARRLEN(dispatchTable) - 1) {
return TV_ERROR_ILLEGAL_CALL;
}
retval = dispatchTable[(int)request->code](request);
if (retval < TV_ERROR_NO_ERROR) {
reply.code = request->code;
reply.error = retval;
__rmonSendReply(&reply, sizeof(reply), KK_TYPE_REPLY);
}
return retval;
}
#endif

View File

@@ -1,127 +0,0 @@
#include "PR/os_version.h"
#ifndef _FINALROM
#include "PRinternal/dbgproto.h"
#include "PR/os_internal.h"
#include "PRinternal/rmonint.h"
#include "PR/rcp.h"
#include "PR/sptask.h"
#include "PR/rdb.h"
#include "PRinternal/macros.h"
// TODO: this comes from a header
#ident "$Revision: 1.4 $"
int __rmonActive = FALSE;
static vu32 somethingToDo;
static u32 inbuffer[280] ALIGNED(0x10);
static u8 cmdinptr;
static u8 cmdoutptr;
static int state;
static char* inPointer;
void __rmonSendHeader(KKHeader* const block, u32 blockSize, u32 type) {
int sent;
char* cPtr = (char*)block;
block->rev = KK_REV;
block->type = type;
sent = 0;
while (sent < blockSize) {
sent += __osRdbSend(cPtr + sent, blockSize - sent, RDB_TYPE_GtoH_DEBUG);
}
}
void __rmonSendReply(KKHeader* const block, u32 blockSize, u32 replyType) {
char* cPtr;
int sent = 0;
block->length = blockSize;
cPtr = (char*)&blockSize;
/* send size */
while (sent < (signed)sizeof(blockSize)) {
sent += __osRdbSend(cPtr + sent, sizeof(blockSize) - sent, RDB_TYPE_GtoH_DEBUG);
}
/* send data */
__rmonSendHeader(block, blockSize, replyType);
__rmonIOflush();
}
void __rmonSendData(char* const block, unsigned int blockSize) {
int* blockPointer = (int*)block;
unsigned int wordCount = (u32)(blockSize + 3) / 4;
u32 data;
union {
char bufBytes[4];
u32 bufWord;
} buffer;
if (((u32)block & 3) == 0) {
while (wordCount--) {
if ((u32)blockPointer >= SP_DMEM_START && (u32)blockPointer < 0x05000000) {
__osSpRawReadIo((u32)blockPointer++, &data);
__rmonIOputw(data);
} else {
__rmonIOputw(*(blockPointer++));
}
}
} else
while (wordCount--) {
__rmonMemcpy((u8*)buffer.bufBytes, (u8*)blockPointer, sizeof(buffer));
__rmonIOputw(buffer.bufWord);
blockPointer++;
}
__rmonIOflush();
}
void rmonMain(void) {
register int newChars UNUSED;
STUBBED_PRINTF(("rmon: Thread %d created\n"));
STUBBED_PRINTF(("rmon: Thread %d destroyed\n"));
somethingToDo = 0;
cmdoutptr = 0;
cmdinptr = 0;
__rmonInit();
__rmonActive = TRUE;
state = 0, newChars = 0, inPointer = (void*)&inbuffer;
for (;;) {
OSMesg work;
osRecvMesg(&__rmonMQ, &work, OS_MESG_BLOCK);
somethingToDo |= (u32)work;
if (somethingToDo & RMON_MESG_CPU_BREAK) {
somethingToDo &= ~RMON_MESG_CPU_BREAK;
__rmonHitBreak();
}
if (somethingToDo & RMON_MESG_SP_BREAK) {
somethingToDo &= ~RMON_MESG_SP_BREAK;
__rmonHitSpBreak();
}
if (somethingToDo & RMON_MESG_FAULT) {
somethingToDo &= ~RMON_MESG_FAULT;
__rmonHitCpuFault();
}
if (somethingToDo & 0x10) {
somethingToDo;
somethingToDo &= (u8)~0x10;
}
if (somethingToDo & 0x20) {
somethingToDo;
somethingToDo &= (u8)~0x20;
}
}
}
#endif

Some files were not shown because too many files have changed in this diff Show More