コード例 #1
0
ファイル: callbacks.c プロジェクト: andrewbird/dosemu2
static void mouse_callback(struct sigcontext *scp,
		    const struct RealModeCallStructure *rmreg,
		    int is_32, void *arg)
{
    void *sp = SEL_ADR_CLNT(_ss, _esp, is_32);
    struct pmaddr_s *mouseCallBack = arg;

    if (!ValidAndUsedSelector(mouseCallBack->selector)) {
	D_printf("MSDOS: ERROR: mouse callback to unused segment\n");
	return;
    }
    D_printf("MSDOS: starting mouse callback\n");

    if (is_32) {
	unsigned int *ssp = sp;
	*--ssp = _cs;
	*--ssp = _eip;
	_esp -= 8;
    } else {
	unsigned short *ssp = sp;
	*--ssp = _cs;
	*--ssp = _LWORD(eip);
	_LWORD(esp) -= 4;
    }

    rm_to_pm_regs(scp, rmreg, ~(1 << ebp_INDEX));
    _ds = ConvertSegmentToDescriptor(RMREG(ds));
    _cs = mouseCallBack->selector;
    _eip = mouseCallBack->offset;
}
コード例 #2
0
ファイル: callbacks.c プロジェクト: andrewbird/dosemu2
static void ps2_mouse_callback(struct sigcontext *scp,
			const struct RealModeCallStructure *rmreg,
			int is_32, void *arg)
{
    unsigned short *rm_ssp;
    void *sp = SEL_ADR_CLNT(_ss, _esp, is_32);
    struct pmaddr_s *PS2mouseCallBack = arg;

    if (!ValidAndUsedSelector(PS2mouseCallBack->selector)) {
	D_printf("MSDOS: ERROR: PS2 mouse callback to unused segment\n");
	return;
    }
    D_printf("MSDOS: starting PS2 mouse callback\n");

    rm_ssp = MK_FP32(RMREG(ss), RMREG(sp) + 4 + 8);
    if (is_32) {
	unsigned int *ssp = sp;
	*--ssp = *--rm_ssp;
	D_printf("data: 0x%x ", *ssp);
	*--ssp = *--rm_ssp;
	D_printf("0x%x ", *ssp);
	*--ssp = *--rm_ssp;
	D_printf("0x%x ", *ssp);
	*--ssp = *--rm_ssp;
	D_printf("0x%x\n", *ssp);
	*--ssp = _cs;
	*--ssp = _eip;
	_esp -= 24;
    } else {
	unsigned short *ssp = sp;
	*--ssp = *--rm_ssp;
	D_printf("data: 0x%x ", *ssp);
	*--ssp = *--rm_ssp;
	D_printf("0x%x ", *ssp);
	*--ssp = *--rm_ssp;
	D_printf("0x%x ", *ssp);
	*--ssp = *--rm_ssp;
	D_printf("0x%x\n", *ssp);
	*--ssp = _cs;
	*--ssp = _LWORD(eip);
	_LWORD(esp) -= 12;
    }

    _cs = PS2mouseCallBack->selector;
    _eip = PS2mouseCallBack->offset;
}
コード例 #3
0
ファイル: g_game.c プロジェクト: Arc0re/jaguardoom
void G_InitNew (skill_t skill, int map, gametype_t gametype) 
{ 
	int             i; 
	
D_printf ("G_InitNew\n");

	M_ClearRandom (); 

/* these may be reset by I_NetSetup */
	gamemap = map; 
	gameskill = skill; 
 	netgame = gametype;
	I_DrawSbar ();			/* draw frag boxes if multiplayer */

/* force players to be initialized upon first level load          */
	for (i=0 ; i<MAXPLAYERS ; i++) 
		players[i].playerstate = PST_REBORN; 

	players[0].mo = players[1].mo = &emptymobj;	/* for net consistancy checks */
 	
	playeringame[0] = true;	
	if (netgame != gt_single)
		playeringame[1] = true;	
	else
		playeringame[1] = false;	

	demorecording = false;
	demoplayback = false;
	

	gametic = 0; 

	if ( skill == sk_nightmare )
	{ 
		states[S_SARG_ATK1].tics = 2;
		states[S_SARG_ATK2].tics = 2;
		states[S_SARG_ATK3].tics = 2;
		mobjinfo[MT_SERGEANT].speed = 15; 
		mobjinfo[MT_SHADOWS].speed = 15; 
		
		mobjinfo[MT_BRUISERSHOT].speed = 40*FRACUNIT; 
		mobjinfo[MT_HEADSHOT].speed = 40*FRACUNIT; 
		mobjinfo[MT_TROOPSHOT].speed = 40*FRACUNIT; 
	} 
	else 
	{ 
		states[S_SARG_ATK1].tics = 4;
		states[S_SARG_ATK2].tics = 4;
		states[S_SARG_ATK3].tics = 4;
		mobjinfo[MT_SERGEANT].speed = 10; 
		mobjinfo[MT_SHADOWS].speed = 10; 
		
		mobjinfo[MT_BRUISERSHOT].speed = 30*FRACUNIT; 
		mobjinfo[MT_HEADSHOT].speed = 20*FRACUNIT; 
		mobjinfo[MT_TROOPSHOT].speed = 20*FRACUNIT; 
	}   
} 
コード例 #4
0
ファイル: callbacks.c プロジェクト: andrewbird/dosemu2
static void rmcb_handler(struct sigcontext *scp,
		  const struct RealModeCallStructure *rmreg, int is_32,
		  void *arg)
{
    switch (RM_LO(ax)) {
    case 0:			/* read */
	{
	    unsigned int offs = E_RMREG(edi);
	    unsigned int size = E_RMREG(ecx);
	    unsigned int dos_ptr = SEGOFF2LINEAR(RMREG(ds), RMLWORD(dx));
	    D_printf("MSDOS: read %x %x\n", offs, size);
	    /* need to use copy function that takes VGA mem into account */
	    if (offs + size <= io_buffer_size)
		memcpy_2unix(io_buffer + offs, dos_ptr, size);
	    else
		error("MSDOS: bad read (%x %x %x)\n", offs, size,
		      io_buffer_size);
	    break;
	}
    case 1:			/* write */
	{
	    unsigned int offs = E_RMREG(edi);
	    unsigned int size = E_RMREG(ecx);
	    unsigned int dos_ptr = SEGOFF2LINEAR(RMREG(ds), RMLWORD(dx));
	    D_printf("MSDOS: write %x %x\n", offs, size);
	    /* need to use copy function that takes VGA mem into account */
	    if (offs + size <= io_buffer_size)
		memcpy_2dos(dos_ptr, io_buffer + offs, size);
	    else
		error("MSDOS: bad write (%x %x %x)\n", offs, size,
		      io_buffer_size);
	    break;
	}
    case 2:			/* error */
	io_error = 1;
	io_error_code = RMLWORD(cx);
	D_printf("MSDOS: set I/O error %x\n", io_error_code);
	break;
    default:
	error("MSDOS: unknown rmcb 0x%x\n", RM_LO(ax));
	break;
    }
}
コード例 #5
0
ファイル: callbacks.c プロジェクト: andrewbird/dosemu2
void xms_call(const struct sigcontext *scp,
	struct RealModeCallStructure *rmreg, void *arg)
{
    far_t *XMS_call = arg;
    int rmask = (1 << cs_INDEX) |
	(1 << eip_INDEX) | (1 << ss_INDEX) | (1 << esp_INDEX);
    D_printf("MSDOS: XMS call to 0x%x:0x%x\n",
	     XMS_call->segment, XMS_call->offset);
    pm_to_rm_regs(scp, rmreg, ~rmask);
    do_call_to(XMS_call->segment, XMS_call->offset, rmreg, rmask);
}
コード例 #6
0
ファイル: g_game.c プロジェクト: Arc0re/jaguardoom
void G_RecordDemo (void)
{
	demo_p = demobuffer = Z_Malloc (0x8000, PU_STATIC, NULL);
	
	*demo_p++ = startskill;
	*demo_p++ = startmap;
	
	G_InitNew (startskill, startmap, gt_single);
	G_DoLoadLevel ();  
	demorecording = true; 
	MiniLoop (P_Start, P_Stop, P_Ticker, P_Drawer);
	demorecording = false;
	
	D_printf ("w %x,%x",demobuffer,demo_p);
	
	while (1)
	{
		G_PlayDemoPtr (demobuffer);
	D_printf ("w %x,%x",demobuffer,demo_p);
	}
	
}
コード例 #7
0
ファイル: callbacks.c プロジェクト: andrewbird/dosemu2
void msdos_api_winos2_call(struct sigcontext *scp, void *arg)
{
    u_short *ldt_alias_winos2 = arg;

    D_printf("MSDOS: WINOS2 extension API call: 0x%04x\n", _LWORD(eax));
    if (_LWORD(eax) == 0x0100) {
	u_short sel = *ldt_alias_winos2;
	if (sel) {
	    _eax = sel;
	    _eflags &= ~CF;
	} else {
	    _eflags |= CF;
	}
    } else {
	_eflags |= CF;
    }
}
コード例 #8
0
ファイル: cparse.c プロジェクト: vasco/racc
static VALUE
reduce0(VALUE val, VALUE data, VALUE self)
{
    struct cparse_params *v;
    VALUE reduce_to, reduce_len, method_id;
    long len;
    ID mid;
    VALUE tmp, tmp_t = Qundef, tmp_v = Qundef;
    long i, k1, k2;
    VALUE goto_state;

    Data_Get_Struct(data, struct cparse_params, v);
    reduce_len = RARRAY_PTR(v->reduce_table)[v->ruleno];
    reduce_to  = RARRAY_PTR(v->reduce_table)[v->ruleno+1];
    method_id  = RARRAY_PTR(v->reduce_table)[v->ruleno+2];
    len = NUM2LONG(reduce_len);
    mid = value_to_id(method_id);

    /* call action */
    if (len == 0) {
        tmp = Qnil;
        if (mid != id_noreduce)
            tmp_v = rb_ary_new();
        if (v->debug)
            tmp_t = rb_ary_new();
    }
    else {
        if (mid != id_noreduce) {
            tmp_v = GET_TAIL(v->vstack, len);
            tmp = RARRAY_PTR(tmp_v)[0];
        }
        else {
            tmp = RARRAY_PTR(v->vstack)[ RARRAY_LEN(v->vstack) - len ];
        }
        CUT_TAIL(v->vstack, len);
        if (v->debug) {
            tmp_t = GET_TAIL(v->tstack, len);
            CUT_TAIL(v->tstack, len);
        }
        CUT_TAIL(v->state, len);
    }
    if (mid != id_noreduce) {
        if (v->use_result_var) {
            tmp = rb_funcall(v->parser, mid,
                             3, tmp_v, v->vstack, tmp);
        }
        else {
            tmp = rb_funcall(v->parser, mid,
                             2, tmp_v, v->vstack);
        }
    }

    /* then push result */
    PUSH(v->vstack, tmp);
    if (v->debug) {
        PUSH(v->tstack, reduce_to);
        rb_funcall(v->parser, id_d_reduce,
                   4, tmp_t, reduce_to, v->tstack, v->vstack);
    }

    /* calculate transition state */
    if (RARRAY_LEN(v->state) == 0)
        rb_raise(RaccBug, "state stack unexpectedly empty");
    k2 = num_to_long(LAST_I(v->state));
    k1 = num_to_long(reduce_to) - v->nt_base;
    D_printf("(goto) k1=%ld\n", k1);
    D_printf("(goto) k2=%ld\n", k2);

    tmp = AREF(v->goto_pointer, k1);
    if (NIL_P(tmp)) goto notfound;

    i = NUM2LONG(tmp) + k2;
    D_printf("(goto) i=%ld\n", i);
    if (i < 0) goto notfound;

    goto_state = AREF(v->goto_table, i);
    if (NIL_P(goto_state)) {
        D_puts("(goto) table[i] == nil");
        goto notfound;
    }
    D_printf("(goto) table[i]=%ld (goto_state)\n", NUM2LONG(goto_state));

    tmp = AREF(v->goto_check, i);
    if (NIL_P(tmp)) {
        D_puts("(goto) check[i] == nil");
        goto notfound;
    }
    if (tmp != LONG2NUM(k1)) {
        D_puts("(goto) check[i] != table[i]");
        goto notfound;
    }
    D_printf("(goto) check[i]=%ld\n", NUM2LONG(tmp));

    D_puts("(goto) found");
  transit:
    PUSH(v->state, goto_state);
    v->curstate = NUM2LONG(goto_state);
    return INT2FIX(0);

  notfound:
    D_puts("(goto) not found: use default");
    /* overwrite `goto-state' by default value */
    goto_state = AREF(v->goto_default, k1);
    goto transit;
}
コード例 #9
0
ファイル: cparse.c プロジェクト: vasco/racc
static void
parse_main(struct cparse_params *v, VALUE tok, VALUE val, int resume)
{
    long i;              /* table index */
    long act;            /* action type */
    VALUE act_value;     /* action type, VALUE version */
    int read_next = 1;   /* true if we need to read next token */
    VALUE tmp;

    if (resume)
        goto resume;
    
    while (1) {
        D_puts("");
        D_puts("---- enter new loop ----");
        D_puts("");

        D_printf("(act) k1=%ld\n", v->curstate);
        tmp = AREF(v->action_pointer, v->curstate);
        if (NIL_P(tmp)) goto notfound;
        D_puts("(act) pointer[k1] ok");
        i = NUM2LONG(tmp);

        D_printf("read_next=%d\n", read_next);
        if (read_next && (v->t != vFINAL_TOKEN)) {
            if (v->lex_is_iterator) {
                D_puts("resuming...");
                if (v->fin) rb_raise(rb_eArgError, "token given after EOF");
                v->i = i;  /* save i */
                return;
              resume:
                D_puts("resumed");
                i = v->i;  /* load i */
            }
            else {
                D_puts("next_token");
                tmp = rb_funcall(v->parser, id_nexttoken, 0);
                extract_user_token(v, tmp, &tok, &val);
            }
            /* convert token */
            v->t = rb_hash_aref(v->token_table, tok);
            if (NIL_P(v->t)) {
                v->t = vERROR_TOKEN;
            }
            D_printf("(act) t(k2)=%ld\n", NUM2LONG(v->t));
            if (v->debug) {
                rb_funcall(v->parser, id_d_read_token,
                           3, v->t, tok, val);
            }
        }
        read_next = 0;

        i += NUM2LONG(v->t);
        D_printf("(act) i=%ld\n", i);
        if (i < 0) goto notfound;

        act_value = AREF(v->action_table, i);
        if (NIL_P(act_value)) goto notfound;
        act = NUM2LONG(act_value);
        D_printf("(act) table[i]=%ld\n", act);

        tmp = AREF(v->action_check, i);
        if (NIL_P(tmp)) goto notfound;
        if (NUM2LONG(tmp) != v->curstate) goto notfound;
        D_printf("(act) check[i]=%ld\n", NUM2LONG(tmp));

        D_puts("(act) found");
      act_fixed:
        D_printf("act=%ld\n", act);
        goto handle_act;
    
      notfound:
        D_puts("(act) not found: use default");
        act_value = AREF(v->action_default, v->curstate);
        act = NUM2LONG(act_value);
        goto act_fixed;


      handle_act:
        if (act > 0 && act < v->shift_n) {
            D_puts("shift");
            if (v->errstatus > 0) {
                v->errstatus--;
                rb_ivar_set(v->parser, id_errstatus, LONG2NUM(v->errstatus));
            }
            SHIFT(v, act, v->t, val);
            read_next = 1;
        }
        else if (act < 0 && act > -(v->reduce_n)) {
            D_puts("reduce");
            REDUCE(v, act);
        }
        else if (act == -(v->reduce_n)) {
            goto error;
          error_recovered:
            ;   /* goto label requires stmt */
        }
        else if (act == v->shift_n) {
            D_puts("accept");
            goto accept;
        }
        else {
            rb_raise(RaccBug, "[Racc Bug] unknown act value %ld", act);
        }

        if (v->debug) {
            rb_funcall(v->parser, id_d_next_state,
                       2, LONG2NUM(v->curstate), v->state);
        }
    }
    /* not reach */


  accept:
    if (v->debug) rb_funcall(v->parser, id_d_accept, 0);
    v->retval = RARRAY_PTR(v->vstack)[0];
    v->fin = CP_FIN_ACCEPT;
    return;


  error:
    D_printf("error detected, status=%ld\n", v->errstatus);
    if (v->errstatus == 0) {
        v->nerr++;
        rb_funcall(v->parser, id_onerror,
                   3, v->t, val, v->vstack);
    }
  user_yyerror:
    if (v->errstatus == 3) {
        if (v->t == vFINAL_TOKEN) {
            v->retval = Qfalse;
            v->fin = CP_FIN_EOT;
            return;
        }
        read_next = 1;
    }
    v->errstatus = 3;
    rb_ivar_set(v->parser, id_errstatus, LONG2NUM(v->errstatus));

    /* check if we can shift/reduce error token */
    D_printf("(err) k1=%ld\n", v->curstate);
    D_printf("(err) k2=%d (error)\n", ERROR_TOKEN);
    while (1) {
        tmp = AREF(v->action_pointer, v->curstate);
        if (NIL_P(tmp)) goto error_pop;
        D_puts("(err) pointer[k1] ok");

        i = NUM2LONG(tmp) + ERROR_TOKEN;
        D_printf("(err) i=%ld\n", i);
        if (i < 0) goto error_pop;

        act_value = AREF(v->action_table, i);
        if (NIL_P(act_value)) {
            D_puts("(err) table[i] == nil");
            goto error_pop;
        }
        act = NUM2LONG(act_value);
        D_printf("(err) table[i]=%ld\n", act);

        tmp = AREF(v->action_check, i);
        if (NIL_P(tmp)) {
            D_puts("(err) check[i] == nil");
            goto error_pop;
        }
        if (NUM2LONG(tmp) != v->curstate) {
            D_puts("(err) check[i] != k1");
            goto error_pop;
        }

        D_puts("(err) found: can handle error token");
        break;
          
      error_pop:
        D_puts("(err) act not found: can't handle error token; pop");

        if (RARRAY_LEN(v->state) <= 1) {
            v->retval = Qnil;
            v->fin = CP_FIN_CANTPOP;
            return;
        }
        POP(v->state);
        POP(v->vstack);
        v->curstate = num_to_long(LAST_I(v->state));
        if (v->debug) {
            POP(v->tstack);
            rb_funcall(v->parser, id_d_e_pop,
                       3, v->state, v->tstack, v->vstack);
        }
    }

    /* shift/reduce error token */
    if (act > 0 && act < v->shift_n) {
        D_puts("e shift");
        SHIFT(v, act, ERROR_TOKEN, val);
    }
    else if (act < 0 && act > -(v->reduce_n)) {
        D_puts("e reduce");
        REDUCE(v, act);
    }
    else if (act == v->shift_n) {
        D_puts("e accept");
        goto accept;
    }
    else {
        rb_raise(RaccBug, "[Racc Bug] unknown act value %ld", act);
    }
    goto error_recovered;
}
コード例 #10
0
ファイル: p_setup.c プロジェクト: team-eternity/calico-doom
void P_SetupLevel(int map, skill_t skill)
{
    int          i;
    static char  lumpname[16];
    int          lumpnum;
    mobj_t      *mobj;
    extern int   cy;

    M_ClearRandom();

    P_LoadingPlaque();

    D_printf("P_SetupLevel(%i,%i)\n", map, skill);

    totalkills = totalitems = totalsecret = 0;
    for(i = 0; i < MAXPLAYERS; i++)
        players[i].killcount = players[i].secretcount = players[i].itemcount = 0;

    Z_CheckHeap(mainzone);
    Z_CheckHeap(refzone);

    Z_FreeTags(mainzone);

    P_InitThinkers();

    //
    // look for a regular (development) map first
    //
    lumpname[0] = 'M';
    lumpname[1] = 'A';
    lumpname[2] = 'P';
    lumpname[3] = '0' + map / 10;
    lumpname[4] = '0' + map % 10;
    lumpname[5] = 0;

    lumpnum = W_GetNumForName(lumpname);

    // note: most of this ordering is important
    P_LoadBlockMap(lumpnum+ML_BLOCKMAP);
    P_LoadVertexes(lumpnum+ML_VERTEXES);
    P_LoadSectors(lumpnum+ML_SECTORS);
    P_LoadSideDefs(lumpnum+ML_SIDEDEFS);
    P_LoadLineDefs(lumpnum+ML_LINEDEFS);
    P_LoadSubsectors(lumpnum+ML_SSECTORS);
    P_LoadNodes(lumpnum+ML_NODES);
    P_LoadSegs(lumpnum+ML_SEGS);

    rejectmatrix = W_CacheLumpNum(lumpnum + ML_REJECT, PU_LEVEL);

    P_GroupLines();

    deathmatch_p = deathmatchstarts;
    P_LoadThings(lumpnum + ML_THINGS);

    //
    // if deathmatch, randomly spawn the active players
    //
    if(netgame == gt_deathmatch)
    {
        for(i = 0; i < MAXPLAYERS; i++)
        {
            if(playeringame[i])
            {
                // must give a player spot before deathmatchspawn
                mobj = P_SpawnMobj(deathmatchstarts[0].x << 16 ,deathmatchstarts[0].y << 16, 0, MT_PLAYER);
                players[i].mo = mobj;
                G_DeathMatchSpawnPlayer(i);
                P_RemoveMobj(mobj);
            }
        }
    }

    // set up world state
    P_SpawnSpecials();
    ST_InitEveryLevel();

    cy = 4;

    iquehead = iquetail = 0;
    gamepaused = false;
}
コード例 #11
0
ファイル: p_setup.c プロジェクト: Arc0re/jaguardoom
void P_SetupLevel (int map, skill_t skill)
{
	int		i;
	static char	lumpname[16];
	int		lumpnum;
	mobj_t	*mobj;
	extern	int	cy;
	
	M_ClearRandom ();

	P_LoadingPlaque ();
	
D_printf ("P_SetupLevel(%i,%i)\n",map,skill);
	
	totalkills = totalitems = totalsecret = 0;
	for (i=0 ; i<MAXPLAYERS ; i++)
	{
		players[i].killcount = players[i].secretcount 
		= players[i].itemcount = 0;
	}

Z_CheckHeap (mainzone);		
#ifndef MARS
Z_CheckHeap (refzone);
#endif

	Z_FreeTags (mainzone);
/*PrintHex (1,1,Z_FreeMemory (mainzone)); */

	P_InitThinkers ();
	
/* */
/* look for a regular (development) map first */
/* */
	lumpname[0] = 'M';
	lumpname[1] = 'A';
	lumpname[2] = 'P';
	lumpname[3] = '0' + map/10;
	lumpname[4] = '0' + map%10;
	lumpname[5] = 0;
	
	lumpnum = W_GetNumForName (lumpname);
	
/* note: most of this ordering is important	 */
	P_LoadBlockMap (lumpnum+ML_BLOCKMAP);
	P_LoadVertexes (lumpnum+ML_VERTEXES);
	P_LoadSectors (lumpnum+ML_SECTORS);
	P_LoadSideDefs (lumpnum+ML_SIDEDEFS);
	P_LoadLineDefs (lumpnum+ML_LINEDEFS);
	P_LoadSubsectors (lumpnum+ML_SSECTORS);
	P_LoadNodes (lumpnum+ML_NODES);
	P_LoadSegs (lumpnum+ML_SEGS);
	
#ifdef MARS
	rejectmatrix = (byte *)(wadfileptr+BIGLONG(lumpinfo[lumpnum+ML_REJECT].filepos));
#else
	rejectmatrix = W_CacheLumpNum (lumpnum+ML_REJECT,PU_LEVEL);
#endif

	P_GroupLines ();

	deathmatch_p = deathmatchstarts;
	P_LoadThings (lumpnum+ML_THINGS);
	
/* */
/* if deathmatch, randomly spawn the active players */
/* */
	if (netgame == gt_deathmatch)
	{
		for (i=0 ; i<MAXPLAYERS ; i++)
			if (playeringame[i])
			{	/* must give a player spot before deathmatchspawn */
				mobj = P_SpawnMobj (deathmatchstarts[0].x<<16
				,deathmatchstarts[0].y<<16,0, MT_PLAYER);
				players[i].mo = mobj;
				G_DeathMatchSpawnPlayer (i);
				P_RemoveMobj (mobj);
			}
	}
	
/* set up world state */
	P_SpawnSpecials ();
	ST_InitEveryLevel ();
	
/*printf ("free memory: 0x%x\n", Z_FreeMemory(mainzone)); */

	cy = 4;

#ifdef JAGUAR
{
extern byte *debugscreen;
	D_memset (debugscreen,0,32*224);
	
}
#endif

	iquehead = iquetail = 0;
	gamepaused = false;
}
コード例 #12
0
ファイル: segreg.c プロジェクト: jschwartzenberg/dosemu2
int msdos_fault(struct sigcontext *scp)
{
    struct sigcontext new_sct;
    int reg;
    unsigned int segment;
    unsigned short desc;

    D_printf("MSDOS: msdos_fault, err=%#lx\n", _err);
    if ((_err & 0xffff) == 0)	/*  not a selector error */
	return msdos_ldt_fault(scp);

    /* now it is a invalid selector error, try to fix it if it is */
    /* caused by an instruction such as mov Sreg,r/m16            */
#define ALL_GDTS 0
#if !ALL_GDTS
    segment = (_err & 0xfff8);
    /* only allow using some special GTDs */
    switch (segment) {
    case 0x0040:
    case 0xa000:
    case 0xb000:
    case 0xb800:
    case 0xc000:
    case 0xe000:
    case 0xf000:
    case 0xbf8:
    case 0xf800:
    case 0xff00:
    case 0x38:		// ShellShock installer
	break;
    default:
	return 0;
    }
    copy_context(&new_sct, scp, 0);
    reg = decode_segreg(&new_sct);
    if (reg == -1)
	return 0;
#else
    copy_context(&new_sct, scp, 0);
    reg = decode_modify_segreg_insn(&new_sct, 1, &segment);
    if (reg == -1)
	return 0;

    if (ValidAndUsedSelector(segment)) {
	/*
	 * The selector itself is OK, but the descriptor (type) is not.
	 * We cannot fix this! So just give up immediately and dont
	 * screw up the context.
	 */
	D_printf("MSDOS: msdos_fault: Illegal use of selector %#x\n",
		 segment);
	return 0;
    }
#endif

    D_printf("MSDOS: try mov to a invalid selector 0x%04x\n", segment);

    switch (segment) {
    case 0x38:
	/* dos4gw sets VCPI descriptors 0x28, 0x30, 0x38 */
	/* The 0x38 is the "flat data" segment (0,4G) */
	desc = ConvertSegmentToDescriptor_lim(0, 0xffffffff);
	break;
    default:
	/* any other special cases? */
	desc = ConvertSegmentToDescriptor(segment);
    }
    if (!desc)
	return 0;

    /* OKay, all the sanity checks passed. Now we go and fix the selector */
    copy_context(scp, &new_sct, 0);
    switch (reg) {
    case es_INDEX:
	_es = desc;
	break;
    case cs_INDEX:
	_cs = desc;
	break;
    case ss_INDEX:
	_ss = desc;
	break;
    case ds_INDEX:
	_ds = desc;
	break;
    case fs_INDEX:
	_fs = desc;
	break;
    case gs_INDEX:
	_gs = desc;
	break;
    }

    /* let's hope we fixed the thing, and return */
    return 1;
}
コード例 #13
0
ファイル: callbacks.c プロジェクト: andrewbird/dosemu2
void xms_ret(struct sigcontext *scp, const struct RealModeCallStructure *rmreg)
{
    rm_to_pm_regs(scp, rmreg, ~0);
    D_printf("MSDOS: XMS call return\n");
}