Metropoli BBS
VIEWER: meminit.asm MODE: TEXT (ASCII)
; see alloc.asm for details

.data?
; This is what each header looks like
heads struct  ;12bytes
  magic dw ? ; 'PQ' ;signature
  flag db ?  ;bit0=free(1)  bit1=last(2)   (1==true)
  _a1 db ?   ;junk byte for alignment (not used!)
  prev dd ?  ;ptr=>previous block
  siz dd ?   ;size of this block
heads ends

externdef _baseram:dword
_baseram dd ? ;RAM base (relative)
_handle dd ?  ;RAM handle  (used for PMODE/W only)

.code

alloc_init proc private
  local siz:dword
  sub esp,48
  mov ax,0500h
  mov edi,esp
  int 31h
  jc outofram
  mov eax,[esp]  ;RAM avail
  add esp,48                               ;FIX : v2.00 Beta #2 : this was
  .if eax>HEAP_MAX   ;too much?            ;before the mov eax,[edi]
    mov eax,HEAP_MAX
  .endif
  ;round to highest 4K
  .if eax & 0fffh
    and eax,0fffff000h
    add eax,1000h
  .endif
  mov siz,eax
  .if !eax
    mov _baseram,0  ;no XMS wanted
    ret
  .endif
; under Windoze and DOS/4GW sometimes more RAM was said to be avail
; than there really is.  So I slowly decrease the amount requested until
; it works or until it drops below HEAP_MIN

retry:
  .if eax<HEAP_MIN
    jmp outofram
  .endif
  mov ebx,eax
  shr ebx,16
  mov cx,ax
  mov ax,0501h
  int 31h
  .if carry?
    .if siz<64*1024+1
      jmp outofram
    .endif
    sub siz,64*1024
    mov eax,siz
    jmp retry
  .endif
  shl ebx,16
  mov bx,cx
  mov _baseram,ebx
  shl esi,16
  mov si,di
  mov _handle,esi

  mov eax,siz  ;FIX : v2.00 Beta #2 : This was not here !?!
  mov word ptr[ebx].heads.magic,5150h  ;'PQ'=50,51
  mov byte ptr[ebx].heads.flag,3h      ;last&free
  mov dword ptr[ebx].heads.prev,0      ;no prev!
  sub eax,sizeof heads
  mov dword ptr[ebx].heads.siz,eax
  ret
alloc_init endp

outofram:
  callp print,"Error:Out of memory...\n"
  mov eax,HEAP_MIN
  add eax,1023
  shr eax,10  ;divide by 1k
  callp printf,"Require at least %uk XMS\n",eax
  mov ax,4c03h
  int 21h

[ RETURN TO DIRECTORY ]