PSX System Calls

注:blackbagの資料をベースにいじってます。

原著者注:私はテストするPSXを持っていないので、いくつかのsyscallは多分間違っています。 しかし、今まで私が解析したところでは、ここで述べたように思えます。

第1欄 - 呼び出しアドレス
第2欄 - 呼び出し時の$t1の値
第3欄 - ファンクション名

引数が必要な場合は常に$a0,1,2,3で渡され、4を越える引数は$sp+0x10で渡されます。

0x00a0 - 0x0000 - int open(char *name , int mode)

 機能
	ファイルを開き、ファイルハンドルを返す

 引数
	name	"デバイス名:ファイル名"
		デバイス名
	 	 cdrom:	CD-ROM。ファイル名はISO-9660レベル1の命名規約で
        		"cdrom:FILENAME;1"と大文字8.3で最後に;1をつける。
		 bu00:	スロット1のメモリカード
		 bu10:	スロット2のメモリカード
		 pcdrv:	caeltaの拡張デバイスで、接続されたPCのファイル。
	mode	アクセスモード
		 1	読み込み
		 2	書き込み
		 0x200	新規作成
		 0x8000	非同期モード?
		 上位16ビット	メモリカードの使用ブロック数

 返り値
	ファイルハンドル エラーは-1

 注
 	一度に16個まで開ける。
 	メモリカードの新規作成の場合は上位16ビットにブロック数(1ブロック8192
 	バイト)を指定し、一度閉じてから書き込みモードで再度開く。作成時に指定
 	したブロック数以上は書き込めない。

0x00a0 - 0x0001 - int lseek(int fd , int offset , int mode)

 機能
	ファイルポインタを移動する

 引数
	fd	ファイルハンドル
	offset	オフセット
	mode
	 0	先頭から
	 1	現在位置から
	 2	末尾から?(k-comm.によるとバグってるらしい)

 返り値
	現在のファイルポインタ エラーは-1

 注
	lseek/read/writeは1バイト単位でなく、デバイス固有のブロックサイズの
 	倍数で行う。CD-ROMは2048、メモリカードは128

0x00a0 - 0x0002 - int read(int fd , char *buf , int nbytes)

 機能
	ファイルから読み込む。

 引数
	fd	ファイルハンドル
	buf	読み込みバッファ
	nbyte	読み込み長さ

 返り値
	実際に読んだ長さ エラーは-1

0x00a0 - 0x0003 - int write(int fd , char *buf , int nbytes)

 機能
	ファイルに書き込む。

 引数
	fd	ファイルハンドル
	buf	書き込みバッファ
	nbyte	書き込み長さ

 返り値
	実際に読んだ長さ エラーは-1

0x00a0 - 0x0004 - close(int fd)

 機能
	ファイルを閉じる

 引数
 	fd	ファイルハンドル

0x00a0 - 0x0005 - int ioctl(int fd , int cmd , int arg)
0x00a0 - 0x0006 - exit()
0x00a0 - 0x0007 - sys_b0_39()
0x00a0 - 0x0008 - char getc(int fd)

 機能
	標準入力から1文字入力する

0x00a0 - 0x0009 - putc(char c , int fd)

 機能
	標準出力に1文字出力する

0x00a0 - 0x000a - todigit

 機能
	不明

0x00a0 - 0x000b - double atof(char *s)

 機能
	文字列をdoubleに変換する

0x00a0 - 0x000c - long strtoul(char *s , char **ptr , int base)
0x00a0 - 0x000d - unsigned long strtol(char *s , char **ptr , int base)
0x00a0 - 0x000e - int abs(int val)

 機能
	絶対値を返す

0x00a0 - 0x000f - long labs(long lval)

 機能
	絶対値をlongで返す(R3000ではlongとintは同じなので多分absと同じ)

0x00a0 - 0x0010 - long atoi(char *s)

 機能
	文字列をintに変換する

0x00a0 - 0x0011 - int atol(char *s)

 機能
	文字列をlongに変換する(R3000ではlongとintは同じなので多分atoiと同じ)

0x00a0 - 0x0012 - atob

 機能
	不明

0x00a0 - 0x0013 - int setjmp(jmp_buf *ctx)

0x00a0 - 0x0014 - longjmp(jmp_buf *ctx , int value)
0x00a0 - 0x0015 - char *strcat(char *dst , char *src)

 機能
	文字列を連結する

0x00a0 - 0x0016 - char *strncat(char *dst , char *src , int n)
0x00a0 - 0x0017 - int strcmp(char *dst , char *src)

 機能
	文字列を比較する

0x00a0 - 0x0018 - int strncmp(char *dst , char *src , int n)

 機能
	文字列の先頭n文字を比較する

0x00a0 - 0x0019 - char *strcpy(char *dst , char *src)

 機能
	文字列を複写する

0x00a0 - 0x001a - char *strncpy(char *dst , char *src , int n))

 機能
	文字列の先頭n文字を複写する

0x00a0 - 0x001b - int strlen(char *s)

 機能
	文字列の長さを返す

0x00a0 - 0x001c - int index(char *s , int c)

 面度臭くなったので以下略。多分標準的なものだと思う。

0x00a0 - 0x001d - int rindex(char *s , int c)
0x00a0 - 0x001e - char *strchr(char *c , int c)
0x00a0 - 0x001f - char *strrchr(char *c , int c)
0x00a0 - 0x0020 - char *strpbrk(char *dst , *src)
0x00a0 - 0x0021 - int strspn(char *s , char *set)
0x00a0 - 0x0022 - int strcspn(char *s , char *set)
0x00a0 - 0x0023 - strtok(char *s , char *set)
0x00a0 - 0x0024 - strstr(char *s , char *set)
0x00a0 - 0x0025 - int toupper(int c)
0x00a0 - 0x0026 - int tolower(int c)
0x00a0 - 0x0027 - void bcopy(void *src , void *dst , int len)
0x00a0 - 0x0028 - void bzero(void *ptr , int len)
0x00a0 - 0x0029 - int bcmp(void *ptr1 , void *ptr2 , int len)
0x00a0 - 0x002a - memcpy(void *dst , void *src , int n)
0x00a0 - 0x002b - memset(void *dst , char c , int n)
0x00a0 - 0x002c - memmove(void *dst , void *src , int n)
0x00a0 - 0x002d - memcmp(void *dst , void *src , int n)
0x00a0 - 0x002e - memchr(void *s , int c , int n)
0x00a0 - 0x002f - int rand()
0x00a0 - 0x0030 - void srand(unsigned int seed)
0x00a0 - 0x0031 - void qsort(void *base , int nel , int width , int (*cmp)*void *,void *))
0x00a0 - 0x0032 - double strtod(char *s , char *endptr)
0x00a0 - 0x0033 - void *malloc(int size)

 注:malloc等を使う前にInitHeapでヒープを初期化しておく

0x00a0 - 0x0034 - free(void *buf)
0x00a0 - 0x0035 - void *lsearch(void *key , void *base , int belp , int width , int (*cmp)(void * , void *))
0x00a0 - 0x0036 - void *bsearch( void *key , void *base , int nel , int size , int (*cmp)(void * , void *))
0x00a0 - 0x0037 - void *calloc(int size , int n)
0x00a0 - 0x0038 - void *realloc(void *buf , int n)
0x00a0 - 0x0039 - InitHeap(void *block , int size)

 機能
	malloc等で使用するヒープを初期化する。

 引数
	block	ヒープの先頭アドレス
	size	ヒープサイズ

0x00a0 - 0x003a - _exit()

0x00a0 - 0x003b - char getchar(void) 

 注:通常はcharを返すが、EOF(-1)を返すことがあるのでintで受けるのがセオリー
     だったような気がするが、もしかしてバグ?それともEOFは絶対返さない?

0x00a0 - 0x003c - putchar(char c)
0x00a0 - 0x003d - char *gets(char *s)
0x00a0 - 0x003e - puts(char *s)
0x00a0 - 0x003f - printf(char *fmt , ...)
0x00a0 - 0x0040 - 

0x00a0 - 0x0041 - LoadTest(char *name , struct EXEC *header)

 機能
	PS-EXEファイルのヘッダを読む

 構造体
   struct EXEC {
	unsigned long pc0;	実行開始アドレス(pc初期値)
	unsigned long gp0;	gpレジスタ初期値
	unsigned long t_addr;	コード(.code)アドレス
	unsigned long t_size;	コードサイズ
	unsigned long d_addr;	初期値ありデータ(.data)アドレス
	unsigned long d_size;	初期値ありデータサイズ
	unsigned long b_addr;	初期値0データ(.bss)アドレス
	unsigned long b_size;	初期値0データサイズ
	unsigned long s_addr;	スタックアドレス?
	unsigned long s_size;	スタックサイズ?
	unsigned long sp,fp,gp,ret,base;	呼び出し側保存用ワーク?
   };

0x00a0 - 0x0042 - Load(char *name , struct EXEC *header)

 機能
	PS-EXEファイルを読み、ヘッダ情報を構造体に設定する

 返り値
	1:成功 0:失敗

0x00a0 - 0x0043 - Exec(struct EXEC *header , int argc , char **argc)

 機能
	メモリにロード済のPS-EXEファイルを実行する?

 返り値
	1:成功 0:失敗

0x00a0 - 0x0044 - FlushCache()

 機能
	CPUキャッシュをフラッシュする?

0x00a0 - 0x0045 - void InstallInterruptHandler()
0x00a0 - 0x0046 - GPU_dw(int x,int y,int w,int h,long *data)

 機能
	フレームバッファの矩形領域にI/Oでデータを送る

 引数
	x,y	領域の左上の座標
	w	領域の幅
	h	領域の高さ
	data	データ

0x00a0 - 0x0047 - mem2vram(int x,int y,int w,int h,long *data)

 機能
	フレームバッファの矩形領域にDMAでデータを送る

 引数
	x,y	領域の左上の座標
	w	領域の幅
	h	領域の高さ
	data	データ

 注:関数名はでっち上げ

0x00a0 - 0x0048 - SendGPU(int status)

 機能
	GPU(gp1)に1ワードの制御コマンドを送る

0x00a0 - 0x0049 - GPU_cw(long cw)

 機能
	GPU(gp0)に1ワードのコマンドをI/Oで送る

0x00a0 - 0x004a - GPU_cwb(long *pkt,int len)

 機能
	GPU(gp0)にlenワードのコマンドパケットをI/Oで送る

0x00a0 - 0x004b - SendPrimitive(long *pkt)

 機能
	GPUにコマンドパケットのリンクリストをDMAで送る

 注:関数名はでっち上げ

0x00a0 - 0x004c - ??()

 機能
	以下の処理を行う。
	d2_chcr = 0x00000401;
	gp1 = 0x04000000;	//I/O
	gp1 = 0x02000000;	//reset IRQ
	gp1 = 0x01000000;	//reset cmd

0x00a0 - 0x004d - int GetGPUStatus()

 機能
	GPUのステータス(gp1)を返す

0x00a0 - 0x004e - GPU_sync()

 機能
	GPUがreadyになるのを待つ?

0x00a0 - 0x004f - 

0x00a0 - 0x0050 - 

0x00a0 - 0x0051 - LoadExec(char *name , int , int)

 機能
	PS-EXEファイルを読み込んで実行する?

 引数
	main()に渡されるargcとargv?

0x00x0 - 0x0052 - GetSysSp()

0x00x0 - 0x0053 - 

0x00a0 - 0x0054 - _96_init()
0x00a0 - 0x0055 - _bu_init()
0x00a0 - 0x0056 - _96_remove()
0x00a0 - 0x0057 - return 0 (it only does this)
0x00a0 - 0x0058 - return 0 (it only does this)
0x00a0 - 0x0059 - return 0 (it only does this)
0x00a0 - 0x005a - return 0 (it only does this)
0x00a0 - 0x005b - dev_tty_init
0x00a0 - 0x005c - dev_tty_open
0x00a0 - 0x005d - dev_tty_??
0x00a0 - 0x005e - dev_tty_ioctl
0x00a0 - 0x005f - dev_cd_open
0x00a0 - 0x0060 - dev_cd_read
0x00a0 - 0x0061 - dev_cd_close
0x00a0 - 0x0062 - dev_cd_firstfile
0x00a0 - 0x0063 - dev_cd_nextfile
0x00a0 - 0x0064 - dev_cd_chdir
0x00a0 - 0x0065 - dev_card_open
0x00a0 - 0x0066 - dev_card_read
0x00a0 - 0x0067 - dev_card_write
0x00a0 - 0x0068 - dev_card_close
0x00a0 - 0x0069 - dev_card_firstfile
0x00a0 - 0x006a - dev_card_nextfile
0x00a0 - 0x006b - dev_card_delete
0x00a0 - 0x006c - dev_card_undelete
0x00a0 - 0x006d - dev_card_format
0x00a0 - 0x006e - dev_card_rename
0x00a0 - 0x006f - dev_card_??
0x00a0 - 0x0070 - _bu_init()
0x00a0 - 0x0071 - _96_init()
0x00a0 - 0x0072 - _96_remove()
0x00a0 - 0x0078 - _96_CdSeekL
0x00a0 - 0x007c - _96_CdGetStatus
0x00a0 - 0x007e - _96_CdRead
0x00a0 - 0x0085 - _96_CdStop
0x00a0 - 0x0096 - AddCDROMDevice()
0x00a0 - 0x0097 - AddMemCardDevice()
0x00a0 - 0x0098 - DisableKernelIORedirection()
0x00a0 - 0x0099 - EnableKernelIORedirection()
0x00a0 - 0x009c - SetConf(int Event , int TCB , int Stack)
0x00a0 - 0x009d - GetConf(int *Event , int *TCB , int *Stack)
0x00a0 - 0x009f - SetMem(int size)
0x00a0 - 0x00a0 - _boot
0x00a0 - 0x00a1 - SystemError
0x00a0 - 0x00a2 - EnqueueCdIntr
0x00a0 - 0x00a3 - DequeueCdIntr
0x00a0 - 0x00a4 - ??
0x00a0 - 0x00a5 - ReadSector(count,sector,buffer)
0x00a0 - 0x00a6 - get_cd_status ??
0x00a0 - 0x00a7 - bufs_cb_0
0x00a0 - 0x00a8 - bufs_cb_1
0x00a0 - 0x00a9 - bufs_cb_2
0x00a0 - 0x00aa - bufs_cb_3
0x00a0 - 0x00ab - _card_info
0x00a0 - 0x00ac - _card_load
0x00a0 - 0x00ad - _card_auto
0x00a0 - 0x00ae - bufs_cb_4
0x00a0 - 0x00b2 - do_a_long_jmp(int value)
0x00a0 - 0x00b4 - (sub_function)
		  0 - u_long GetKernelDate (date is in 0xYYYYMMDD BCD format)
		  1 - u_long GetKernel???? (returns 3 on cex1000 and cex3000)
		  2 - char *GetKernelRomVersion()
		  3 - ?
		  4 - ?
		  5 - u_long GetRamSize() (in bytes)
		  6 -> F - ??

0x00b0 - 0x0000 - SysMalloc (to malloc kernel memory)
0x00b0 - 0x0007 - DeliverEvent(class , event)
0x00b0 - 0x0008 - OpenEvent(class , spec , mode , func) (source code is corrected)
0x00b0 - 0x0009 - CloseEvent(event)
0x00b0 - 0x000a - WaitEvent(event)
0x00b0 - 0x000b - TestEvent(event)
0x00b0 - 0x000c - EnableEvent(event)
0x00b0 - 0x000d - DisableEvent(event)
0x00b0 - 0x000e - OpenTh
0x00b0 - 0x000f - CloseTh
0x00b0 - 0x0010 - ChangeTh
0x00b0 - 0x0012 - InitPAD(char *buf1,int len1,char *buf2,int len2)

 機能
	パッドドライバの初期化
	StartPADを行うとバッファに定期的にデータが入る

 引数
	buf1	パッド1用のバッファ
	len1	パッド1用のバッファのサイズ
	buf2	パッド1用のバッファ
	len2	パッド1用のバッファのサイズ

 データ内容
 	バイト
 	0	0xff:コントローラ無し 0x00:コントローラ有り
 	1	上位4ビット:端末種別 下位4ビット:受信データサイズ(バイト数の1/2)
 	2-	受信データ(最大32バイト)

	端末種別/受信データ内容
	1	マウス
	  3	ビット2:右ボタン ビット3:左ボタン 押されていれば0
	  4	x移動(-128〜127)
	  5	y移動(-128〜127)
	2	ネジコン
	4	標準パッド
	  2	下記PAD_drの上位8ビット
	  3	下記PAD_drの下位8ビット
	5	ジョイスティック

 注:バッファのサイズは36?

0x00b0 - 0x0013 - StartPAD()

 機能
	パッドドライバの開始?

0x00b0 - 0x0014 - StopPAD()

 機能
	パッドドライバの停止?

0x00b0 - 0x0015 - PAD_init(u_long mode,u_long *pad_buf)

 機能
	PAD_dr用のパッドドライバの初期化?

 引数
	mode	不明 0x20000001を渡す
	pad_buf	パッドデータの入るアドレス

0x00b0 - 0x0016 - u_long PAD_dr()

 機能
	標準パッドの入力?
	PAD_initで指定したpad_bufにパッドデータを入れる?

 返り値
	不明

 pad_bufの内容
 	押されたビットが0
	ビット	ボタン
	0	L2
	1	R2
	2	L1
	3	R1
	4	△
	5	○
	6	×
	7	□
	8	SELECT
	9	不明
	10	不明
	11	START
	12	↑
	13	→
	14	↓
	15	←

0x00b0 - 0x0017 - ReturnFromException
0x00b0 - 0x0018 - ResetEntryInt
0x00b0 - 0x0019 - HookEntryInt
0x00b0 - 0x0020 - UnDeliverEvent(class , event)
0x00b0 - 0x0032 - int open(char *name,int access)

 注:このへんa0コールとダブっていて、同じ処理を行う

0x00b0 - 0x0033 - int lseek(int fd,long pos,int seektype)
0x00b0 - 0x0034 - int read(int fd,void *buf,int nbytes)
0x00b0 - 0x0035 - int write(int fd,void *buf,int nbytes)
0x00b0 - 0x0036 - close(int fd)
0x00b0 - 0x0037 - int ioctl(int fd , int cmd , int arg)
0x00b0 - 0x0038 - exit(int exitcode)
0x00b0 - 0x003a - char getc(int fd)
0x00b0 - 0x003b - putc(int fd,char ch)
0x00b0 - 0x003c - char getchar(void)
0x00b0 - 0x003d - putchar(char ch)
0x00b0 - 0x003e - char *gets(char *s)
0x00b0 - 0x003f - puts(char *s)
0x00b0 - 0x0040 - int cd(char *path)

 機能
	カレントディレクトリを変更する

0x00b0 - 0x0041 - int format(char *fs)

 機能
	デバイスをフォーマットする(メモリカード専用?)

 引数
	fs	デバイス名("bu00:"、"bu10:"等)

0x00b0 - 0x0042 - struct DIRENTRY* firstfile(char *name,struct DIRENTRY *dir)

 機能
	一致する最初のファイルを検索する

 引数
 	name	ファイル名(ワイルドカード*?可
 	dir	ファイル情報を返すバッファ

 返り値
 	見つかればdir 見つからなければNULL(0)

 構造体
   struct DIRENTRY {
	char name[20];	一致したファイル名
	long attr;	属性?
	long size;	ファイルサイズ
	struct DIRENTRY *next;
	long head;
	char system[4];
    };



0x00b0 - 0x0043 - struct DIRENTRY* nextfile(struct DIRENTRY *dir)

 機能
	直前のfirstfileに一致する次のファイルを検索する

 返り値
 	見つかればdir 見つからなければNULL(0)

0x00b0 - 0x0044 - int rename(char *oldname,char *newname)

 機能
	ファイル名を変更する

 返り値
	1:成功 0:失敗

0x00b0 - 0x0045 - int delete(char *name)

 機能
	ファイルを削除する

 返り値
	1:成功 0:失敗

0x00b0 - 0x0046 - undelete
0x00b0 - 0x0047 - AddDevice (used by AddXXXDevice)
0x00b0 - 0x0048 - RemoveDevice
0x00b0 - 0x0049 - PrintInstalledDevices
0x00b0 - 0x004a - InitCARD

 機能
 	メモリカードドライバの初期化?

0x00b0 - 0x004b - StartCARD()

 機能
 	メモリカードドライバの開始?

0x00b0 - 0x004c - StopCARD()

 機能
 	メモリカードドライバの停止?

0x00b0 - 0x004e - _card_write
0x00b0 - 0x004f - _card_read
0x00b0 - 0x0050 - _new_card
0x00b0 - 0x0051 - void *Krom2RawAdd(int code)

 機能
	シフトJISコードを漢字ROMのアドレスに変換する

 引数
 	code	シフトJISコード

 返り値
 	漢字ROMのアドレス

0x00b0 - 0x0054 - long _get_errno(void)

 機能
	直前に発生したエラー番号を返す?

0x00b0 - 0x0055 - long _get_error(long fd)

 機能
	ファイルハンドルfdで直前に発生したエラー番号を返す?

0x00b0 - 0x0056 - GetC0Table
0x00b0 - 0x0057 - GetB0Table
0x00b0 - 0x0058 - _card_chan
0x00b0 - 0x005b - ChangeClearPAD(int)

 機能
	パッドドライバの初期化?

 引数
	不明 0を渡す

0x00b0 - 0x005c - _card_status
0x00b0 - 0x005d - _card_wait

0x00c0 - 0x0000 - InitRCnt
0x00c0 - 0x0001 - InitException
0x00c0 - 0x0002 - SysEnqIntRP(int index , long *queue)
0x00c0 - 0x0003 - SysDeqIntRP(int index , long *queue)
0x00c0 - 0x0004 - get_free_EvCB_slot()
0x00c0 - 0x0005 - get_free_TCB_slot()
0x00c0 - 0x0006 - ExceptionHandler
0x00c0 - 0x0007 - InstallExceptionHandlers
0x00c0 - 0x0008 - SysInitMemory
0x00c0 - 0x0009 - void SysInitKMem(void)
0x00c0 - 0x000a - ChangeClearRCnt
0x00c0 - 0x000b - SystemError ???
0x00c0 - 0x000c - InitDefInt
0x00c0 - 0x0012 - InstallDevices
0x00c0 - 0x0013 - FlushStdInOutPut
0x00c0 - 0x0014 - return 0
0x00c0 - 0x0015 - _cdevinput
0x00c0 - 0x0016 - _cdevscan
0x00c0 - 0x0017 - char _circgetc(struct device_buf *circ)
0x00c0 - 0x0018 - _circputc(char c , struct device_buf *circ)
0x00c0 - 0x0019 - ioabort(char *str)
0x00c0 - 0x001b - KernelRedirect(int flag)
0x00c0 - 0x001c - PatchA0Table

上記と違う方法で呼ばれるものが3つあります:

MiPS R3000:

Exception() {
li $a0,0
syscall
}

EnterCriticalSection() { 割込み禁止
li $a0,1
syscall
}

ExitCriticalSection() { 割り込み許可
li $a0,2
syscall
}

参考文献   1