1
0
mirror of https://github.com/Interlisp/maiko.git synced 2026-01-21 10:03:00 +00:00

1263 lines
34 KiB
C
Executable File

/* $Id: llstk.c,v 1.5 2001/12/26 22:17:03 sybalsky Exp $ (C) Copyright Venue, All Rights Reserved */
static char *id = "$Id: llstk.c,v 1.5 2001/12/26 22:17:03 sybalsky Exp $ Copyright (C) Venue";
/************************************************************************/
/* */
/* (C) Copyright 1989-95 Venue. All Rights Reserved. */
/* Manufactured in the United States of America. */
/* */
/* The contents of this file are proprietary information */
/* belonging to Venue, and are provided to you under license. */
/* They may not be further distributed or disclosed to third */
/* parties without the specific permission of Venue. */
/* */
/************************************************************************/
#include "version.h"
/******************************************************************/
/*
File Name : llstk.c
Desc. : Low Level stack operations
Including :
Edited by : Takeshi Shimizu(March 14, 1988)
*/
/******************************************************************/
#include <stdio.h> /* for printf */
#include "lispemul.h"
#include "lispmap.h"
#include "adr68k.h"
#include "address.h"
#include "lsptypes.h"
#include "initatms.h"
#include "lspglob.h"
#include "emlglob.h"
#include "cell.h"
#include "stack.h"
#include "return.h"
extern int extended_frame;
/******************************************************************/
/*
Func Name : moveframe(oldfx68k)
Edited by : Take(March 14, 1988)
*/
/******************************************************************/
LispPTR moveframe(register FX *oldfx68k)
{
register int size;
register DLword *next68k;
register DLword *new68k;
DLword *freestackblock(DLword n, StackWord *start68k, int align);
DLword *extendstack(void);
int nametbl_on_stk =NIL;
int at_eos = NIL;
PreMoveFrameCheck(oldfx68k);
#ifdef FLIPCURSOR
flip_cursorbar(10);
#endif
size = FX_size(oldfx68k) + DLWORDSPER_CELL;
S_CHECK(size > 0, "size of stack block < 0");
next68k=Addr68k_from_StkOffset(oldfx68k->nextblock);
tryfsb:
if(FSBP(next68k))
{
/* merge free blocks */
new68k = next68k + FSB_size(next68k);
if(FSBP(new68k))
{
for(;FSBP(new68k); new68k = new68k + FSB_size(new68k))
FSB_size(next68k) += FSB_size(new68k);
new68k=(DLword *)oldfx68k;
goto out;
}
else if(StkOffset_from_68K(new68k) == InterfacePage->endofstack)
{
if((StkOffset_from_68K(new68k) > LOLOC(*GuardStackAddr_word)) &&
((*STACKOVERFLOW_word)== NIL) )
at_eos = T; /* search FSB in earler STACK area by freestackblock */
else if(extendstack() != NIL)
{
new68k=(DLword *)oldfx68k;
goto out;
}
else
{
/* These lines are different from Original Code */
return(0xFFFF); /* No space */
}
}/* else if end */
}
CHECK_FX(oldfx68k);
S_CHECK(oldfx68k->usecount == 0, "use count > 0");
/* we don't check \INTERRUPTABLE */
#ifdef BIGVM
if(oldfx68k->validnametable && ((oldfx68k->nametable>>16)==STK_HI))
#else
if(oldfx68k->validnametable && (oldfx68k->hi2nametable==STK_HI))
#endif /* BIGVM */
{
/* frame contains a name table, so we care that the alignment
of the new block be same as old */
#ifdef STACKCHECK
{ DLword n;
#ifdef BIGVM
n = oldfx68k->nametable & 0xFFFF;
#else
n=oldfx68k->lonametable;
#endif /* BIGVM */
if((n <= StkOffset_from_68K(oldfx68k))
&& (n >= oldfx68k->nextblock))
{ WARN("moveframe:check!!", sff(LADDR_from_68k(oldfx68k)));}
}
#endif
nametbl_on_stk = T;
/* Find a free stack block */
new68k=freestackblock(size,(StackWord *)oldfx68k,
(LADDR_from_68k(oldfx68k)-DLWORDSPER_CELL)% DLWORDSPER_QUAD);
}
else
new68k=freestackblock(size,(StackWord *)oldfx68k,-1);/* Not needed to align */
if(new68k==0) return(0xFFFF); /* exhausted */
if (new68k < Stackspace) error("freestackblock returned gunk.");
if( at_eos && ((UNSIGNED)new68k > (UNSIGNED)oldfx68k))
{
/* extendstack already done in freestackblock */
((STKBLK*)new68k)->flagword = STK_FSB_WORD;
if (((STKBLK *)new68k)->size == 0) error("0-long stack freeblock.");
goto tryfsb;
}
/* copy frame and dummy bf pointer too */
blt(new68k,(((DLword*)oldfx68k) - DLWORDSPER_CELL),size);
((Bframe*)new68k)->residual =T;
new68k = new68k + DLWORDSPER_CELL; /* now NEW points to the FX */
((FX*)new68k)->nextblock = (StkOffset_from_68K(new68k) + size)
-DLWORDSPER_CELL;
/* (CHECK (fetch (BF CHECKED) of (fetch (FX BLINK) of OLDFRAME)))*/
CHECK_BF(Addr68k_from_StkOffset(GETBLINK(oldfx68k)));
/* Set true BFptr,not residual */
SETBLINK(new68k,GETBLINK(oldfx68k));
if(nametbl_on_stk)
{
S_CHECK(( (((UNSIGNED)new68k - (UNSIGNED)oldfx68k)>>1) % DLWORDSPER_QUAD) == 0,
"Misalignment of stack blocks, with nametable on stack");
#ifdef BIGVM
((FX*)new68k)->nametable += (((UNSIGNED)new68k - (UNSIGNED)oldfx68k)>>1);
#else
((FX*)new68k)->lonametable += (((UNSIGNED)new68k - (UNSIGNED)oldfx68k)>>1);
#endif
}
if( ((Bframe*)DUMMYBF(oldfx68k))->residual )
{
MAKEFREEBLOCK(((DLword*)oldfx68k)-DLWORDSPER_CELL , size);
}
else
{
MAKEFREEBLOCK(oldfx68k,size - DLWORDSPER_CELL);
}
out:
#ifdef FLIPCURSOR
flip_cursorbar(10);
#endif
return(S_POSITIVE|StkOffset_from_68K(new68k));
} /* moveframe end */
/******************************************************************/
/*
Func Name : do_stackoverflow(incallp)
retval: If There is no space for stack then return 1
else return 0
incallp:
If Calling during function call,incallp=T
else NIL
Edited by : Take(March 28, 1988)
*/
/******************************************************************/
int do_stackoverflow(int incallp)
{
register DLword *next68k;
DLword newfx;
DLword savenext;
DLword *oldPVar;
int movedistance;
LispPTR moveframe(register FX *oldfx68k);
#ifdef STACKCHECK
LispPTR stackcontents;
LispPTR TopIVAR;
stackcontents= *((LispPTR*)CurrentStackPTR);
TopIVAR= *((LispPTR*)IVar);
#endif
/* Don't care PC,FuncObj, */
/*if incall flag ON ,Don't care IVar
,became resudual and it is pointed by copied FX's BLINK*/
oldPVar=PVar;
if(*NeedHardreturnCleanup_word)
{
warn("HardreturnCleanup in do_stackoverflow");
}
if(incallp)
{
savenext=CURRENTFX->nextblock; /* save old nextblock */
}
BEFORE_CONTEXTSW; /* Don't Use MIDPUNT and Don't care IFPAGE */
/* Call MOVEFRAME directly */
if((newfx=(DLword)moveframe(CURRENTFX)) == 0xFFFF)
{
/* To make immidiately call HARDRESET */
Irq_Stk_Check = 0;
Irq_Stk_End=0;
return(1); /* Whole space exausted */
}
/* Return from MOVEFRAME directly */
PVar=(DLword*)Addr68k_from_StkOffset(newfx+FRAMESIZE);
movedistance= ((UNSIGNED)PVar-(UNSIGNED)oldPVar) >>1;
AFTER_CONTEXTSW;
if(incallp)
{
/* set next(it pointed to old IVar) with offset */
CURRENTFX->nextblock= savenext + movedistance;
/* including Last Arg(kept in TOS */
#ifdef BIGVM
S_CHECK(FuncObj == (struct fnhead *)
Addr68k_from_LADDR(CURRENTFX->fnheader),
"in call, but stack frame doesn't match FN being executed." );
#else
S_CHECK(FuncObj == (struct fnhead *)
Addr68k_from_LADDR(
(CURRENTFX->hi2fnheader << 16) |
CURRENTFX->lofnheader),
"in call, but stack frame doesn't match FN being executed." );
#endif /* BIGVM */
CHECK_FX(CURRENTFX);
/* We should re-Set up IVAR,CURRENTFX->nextblock */
IVar += movedistance;
} /* incallp */
return(0); /* Normal return */
/* If incallp ,we CAN continue executing FN or APPLY by just returning */
/* new PVar will set in funcall */
}/* end do_stackoverflow */
/******************************************************************/
/*
Func Name : extendstack()
Desc. : if LastStackAddr_word is exceeded,then allocate
one new lisppage for STACK area.
Edited by : Take(March 14, 1988)
*/
/******************************************************************/
DLword *extendstack(void)
{
register LispPTR easp;
register LispPTR scanptr;
easp = InterfacePage->endofstack;
if (easp < LOLOC(*LastStackAddr_word))
{
if((easp > LOLOC(*GuardStackAddr_word)) &&
((*STACKOVERFLOW_word)== NIL) )
{ extended_frame = 1;
((INTSTAT*)Addr68k_from_LADDR(*INTERRUPTSTATE_word))->stackoverflow = 1;
*STACKOVERFLOW_word = *PENDINGINTERRUPT_word=ATOM_T;
}
newpage(STK_OFFSET|(scanptr=easp+2));
/* I don't concern about DOLOCKPAGES */
MAKEFREEBLOCK(Addr68k_from_StkOffset(scanptr),DLWORDSPER_PAGE-2);
InterfacePage->endofstack = scanptr=easp+DLWORDSPER_PAGE;
SETUPGUARDBLOCK(
Addr68k_from_StkOffset(InterfacePage->endofstack), 2);
MAKEFREEBLOCK(Addr68k_from_StkOffset(easp) , 2);
return((DLword*)Addr68k_from_StkOffset(scanptr));
}
else return(NIL);
} /* end extendstack */
/******************************************************************/
/*
Func Name : freestackblock(n,sart,align)
Desc. : Search the FSB has specified size n or more
Return useful area's ptr.
If there is no space for STACK,return 0
Edited by : take(15-Jul-87)
take(11-Apr-88)
*/
/******************************************************************/
DLword *freestackblock(DLword n, StackWord *start68k, int align)
/* size you want(in DLword) */
/* searching will start68k at here */
/* if Negative,it needn't align */
{
register int wantedsize;
register StackWord *scanptr68k;
StackWord *ooscan, *oscan;
register StackWord *orig68k;
register STKBLK *freeptr68k;
register StackWord *easp68k;
register DLword freesize;
DLword *extendstack(void);
if (n%2) error("asking for odd-length stack block");
/* compute actually size you needed */
wantedsize = n + STACKAREA_SIZE + MINEXTRASTACKWORDS;
easp68k =(StackWord*) (Addr68k_from_StkOffset(InterfacePage->endofstack));
/*** DEBUG ***/
S_CHECK(n>2, "asking for block < 2 words long");
S_CHECK(start68k != 0, "start68k = 0");
S_CHECK(start68k >=
(StackWord*)Addr68k_from_StkOffset(InterfacePage->stackbase),
"start68k before stack base");
STARTOVER :
if(start68k) scanptr68k = start68k;
else scanptr68k =
(StackWord *)Addr68k_from_StkOffset(InterfacePage->stackbase);
SCAN : switch((unsigned)(STKWORD(scanptr68k)->flags))
{
case STK_FSB : goto FREESCAN;
break;
case STK_GUARD: if((UNSIGNED)scanptr68k < (UNSIGNED)easp68k)
goto FREESCAN;
if (start68k)
{
scanptr68k =(StackWord *)Addr68k_from_StkOffset
(InterfacePage->stackbase);
goto SCAN;
}
else goto NEWPAGE;
break;
case STK_FX : scanptr68k =(StackWord *)Addr68k_from_StkOffset(
((FX*)scanptr68k)->nextblock);
break;
default : orig68k = scanptr68k;
while(STKWORD(scanptr68k)->flags != STK_BF)
{
S_WARN(STKWORD(scanptr68k)->flags==STK_NOTFLG,
"NOTFLG not on", scanptr68k);
scanptr68k = (StackWord *)
(((DLword *)scanptr68k)
+ DLWORDSPER_CELL);
};
#ifdef STACKCHECK
if(((Bframe*)scanptr68k)->residual)
{ if(scanptr68k != orig68k)
{
WARN("freestackblock:scanptr68k !=org",
printf(":0x%x\n",
LADDR_from_68k(scanptr68k)));
}
}
else
{
if(((Bframe*)scanptr68k)->ivar
!= StkOffset_from_68K(orig68k))
{
WARN("BF doesn't point TopIVAR",
printf(":0x%x\n",
LADDR_from_68k(scanptr68k)));
}
}
#endif
/* Used to be a +=, but SunOS4/Sparc compiles it wrong */
scanptr68k = (StackWord *)
((DLword *)scanptr68k
+ DLWORDSPER_CELL);
break;
} /* end switch(scanptr68k */
NEXT: if(scanptr68k != start68k)
{
S_CHECK((UNSIGNED)scanptr68k <=(UNSIGNED)easp68k, "scan ptr past end of stack");
goto SCAN;
}
NEWPAGE : easp68k =(StackWord*)extendstack();
if(easp68k) goto STARTOVER;
else
{
warn("freestackblock:StackFull MP9319");
return(0);
}
FREESCAN : freeptr68k=(STKBLK *)scanptr68k;
freesize=FSB_size(freeptr68k);
FREE:
ooscan = oscan; oscan = scanptr68k;
scanptr68k = (StackWord *)(((DLword *)freeptr68k) + freesize);
if (freesize == 0) error("FREESIZE = 0");
switch((unsigned)(STKWORD(scanptr68k)->flags))
{
case STK_FSB: freesize = freesize + FSB_size(scanptr68k);
goto FREE;
case STK_GUARD: if((UNSIGNED)scanptr68k<(UNSIGNED)easp68k)
{
freesize = freesize + FSB_size(scanptr68k);
goto FREE;
}
break;
default : break;
} /* end switch(scanp.. */
if(freesize >= wantedsize)
{
if((align<0) ||
(align==(StkOffset_from_68K(freeptr68k) % DLWORDSPER_QUAD)))
wantedsize= MINEXTRASTACKWORDS;
else wantedsize= MINEXTRASTACKWORDS+DLWORDSPER_CELL;
scanptr68k =(StackWord*) (((DLword *)freeptr68k) + wantedsize);
SETUPGUARDBLOCK(scanptr68k, n);
MAKEFREEBLOCK(freeptr68k,wantedsize);
MAKEFREEBLOCK(((DLword*)scanptr68k) + n, freesize - wantedsize -n);
return((DLword*)scanptr68k);
}
else MAKEFREEBLOCK( freeptr68k, freesize);
goto NEXT;
} /* freestackblock end */
/******************************************************************/
/*
Func Name : decusecount68k(frame)
Desc. : Search the FSB has specified size n or more
Return useful are ptr.
Edited by : take(March 14, 1988)
*/
/******************************************************************/
#define BF_size(ptr68k) ((StkOffset_from_68K(ptr68k)) - ((Bframe*)(ptr68k))->ivar + 2)
decusecount68k(register FX *frame68k)
{
DLword *alink68k;
register Bframe *blink68k;
DLword *clink68k;
register DLword *ivar68k;
register int size;
if(FX_INVALIDP(frame68k)) return;
CHECK_FX(frame68k);
/* I don't check if \INTERRUPTABLE is NIL */
while(StkOffset_from_68K(frame68k))
{
if(frame68k->usecount != 0)
{
frame68k->usecount--;
return;
}
else
{
alink68k = Addr68k_from_StkOffset(GETALINK(frame68k));
blink68k =(Bframe*) Addr68k_from_StkOffset(GETBLINK(frame68k));
clink68k = Addr68k_from_StkOffset(GETCLINK(frame68k));
size = FX_size(frame68k);
if(((Bframe*)DUMMYBF(frame68k))->residual)
{ /* this frame has dummy BF */
MAKEFREEBLOCK(((DLword*)frame68k) -DLWORDSPER_CELL,size+DLWORDSPER_CELL);
}
else
{
MAKEFREEBLOCK(frame68k,size);
}
if(blink68k->usecnt !=0)
{
blink68k->usecnt--;
}
else
{
/*** ivar68k=Addr68k_from_StkOffset(blink68k->ivar);
GETWORD(ivar68k)=STK_FSB_WORD;
GETWORD(ivar68k+1)=ivar68k -(DLword *)blink68k +2; **/
MAKEFREEBLOCK(Addr68k_from_StkOffset(blink68k->ivar),
BF_size(blink68k));
}
if(alink68k!= clink68k)
decusecount68k((FX *)alink68k);
frame68k = (FX*)clink68k;
} /* else end */
}/*while end */
} /* decusecount68k end */
#ifdef ORG_FILPCORSORBAR
extern DLword *EmCursorBitMap68K;
extern int LispWindowFd;
#ifdef XWINDOW
extern int Current_Hot_X, Current_Hot_Y;
#endif /* XWINDOW */
extern struct cursor CurrentCursor;
flip_cursorbar(n)
int n;
{
GETWORD(EmCursorBitMap68K +n) = ~(GETWORD(EmCursorBitMap68K +n));
#ifdef SUNDISPLAY
win_setcursor(LispWindowFd,&CurrentCursor);
#endif /* SUNDISPLAY */
#ifdef XWINDOW
/* JDS 011213 When using current_hot_y, remember fn does 15-it! */
Set_XCursor( Current_Hot_X, 15-Current_Hot_Y );
#endif /* XWINDOW */
}
#else
extern short *DisplayRegion68k;
extern int DisplayRasterWidth;
flip_cursorbar(int n)
{
register short *word;
word = DisplayRegion68k + (n * DisplayRasterWidth);
GETWORD(word) ^= 0xFFFF;
}
#endif
/**************************************************************/
/*
blt(dest,source,size)
*/
/**************************************************************/
blt(register DLword *dest68k, register DLword *source68k, int nw)
{
/******* OLD def ,
Due to C compiler's bug, we can't use pre-decriment for register val
source68k += nw;
dest68k += nw;
while(nw)
{
GETWORD(--dest68k)= GETWORD(--source68k);
nw--;
}
**** OLD def ****/
source68k = source68k + nw-1;
dest68k = dest68k + nw-1;
while(nw--)
{
GETWORD(dest68k--) = GETWORD(source68k--);
}
}
/**************************************************************/
/*
stack_check(start68k)
for DEBUG
*/
/**************************************************************/
stack_check(StackWord *start68k)
{
StackWord *scanptr68k;
StackWord *endstack68k;
DLword *top_ivar;
DLword save_nextblock;
DLword savestack1,savestack2;
DLword setflg=NIL;
DLword freesize;
#ifdef FSBCHECK
struct big_fsbs { DLword offset; DLword size;} bigFSB[100];
int bigFSBindex=0;
memset((char*)bigFSB, 0, 100 * 2 * 2);
#endif
if((CURRENTFX->nextblock != StkOffset_from_68K(CurrentStackPTR))
||(!FSBP(CurrentStackPTR)))
{
if((DLword*)CURRENTFX >= CurrentStackPTR)
{
WARN("CURRENTFX >= CurrentStackPTR??\n",
printf("CURRENTFX=0x%x,CurrentStackPTR=0x%x\n",
LADDR_from_68k(CURRENTFX),LADDR_from_68k(CurrentStackPTR)));
}
setflg=T;
printf("set CURRENTFX->nextblock in debugger. But it will be reset after this check \n");
save_nextblock=CURRENTFX->nextblock;
savestack1= GETWORD(CurrentStackPTR+2);
savestack2= GETWORD(CurrentStackPTR+3);
CURRENTFX->nextblock=StkOffset_from_68K(CurrentStackPTR+2);
GETWORD(CurrentStackPTR+2)=STK_FSB_WORD;
GETWORD(CurrentStackPTR+3)= (((UNSIGNED)EndSTKP-(UNSIGNED)(CurrentStackPTR+2))>>1);
}
if(start68k) scanptr68k =start68k;
else scanptr68k =
(StackWord *)Addr68k_from_StkOffset(InterfacePage->stackbase);
endstack68k=(StackWord *)Addr68k_from_StkOffset(InterfacePage->endofstack);
if(STKWORD(endstack68k)->flags !=STK_GUARD)
printf("?? endstack is not GUARD BLK\n");
while(scanptr68k <endstack68k)
{
switch((unsigned)(STKWORD(scanptr68k)->flags))
{
case STK_FSB : freesize= FSB_size(scanptr68k);
if (freesize == 0)
{
warn("FSB freesize = 0!");
}
#ifdef FSBCHECK
if(freesize > STACKAREA_SIZE+MINEXTRASTACKWORDS)
{
if(bigFSBindex < 100)
{
bigFSB[bigFSBindex].offset = StkOffset_from_68K(scanptr68k);
bigFSB[bigFSBindex].size = freesize;
bigFSBindex++;
}
}
#endif
scanptr68k = (StackWord *)
((DLword *)scanptr68k + freesize);
putchar('F');
break;
case STK_GUARD: freesize = FSB_size(scanptr68k);
if (freesize == 0)
{
warn("Guard block freesize = 0!");
}
scanptr68k = (StackWord *)
((DLword *)scanptr68k + freesize);
putchar('G');
break;
case STK_FX : CHECK_FX(scanptr68k);
scanptr68k =(StackWord *)Addr68k_from_StkOffset(
((FX*)scanptr68k)->nextblock);
putchar('X');
break;
default: top_ivar=(DLword*)scanptr68k;
while(STKWORD(scanptr68k)->flags != STK_BF)
{
if (STKWORD(scanptr68k)->flags!=STK_NOTFLG)
{
WARN("StackCheck:!=STK_NOTFLG",
printf("content:0x%x\n",GETWORD(scanptr68k)));
}
scanptr68k = (StackWord *)
((DLword *)scanptr68k + DLWORDSPER_CELL);
}/* while end */;
CHECK_BF(scanptr68k);
if(((Bframe*)scanptr68k)->residual)
{
if((DLword*)scanptr68k != top_ivar)
printf("Residual has real IVAR:0x%x\n",
LADDR_from_68k(scanptr68k));
}
else
{
if(((Bframe*)scanptr68k)->ivar
!= StkOffset_from_68K(top_ivar))
printf("BF doesn't point TopIVAR:0x%x\n",
LADDR_from_68k(scanptr68k));
}
scanptr68k = (StackWord *)
((DLword *)scanptr68k
+ DLWORDSPER_CELL);
putchar('B');
break;
}/*switch end */
if(scanptr68k != start68k)
{
if(scanptr68k >endstack68k)
{
WARN("scanptr exceeded end stack",
printf("scanptr68k=0x%x endstack68k=0x%x",scanptr68k,endstack68k));
}
}
}/* while end */
#ifdef FSBCHECK
if(bigFSBindex!=0){
int i;
printf("\nBIG FSB(s):\n");
for(i=0;i<bigFSBindex;i++){
printf("Offset: 0x%x , Size: 0x%x\n",bigFSB[i].offset,bigFSB[i].size);
}
}
#endif
printf("\nStack Check done\n");
if(setflg)
{
CURRENTFX->nextblock=save_nextblock;
GETWORD(CurrentStackPTR+2)=savestack1;
GETWORD(CurrentStackPTR+3)=savestack2;
}
}/*stack_check end */
/**************************************************************/
/*
walk_stack(start68k)
for DEBUG
Walk the stack, printing information about what we
see as we go. Unlike stack_check, this prints frame
names, alink/clink/next values, free-block lengths, etc.
*/
/**************************************************************/
walk_stack(StackWord *start68k)
{
StackWord *scanptr68k;
StackWord *endstack68k;
DLword *top_ivar;
DLword save_nextblock;
DLword savestack1,savestack2;
DLword setflg=NIL;
DLword freesize;
if((CURRENTFX->nextblock != StkOffset_from_68K(CurrentStackPTR))
||(!FSBP(CurrentStackPTR)))
{
if((DLword*)CURRENTFX >= CurrentStackPTR)
{
WARN("CURRENTFX >= CurrentStackPTR??\n",
printf("CURRENTFX=0x%x,CurrentStackPTR=0x%x\n",
LADDR_from_68k(CURRENTFX),LADDR_from_68k(CurrentStackPTR)));
}
setflg=T;
printf("set CURRENTFX->nextblock in debugger. But it will be reset after this check \n");
save_nextblock=CURRENTFX->nextblock;
savestack1= GETWORD(CurrentStackPTR+2);
savestack2= GETWORD(CurrentStackPTR+3);
CURRENTFX->nextblock=StkOffset_from_68K(CurrentStackPTR+2);
GETWORD(CurrentStackPTR+2)=STK_FSB_WORD;
GETWORD(CurrentStackPTR+3)= (((UNSIGNED)EndSTKP-(UNSIGNED)(CurrentStackPTR+2))>>1);
}
/* Start from where caller specifies, (as real address!); if addr=0 */
/* start from stackbase. */
if(start68k)
{
scanptr68k =(StackWord *) ((unsigned long)start68k & -2 );
printf("Starting at 0x%x.", (DLword*)scanptr68k-Stackspace);
}
else
{
scanptr68k =
(StackWord *)Addr68k_from_StkOffset(InterfacePage->stackbase);
printf("Stack base = 0x%x.", (DLword*)scanptr68k-Stackspace);
}
endstack68k=(StackWord *)Addr68k_from_StkOffset(InterfacePage->endofstack);
printf(" End of stack = 0x%x.\n\n", (DLword*)endstack68k-Stackspace);
if(STKWORD(endstack68k)->flags !=STK_GUARD)
printf("?? endstack is not GUARD BLK\nendstack = 0x%x, flags = %d\n\n",
endstack68k, STKWORD(endstack68k)->flags);
while(scanptr68k < endstack68k)
{
switch((unsigned)(STKWORD(scanptr68k)->flags))
{
/* Free stack block */
case STK_FSB : freesize= FSB_size(scanptr68k);
printf("%04x: Free block (len %d/0x%x)\n",
(DLword*)scanptr68k-Stackspace, freesize,
freesize);
if (freesize == 0)
{
freesize = 2;
}
scanptr68k = (StackWord *)
((DLword *)scanptr68k + freesize);
break;
case STK_GUARD: freesize = FSB_size(scanptr68k);
printf("%04x: Guard block (len %d/0x%x)\n",
(DLword*)scanptr68k-Stackspace, freesize,
freesize);
if (freesize == 0)
{
freesize = 2;
}
scanptr68k = (StackWord *)
((DLword *)scanptr68k + freesize);
break;
case STK_FX : CHECK_FX(scanptr68k);
printf("%04x: ",
(DLword*)scanptr68k-Stackspace);
{
FX *fx = (FX *)scanptr68k;
struct fnhead *fnobj;
#ifdef BIGVM
fnobj = (struct fnhead *)
Addr68k_from_LADDR(fx->fnheader);
#else
fnobj = (struct fnhead *)
Addr68k_from_LADDR(
((int)fx->hi2fnheader << 16)
| fx->lofnheader);
#endif /* BIGVM */
print(fnobj->framename);
printf("\talink: 0x%04x, clink: 0x%04x, next: 0x%04x\n",
fx->alink, fx->clink, fx->nextblock);
}
{
Bframe *dummybf,*mtmp;
int mblink;
/* Now make sure the FX is connected to */
/* a Basic Frame. */
dummybf=(Bframe*)DUMMYBF(scanptr68k);
/* Check for connection via BLINK field: */
if(StkOffset_from_68K(dummybf)
!= GETBLINK(scanptr68k))
{
mblink=GETBLINK(scanptr68k);
mtmp=(Bframe*)
Addr68k_from_StkOffset(mblink);
if( ( dummybf->residual == NIL ) ||
( dummybf->ivar != mtmp->ivar ) )
printf(" [Bad residual]\n");
}
}
scanptr68k =(StackWord *)Addr68k_from_StkOffset(
((FX*)scanptr68k)->nextblock);
break;
default: top_ivar=(DLword*)scanptr68k;
while(STKWORD(scanptr68k)->flags != STK_BF)
{
if (STKWORD(scanptr68k)->flags!=STK_NOTFLG)
{
printf("%04x: Bad BF IVAR 0x%x\n",
(DLword*)scanptr68k-Stackspace,
GETWORD(scanptr68k));
}
scanptr68k = (StackWord *)
((DLword *)scanptr68k + DLWORDSPER_CELL);
}/* while end */;
/* CHECK_BF(scanptr68k); */
{
Bframe *bf = (Bframe *)scanptr68k;
printf("%04x: BF usecnt %d, resid %d, padding %d, ivar 0x%04x\n",
(DLword*)scanptr68k-Stackspace,
bf->usecnt, bf->residual, bf->padding,
bf->ivar);
if(((Bframe*)scanptr68k)->ivar
!= StkOffset_from_68K(top_ivar))
printf(" [but top_ivar = 0x%04x]\n",
top_ivar - Stackspace);
}
scanptr68k = (StackWord *)
((DLword *)scanptr68k
+ DLWORDSPER_CELL);
break;
}/*switch end */
if(scanptr68k != start68k)
{
if(scanptr68k >endstack68k)
{
WARN("scanptr exceeded end stack",
printf("scanptr68k=0x%x endstack68k=0x%x",scanptr68k,endstack68k));
}
}
}/* while end */
#ifdef FSBCHECK
if(bigFSBindex!=0){
int i;
printf("\nBIG FSB(s):\n");
for(i=0;i<bigFSBindex;i++){
printf("Offset: 0x%x , Size: 0x%x\n",bigFSB[i].offset,bigFSB[i].size);
}
}
#endif
printf("\nStack Check done\n");
if(setflg)
{
CURRENTFX->nextblock=save_nextblock;
GETWORD(CurrentStackPTR+2)=savestack1;
GETWORD(CurrentStackPTR+3)=savestack2;
}
} /* walk_stack end */
/**************************************************************/
/*
quick_stack_check()
for DEBUGING using FNSTKCHECK
*/
/**************************************************************/
quick_stack_check(void)
{
StackWord *start68k;
StackWord *scanptr68k;
StackWord *endstack68k;
DLword *top_ivar;
DLword save_nextblock;
DLword savestack1,savestack2;
DLword setflg=NIL;
DLword freesize;
#ifdef FSBCHECK
struct big_fsbs { DLword offset; DLword size;} bigFSB[100];
int bigFSBindex=0;
memset((char*)bigFSB, 0, 100 * 2 * 2);
#endif
if((CURRENTFX->nextblock != StkOffset_from_68K(CurrentStackPTR))
||(!FSBP(CurrentStackPTR)))
{
if((DLword*)CURRENTFX >= CurrentStackPTR)
{
return(0);
WARN("CURRENTFX >= CurrentStackPTR??\n",
printf("CURRENTFX=0x%x,CurrentStackPTR=0x%x\n",
LADDR_from_68k(CURRENTFX),LADDR_from_68k(CurrentStackPTR)));
}
setflg=T;
save_nextblock=CURRENTFX->nextblock;
savestack1= GETWORD(CurrentStackPTR+2);
savestack2= GETWORD(CurrentStackPTR+3);
CURRENTFX->nextblock=StkOffset_from_68K(CurrentStackPTR+2);
GETWORD(CurrentStackPTR+2)=STK_FSB_WORD;
GETWORD(CurrentStackPTR+3)= (((UNSIGNED)EndSTKP-(UNSIGNED)(CurrentStackPTR+2))>>1);
}
scanptr68k = start68k =
(StackWord *)Addr68k_from_StkOffset(InterfacePage->stackbase);
endstack68k=(StackWord *)Addr68k_from_StkOffset(InterfacePage->endofstack);
if(STKWORD(endstack68k)->flags !=STK_GUARD)
printf("?? endstack is not GUARD BLK\n");
while(scanptr68k <endstack68k)
{
switch((unsigned)(STKWORD(scanptr68k)->flags))
{
case STK_FSB : freesize= FSB_size(scanptr68k);
if (freesize == 0)
{
warn("FSB freesize = 0!");
return(1);
}
#ifdef FSBCHECK
if(freesize > STACKAREA_SIZE+MINEXTRASTACKWORDS){
if(bigFSBindex < 100){
bigFSB[bigFSBindex].offset = StkOffset_from_68K(scanptr68k);
bigFSB[bigFSBindex].size = freesize;
bigFSBindex++;
}
}
#endif
scanptr68k = (StackWord *)
((DLword *)scanptr68k + freesize);
break;
case STK_GUARD: freesize = FSB_size(scanptr68k);
if (freesize == 0)
{
warn("Guard block freesize = 0!");
return(1);
}
scanptr68k = (StackWord *)
((DLword *)scanptr68k + freesize);
break;
case STK_FX : CHECK_FX(scanptr68k);
scanptr68k =(StackWord *)Addr68k_from_StkOffset(
((FX*)scanptr68k)->nextblock);
break;
default: top_ivar=(DLword*)scanptr68k;
while(STKWORD(scanptr68k)->flags != STK_BF) {
if (STKWORD(scanptr68k)->flags!=STK_NOTFLG)
{
warn("StackCheck:!=STK_NOTFLG");
printf("content:0x%x\n",GETWORD(scanptr68k));
return(1);
}
scanptr68k = (StackWord *)
((DLword *)scanptr68k + DLWORDSPER_CELL);
}/* while end */;
CHECK_BF(scanptr68k);
if(((Bframe*)scanptr68k)->residual)
{
if((DLword*)scanptr68k != top_ivar)
printf("Residual has real IVAR:0x%x\n",LADDR_from_68k(scanptr68k));
}
else
{
if(((Bframe*)scanptr68k)->ivar
!= StkOffset_from_68K(top_ivar))
printf("BF doesn't point TopIVAR:0x%x\n",LADDR_from_68k(scanptr68k));
}
scanptr68k = (StackWord *)
((DLword *)scanptr68k
+ DLWORDSPER_CELL);
break;
}/*switch end */
if(scanptr68k != start68k)
{
if(scanptr68k >endstack68k)
{
WARN("scanptr exceeded end stack",printf("scanptr68k=0x%x endstack68k=0x%x",scanptr68k,endstack68k));
}
}
}/* while end */
#ifdef FSBCHECK
if(bigFSBindex!=0){
int i;
printf("\nBIG FSB(s):\n");
for(i=0;i<bigFSBindex;i++){
printf("Offset: 0x%x , Size: 0x%x\n",bigFSB[i].offset,bigFSB[i].size);
}
}
#endif
if(setflg)
{
CURRENTFX->nextblock=save_nextblock;
GETWORD(CurrentStackPTR+2)=savestack1;
GETWORD(CurrentStackPTR+3)=savestack2;
}
return(0);
}/* quick_stack_check end */
/************************************************************************/
/* */
/* C H E C K _ F X */
/* */
/* Consistency checks on a Frame Extension; used when the */
/* STACKCHECK compile switch is on. */
/* */
/* The function just returns if things are OK; calls error */
/* if there are problems. */
/* */
/************************************************************************/
check_FX(FX *fx68k)
{
Bframe *dummybf,*mtmp;
int mblink;
/* The FX better really be an FX */
if(((FX*)(fx68k))->flags != STK_FX)
error("CheckFX:NOT FX");
/* Make sure the NEXTBLOCK field of the FX */
/* Points BEYOND the start of the FX; some */
/* stack blocks have been corrupted this */
/* way. --JDS 2/3/98 */
if (fx68k->nextblock < StkOffset_from_68K(fx68k)/*+FRAMESIZE*/)
{
error("FX's nextblock field < the FFX.");
}
/* Now make sure the FX is connected to */
/* a Basic Frame. */
dummybf=(Bframe*)DUMMYBF(fx68k);
/* Check for connection via BLINK field: */
if(StkOffset_from_68K(dummybf) == GETBLINK(fx68k)) return;
mblink=GETBLINK(fx68k);
mtmp=(Bframe*)Addr68k_from_StkOffset(mblink);
if( ( dummybf->residual != NIL ) &&
( dummybf->ivar == mtmp->ivar ) )
return;
else error("CheckFX:bad residual case");
} /* END check_FX */
/************************************************************************/
/* */
/* C H E C K _ B F */
/* */
/* Check a Basic Frame (BF) for consistency. This is used */
/* when STACKCHECK is defined. */
/* */
/************************************************************************/
check_BF(Bframe *bf68k)
{
Bframe *iptr68k;
/* For starterd, it must BE a BF */
if(bf68k->flags != STK_BF) error("checkBF:not BF1");
/* If the frame is residual (whatever that means), it's OK */
if(bf68k->residual == T) return;
else
{
if (bf68k->ivar & 1) error("IVAR is ODD in a BF");
else for (iptr68k=(Bframe*)Addr68k_from_StkOffset(bf68k->ivar);
iptr68k <=(Bframe*)(((DLword*)bf68k)-2);
iptr68k++ ) /* inc 2DLword */
{
/* Make sure none of the "ivar" slots have stack-type */
/* bits set. */
if(iptr68k->flags!=STK_NOTFLG)
warn("CheckBF:Stack-bits set in IVAR");
}
}
} /* end check_BF */
/************************************************************************/
/* */
/* */
/* */
/* */
/* */
/************************************************************************/
check_stack_rooms(FX *fx68k)
{
int size;
DLword *freeptr68k,*endstk68k;
CHECK_FX(fx68k);
freeptr68k=Addr68k_from_StkOffset(fx68k->nextblock);
if(!FSBP(freeptr68k))
error("check_stack_rooms: nextblock doesn't point to an FSB");
/*endstk68k=freeptr68k + FSB_size(freeptr68k);
size=((UNSIGNED)endstk68k - (UNSIGNED)CurrentStackPTR) >> 1;*/
return(FSB_size(freeptr68k));
} /* end check_stack_rooms */