nkeynes@102: /** nkeynes@182: * $Id: dcload.c,v 1.4 2006-07-06 08:47:33 nkeynes Exp $ nkeynes@102: * nkeynes@102: * DC-load syscall implementation. nkeynes@102: * nkeynes@102: * Copyright (c) 2005 Nathan Keynes. nkeynes@102: * nkeynes@102: * This program is free software; you can redistribute it and/or modify nkeynes@102: * it under the terms of the GNU General Public License as published by nkeynes@102: * the Free Software Foundation; either version 2 of the License, or nkeynes@102: * (at your option) any later version. nkeynes@102: * nkeynes@102: * This program is distributed in the hope that it will be useful, nkeynes@102: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@102: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@102: * GNU General Public License for more details. nkeynes@102: */ nkeynes@102: nkeynes@102: #include nkeynes@102: #include "dream.h" nkeynes@182: #include "dreamcast.h" nkeynes@102: #include "mem.h" nkeynes@102: #include "syscall.h" nkeynes@102: #include "sh4/sh4core.h" nkeynes@102: nkeynes@102: #define SYS_READ 0 nkeynes@102: #define SYS_WRITE 1 nkeynes@102: #define SYS_OPEN 2 nkeynes@102: #define SYS_CLOSE 3 nkeynes@102: #define SYS_CREAT 4 nkeynes@102: #define SYS_LINK 5 nkeynes@102: #define SYS_UNLINK 6 nkeynes@102: #define SYS_CHDIR 7 nkeynes@102: #define SYS_CHMOD 8 nkeynes@102: #define SYS_LSEEK 9 nkeynes@102: #define SYS_FSTAT 10 nkeynes@102: #define SYS_TIME 11 nkeynes@102: #define SYS_STAT 12 nkeynes@102: #define SYS_UTIME 13 nkeynes@102: #define SYS_ASSIGNWRKMEM 14 nkeynes@102: #define SYS_EXIT 15 nkeynes@102: #define SYS_OPENDIR 16 nkeynes@102: #define SYS_CLOSEDIR 17 nkeynes@102: #define SYS_READDIR 18 nkeynes@102: #define SYS_GETHOSTINFO 19 nkeynes@102: nkeynes@102: #define SYS_MAGIC 0xDEADBEEF nkeynes@102: #define SYS_MAGIC_ADDR 0x8c004004 nkeynes@102: #define SYSCALL_ADDR 0x8c004008 nkeynes@102: nkeynes@182: static gboolean dcload_allow_exit = FALSE; nkeynes@182: nkeynes@182: void dcload_set_allow_exit( gboolean allow ) nkeynes@182: { nkeynes@182: dcload_allow_exit = allow; nkeynes@182: } nkeynes@182: nkeynes@102: void dcload_syscall( uint32_t syscall_id ) nkeynes@102: { nkeynes@102: uint32_t syscall = sh4r.r[4]; nkeynes@102: switch( sh4r.r[4] ) { nkeynes@102: case SYS_READ: nkeynes@102: if( sh4r.r[5] == 0 ) { nkeynes@102: char *buf = mem_get_region( sh4r.r[6] ); nkeynes@102: int length = sh4r.r[7]; nkeynes@102: sh4r.r[0] = read( 0, buf, length ); nkeynes@102: } else { nkeynes@102: sh4r.r[0] = -1; nkeynes@102: } nkeynes@102: break; nkeynes@102: case SYS_WRITE: nkeynes@102: if( sh4r.r[5] == 1 || sh4r.r[5] == 2 ) { nkeynes@102: char *buf = mem_get_region( sh4r.r[6] ); nkeynes@102: int length = sh4r.r[7]; nkeynes@102: sh4r.r[0] = write( sh4r.r[5], buf, length ); nkeynes@102: } else { nkeynes@102: sh4r.r[0] = -1; nkeynes@102: } nkeynes@102: break; nkeynes@102: case SYS_EXIT: nkeynes@182: if( dcload_allow_exit ) nkeynes@182: exit( sh4r.r[4] ); nkeynes@182: else nkeynes@182: dreamcast_stop(); nkeynes@102: default: nkeynes@102: sh4r.r[0] = -1; nkeynes@102: } nkeynes@102: nkeynes@102: } nkeynes@102: nkeynes@102: void dcload_install() nkeynes@102: { nkeynes@102: syscall_add_hook_vector( 0xF0, SYSCALL_ADDR, dcload_syscall ); nkeynes@102: sh4_write_long( SYS_MAGIC_ADDR, SYS_MAGIC ); nkeynes@102: }