code	segment word public
assume	cs:code
include errno.inc

; Memory control block structure:
;
; offs  type  description
; ----  ----  ----------------------
;  0    byte  signature "R"
;  1    byte  status - "F" free  "A" allocated
;  2    word  size of block in bytes
;  4    word  pointer: previous MCB (0=first block)
;  6    word  pointer: forward MCB (0=last block)
;  8

extrn _startofdynamic:near
extrn errno:word

public _tinymeminit
_tinymeminit:
; initalise memory in TINY model (code + data + stack in same segment).
; this function takes the requested stack size as a parameter and
; returns the size of dynamic data space (64k - code - static data - stack)
        push    bp
        mov     bp,sp
        push    si di
        mov     word ptr ds:[errno],0
        mov     si,0ffffh
        sub     si,offset _startofdynamic ; code + static data
        sub     si,[bp+4]                 ; requested stack size
        jnc     L1                        ; overflow?
        mov     word ptr ds:[errno],ERR_MEM_NOFREE  ; yes, we're too greedy
        jmp     errexit
L1:
        mov     di,offset _startofdynamic
        mov     word ptr [di],'FR'        ; free block
        sub     si,16
        mov     ax,si                     ; size of block to return
        mov     word ptr [di+2],si        ; size of first block
        mov     word ptr [di+4],0
        add     si,8
        mov     word ptr [di+6],si        ; pointer to next block

        mov     [si],'AR'                 ; fill in the final MCB
        mov     word ptr [si+2],0         ; zero size
        mov     [si+4],di                 ; previous MCB
        mov     word ptr [si+6],0         ; next MCB (0 - last block)
L2:
        pop     di si
        pop     bp
        ret     2
errexit:
        mov     ax,-1
        jmp     L2

code ends
end
