📄 sysemx.c
字号:
/* void scrsize(EDX) */
static int sys_emx1d_scrsize(void)
{
store32(DS, EDX + 0L, read32(bios_selector, 0x4AL) & 0xFFFFL);
store32(DS, EDX + 4L, (read32(bios_selector, 0x84L) & 0xFFL) + 1L);
return CARRY_NON;
}
int sysemx_select(int dos_handle, DWORD tics)
{
int is_termio_handle = 0;
DWORD time_end = time_tic + tics;
if (dos_handle == 0 && rm_isatty(dos_handle) && (npz->p_flags & PF_TERMIO))
is_termio_handle = 1;
for (;;) {
if (is_termio_handle) {
if (rm_bios_read_keybrd(kready))
return 1;
}
if (rm_ioctl_select_in(dos_handle))
return 1;
if (tics != 0xFFFFFFFF && time_reached(time_end))
return 0;
}
}
/* void select(edx) errno:ecx */
static int sys_emx1e_select(void)
{
int ret = sys_select(EDX);
if (ret < 0)
set_ecx_error(-ret);
else
set_eax_return(ret);
return CARRY_NON;
}
/* eax syserrno(void) */
static int sys_emx1f_syserrno(void)
{
EAX = doserror_to_errno(_doserrno);
return CARRY_NON;
}
/*
** eax stat(name_edx,struc_edi) errno:ecx
*/
static int sys_emx20_stat(void)
{
struct stat st;
strcpy32_16(DS, EDX, iobuf);
if (!sys_stat(iobuf, &st)) {
cpy16_32(DS, EDI, &st, sizeof(st));
set_no_error();
} else
set_ecx_error(doserror_to_errno(_doserrno));
return CARRY_NON;
}
/*
** eax fstat(ebx, edi) errno:ecx
*/
static int sys_emx21_fstat(void)
{
struct stat st;
CONVERT2_BX_HANDLE;
if (!sys_fstat(BX, &st)) {
cpy16_32(DS, EDI, &st, sizeof(st));
set_no_error();
} else
set_ecx_error(doserror_to_errno(_doserrno));
return CARRY_NON;
}
static int sys_emx22_unused(void)
{
return CARRY_NON;
}
/* filesys(edx,edi,ecx) errno:ecx */
static int sys_emx23_filesys(void)
{
char drive[4];
char *res;
int ret;
*(DWORD *) drive = read32(DS, EDX);
if (drive[0] >= 'a')
drive[0] -= 0x20;
if (drive[0] < 'A' || drive[0] > 'Z' || drive[1] != ':' || drive[2] != 0) {
set_ecx_error(EMX_EINVAL);
return -1;
}
drive[0] -= ('A' - 1);
ret = rm_ioctl_remotedrive(drive[0]);
if (ret == 1)
res = "LAN";
else
res = "FAT";
strcpy16_32(DS, EDI, res);
set_no_error();
return CARRY_NON;
}
/* eax utimes(name_edx,struct tval esi) errno:ecx */
/* set access and modif time of file */
static int sys_emx24_utimes(void)
{
struct file_time ft;
DWORD utimes[2];
int handle;
strcpy32_16(DS, EDX, iobuf);
cpy32_16(DS, ESI, utimes, sizeof(utimes));
if ((handle = rm_open(iobuf, RM_O_WRONLY)) == -1) {
set_ecx_error(doserror_to_errno(_doserrno));
return CARRY_NON;
}
gmt2filetime(utimes[0], &ft);
if (rm_setftime(handle, ft.ft_date, ft.ft_time) == -1)
set_ecx_error(doserror_to_errno(_doserrno));
else
set_eax_return(0);
rm_close(handle);
return CARRY_NON;
}
/* eax ftruncate(ebx,edx) errno:ecx */
static int sys_emx25_ftruncate(void)
{
long temp;
CONVERT2_BX_HANDLE;
if ((temp = rm_lseek(BX, 0, SEEK_END)) == -1) {
set_ecx_error(doserror_to_errno(_doserrno));
return CARRY_NON;
} else if (temp > (long) EDX) {
if (rm_lseek(BX, EDX, SEEK_SET) == -1 || rm_write(BX, iobuf, 0) == -1) {
set_ecx_error(doserror_to_errno(_doserrno));
return CARRY_NON;
}
}
set_no_error();
return CARRY_NON;
}
/* eax clock(void) err:no */
static int sys_emx26_clock(void)
{
/* clk_tck = 100 ; timer 18.2 pre sec */
EAX = (time_tic - npz->time_tic) * 500 / 91;
EDX = 0;
return CARRY_NON;
}
/* void ftime(edx) err:no */
static int sys_emx27_ftime(void)
{
struct emx_timeb {
long time, millitm, timezone, dstflag;
} emx_timeb;
struct dos_date dd;
struct dos_time dt;
unsigned long gmt;
rm_getdate(&dd);
rm_gettime(&dt);
gmt = dos2gmt(&dd, &dt);
emx_timeb.time = gmt;
emx_timeb.millitm = (DWORD) dt.dtime_hsec * 10;
emx_timeb.timezone = 0;
emx_timeb.dstflag = 0;
cpy16_32(DS, EDX, &emx_timeb, sizeof(emx_timeb));
return CARRY_NON;
}
/* eax umask(edx) err:no */
static int sys_emx28_umask(void)
{
EAX = EDX;
return CARRY_NON;
}
/* eax getppid(void) err:no */
static int sys_emx29_getppid(void)
{
EAX = (DWORD) npz->pptr->pid;
return CARRY_NON;
}
/* void nls_menupr(buf edx,size ecx) err:no */
/* buffer to upper case */
static int sys_emx2a_nlsmemupr(void)
{
return CARRY_NON;
}
/*
** eax open(edx, ecx) errno:ecx
**
** pathname <= sizeof(iobuf) !
** creat: CH = creat file attr
** open: CL = access & sharing mode
*/
typedef int (*OPENFUNC) (char *, WORD);
static int sys_emx2b_open(void)
{
int i, dosfile, handle;
OPENFUNC openfn;
WORD p2;
strcpy32_16(DS, EDX, iobuf);
/* replace unix names */
if (strcmp("/dev/null", iobuf) == 0)
strcpy(iobuf, "nul");
else if (strcmp("/dev/tty", iobuf) == 0)
strcpy(iobuf, "con");
i = (int) (ECX >> 16); /* 1 = O_CREAT, 2 = O_EXCL, 4 = O_TRUNC */
/* 8 = O_INHERIT, 16 = SYNC */
if (i & 0x01) {
if (i & 0x02) /* O_CREAT | O_EXCL */
openfn = rm_creatnew;
else if (i & 4) /* O_CREAT | O_TRUNC */
openfn = rm_creat;
else if (rm_access(iobuf, 0) == -1) /* old file there ? */
openfn = rm_creat;
else
openfn = rm_open;
} else /* not O_CREAT */
openfn = rm_open;
if (openfn == rm_open)
p2 = CX & 0xff; /* open mode */
else
p2 = CX >> 8; /* creat attrib */
dosfile = (*openfn) (iobuf, p2);
if (dosfile == -1)
set_ecx_error(doserror_to_errno(_doserrno));
else {
if ((i & 0x05) == 0x4) { /* O_TRUNC with open */
if (rm_lseek(dosfile, 0, SEEK_SET) == -1L
|| rm_write(dosfile, iobuf, 0) == -1) {
set_ecx_error(doserror_to_errno(_doserrno));
return CARRY_NON;
}
}
handle = get_empty_proc_filp();
npz->filp[handle]->f_mode = FMODE_READ | FMODE_WRITE;
npz->filp[handle]->f_doshandle = dosfile;
npz->filp[handle]->f_op = & msdos_fop;
if (i & 16) /* inherit file handle */
FD_CLR(handle, &npz->close_on_exec);
set_eax_return(handle);
}
return CARRY_NON;
}
/* eax newthread(edx) errno:ecx */
static int sys_emx2c_newthread(void)
{
set_ecx_error(EMX_EMSDOS);
return CARRY_NON;
}
/* eax endthread(void) errno:ecx */
static int sys_emx2d_endthread(void)
{
set_ecx_error(EMX_EMSDOS);
return CARRY_NON;
}
/* waitpid(pid_edx, options_ecx) ret: eax,ecx edx=status*/
static int sys_emx2e_waitpid(void)
{
if (!opt_schedule)
set_ecx_error(EMX_EMSDOS);
else {
int ret;
unsigned status;
if ((ret = sys_waitpid((int)EDX, &status)) >= 0) {
EDX = (DWORD) status;
set_eax_return((DWORD) (unsigned) ret);
} else
set_ecx_error(EMX_ESRCH);
}
return CARRY_NON;
}
static int sys_emx2f_readkbd()
{
static unsigned char next_key = 0;
int key;
unsigned char ascii, scan;
if (next_key) {
EAX = (DWORD) next_key;
next_key = 0;
return CARRY_NON;
}
if (DX & 2) { /* wait */
while (rm_bios_read_keybrd(kready))
rm_bios_read_keybrd(kread);
key = rm_bios_read_keybrd(kread);
} else if ((key = rm_bios_read_keybrd(kready)) != 0)
key = rm_bios_read_keybrd(kread);
else {
EAX = -1;
return CARRY_NON;
}
ascii = (BYTE) (key & 0xFF);
scan = (BYTE) (key >> 8);
if (ascii == 0xE0)
ascii = 0;
if (ascii == 0)
next_key = scan;
if (DX & 1) /* echo */
if (ascii >= 32)
/* change to: sys_write() */
rm_write((int) npz->filp[1]->f_doshandle, &ascii, 1);
if ((DX & 4) && ascii == 3) /* signal */
send_signal(npz, SIGINT);
EAX = (DWORD) (ascii);
return CARRY_NON;
}
/* sleep2 ; err:-*/
static int sys_emx30_sleep2(void)
{
sleep_until(time_tic + EDX / 55);
EAX = 0;
return CARRY_NON;
}
/* void unwind2(); not DOS */
static int sys_emx31_unwind2(void)
{
return CARRY_NON;
}
/* void pause(); err: eax=-1, return until signal handler */
static int sys_emx32_pause(void)
{
for (;;) {
if (npz->sig_raised & ~npz->sig_blocked) {
EAX = 0;
break;
}
if (!schedule()) { /* no other processes */
EAX = -1L;
break;
}
}
return CARRY_NON;
}
/* int execname(edx=buf, ecx=size); err=-1 */
static int sys_emx33_execname(void)
{
DWORD pos = read32(npz->data32sel, npz->stack_top - 8L);
DWORD len = read32(npz->data32sel, npz->stack_top - 12L);
if (ECX < len || verify_illegal(npz, EDX, len)
|| verify_illegal(npz, pos, len)) {
EAX = -1;
return CARRY_NON;
}
cpy32_32(npz->data32sel, pos, npz->data32sel, EDX, npz->stack_top - pos);
EAX = 0;
return CARRY_NON;
}
/* int initthread() ; not DOS */
static int sys_emx34_initthread(void)
{
EAX = -1;
return CARRY_NON;
}
/* int sigaction(no ECX, in EDX, out EBX) */
static int sys_emx35_sigaction(void)
{
int err = sys_sigaction((int)ECX, EDX, EBX);
if (err < 0)
set_ecx_error(-err);
else
set_eax_return(err);
return CARRY_NON;
}
/* int sigpending(in EDX) */
static int sys_emx36_sigpending(void)
{
int err = sys_sigpending(EDX);
if (err < 0)
set_ecx_error(-err);
else
set_eax_return(err);
return CARRY_NON;
}
/* int sigprocmask(how ECX, in EDX, out EBX) */
static int sys_emx37_sigprocmask(void)
{
int err = sys_sigprocmask((int)ECX, EDX, EBX);
if (err < 0)
set_ecx_error(-err);
else
set_eax_return(err);
return CARRY_NON;
}
/* int sigsuspend(sigset_t EDX) */
static int sys_emx38_sigsuspend(void)
{
set_ecx_error(EMX_EMSDOS);
return CARRY_NON;
}
/* os/2 only */
static int sys_emx39_imphandle(void)
{
set_ecx_error(EMX_EMSDOS);
return CARRY_NON;
}
#define EMX_FNCT_MAX 0x40
typedef int (*EMXFNCT) (void);
static EMXFNCT emx_fnct[EMX_FNCT_MAX] =
{
sys_emx00_sbrk,
sys_emx01_brk,
sys_emx02_ulimit,
sys_emx03_vmstat,
sys_emx04_umask,
sys_emx05_getpid,
sys_emx06_spawn,
sys_emx07_sigreturn,
sys_emx08_ptrace,
sys_emx09_wait,
sys_emx0a_version,
sys_emx0b_memavail,
sys_emx0c_signal,
sys_emx0d_kill,
sys_emx0e_raise,
sys_emx0f_uflags,
sys_emx10_unwind,
sys_emx11_core,
sys_emx12_portaccess,
sys_emx13_memaccess,
sys_emx14_ioctl,
sys_emx15_alarm,
sys_emx16_internal,
sys_emx17_sleep,
sys_emx18_chsize,
sys_emx19_fcntl,
sys_emx1a_pipe,
sys_emx1b_fsync,
sys_emx1c_fork,
sys_emx1d_scrsize,
sys_emx1e_select,
sys_emx1f_syserrno,
sys_emx20_stat,
sys_emx21_fstat,
sys_emx22_unused,
sys_emx23_filesys,
sys_emx24_utimes,
sys_emx25_ftruncate,
sys_emx26_clock,
sys_emx27_ftime,
sys_emx28_umask,
sys_emx29_getppid,
sys_emx2a_nlsmemupr,
sys_emx2b_open,
sys_emx2c_newthread,
sys_emx2d_endthread,
sys_emx2e_waitpid,
sys_emx2f_readkbd,
sys_emx30_sleep2,
sys_emx31_unwind2,
sys_emx32_pause,
sys_emx33_execname,
sys_emx34_initthread,
sys_emx35_sigaction,
sys_emx36_sigpending,
sys_emx37_sigprocmask,
sys_emx38_sigsuspend,
sys_emx39_imphandle
/* sys_emx3a_fpu */
};
static int i_21_7f(void)
{
WORD i = AX & 0xFF;
/* emx fnct = al */
if (i < EMX_FNCT_MAX)
return (emx_fnct[i]) ();
else {
set_ecx_error(EMX_EMSDOS);
if (opt_printall)
printf("Warning: unknown emx syscall: %04X\n", i);
return CARRY_ON;
}
}
extern int i_21_ff(void);
extern int i_21_fe(void);
void int21(void)
{
WORD ret;
if (opt_print_syscalls)
printf("21h: a=%08X b=%08lX c=%08lX d=%08lX D=%08lX S=%08lX\n"
, AX, EBX, ECX, EDX, EDI, ESI);
/* emx functions */
if ((AX & 0xff00) == 0x7f00)
ret = i_21_7f();
/* go32 functions */
else if ((AX & 0xff00) == 0xff00)
ret = i_21_ff();
/* go32 debug */
else if ((AX & 0xff00) == 0xfe00)
ret = i_21_fe();
/* DOS functions */
else {
ret = int21normal();
/* if DOS indicates an error (carry-flag set), convert error code */
if (ret == CARRY_NON && (FLAGS & 1)) {
EAX = (DWORD) doserror_to_errno(AX);
ret = CARRY_ON;
}
}
if (ret == CARRY_ON) {
EFLAGS |= 1;
if (npz->p_flags & PF_DJGPP_FILE)
EAX = (DWORD) errno_djgpp(AX);
} else if (ret == CARRY_OFF)
EFLAGS &= ~1L;
if (opt_print_syscalls)
printf(" : a=%08lX b=%08lX c=%08lX d=%08lX D=%08lX S=%08lX F:%04X\n"
, EAX, EBX, ECX, EDX, EDI, ESI, FLAGS);
if (npz->time_alarm != 0 && time_reached(npz->time_alarm)) {
npz->time_alarm = 0;
send_signal(npz, SIGALRM);
}
/* stack check */
if (npz->stack_down + 0x1000L >= ESP) {
puts("stack too small!!");
printf("ESP %lX stack : min %lX max %lX\n",
ESP, npz->stack_down, npz->stack_top);
send_signal(npz, SIGKILL);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -