summaryrefslogtreecommitdiff
path: root/v2.0/source/MSINIT.ASM
blob: 36edf9f529a63c9d302bee0cb54832e23eae3848 (plain) (blame)
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
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
; TITLE MSINIT.ASM -- MS-DOS INITIALIZATION CODE

        ORG     0                       ; reset to beginning of data segment
; Init code below overlaps with data area

INITBLOCK DB    110H DUP(0)     ; Allow for segment round up

INITSP  DW      ?
INITSS  DW      ?
BUFFSTRT DW     ?

ASSUME  CS:DOSGROUP,DS:DOSGROUP,ES:DOSGROUP,SS:NOTHING

        EXTRN   QUIT:NEAR,IRET:NEAR,ABSDRD:FAR,ABSDWRT:FAR
        EXTRN   COMMAND:NEAR,CALL_ENTRY:NEAR
        IF      NOT IBM
        EXTRN   HEADER:BYTE
        ENDIF

MOVDPB:
; This section of code is safe from being overwritten by block move
        MOV     SP,CS:[INITSP]
        MOV     SS,CS:[INITSS]
        REP     MOVS    BYTE PTR [DI],[SI]
        CLD
        MOV     WORD PTR ES:[DMAADD+2],DX
        MOV     SI,WORD PTR [DPBHEAD]   ; Address of first DPB
        MOV     WORD PTR ES:[DPBHEAD+2],ES
        MOV     WORD PTR ES:[sft_addr+2],ES
        MOV     CL,[NUMIO]      ; Number of DPBs
        XOR     CH,CH
SETFINDPB:
        MOV     WORD PTR ES:[SI.dpb_next_dpb+2],ES
        MOV     ES:[SI.dpb_first_access],-1      ; Never accessed before
        ADD     SI,DPBSIZ       ; Point to next DPB
        LOOP    SETFINDPB
        SUB     SI,DPBSIZ
        MOV     WORD PTR ES:[SI.dpb_next_dpb+2],-1
        MOV     DI,[BUFFSTRT]                   ; Set up one default buffer
        MOV     WORD PTR ES:[BUFFHEAD+2],ES
        MOV     WORD PTR ES:[BUFFHEAD],DI
        MOV     WORD PTR ES:[DI.BUFDRV],00FFH
        MOV     ES:[DI.BUFPRI],FREEPRI
        MOV     WORD PTR ES:[DI.NEXTBUF],-1
        MOV     WORD PTR ES:[DI.NEXTBUF+2],-1
        PUSH    ES
        INC     DX                          ; Leave enough room for the ARENA
        MOV     BYTE PTR [CreatePDB],0FFh   ; create jfns and set CurrentPDB
        invoke  $CREATE_PROCESS_DATA_BLOCK     ; Set up segment
ASSUME  DS:NOTHING,ES:NOTHING
        POP     ES
ASSUME  ES:DOSGROUP

;
; set up memory arena
;SPECIAL NOTE FOR HIGHMEM VERSION
; At this point a process header has been built where the start of the 
; CONSTANTS segment as refed by CS is. From this point until the return 
; below be careful about references off of CS.
;
        PUSH    AX
        MOV     AX,[CurrentPDB]
        MOV     ES:[CurrentPDB],AX         ; Put it in the REAL location
        MOV     BYTE PTR ES:[CreatePDB],0h ; reset flag in REAL location
        DEC     AX
        MOV     ES:[arena_head],AX
        PUSH    DS
        MOV     DS,AX
        MOV     DS:[arena_signature],arena_signature_end
        MOV     DS:[arena_owner],arena_owner_system
        SUB     AX,ES:[ENDMEM]
        NEG     AX
        DEC     AX
        MOV     DS:[arena_size],AX
        POP     DS
        POP     AX

        MOV     DI,OFFSET DOSGROUP:sftabl + sft_table   ; Point to sft 0
        MOV     AL,3
        STOSB           ; Adjust Refcount
        MOV     DI,OFFSET DOSGROUP:SYSINITVAR

XXX     PROC FAR
        RET
XXX     ENDP
DATA    ENDS

; the next segment defines a new class that MUST appear last in the link map.
; This defines several important locations for the initialization process that
; must be the first available locations of free memory.

LAST    SEGMENT BYTE PUBLIC 'LAST'
        PUBLIC  SYSBUF
        PUBLIC  MEMSTRT

SYSBUF  LABEL   WORD
ASSUME  CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING

DOSINIT:
        CLI
        CLD
        MOV     [ENDMEM],DX
        MOV     [INITSP],SP
        MOV     [INITSS],SS
        MOV     SP,OFFSET DOSGROUP:INITSTACK
        MOV     AX,CS
        MOV     SS,AX
ASSUME  SS:DOSGROUP
        MOV     WORD PTR [DEVHEAD+2],DS
        MOV     WORD PTR [DEVHEAD],SI   ; DS:SI Points to CONSOLE Device
        CALL    CHARINIT
        PUSH    SI
        ADD     SI,SDEVNAME             ; Point to name
        PUSH    CS
        POP     ES
ASSUME  ES:DOSGROUP
        MOV     DI,OFFSET DOSGROUP:sftabl + sft_table   ; Point to sft 0
        MOV     AL,3
        STOSB           ; Refcount
        DEC     AL
        STOSB           ; Access rd/wr
        XOR     AL,AL
        STOSB           ; Drive byte
        STOSB           ; attribute
        MOV     CX,4
        REP     MOVSW   ; Name
        MOV     CL,3
        MOV     AL," "
        REP     STOSB   ; Extension
        ADD     DI,12   ; Skip
        MOV     AL,0C0H OR ISCIN OR ISCOUT
        STOSB
        POP     SI
        MOV     AX,SI
        STOSW                   ; Device pointer in FIRCLUS
        MOV     AX,DS
        STOSW
        OR      BYTE PTR [SI.SDEVATT],ISCIN OR ISCOUT
        MOV     WORD PTR [BCON],SI
        MOV     WORD PTR [BCON+2],DS
CHAR_INIT_LOOP:
        LDS     SI,DWORD PTR [SI]               ; AUX device
        CALL    CHARINIT
        TEST    BYTE PTR [SI.SDEVATT],ISCLOCK
        JZ      CHAR_INIT_LOOP
        MOV     WORD PTR [BCLOCK],SI
        MOV     WORD PTR [BCLOCK+2],DS
        MOV     BP,OFFSET DOSGROUP:MEMSTRT      ; ES:BP points to DPB
PERDRV:
        LDS     SI,DWORD PTR [SI]               ; Next device
        CMP     SI,-1
        JZ      CONTINIT
        CALL    CHARINIT
        TEST    [SI.SDEVATT],DEVTYP
        JNZ     PERDRV                          ; Skip any other character devs
        MOV     CL,[CALLUNIT]
        XOR     CH,CH
        MOV     [SI.SDEVNAME],CL                ; Number of units in name field
        MOV     DL,[NUMIO]
        XOR     DH,DH
        ADD     [NUMIO],CL
        PUSH    DS
        PUSH    SI
        LDS     BX,[CALLBPB]
PERUNIT:
        MOV     SI,[BX]                 ; DS:SI Points to BPB
        INC     BX
        INC     BX                      ; On to next BPB
        MOV     ES:[BP.dpb_drive],DL
        MOV     ES:[BP.dpb_UNIT],DH
        PUSH    BX
        PUSH    CX
        PUSH    DX
        invoke  $SETDPB
        MOV     AX,ES:[BP.dpb_sector_size]
        CMP     AX,[MAXSEC]
        JBE     NOTMAX
        MOV     [MAXSEC],AX
NOTMAX:
        POP     DX
        POP     CX
        POP     BX
        MOV     AX,DS                   ; Save DS
        POP     SI
        POP     DS
        MOV     WORD PTR ES:[BP.dpb_driver_addr],SI
        MOV     WORD PTR ES:[BP.dpb_driver_addr+2],DS
        PUSH    DS
        PUSH    SI
        INC     DH
        INC     DL
        MOV     DS,AX
        ADD     BP,DPBSIZ
        LOOP    PERUNIT
        POP     SI
        POP     DS
        JMP     PERDRV

CONTINIT:
        PUSH    CS
        POP     DS
ASSUME  DS:DOSGROUP
; Calculate true address of buffers, FATs, free space
        MOV     DI,BP           ; First byte after current DPBs
        MOV     BP,[MAXSEC]
        MOV     AX,OFFSET DOSGROUP:SYSBUF
        MOV     [BUFFSTRT],AX
        ADD     AX,BP           ; One I/O buffer
        ADD     AX,BUFINSIZ
        MOV     WORD PTR [DPBHEAD],AX      ; True start of DPBs
        MOV     DX,AX
        SUB     DX,OFFSET DOSGROUP:SYSBUF
        MOV     BP,DX
        ADD     BP,DI           ; Allocate buffer space
        SUB     BP,ADJFAC       ; True address of free memory
        PUSH    BP
        MOV     DI,OFFSET DOSGROUP:MEMSTRT    ; Current start of DPBs
        ADD     DI,dpb_next_dpb      ; Point at dpb_next_dpb field
        MOV     CL,[NUMIO]
        XOR     CH,CH
TRUEDPBAD:
        ADD     AX,DPBSIZ       ; Compute address of next DPB
        STOSW                   ; Set the link to next DPB
        ADD     DI,DPBSIZ-2     ; Point at next address
        LOOP    TRUEDPBAD
        SUB     DI,DPBSIZ       ; Point at last dpb_next_dpb field
        MOV     AX,-1
        STOSW                   ; End of list
        ADD     BP,15           ;True start of free space (round up to segment)
        MOV     CL,4
        SHR     BP,CL           ; Number of segments for DOS resources
        MOV     DX,CS
        ADD     DX,BP           ; First free segment
        MOV     BX,0FH
        MOV     CX,[ENDMEM]

        IF      HIGHMEM
        SUB     CX,BP
        MOV     BP,CX           ; Segment of DOS
        MOV     DX,CS           ; Program segment
        ENDIF

        IF      NOT HIGHMEM
        MOV     BP,CS
        ENDIF

; BP has segment of DOS (whether to load high or run in place)
; DX has program segment (whether after DOS or overlaying DOS)
; CX has size of memory in paragraphs (reduced by DOS size if HIGHMEM)
        MOV     [ENDMEM],CX
        MOV     ES,BP
ASSUME  ES:DOSGROUP

        IF      HIGHMEM
        XOR     SI,SI
        MOV     DI,SI
        MOV     CX,OFFSET DOSGROUP:SYSBUF  ;# bytes to move
        SHR     CX,1            ;# words to move (carry set if odd)
        REP MOVSW               ; Move DOS to high memory
        JNC     NOTODD
        MOVSB
NOTODD:
        ENDIF

        MOV     WORD PTR ES:[DSKCHRET+3],ES
        XOR     AX,AX
        MOV     DS,AX
        MOV     ES,AX
ASSUME  DS:NOTHING,ES:NOTHING
        MOV     DI,INTBASE+2
        MOV     AX,BP
        MOV     BYTE PTR DS:[ENTRYPOINT],mi_Long_JMP
        MOV     WORD PTR DS:[ENTRYPOINT+1],OFFSET DOSGROUP:CALL_ENTRY
        MOV     WORD PTR DS:[ENTRYPOINT+3],AX
        EXTRN   DIVOV:near
        MOV     WORD PTR DS:[0],OFFSET DOSGROUP:DIVOV   ; Set default divide 
							; trap address
        MOV     DS:[2],AX
        MOV     CX,17
        REP STOSW               ; Set 9 segments (skip 2 between each)

        IF      ALTVECT
        MOV     DI,ALTBASE+2
        MOV     CX,15
        REP     STOSW           ; Set 8 segments (skip 2 between each)
        ENDIF

        MOV     WORD PTR DS:[addr_int_abort],OFFSET DOSGROUP:QUIT
        MOV     WORD PTR DS:[addr_int_command],OFFSET DOSGROUP:COMMAND
        MOV     WORD PTR DS:[addr_int_terminate],100H
        MOV     WORD PTR DS:[addr_int_terminate+2],DX
        MOV     WORD PTR DS:[addr_int_ctrl_c],OFFSET DOSGROUP:IRET   
							; Ctrl-C exit
        MOV     WORD PTR DS:[addr_int_fatal_abort],OFFSET DOSGROUP:IRET
							; Fatal error exit
        MOV     WORD PTR DS:[addr_int_disk_read],OFFSET DOSGROUP:ABSDRD
							; INT 25
        MOV     WORD PTR DS:[addr_int_disk_write],OFFSET DOSGROUP:ABSDWRT
							; INT 26
        EXTRN   Stay_resident:NEAR
        MOV     WORD PTR DS:[addr_int_keep_process],OFFSET DOSGROUP:Stay_resident
        MOV     WORD PTR DS:[addr_int_spooler],OFFSET DOSGROUP:IRET  ; Spooler

        IF      NOT ALTVECT
        MOV     CX,12
        XOR     AX,AX
        MOV     DI,2AH*4
        REP     STOSW           ;Zero interrupt locs for ints 2AH-2FH
        ENDIF

        PUSH    CS
        POP     DS
        PUSH    CS
        POP     ES
ASSUME  DS:DOSGROUP,ES:DOSGROUP
        MOV     AX,OFFSET DOSGROUP:INITBLOCK
        ADD     AX,0Fh                  ; round to a paragraph
        MOV     CL,4
        SHR     AX,CL
        MOV     DI,DS
        ADD     DI,AX
        INC     DI
        MOV     [CurrentPDB],DI
        PUSH    BP
        PUSH    DX              ; Save COMMAND address
        MOV     AX,[ENDMEM]
        MOV     DX,DI

        invoke    SETMEM          ; Basic Header
ASSUME  DS:NOTHING,ES:NOTHING
        PUSH    CS
        POP     DS
ASSUME  DS:DOSGROUP
        MOV     DI,PDB_JFN_Table
        XOR     AX,AX
        STOSW
        STOSB                   ; 0,1 and 2 are CON device
        MOV     AL,0FFH
        MOV     CX,FilPerProc - 3
        REP     STOSB           ; Rest are unused
        PUSH    CS
        POP     ES
ASSUME  ES:DOSGROUP
        MOV     WORD PTR [sft_addr+2],DS     ; Must be set to print messages

; After this points the char device functions for CON will work for
; printing messages

        IF      NOT IBM
        IF      NOT ALTVECT
        MOV     SI,OFFSET DOSGROUP:HEADER
        invoke  OUTMES
        PUSH    CS                      ; Outmes stomps on segments
        POP     DS
        PUSH    CS
        POP     ES
        ENDIF
        ENDIF

; Move the FATs into position
        POP     DX                      ; Restore COMMAND address
        POP     BP
        POP     CX                      ; True address of free memory
        MOV     SI,OFFSET DOSGROUP:MEMSTRT      ; Place to move DPBs from
        MOV     DI,WORD PTR [DPBHEAD]   ; Place to move DPBs to
        SUB     CX,DI                   ; Total length of DPBs
        CMP     DI,SI
        JBE     MOVJMP                  ; Are we moving to higher or 
					; lower memory?
        DEC     CX                      ; Move backwards to higher memory
        ADD     DI,CX
        ADD     SI,CX
        INC     CX
        STD
MOVJMP:
        MOV     ES,BP
ASSUME  ES:DOSGROUP
        JMP     MOVDPB

CHARINIT:
ASSUME  DS:NOTHING,ES:NOTHING
; DS:SI Points to device header
        MOV     [DEVCALL.REQLEN],DINITHL
        MOV     [DEVCALL.REQUNIT],0
        MOV     [DEVCALL.REQFUNC],DEVINIT
        MOV     [DEVCALL.REQSTAT],0
        PUSH    ES
        PUSH    BX
        PUSH    AX
        MOV     BX,OFFSET DOSGROUP:DEVCALL
        PUSH    CS
        POP     ES
        invoke  DEVIOCALL2
        POP     AX
        POP     BX
        POP     ES
        RET

        DB      80H DUP(?)
INITSTACK LABEL BYTE
        DW      ?

MEMSTRT LABEL   WORD
ADJFAC  EQU     MEMSTRT-SYSBUF

        do_ext
LAST    ENDS