/* $Id: return.c,v 1.4 2001/12/24 01:09:05 sybalsky Exp $ (C) Copyright Venue, All Rights Reserved */ /************************************************************************/ /* */ /* (C) Copyright 1989-95 Venue. All Rights Reserved. */ /* Manufactured in the United States of America. */ /* */ /************************************************************************/ #include "version.h" /***********************************************************/ /* File Name : return.c Including : OP_contextsw contextsw Created : May 1, 1987 Takeshi Shimizu Changed : May 19 1987 take Aug 27 1987 NMitani Sep.02 1987 take Sep.09 1987 take Oct.23 1987 Take */ /***********************************************************/ #include #include "lispemul.h" #include "address.h" #include "adr68k.h" #include "lsptypes.h" #include "lispmap.h" #include "stack.h" #include "emlglob.h" #include "lspglob.h" #include "initatms.h" #include "cell.h" #include "return.h" #include "returndefs.h" #include "commondefs.h" /***********************************************************************/ /* Func Name : OP_contextsw Created : Jul 3, 1987 Takeshi Shimizu changed AUG 25 1987 TAKE aug 31 take Aug 4 1987 NMitani Oct 23 1987 Take Nov 05 1987 Take(modify flags,del. whocalls and incall args) Desc : Execute ContextSW to FX specified as offset from IFPGE by TOS . */ /***********************************************************************/ void OP_contextsw(void) { void contextsw(DLword fxnum, DLword bytenum, DLword flags); #ifdef TRACE printf("OP_contextsw:\n"); #endif contextsw(TopOfStack & 0xffff, 1, 2); /* TOS will be smashed ?? I'm not sure . PC will be incremented 1. */ } /* OP_contextsw */ /************************************************************************/ /* */ /* C O N T E X T S W */ /* */ /* Context switch */ /* */ /************************************************************************/ void contextsw(register DLword fxnum, register DLword bytenum, register DLword flags) /* BYTEnum that you want increment PC after CONTEXTSW */ /* 0bit(MSB) ON: incall mode */ /* 1bit ON : call from OP_contextsw */ /* I don't know that it is the possible case that flags is 3 . */ { register DLword *next68k; register DLword *freeptr; /* point to STK to be FSB */ #ifdef TRACE printf("contextsw : %d \n", fxnum); #endif if (!(fxnum == SubovFXP)) { /* interrupt disable during executing [special] function invoked by contextsw(\KEYHANDLER,\RESETSTACK,FAULT) */ } if (flags & 1) /* INCALL? */ error("contextswitch sets Incall"); else CURRENTFX->nopush = T; /* store PC */ CURRENTFX->pc = (UNSIGNED)PC - (UNSIGNED)FuncObj + bytenum; /* TOS save */ if (flags & 2) { PushStack(fxnum); CurrentStackPTR += 2; } else { PushCStack; CurrentStackPTR += 2; } CURRENTFX->nextblock = LOLOC(LADDR_from_68k(CurrentStackPTR)); /* FSB set */ GETWORD(CurrentStackPTR) = STK_FSB_WORD; GETWORD(CurrentStackPTR + 1) = (((UNSIGNED)EndSTKP - (UNSIGNED)CurrentStackPTR) >> 1); if (0 == GETWORD(CurrentStackPTR + 1)) error("creating 0-long free stack block."); #ifdef STACKCHECK if (EndSTKP < CurrentStackPTR) error("contextsw:Illegal ESP"); #endif Midpunt(fxnum); /* exchanging FX */ next68k = (DLword *)Addr68k_from_LADDR(STK_OFFSET | CURRENTFX->nextblock); if (GETWORD(next68k) != STK_FSB_WORD) error("contextsw(): MP9316"); freeptr = next68k; /* Merging FSB area */ while (GETWORD(freeptr) == STK_FSB_WORD) EndSTKP = freeptr = freeptr + GETWORD(freeptr + 1); #ifdef DEBUG printf("contextsw:ESTKP set "); laddr(EndSTKP); #endif if (CURRENTFX->incall) { error("return to frame with incall bit "); } else { if (CURRENTFX->nopush) { #ifdef DEBUG printf("context:after:nopush \n"); #endif CURRENTFX->nopush = NIL; CurrentStackPTR = next68k - 2; TopOfStack = *((LispPTR *)CurrentStackPTR); CurrentStackPTR -= 2; } else { #ifdef DEBUG printf("context:after:3 \n"); #endif CurrentStackPTR = next68k - 2 /*-1*/; /* CHanged by Hayata */ } #ifdef STACKCHECK CHECKFX; if (EndSTKP < CurrentStackPTR) error("contextsw:Illegal ESP"); #endif FastRetCALL return; } } /* end contextsw */