-
Notifications
You must be signed in to change notification settings - Fork 1
/
LIBINIT.ASM
292 lines (225 loc) · 7.58 KB
/
LIBINIT.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
page 60,132
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; libinit.asm
;
; Copyright (c) 1991-1992 Microsoft Corporation. All Rights Reserved.
; Copyright (c) 2019-2020 Andrei Warkentin <andrey.warkentin@gmail.com>
;
; General Description:
; Library stub to do local init for a dynamic linked library.
;
; Restrictions:
; This must be the first object file in the LINK line. This assures
; that the reserved parameter block is at the *base* of DGROUP.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if1
%out link me first!!
endif
PMODE = 1
.xlist
include cmacros.inc
include windows.inc
include vadlibd.inc
.list
?PLM=1 ; Pascal calling convention
?WIN=0 ; NO! Windows prolog/epilog code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; equates
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
OFFSEL struc
off dw ?
sel dw ?
OFFSEL ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; segmentation
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ifndef SEGNAME
SEGNAME equ <_TEXT>
endif
createSeg %SEGNAME, CodeSeg, word, public, CODE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; external functions
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
externFP LocalInit ; in KERNEL
externNP LibMain ; C code to do DLL init
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; data segment
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sBegin Data
assumes ds, Data
; stuff needed to avoid the C runtime coming in, and init the Windows
; reserved parameter block at the base of DGROUP
org 0 ; base of DATA segment!
dd 0 ; so null pointers get 0
maxRsrvPtrs = 5
dw maxRsrvPtrs
usedRsrvPtrs = 0
labelDP <PUBLIC, rsrvptrs>
DefRsrvPtr macro name
globalW name, 0
usedRsrvPtrs = usedRsrvPtrs + 1
endm
DefRsrvPtr pLocalHeap ; local heap pointer
DefRsrvPtr pAtomTable ; atom table pointer
DefRsrvPtr pStackTop ; top of stack
DefRsrvPtr pStackMin ; minimum value of SP
DefRsrvPtr pStackBot ; bottom of stack
if maxRsrvPtrs-usedRsrvPtrs
dw maxRsrvPtrs-usedRsrvPtrs DUP (0)
endif
public __acrtused
__acrtused = 1
externW <_wPort> ; address of sound chip
public VADLIBD_Entry
VADLIBD_Entry dd 0
sEnd Data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; code segment
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sBegin CodeSeg
assumes cs, CodeSeg
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; @doc INTERNAL
;
; @asm LibEntry | Called when DLL is loaded.
;
; @reg CX | Size of heap.
;
; @reg DI | Module handle.
;
; @reg DS | Automatic data segment.
;
; @reg ES:SI | Address of command line (not used).
;
; @rdesc AX is TRUE if the load is successful and FALSE otherwise.
;
; @comm Registers preserved are SI,DI,DS,BP. Registers destroyed are
; AX,BX,CX,DX,ES,FLAGS.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
cProc LibEntry <FAR, PUBLIC, NODATA>, <>
cBegin
; push frame for LibMain (hModule, cbHeap, lpszCmdLine)
push di
push cx
push es
push si
; init the local heap (if one is declared in the .def file)
jcxz no_heap
cCall LocalInit, <0, 0, cx>
no_heap:
cCall LibMain
cEnd
;---------------------------------------------------------------------------;
;
; vadlibdGetEntryPoint
;
; DESCRIPTION:
;
;
;---------------------------------------------------------------------------;
assumes ds, Data
assumes es, nothing
cProc vadlibdGetEntryPoint <FAR, PASCAL, PUBLIC> <si, di>
cBegin
xor di, di ; zero ES:DI before call
mov es, di
mov ax, 1684h ; get device API entry point
mov bx, VADLIBD_Device_ID ; virtual device ID
int 2Fh ; call WIN/386 INT 2F API
mov ax, es ; return farptr
or ax, di
jz gvadlibd_exit
mov word ptr [VADLIBD_Entry.off], di
mov word ptr [VADLIBD_Entry.sel], es
gvadlibd_exit:
cEnd
;---------------------------------------------------------------------------;
;
; WORD FAR PASCAL vadlibdAcquireAdLibSynth( void )
;
; DESCRIPTION:
;
; ENTRY:
;
; EXIT:
; IF Carry Clear
; AX = 0, success--go ahead and open
; ELSE
; carry set, AX = error code:
; ADLIB_AS_Err_Bad_Synth equ 01h
; ADLIB_AS_Err_Already_Owned equ 02h
;
; USES:
; Flags, AX, BX, DX
;
;---------------------------------------------------------------------------;
assumes ds, Data
assumes es, nothing
cProc vadlibdAcquireAdLibSynth <FAR, PASCAL, PUBLIC> <>
cBegin
mov ax, [VADLIBD_Entry.off] ; Q: is VADLIBD installed?
or ax, [VADLIBD_Entry.sel]
jz vadlibd_Acquire_Exit ; N: then leave (return 0)
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; AX = Base of Syth to acquire (for example, 0388h)
; BX = Flags, should be zero.
; DX = ADLIB_API_Acquire_Synth (1)
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
mov ax, [_wPort] ; base port to acquire
xor bx, bx
mov dx, ADLIB_API_Acquire_Synth
call [VADLIBD_Entry]
vadlibd_Acquire_Exit:
cEnd
;---------------------------------------------------------------------------;
;
; WORD FAR PASCAL vadlibdReleaseAdLibSynth( void )
;
; DESCRIPTION:
;
; ENTRY:
;
; EXIT:
; IF Carry Clear
; AX = 0, success--go ahead and open
; ELSE
; carry set, AX = error code:
; ADLIB_RS_Err_Bad_Synth equ 01h
; ADLIB_RS_Err_Not_Yours equ 02h
;
; USES:
; Flags, AX, BX, DX
;
;---------------------------------------------------------------------------;
assumes ds, Data
assumes es, nothing
cProc vadlibdReleaseAdLibSynth <FAR, PASCAL, PUBLIC> <>
cBegin
mov ax, [VADLIBD_Entry.off] ; Q: is VADLIBD installed?
or ax, [VADLIBD_Entry.sel]
jz vadlibd_Release_Exit ; N: then leave (return 0)
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; AX = Base of synth to release (for example, 0388h)
; BX = Flags should be zero.
; DX = ADLIB_API_Release_Synth (2)
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
mov ax, [_wPort] ; base port to acquire
xor bx, bx
mov dx, ADLIB_API_Release_Synth
call [VADLIBD_Entry]
vadlibd_Release_Exit:
cEnd
sEnd CodeSeg
end LibEntry