⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysemx.c

📁 大量的汇编程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 + -