Memory Allocation

license
ANS 6.1.1650 HERE

( -- addr )

addr is the data-space pointer.

A system guarantees that a region of data space allocated using ALLOT, , (comma) , C, (c-comma), and ALIGN shall be contiguous with the last region allocated with one of the above words, unless the restrictions in the following paragraphs apply. The data-space pointer HERE always identifies the beginning of the next data-space region to be allocated. As successive allocations are made, the data-space pointer increases. A program may perform address arithmetic within contiguously allocated regions. The last region of data space allocated using the above operators may be released by allocating a corresponding negatively-sized region using ALLOT, subject to the restrictions of the following paragraphs.

CREATE establishes the beginning of a contiguous region of data space, whose starting address is returned by the CREATEd definition. This region is terminated by compiling the next definition.

Since an implementation is free to allocate data space for use by code, the above operators need not produce contiguous regions of data space if definitions are added to or removed from the dictionary between allocations. An ambiguous condition exists if deallocated memory contains definitions.

The data space of a Forth system comes in discontinuous regions! The location of some regions is provided by the system, some by the program. Data space is contiguous within regions, allowing address arithmetic to generate valid addresses only within a single region. A Standard Program cannot make any assumptions about the relative placement of multiple regions in memory.

Section 3.3.3.2 does prescribe conditions under which contiguous regions of data space may be obtained. For example:

 
        CREATE TABLE   1 C, 2 C, ALIGN 1000 , 2000 ,
 

makes a table whose address is returned by TABLE. In accessing this table,

 
TABLE C@                        will return 1
TABLE CHAR+ C@                  will return 2
TABLE 2 CHARS + ALIGNED @       will return 1000
TABLE 2 CHARS + ALIGNED CELL+ @ will return 2000.

Similarly,

 
        CREATE DATA   1000 ALLOT
 

makes an array 1000 address units in size. A more portable strategy would define the array in application units, such as:

 
        500 CONSTANT NCELLS
        CREATE CELL-DATA  NCELLS CELLS ALLOT
 

This array can be indexed like this:

 
        : LOOK   NCELLS 0 DO  CELL-DATA I CELLS + ? LOOP ;
 

COLDFORTH MEMORY AREAS There are four data spaces. The dictionary space, ram space, dual port memory and the fast space. The dictionary space is intended to be used for code, and the ram space for variables. The area of the dictionary remembered is checksummed on restart and it is considered an error if checksumming fails. The dictionary space can be written to by a program but it is unwise, the dictionary has to be stable while it is being written to flash as an application. The dictionary is checksumed and written to flash with interrupts enabled. The variable space is reset to zero on a restart. The fast space is not reset and may be used to retain values between restarts. The dual port space is reset and resetup.

 
To allocate 10 bytes of dictionary space you use the pair:
	CREATE 10 ALLOT 
This area may be written to at comple time but not there after.

To allocate ram_variable space
	ram_create 10 ram_allot

To allocate fast memory:
	fast_create 10 fast_allot
 
 
    : HERE   ( --addr) _'h> @ @ ;
	 
6.2.2395 UNUSED

CORE EXT

( -- u )

u is the amount of space remaining in the region addressed by HERE , in address units.

 
	: UNUSED ( --n)
		_'h_top> @ @ _'h> @ @ -
	;

	
	: ?org  ( n --flag)		
		DUP _'h> @ !
		_'h_top> @ @ > 
	;

	: org  ( n -- )
		?org  ABORT" Dictionary full" 
	; 
	 
6.1.0710 ALLOT

CORE

( n -- )

If n is greater than zero, reserve n address units of data space. If n is less than zero, release |n| address units of data space. If n is zero, leave the data-space pointer unchanged.

If the data-space pointer is aligned and n is a multiple of the size of a cell when ALLOT begins execution, it will remain aligned when ALLOT finishes execution.

If the data-space pointer is character aligned and n is a multiple of the size of a character when ALLOT begins execution, it will remain character aligned when ALLOT finishes execution.

    
	: ALLOT  ( +n --)
		HERE + org 
	;
	 
6.1.0705 ALIGN

CORE

( -- )

If the data-space pointer is not aligned, reserve enough space to align it.

 
	: ALIGN HERE ALIGNED org ;
	 

The ram area.

  
    : ram_here  ( --addr) 'ram @ ;
	: ?ram_allot  ( n --flag)		
		'ram @ +
		ALIGNED
		DUP 'ram !
		_'ram_top @ >  ;
    : ram_allot  ( n --)
		?ram_allot ABORT" Memeory area full"  ;   

The coldfire cache does a line read when fetching any data. If your pushing it you arrange things so that reads gets things you want. To that end you have to be able to align data areas on a cache line boundary.


	: ram_line_align
		'ram @
		16aligned
		'ram !
	;
 

code and : words have no cfa

   
	: _recover_cfa 
		[ _#head_cfa _#head_pfa - ]T LITERAL ALLOT ;
	 
6.1.0150 ,

comma CORE

( x -- )

Reserve one cell of data space and store x in the cell. If the data-space pointer is aligned when , begins execution, it will remain aligned when , finishes execution. An ambiguous condition exists if the data-space pointer is not aligned prior to execution of ,.

The use of , (comma) for compiling execution tokens does not work.

 
	: , ( x--)  
    	four ALLOT HERE cell- !  
    ;
	 
6.1.0860 C,

c-comma CORE

( char -- )

Reserve space for one character in the data space and store char in the space. If the data-space pointer is character aligned when C, begins execution, it will remain character aligned when C, finishes execution. An ambiguous condition exists if the data-space pointer is not character-aligned prior to execution of C,.

  
    : C, ( char --)   
    	HERE C! one _'h> @ +! 
    ;
     
 
    : W, ( 32b--)
		HERE W! two _'h> @ +!  
    ;
	 

fast memory

 
	: fast_here ( --addr) 'fast @ ;

	: ?fast_allot ( n --true)
		'fast @ + 4aligned  DUP 'fast !
		_'fast_top @ >
	;
    
	: fast_allot ( num --)
		?fast_allot ABORT" High speed memory area full" ;
     

dual port memory

 
	: port_here ( --addr) 'port @ ;

	: ?port_allot ( n --true)
		'port @ + ALIGNED  DUP 'port !
		_'port_top @ >
	;
    
	: port_allot ( num --)
		?port_allot ABORT" RTI1000 dual port memory area full"
	;
     

static memeory

 
#BVP5502 #BVP5501 + #BVP5552 + #BVP5551 + [IF]
     

static memory

 
	: static_here ( --addr) 'static @ ;


	\ align satic memory to a cache line
	: static_line_align  ( --)
		'static @ 16aligned 'static !
	;
	
	: ?static_allot ( n --true)
		'static @ + ALIGNED  DUP 'static !
		_'static_top @ >
	;
    
	: static_allot ( num --)
		?static_allot ABORT" Synch static memory area full"
	;

     

bank memory

 

	: bank_here ( --addr) 'bank @ ;

	: ?bank_allot ( n --true)
		'bank @ + ALIGNED  DUP 'bank !
		_'bank_top @ >
	;
    
	: bank_allot ( num --)
		?bank_allot ABORT" Bank memory area full"
	;

[THEN]
     
link_here ( head --)

Link here into a single lnked list.

 
	:  link_here ( head --)
		DUP @       \ head link (--
		HERE ROT ! \ link (--
		 ,
	;