How do you grab memory dynamically in CP/M? - CP/M

This is a discussion on How do you grab memory dynamically in CP/M? - CP/M ; I am trying to add an "INCLUDED" word to the Z80 hForth for CP/M. Now INCLUDED nests, so the memory efficient way to handle that is to save the information from a FCB to be able to get back to ...

+ Reply to Thread
Results 1 to 18 of 18

Thread: How do you grab memory dynamically in CP/M?

  1. How do you grab memory dynamically in CP/M?

    I am trying to add an "INCLUDED" word to the Z80 hForth for CP/M. Now
    INCLUDED nests, so the memory efficient way to handle that is to save
    the information from a FCB to be able to get back to the next line
    from a file that has just executed a word to include another file.

    However, most straightforward is just to make a new FCB for the
    included file, letting it run until its done, and then releasing it.

    How is that normally done in CP/M? Do you just grab that kind of
    memory from the hardware stack?

    Unlike generic file I/O, this would be guaranteed to be nested.

  2. Re: How do you grab memory dynamically in CP/M?

    BruceMcF wrote:
    > I am trying to add an "INCLUDED" word to the Z80 hForth for CP/M. Now
    > INCLUDED nests, so the memory efficient way to handle that is to save
    > the information from a FCB to be able to get back to the next line
    > from a file that has just executed a word to include another file.
    >
    > However, most straightforward is just to make a new FCB for the
    > included file, letting it run until its done, and then releasing it.
    >
    > How is that normally done in CP/M? Do you just grab that kind of
    > memory from the hardware stack?
    >
    > Unlike generic file I/O, this would be guaranteed to be nested.


    Can you use a recursive function to read the line? (Following example in C).

    static char line[120]; /* Don't create for every new file */
    void ProcessFile(char *name)
    {
    FILE *fp = fopen(name, "r");
    while(fgets(line, sizeof(line) ,fp))
    {
    ...
    switch(Category(line))
    {
    case INCLUDE:
    ProcessFile(newname);
    break;
    ...
    }
    }
    }


  3. Re: How do you grab memory dynamically in CP/M?

    On Thu, 3 Apr 2008 22:23:44 -0700 (PDT), BruceMcF
    wrote:

    >I am trying to add an "INCLUDED" word to the Z80 hForth for CP/M. Now
    >INCLUDED nests, so the memory efficient way to handle that is to save
    >the information from a FCB to be able to get back to the next line
    >from a file that has just executed a word to include another file.
    >
    >However, most straightforward is just to make a new FCB for the
    >included file, letting it run until its done, and then releasing it.


    CP/M has no built in memory allocation scheme. It assumes a flat 64K
    and there are few areas that are reserved for CP/M it self and all
    other areas are fair game( can or may be over written).

    However if the current progam is maintaing dicipline in how the TPA is
    used then ayny scheme may be applied. If ther is memory management
    available (paging or banking) then the doors open a bit wider to
    create protected areas.

    >How is that normally done in CP/M? Do you just grab that kind of
    >memory from the hardware stack?


    No the stack is rarely that large and it's also potentially saved and
    restored by bios and other software.
    >
    >Unlike generic file I/O, this would be guaranteed to be nested.


    CP/M you have to be careful with file IO as it can be nested but
    it is not safely recursive. It's a matter of the system being single
    thread and not multitasking (unless MPM).

    Allison

  4. Re: How do you grab memory dynamically in CP/M?

    On Apr 4, 4:59 am, David R Brooks wrote:
    > Can you use a recursive function to read the line?


    That is what I am writing, a recursive function to open a file, fetch
    the characters in sequence from the file, then close it, where some of
    those characters may resolve to a command that calls the same
    function.

    I can use that function ... once I've written it.

  5. Re: How do you grab memory dynamically in CP/M?

    On Apr 4, 7:42 am, no.s...@no.uce.bellatlantic.net wrote:
    > CP/M has no built in memory allocation scheme. It assumes a flat 64K
    > and there are few areas that are reserved for CP/M it self and all
    > other areas are fair game( can or may be over written).


    > However if the current progam is maintaing dicipline in how the TPA is
    > used then ayny scheme may be applied. If ther is memory management
    > available (paging or banking) then the doors open a bit wider to
    > create protected areas.


    How do you find the end of the TPA? As far as I can see, hForth just
    loads and starts growing in memory, basically assuming that there is
    more there. Given that most TPA's will be in excess of 32K, and hForth
    would be perfectly happy with a TPA of 16K, its a pretty safe
    assumption, but how do I find the end of the TPA to start using RAM
    from that side?

    I don't need to create a protected area, I need to create a transitory
    area. I have the Forth dictionary being built from the bottom to the
    top:

    [ defined words ... HERE ... ]

    and I do not want to put the FCB and a block sector buffer in the
    dictionary because then that will give:

    [ defined words ... OLD-HERE FCB_0 ... FCB_n buff_0 ... buff_n
    HERE ... ]

    and if the application only needs INCLUDED and does not need the FILES
    wordset, then that is memory taken away from the application that was
    only needed to load the application definition file.

    So what I want to design INCLUDED to do is:

    [ ... HERE >>> ... <<< buff_0 ... buff_n FCB_0 ... FCB_n ]

    .... where the top part is managed like a software file-access-stack,
    with only a double variable in the codespace that points to the low
    memory end of the file-access-stack and the top end of the file-access-
    stack.

    So INCLUDED would just adjust the bottom of the file-access-stack down
    by the size of one FCB and one sector buffer, check that its above
    HERE, set the end of codespace so that the dictionary cannot overflow,
    starting feeding each character from each sector of the file in turn,
    close the file when finished, re-adjust the pointer to the file-access-
    stack up, if there is file-access data on the stack, pick up where it
    left off, if the file-access stack is empty, return control to the
    console.

    > >How is that normally done in CP/M? Do you just grab that kind of
    > >memory from the hardware stack?


    > No the stack is rarely that large and it's also potentially saved and
    > restored by bios and other software.


    > >Unlike generic file I/O, this would be guaranteed to be nested.


    > CP/M you have to be careful with file IO as it can be nested but
    > it is not safely recursive. It's a matter of the system being single
    > thread and not multitasking (unless MPM).


    Only the foreground task would be able to use INCLUDED, background
    tasks are restricted to using definitions that have already been
    defined. So the INCLUDED file could define and launch a background
    task, but that could not then execute INCLUDED.

    That requires a few changes to the source of the multi-tasker, but the
    multi-tasker is given in source (its one of the files that would be
    INCLUDED), so that's not a big hurdle.

  6. Re: How do you grab memory dynamically in CP/M?

    On Apr 4, 10:58*am, BruceMcF wrote:
    > On Apr 4, 7:42 am, no.s...@no.uce.bellatlantic.net wrote:
    >
    > > CP/M has no built in memory allocation scheme. *It assumes a flat 64K
    > > and there are few areas that are reserved for CP/M it self and all
    > > other areas are fair game( can or may be over written).
    > > However if the current progam is maintaing dicipline in how the TPA is
    > > used then ayny scheme may be applied. *If ther is memory management
    > > available (paging or banking) then the doors open a bit wider to
    > > create protected areas.

    >
    > How do you find the end of the TPA? As far as I can see, hForth just
    > loads and starts growing in memory, basically assuming that there is
    > more there. Given that most TPA's will be in excess of 32K, and hForth
    > would be perfectly happy with a TPA of 16K, its a pretty safe
    > assumption, but how do I find the end of the TPA to start using RAM
    > from that side?
    >

    Let's see, it's been awhile,
    jmp bdos, is jmp 0005h which holds another jmp instruction to the
    BDOS base, which, in the typical cp/m memory map, is the top of TPA
    +1+6. So location 0006h holds the address to TPA_top + 7, in that
    TPA_top +1 thru 6 is the bdos s/n number. The bdos is page aligned,
    nn00h, so the actual bdos entry is nn06h, nn00h..nn05H is the s/n, and
    the 'page' byte of TPA_top is nn-1, and last addressable of TPA is
    (nn-1)FFh. So, for an enviornment such as C, (nn-1)FFh could be the
    top of the Program Stack. The area between program code|data and
    program stack of stacksize is usually the Heap from which dynamic
    memory is allocated.

    Steve

    > I don't need to create a protected area, I need to create a transitory
    > area. I have the Forth dictionary being built from the bottom to the
    > top:
    >
    > [ defined words ... HERE ... ]
    >
    > and I do not want to put the FCB and a block sector buffer in the
    > dictionary because then that will give:
    >
    > [ defined words ... OLD-HERE FCB_0 ... FCB_n buff_0 ... buff_n
    > HERE ... ]
    >
    > and if the application only needs INCLUDED and does not need the FILES
    > wordset, then that is memory taken away from the application that was
    > only needed to load the application definition file.
    >
    > So what I want to design INCLUDED to do is:
    >
    > [ ... HERE >>> ... <<< buff_0 ... buff_n FCB_0 ... FCB_n ]
    >
    > ... where the top part is managed like a software file-access-stack,
    > with only a double variable in the codespace that points to the low
    > memory end of the file-access-stack and the top end of the file-access-
    > stack.
    >
    > So INCLUDED would just adjust the bottom of the file-access-stack down
    > by the size of one FCB and one sector buffer, check that its above
    > HERE, set the end of codespace so that the dictionary cannot overflow,
    > starting feeding each character from each sector of the file in turn,
    > close the file when finished, re-adjust the pointer to the file-access-
    > stack up, if there is file-access data on the stack, pick up where it
    > left off, if the file-access stack is empty, return control to the
    > console.
    >
    > > >How is that normally done in CP/M? Do you just grab that kind of
    > > >memory from the hardware stack?

    > > No the stack is rarely that large and it's also potentially saved and
    > > restored by bios and other software.
    > > >Unlike generic file I/O, this would be guaranteed to be nested.

    > > CP/M you have to be careful with file IO as it can be nested but
    > > it is not safely recursive. *It's a matter of the system being single
    > > thread and not multitasking (unless MPM).

    >
    > Only the foreground task would be able to use INCLUDED, background
    > tasks are restricted to using definitions that have already been
    > defined. So the INCLUDED file could define and launch a background
    > task, but that could not then execute INCLUDED.
    >
    > That requires a few changes to the source of the multi-tasker, but the
    > multi-tasker is given in source (its one of the files that would be
    > INCLUDED), so that's not a big hurdle.



  7. Re: How do you grab memory dynamically in CP/M?

    "BruceMcF" wrote in message
    news:81b30d4f-7f84-480a-ab00-3aa8a3cd8117@k13g2000hse.googlegroups.com...
    > How do you find the end of the TPA?


    I haven't been following this in detail, but I gather we're talking about
    CP/M-80 here. If so...

    Take the word (16 bits) stored at locations 0x0006 and subtract one.

    See page 6-26 at http://www.cpm.z80.de/manuals/cpm22-m.pdf reading the note
    about 0005H - 0007H.

    - Bill


  8. Re: How do you grab memory dynamically in CP/M?

    BruceMcF wrote:
    >

    .... snip ...
    >
    > How do you find the end of the TPA? As far as I can see, hForth
    > just loads and starts growing in memory, basically assuming that
    > there is more there. Given that most TPA's will be in excess of
    > 32K, and hForth would be perfectly happy with a TPA of 16K, its
    > a pretty safe assumption, but how do I find the end of the TPA
    > to start using RAM from that side?


    Address 5 contains a instruction. The operand of that
    instruction ends in '06' (hex) and the whole address is the lowest
    address of the BDOS module. The 6 bytes below it CAN (but usually
    don't) contain a serial number. Below that address is the CCP,
    which is not needed when running a program, and which is reloaded
    on a reboot.

    So that address, which can be found by loading the 16 bit value
    found at address 0006, gives the first address that must not be
    disturbed to preserve BDOS. You can use everything below it,
    bearing in mind the reserved usage for the area below 0100h.

    If you don't need the bdos during program run you can find the
    bottom of the bios via the pointer at address 0001. This is used
    in rebooting by a jump to 0.

    Things are different when such things as DDT or DDTZ are in use.
    Also system extensions.

    I recommend getting and reading the source code for a clone of
    CP/M. One that is available is DOSPLUS 2.5, both as binaries and
    as source, available at:



    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]:
    Try the download section.


    --
    Posted via a free Usenet account from http://www.teranews.com


  9. Re: How do you grab memory dynamically in CP/M?

    On Apr 4, 3:51 pm, "Bill Leary" wrote:
    > "BruceMcF" wrote in message
    >
    > news:81b30d4f-7f84-480a-ab00-3aa8a3cd8117@k13g2000hse.googlegroups.com...
    >
    > > How do you find the end of the TPA?

    >
    > I haven't been following this in detail, but I gather we're talking about
    > CP/M-80 here. If so...
    >
    > Take the word (16 bits) stored at locations 0x0006 and subtract one.
    >
    > See page 6-26 athttp://www.cpm.z80.de/manuals/cpm22-m.pdfreading the note
    > about 0005H - 0007H.
    >
    > - Bill


    Thanks, that's easy to do.

    : TPA ( -- &tpa ) 6 @ 1- ;

    .... and thanks for the link.

  10. Re: How do you grab memory dynamically in CP/M?

    On Apr 4, 6:33 pm, CBFalconer wrote:
    > I recommend getting and reading the source code for a clone of
    > CP/M. One that is available is DOSPLUS 2.5, both as binaries and
    > as source, available at:


    After looking at the Z-system that is running under the hood of MyZ80,
    and the ability to load temporary extensions below the CCP, and the
    ability to have "load high" environment-3 programs, I think I'll just
    set the top of RAM for the extended-hforth at $7FFF and leave $8000 on
    up to the system. After all, 20K codespace is ample for any minimalist
    Forth, leaving 31.75K - codespace for RAM allocated dynamically by
    hforthx.

    Then its just documentation ... "HFORTHX.COM requires a 31.75K TPA".

  11. Re: How do you grab memory dynamically in CP/M?

    On Apr 5, 11:09 am, BruceMcF wrote:
    > On Apr 4, 6:33 pm, CBFalconer wrote:
    >
    > > I recommend getting and reading the source code for a clone of
    > > CP/M. One that is available is DOSPLUS 2.5, both as binaries and
    > > as source, available at:

    >
    > After looking at the Z-system that is running under the hood of MyZ80,
    > and the ability to load temporary extensions below the CCP, and the
    > ability to have "load high" environment-3 programs, I think I'll just
    > set the top of RAM for the extended-hforth at $7FFF and leave $8000 on
    > up to the system. After all, 20K codespace is ample for any minimalist
    > Forth, leaving 31.75K - codespace for RAM allocated dynamically by
    > hforthx.


    > Then its just documentation ... "HFORTHX.COM requires a 31.75K TPA".


    On second thought, after saving the hforthx.com with the SEARCH-ORDER
    core and TOOLS core ``SEE DEBUG .S MARKER'' etc., and mostly without
    extensions, its already 16K. So make that a 40K TPA.

    I'm getting the impression that the most common target model for
    hForth in DOS is the EXE model.

  12. Re: How do you grab memory dynamically in CP/M?

    On Tue, 8 Apr 2008 11:36:34 -0700 (PDT), BruceMcF
    wrote:

    >On Apr 5, 11:09 am, BruceMcF wrote:
    >> On Apr 4, 6:33 pm, CBFalconer wrote:
    >>
    >> > I recommend getting and reading the source code for a clone of
    >> > CP/M. One that is available is DOSPLUS 2.5, both as binaries and
    >> > as source, available at:

    >>
    >> After looking at the Z-system that is running under the hood of MyZ80,
    >> and the ability to load temporary extensions below the CCP, and the
    >> ability to have "load high" environment-3 programs, I think I'll just
    >> set the top of RAM for the extended-hforth at $7FFF and leave $8000 on
    >> up to the system. After all, 20K codespace is ample for any minimalist
    >> Forth, leaving 31.75K - codespace for RAM allocated dynamically by
    >> hforthx.

    >
    >> Then its just documentation ... "HFORTHX.COM requires a 31.75K TPA".

    >
    >On second thought, after saving the hforthx.com with the SEARCH-ORDER
    >core and TOOLS core ``SEE DEBUG .S MARKER'' etc., and mostly without
    >extensions, its already 16K. So make that a 40K TPA.
    >
    >I'm getting the impression that the most common target model for
    >hForth in DOS is the EXE model.



    Here is a trick I've used to create CP/M protected space. Put what
    every code you want to be out of the TPA above the BIOS. That
    translates to building a CP/M system that is smaller by whatever space
    you want out of the TPA. In my Case I generally do 1/2/4K
    (0F[0,8,C]00->FFFFh) as reserved space and move wevery thing down that
    amount. A system with 4k reserved that way will generally have a TPA
    of 54-56K wich by CP/M standards is very good and if you have the BDOS
    resident that only takes 3.5K off that (50.5-52.5k). That would allow
    a fairly great amount of space and the location 6/7 data minus 6 will
    be the usual TPA space. Typical TPAs for decent systems is at least
    48K(0C000h).


    Allison

  13. Re: How do you grab memory dynamically in CP/M?

    On Apr 8, 6:25 pm, no.s...@no.uce.bellatlantic.net wrote:
    > Here is a trick I've used to create CP/M protected space.


    Thanks for that ... the information is filed for when I need it. This
    particular step doesn't need protected space ... I'm more concerned
    about protecting other things from this. But after looking around the
    conventional CP/M, I figure if a 40K TPA is on the low side, then
    it'll have the programs with larger TPA's running interference, as it
    were.

    Further, this is not hard to modify ... once its working,

    HEX C000 TO ram-end save# BYE

    .... will give, if there are 58 pages in codespace:

    HEX C000 TO ram-end save# BYE 56 ok

    then

    A2>save 56 hforthx.com

    .... and the new hforthx.com image will operate on the presumption of a
    48K TPA ...

    HEX 8000 TO ram-end

    .... and the image will assume it has a 32K TPA.

    What's great about CP/M was the only thing I to get a SAVE-SYSTEM
    function in a minimalist Forth was the little routine to print out the
    codespace size in pages, and that was adapted from Brad Rodriguez's
    instructions for getting the page parameter for the Z80 CamelForth.

    I've done a trial run in extending hForth by hand, entering the most
    essential functions ("words") from OPTIONAL.F by hand and
    incrementally saving hforth1.com, hforth2.com, etc. up to the the
    hforthx.com with the main debugging tools (DUMP SEE .S MARKER) ...

    .... that seems to be working. DUMP was an awfully long routine for
    Forth, with next to no factoring, and I bailed out the first time I
    was typing it in, but I was surprised to see that when I had a
    definition that compiled, it seemed to work perfectly.

    So I'll be working with that hForthx.com with the embedded debugging
    routines to develop the routines that can INCLUDE files, and then go
    back to the original hforth.com and built the capability into that.
    Then hforth.com will be able to load files from text source (including
    file based definitions of the stuff I hand-coded into hforthx.com),
    and I can move up to using VDE for working on hForth source within CP/
    M.

  14. Re: How do you grab memory dynamically in CP/M?

    /*
    Full K&R alloc() and free() for AZTEC C II

    This module adapted for the CP/M environment from source code in Brian
    W. Kernighan and Dennis M. Ritchie's "The C Programming Language" by
    William C. Colley III -- 4 OCT 1982.

    This module implements the functions alloc(), morecore(), sbrk(), and
    free() as per pp. 173-7 of Kernighan and Ritchie. Since sbrk() is
    responsible for preventing collision between the allocated data and
    the stack, it must know how much space to leave for the stack. Thus,
    a function rsvstk() is provided to override the default 1024 bytes.

    The functions in this package are:

    char *alloc(nb) Allocates a block of nb bytes and
    unsigned nb; returns a pointer to it. If no such
    block is available, the value NULL (0)
    is returned.

    free(blk) Attaches the storage allocation block
    char *blk; blk to the free list. Returns no
    meaningful value.

    HEADER *morecore(nb) Gets a storage allocation block of
    unsigned nb; size nb from the heap and returns a
    pointer to it. Returns NULL (0) if
    not enough space is available.

    char *sbrk(nb) Gets nb bytes from the heap. Returns
    unsigned nb; a pointer to the bytes or -1 if not
    enough bytes are available.

    char *settop(nb) Gets nb bytes from the heap. Returns
    unsigned nb; a pointer to the bytes or NULL (0) if
    not enough bytes are available.

    rsvstk(stk) Changes the minimum allowable remaining
    unsigned stk; stack size at a call to sbrk() to stk
    bytes. Default value is 1024 bytes.
    */

    #define NULL 0

    union header {
    struct {
    union header *ptr;
    unsigned size;
    } s;
    long l;
    };

    typedef union header HEADER;

    static HEADER base, *allocp = NULL;

    char *alloc(nb)
    unsigned nb;
    {
    HEADER *morecore();
    register HEADER *p, *q;
    register unsigned nu;

    nu = ((nb + 3) >> 2) + 1;
    if ((q = allocp) == NULL) {
    base.s.ptr = allocp = q = &base;
    base.s.size = 1;
    }
    for (p = q->s.ptr; ; q = p, p = p->s.ptr) {
    if (p->s.size >= nu) {
    if (p->s.size == nu) q->s.ptr = p->s.ptr;
    else {
    p->s.size -= nu;
    p += p->s.size;
    p->s.size = nu;
    }
    allocp = q; return (char *)(p + 1);
    }
    if (p == allocp)
    if ((p = morecore(nu)) == NULL) return NULL;
    }
    }

    HEADER *morecore(nu)
    unsigned nu;
    {
    char *sbrk();
    register char *cp;
    register HEADER *up;

    if ((int)(cp = sbrk(nu << 2)) == -1) return NULL;
    up = (HEADER *)cp;
    up->s.size = nu;
    free((char *)(up + 1));
    return allocp;
    }

    free(blk)
    char *blk;
    {
    register HEADER *p, *q;

    p = (HEADER *)blk - 1;
    for (q = allocp; !(p > q && p < q->s.ptr); q = q->s.ptr)
    if (q >= q ->s.ptr && (p > q || p < q->s.ptr)) break;

    if (p + p->s.size == q->s.ptr) {
    p->s.size += q->s.ptr->s.size;
    p->s.ptr = q->s.ptr->s.ptr;
    }
    else p->s.ptr = q->s.ptr;
    if (q + q->s.size == p) {
    q->s.size += p->s.size;
    q->s.ptr = p->s.ptr;
    }
    else q->s.ptr = p;
    allocp = q;
    }

    /* The functions sbrk(), settop(), and rsvstk() live in the module
    sbrk.mac
    as they have to beat on machine things like the stack pointer. */
    x--- snip ---x

    ;
    ; Rest of Full K&R alloc() and free() for AZTEC C II
    ;
    ; This module copyright (c) 1982 William C. Colley III
    ;
    ; I grant Manx Software Systems permission to incorporate these
    functions
    ; into the AZTEC C library subject only to the condition that my
    copyright
    ; notice remain in the source code. WCC3.
    ;
    ; See the module ALLOC.C for documentation. To use this module, you
    must
    ; modify the AZTEC module CALLCPM.ASM by removing the definition of
    the
    ; location $MEMRY. You also will save code if you remove their
    function
    ; settop()/sbrk() as two of these functions will replace it.
    ;
    PUBLIC settop_, sbrk_, rsvstk_, $MEMRY

    CSEG

    ;************************************************* *****************************

    settop_: LXI H, 4 ;Fudge up a call to sbrk() to allocate
    CALL sbrk1 ; the space.

    INX H ;If sbrk() returned -1, set the Z flag
    MOV A, H ; and return 0 as space was not
    ORA L ; available.
    RZ

    DCX H ;If space was available, return a
    RET ; pointer to the space. Note that
    ; Z flag is cleared at this point.

    sbrk_: LXI H, 2 ;Get size of block to allocate and
    sbrk1: DAD SP ; compute end address of prospective
    MOV E, M ; block.
    INX H
    MOV D, M
    LHLD $MEMRY
    DAD D
    XCHG

    JC sbrk2 ;If block wraps around top of memory,
    ; not enough space available.

    LHLD safety ;Compute stack pointer less safety
    DAD SP ; margin -- i.e. top of memory.

    MOV A, L ;If end address > top of memory,
    SUB E ; not enough space available.
    MOV A, H
    SBB D
    JC sbrk2

    LHLD $MEMRY ;If space is available, allocate
    XCHG ; the space, set Z flag on pointer,
    SHLD $MEMRY ; and return pointer to space.
    XCHG
    MOV A, H
    ORA L
    RET

    sbrk2: XRA A ;If not enough space, clear the Z flag
    DCR A ; and send back -1.
    MOV H, A
    MOV L, A
    RET

    ;************************************************* *****************************

    rsvstk_: LXI H, 2 ;Get new stack safety margin.
    DAD SP
    MOV A, M
    INX H
    MOV H, M

    CMA ;Negate and save it.
    MOV L, A
    MOV A, H
    CMA
    MOV H, A
    INX H
    SHLD safety

    RET ;Return nothing in particular.

    ;************************************************* *****************************

    DSEG

    $MEMRY: DW 0 ;Let linker put end of externals here.
    safety: DW -1024 ;Default value of safety margin.

    END

  15. Re: How do you grab memory dynamically in CP/M?

    On Apr 9, 7:06 am, Bill Buckels wrote:

    .... a bunch of C routines ...

    hForth is Forth. If I implement ALLOCATE and FREE for hForth it will
    be:
    (1) in Forth and
    (2) much smaller than that

    There is already a Forth-94 wordset that defines a dataspace buffer in
    the dictionary and the heap memory wordset to work with it, so if I
    decide to do it, its not like I have to write the whole system from
    scratch.

    The only question is whether I decide to do it, since the FCB and file
    sector buffers for INCLUDE are so well suited to a pure (software)
    stack.

  16. Re: How do you grab memory dynamically in CP/M?

    I just put the CP/M hforth that I expanded on the console to include a
    selection of the OPTIONAL.F words here:

    http://groups.google.com/group/niclo...le-development


  17. Re: How do you grab memory dynamically in CP/M?

    On Apr 4, 1:29 pm, s_dubrov...@yahoo.com wrote:
    > Let's see, it's been awhile,
    > jmp bdos, is jmp 0005h which holds another jmp instruction to the
    > BDOS base, which, in the typical cp/m memory map, is the top of TPA
    > +1+6. So location 0006h holds the address to TPA_top + 7, in that
    > TPA_top +1 thru 6 is the bdos s/n number. The bdos is page aligned,
    > nn00h, so the actual bdos entry is nn06h, nn00h..nn05H is the s/n, and
    > the 'page' byte of TPA_top is nn-1, and last addressable of TPA is
    > (nn-1)FFh. So, for an enviornment such as C, (nn-1)FFh could be the
    > top of the Program Stack. The area between program code|data and
    > program stack of stacksize is usually the Heap from which dynamic
    > memory is allocated.
    >
    > Steve


    Thanks, this is what it turns out I needed to understand what CP/M
    hForth was doing.

    What I thought was an issue is no an issue after all, hForth grabs the
    top of the TPA for its text input buffer and PAD at the start, so I
    just say:

    ``PAD cell-''

    and I am in the free RAM I was looking for.

    After my rummaging around to figure it out, I've decided to just go
    ahead and define an ALLOCATE FREE and RESIZE that use that memory, and
    then use those functions for the INCLUDED routine. That will give more
    leverage to someone trying to bootstrap something up in hForth for CP/
    M.

    All of this hopefully finished in time, for when I have the funds in
    hand for either a C128 or PX-8, or preferably both.

  18. CP/M hforthm.cpm uploaded (Was Re: How do you grab memory dynamicallyin CP/M?)

    On Apr 4, 1:23 am, BruceMcF wrote:
    > I am trying to add an "INCLUDED" word to the Z80 hForth for CP/M. Now
    > INCLUDED nests, so the memory efficient way to handle that is to save
    > the information from a FCB to be able to get back to the next line
    > from a file that has just executed a word to include another file.
    >
    > However, most straightforward is just to make a new FCB for the
    > included file, letting it run until its done, and then releasing it.
    >
    > How is that normally done in CP/M? Do you just grab that kind of
    > memory from the hardware stack?
    >
    > Unlike generic file I/O, this would be guaranteed to be nested.


    The google group page ...

    http://groups.google.com/group/niclo...le-development

    .... has some details on hforthm.cpm which is a CP/M .COM file
    containing CP/M hForth, extended to include the programming tools
    wordset and memory allocation wordset.

    The ALLOCATE and FREE are very simple-minded, since there's no need to
    be sophisticated to support INCLUDED.

    It goes without saying ... therefore probably ought to be said ...
    rename hforthm.cpm to hforthm.com ... Google Groups as such is happy
    to host files, but not .COM files.

+ Reply to Thread