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