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

Reply via email to