diff --git a/Makefile b/Makefile index a5c2289..ccae37b 100644 --- a/Makefile +++ b/Makefile @@ -82,6 +82,12 @@ ifneq ($(NON_MATCHING),1) @touch $@ endif +$(BUILD_DIR)/src/os/assert.marker: OPTFLAGS := -O0 +$(BUILD_DIR)/src/os/ackramromread.marker: OPTFLAGS := -O0 +$(BUILD_DIR)/src/os/ackramromwrite.marker: OPTFLAGS := -O0 +$(BUILD_DIR)/src/os/exit.marker: OPTFLAGS := -O0 +$(BUILD_DIR)/src/os/seterrorhandler.marker: OPTFLAGS := -O0 + $(BUILD_DIR)/%.marker: %.c cd $( RDRAM */ +#define OS_WRITE 1 /* device <- RDRAM */ +#define OS_OTHERS 2 /* for Leo disk only */ + +/* + * I/O message types + */ +#define OS_MESG_TYPE_BASE (10) +#define OS_MESG_TYPE_LOOPBACK (OS_MESG_TYPE_BASE+0) +#define OS_MESG_TYPE_DMAREAD (OS_MESG_TYPE_BASE+1) +#define OS_MESG_TYPE_DMAWRITE (OS_MESG_TYPE_BASE+2) +#define OS_MESG_TYPE_VRETRACE (OS_MESG_TYPE_BASE+3) +#define OS_MESG_TYPE_COUNTER (OS_MESG_TYPE_BASE+4) +#define OS_MESG_TYPE_EDMAREAD (OS_MESG_TYPE_BASE+5) +#define OS_MESG_TYPE_EDMAWRITE (OS_MESG_TYPE_BASE+6) + +/* + * I/O message priority + */ +#define OS_MESG_PRI_NORMAL 0 +#define OS_MESG_PRI_HIGH 1 + +/* + * Page size argument for TLB routines + */ +#define OS_PM_4K 0x0000000 +#define OS_PM_16K 0x0006000 +#define OS_PM_64K 0x001e000 +#define OS_PM_256K 0x007e000 +#define OS_PM_1M 0x01fe000 +#define OS_PM_4M 0x07fe000 +#define OS_PM_16M 0x1ffe000 + +/* + * Stack size for I/O device managers: PIM (PI Manager), VIM (VI Manager), + * SIM (SI Manager) + * + */ +#define OS_PIM_STACKSIZE 4096 +#define OS_VIM_STACKSIZE 4096 +#define OS_SIM_STACKSIZE 4096 + +#define OS_MIN_STACKSIZE 72 + +/* + * Values for osTvType + */ +#define OS_TV_PAL 0 +#define OS_TV_NTSC 1 +#define OS_TV_MPAL 2 + +/* + * Video Interface (VI) mode type + */ +#define OS_VI_NTSC_LPN1 0 /* NTSC */ +#define OS_VI_NTSC_LPF1 1 +#define OS_VI_NTSC_LAN1 2 +#define OS_VI_NTSC_LAF1 3 +#define OS_VI_NTSC_LPN2 4 +#define OS_VI_NTSC_LPF2 5 +#define OS_VI_NTSC_LAN2 6 +#define OS_VI_NTSC_LAF2 7 +#define OS_VI_NTSC_HPN1 8 +#define OS_VI_NTSC_HPF1 9 +#define OS_VI_NTSC_HAN1 10 +#define OS_VI_NTSC_HAF1 11 +#define OS_VI_NTSC_HPN2 12 +#define OS_VI_NTSC_HPF2 13 + +#define OS_VI_PAL_LPN1 14 /* PAL */ +#define OS_VI_PAL_LPF1 15 +#define OS_VI_PAL_LAN1 16 +#define OS_VI_PAL_LAF1 17 +#define OS_VI_PAL_LPN2 18 +#define OS_VI_PAL_LPF2 19 +#define OS_VI_PAL_LAN2 20 +#define OS_VI_PAL_LAF2 21 +#define OS_VI_PAL_HPN1 22 +#define OS_VI_PAL_HPF1 23 +#define OS_VI_PAL_HAN1 24 +#define OS_VI_PAL_HAF1 25 +#define OS_VI_PAL_HPN2 26 +#define OS_VI_PAL_HPF2 27 + +#define OS_VI_MPAL_LPN1 28 /* MPAL - mainly Brazil */ +#define OS_VI_MPAL_LPF1 29 +#define OS_VI_MPAL_LAN1 30 +#define OS_VI_MPAL_LAF1 31 +#define OS_VI_MPAL_LPN2 32 +#define OS_VI_MPAL_LPF2 33 +#define OS_VI_MPAL_LAN2 34 +#define OS_VI_MPAL_LAF2 35 +#define OS_VI_MPAL_HPN1 36 +#define OS_VI_MPAL_HPF1 37 +#define OS_VI_MPAL_HAN1 38 +#define OS_VI_MPAL_HAF1 39 +#define OS_VI_MPAL_HPN2 40 +#define OS_VI_MPAL_HPF2 41 + +/* + * Video Interface (VI) special features + */ +#define OS_VI_GAMMA_ON 0x0001 +#define OS_VI_GAMMA_OFF 0x0002 +#define OS_VI_GAMMA_DITHER_ON 0x0004 +#define OS_VI_GAMMA_DITHER_OFF 0x0008 +#define OS_VI_DIVOT_ON 0x0010 +#define OS_VI_DIVOT_OFF 0x0020 +#define OS_VI_DITHER_FILTER_ON 0x0040 +#define OS_VI_DITHER_FILTER_OFF 0x0080 + +/* + * Video Interface (VI) mode attribute bit + */ +#define OS_VI_BIT_NONINTERLACE 0x0001 /* lo-res */ +#define OS_VI_BIT_INTERLACE 0x0002 /* lo-res */ +#define OS_VI_BIT_NORMALINTERLACE 0x0004 /* hi-res */ +#define OS_VI_BIT_DEFLICKINTERLACE 0x0008 /* hi-res */ +#define OS_VI_BIT_ANTIALIAS 0x0010 +#define OS_VI_BIT_POINTSAMPLE 0x0020 +#define OS_VI_BIT_16PIXEL 0x0040 +#define OS_VI_BIT_32PIXEL 0x0080 +#define OS_VI_BIT_LORES 0x0100 +#define OS_VI_BIT_HIRES 0x0200 +#define OS_VI_BIT_NTSC 0x0400 +#define OS_VI_BIT_PAL 0x0800 + +/* + * Leo Disk + */ + +/* transfer mode */ + +#define LEO_BLOCK_MODE 1 +#define LEO_TRACK_MODE 2 +#define LEO_SECTOR_MODE 3 + +/* + * Controllers number + */ + +#ifndef _HW_VERSION_1 +#define MAXCONTROLLERS 4 +#else +#define MAXCONTROLLERS 6 +#endif + +/* controller errors */ +#define CONT_NO_RESPONSE_ERROR 0x8 +#define CONT_OVERRUN_ERROR 0x4 +#ifdef _HW_VERSION_1 +#define CONT_FRAME_ERROR 0x2 +#define CONT_COLLISION_ERROR 0x1 +#endif + +/* Controller type */ + +#define CONT_ABSOLUTE 0x0001 +#define CONT_RELATIVE 0x0002 +#define CONT_JOYPORT 0x0004 +#define CONT_EEPROM 0x8000 +#define CONT_EEP16K 0x4000 +#define CONT_TYPE_MASK 0x1f07 +#define CONT_TYPE_NORMAL 0x0005 +#define CONT_TYPE_MOUSE 0x0002 + +/* Controller status */ + +#define CONT_CARD_ON 0x01 +#define CONT_CARD_PULL 0x02 +#define CONT_ADDR_CRC_ER 0x04 +#define CONT_EEPROM_BUSY 0x80 + +/* EEPROM TYPE */ + +#define EEPROM_TYPE_4K 0x01 +#define EEPROM_TYPE_16K 0x02 + +/* Buttons */ + +#define CONT_A 0x8000 +#define CONT_B 0x4000 +#define CONT_G 0x2000 +#define CONT_START 0x1000 +#define CONT_UP 0x0800 +#define CONT_DOWN 0x0400 +#define CONT_LEFT 0x0200 +#define CONT_RIGHT 0x0100 +#define CONT_L 0x0020 +#define CONT_R 0x0010 +#define CONT_E 0x0008 +#define CONT_D 0x0004 +#define CONT_C 0x0002 +#define CONT_F 0x0001 + +/* Nintendo's official button names */ + +#define A_BUTTON CONT_A +#define B_BUTTON CONT_B +#define L_TRIG CONT_L +#define R_TRIG CONT_R +#define Z_TRIG CONT_G +#define START_BUTTON CONT_START +#define U_JPAD CONT_UP +#define L_JPAD CONT_LEFT +#define R_JPAD CONT_RIGHT +#define D_JPAD CONT_DOWN +#define U_CBUTTONS CONT_E +#define L_CBUTTONS CONT_C +#define R_CBUTTONS CONT_F +#define D_CBUTTONS CONT_D + +/* File System size */ +#define OS_PFS_VERSION 0x0200 +#define OS_PFS_VERSION_HI (OS_PFS_VERSION >> 8) +#define OS_PFS_VERSION_LO (OS_PFS_VERSION & 255) + +#define PFS_FILE_NAME_LEN 16 +#define PFS_FILE_EXT_LEN 4 +#define BLOCKSIZE 32 /* bytes */ +#define PFS_ONE_PAGE 8 /* blocks */ +#define PFS_MAX_BANKS 62 + +/* File System flag */ + +#define PFS_READ 0 +#define PFS_WRITE 1 +#define PFS_CREATE 2 + +/* File System status */ +#define PFS_INITIALIZED 0x1 +#define PFS_CORRUPTED 0x2 /* File system was corrupted */ + +/* File System error number */ + +#define PFS_ERR_NOPACK 1 /* no memory card is plugged or */ +#define PFS_ERR_NEW_PACK 2 /* ram pack has been changed to a */ + /* different one */ +#define PFS_ERR_INCONSISTENT 3 /* need to run Pfschecker */ +#define PFS_ERR_CONTRFAIL CONT_OVERRUN_ERROR +#define PFS_ERR_INVALID 5 /* invalid parameter or file not exist*/ +#define PFS_ERR_BAD_DATA 6 /* the data read from pack are bad*/ +#define PFS_DATA_FULL 7 /* no free pages on ram pack */ +#define PFS_DIR_FULL 8 /* no free directories on ram pack*/ +#define PFS_ERR_EXIST 9 /* file exists */ +#define PFS_ERR_ID_FATAL 10 /* dead ram pack */ +#define PFS_ERR_DEVICE 11 /* wrong device type*/ + +/* definition for EEPROM */ + +#define EEPROM_MAXBLOCKS 64 +#define EEP16K_MAXBLOCKS 256 +#define EEPROM_BLOCK_SIZE 8 + +/* + * PI/EPI + */ +#define PI_DOMAIN1 0 +#define PI_DOMAIN2 1 + +/* + * Profiler constants + */ +#define PROF_MIN_INTERVAL 50 /* microseconds */ + +/* + * Boot addresses + */ +#define BOOT_ADDRESS_ULTRA 0x80000400 +#define BOOT_ADDRESS_COSIM 0x80002000 +#define BOOT_ADDRESS_EMU 0x20010000 +#define BOOT_ADDRESS_INDY 0x88100000 + +/* + * Size of buffer the retains contents after NMI + */ +#define OS_APP_NMI_BUFSIZE 64 + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/************************************************************************** + * + * Macro definitions + * + */ + +/* PARTNER-N64 */ +#ifdef PTN64 +#define osReadHost osReadHost_pt +#define osWriteHost osWriteHost_pt +#endif + +/* Get count of valid messages in queue */ +#define MQ_GET_COUNT(mq) ((mq)->validCount) + +/* Figure out if message queue is empty or full */ +#define MQ_IS_EMPTY(mq) (MQ_GET_COUNT(mq) == 0) +#define MQ_IS_FULL(mq) (MQ_GET_COUNT(mq) >= (mq)->msgCount) + +/* + * CPU counter increments at 3/4 of bus clock rate: + * + * Bus Clock Proc Clock Counter (1/2 Proc Clock) + * --------- ---------- ------------------------ + * 62.5 Mhz 93.75 Mhz 46.875 Mhz + */ +extern u64 osClockRate; + +#define OS_CLOCK_RATE 62500000LL +#define OS_CPU_COUNTER (OS_CLOCK_RATE*3/4) +#define OS_NSEC_TO_CYCLES(n) (((u64)(n)*(OS_CPU_COUNTER/15625000LL))/(1000000000LL/15625000LL)) +#define OS_USEC_TO_CYCLES(n) (((u64)(n)*(OS_CPU_COUNTER/15625LL))/(1000000LL/15625LL)) +#define OS_CYCLES_TO_NSEC(c) (((u64)(c)*(1000000000LL/15625000LL))/(OS_CPU_COUNTER/15625000LL)) +#define OS_CYCLES_TO_USEC(c) (((u64)(c)*(1000000LL/15625LL))/(OS_CPU_COUNTER/15625LL)) + +/************************************************************************** + * + * Extern variables + * + */ +extern OSViMode osViModeTable[]; /* Global VI mode table */ + +extern OSViMode osViModeNtscLpn1; /* Individual VI NTSC modes */ +extern OSViMode osViModeNtscLpf1; +extern OSViMode osViModeNtscLan1; +extern OSViMode osViModeNtscLaf1; +extern OSViMode osViModeNtscLpn2; +extern OSViMode osViModeNtscLpf2; +extern OSViMode osViModeNtscLan2; +extern OSViMode osViModeNtscLaf2; +extern OSViMode osViModeNtscHpn1; +extern OSViMode osViModeNtscHpf1; +extern OSViMode osViModeNtscHan1; +extern OSViMode osViModeNtscHaf1; +extern OSViMode osViModeNtscHpn2; +extern OSViMode osViModeNtscHpf2; + +extern OSViMode osViModePalLpn1; /* Individual VI PAL modes */ +extern OSViMode osViModePalLpf1; +extern OSViMode osViModePalLan1; +extern OSViMode osViModePalLaf1; +extern OSViMode osViModePalLpn2; +extern OSViMode osViModePalLpf2; +extern OSViMode osViModePalLan2; +extern OSViMode osViModePalLaf2; +extern OSViMode osViModePalHpn1; +extern OSViMode osViModePalHpf1; +extern OSViMode osViModePalHan1; +extern OSViMode osViModePalHaf1; +extern OSViMode osViModePalHpn2; +extern OSViMode osViModePalHpf2; + +extern OSViMode osViModeMpalLpn1; /* Individual VI MPAL modes */ +extern OSViMode osViModeMpalLpf1; +extern OSViMode osViModeMpalLan1; +extern OSViMode osViModeMpalLaf1; +extern OSViMode osViModeMpalLpn2; +extern OSViMode osViModeMpalLpf2; +extern OSViMode osViModeMpalLan2; +extern OSViMode osViModeMpalLaf2; +extern OSViMode osViModeMpalHpn1; +extern OSViMode osViModeMpalHpf1; +extern OSViMode osViModeMpalHan1; +extern OSViMode osViModeMpalHaf1; +extern OSViMode osViModeMpalHpn2; +extern OSViMode osViModeMpalHpf2; + +extern s32 osRomType; /* Bulk or cartridge ROM. 0=cartridge 1=bulk */ +extern void *osRomBase; /* Rom base address of the game image */ +extern s32 osTvType; /* 0 = PAL, 1 = NTSC, 2 = MPAL */ +extern s32 osResetType; /* 0 = cold reset, 1 = NMI */ +extern s32 osCicId; +extern s32 osVersion; +extern u32 osMemSize; /* Memory Size */ +extern s32 osAppNMIBuffer[]; + +extern OSIntMask __OSGlobalIntMask; /* global interrupt mask */ +extern OSPiHandle *__osPiTable; /* The head of OSPiHandle link list */ +extern OSPiHandle *__osDiskHandle; /* For exceptasm to get disk info*/ + + + +/************************************************************************** + * + * Function prototypes + * + */ + +/* Thread operations */ + +extern void osCreateThread(OSThread *, OSId, void (*)(void *), + void *, void *, OSPri); +extern void osDestroyThread(OSThread *); +extern void osYieldThread(void); +extern void osStartThread(OSThread *); +extern void osStopThread(OSThread *); +extern OSId osGetThreadId(OSThread *); +extern void osSetThreadPri(OSThread *, OSPri); +extern OSPri osGetThreadPri(OSThread *); + +/* Message operations */ + +extern void osCreateMesgQueue(OSMesgQueue *, OSMesg *, s32); +extern s32 osSendMesg(OSMesgQueue *, OSMesg, s32); +extern s32 osJamMesg(OSMesgQueue *, OSMesg, s32); +extern s32 osRecvMesg(OSMesgQueue *, OSMesg *, s32); + +/* Event operations */ + +extern void osSetEventMesg(OSEvent, OSMesgQueue *, OSMesg); + +/* Interrupt operations */ + +extern OSIntMask osGetIntMask(void); +extern OSIntMask osSetIntMask(OSIntMask); + +/* RDB port operations */ + +extern void osInitRdb(u8 *sendBuf, u32 sendSize); + +/* Cache operations and macros */ + +extern void osInvalDCache(void *, s32); +extern void osInvalICache(void *, s32); +extern void osWritebackDCache(void *, s32); +extern void osWritebackDCacheAll(void); + +#define OS_DCACHE_ROUNDUP_ADDR(x) (void *)(((((u32)(x)+0xf)/0x10)*0x10)) +#define OS_DCACHE_ROUNDUP_SIZE(x) (u32)(((((u32)(x)+0xf)/0x10)*0x10)) + +/* TLB management routines */ + +extern void osMapTLB(s32, OSPageMask, void *, u32, u32, s32); +extern void osMapTLBRdb(void); +extern void osUnmapTLB(s32); +extern void osUnmapTLBAll(void); +extern void osSetTLBASID(s32); + +/* Address translation routines and macros */ + +extern u32 osVirtualToPhysical(void *); +extern void * osPhysicalToVirtual(u32); + +#define OS_K0_TO_PHYSICAL(x) (u32)(((char *)(x)-0x80000000)) +#define OS_K1_TO_PHYSICAL(x) (u32)(((char *)(x)-0xa0000000)) + +#define OS_PHYSICAL_TO_K0(x) (void *)(((u32)(x)+0x80000000)) +#define OS_PHYSICAL_TO_K1(x) (void *)(((u32)(x)+0xa0000000)) + +/* I/O operations */ + +/* Audio interface (Ai) */ +extern u32 osAiGetStatus(void); +extern u32 osAiGetLength(void); +extern s32 osAiSetFrequency(u32); +extern s32 osAiSetNextBuffer(void *, u32); + +/* Display processor interface (Dp) */ +extern u32 osDpGetStatus(void); +extern void osDpSetStatus(u32); +extern void osDpGetCounters(u32 *); +extern s32 osDpSetNextBuffer(void *, u64); + +/* Peripheral interface (Pi) */ +extern u32 osPiGetStatus(void); +extern s32 osPiGetDeviceType(void); +extern s32 osPiRawWriteIo(u32, u32); +extern s32 osPiRawReadIo(u32, u32 *); +extern s32 osPiRawStartDma(s32, u32, void *, u32); +extern s32 osPiWriteIo(u32, u32); +extern s32 osPiReadIo(u32, u32 *); +extern s32 osPiStartDma(OSIoMesg *, s32, s32, u32, void *, u32, + OSMesgQueue *); +extern void osCreatePiManager(OSPri, OSMesgQueue *, OSMesg *, s32); + +/* Video interface (Vi) */ +extern u32 osViGetStatus(void); +extern u32 osViGetCurrentMode(void); +extern u32 osViGetCurrentLine(void); +extern u32 osViGetCurrentField(void); +extern void *osViGetCurrentFramebuffer(void); +extern void *osViGetNextFramebuffer(void); +extern void osViSetXScale(f32); +extern void osViSetYScale(f32); +extern void osViSetSpecialFeatures(u32); +extern void osViSetMode(OSViMode *); +extern void osViSetEvent(OSMesgQueue *, OSMesg, u32); +extern void osViSwapBuffer(void *); +extern void osViBlack(u8); +extern void osViFade(u8, u16); +extern void osViRepeatLine(u8); +extern void osCreateViManager(OSPri); + +/* Timer interface */ + +extern OSTime osGetTime(void); +extern void osSetTime(OSTime); +extern int osSetTimer(OSTimer *, OSTime, OSTime, + OSMesgQueue *, OSMesg); +extern int osStopTimer(OSTimer *); + +/* Controller interface */ + +extern s32 osContInit(OSMesgQueue *, u8 *, OSContStatus *); +extern s32 osContReset(OSMesgQueue *, OSContStatus *); +extern s32 osContStartQuery(OSMesgQueue *); +extern s32 osContStartReadData(OSMesgQueue *); +#ifndef _HW_VERSION_1 +extern s32 osContSetCh(u8); +#endif +extern void osContGetQuery(OSContStatus *); +extern void osContGetReadData(OSContPad *); + +/* file system interface */ + +extern s32 osPfsInitPak(OSMesgQueue *, OSPfs *, int); +extern s32 osPfsRepairId(OSPfs *); +extern s32 osPfsInit(OSMesgQueue *, OSPfs *, int); +extern s32 osPfsReFormat(OSPfs *, OSMesgQueue *, int); +extern s32 osPfsChecker(OSPfs *); +extern s32 osPfsAllocateFile(OSPfs *, u16, u32, u8 *, u8 *, int, s32 *); +extern s32 osPfsFindFile(OSPfs *, u16, u32, u8 *, u8 *, s32 *); +extern s32 osPfsDeleteFile(OSPfs *, u16, u32, u8 *, u8 *); +extern s32 osPfsReadWriteFile(OSPfs *, s32, u8, int, int, u8 *); +extern s32 osPfsFileState(OSPfs *, s32, OSPfsState *); +extern s32 osPfsGetLabel(OSPfs *, u8 *, int *); +extern s32 osPfsSetLabel(OSPfs *, u8 *); +extern s32 osPfsIsPlug(OSMesgQueue *, u8 *); +extern s32 osPfsFreeBlocks(OSPfs *, s32 *); +extern s32 osPfsNumFiles(OSPfs *, s32 *, s32 *); + +/* EEPROM interface */ + +extern s32 osEepromProbe(OSMesgQueue *); +extern s32 osEepromRead(OSMesgQueue *, u8, u8 *); +extern s32 osEepromWrite(OSMesgQueue *, u8, u8 *); +extern s32 osEepromLongRead(OSMesgQueue *, u8, u8 *, int); +extern s32 osEepromLongWrite(OSMesgQueue *, u8, u8 *, int); + +/* MOTOR interface */ + +extern s32 osMotorInit(OSMesgQueue *, OSPfs *, int); +extern s32 osMotorStop(OSPfs *); +extern s32 osMotorStart(OSPfs *); + +/* Enhanced PI interface */ + +extern OSPiHandle *osCartRomInit(void); +extern OSPiHandle *osLeoDiskInit(void); +extern OSPiHandle *osDriveRomInit(void); + +extern s32 osEPiDeviceType(OSPiHandle *, OSPiInfo *); +extern s32 osEPiRawWriteIo(OSPiHandle *, u32 , u32); +extern s32 osEPiRawReadIo(OSPiHandle *, u32 , u32 *); +extern s32 osEPiRawStartDma(OSPiHandle *, s32 , u32 , void *, u32 ); +extern s32 osEPiWriteIo(OSPiHandle *, u32 , u32 ); +extern s32 osEPiReadIo(OSPiHandle *, u32 , u32 *); +extern s32 osEPiStartDma(OSPiHandle *, OSIoMesg *, s32); +extern s32 osEPiLinkHandle(OSPiHandle *); + +/* Profiler Interface */ + +extern void osProfileInit(OSProf *, u32 profcnt); +extern void osProfileStart(u32); +extern void osProfileFlush(void); +extern void osProfileStop(void); + +/* Game <> Host data transfer functions */ + +extern s32 osTestHost(void); +extern void osReadHost(void *, u32); +extern void osWriteHost(void *, u32); +extern void osAckRamromRead(void); +extern void osAckRamromWrite(void); + + +/* byte string operations */ + +extern void bcopy(const void *, void *, int); +extern int bcmp(const void *, const void *, int); +extern void bzero(void *, int); + +/* Miscellaneous operations */ + +extern void osInitialize(void); +extern u32 osGetCount(void); +extern void osExit(void); +extern u32 osGetMemSize(void); + +/* Printf */ + +extern int sprintf(char *s, const char *fmt, ...); +extern void osSyncPrintf(const char *fmt, ...); +extern void osAsyncPrintf(const char *fmt, ...); +extern int osSyncGetChars(char *buf); +extern int osAsyncGetChars(char *buf); + +#endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* !_OS_H */ diff --git a/include/PR/os_internal.h b/include/PR/os_internal.h new file mode 100644 index 0000000..7f874cd --- /dev/null +++ b/include/PR/os_internal.h @@ -0,0 +1,106 @@ +/************************************************************************** + * + * $Revision: 1.18 $ + * $Date: 1997/02/11 08:26:14 $ + * $Source: /hosts/liberte/disk6/Master/cvsmdev2/PR/include/os_internal.h,v $ + * + **************************************************************************/ + +#ifndef _OS_INTERNAL_H_ +#define _OS_INTERNAL_H_ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +#include "PR/os.h" + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +#include "os_internal_reg.h" +#include "os_internal_exception.h" + +/* Routines to get/fetch coprocessor 0 registers */ + +extern u32 __osGetCause(void); +extern void __osSetCause(u32); +extern u32 __osGetCompare(void); +extern void __osSetCompare(u32); +extern u32 __osGetConfig(void); +extern void __osSetConfig(u32); +extern void __osSetCount(u32); +extern u32 __osGetSR(void); +extern void __osSetSR(u32); +extern u32 __osDisableInt(void); +extern void __osRestoreInt(u32); + +/* Routines to get/set floating-point control and status register */ +extern u32 __osSetFpcCsr(u32); +extern u32 __osGetFpcCsr(void); + +/* Routine for global interrupt mask */ +extern void __osSetGlobalIntMask(OSHWIntr); +extern void __osResetGlobalIntMask(OSHWIntr); + +/* Routine for global interrupt mask */ +extern s32 __osLeoInterrupt(void); + +/* Routines for fetch TLB info */ + +extern u32 __osGetTLBASID(void); +extern u32 __osGetTLBPageMask(s32); +extern u32 __osGetTLBHi(s32); +extern u32 __osGetTLBLo0(s32); +extern u32 __osGetTLBLo1(s32); + +/* Serial interface (Si) */ + +extern u32 __osSiGetStatus(void); +extern s32 __osSiRawWriteIo(u32, u32); +extern s32 __osSiRawReadIo(u32, u32 *); +extern s32 __osSiRawStartDma(s32, void *); + +/* Signal processor interface (Sp) */ + +extern u32 __osSpGetStatus(void); +extern void __osSpSetStatus(u32); +extern s32 __osSpSetPc(u32); +extern s32 __osSpRawWriteIo(u32, u32); +extern s32 __osSpRawReadIo(u32, u32 *); +extern s32 __osSpRawStartDma(s32, u32, void *, u32); + +/* Error handling */ + +extern void __osError(s16, s16, ...); +extern OSThread * __osGetCurrFaultedThread(void); +extern OSThread * __osGetNextFaultedThread(OSThread *); + +/* Development board functions */ + +extern void __osGIOInit(s32); +extern void __osGIOInterrupt(s32); +extern void __osGIORawInterrupt(s32); + +/* For debugger use */ + +extern OSThread * __osGetActiveQueue(void); + +/* Debug port */ +extern void __osSyncPutChars(int, int, const char *); +extern int __osSyncGetChars(char *); +extern void __osAsyncPutChars(int, int, const char *); +extern int __osAsyncGetChars(char *); +extern int __osAtomicInc(unsigned int *p); +extern int __osAtomicDec(unsigned int *p); + +/* routine for rdb port */ +extern u32 __osRdbSend(u8 *buf, u32 size, u32 type); + + +#endif /* _LANGUAGE_C */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* !_OS_INTERNAL_H */ diff --git a/include/PR/os_internal_exception.h b/include/PR/os_internal_exception.h new file mode 100644 index 0000000..198657e --- /dev/null +++ b/include/PR/os_internal_exception.h @@ -0,0 +1,36 @@ +/*---------------------------------------------------------------------* + + $RCSfile: os_internal_exception.h,v $ + $Revision: 1.1 $ + $Date: 1998/10/09 08:01:10 $ + *---------------------------------------------------------------------*/ + +#ifndef _OS_INTERNAL_EXCEPTION_H_ +#define _OS_INTERNAL_EXCEPTION_H_ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +#include "PR/os.h" + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/* Routine for HW interrupt "handler" */ +extern void __osSetHWIntrRoutine(OSHWIntr interrupt, + s32 (*handler)(void), void *stackEnd); +extern void __osGetHWIntrRoutine(OSHWIntr interrupt, + s32 (**handler)(void), void **stackEnd); + +/* Routine for global interrupt mask */ +extern void __osSetGlobalIntMask(OSHWIntr); +extern void __osResetGlobalIntMask(OSHWIntr); + + +#endif /* _LANGUAGE_C */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* !_OS_INTERNAL_EXCEPTION_H */ diff --git a/include/PR/os_internal_reg.h b/include/PR/os_internal_reg.h new file mode 100644 index 0000000..6ed720e --- /dev/null +++ b/include/PR/os_internal_reg.h @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------* + + $RCSfile: os_internal_reg.h,v $ + $Revision: 1.2 $ + $Date: 1999/03/10 12:19:14 $ + *---------------------------------------------------------------------*/ + +#ifndef _OS_INTERNAL_REG_H_ +#define _OS_INTERNAL_REG_H_ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +#include "PR/os.h" + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/* Routines to get/fetch coprocessor 0 registers */ + +extern u32 __osGetCause(void); +extern void __osSetCause(u32); +extern u32 __osGetCompare(void); +extern void __osSetCompare(u32); +extern u32 __osGetConfig(void); +extern void __osSetConfig(u32); +extern void __osSetCount(u32); +extern u32 __osGetSR(void); +extern void __osSetSR(u32); +extern u32 __osDisableInt(void); +extern void __osRestoreInt(u32); +extern u32 __osGetWatchLo(void); +extern void __osSetWatchLo(u32); + +/* Routines to get/set floating-point control and status register */ +extern u32 __osSetFpcCsr(u32); +extern u32 __osGetFpcCsr(void); + + +#endif /* _LANGUAGE_C */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* !_OS_INTERNAL_REG_H */ diff --git a/include/PR/rcp.h b/include/PR/rcp.h index 2a2b0e2..9a21a87 100644 --- a/include/PR/rcp.h +++ b/include/PR/rcp.h @@ -66,6 +66,10 @@ #define RDRAM_0_DEVICE_ID 0 #define RDRAM_1_DEVICE_ID 1 +#define RDRAM_RESET_MODE 0 +#define RDRAM_ACTIVE_MODE 1 +#define RDRAM_STANDBY_MODE 2 + #define RDRAM_LENGTH (2 * 512 * 2048) #define RDRAM_0_BASE_ADDRESS (RDRAM_0_DEVICE_ID * RDRAM_LENGTH) #define RDRAM_1_BASE_ADDRESS (RDRAM_1_DEVICE_ID * RDRAM_LENGTH) @@ -74,9 +78,46 @@ #define RDRAM_1_CONFIG 0x00400 #define RDRAM_GLOBAL_CONFIG 0x80000 -#define RDRAM_RESET_MODE 0 -#define RDRAM_ACTIVE_MODE 1 -#define RDRAM_STANDBY_MODE 2 +/** + * PIF Physical memory map (total size = 2 KB) + * + * Size Description Mode + * 1FC007FF +-------+-----------------+-----+ + * | 64 B | JoyChannel RAM | R/W | + * 1FC007C0 +-------+-----------------+-----+ + * |1984 B | Boot ROM | * | * = Reserved + * 1FC00000 +-------+-----------------+-----+ + */ +#define PIF_ROM_START 0x1FC00000 +#define PIF_ROM_END 0x1FC007BF +#define PIF_RAM_START 0x1FC007C0 +#define PIF_RAM_END 0x1FC007FF + + +/** + * Controller channel + * Each game controller channel has 4 error bits that are defined in bit 6-7 of + * the Rx and Tx data size area bytes. Programmers need to clear these bits + * when setting the Tx/Rx size area values for a channel + */ +#define CHNL_ERR_NORESP 0x80 /* Bit 7 (Rx): No response error */ +#define CHNL_ERR_OVERRUN 0x40 /* Bit 6 (Rx): Overrun error */ +#define CHNL_ERR_FRAME 0x80 /* Bit 7 (Tx): Frame error */ +#define CHNL_ERR_COLLISION 0x40 /* Bit 6 (Tx): Collision error */ + +#define CHNL_ERR_MASK 0xC0 /* Bit 6-7: channel errors */ + + +/** + * External device info + */ +#define DEVICE_TYPE_CART 0 /* ROM cartridge */ +#define DEVICE_TYPE_BULK 1 /* ROM bulk */ +#define DEVICE_TYPE_64DD 2 /* 64 Disk Drive */ +#define DEVICE_TYPE_SRAM 3 /* SRAM */ +/* 4-6 are reserved */ +#define DEVICE_TYPE_INIT 7 /* initial value */ +/* 8-14 are reserved */ /** * Signal Processor (SP) Memory @@ -87,7 +128,7 @@ #define SP_IMEM_END 0x04001FFF /** - * Signal Processor (SP) Registers + * Signal Processor (SP) CP0 Registers */ #define SP_BASE_REG 0x04040000 @@ -119,9 +160,6 @@ //! SP PC (R/W): [11:0] program counter #define SP_PC_REG 0x04080000 -//! SP IMEM BIST REG (R/W): [6:0] BIST status bits -#define SP_IBIST_REG 0x04080004 - /** * SP_MEM_ADDR_REG: bit 12 */ @@ -195,6 +233,11 @@ #define SP_SET_CPUSIGNAL SP_SET_SIG4 #define SP_STATUS_CPUSIGNAL SP_STATUS_SIG4 +/* + * SP IMEM BIST REG (R/W): [6:0] BIST status bits; see below for detail + */ +#define SP_IBIST_REG 0x04080004 + /* * SP_IBIST_REG: write bits */ @@ -749,20 +792,23 @@ #define SI_STATUS_INTERRUPT (1 << 12) // Interrupt is set /** - * PIF Physical memory map (total size = 2 KB) - * - * Size Description Mode - * 1FC007FF +-------+-----------------+-----+ - * | 64 B | JoyChannel RAM | R/W | - * 1FC007C0 +-------+-----------------+-----+ - * |1984 B | Boot ROM | * | * = Reserved - * 1FC00000 +-------+-----------------+-----+ + * Development Board GIO Control Registers */ -#define PIF_ROM_START 0x1FC00000 -#define PIF_ROM_END 0x1FC007BF -#define PIF_RAM_START 0x1FC007C0 -#define PIF_RAM_END 0x1FC007FF +#define GIO_BASE_REG 0x18000000 + +/* Game to Host Interrupt */ +#define GIO_GIO_INTR_REG (GIO_BASE_REG+0x000) + +/* Game to Host SYNC */ +#define GIO_GIO_SYNC_REG (GIO_BASE_REG+0x400) + +/* Host to Game Interrupt */ +#define GIO_CART_INTR_REG (GIO_BASE_REG+0x800) + +/** + * Common macros + */ #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) #define IO_READ(addr) (*(vu32*)PHYS_TO_K1(addr)) #define IO_WRITE(addr,data) (*(vu32*)PHYS_TO_K1(addr)=(u32)(data)) diff --git a/include/PR/rdb.h b/include/PR/rdb.h new file mode 100644 index 0000000..e149a7c --- /dev/null +++ b/include/PR/rdb.h @@ -0,0 +1,93 @@ + +/************************************************************************** + * + * $Revision: 1.6 $ + * $Date: 1997/02/11 08:29:31 $ + * $Source: /exdisk2/cvs/N64OS/Master/cvsmdev2/PR/include/rdb.h,v $ + * + **************************************************************************/ + +#ifndef _RDB_H +#define _RDB_H + +/* U64 side address */ +#define RDB_BASE_REG 0xc0000000 +#define RDB_WRITE_INTR_REG (RDB_BASE_REG + 0x8) +#define RDB_READ_INTR_REG (RDB_BASE_REG + 0xc) +#define RDB_BASE_VIRTUAL_ADDR 0x80000000 + +/* packet type Have six bits, so can have up to 63 types */ +#define RDB_TYPE_INVALID 0 +#define RDB_TYPE_GtoH_PRINT 1 +#define RDB_TYPE_GtoH_FAULT 2 +#define RDB_TYPE_GtoH_LOG_CT 3 +#define RDB_TYPE_GtoH_LOG 4 +#define RDB_TYPE_GtoH_READY_FOR_DATA 5 +#define RDB_TYPE_GtoH_DATA_CT 6 +#define RDB_TYPE_GtoH_DATA 7 +#define RDB_TYPE_GtoH_DEBUG 8 +#define RDB_TYPE_GtoH_RAMROM 9 +#define RDB_TYPE_GtoH_DEBUG_DONE 10 +#define RDB_TYPE_GtoH_DEBUG_READY 11 +#define RDB_TYPE_GtoH_KDEBUG 12 +#define RDB_TYPE_GtoH_PROF_DATA 22 + + +#define RDB_TYPE_HtoG_LOG_DONE 13 +#define RDB_TYPE_HtoG_DEBUG 14 +#define RDB_TYPE_HtoG_DEBUG_CT 15 +#define RDB_TYPE_HtoG_DATA 16 +#define RDB_TYPE_HtoG_DATA_DONE 17 +#define RDB_TYPE_HtoG_REQ_RAMROM 18 +#define RDB_TYPE_HtoG_FREE_RAMROM 19 +#define RDB_TYPE_HtoG_KDEBUG 20 +#define RDB_TYPE_HtoG_PROF_SIGNAL 21 + + +#define RDB_PROF_ACK_SIG 1 +#define RDB_PROF_FLUSH_SIG 2 +#define PROF_BLOCK_SIZE 2048 + +#define RDB_LOG_MAX_BLOCK_SIZE 0x8000 +#define RDB_DATA_MAX_BLOCK_SIZE 0x8000 + + +/* GIO side address */ +#define GIO_RDB_BASE_REG 0xbf480000 +#define GIO_RDB_WRITE_INTR_REG (GIO_RDB_BASE_REG + 0x8) +#define GIO_RDB_READ_INTR_REG (GIO_RDB_BASE_REG + 0xc) + +/* minor device number */ +#define GIO_RDB_PRINT_MINOR 1 +#define GIO_RDB_DEBUG_MINOR 2 + +/* interrupt bit */ +#define GIO_RDB_WRITE_INTR_BIT 0x80000000 +#define GIO_RDB_READ_INTR_BIT 0x40000000 + +/* debug command */ +#define DEBUG_COMMAND_NULL 0 +#define DEBUG_COMMAND_MEMORY 1 +#define DEBUG_COMMAND_REGISTER 2 +#define DEBUG_COMMAND_INVALID 255 + +/* debug state */ +#define DEBUG_STATE_NULL 0 +#define DEBUG_STATE_RECEIVE 1 +#define DEBUG_STATE_INVALID 255 + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/* Structure for debug port */ +typedef struct { + unsigned type : 6; /* 0: invalid, 1: print, 2: debug */ + unsigned length : 2; /* 1, 2, or 3 */ + char buf[3]; /* character buffer */ +} rdbPacket; + +extern unsigned int __osRdbWriteOK; +extern unsigned int __osRdbSendMessage; + +#endif /* _LANGUAGE_C */ + +#endif /* !_RDB_H */ diff --git a/include/PR/ultraerror.h b/include/PR/ultraerror.h new file mode 100644 index 0000000..b5295ab --- /dev/null +++ b/include/PR/ultraerror.h @@ -0,0 +1,145 @@ +/************************************************************************** + * + * $Revision: 1.23 $ + * $Date: 1997/02/11 08:38:08 $ + * $Source: /hosts/liberte/disk6/Master/cvsmdev2/PR/include/ultraerror.h,v $ + * + **************************************************************************/ + +#ifndef __ULTRAERROR_H__ +#define __ULTRAERROR_H__ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +#include "PR/ultratypes.h" + +#define OS_ERROR_FMT "/usr/lib/PR/error.fmt" +#define OS_ERROR_MAGIC 0x6b617479 + +/* OS error codes */ + +#define ERR_OSCREATETHREAD_SP 1 +#define ERR_OSCREATETHREAD_PRI 2 +#define ERR_OSSTARTTHREAD 3 +#define ERR_OSSETTHREADPRI 4 +#define ERR_OSCREATEMESGQUEUE 5 +#define ERR_OSSENDMESG 6 +#define ERR_OSJAMMESG 7 +#define ERR_OSRECVMESG 8 +#define ERR_OSSETEVENTMESG 9 +#define ERR_OSMAPTLB_INDEX 10 +#define ERR_OSMAPTLB_ASID 11 +#define ERR_OSUNMAPTLB 12 +#define ERR_OSSETTLBASID 13 +#define ERR_OSAISETFREQUENCY 14 +#define ERR_OSAISETNEXTBUFFER_ADDR 15 +#define ERR_OSAISETNEXTBUFFER_SIZE 16 +#define ERR_OSDPSETNEXTBUFFER_ADDR 17 +#define ERR_OSDPSETNEXTBUFFER_SIZE 18 +#define ERR_OSPIRAWREADIO 19 +#define ERR_OSPIRAWWRITEIO 20 +#define ERR_OSPIRAWSTARTDMA_DIR 21 +#define ERR_OSPIRAWSTARTDMA_DEVADDR 22 +#define ERR_OSPIRAWSTARTDMA_ADDR 23 +#define ERR_OSPIRAWSTARTDMA_SIZE 24 +#define ERR_OSPIRAWSTARTDMA_RANGE 25 +#define ERR_OSPIREADIO 26 +#define ERR_OSPIWRITEIO 27 +#define ERR_OSPISTARTDMA_PIMGR 28 +#define ERR_OSPISTARTDMA_PRI 29 +#define ERR_OSPISTARTDMA_DIR 30 +#define ERR_OSPISTARTDMA_DEVADDR 31 +#define ERR_OSPISTARTDMA_ADDR 32 +#define ERR_OSPISTARTDMA_SIZE 33 +#define ERR_OSPISTARTDMA_RANGE 34 +#define ERR_OSCREATEPIMANAGER 35 +#define ERR_OSVIGETCURRENTMODE 36 +#define ERR_OSVIGETCURRENTFRAMEBUFFER 37 +#define ERR_OSVIGETNEXTFRAMEBUFFER 38 +#define ERR_OSVISETXSCALE_VALUE 39 +#define ERR_OSVISETXSCALE_VIMGR 40 +#define ERR_OSVISETYSCALE_VALUE 41 +#define ERR_OSVISETYSCALE_VIMGR 42 +#define ERR_OSVISETSPECIAL_VALUE 43 +#define ERR_OSVISETSPECIAL_VIMGR 44 +#define ERR_OSVISETMODE 45 +#define ERR_OSVISETEVENT 46 +#define ERR_OSVISWAPBUFFER_ADDR 47 +#define ERR_OSVISWAPBUFFER_VIMGR 48 +#define ERR_OSCREATEVIMANAGER 49 +#define ERR_OSCREATEREGION_ALIGN 50 +#define ERR_OSCREATEREGION_SIZE 51 +#define ERR_OSMALLOC 52 +#define ERR_OSFREE_REGION 53 +#define ERR_OSFREE_ADDR 54 +#define ERR_OSGETREGIONBUFCOUNT 55 +#define ERR_OSGETREGIONBUFSIZE 56 +#define ERR_OSSPTASKLOAD_DRAM 57 +#define ERR_OSSPTASKLOAD_OUT 58 +#define ERR_OSSPTASKLOAD_OUTSIZE 59 +#define ERR_OSSPTASKLOAD_YIELD 60 +#define ERR_OSPROFILEINIT_STR 61 +#define ERR_OSPROFILEINIT_CNT 62 +#define ERR_OSPROFILEINIT_ALN 63 +#define ERR_OSPROFILEINIT_ORD 64 +#define ERR_OSPROFILEINIT_SIZ 65 +#define ERR_OSPROFILESTART_TIME 66 +#define ERR_OSPROFILESTART_FLAG 67 +#define ERR_OSPROFILESTOP_FLAG 68 +#define ERR_OSPROFILESTOP_TIMER 69 +#define ERR_OSREADHOST_ADDR 70 +#define ERR_OSREADHOST_SIZE 71 +#define ERR_OSWRITEHOST_ADDR 72 +#define ERR_OSWRITEHOST_SIZE 73 +#define ERR_OSGETTIME 74 +#define ERR_OSSETTIME 75 +#define ERR_OSSETTIMER 76 +#define ERR_OSSTOPTIMER 77 +#define ERR_ALSEQP_NO_SOUND 100 +#define ERR_ALSEQP_NO_VOICE 101 +#define ERR_ALSEQP_MAP_VOICE 102 +#define ERR_ALSEQP_OFF_VOICE 103 +#define ERR_ALSEQP_POLY_VOICE 104 +#define ERR_ALSNDP_NO_VOICE 105 +#define ERR_ALSYN_NO_UPDATE 106 +#define ERR_ALSNDPDEALLOCATE 107 +#define ERR_ALSNDPDELETE 108 +#define ERR_ALSNDPPLAY 109 +#define ERR_ALSNDPSETSOUND 110 +#define ERR_ALSNDPSETPRIORITY 111 +#define ERR_ALSNDPSETPAR 112 +#define ERR_ALBNKFNEW 113 +#define ERR_ALSEQNOTMIDI 114 +#define ERR_ALSEQNOTMIDI0 115 +#define ERR_ALSEQNUMTRACKS 116 +#define ERR_ALSEQTIME 117 +#define ERR_ALSEQTRACKHDR 118 +#define ERR_ALSEQSYSEX 119 +#define ERR_ALSEQMETA 120 +#define ERR_ALSEQPINVALIDPROG 121 +#define ERR_ALSEQPUNKNOWNMIDI 122 +#define ERR_ALSEQPUNMAP 123 +#define ERR_ALEVENTNOFREE 124 +#define ERR_ALHEAPNOFREE 125 +#define ERR_ALHEAPCORRUPT 126 +#define ERR_ALHEAPFIRSTBLOCK 127 +#define ERR_ALCSEQZEROSTATUS 128 +#define ERR_ALCSEQZEROVEL 129 +#define ERR_ALCSPVNOTFREE 130 +#define ERR_ALSEQOVERRUN 131 +#define ERR_OSAISETNEXTBUFFER_ENDADDR 132 +#define ERR_ALMODDELAYOVERFLOW 133 + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) +typedef void (*OSErrorHandler)(s16, s16, ...); + +OSErrorHandler osSetErrorHandler(OSErrorHandler); +#endif + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* __ULTRAERROR_H__ */ diff --git a/src/os/ackramromread.c b/src/os/ackramromread.c new file mode 100644 index 0000000..4aea863 --- /dev/null +++ b/src/os/ackramromread.c @@ -0,0 +1,8 @@ +#include "PR/os_internal.h" + +// TODO: this comes from a header +#ident "$Revision: 1.4 $" + +void osAckRamromRead() { + +} diff --git a/src/os/ackramromwrite.c b/src/os/ackramromwrite.c new file mode 100644 index 0000000..34fe2ad --- /dev/null +++ b/src/os/ackramromwrite.c @@ -0,0 +1,8 @@ +#include "PR/os_internal.h" + +// TODO: this comes from a header +#ident "$Revision: 1.4 $" + +void osAckRamromWrite() { + +} diff --git a/src/os/assert.c b/src/os/assert.c new file mode 100644 index 0000000..d076a24 --- /dev/null +++ b/src/os/assert.c @@ -0,0 +1,5 @@ +#include "PR/os_internal.h" + +void __assert(const char *exp, const char *filename, int line) { + osSyncPrintf("\nASSERTION FAULT: %s, %d: \"%s\"\n", filename, line, exp); +} diff --git a/src/os/atomic.c b/src/os/atomic.c new file mode 100644 index 0000000..f96bb63 --- /dev/null +++ b/src/os/atomic.c @@ -0,0 +1,15 @@ +#include "PR/os_internal.h" + +int __osAtomicDec(unsigned int *p) { + register u32 saveMask = __osDisableInt(); + int mask; + + if (*p) { + (*p)--; + mask = 1; + } else { + mask = 0; + } + __osRestoreInt(saveMask); + return mask; +} diff --git a/src/os/createmesgqueue.c b/src/os/createmesgqueue.c new file mode 100644 index 0000000..4e71cba --- /dev/null +++ b/src/os/createmesgqueue.c @@ -0,0 +1,11 @@ +#include "PR/os_internal.h" +#include "osint.h" + +void osCreateMesgQueue(OSMesgQueue *mq, OSMesg *msg, s32 msgCount) { + mq->mtqueue = &__osThreadTail.next; + mq->fullqueue = &__osThreadTail.next; + mq->validCount = 0; + mq->first = 0; + mq->msgCount = msgCount; + mq->msg = msg; +} diff --git a/src/os/createthread.c b/src/os/createthread.c new file mode 100644 index 0000000..1ae9f0b --- /dev/null +++ b/src/os/createthread.c @@ -0,0 +1,27 @@ +#include "PR/os_internal.h" +#include "PR/R4300.h" +#include "osint.h" + +void osCreateThread(OSThread *t, OSId id, void (*entry)(void *), void *arg, void *sp, OSPri p) { + register u32 saveMask; + OSIntMask mask; + t->id = id; + t->priority = p; + t->next = NULL; + t->queue = NULL; + t->context.pc = (u32)entry; + t->context.a0 = (s64)(s32)arg; // Double cast gets rid of compiler warning + t->context.sp = (s64)(s32)sp - 16; + t->context.ra = (u64)__osCleanupThread; + mask = OS_IM_ALL; + t->context.sr = SR_IMASK | SR_EXL | SR_IE; + t->context.rcp = (mask & RCP_IMASK) >> RCP_IMASKSHIFT; + t->context.fpcsr = (u32)(FPCSR_FS | FPCSR_EV); + t->fp = 0; + t->state = OS_STATE_STOPPED; + t->flags = 0; + saveMask = __osDisableInt(); + t->tlnext = __osActiveQueue; + __osActiveQueue = t; + __osRestoreInt(saveMask); +} diff --git a/src/os/destroythread.c b/src/os/destroythread.c new file mode 100644 index 0000000..43d2436 --- /dev/null +++ b/src/os/destroythread.c @@ -0,0 +1,37 @@ +#include "PR/os_internal.h" +#include "osint.h" + +void osDestroyThread(OSThread *t) { + register u32 saveMask; + register OSThread *pred; + register OSThread *succ; + + saveMask = __osDisableInt(); + + if (t == NULL) { + t = __osRunningThread; + } else if (t->state != OS_STATE_STOPPED) { + __osDequeueThread(t->queue, t); + } + + if (__osActiveQueue == t) { + __osActiveQueue = __osActiveQueue->tlnext; + } else { + pred = __osActiveQueue; + while (pred->priority != -1) { + succ = pred->tlnext; + if (succ == t) { + pred->tlnext = t->tlnext; + break; + } + pred = succ; + succ = pred->tlnext; + } + } + + if (t == __osRunningThread) { + __osDispatchThread(); + } + + __osRestoreInt(saveMask); +} diff --git a/src/os/exit.c b/src/os/exit.c new file mode 100644 index 0000000..d5e60eb --- /dev/null +++ b/src/os/exit.c @@ -0,0 +1,8 @@ +#include "PR/os_internal.h" + +void osExit() { + __osGIOInterrupt(16); + + for (;;); +} + diff --git a/src/os/getactivequeue.c b/src/os/getactivequeue.c new file mode 100644 index 0000000..4175e7d --- /dev/null +++ b/src/os/getactivequeue.c @@ -0,0 +1,6 @@ +#include "PR/os_internal.h" +#include "osint.h" + +OSThread *__osGetActiveQueue(void) { + return __osActiveQueue; +} diff --git a/src/os/getcurrfaultthread.c b/src/os/getcurrfaultthread.c new file mode 100644 index 0000000..7500928 --- /dev/null +++ b/src/os/getcurrfaultthread.c @@ -0,0 +1,6 @@ +#include "PR/os_internal.h" +#include "osint.h" + +OSThread *__osGetCurrFaultedThread() { + return __osFaultedThread; +} diff --git a/src/os/getmemsize.c b/src/os/getmemsize.c new file mode 100644 index 0000000..44fbc19 --- /dev/null +++ b/src/os/getmemsize.c @@ -0,0 +1,35 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" +#include "PR/R4300.h" + +#define STEP 0x100000 +#define SIZE_4MB 0x400000 +#define SIZE_8MB 0x800000 + +u32 osGetMemSize(void) { + vu32* ptr; + u32 size = SIZE_4MB; + u32 data0; + u32 data1; + + while (size < SIZE_8MB) { + ptr = (vu32*)(K1BASE + size); + + data0 = *ptr; + data1 = ptr[STEP / 4 - 1]; + + *ptr ^= ~0; + ptr[STEP / 4 - 1] ^= ~0; + + if ((*ptr != (data0 ^ ~0)) || (ptr[STEP / 4 - 1] != (data1 ^ ~0))) { + return size; + } + + *ptr = data0; + ptr[STEP / 4 - 1] = data1; + + size += STEP; + } + + return size; +} diff --git a/src/os/getnextfaultthread.c b/src/os/getnextfaultthread.c new file mode 100644 index 0000000..9add6dd --- /dev/null +++ b/src/os/getnextfaultthread.c @@ -0,0 +1,28 @@ +#include "PR/os_internal.h" +#include "osint.h" + +OSThread *__osGetNextFaultedThread(OSThread *lastFault) { + register int saveMask = __osDisableInt(); + register OSThread *fault; + + if (lastFault == NULL) { + fault = __osActiveQueue; + } else { + fault = lastFault; + } + + while (fault->priority != -1) { + if ((fault->flags & OS_FLAG_FAULT) != 0 && fault != lastFault) { + break; + } + fault = fault->tlnext; + } + + if (fault->priority == -1) { + fault = NULL; + } + + __osRestoreInt(saveMask); + return fault; +} + diff --git a/src/os/getthreadid.c b/src/os/getthreadid.c new file mode 100644 index 0000000..9aac16d --- /dev/null +++ b/src/os/getthreadid.c @@ -0,0 +1,10 @@ +#include "PR/os_internal.h" +#include "osint.h" + +OSId osGetThreadId(OSThread *thread) { + if (thread == NULL) { + thread = __osRunningThread; + } + + return thread->id; +} diff --git a/src/os/getthreadpri.c b/src/os/getthreadpri.c new file mode 100644 index 0000000..a1e9ce2 --- /dev/null +++ b/src/os/getthreadpri.c @@ -0,0 +1,10 @@ +#include "PR/os_internal.h" +#include "osint.h" + +OSPri osGetThreadPri(OSThread *thread) { + if (thread == NULL) { + thread = __osRunningThread; + } + + return thread->priority; +} diff --git a/src/os/gettime.c b/src/os/gettime.c new file mode 100644 index 0000000..aee799a --- /dev/null +++ b/src/os/gettime.c @@ -0,0 +1,15 @@ +#include "PR/os_internal.h" +#include "osint.h" + +OSTime osGetTime() { + u32 tmptime; + u32 elapseCount; + OSTime currentCount; + register u32 saveMask; + saveMask = __osDisableInt(); + tmptime = osGetCount(); + elapseCount = tmptime - __osBaseCounter; + currentCount = __osCurrentTime; + __osRestoreInt(saveMask); + return currentCount + elapseCount; +} diff --git a/src/os/initialize.c b/src/os/initialize.c new file mode 100644 index 0000000..7cd169f --- /dev/null +++ b/src/os/initialize.c @@ -0,0 +1,85 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" + +typedef struct +{ + /* 0x0 */ unsigned int inst1; + /* 0x4 */ unsigned int inst2; + /* 0x8 */ unsigned int inst3; + /* 0xC */ unsigned int inst4; +} __osExceptionVector; +extern __osExceptionVector __osExceptionPreamble; + +extern OSPiHandle __Dom1SpeedParam; +extern OSPiHandle __Dom2SpeedParam; + +OSTime osClockRate = OS_CLOCK_RATE; +s32 osViClock = VI_NTSC_CLOCK; +u32 __osShutdown = 0; +u32 __OSGlobalIntMask = OS_IM_ALL; +u32 __osFinalrom; + +void __createSpeedParam(void) { + __Dom1SpeedParam.type = DEVICE_TYPE_INIT; + __Dom1SpeedParam.latency = IO_READ(PI_BSD_DOM1_LAT_REG); + __Dom1SpeedParam.pulse = IO_READ(PI_BSD_DOM1_PWD_REG); + __Dom1SpeedParam.pageSize = IO_READ(PI_BSD_DOM1_PGS_REG); + __Dom1SpeedParam.relDuration = IO_READ(PI_BSD_DOM1_RLS_REG); + + __Dom2SpeedParam.type = DEVICE_TYPE_INIT; + __Dom2SpeedParam.latency = IO_READ(PI_BSD_DOM2_LAT_REG); + __Dom2SpeedParam.pulse = IO_READ(PI_BSD_DOM2_PWD_REG); + __Dom2SpeedParam.pageSize = IO_READ(PI_BSD_DOM2_PGS_REG); + __Dom2SpeedParam.relDuration = IO_READ(PI_BSD_DOM2_RLS_REG); +} + +void __osInitialize_common() { + u32 pifdata; + __osFinalrom = TRUE; + __osSetSR(__osGetSR() | SR_CU1); //enable fpu + __osSetFpcCsr(FPCSR_FS | FPCSR_EV); //flush denorm to zero, enable invalid operation + __osSetWatchLo(0x4900000); + + while (__osSiRawReadIo(PIF_RAM_END - 3, &pifdata)) { //last byte of joychannel ram + ; + } + while (__osSiRawWriteIo(PIF_RAM_END - 3, pifdata | 8)) { + ; //todo: magic contant + } + *(__osExceptionVector *)UT_VEC = __osExceptionPreamble; + *(__osExceptionVector *)XUT_VEC = __osExceptionPreamble; + *(__osExceptionVector *)ECC_VEC = __osExceptionPreamble; + *(__osExceptionVector *)E_VEC = __osExceptionPreamble; + osWritebackDCache((void *)UT_VEC, E_VEC - UT_VEC + sizeof(__osExceptionVector)); + osInvalICache((void *)UT_VEC, E_VEC - UT_VEC + sizeof(__osExceptionVector)); + __createSpeedParam(); + osUnmapTLBAll(); + osMapTLBRdb(); + osClockRate = osClockRate * 3 / 4; + + if (osResetType == 0 ) { // cold reset + bzero(osAppNMIBuffer, OS_APP_NMI_BUFSIZE); + } + + if (osTvType == OS_TV_PAL) { + osViClock = VI_PAL_CLOCK; + } else if (osTvType == OS_TV_MPAL) { + osViClock = VI_MPAL_CLOCK; + } else { + osViClock = VI_NTSC_CLOCK; + } + + // Wait until there are no RCP interrupts + if (__osGetCause() & CAUSE_IP5) { + while (TRUE) { + ; + } + } + + IO_WRITE(AI_CONTROL_REG, AI_CONTROL_DMA_ON); + IO_WRITE(AI_DACRATE_REG, AI_MAX_DAC_RATE - 1); + IO_WRITE(AI_BITRATE_REG, AI_MAX_BIT_RATE - 1); +} + +void __osInitialize_autodetect() { +} diff --git a/src/os/initrdb.c b/src/os/initrdb.c new file mode 100644 index 0000000..9ead917 --- /dev/null +++ b/src/os/initrdb.c @@ -0,0 +1 @@ +//not included in the rom build of libultra diff --git a/src/os/jammesg.c b/src/os/jammesg.c new file mode 100644 index 0000000..289d850 --- /dev/null +++ b/src/os/jammesg.c @@ -0,0 +1,27 @@ +#include "PR/os_internal.h" +#include "osint.h" + +s32 osJamMesg(OSMesgQueue *mq, OSMesg msg, s32 flag) { + register u32 saveMask = __osDisableInt(); + + while (mq->validCount >= mq->msgCount) { + if (flag == OS_MESG_BLOCK) { + __osRunningThread->state = OS_STATE_WAITING; + __osEnqueueAndYield(&mq->fullqueue); + } else { + __osRestoreInt(saveMask); + return -1; + } + } + + mq->first = (mq->first + mq->msgCount - 1) % mq->msgCount; + mq->msg[mq->first] = msg; + mq->validCount++; + + if (mq->mtqueue->next != NULL) { + osStartThread(__osPopThread(&mq->mtqueue)); + } + + __osRestoreInt(saveMask); + return 0; +} diff --git a/src/os/kdebugserver.c b/src/os/kdebugserver.c new file mode 100644 index 0000000..c98009b --- /dev/null +++ b/src/os/kdebugserver.c @@ -0,0 +1,4 @@ +#include "PR/os_internal.h" + +//not included in final rom, but __osThreadSave is here for some reason +OSThread __osThreadSave; diff --git a/src/os/osint.h b/src/os/osint.h new file mode 100644 index 0000000..a68d02f --- /dev/null +++ b/src/os/osint.h @@ -0,0 +1,50 @@ +#ifndef _OSINT_H +#define _OSINT_H +#include "PR/os_internal.h" +typedef struct __OSEventState +{ + OSMesgQueue *messageQueue; + OSMesg message; +} __OSEventState; +extern struct __osThreadTail +{ + OSThread *next; + OSPri priority; +} __osThreadTail; + +//maybe should be in exceptasm.h? +extern void __osEnqueueAndYield(OSThread **); +extern void __osDequeueThread(OSThread **, OSThread *); +extern void __osEnqueueThread(OSThread **, OSThread *); +extern OSThread *__osPopThread(OSThread **); +extern void __osDispatchThread(void); +extern void __osCleanupThread(void); + +extern void __osSetTimerIntr(OSTime); +extern OSTime __osInsertTimer(OSTimer *); +extern void __osTimerInterrupt(void); +extern u32 __osProbeTLB(void *); +extern int __osSpDeviceBusy(void); + +extern OSThread *__osRunningThread; +extern OSThread *__osActiveQueue; +extern OSThread *__osFaultedThread; +extern OSThread *__osRunQueue; + +extern OSTimer *__osTimerList; +extern OSTimer __osBaseTimer; +extern OSTime __osCurrentTime; +extern u32 __osBaseCounter; +extern u32 __osViIntrCount; +extern u32 __osTimerCounter; +extern u32 __osShutdown; + +extern __OSEventState __osEventStateTab[OS_NUM_EVENTS]; + + +//not sure if this should be here +extern s32 osViClock; +extern void __osTimerServicesInit(void); +extern s32 __osAiDeviceBusy(void); +extern int __osDpDeviceBusy(void); +#endif diff --git a/src/os/physicaltovirtual.c b/src/os/physicaltovirtual.c new file mode 100644 index 0000000..a0c1bae --- /dev/null +++ b/src/os/physicaltovirtual.c @@ -0,0 +1,6 @@ +#include "PR/os_internal.h" +#include "PR/R4300.h" + +void *osPhysicalToVirtual(u32 addr) { + return (void *)PHYS_TO_K0(addr); +} diff --git a/src/os/rdbsend.c b/src/os/rdbsend.c new file mode 100644 index 0000000..b561d99 --- /dev/null +++ b/src/os/rdbsend.c @@ -0,0 +1 @@ +/* this file is completely empty in the rom release */ diff --git a/src/os/recvmesg.c b/src/os/recvmesg.c new file mode 100644 index 0000000..f7f0e63 --- /dev/null +++ b/src/os/recvmesg.c @@ -0,0 +1,31 @@ +#include "PR/os_internal.h" +#include "osint.h" + +s32 osRecvMesg(OSMesgQueue *mq, OSMesg *msg, s32 flags) { + register u32 saveMask; + saveMask = __osDisableInt(); + + while (MQ_IS_EMPTY(mq)) { + if (flags == OS_MESG_NOBLOCK) { + __osRestoreInt(saveMask); + return -1; + } + + __osRunningThread->state = OS_STATE_WAITING; + __osEnqueueAndYield(&mq->mtqueue); + } + + if (msg != NULL) { + *msg = mq->msg[mq->first]; + } + + mq->first = (mq->first + 1) % mq->msgCount; + mq->validCount--; + + if (mq->fullqueue->next != NULL) { + osStartThread(__osPopThread(&mq->fullqueue)); + } + + __osRestoreInt(saveMask); + return 0; +} diff --git a/src/os/resetglobalintmask.c b/src/os/resetglobalintmask.c new file mode 100644 index 0000000..780da7c --- /dev/null +++ b/src/os/resetglobalintmask.c @@ -0,0 +1,9 @@ +#include "PR/os_internal.h" + +void __osResetGlobalIntMask(OSHWIntr mask) { + register u32 saveMask = __osDisableInt(); + + __OSGlobalIntMask &= ~(mask & ~OS_IM_RCP); + + __osRestoreInt(saveMask); +} diff --git a/src/os/sendmesg.c b/src/os/sendmesg.c new file mode 100644 index 0000000..4d48d08 --- /dev/null +++ b/src/os/sendmesg.c @@ -0,0 +1,28 @@ +#include "PR/os_internal.h" +#include "osint.h" + +s32 osSendMesg(OSMesgQueue *mq, OSMesg msg, s32 flags) { + register u32 saveMask; + register s32 last; + saveMask = __osDisableInt(); + while (MQ_IS_FULL(mq)) { + if (flags == OS_MESG_BLOCK) { + __osRunningThread->state = OS_STATE_WAITING; + __osEnqueueAndYield(&mq->fullqueue); + } else { + __osRestoreInt(saveMask); + return -1; + } + } + + last = (mq->first + mq->validCount) % mq->msgCount; + mq->msg[last] = msg; + mq->validCount++; + + if (mq->mtqueue->next != NULL) { + osStartThread(__osPopThread(&mq->mtqueue)); + } + + __osRestoreInt(saveMask); + return 0; +} diff --git a/src/os/seterrorhandler.c b/src/os/seterrorhandler.c new file mode 100644 index 0000000..4e839e8 --- /dev/null +++ b/src/os/seterrorhandler.c @@ -0,0 +1,10 @@ +#include "PR/ultraerror.h" + +extern OSErrorHandler __osErrorHandler; + +OSErrorHandler osSetErrorHandler(OSErrorHandler handler) { + OSErrorHandler oldHandler = __osErrorHandler; + + __osErrorHandler = handler; + return oldHandler; +} diff --git a/src/os/seteventmesg.c b/src/os/seteventmesg.c new file mode 100644 index 0000000..dd2ad99 --- /dev/null +++ b/src/os/seteventmesg.c @@ -0,0 +1,23 @@ +#include "macros.h" +#include "PR/os_internal.h" +#include "osint.h" + +__OSEventState __osEventStateTab[OS_NUM_EVENTS] ALIGNED(8); +u32 __osPreNMI = FALSE; + +void osSetEventMesg(OSEvent event, OSMesgQueue *mq, OSMesg msg) { + register u32 saveMask = __osDisableInt(); + __OSEventState *es = &__osEventStateTab[event]; + + es->messageQueue = mq; + es->message = msg; + + if (event == OS_EVENT_PRENMI) { + if (__osShutdown && !__osPreNMI) { + osSendMesg(mq, msg, OS_MESG_NOBLOCK); + } + __osPreNMI = TRUE; + } + + __osRestoreInt(saveMask); +} diff --git a/src/os/setglobalintmask.c b/src/os/setglobalintmask.c index 9d6d5f6..1d82b6e 100644 --- a/src/os/setglobalintmask.c +++ b/src/os/setglobalintmask.c @@ -1,17 +1,9 @@ -#include "PR/ultratypes.h" +#include "PR/os_internal.h" -typedef u32 OSEvent; -typedef u32 OSIntMask; -typedef u32 OSPageMask; -typedef u32 OSHWIntr; - -extern OSIntMask __OSGlobalIntMask; /* global interrupt mask */ -extern u32 __osDisableInt(void); -extern void __osRestoreInt(u32); - -void __osSetGlobalIntMask(OSHWIntr mask) -{ +void __osSetGlobalIntMask(OSHWIntr mask) { register u32 saveMask = __osDisableInt(); + __OSGlobalIntMask |= mask; + __osRestoreInt(saveMask); } diff --git a/src/os/sethwinterrupt.c b/src/os/sethwinterrupt.c new file mode 100644 index 0000000..0fc9d30 --- /dev/null +++ b/src/os/sethwinterrupt.c @@ -0,0 +1,16 @@ +#include "PR/os_internal.h" + +struct __osHwInt { + s32 (*handler)(void); + void *stackEnd; +}; + +extern struct __osHwInt __osHwIntTable[]; + +void __osSetHWIntrRoutine(OSHWIntr interrupt, s32 (*handler)(void), void *stackEnd) { + register u32 saveMask= __osDisableInt(); + + __osHwIntTable[interrupt].handler = handler; + __osHwIntTable[interrupt].stackEnd = stackEnd; + __osRestoreInt(saveMask); +} diff --git a/src/os/setthreadpri.c b/src/os/setthreadpri.c new file mode 100644 index 0000000..ab6b23e --- /dev/null +++ b/src/os/setthreadpri.c @@ -0,0 +1,26 @@ +#include "PR/os_internal.h" +#include "osint.h" + +void osSetThreadPri(OSThread *t, OSPri pri) { + register u32 saveMask = __osDisableInt(); + + if (t == NULL) { + t = __osRunningThread; + } + + if (t->priority != pri) { + t->priority = pri; + + if (t != __osRunningThread && t->state != OS_STATE_STOPPED) { + __osDequeueThread(t->queue, t); + __osEnqueueThread(t->queue, t); + } + + if (__osRunningThread->priority < __osRunQueue->priority) { + __osRunningThread->state = OS_STATE_RUNNABLE; + __osEnqueueAndYield(&__osRunQueue); + } + } + + __osRestoreInt(saveMask); +} diff --git a/src/os/settime.c b/src/os/settime.c new file mode 100644 index 0000000..5bae2a2 --- /dev/null +++ b/src/os/settime.c @@ -0,0 +1,6 @@ +#include "PR/os_internal.h" +#include "osint.h" + +void osSetTime(OSTime time) { + __osCurrentTime = time; +} diff --git a/src/os/settimer.c b/src/os/settimer.c new file mode 100644 index 0000000..0b78f27 --- /dev/null +++ b/src/os/settimer.c @@ -0,0 +1,41 @@ +#include "PR/os_internal.h" +#include "osint.h" + +int osSetTimer(OSTimer *t, OSTime countdown, OSTime interval, OSMesgQueue *mq, OSMesg msg) { + register u32 saveMask; + OSTime time; + OSTimer* next; + u32 count; + u32 value; + + t->next = NULL; + t->prev = NULL; + t->value = countdown; + t->interval = interval; + + if (countdown == 0) { + t->value = interval; + } + + t->mq = mq; + t->msg = msg; + + saveMask = __osDisableInt(); + if (__osTimerList->next != __osTimerList) { + next = __osTimerList->next; + count = osGetCount(); + value = count - __osTimerCounter; + + if (value < next->value) { + next->value -= value; + } else { + next->value = 1; + } + } + + time = __osInsertTimer(t); + __osSetTimerIntr(__osTimerList->next->value); + __osRestoreInt(saveMask); + + return 0; +} diff --git a/src/os/startthread.c b/src/os/startthread.c new file mode 100644 index 0000000..deef4ed --- /dev/null +++ b/src/os/startthread.c @@ -0,0 +1,35 @@ +#include "PR/os_internal.h" +#include "osint.h" + +void osStartThread(OSThread *t) { + register u32 saveMask = __osDisableInt(); + + switch (t->state) { + case OS_STATE_WAITING: + t->state = OS_STATE_RUNNABLE; + __osEnqueueThread(&__osRunQueue, t); + break; + case OS_STATE_STOPPED: + if (t->queue == NULL || t->queue == &__osRunQueue) + { + t->state = OS_STATE_RUNNABLE; + __osEnqueueThread(&__osRunQueue, t); + } + else + { + t->state = OS_STATE_WAITING; + __osEnqueueThread(t->queue, t); + __osEnqueueThread(&__osRunQueue, __osPopThread(t->queue)); + } + break; + } + + if (__osRunningThread == NULL) { + __osDispatchThread(); + } else if (__osRunningThread->priority < __osRunQueue->priority) { + __osRunningThread->state = OS_STATE_RUNNABLE; + __osEnqueueAndYield(&__osRunQueue); + } + + __osRestoreInt(saveMask); +} diff --git a/src/os/stopthread.c b/src/os/stopthread.c new file mode 100644 index 0000000..d276b3b --- /dev/null +++ b/src/os/stopthread.c @@ -0,0 +1,25 @@ +#include "PR/os_internal.h" +#include "osint.h" + +void osStopThread(OSThread *t) { + register u32 saveMask = __osDisableInt(); + register u16 state = OS_STATE_RUNNING; + + if (t != NULL) { + state = t->state; + } + + switch (state) { + case OS_STATE_RUNNING: + __osRunningThread->state = OS_STATE_STOPPED; + __osEnqueueAndYield(NULL); + break; + case OS_STATE_RUNNABLE: + case OS_STATE_WAITING: + t->state = OS_STATE_STOPPED; + __osDequeueThread(t->queue, t); + break; + } + + __osRestoreInt(saveMask); +} diff --git a/src/os/stoptimer.c b/src/os/stoptimer.c new file mode 100644 index 0000000..e9e07af --- /dev/null +++ b/src/os/stoptimer.c @@ -0,0 +1,30 @@ +#include "PR/os_internal.h" +#include "osint.h" + +int osStopTimer(OSTimer *t) { + register u32 savedMask; + OSTimer *timep; + + if (t->next == NULL) { + return -1; + } + + savedMask = __osDisableInt(); + timep = t->next; + + if (timep != __osTimerList) { + timep->value += t->value; + } + + t->prev->next = t->next; + t->next->prev = t->prev; + t->next = NULL; + t->prev = NULL; + + if (__osTimerList->next == __osTimerList) { + __osSetCompare(0); + } + + __osRestoreInt(savedMask); + return 0; +} diff --git a/src/os/syncputchars.c b/src/os/syncputchars.c new file mode 100644 index 0000000..9095a04 --- /dev/null +++ b/src/os/syncputchars.c @@ -0,0 +1,32 @@ +#include "PR/os_internal.h" +#include "PR/rdb.h" +#include "PR/rcp.h" +#include "PR/R4300.h" + +unsigned int __osRdbSendMessage = 0; +unsigned int __osRdbWriteOK = 1; + +void __osSyncPutChars(int type, int length, const char *buf) { + rdbPacket packet; + int i; + u32 mask; + packet.type = type; + packet.length = length; + + for (i = 0; i < length; i++) { + packet.buf[i] = buf[i]; + } + + while (!__osAtomicDec(&__osRdbWriteOK)) { + } + + mask = __osDisableInt(); + *(vu32 *)RDB_BASE_REG = *(vu32 *)&packet; + + while (!(__osGetCause() & CAUSE_IP6)) { + } + + *(vu32 *)RDB_READ_INTR_REG = 0; + __osRdbWriteOK++; + __osRestoreInt(mask); +} diff --git a/src/os/testhost.c b/src/os/testhost.c new file mode 100644 index 0000000..70514eb --- /dev/null +++ b/src/os/testhost.c @@ -0,0 +1,4 @@ +#include "PR/os_internal.h" + +// TODO: this comes from a header +#ident "$Revision: 1.4 $" diff --git a/src/os/thread.c b/src/os/thread.c new file mode 100644 index 0000000..767c4cf --- /dev/null +++ b/src/os/thread.c @@ -0,0 +1,25 @@ +#include "PR/os_internal.h" +#include "osint.h" + +struct __osThreadTail __osThreadTail = {NULL, -1}; +OSThread *__osRunQueue = (OSThread *)&__osThreadTail; +OSThread *__osActiveQueue = (OSThread *)&__osThreadTail; +OSThread *__osRunningThread = {0}; +OSThread *__osFaultedThread = {0}; + +void __osDequeueThread(OSThread **queue, OSThread *t) { + register OSThread **pred; + register OSThread *succ; + + pred = queue; + succ = *pred; + + while (succ != NULL) { + if (succ == t) { + *pred = t->next; + return; + } + pred = succ; + succ = *pred; + } +} diff --git a/src/os/timerintr.c b/src/os/timerintr.c new file mode 100644 index 0000000..0f09d1f --- /dev/null +++ b/src/os/timerintr.c @@ -0,0 +1,106 @@ +#include "PR/os_internal.h" +#include "osint.h" + +OSTimer *__osTimerList = &__osBaseTimer; +OSTimer __osBaseTimer; +OSTime __osCurrentTime; +u32 __osBaseCounter; +u32 __osViIntrCount; +u32 __osTimerCounter; + +void __osTimerServicesInit(void) { + __osCurrentTime = 0; + __osBaseCounter = 0; + __osViIntrCount = 0; + __osTimerList->prev = __osTimerList; + __osTimerList->next = __osTimerList->prev; + __osTimerList->value = 0; + __osTimerList->interval = __osTimerList->value; + __osTimerList->mq = NULL; + __osTimerList->msg = 0; +} + +void __osTimerInterrupt(void) { + OSTimer *t; + u32 count; + u32 elapsed_cycles; + + if (__osTimerList->next != __osTimerList) { + while (TRUE) { + t = __osTimerList->next; + if (t == __osTimerList) { + __osSetCompare(0); + __osTimerCounter = 0; + break; + } + + count = osGetCount(); + elapsed_cycles = count - __osTimerCounter; + __osTimerCounter = count; + + if (elapsed_cycles < t->value) + { + t->value -= elapsed_cycles; + __osSetTimerIntr(t->value); + break; + } else { + t->prev->next = t->next; + t->next->prev = t->prev; + t->next = NULL; + t->prev = NULL; + + if (t->mq != NULL) { + osSendMesg(t->mq, t->msg, OS_MESG_NOBLOCK); + } + + if (t->interval != 0) { + t->value = t->interval; + __osInsertTimer(t); + } + } + } + } +} + +void __osSetTimerIntr(OSTime tim) { + OSTime NewTime; + u32 savedMask; + + if (tim < 468) { + tim = 468; + } + + savedMask = __osDisableInt(); + __osTimerCounter = osGetCount(); + NewTime = __osTimerCounter + tim; + __osSetCompare(NewTime); + __osRestoreInt(savedMask); +} + +OSTime __osInsertTimer(OSTimer *t) { + OSTimer *timep; + OSTime tim; + u32 savedMask; + savedMask = __osDisableInt(); + + timep = __osTimerList->next; + tim = t->value; + + while (timep != __osTimerList && tim > timep->value) { + tim -= timep->value; + timep = timep->next; + } + + t->value = tim; + + if (timep != __osTimerList) { + timep->value -= tim; + } + + t->next = timep; + t->prev = timep->prev; + timep->prev->next = t; + timep->prev = t; + __osRestoreInt(savedMask); + return tim; +} diff --git a/src/os/virtualtophysical.c b/src/os/virtualtophysical.c new file mode 100644 index 0000000..5cf9e86 --- /dev/null +++ b/src/os/virtualtophysical.c @@ -0,0 +1,13 @@ +#include "PR/os_internal.h" +#include "PR/R4300.h" +#include "osint.h" + +u32 osVirtualToPhysical(void *addr) { + if (IS_KSEG0(addr)) { + return K0_TO_PHYS(addr); + } else if (IS_KSEG1(addr)) { + return K1_TO_PHYS(addr); + } else { + return __osProbeTLB(addr); + } +} diff --git a/src/os/yieldthread.c b/src/os/yieldthread.c new file mode 100644 index 0000000..f4ed7c5 --- /dev/null +++ b/src/os/yieldthread.c @@ -0,0 +1,10 @@ +#include "PR/os_internal.h" +#include "osint.h" + +void osYieldThread(void) { + register u32 saveMask = __osDisableInt(); + + __osRunningThread->state = OS_STATE_RUNNABLE; + __osEnqueueAndYield(&__osRunQueue); + __osRestoreInt(saveMask); +}