aboutsummaryrefslogtreecommitdiff
path: root/libpsn00b/include/psxapi.h
blob: 35ee04025ab65df437720c26eef97cb477b8cb78 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
/*
 * PSn00bSDK kernel API library
 * (C) 2019-2023 Lameguy64, spicyjpeg - MPL licensed
 */

/**
 * @file psxapi.h
 * @brief Kernel API library header
 *
 * @details This header provides access to most of the APIs made available by
 * the system's BIOS, including basic file I/O, TTY output, controller and
 * memory card drivers, threads, events as well as kernel memory allocation.
 *
 * For more information and up-to-date documentation on kernel APIs, see:
 * https://psx-spx.consoledev.net/kernelbios/
 */

#pragma once

#include <stdint.h>
#include <stddef.h>
#include <hwregs_c.h>

/* Definitions */

// TODO: these desperately need to be cleaned up

#define SEEK_SET	0
#define SEEK_CUR	1
#define SEEK_END	2

#define DescMask	0xff000000		// Event descriptor mask
#define DescTH		DescMask
#define DescHW		0xf0000000		// Hardware event (IRQ)
#define DescEV		0xf1000000		// Event event
#define DescRC		0xf2000000		// Root counter event
#define DescUEV		0xf3000000		// User event
#define DescSW		0xf4000000		// BIOS event

#define	HwVBLANK	(DescHW|0x01)	// VBlank
#define HwGPU		(DescHW|0x02)	// GPU
#define HwCdRom		(DescHW|0x03)	// CDROM
#define HwDMAC		(DescHW|0x04)	// DMA
#define HwRTC0		(DescHW|0x05)	// Timer 0
#define HwRTC1		(DescHW|0x06)	// Timer 1
#define HwRTC2		(DescHW|0x07)	// Timer 2
#define HwCNTL		(DescHW|0x08)	// Controller
#define HwSPU		(DescHW|0x09)	// SPU
#define HwPIO		(DescHW|0x0a)	// PIO & lightgun
#define HwSIO		(DescHW|0x0b)	// Serial

#define HwCPU		(DescHW|0x10)	// Processor exception
#define HwCARD		(DescHW|0x11)	// Memory card (lower level BIOS functions)
#define HwCard_0	(DescHW|0x12)
#define HwCard_1	(DescHW|0x13)
#define SwCARD		(DescSW|0x01)	// Memory card (higher level BIOS functions)
#define SwMATH		(DescSW|0x02)

#define EvSpIOE			0x0004
#define EvSpERROR		0x8000
#define EvSpTIMOUT		0x0100
#define EvSpNEW			0x0200

#define EvMdINTR		0x1000
#define EvMdNOINTR		0x2000

// Root counter (timer) definitions
#define DescRC			0xf2000000

#define RCntCNT0		(DescRC|0x00)
#define RCntCNT1		(DescRC|0x01)
#define RCntCNT2		(DescRC|0x02)
#define RCntCNT3		(DescRC|0x03)

#define RCntMdINTR		0x1000		// Turns on IRQ
#define RCntMdNOINTR	0x2000		// Polling mode
#define RCntMdSC		0x0001		// IRQ when counter target
#define RCntMdSP		0x0000
#define RCntMdFR		0x0000
#define RCntMdGATE		0x0010

/* Structure definitions */

typedef struct {	// Thread control block
	int					status;
	int					mode;
	union {
		uint32_t		reg[37];
		struct {
			uint32_t	zero, at;
			uint32_t	v0, v1;
			uint32_t	a0, a1, a2, a3;
			uint32_t	t0, t1, t2, t3, t4, t5, t6, t7;
			uint32_t	s0, s1, s2, s3, s4, s5, s6, s7;
			uint32_t	t8, t9;
			uint32_t	k0, k1;
			uint32_t	gp, sp, fp, ra;

			uint32_t	cop0r14;
			uint32_t	hi;
			uint32_t	lo;
			uint32_t	cop0r12;
			uint32_t	cop0r13;
		};
	};
	int					_reserved[9];
} TCB;

typedef struct {	// Process control block
	TCB *thread;
} PCB;

typedef struct {					// Device control block
	char	*name;
	int		flags;
	int		ssize;
	char	*desc;
	void	*f_init;
	void	*f_open;
	void	*f_inout;
	void	*f_close;
	void	*f_ioctl;
	void	*f_read;
	void	*f_write;
	void	*f_erase;
	void	*f_undelete;
	void	*f_firstfile;
	void	*f_nextfile;
	void	*f_format;
	void	*f_chdir;
	void	*f_rename;
	void	*f_remove;
	void	*f_testdevice;
} DCB;

typedef struct {			// File control block
	int			status;
	uint32_t	diskid;
	void		*trns_addr;
	uint32_t	trns_len;
	uint32_t	filepos;
	uint32_t	flags;
	uint32_t	lasterr;
	DCB			*dcb;
	uint32_t	filesize;
	uint32_t	lba;
	uint32_t	fcbnum;
} FCB;

struct DIRENTRY {			// Directory entry
	char			name[20];
	int				attr;
	int				size;
	struct DIRENTRY	*next;
	int				head;
	char			system[4];
};

struct EXEC {
	uint32_t pc0, gp0;
	uint32_t t_addr, t_size;
	uint32_t d_addr, d_size;
	uint32_t b_addr, b_size;
	uint32_t s_addr, s_size;
	uint32_t sp, fp, rp, ret, base;
};

struct JMP_BUF {
	uint32_t ra, sp, fp;
	uint32_t s0, s1, s2, s3, s4, s5, s6, s7;
	uint32_t gp;
};

typedef struct {
	uint32_t	*next;
	uint32_t	*func2;
	uint32_t	*func1;
	int			_reserved;
} INT_RP;

/* Fast interrupt disabling macros */

// Clearing the IRQ_MASK register is faster than manipulating cop0r12, even
// though it requires declaring a "hidden" local variable to save its state to;
// it's also resilient to race conditions as there's no read-modify-write
// operation during which an interrupt can occur. Note that interrupt flags in
// the IRQ_STAT register will get set even if the respective enable bits in
// IRQ_MASK are cleared, so doing this will properly defer IRQs rather than
// dropping them.
#define FastEnterCriticalSection() \
	uint16_t __saved_irq_mask = IRQ_MASK; (IRQ_MASK = 0)
#define FastExitCriticalSection() \
	(IRQ_MASK = __saved_irq_mask)

#if 0
#define FastEnterCriticalSection() { \
	uint32_t r0, r1; \
	__asm__ volatile( \
		"mfc0 %0, $12;" \
		"li   %1, -1026;" \
		"and  %1, %0;" \
		"mtc0 %1, $12;" \
		"nop;" \
		: "=r"(r0), "=r"(r1) :: \
	); \
}
#define FastExitCriticalSection() { \
	uint32_t r0; \
	__asm__ volatile( \
		"mfc0 %0, $12;" \
		"nop;" \
		"ori  %0, 0x0401;" \
		"mtc0 %0, $12;" \
		"nop;" \
		: "=r"(r0) :: \
	); \
}
#endif

/* BIOS API */

#ifdef __cplusplus
extern "C" {
#endif

void SysEnqIntRP(int pri, INT_RP *rp);
void SysDeqIntRP(int pri, INT_RP *rp);

int OpenEvent(uint32_t cl, uint32_t spec, int mode, void (*func)());
int CloseEvent(int event);
int WaitEvent(int event);
int TestEvent(int event);
int EnableEvent(int event);
int DisableEvent(int event);
void DeliverEvent(uint32_t cl, uint32_t spec);
void UnDeliverEvent(uint32_t cl, uint32_t spec);

int open(const char *path, int mode);
int close(int fd);
int lseek(int fd, uint32_t offset, int mode);
int read(int fd, void *buff, size_t len);
int write(int fd, const void *buff, size_t len);
int getc(int fd);
int putc(int ch, int fd);
int ioctl(int fd, int cmd, int arg);
int isatty(int fd);
struct DIRENTRY *firstfile(const char *wildcard, struct DIRENTRY *entry);
struct DIRENTRY *nextfile(struct DIRENTRY *entry);
int erase(const char *path);
int undelete(const char *path);
int cd(const char *path);

int _get_errno(void);
int _get_error(int fd);

int AddDrv(DCB *dcb);
int DelDrv(const char *name);
void ListDrv(void);
void add_nullcon_driver(void);

int EnterCriticalSection(void);
void ExitCriticalSection(void);
int SwEnterCriticalSection(void);
void SwExitCriticalSection(void);

void _InitCd(void);
void _96_init(void);
void _96_remove(void);

void InitPAD(uint8_t *buff1, int len1, uint8_t *buff2, int len2);
void StartPAD(void);
void StopPAD(void);

void InitCARD(int pad_enable);
void StartCARD(void);
void StopCARD(void);
void _bu_init(void);

int _card_load(int chan);
int _card_info(int chan);
int _card_status(int chan);
int _card_wait(int chan);
int _card_clear(int chan);
int _card_chan(void);
int _card_read(int chan, int sector, uint8_t *buf);
int _card_write(int chan, int sector, uint8_t *buf);
void _new_card(void);

int SetRCnt(int spec, uint16_t target, int mode);
int GetRCnt(int spec);
int StartRCnt(int spec);
int StopRCnt(int spec);
int ResetRCnt(int spec);

void ChangeClearPAD(int mode);
void ChangeClearRCnt(int t, int m);

int OpenTh(uint32_t (*func)(), uint32_t sp, uint32_t gp);
int CloseTh(int thread);
int ChangeTh(int thread);

int Exec(struct EXEC *exec, int argc, const char **argv);
int LoadExec(const char *path, int argc, const char **argv);
void FlushCache(void);

void b_setjmp(struct JMP_BUF *buf);
void b_longjmp(const struct JMP_BUF *buf, int param);
void ResetEntryInt(void);
void HookEntryInt(const struct JMP_BUF *buf);
void ReturnFromException(void);

int SetConf(int evcb, int tcb, uint32_t sp);
void GetConf(int *evcb, int *tcb, uint32_t *sp);
void SetMem(int size);

int GetSystemInfo(int index);
void *GetB0Table(void);
void *GetC0Table(void);

void *alloc_kernel_memory(int size);
void free_kernel_memory(void *ptr);

void _boot(void);

#ifdef __cplusplus
}
#endif