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 }参考文献