79 lines
2.2 KiB
Tal
79 lines
2.2 KiB
Tal
|
( alloc.tal )
|
||
|
( )
|
||
|
( simple arena allocator )
|
||
|
( )
|
||
|
( the idea here is to pre-allocate a large arena of memory )
|
||
|
( and then keep a pointer to the first unallocated byte. )
|
||
|
( memory is released in reverse order of when it was allocated. )
|
||
|
( )
|
||
|
( in this example we're preallocating 16,384 bytes (#4000) )
|
||
|
( located at mem-arena. we're using mem-cursor to point to )
|
||
|
( the next unallocated byte. )
|
||
|
( )
|
||
|
( if mem-cursor ever contains the address of mem-cursor it )
|
||
|
( means we've reached the limit of what we can allocate. )
|
||
|
( we raise divide-by-zero errors if we cannot allocate )
|
||
|
( or release memory as requested. )
|
||
|
( )
|
||
|
( memory can be freed by size (number of bytes) or cleared )
|
||
|
( all at once. )
|
||
|
|
||
|
( macro to allocate one byte of memory )
|
||
|
%mem-alloc-byte { #0001 ;mem-alloc JMP2r } ( -> addr* )
|
||
|
|
||
|
( macro to allocate two bytes of memory )
|
||
|
%mem-alloc-short { #0002 ;mem-alloc JMP2r } ( -> addr* )
|
||
|
|
||
|
( macro to allocate an 8-bit count of memory (n) )
|
||
|
%mem-alloc8 { #00 SWP ;mem-alloc JMP2r } ( n^ -> addr* )
|
||
|
|
||
|
( macro to allocate a 16-bit count of memory (n) )
|
||
|
%mem-alloc16 { ;mem-alloc JMP2r } ( n* -> addr* )
|
||
|
|
||
|
|10 @Console [ &vector $2 &read $1 &pad $5 &write $1 ]
|
||
|
|
||
|
|0100
|
||
|
;mem-init JSR2
|
||
|
;on-input .Console/vector DEO2
|
||
|
;mem-cursor LDA2 ;start STA2
|
||
|
BRK
|
||
|
|
||
|
@start $2
|
||
|
|
||
|
@on-input
|
||
|
.Console/read DEI DUP ,&continue JCN
|
||
|
( ;on-complete JSR2 ) POP BRK
|
||
|
&continue ( mem-alloc-byte STA ) BRK
|
||
|
|
||
|
@on-complete
|
||
|
;mem-cursor LDA2 STH2
|
||
|
;start LDA2
|
||
|
&loop
|
||
|
DUP2 STH2kr LTH2 ,&continue JCN
|
||
|
;mem-init JSR2 POP2 POP2r JMP2r
|
||
|
&continue
|
||
|
LDA2k .Console/write DEO
|
||
|
INC2 ,&loop JMP
|
||
|
|
||
|
( allocate n bytes of memory )
|
||
|
@mem-alloc ( n* -> addr* )
|
||
|
;mem-cursor LDA2 ADD2 DUP2 ( new-addr new-addr )
|
||
|
;mem-cursor LTH2 ,&ok JCN DIV2 #0000 ( fail if we reach mem-cursor's own address )
|
||
|
&ok DUP2 ;mem-cursor STA2 JMP2r
|
||
|
|
||
|
( initialize memory, release all allocated memory )
|
||
|
@mem-init ( -> )
|
||
|
;mem-arena ;mem-cursor STA2 JMP2r
|
||
|
|
||
|
( release n bytes of allocated memory )
|
||
|
@mem-release ( n* -> )
|
||
|
;mem-cursor LDA2 SUB2 DUP2 ( new-addr new-addr )
|
||
|
;mem-arena LTH2 ,&fail JCN ;mem-cursor STA2 JMP2r
|
||
|
&fail DIV2 #0000 ( fail if we reach beyond mem-arena's own address )
|
||
|
|
||
|
( location of the memory to be allocated )
|
||
|
@mem-arena $4000
|
||
|
|
||
|
( pointer to the next free byte, if any )
|
||
|
@mem-cursor $2
|