-
Notifications
You must be signed in to change notification settings - Fork 2
/
DALLOC.ASM
102 lines (82 loc) · 2.34 KB
/
DALLOC.ASM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
;-----------------------------------------------------------------
; dalloc.asm
; ----------
; Memory-allocation routines that operate OUTSIDE of the data segment.
; These work with SEGMENT addresses, NOT actual pointers.
; For allocation in the data segment, just use malloc () and free ().
;-----------------------------------------------------------------
include asm.inc
HEADER dalloc
PSEG dalloc
;-----------------------------------------------------------------
; WORD DAlloc (size);
; UWORD size;
; Allocate a block of "size" bytes and return its segment. If
; the allocation fails, return NULL.
; Since this uses DOS allocation, it will allocate just enough paragraphs
; for the number of bytes requested.
;-----------------------------------------------------------------
public _DAlloc
STARTPROC _DAlloc
push bp
mov bp,sp
mov ah,048h ; function #
; bx = number of paragraphs = (bytes >> 4) + (bytes & 0x0f) ? 1 : 0;
mov bx,ARGB[bp]
mov cl,4
shr bx,cl
test word ptr ARGB[bp],0fh
je dalloc_p0
inc bx
dalloc_p0:
int 021h
jnc dalloc_p1
xor ax,ax ; alloc failed, so return NULL
dalloc_p1:
pop bp
ret
ENDPROC _DAlloc
;-----------------------------------------------------------------
; void SFree (seg);
; Was "DFree", but PLink said that conflicted with "dfree".
; Free the block at the given segment address.
;
; Okay to call with NULL, so safe to call on already freed segment
; variables. That DOESN'T mean it is okay to maintain two DIFFERENT
; segment variables, and try to free the same region twice through
; two different variables! Also, it is up to the caller to NULL
; his sgment variable when done. Maybe we should switch to a model
; where caller passes ADDRESS of segment variable! [sss]
; Always returns null, so can use to null a variable holding a
; segment address:
; "segname = SFree(segname);"
;-----------------------------------------------------------------
public _SFree
STARTPROC _SFree
push bp
mov bp,sp
push es
; if (!seg), don't do anything
test word ptr ARGB[bp],0ffffh
jz dfree_done
; free the segment
mov ah,049h
mov es,ARGB[bp]
int 021h
ifdef DEBUGGING
jnc dfree_1
mov ax,9999
push ax
call _crash
dfree_1:
endif
dfree_done:
xor ax,ax ; NULL return value so can assign.
pop es
pop bp
ret
ENDPROC _SFree
;-----------------------------------------------------------------
ENDPS dalloc
end