📄 liballoc.a
字号:
****************************************************************************** * FREXX PROGRAMMING LANGUAGE * ****************************************************************************** * liballoc.a * Stack allocation/checking/expanding routines. * Authors: Kjell Ericson and Daniel Stenberg ****************************************************************************** ************************************************************************ * * * fpl.library - A shared library interpreting script langauge. * * Copyright (C) 1992-1994 FrexxWare * * Author: Daniel Stenberg * * * * This program is free software; you may redistribute for non * * commercial purposes only. Commercial programs must have a written * * permission from the author to use FPL. FPL is *NOT* public domain! * * Any provided source code is only for reference and for assurance * * that users should be able to compile FPL on any operating system * * he/she wants to use it in! * * * * You may not change, resource, patch files or in any way reverse * * engineer anything in the FPL package. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * * * Daniel Stenberg * * Ankdammsgatan 36, 4tr * * S-171 43 Solna * * Sweden * * * * FidoNet 2:201/328 email:dast@sth.frontec.se * * * ************************************************************************ ; LibAlloc.a ; ; Allocate and expands the stack at need. a6 is always the FPLBase ; pointer when any of these routine are called! CSECT LibAlloc xdef _GetStackUsed ; long GetStackUsed(struct Data *); xdef _InitStack ; void InitStack(struct Data *) xdef _CheckStack ; long OK= CheckStack(struct Data *, ; long maxstack, ; long minstack); xdef _InterfaceCall ; long InterfaceCall(struct Data *, ; void **); ; func pointer); xdef _InterfaceCallNoStack ; long InterfaceCallNoStack( ; struct Data *, ; void **); ; func pointer); xdef _StoreRegisters ; void StoreRegisters(stuct Data *); xref _Script ; call this function! xref _Malloc ; malloc routine xref _Free ; free routine IFD LOCKFUNTIONS_WANTED xdef _Locker ; void Locker(long *data, char bit); xdef _Unlocker ; void Unlocker(long *data, char bit); ENDC include "exec/memory.i" include "exec/tasks.i" include "liballoc.i"asALLOCSTACK equ 5000 ; Number of bytes added to current size when reallocingasINITCOPY equ 100 ; Amout of memory copied from stack (even 4)MALLOC_STATIC equ 1 ; Static allocation type specifier_InitStack: ; struct Data * in A2 ; struct Expr * in A3 ; short control in D2 ; struct Condition * in A1 move.l sp,DATA_EXT_STACK(a2) ; store external stack pointer move.l DATA_INT_STACK(a2),sp ; internal stack pointer in A0 move.l DATA_TASK(a2),a0 ; get task pointer in A0 move.l TC_SPUPPER(a0),DATA_OLDTOP(a2) ; upper move.l TC_SPLOWER(a0),DATA_OLDBOT(a2) ; lower move.l DATA_STACKBASE(a2),d0 ; get stack base in D0 add.l DATA_STACKSIZE(a2),d0 ; add stack size move.l d0,TC_SPUPPER(a0) ; set new stack upper bound move.l DATA_STACKBASE(a2),TC_SPLOWER(a0) ; set new stack lower bound bsr _Script ; don't mess with D0!! move.l DATA_TASK(a2),a0 ; get task pointer in A0 move.l TC_SPLOWER(a0),DATA_STACKBASE(a2) ; get new stack lower bound move.l DATA_OLDBOT(a2),TC_SPLOWER(a0) ; set lower bounds move.l DATA_OLDTOP(a2),TC_SPUPPER(a0) ; set upper bounds move.l sp,DATA_INT_STACK(a2) ; store internal stack pointer move.l DATA_EXT_STACK(a2),sp ; external stack pointer rts_GetStackUsed: ;(struct Data * - A0) move.l a1,-(sp) ; backup A1 move.l DATA_STACKBASE(a0),a1 ; stack base address move.l sp,d0 ; get stack pointer to d0 sub.l a1,d0 ; subtract stack base pointer move.l (sp)+,a1 ; restore A1 rts_CheckStack: ;(struct Data * - A3; stack limit - D2 ; stack margin - D3) movem.l d1/a0/a1/a2,-(sp) ; [PUSH] move.l DATA_STACKBASE(a3),a0 ; stack base address in A0 move.l sp,d0 ; stack pointer in D0 sub.l a0,d0 ; subtract stack base cmp.l d3,d0 ; stack usage larger than margin? bpl csend ; no? return! move.l DATA_STACKSIZE(a3),d0 ; current stack size to D0 add.l d3,d0 ; add margin size to stack size cmp.l d0,d2 ; Compare with the stack limit bmi csend3 ; reached stack limit, fail! movem.l d0/a0,-(sp) ; size in D0 [PUSH] move.b #MALLOC_STATIC,d1 ; type move.l a3,a0 ; struct Data * IFD DEBUG lea.l sourcename,a1 clr.l d2 ENDC jsr _Malloc ; get memory movem.l (sp)+,d1/a0 : [POP] size is now in D1 tst.l d0 ; Did we get memory? beq.s csend2 ; no memory, fail! move.l d0,a2 ; memory pointer (stack base) in A2 move.l d1,DATA_STACKSIZE(a3) ; store size in Data struct! move.l d1,d0 ; get new size in D0 sub.l d3,d0 ; subtract the addition to get old movem.l a2/a3,-(sp) ; [PUSH] move.l a0,a1 ; old stack base to A1 sub.l d0,a2 ; subtract old size from new base add.l d1,a2 ; add new size to new base ; old size is in D0 sub.l #4,d0 ; count down four bytes nowcslo1: move.l (a1)+,(a2)+ ; move sub.l #4,d0 bpl.s cslo1 ; while positive, loop! movem.l (sp)+,a2/a3 ; [POP] move.l sp,a1 ; stack pointer to A1 sub.l a0,a1 ; subtract old stack base add.l a2,a1 ; add new stack base add.l d3,a1 ; add margin size; add.l #asALLOCSTACK,a1 ; add stack realloc size move.l a1,sp ; SET NEW STACK POINTER!!! move.l DATA_TASK(a3),a1 ; get task pointer in A1 move.l a2,d0 ; get stack base in D0 add.l DATA_STACKSIZE(a3),d0 ; add stack size move.l d0,TC_SPUPPER(a1) ; set new stack upper bound move.l a2,TC_SPLOWER(a1) ; set new stack lower bound ; Deallocate old stack movem.l a2/a3,-(sp) ; [PUSH] move.l a0,a1 ; memory pointer to A1 move.l a3,a0 ; struct Data * to A0 move.b #MALLOC_STATIC,d0 ; type to D0 jsr _Free movem.l (sp)+,a2/a3 ; [POP] move.l a2,DATA_STACKBASE(a3) ; Store the new valuecsend: ; OK moveq.l #0,d0 movem.l (sp)+,d1/a0/a1/a2 ; [POP] rtscsend2: ; OUT OF MEM moveq.l #1,d0 movem.l (sp)+,d1/a0/a1/a2 ; [POP] rtscsend3: ; MAX STACK REACHED moveq.l #2,d0 movem.l (sp)+,d1/a0/a1/a2 ; [POP] rts_InterfaceCall: ; struct Data * in A1 ; void * in A0 ; function pointer in A2 movem.l d2-d7/a1/a3-a6,-(sp) ; store registers move.l DATA_TASK(a1),a3 move.l DATA_OLDTOP(a1),TC_SPUPPER(a3) ; upper move.l DATA_OLDBOT(a1),TC_SPLOWER(a3) ; lower move.l sp,DATA_INT_STACK(a1) ; set internal pointer move.l DATA_EXT_STACK(a1),sp ; set external pointer lea DATA_REGISTERSTORAGE(a1),a3 ; get register buffer move.l a1,-(sp) ; store struct Data * movem.l (a3),d2-d7/a3-a6 ; get registers from buffer jsr (a2) ; call interface function ; DON'T MESS WITH D0!!! move.l (sp)+,a1 ; get struct Data * in A1 move.l sp,DATA_EXT_STACK(a1) move.l DATA_INT_STACK(a1),sp move.l DATA_TASK(a1),a2 move.l TC_SPUPPER(a2),DATA_OLDTOP(a1) ; upper move.l TC_SPLOWER(a2),DATA_OLDBOT(a1) ; lower move.l DATA_STACKBASE(a1),d1 ; get stack base in D1 move.l d1,TC_SPLOWER(a2) ; set new stack lower bound add.l DATA_STACKSIZE(a1),d1 ; add stack size move.l d1,TC_SPUPPER(a2) ; set new stack upper bound movem.l (sp)+,d2-d7/a1/a3-a6 ; restore old registers rts_InterfaceCallNoStack: ; struct Data * in A1 ; void * in A0 ; function pointer in A2 movem.l d2-d7/a1/a3-a6,-(sp) ; store registers lea DATA_REGISTERSTORAGE(a1),a3 ; get register buffer movem.l (a3),d2-d7/a3-a6 ; get registers from buffer jsr (a2) ; call interface function ; DON'T MESS WITH D0!!! movem.l (sp)+,d2-d7/a1/a3-a6 ; restore old registers rts_StoreRegisters: ; struct Data * in A0 lea DATA_REGISTERSTORAGE(a0),a0 ; get register buffer address movem.l d2-d7/a3-a6,(a0) ; store registers in buffer rts IFD DEBUGsourcename: dc.b 'liballoc.a' ENDC IFD LOCKFUNCTIONS_WANTED_Locker: ; long *data in A0 ; char bit in D0 bset d0,(a0) bne.s _Locker rts_Unlocker: ; long *data in A0 ; char bit in D0 bclr d0,(a0) rts ENDC END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -