/* ********************************************************************************************************* * INITIALIZE A TASK'S STACK FOR FLOATING POINT EMULATION * * Description: This function MUST be called BEFORE calling either OSTaskCreate() or OSTaskCreateExt() in * order to initialize the task's stack to allow the task to use the Borland floating-point * emulation. The returned pointer MUST be used in the task creation call. * * Ex.: OS_STK TaskStk[1000]; * * * void main (void) * { * OS_STK *ptos; * OS_STK *pbos; * INT32U size; * * * OSInit(); * . * . * ptos = &TaskStk[999]; * pbos = &TaskStk[0]; * size = 1000; * OSTaskStkInit_FPE_x86(&ptos, &pbos, &size); * OSTaskCreate(Task, (void *)0, ptos, 10); * . * . * OSStart(); * } * * Arguments : pptos is the pointer to the task's top-of-stack pointer which would be passed to * OSTaskCreate() or OSTaskCreateExt(). * * ppbos is the pointer to the new bottom of stack pointer which would be passed to * OSTaskCreateExt(). * * psize is a pointer to the size of the stack (in number of stack elements). You * MUST allocate sufficient stack space to leave at least 384 bytes for the * floating-point emulation. * * Returns : The new size of the stack once memory is allocated to the floating-point emulation. * * Note(s) : 1) _SS is a Borland 'pseudoregister' and returns the contents of the Stack Segment (SS) * 2) The pointer to the top-of-stack (pptos) will be modified so that it points to the new * top-of-stack. * 3) The pointer to the bottom-of-stack (ppbos) will be modified so that it points to the new * bottom-of-stack. * 4) The new size of the stack is adjusted to reflect the fact that memory was reserved on * the stack for the floating-point emulation. ********************************************************************************************************* */ void OSTaskStkInit_FPE_x86 (OS_STK **pptos, OS_STK **ppbos, INT32U *psize) { INT32U lin_tos; /* 'Linear' version of top-of-stack address */ INT32U lin_bos; /* 'Linear' version of bottom-of-stack address */ INT16U seg; INT16U off; INT32U bytes; seg = FP_SEG(*pptos); /* Decompose top-of-stack pointer into seg:off */ off = FP_OFF(*pptos); lin_tos = ((INT32U)seg << 4) + (INT32U)off; /* Convert seg:off to linear address */ bytes = *psize * sizeof(OS_STK); /* Determine how many bytes for the stack */ lin_bos = (lin_tos - bytes + 15) & 0xFFFFFFF0L; /* Ensure paragraph alignment for BOS */ seg = (INT16U)(lin_bos >> 4); /* Get new 'normalized' segment */ *ppbos = (OS_STK *)MK_FP(seg, 0x0000); /* Create 'normalized' BOS pointer */ memcpy(*ppbos, MK_FP(_SS, 0), 384); /* Copy FP emulation memory to task's stack */ bytes = bytes - 16; /* Loose 16 bytes because of alignment */ *pptos = (OS_STK *)MK_FP(seg, (INT16U)bytes); /* Determine new top-of-stack */ *ppbos = (OS_STK *)MK_FP(seg, 384); /* Determine new bottom-of-stack */ bytes = bytes - 384; *psize = bytes / sizeof(OS_STK); /* Determine new stack size */ }