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