I'm extending SuperForth -- the first version of the library is already
online, http://programandala.net/en.program.sfera.html, also on GitHub.
Unfortunately, the old Forth-83 Standard imposed a 64 KiB memory space
and 16-bit cells, what doesn't make sense for QL, so SuperForth uses
special words to access the QL memory outside its own 64 KiB. But it
lacks words to allocate memory from the common heap, so I'm implementing
it.
I extracted the relevant code from Mark Knight's SystemKit/KnightKit
(1994, 1995, public domain), and adapted it. All the S*BASIC stuff
(parameters passing and checking) is unnecessary:
----
include 'inc_macros_asm'
include 'inc_labels_asm'
code 'aallocate',aallocate_end ; ( d -- da ior )
movem.l a0-a3/d2,-(sp) ; save the SuperForth registers
pop_l d1 ; get the required space
addq.l #4,d1 ; add 4 to number of bytes, for marker
move.l #-1,d2 ; this job will own the memory
moveq #mt_alchp,d0 ; select mt.alchp, grab some heap memory
trap #1 ; call it to reserve the memory
tst.l d0 ; was there an error?
bmi.s aallocate_error ; if yes, error
move.l #'grab',(a0) ; put marker in the area reserved.
adda.l #4,a0 ; add 4 to base, avoid overwriting marker
move.l a0,d1
movem.l (sp)+,a0-a3/d2 ; restore the SuperForth registers
push_l d1 ; push the address
moveq #0,d0 ; signal no error
push_w d0 ; push the ior code
next
aallocate_error
; d0 = ior
movem.l (sp)+,a0-a3/d2 ; restore the SuperForth registers
push_w d0 ; push the ior code
next
aallocate_end equ *
----
At the moment I prefer to to duplicate code at both possible exit
points, for speed. Besides, I will remove the "grab" marker, which is
used as an address check before releasing the space, because a Forth
programmer is supposed to know what he's doing anyway :)
But I've seen a similar code by Simon N. Goodwin, in his DIY TK (volume
H, file "memory_asm", keyword `reserve`), where he stores the marker
this way:
----
moveq #24,d0 MT.ALCHP
trap #1 Allocate RAM
tst.l d0
bmi.s return_fp Return error code
move.l #'Bufa',-4(a0) Identify this block
----
This uses the long word below the address of the free space, just
returned by the trap. My doubt is: Why is that lower space supposed to
be free? It may belong to a previous allocated space, or to a node of
the heap structure. Am I missing something? Is there a "safe gap"
between allocated spaces? So far I've not found this information in the
low-level documentation I have. Norman Dumbar includes similar code in
his Programming Series, but of course without the checking marker.
--
Marcos Cruz
http://programandala.net
_______________________________________________
QL-Users Mailing List