home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
pascal
/
library
/
dos
/
t_power
/
getmem.asm
< prev
next >
Wrap
Assembly Source File
|
1988-09-29
|
12KB
|
274 lines
;*******************************************************
; GETMEM.ASM 5.00
; Copyright (c) TurboPower Software 1987.
; All rights reserved.
;*******************************************************
DSEG SEGMENT WORD PUBLIC
EXTRN PrefixSeg:WORD ;Variables in SYSTEM
EXTRN FreePtr:DWORD
EXTRN HeapPtr:DWORD
EXTRN HeapOrg:DWORD
DSEG ENDS
CSEG SEGMENT BYTE PUBLIC
ASSUME CS:CSEG,DS:DSEG
PUBLIC SetMaxHeap
PUBLIC GetMemDos
PUBLIC Pointer2String
PUBLIC String2Pointer
ofst EQU (WORD PTR 0)
segm EQU (WORD PTR 2)
;*********************************************************** SetMaxHeap
; procedure SetMaxHeap(Bytes : LongInt);
; Set maximum heap and adjust DOS memory allocation block
SetMaxHeap PROC FAR
MOV BX,SP
LES AX,SS:[BX+4]
MOV DX,ES ;DX:AX = bytes we want
ADD AX,0Fh ;Add 15 bytes to round up
ADC DX,0
MOV CX,4 ;Divide bytes by 16
SetMaxR:
SHR DX,1 ;Shift a LongInt right
RCR AX,1
LOOP SetMaxR
OR DX,DX ;More than 640K?
JNZ SetMaxDone ;Jump if so
MOV ES,[PrefixSeg] ;ES = base of program
MOV DX,ES:[0002h] ;DX = Top of memory
MOV BX,HeapOrg.segm ;BX = base of heap
SUB DX,BX ;DX = paragraphs of heap now
CMP DX,AX ;Space left to give away?
JBE SetMaxDone ;Jump if not
MOV DX,ES ;DX = base of program
SUB BX,DX ;BX = paras to base of heap
ADD BX,AX ;BX = paras we want
MOV AH,4Ah
INT 21h ;DOS SetBlock
JC SetMaxDone ;Jump if error
MOV AX,ES
ADD AX,BX ;AX = top of program segment
MOV ES:[0002h],AX ;Store in PSP
SUB AX,1000h ;FreePtr segment
MOV FreePtr.segm,AX ;Store new FreePtr
XOR AX,AX
MOV FreePtr.ofst,AX
SetMaxDone:
RET 4
SetMaxHeap ENDP
;*********************************************************** Pointer2String
; function Pointer2String(P : pointer) : string;
Pointer2String PROC FAR
MOV BX,SP ;Set up stack frame
PUSH DS ;Save DS
PUSH SS
POP DS ;DS = SS
LEA SI,DWORD PTR SS:[BX+4] ;DS:SI => P parameter
LES DI,DWORD PTR SS:[BX+8] ;ES:DI => Result
CLD
MOV CX,8 ;Eight bytes in string
MOV AL,CL
STOSB ;Store length byte
SHR CX,1 ;Four input bytes
MOV DX,0F30h ;DH/DL are constants
P2SNext:
LODSB ;Next byte
MOV AH,AL ;Save it
AND AL,DH ;Low nibble
ADD AL,DL ;Bias into ASCII
STOSB ;Store in string
MOV AL,AH ;Restore byte
SHR AL,1
SHR AL,1
SHR AL,1
SHR AL,1 ;High nibble
ADD AL,DL
STOSB ;Store in string
LOOP P2SNext ;Do four bytes
POP DS ;Restore DS
RET 4 ;Remove parameter and return
Pointer2String ENDP
;*********************************************************** String2Pointer
; function String2Pointer(S : string) : pointer;
;Parameters and locals
S EQU DWORD PTR [BP+6]
ResultHigh EQU WORD PTR [BP-2]
ResultLow EQU WORD PTR [BP-4]
Result EQU BYTE PTR [BP-4]
String2Pointer PROC FAR
PUSH BP
MOV BP,SP
SUB SP,4 ;Space for locals
PUSH DS ;Save DS
LDS SI,S ;DS:SI => S
CLD ;Forward
XOR CX,CX ;Prepare for error
LODSB ;AL = length byte
CMP AL,8 ;Proper length?
MOV DX,CX ;Nil in DX
JNZ S2PDone ;Wrong length, return nil
PUSH SS
POP ES
LEA DI,Result ;ES:DI => Result
MOV CX,4 ;4 words in string
MOV DL,'0' ;Constant
S2PNext:
LODSW ;First two bytes in AX
SUB AH,DL ;Debias ASCII
SHL AH,1
SHL AH,1
SHL AH,1
SHL AH,1
SUB AL,DL ;Debias ASCII
OR AL,AH ;Put bytes back together
STOSB ;Store in result
LOOP S2PNext
MOV CX,ResultLow ;Get result in registers
MOV DX,ResultHigh
S2PDone:
MOV AX,CX ;Store low word
POP DS ;Restore DS
MOV SP,BP
POP BP
RET 4 ;Remove parameter and return
String2Pointer ENDP
;**************************************************************** GetMemDos
; procedure GetMemDos(var P : pointer; Bytes : longint);
;Parameters
P EQU DWORD PTR [BP+10] ;Pointer to initialize
Bytes EQU DWORD PTR [BP+6] ;Bytes to allocate
GetMemDos PROC FAR
PUSH BP
MOV BP,SP ;Set up stack frame
;Get requested bytes and convert to paragraphs
LES AX,Bytes ;Get the bytes longint
MOV DX,ES ;DX:AX has bytes to allocate
ADD AX,0Fh ;Add 15 bytes to round up
ADC DX,0
MOV CX,4 ;Divide bytes by 16
NextShiftR:
SHR DX,1 ;Shift a LongInt right
RCR AX,1
LOOP NextShiftR
OR DX,DX ;Requesting more than 640K?
JNZ Error ;Error
;Try to get memory from DOS without affecting this process
MOV BX,AX ;Paragraphs to request
INC AX ;Ask for extra paragraph later
MOV DI,AX ;DI = Paragraphs+1
MOV AH,48h ;Allocate memory
INT 21h
JNC Store ;Success if no carry
;See if moving the free list down will fit the request
;Ignore the DOS free block since it may not be contiguous with the Turbo heap
LES AX,FreePtr ;ES:AX = FreePtr
MOV DX,ES ;DX:AX = FreePtr
PUSH DX ;Save FreeSeg
PUSH AX ;Save FreeOfs
OR AX,AX ;FreeList empty?
JNZ FreeListNotEmpty
MOV AX,1000h ;Empty FreeList => +64K free
JMP SHORT GetFreeSpace
FreeListNotEmpty:
MOV CL,4
SHR AX,CL ;Convert FreeOfs to paras
GetFreeSpace:
ADD DX,AX ;DX = segment of
; lowest free list entry
LES BX,HeapPtr ;ES:BX = HeapPtr
MOV AX,ES ;AX is seg(HeapPtr^)
INC AX ;Ignore up to 16 bytes
SUB DX,AX ;DX = paragraphs free at
; top of heap
CMP DX,DI ;Is free amount >= request?
JB Error ;No, error
;Move free list down into free heap
POP SI ;SI = FreeOfs
POP DX ;DX = FreeSeg
PUSH DI ;Save Paragraphs+1
MOV CX,DX ;CX = FreeSeg
SUB CX,DI ;CX = seg of new free list
MOV ES,CX ;ES = seg of new free list
OR SI,SI ;Is FreeList empty?
JZ StoreFreePtr ;Yes, skip the move
PUSH DS ;Save DS
MOV DS,DX ;DS:SI => old free list
CLD ;Forward avoids overwrite
MOV DI,SI ;ES:DI => new free list
MOV CX,SI ;CX = FreeOfs
NEG CX ;CX = 10000h-FreeOfs
SHR CX,1 ;Always even number of bytes
REP MOVSW ;Copy the free list
POP DS ;Restore DS
;Store the new free list pointer
StoreFreePtr:
POP DI ;Restore Paragraphs+1
MOV WORD PTR [FreePtr+2],ES ;Store new FreeSeg
;Shrink memory block for this process
MOV BX,ES ;BX = NewFreeSeg
ADD BX,1000h ;BX = Top of NewFreeSeg
MOV AX,[PrefixSeg] ;AX = base segment of process
SUB BX,AX ;BX = paras to keep
MOV ES,AX ;ES = segment of memory block
MOV AH,4Ah ;DOS SetBlock
INT 21h
JC Error ;Error
;Try to get the requested block again
Get2: MOV BX,DI ;BX = Paragraphs+1
DEC BX ;BX = Paragraphs
MOV AH,48h ;Allocate memory
INT 21h
JNC Store ;Success if no carry
Error: XOR AX,AX ;Error, return nil
Store: LES DI,P ;ES:DI => result pointer
MOV WORD PTR ES:[DI],0 ;Store the return pointer
MOV ES:[DI+2],AX ;Segment in AX
MOV SP,BP
POP BP
RET 8
GetMemDos ENDP
CSEG ENDS
END