rev |
line source |
pascal@19515
|
1 ;***************************************************************
|
pascal@19515
|
2 ;****** This file is distributed under GPL
|
pascal@19515
|
3 ;***************************************************************
|
pascal@19515
|
4 ideal
|
pascal@19515
|
5 %crefref
|
pascal@19515
|
6 %noincl
|
pascal@19515
|
7 %nomacs
|
pascal@19636
|
8 p8086
|
pascal@19515
|
9
|
pascal@19515
|
10 group DGROUP _TEXT,_DATA,_BSS
|
pascal@19515
|
11 assume cs:DGROUP,ds:DGROUP
|
pascal@19515
|
12
|
pascal@19515
|
13 segment _TEXT byte public use16 'CODE'
|
pascal@19515
|
14
|
pascal@19825
|
15 macro cpuid
|
pascal@19825
|
16 db 0fh,0A2h
|
pascal@19825
|
17 endm
|
pascal@19825
|
18
|
pascal@19515
|
19 org 100h
|
pascal@19515
|
20 global _text_start:byte
|
pascal@19515
|
21 label _text_start byte
|
pascal@19546
|
22
|
pascal@19515
|
23 ;***************************************************************
|
pascal@19515
|
24 ; clear bss
|
pascal@19515
|
25 ;***************************************************************
|
pascal@20426
|
26 mov si,offset _bss_start
|
pascal@19515
|
27 clearbss:
|
pascal@20426
|
28 mov [byte si],0 ; clear bss + heap + sp
|
pascal@20426
|
29 inc si
|
pascal@19546
|
30 jne clearbss
|
pascal@19571
|
31 cld
|
pascal@19546
|
32
|
pascal@19546
|
33 ;***************************************************************
|
pascal@19546
|
34 ; check CPU
|
pascal@19546
|
35 ;***************************************************************
|
pascal@19546
|
36
|
pascal@19546
|
37 ; Check for oldies
|
pascal@19873
|
38 ifndef EXTRA
|
pascal@19848
|
39 push sp
|
pascal@19848
|
40 pop ax
|
pascal@19873
|
41 sub ax,sp
|
pascal@19873
|
42 ifndef NO386
|
pascal@19571
|
43 mov bx,offset msg_badcpu
|
pascal@19848
|
44 jnz no_vcpi ;it is a 86/186 not a 286+
|
pascal@19873
|
45 else
|
pascal@19873
|
46 jnz endcpu ;it is a 86/186 not a 286+
|
pascal@19873
|
47 endif
|
pascal@19546
|
48 else
|
pascal@19873
|
49 pushf
|
pascal@19873
|
50 mov bh, 0F0h
|
pascal@19873
|
51 push bx ; < 286 : flags[12..15] are forced 1
|
pascal@19873
|
52 popf ; = 286 : flags[12..15] are forced 0
|
pascal@19873
|
53 pushf ; > 286 : only flags[15] is forced 0
|
pascal@19873
|
54 pop dx
|
pascal@19873
|
55 popf
|
pascal@19873
|
56 add dh,bh ; NS=386+, NC=286
|
pascal@19873
|
57 ifndef NO386
|
pascal@19873
|
58 mov bx,offset msg_badcpu
|
pascal@19874
|
59 js no_vcpi ;it is not a 386+
|
pascal@19873
|
60 else
|
pascal@19874
|
61 js endcpu ;it is not a 386+
|
pascal@19873
|
62 endif
|
pascal@19546
|
63 endif
|
pascal@19636
|
64 p386
|
pascal@19825
|
65 ifdef EXTRA
|
pascal@19825
|
66 pushfd
|
pascal@19825
|
67 pop dx
|
pascal@19825
|
68 pop ax
|
pascal@19825
|
69 mov bl,al
|
pascal@19825
|
70 xor al,20h ; toggle CPUID feature bit 21
|
pascal@19825
|
71 push ax
|
pascal@19825
|
72 push dx
|
pascal@19825
|
73 popfd
|
pascal@19825
|
74 pushfd
|
pascal@19825
|
75 pop dx
|
pascal@19825
|
76 pop ax
|
pascal@19825
|
77 xor al,bl ; clear C
|
pascal@19825
|
78 je @@check_vm ; CPUID feature bit changed ?
|
pascal@19825
|
79 mov eax,80000001h ; Extended Processor Info and Feature Bits
|
pascal@19825
|
80 cpuid
|
pascal@19825
|
81 mov [_cpu_features],edx
|
pascal@19825
|
82 @@check_vm:
|
pascal@19825
|
83 endif
|
pascal@19546
|
84 ; Check for vm
|
pascal@19546
|
85 smsw ax ;SMSW cannot be trapped! :-)
|
pascal@19571
|
86 and al,1 ;MSW_PE
|
pascal@19546
|
87 ; We're in vm
|
pascal@19571
|
88 jz check_rm_paging
|
pascal@19546
|
89
|
pascal@19546
|
90 ;***************************************************************
|
pascal@19546
|
91 ; checks for vcpi
|
pascal@19546
|
92 ;***************************************************************
|
pascal@19546
|
93 label check_vcpi near
|
pascal@19546
|
94 push ds
|
pascal@19546
|
95 ; Check whether it is safe to call 67h (we trust only known EMM managers)
|
pascal@20426
|
96 push si
|
pascal@19546
|
97 pop ds
|
pascal@19546
|
98 mov ds,[word 67h*4+2]
|
pascal@20426
|
99 cmp [dword si+10+4],'0XXX'
|
pascal@19546
|
100 jne skip
|
pascal@19825
|
101 ;mov eax,'XMME'
|
pascal@20426
|
102 ;xor eax,[dword si+10]
|
pascal@19546
|
103 ; QMME also works (as told by <J.S.Peatfield@damtp.cambridge.ac.uk>)
|
pascal@19825
|
104 ;shl eax,8
|
pascal@19825
|
105 mov ax,'ME'
|
pascal@20426
|
106 xor ax,[word si+10]
|
pascal@19546
|
107 skip:
|
pascal@19546
|
108 pop ds
|
pascal@19546
|
109 jne no_vcpi
|
pascal@19546
|
110
|
pascal@19546
|
111 ; Check emm manager status and version
|
pascal@19571
|
112 ;mov ah,40h ; get status
|
pascal@19571
|
113 ;int 67h
|
pascal@19571
|
114 ;test ah,ah
|
pascal@19571
|
115 ;jnz no_vcpi
|
pascal@19546
|
116 mov ah,46h ; get version
|
pascal@19546
|
117 int 67h
|
pascal@19546
|
118 test ah,ah
|
pascal@19546
|
119 jnz no_vcpi
|
pascal@19546
|
120 cmp al,40h ; version must be >= 4.0
|
pascal@19546
|
121 jb no_vcpi
|
pascal@19546
|
122 ; Check vcpi manager status
|
pascal@19546
|
123 ;;mov ax,5A01h ; ALLOCATE RAW PAGES
|
pascal@19546
|
124 ;;mov bx,4
|
pascal@19546
|
125 ;;int 67h
|
pascal@19546
|
126 ;;test ah,ah
|
pascal@19546
|
127 ;;jnz no_vcpi
|
pascal@19546
|
128 ;;push dx ;$ save handle
|
pascal@19546
|
129 mov ax,0DE00h ; check for vcpi present
|
pascal@19546
|
130 int 67h
|
pascal@19546
|
131 test ah,ah
|
pascal@19571
|
132 jnz no_vcpi
|
pascal@19546
|
133 is386vcpi:
|
pascal@19571
|
134 inc [_vcpi]
|
pascal@19546
|
135 extrn prepare_vcpi:near
|
pascal@19546
|
136 call prepare_vcpi
|
pascal@19546
|
137 ; get_vcpi_interface() || die("VCPI: low 640k: need 1:1 mapping");
|
pascal@19546
|
138 ;extrn _get_vcpi_interface:near
|
pascal@19546
|
139 ;call _get_vcpi_interface
|
pascal@19546
|
140 mov bx,offset msg_badmapping
|
pascal@19634
|
141 jz endcpu
|
pascal@19571
|
142 no_vcpi:
|
pascal@19636
|
143 p8086
|
pascal@19571
|
144 ;;pop dx ;$ handle
|
pascal@19571
|
145 ;;mov ax,4500h ; DEALLOCATE PAGES
|
pascal@19571
|
146 ;;int 67h
|
pascal@19571
|
147 extrn die:near
|
pascal@19571
|
148 godie:
|
pascal@20427
|
149 call near die
|
pascal@19571
|
150 check_rm_paging:
|
pascal@19571
|
151 ; It's a 386 in real mode, chk for paging (crazy but possible)
|
pascal@19636
|
152 p386
|
pascal@20142
|
153 mov eax,cr0
|
pascal@20142
|
154 inc eax ;CR0_PG to S
|
pascal@20142
|
155 js no_vcpi
|
pascal@19546
|
156 endcpu:
|
pascal@19636
|
157 p8086
|
pascal@19546
|
158
|
pascal@19515
|
159 ;***************************************************************
|
pascal@19515
|
160 ; build argv & argc
|
pascal@19515
|
161 ;***************************************************************
|
pascal@19546
|
162 extrn _heap_top:word
|
pascal@19546
|
163 mov di,[_heap_top]
|
pascal@19546
|
164 ;xor ax,ax
|
pascal@19546
|
165 ;push ax ; envp (already cleared)
|
pascal@19546
|
166 ;mov [word di],ax ; argv[0] = 0 (idem)
|
pascal@19515
|
167 mov si,80h
|
pascal@19515
|
168 lodsb
|
pascal@19515
|
169 cmp al,7Eh
|
pascal@19515
|
170 jbe alok
|
pascal@19515
|
171 mov al,7Eh
|
pascal@19515
|
172 alok:
|
pascal@19546
|
173 cbw
|
pascal@19515
|
174 xchg ax,bx
|
pascal@19515
|
175 mov [bx+si],bh ; set eos
|
pascal@19515
|
176 argbuild:
|
pascal@20160
|
177 ifdef DEBUG
|
pascal@20142
|
178 p386
|
pascal@20142
|
179 pusha
|
pascal@20142
|
180 mov bx,si
|
pascal@20142
|
181 extrn puts:near
|
pascal@20142
|
182 call puts
|
pascal@20142
|
183 popa
|
pascal@20160
|
184 endif
|
pascal@19515
|
185 mov bx,2 ; argc * 2
|
pascal@19515
|
186 argeos:
|
pascal@19515
|
187 mov dl,1 ; look for a start of string
|
pascal@19515
|
188 mov [byte si-1],bh ; mark eos
|
pascal@19515
|
189 mov ah,20h ; space will be eos
|
pascal@19515
|
190 arglp:
|
pascal@19515
|
191 lodsb
|
pascal@19515
|
192 cmp al,0h
|
pascal@19515
|
193 je argdone
|
pascal@19515
|
194 cmp al,20h
|
pascal@19515
|
195 jb argeos
|
pascal@19515
|
196 cmp al,ah
|
pascal@19515
|
197 je argeos
|
pascal@19515
|
198 cmp al,27h
|
pascal@19515
|
199 je isargstr
|
pascal@19515
|
200 cmp al,22h
|
pascal@19515
|
201 je isargstr
|
pascal@19515
|
202 or dl,dl
|
pascal@19515
|
203 je arglp ; not start of string
|
pascal@19515
|
204 dec si
|
pascal@19884
|
205 ;jmp newarg
|
pascal@19884
|
206 db 0B9h ; mov cx,im opcode
|
pascal@19515
|
207 isargstr:
|
pascal@19515
|
208 mov ah,al ; expected eos
|
pascal@19515
|
209 newarg:
|
pascal@19515
|
210 mov [word bx+di],si ; argv[argc++] = si
|
pascal@19515
|
211 inc bx
|
pascal@19515
|
212 inc bx
|
pascal@19515
|
213 dec dx
|
pascal@19515
|
214 jmp arglp
|
pascal@19515
|
215 argdone:
|
pascal@19515
|
216 ;mov [word bx+di],0 ; argv[argc] = 0
|
pascal@19546
|
217 lea ax,[bx+di+2]
|
pascal@19546
|
218 mov [_heap_top],ax
|
pascal@19515
|
219 push di ; argv
|
pascal@19515
|
220 shr bx,1
|
pascal@19515
|
221 push bx ; argc
|
pascal@19515
|
222 ifndef filearg
|
pascal@19515
|
223 mov bx,[di+2] ; argv[1]
|
pascal@19515
|
224 cmp [byte bx],'@'
|
pascal@19515
|
225 jne argend
|
pascal@19546
|
226 inc bx
|
pascal@19515
|
227 extrn open:near
|
pascal@19515
|
228 call near open
|
pascal@19515
|
229 jc argend
|
pascal@19515
|
230 pop bx ; trash argc, argv >> 1Kb !
|
pascal@19546
|
231 global read_cmdline:near
|
pascal@19546
|
232 read_cmdline:
|
pascal@19515
|
233 push di
|
pascal@19515
|
234 push ax
|
pascal@19515
|
235 extrn _read:near
|
pascal@19515
|
236 call near _read
|
pascal@19515
|
237 pop bx ; fd for close
|
pascal@19515
|
238 pop si ; si=buffer=argv
|
pascal@19515
|
239 add di,ax
|
pascal@19515
|
240 pop ax ; trash sizemax=argv
|
pascal@19515
|
241 extrn close:near
|
pascal@19515
|
242 call near close
|
pascal@19515
|
243 jmp argbuild
|
pascal@19515
|
244 argend:
|
pascal@19515
|
245 endif
|
pascal@19515
|
246
|
pascal@19515
|
247 ;***************************************************************
|
pascal@19515
|
248 extrn _main:near
|
pascal@19515
|
249 call _main
|
pascal@19538
|
250
|
pascal@19515
|
251 ;***************************************************************
|
pascal@19515
|
252 global exit:near
|
pascal@19515
|
253 exit:
|
pascal@19515
|
254 mov ah,4Ch
|
pascal@19515
|
255 int 21h
|
pascal@19515
|
256 ends _TEXT
|
pascal@19515
|
257
|
pascal@19515
|
258 segment _DATA byte public use16 'DATA'
|
pascal@19515
|
259 global _data_start:byte
|
pascal@19515
|
260 label _data_start byte
|
pascal@19873
|
261 ifndef NO386
|
pascal@19546
|
262 msg_badcpu db "I need 386+ CPU in real mode or under VCPI manager"
|
pascal@19873
|
263 endif
|
pascal@19546
|
264 global _vcpi:byte
|
pascal@19546
|
265 _vcpi db 0
|
pascal@19546
|
266 msg_badmapping db "VCPI: low 640k: need 1:1 mapping",0
|
pascal@19546
|
267
|
pascal@19515
|
268 ends _DATA
|
pascal@19515
|
269
|
pascal@19515
|
270 segment _BSS byte public use16 'BSS'
|
pascal@19515
|
271 global _bss_start:byte
|
pascal@19515
|
272 label _bss_start byte
|
pascal@19825
|
273 ifdef EXTRA
|
pascal@19825
|
274 global _cpu_features:dword
|
pascal@19825
|
275 _cpu_features dd ?
|
pascal@19825
|
276 endif
|
pascal@19515
|
277 ends _BSS
|
pascal@19515
|
278
|
pascal@19515
|
279 end _text_start
|
pascal@19515
|
280
|
pascal@19515
|
281 ;###### END OF FILE ############################################
|