Main Page | Modules | File List | File Members

stack.c

00001 /* ndk - [ stack.c ]
00002  *
00003  * This source file implements a basic 32-bit stack;  Only longs/dwords
00004  * can be pushed or poped from the stack.  The stack can expand upwards
00005  * or downwards (conforming to the Intel definitions).  These stacks are
00006  * used, primarily, for ndk's memory management.
00007  *
00008  * Please see:
00009  *   /doc/memoryManagement.kwd
00010  *   /doc/memoryMap.kwd
00011  *   /src/pager.{c,h}
00012  *
00013  * (c)2002 dcipher / neuraldk
00014  *           www.neuraldk.org
00015  */
00016 
00017 #include "stack.h"
00018 
00019 // puts a new value onto the top of the stack, incrementing pointer
00020 void stackPush(Stack *stack, long data) {
00021   if(stack->flags & STACK_EXPAND_UP) {
00022     *(long *)(stack->base - (4*stack->pointer++)) = data;
00023   }
00024   else {
00025     *(long *)(stack->base + (4*stack->pointer++)) = data;
00026   }
00027 }
00028 
00029 // returns current value on top of stack, decrementing pointer
00030 long stackPop(Stack *stack) {
00031   if(stack->flags & STACK_EXPAND_UP) {
00032     return *(long *)(stack->base - (4*--stack->pointer));
00033   }
00034   else {
00035     return *(long *)(stack->base + (4*--stack->pointer));
00036   }
00037 }
00038 
00039 // return stack data without changing pointer
00040 long stackPeek(Stack *stack, long offset) {
00041   if(stack->flags & STACK_EXPAND_UP) {
00042     return *(long *)(stack->base - (4*offset));
00043   }
00044   else {
00045     return *(long *)(stack->base + (4*offset));
00046   }
00047 }
00048 
00049 // change data in stack without changing pointer
00050 void stackPoke(Stack *stack, long offset, long data) {
00051   if(stack->flags & STACK_EXPAND_UP) {
00052     *(long *)(stack->base - (4*offset)) = data;
00053   }
00054   else {
00055     *(long *)(stack->base + (4*offset)) = data;
00056   }
00057 }
00058 
00059 // remove a chunk of 'count' longs from anywhere withen the stack
00060 void stackRemove(Stack *stack, long offset, long count) {
00061   long src, dst, tot;
00062 
00063   debugEnter("stackRemove", "0x%8x, %d, %d", stack, offset, count);
00064 
00065   // error out, if trying to remove more than is available
00066   if(count >= stack->pointer) {
00067     consoleOut("stackRemove > stack->pointer\n");
00068     return;
00069   }
00070 
00071   // if we're removing the top-most item, just adjust the stack pointer,
00072   // no memcpy's needed
00073   if(offset == stack->pointer-1) {
00074     consoleOut("stackRemove, stack->pointer == 1\n");
00075     stack->pointer -= count;
00076     return;
00077   }
00078 
00079   // calculate starting/ended address, and total # bytes to move,
00080   // based on the type of stack
00081   if(stack->flags & STACK_EXPAND_UP) {
00082     src = stack->base - (4 * (stack->pointer - 1) );
00083     dst = src + (4 * count);
00084     tot = (stack->base - (4 * offset)) - src;
00085   } else {
00086     src = stack->base + (4 * (stack->pointer - 1) );
00087     dst = src - (4 * count);
00088     tot = src - (stack->base + (4 * offset));
00089   }
00090 
00091   // adjust the counter
00092   stack->pointer -= count;
00093 
00094   //consoleOut("Copying, dst (0x%8x), src (0x%8x), tot (%d)\n", dst, src, tot);
00095   // and perform the copy
00096   memcpy(dst, src, tot);
00097 
00098   debugLeave("stackRemove", 0, 0);
00099 }
00100 
00101 void stackDisplay(Stack *stack) {
00102   long i;
00103 
00104   for(i = 0; i < stack->pointer; i++) {
00105     consoleOut("%3d: 0x%8x\n", i, stackPeek(stack, i));
00106   }
00107 }
00108 
00109 // currently not used, and therefore not implemented...
00110 /*
00111 void stackInsert(Stack *stack, long offset, long *data, long count) {
00112 }
00113 */

Generated on Sun Nov 21 18:26:11 2004 for ndk by doxygen 1.3.2