Metropoli BBS
VIEWER: lock.asm MODE: TEXT (ASCII)
include qlib.inc

.data
externdef _baseram:dword     ;... don't want user to touch cause malloc sceme may change
                             
;RAM header
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

.code
lock_ram proc,off:dword,siz:dword
  .if _pmmode<SRV_DPMI
    xor eax,eax
    ret
  .endif
  pushad
  mov ax,600h
  mov ebx,off
  mov esi,siz
  mov cx,bx
  mov di,si
  shr ebx,16
  shr esi,16
  int 31h
  jc bad
  popad
  xor eax,eax
  ret
bad:
  popad
  mov eax,ERROR
  ret
lock_ram endp

unlock_ram proc,off:dword,siz:dword
  .if _pmmode<SRV_DPMI
    xor eax,eax
    ret
  .endif
  pushad
  mov ax,601h
  mov ebx,off
  mov esi,siz
  mov cx,bx
  mov di,si
  shr ebx,16
  shr esi,16
  int 31h
  jc bad
  popad
  xor eax,eax
  ret
bad:
  popad
  mov eax,ERROR
  ret
unlock_ram endp

;this call will LOCK all RAM possible
;iff useonly==1 then it makes sure you only alloc RAM from the locked RAM
;you must call this before you ever call malloc() (else this will fail)

locksiz equ 4*1024    ;this is the size to lock each time
lockbtz equ 12        ;this is # bits that locksiz is equal to
lock_all proc,useonly:byte
  ; MAKE SURE YOU PRINT A MESSAGE LIKE "LOCKING MEMORY..." cause locking
  ; 16 MBs RAM under Win95 takes about 3 mins.. (which I suggest you never
  ; do)  just lock important parts (around 1-2 megs at max)
  mov eax,_baseram
  mov al,[eax].heads.flag
  or al,3          ;last and free?
  .if al!=3  
    mov eax,ERROR  ;nope!
    ret
  .endif
  pushad
  mov ebx,_baseram
  .if _pmmode<SRV_DPMI  ;not in DPMI mode
    mov eax,[ebx].heads.siz
    mov [esp+7*4],eax
    popad
    ret
  .endif
  mov ecx,[ebx].heads.siz
  shr ecx,lockbtz  ;make divisable by 4K
  dec ecx          ;do not use last 4k fragment
  xor edx,edx      ;final size
@@:
  callp lock_ram,ebx,locksiz
  .if eax==ERROR
    .if useonly
      sub edx,sizeof heads
      mov ebx,_baseram
      mov [ebx].heads.siz,edx
    .else
      sub edx,sizeof heads
      mov ebx,_baseram
      mov [ebx].heads.siz,edx
    .endif
    mov [esp+7*4],edx  ;total locked (into EAX)
    popad
    ret
  .endif
  add edx,locksiz
  add ebx,locksiz
  dec ecx
  jnz @b
;all pages locked
  sub edx,sizeof heads
  mov ebx,_baseram
  mov [ebx].heads.siz,edx
  mov [esp+7*4],edx  ;total locked (into EAX)
  popad
  ret
lock_all endp

end
[ RETURN TO DIRECTORY ]