rev |
line source |
pascal@19515
|
1 ;***************************************************************
|
pascal@19515
|
2 ;****** This file is distributed under GPL
|
pascal@19515
|
3 ;***************************************************************
|
pascal@19515
|
4 ideal
|
pascal@21984
|
5 %PAGESIZE 1000
|
pascal@19515
|
6 %crefref
|
pascal@19515
|
7 %noincl
|
pascal@19515
|
8 %nomacs
|
pascal@24019
|
9
|
pascal@24019
|
10 include "common.inc"
|
pascal@24022
|
11 include "himem.inc"
|
pascal@24022
|
12 include "isostate.inc"
|
pascal@24022
|
13
|
pascal@24022
|
14 ifdef QUICK_BOOT
|
pascal@24022
|
15 CMDNUMCNT = 7
|
pascal@24022
|
16 else
|
pascal@24022
|
17 CMDNUMCNT = 5
|
pascal@24022
|
18 endif
|
pascal@24022
|
19
|
pascal@24022
|
20 macro alloc_isostate
|
pascal@24022
|
21 public _isostate
|
pascal@24022
|
22 _isostate isostate <?>
|
pascal@24022
|
23 org $-ISOSTATE_OVERLAP
|
pascal@24022
|
24 endm
|
pascal@24022
|
25
|
pascal@24022
|
26 macro alloc_image
|
pascal@24022
|
27 rm_size dw ? ; _imgs-4
|
pascal@24022
|
28 rm_buf dw ? ; _imgs-2
|
pascal@24022
|
29 global _imgs:byte
|
pascal@24022
|
30 label _imgs byte
|
pascal@24022
|
31 img_kernel image_himem ?
|
pascal@24022
|
32 img_initrd image_himem ?
|
pascal@24022
|
33 endm
|
pascal@24022
|
34
|
pascal@24023
|
35 macro alloc_cmdnum
|
pascal@24022
|
36 global _cmdnum:word
|
pascal@24022
|
37 label _cmdnum word
|
pascal@24022
|
38 dd CMDNUMCNT dup(?)
|
pascal@24022
|
39 endm
|
pascal@24019
|
40
|
pascal@19636
|
41 p8086
|
pascal@19515
|
42
|
pascal@19515
|
43 group DGROUP _TEXT,_DATA,_BSS
|
pascal@19515
|
44 assume cs:DGROUP,ds:DGROUP
|
pascal@19515
|
45
|
pascal@19515
|
46 segment _TEXT byte public use16 'CODE'
|
pascal@20451
|
47 ends _TEXT
|
pascal@20451
|
48
|
pascal@20451
|
49 segment _DATA byte public use16 'DATA'
|
pascal@23996
|
50 ;global _data_start:byte
|
pascal@20451
|
51 label _data_start byte
|
pascal@20451
|
52 ifndef NO386
|
pascal@24019
|
53 msg_badcpu db "I need a 386+ in real mode w/o paging"
|
pascal@24019
|
54 ifdef VCPI
|
pascal@22183
|
55 db " or "
|
pascal@22183
|
56 msg_badmapping db "under VCPI 4.0+ manager with low 640k 1:1 mapping"
|
pascal@22183
|
57 global _vcpi:byte
|
pascal@24019
|
58 endif
|
pascal@22183
|
59 _vcpi db 0
|
pascal@20451
|
60 endif
|
pascal@20451
|
61
|
pascal@20451
|
62 ends _DATA
|
pascal@20451
|
63
|
pascal@20451
|
64 segment _BSS byte public use16 'BSS'
|
pascal@21757
|
65
|
pascal@24022
|
66 ifdef ISO9660
|
pascal@24022
|
67 ifndef VCPI
|
pascal@24022
|
68 alloc_isotate
|
pascal@24022
|
69 else
|
pascal@24022
|
70 room_for_isostate = 1
|
pascal@24022
|
71 endif
|
pascal@24022
|
72 endif
|
pascal@24022
|
73
|
pascal@24013
|
74 ifdef ISOHOOK
|
pascal@23996
|
75 extrn _big_cmdline:byte
|
pascal@23996
|
76 db 254 dup(?)
|
pascal@23996
|
77 endif
|
pascal@23996
|
78 ;global _bss_start:byte
|
pascal@20451
|
79 label _bss_start byte
|
pascal@22312
|
80 global stktop:byte
|
pascal@22183
|
81 global _cpu386:byte
|
pascal@22183
|
82 _cpu386 db ?
|
pascal@24019
|
83 ifdef CPU64
|
pascal@22183
|
84 org $-1
|
pascal@20451
|
85 global _cpu_features:dword
|
pascal@20451
|
86 _cpu_features dd ?
|
pascal@24022
|
87 room_for_image = 1
|
pascal@24022
|
88 else
|
pascal@24022
|
89 alloc_image
|
pascal@24019
|
90 endif
|
pascal@24022
|
91
|
pascal@24022
|
92 ifndef BSS_OVERLAP_BOOT
|
pascal@24022
|
93
|
pascal@24022
|
94 ifdef room_for_isostate
|
pascal@24022
|
95 alloc_isostate
|
pascal@24022
|
96 endif
|
pascal@24022
|
97
|
pascal@24022
|
98 ifdef room_for_image
|
pascal@24022
|
99 alloc_image
|
pascal@24022
|
100 endif
|
pascal@24022
|
101
|
pascal@24023
|
102 alloc_cmdnum
|
pascal@24022
|
103
|
pascal@24022
|
104 endif
|
pascal@24022
|
105
|
pascal@20451
|
106 ends _BSS
|
pascal@20451
|
107
|
pascal@20451
|
108 segment _TEXT byte public use16 'CODE'
|
pascal@19515
|
109
|
pascal@19825
|
110 macro cpuid
|
pascal@19825
|
111 db 0fh,0A2h
|
pascal@19825
|
112 endm
|
pascal@19825
|
113
|
pascal@19515
|
114 org 100h
|
pascal@23996
|
115 ;global _text_start:byte
|
pascal@19515
|
116 label _text_start byte
|
pascal@19546
|
117
|
pascal@19515
|
118 ;***************************************************************
|
pascal@19515
|
119 ; clear bss
|
pascal@19515
|
120 ;***************************************************************
|
pascal@21757
|
121 mov sp,offset stktop
|
pascal@23996
|
122 mov bx, 0F000h ; cld ; cli & empty string
|
pascal@22179
|
123 mov si,offset _bss_start
|
pascal@19515
|
124 clearbss:
|
pascal@22312
|
125 mov [si],bl ; clear bss + heap
|
pascal@20426
|
126 inc si
|
pascal@19546
|
127 jne clearbss
|
pascal@19546
|
128
|
pascal@19546
|
129 ;***************************************************************
|
pascal@19546
|
130 ; check CPU
|
pascal@19546
|
131 ;***************************************************************
|
pascal@19546
|
132
|
pascal@19546
|
133 ; Check for oldies
|
pascal@19873
|
134 push bx ; < 286 : flags[12..15] are forced 1
|
pascal@24013
|
135 popf ; = 286 : flags[12..15] are forced 0, cld
|
pascal@19873
|
136 pushf ; > 286 : only flags[15] is forced 0
|
pascal@19873
|
137 pop dx
|
pascal@20451
|
138 add dh,bh ; NS=386+, S+NC=286, S+C=86/186
|
pascal@20451
|
139 ifndef NO386
|
pascal@19873
|
140 mov bx,offset msg_badcpu
|
pascal@22183
|
141 js godie ;it is not a 386+, die
|
pascal@20451
|
142 else
|
pascal@22183
|
143 js endcpu86 ;it is not a 386+, try ELKS & co
|
pascal@19546
|
144 endif
|
pascal@19636
|
145 p386
|
pascal@23996
|
146 mov edx,cs
|
pascal@23996
|
147 shl edx,4 ; edx for prepare_vcpi
|
pascal@23996
|
148 extrn gdt_base_memcpy:word ; gdt_base for memcpy32
|
pascal@23996
|
149 add [dword gdt_base_memcpy],edx
|
pascal@19546
|
150 ; Check for vm
|
pascal@19546
|
151 smsw ax ;SMSW cannot be trapped! :-)
|
pascal@19571
|
152 and al,1 ;MSW_PE
|
pascal@19546
|
153 ; We're in vm
|
pascal@20457
|
154 jnz check_vcpi
|
pascal@20457
|
155
|
pascal@20457
|
156 check_rm_paging:
|
pascal@20457
|
157 ; It's a 386 in real mode, chk for paging (crazy but possible)
|
pascal@20457
|
158 mov eax,cr0
|
pascal@20457
|
159 inc eax ;CR0_PG to S
|
pascal@20457
|
160 jns endcpu386
|
pascal@22183
|
161 ifndef NO386
|
pascal@20457
|
162 p8086
|
pascal@20457
|
163 extrn die:near
|
pascal@20457
|
164 godie:
|
pascal@20457
|
165 call near die
|
pascal@22183
|
166 else
|
pascal@22183
|
167 jmp endcpu86
|
pascal@22183
|
168 endif
|
pascal@19546
|
169
|
pascal@23797
|
170
|
pascal@19546
|
171 ;***************************************************************
|
pascal@19546
|
172 ; checks for vcpi
|
pascal@19546
|
173 ;***************************************************************
|
pascal@19546
|
174 label check_vcpi near
|
pascal@20457
|
175 p386
|
pascal@24019
|
176 ifdef VCPI
|
pascal@24013
|
177 ; Check whether it is safe to call 67h
|
pascal@24013
|
178 xor eax,eax
|
pascal@24022
|
179 push ds
|
pascal@24022
|
180 mov ds,ax
|
pascal@24022
|
181 cmp [dword 67h*4],eax
|
pascal@24022
|
182 pop ds
|
pascal@23996
|
183 je no_vcpi
|
pascal@24013
|
184 mov ah,0DEh ; check for vcpi present
|
pascal@19546
|
185 int 67h
|
pascal@23996
|
186 or ah,ah
|
pascal@19571
|
187 jnz no_vcpi
|
pascal@19546
|
188 is386vcpi:
|
pascal@19546
|
189 extrn prepare_vcpi:near
|
pascal@19546
|
190 call prepare_vcpi
|
pascal@19546
|
191 ; get_vcpi_interface() || die("VCPI: low 640k: need 1:1 mapping");
|
pascal@19546
|
192 ;extrn _get_vcpi_interface:near
|
pascal@19546
|
193 ;call _get_vcpi_interface
|
pascal@22183
|
194 ifndef NO386
|
pascal@19546
|
195 mov bx,offset msg_badmapping
|
pascal@20457
|
196 jnz no_vcpi
|
pascal@22183
|
197 dec [byte bx+_vcpi-msg_badmapping]
|
pascal@22183
|
198 else
|
pascal@22183
|
199 jnz no_vcpi
|
pascal@22183
|
200 extrn _vcpi:byte
|
pascal@22183
|
201 dec [byte _vcpi]
|
pascal@22183
|
202 endif
|
pascal@24019
|
203 endif
|
pascal@23996
|
204 no_vcpi:
|
pascal@20457
|
205 endcpu386:
|
pascal@24019
|
206 ifdef CPU64
|
pascal@20457
|
207 pushfd
|
pascal@20457
|
208 pop dx
|
pascal@20457
|
209 pop ax
|
pascal@20457
|
210 mov bl,al
|
pascal@23996
|
211 xor al,20h ; toggle CPUID feature bit 21 (=> pentium+)
|
pascal@23996
|
212 push ax ; (toggle AC: bit 18 => 486+)
|
pascal@20457
|
213 push dx
|
pascal@20457
|
214 popfd
|
pascal@20457
|
215 pushfd
|
pascal@22203
|
216 pop dx ; dx.1=flags.1=1
|
pascal@20457
|
217 pop ax
|
pascal@20457
|
218 xor al,bl ; clear C
|
pascal@20457
|
219 je @@no_cpuid ; CPUID feature bit changed ?
|
pascal@20457
|
220 mov eax,80000001h ; Extended Processor Info and Feature Bits
|
pascal@20457
|
221 cpuid
|
pascal@23996
|
222 mov dl,-1 ; set 386 flag (assume cpuid => fpu:bit0=1 ?)
|
pascal@22183
|
223 ifdef NO386
|
pascal@22203
|
224 db 66h ; mov [_cpu_features],edx
|
pascal@22203
|
225 @@no_cpuid:
|
pascal@22203
|
226 mov [word _cpu_features],dx ; dl != 0
|
pascal@22203
|
227 else
|
pascal@20457
|
228 mov [_cpu_features],edx
|
pascal@20457
|
229 @@no_cpuid:
|
pascal@22203
|
230 endif
|
pascal@24019
|
231 else
|
pascal@24019
|
232 dec [_cpu386]
|
pascal@24019
|
233 endif
|
pascal@20457
|
234 endcpu86:
|
pascal@19636
|
235 p8086
|
pascal@19546
|
236
|
pascal@19515
|
237 ;***************************************************************
|
pascal@19515
|
238 ; build argv & argc
|
pascal@19515
|
239 ;***************************************************************
|
pascal@19515
|
240 mov si,80h
|
pascal@24013
|
241 ifdef ISOHOOK
|
pascal@23996
|
242 mov bx,offset _big_cmdline
|
pascal@23996
|
243 cmp [byte si],2
|
pascal@23996
|
244 jnb @@user_args
|
pascal@23996
|
245 call @set_cmdline$qpxzc
|
pascal@23996
|
246 @@user_args:
|
pascal@23996
|
247 endif
|
pascal@23996
|
248 lodsb ; size 0..127
|
pascal@19546
|
249 cbw
|
pascal@24013
|
250 ifdef ISOHOOK
|
pascal@23996
|
251 inc ax
|
pascal@23996
|
252 jnz short_cmdline
|
pascal@23996
|
253 mov si,bx
|
pascal@23996
|
254 lodsb ; size 0..254
|
pascal@23996
|
255 short_cmdline:
|
pascal@23996
|
256 dec ax
|
pascal@23996
|
257 endif
|
pascal@19515
|
258 xchg ax,bx
|
pascal@19515
|
259 mov [bx+si],bh ; set eos
|
pascal@24022
|
260
|
pascal@24022
|
261 ;***************************************************************
|
pascal@24022
|
262
|
pascal@24023
|
263 org $-4 ; _himem_buf
|
pascal@24023
|
264
|
pascal@24022
|
265 ifdef BSS_OVERLAP_BOOT
|
pascal@24022
|
266 mov al,0
|
pascal@24022
|
267 mov di,100h
|
pascal@24022
|
268 mov cx,offset clean-100h
|
pascal@24022
|
269
|
pascal@24023
|
270 org $-(CMDNUMCNT*4) ; alloc_cmdnum
|
pascal@24022
|
271
|
pascal@24022
|
272 ifdef room_for_image
|
pascal@24023
|
273 org $-2-2-(2*size image_himem) ; alloc_image
|
pascal@24022
|
274 endif
|
pascal@24022
|
275
|
pascal@24022
|
276 ifdef room_for_isostate
|
pascal@24022
|
277 org $+ISOSTATE_OVERLAP-size isostate
|
pascal@24022
|
278 alloc_isostate
|
pascal@24022
|
279 endif
|
pascal@24022
|
280
|
pascal@24022
|
281 ifdef room_for_image
|
pascal@24022
|
282 alloc_image
|
pascal@24022
|
283 endif
|
pascal@24022
|
284
|
pascal@24023
|
285 alloc_cmdnum
|
pascal@24023
|
286 endif
|
pascal@24023
|
287
|
pascal@24023
|
288 global _himem_buf:dword
|
pascal@24023
|
289 _himem_buf dd ?
|
pascal@24023
|
290
|
pascal@24023
|
291 ifdef BSS_OVERLAP_BOOT
|
pascal@24022
|
292 clean:
|
pascal@24022
|
293 rep
|
pascal@24022
|
294 stosb
|
pascal@24022
|
295 endif
|
pascal@24022
|
296
|
pascal@24022
|
297 ;***************************************************************
|
pascal@24022
|
298 extrn _bss_end:word
|
pascal@24022
|
299 mov di,offset _bss_end
|
pascal@24022
|
300 global _heap_top
|
pascal@24022
|
301 org $-2
|
pascal@24022
|
302 _heap_top dw ?
|
pascal@23996
|
303 ;xor dx,dx
|
pascal@23996
|
304 ;push dx ; envp (already cleared)
|
pascal@23996
|
305 ;mov [word di],dx ; argv[0] = 0 (idem)
|
pascal@19515
|
306 argbuild:
|
pascal@19515
|
307 mov bx,2 ; argc * 2
|
pascal@19515
|
308 argeos:
|
pascal@20451
|
309 mov cx,1 ; look for a start of string
|
pascal@19515
|
310 mov [byte si-1],bh ; mark eos
|
pascal@19515
|
311 mov ah,20h ; space will be eos
|
pascal@19515
|
312 arglp:
|
pascal@19515
|
313 lodsb
|
pascal@19515
|
314 cmp al,0h
|
pascal@19515
|
315 je argdone
|
pascal@19515
|
316 cmp al,20h
|
pascal@19515
|
317 jb argeos
|
pascal@19515
|
318 cmp al,ah
|
pascal@19515
|
319 je argeos
|
pascal@19515
|
320 cmp al,27h
|
pascal@19515
|
321 je isargstr
|
pascal@19515
|
322 cmp al,22h
|
pascal@19515
|
323 je isargstr
|
pascal@20451
|
324 jcxz arglp ; not start of string
|
pascal@19515
|
325 dec si
|
pascal@19884
|
326 ;jmp newarg
|
pascal@20451
|
327 db 0BAh ; mov dx,im opcode
|
pascal@19515
|
328 isargstr:
|
pascal@19515
|
329 mov ah,al ; expected eos
|
pascal@19515
|
330 newarg:
|
pascal@19515
|
331 mov [word bx+di],si ; argv[argc++] = si
|
pascal@19515
|
332 inc bx
|
pascal@19515
|
333 inc bx
|
pascal@20451
|
334 dec cx
|
pascal@19515
|
335 jmp arglp
|
pascal@23992
|
336
|
pascal@23992
|
337 ;***************************************************************
|
pascal@23992
|
338 ;_fastcall void set_cmdline(bx:const char *filename);
|
pascal@23992
|
339 ;***************************************************************
|
pascal@23992
|
340 global @set_cmdline$qpxzc:near
|
pascal@23992
|
341 proc @set_cmdline$qpxzc near
|
pascal@23992
|
342 extrn openargs:near
|
pascal@23992
|
343 call openargs
|
pascal@23992
|
344 jc @ret
|
pascal@23992
|
345 mov ch,15 ; cx<4096
|
pascal@23992
|
346 mov di,[_heap_top]
|
pascal@23992
|
347 jmp read_cmdline ; read_cmdline(ax,di,cx)
|
pascal@23992
|
348
|
pascal@23992
|
349 endp @set_cmdline$qpxzc
|
pascal@23992
|
350
|
pascal@23992
|
351 ifdef NO386
|
pascal@23992
|
352 ;***************************************************************
|
pascal@23992
|
353 ;u16 topseg();
|
pascal@23992
|
354 ;***************************************************************
|
pascal@23992
|
355 global _topseg:near
|
pascal@23992
|
356 proc _topseg near
|
pascal@23992
|
357
|
pascal@23992
|
358 int 12h
|
pascal@23992
|
359 jnc @@max640k
|
pascal@23992
|
360 mov ax,640 ; 9000
|
pascal@23992
|
361 @@max640k:
|
pascal@23992
|
362 dec ax
|
pascal@23992
|
363 and al,0C0h
|
pascal@23992
|
364 mov cl,6
|
pascal@23992
|
365 shl ax,cl
|
pascal@23992
|
366 @ret:
|
pascal@23992
|
367 ret
|
pascal@23992
|
368
|
pascal@23992
|
369 endp _topseg
|
pascal@24019
|
370 else
|
pascal@24019
|
371 @ret:
|
pascal@24019
|
372 ret
|
pascal@23992
|
373 endif
|
pascal@23992
|
374
|
pascal@24013
|
375 ;***************************************************************
|
pascal@24013
|
376 argdone:
|
pascal@24013
|
377 ;mov [word bx+di],0 ; argv[argc] = 0
|
pascal@24013
|
378 lea ax,[bx+di+2]
|
pascal@24013
|
379 mov [_heap_top],ax
|
pascal@24013
|
380 ;push di ; argv
|
pascal@24013
|
381 ;shr bx,1
|
pascal@24013
|
382 ;push bx ; argc
|
pascal@24013
|
383 ifndef filearg
|
pascal@24013
|
384 mov bx,[di+2] ; argv[1]
|
pascal@24013
|
385 extrn openargs:near
|
pascal@24013
|
386 call near openargs
|
pascal@24013
|
387 jc argend
|
pascal@24013
|
388 ;pop bx ; trash argc, argv >> 1Kb !
|
pascal@24013
|
389 ;pop cx ; sizemax=argv
|
pascal@24013
|
390 dec cx ; sizemax=0ffffh
|
pascal@24013
|
391 read_cmdline:
|
pascal@24013
|
392 mov dx,di
|
pascal@24013
|
393 push dx
|
pascal@24013
|
394 xchg ax,bx
|
pascal@24013
|
395 extrn @read$cxdxbx:near ; read(fd=bx,buffer=dx,size=cx)
|
pascal@24013
|
396 call near @read$cxdxbx
|
pascal@24013
|
397 pop si ; si=buffer=argv
|
pascal@24013
|
398 add di,ax
|
pascal@24013
|
399 ifndef NO_CLOSE
|
pascal@24013
|
400 extrn close:near
|
pascal@24013
|
401 call near close
|
pascal@24013
|
402 endif
|
pascal@24013
|
403 jmp argbuild
|
pascal@24013
|
404 argend:
|
pascal@24013
|
405 endif
|
pascal@24013
|
406
|
pascal@24013
|
407 ;***************************************************************
|
pascal@24013
|
408 ; extrn _main:near
|
pascal@24013
|
409 ; call _main
|
pascal@24013
|
410 ;never return
|
pascal@24013
|
411
|
pascal@24013
|
412 ;***************************************************************
|
pascal@24013
|
413
|
pascal@24013
|
414
|
pascal@19515
|
415 ends _TEXT
|
pascal@19515
|
416
|
pascal@19515
|
417
|
pascal@19515
|
418 end _text_start
|
pascal@19515
|
419
|
pascal@19515
|
420 ;###### END OF FILE ############################################
|