rev |
line source |
pascal@13691
|
1 #include <stdio.h>
|
pascal@17160
|
2 #include "libdos.h"
|
pascal@13691
|
3 #include "iso9660.h"
|
pascal@17473
|
4 #asm
|
pascal@17473
|
5 use16 86
|
pascal@17473
|
6 #endasm
|
pascal@13691
|
7
|
pascal@17160
|
8 #define ELKSSIG 0x1E6
|
pascal@13691
|
9 #define SETUPSECTORS 0x1F1
|
pascal@13691
|
10 #define ROFLAG 0x1F2
|
pascal@13691
|
11 #define SYSSIZE 0x1F4
|
pascal@13691
|
12 #define VIDEOMODE 0x1FA
|
pascal@13691
|
13 #define BOOTFLAG 0x1FE
|
pascal@13691
|
14 #define HEADER 0x202
|
pascal@13691
|
15 #define VERSION 0x206
|
pascal@13691
|
16 #define RMSWOFS 0x208
|
pascal@13691
|
17 #define RMSWSEG 0x20A
|
pascal@13691
|
18 #define LOADERTYPE 0x210
|
pascal@13691
|
19 #define LOADFLAGS 0x211
|
pascal@13691
|
20 #define SYSTEMCODE 0x214
|
pascal@13691
|
21 #define INITRDCODE 0x218
|
pascal@13691
|
22 #define INITRDSIZE 0x21C
|
pascal@13691
|
23 #define HEAPPTR 0x224
|
pascal@13691
|
24 #define CMDLINE 0x228
|
pascal@13691
|
25
|
pascal@16069
|
26 #define SYSTEM_SEGMENT 0x1000
|
pascal@13691
|
27 #define SETUP_SEGMENT 0x9000
|
pascal@13691
|
28 #define CMDLINE_OFFSET 0x9E00
|
pascal@16069
|
29 #define SETUP_END 0x8200
|
pascal@13691
|
30
|
pascal@13733
|
31 #define PAGE_BITS 12
|
pascal@13733
|
32 #define PAGE_SIZE 4096
|
pascal@16025
|
33 #define BUFFERSZ 2048 // lower than min setup
|
pascal@13691
|
34 static char buffer[BUFFERSZ];
|
pascal@16022
|
35 static unsigned long initrd_addr = 0, initrd_size;
|
pascal@13691
|
36
|
pascal@13691
|
37 static int may_exit_dos = 1;
|
pascal@13691
|
38 static void die(char *msg)
|
pascal@13691
|
39 {
|
pascal@13691
|
40 printf("%s.\n", msg);
|
pascal@13691
|
41 if (may_exit_dos)
|
pascal@13691
|
42 exit(1);
|
pascal@13691
|
43 while (1);
|
pascal@13691
|
44 }
|
pascal@13691
|
45
|
pascal@17160
|
46 static int iselks;
|
pascal@13691
|
47 static int vm86(void)
|
pascal@13691
|
48 {
|
pascal@13691
|
49 #asm
|
pascal@17450
|
50 mov ax, _iselks
|
pascal@17450
|
51 dec ax
|
pascal@17450
|
52 je fakerealmode // elks may run on a 8086
|
pascal@17473
|
53 use16 286
|
pascal@17160
|
54 smsw ax // 286+
|
pascal@13691
|
55 and ax, #1 // 0:realmode 1:vm86
|
pascal@17473
|
56 use16 86
|
pascal@17160
|
57 fakerealmode:
|
pascal@13691
|
58 #endasm
|
pascal@13691
|
59 }
|
pascal@13691
|
60
|
pascal@16022
|
61 static struct {
|
pascal@13691
|
62 unsigned long base;
|
pascal@13691
|
63 int align;
|
pascal@16022
|
64 } mem = { 0x100000, 0 };
|
pascal@13691
|
65
|
pascal@17450
|
66 #ifdef __MSDOS__
|
pascal@17450
|
67 #define A20HOLDBUFFER 0x80000
|
pascal@17450
|
68 static int a20buffer = 0;
|
pascal@17450
|
69 #endif
|
pascal@17450
|
70
|
pascal@13691
|
71 static void movehi(void)
|
pascal@13691
|
72 {
|
pascal@13691
|
73 #asm
|
pascal@17160
|
74 push si
|
pascal@17160
|
75 push di
|
pascal@17160
|
76
|
pascal@17450
|
77 xor ax, ax
|
pascal@17160
|
78 mov si, #_mem
|
pascal@17160
|
79 cmp word ptr [si+2], #0x10
|
pascal@17450
|
80 #ifdef __MSDOS__
|
pascal@17450
|
81 jne nota20
|
pascal@17450
|
82 mov ax, #A20HOLDBUFFER/16
|
pascal@17450
|
83 mov _a20buffer, ax
|
pascal@17450
|
84 mov di, [si] // mem.base & 0xFFFF
|
pascal@17450
|
85 jmp mvbuffer
|
pascal@17450
|
86 nota20:
|
pascal@17450
|
87 #endif
|
pascal@17160
|
88 jnc movehiz
|
pascal@17450
|
89 lodsb
|
pascal@17450
|
90 xchg ax, di
|
pascal@17450
|
91 lodsw
|
pascal@17160
|
92 mov cl, #4
|
pascal@17160
|
93 shl ax, cl // 8086 support for elks
|
pascal@17450
|
94 mvbuffer:
|
pascal@17160
|
95 mov es, ax
|
pascal@17160
|
96 mov si, #_buffer
|
pascal@17450
|
97 cld
|
pascal@17160
|
98 mov cx, #BUFFERSZ/2
|
pascal@17160
|
99 rep
|
pascal@17160
|
100 movw
|
pascal@17160
|
101 jmp movedone
|
pascal@17450
|
102 movehiz: // 30
|
pascal@17473
|
103 use16 286 // more than 1Mb => 286+
|
pascal@13691
|
104 mov cx, #9 // 2E..1E
|
pascal@13691
|
105 zero1:
|
pascal@17450
|
106 push ax
|
pascal@13691
|
107 loop zero1
|
pascal@17473
|
108 push word [si+2]
|
pascal@17473
|
109 push word [si] // 1A mem.base
|
pascal@13691
|
110 push #-1 // 18
|
pascal@17450
|
111 push ax // 16
|
pascal@17473
|
112 mov ax, ds
|
pascal@17473
|
113 mov dx, ax
|
pascal@17473
|
114 shl ax, #4
|
pascal@17473
|
115 shr dx, #12
|
pascal@17473
|
116 add ax, #_buffer
|
pascal@17473
|
117 adc dx, #0
|
pascal@17473
|
118 push dx
|
pascal@17473
|
119 push ax
|
pascal@13691
|
120 push #-1 // 10
|
pascal@13691
|
121 mov cl, #8 // 0E..00
|
pascal@13691
|
122 zero2:
|
pascal@17450
|
123 push #0
|
pascal@13691
|
124 loop zero2
|
pascal@13691
|
125 mov ch, #BUFFERSZ/512
|
pascal@13691
|
126 push ss
|
pascal@13691
|
127 pop es
|
pascal@13691
|
128 mov si, sp
|
pascal@13691
|
129 mov ax, #0x8793
|
pascal@13691
|
130 mov [si+0x15], al
|
pascal@13691
|
131 xchg [si+0x1D], al
|
pascal@16008
|
132 xchg [si+0x1F], al // bits 24..31
|
pascal@13691
|
133 int 0x15
|
pascal@13691
|
134 add sp, #0x30
|
pascal@17473
|
135 use16 86
|
pascal@17160
|
136 movedone:
|
pascal@17160
|
137 pop di
|
pascal@17160
|
138 pop si
|
pascal@13691
|
139 #endasm
|
pascal@13691
|
140 }
|
pascal@13691
|
141
|
pascal@17489
|
142 static unsigned vgamode, zimage = 0;
|
pascal@16022
|
143 static unsigned getss(void)
|
pascal@16022
|
144 {
|
pascal@16022
|
145 #asm
|
pascal@16022
|
146 mov ax, ss
|
pascal@16022
|
147 #endasm
|
pascal@16022
|
148 }
|
pascal@13699
|
149
|
pascal@15981
|
150 static unsigned extendedramsizeinkb(void)
|
pascal@15981
|
151 {
|
pascal@15981
|
152 #asm
|
pascal@15981
|
153 mov ah, #0x88
|
pascal@15981
|
154 int 0x15
|
pascal@15981
|
155 jnc gottop
|
pascal@15981
|
156 xor ax, ax
|
pascal@15981
|
157 gottop:
|
pascal@15981
|
158 #endasm
|
pascal@15981
|
159 }
|
pascal@15981
|
160
|
pascal@16069
|
161
|
pascal@16069
|
162 #include "a20.c"
|
pascal@16069
|
163
|
pascal@16022
|
164 static void load(unsigned long size)
|
pascal@13691
|
165 {
|
pascal@13691
|
166 if (vm86())
|
pascal@13691
|
167 die("Need real mode");
|
pascal@16022
|
168 switch (mem.align) {
|
pascal@13691
|
169 case 0: // kernel
|
pascal@17160
|
170 #ifdef __MSDOS__
|
pascal@16069
|
171 if ((unsigned) (dosversion() - 3) > 7 - 3) {
|
pascal@13699
|
172 printf("DOS %d not supported.\nTrying anyway...\n",
|
pascal@13699
|
173 versiondos);
|
pascal@13699
|
174 }
|
pascal@17160
|
175 #endif
|
pascal@16022
|
176 mem.align = PAGE_SIZE;
|
pascal@13691
|
177 break;
|
pascal@16008
|
178 case PAGE_SIZE: // first initrd : keep 16M..48M for the kernel
|
pascal@16022
|
179 if (extendedramsizeinkb() > 0xF000U && mem.base < 0x3000000)
|
pascal@16022
|
180 mem.base = 0x3000000;
|
pascal@16022
|
181 initrd_addr = mem.base;
|
pascal@16022
|
182 mem.align = 4;
|
pascal@13691
|
183 }
|
pascal@16069
|
184 #ifdef ALLOCMEM
|
pascal@16069
|
185 ALLOCMEM(size);
|
pascal@16069
|
186 #endif
|
pascal@13691
|
187 while (size) {
|
pascal@13691
|
188 int n, s = sizeof(buffer);
|
pascal@13691
|
189 for (n = 0; n < s; n++) buffer[n] = 0;
|
pascal@13691
|
190 if (s > size) s = size;
|
pascal@16022
|
191 if ((n = isoread(buffer, s)) < 0) break;
|
pascal@13691
|
192 movehi();
|
pascal@16022
|
193 mem.base += n;
|
pascal@16022
|
194 size -= n;
|
pascal@16022
|
195 if (s != n) break; // end of file
|
pascal@13691
|
196 }
|
pascal@16022
|
197 initrd_size = mem.base - initrd_addr;
|
pascal@16022
|
198 mem.base += mem.align - 1;
|
pascal@16022
|
199 mem.base &= - mem.align;
|
pascal@13691
|
200 }
|
pascal@13691
|
201
|
pascal@17160
|
202 static unsigned setupseg = SETUP_SEGMENT;
|
pascal@13691
|
203 static unsigned setupofs = 0;
|
pascal@13691
|
204
|
pascal@13691
|
205 void movesetup(void)
|
pascal@13691
|
206 {
|
pascal@13691
|
207 #asm
|
pascal@17160
|
208 push si
|
pascal@17160
|
209 mov es, _setupseg
|
pascal@17450
|
210 xchg di, _setupofs
|
pascal@13691
|
211 mov si, #_buffer
|
pascal@17450
|
212 cld
|
pascal@13691
|
213 mov cx, #BUFFERSZ/2
|
pascal@13691
|
214 rep
|
pascal@13691
|
215 movsw
|
pascal@17450
|
216 xchg di, _setupofs
|
pascal@17160
|
217 pop si
|
pascal@13691
|
218 #endasm
|
pascal@13691
|
219 }
|
pascal@13691
|
220
|
pascal@14257
|
221 static unsigned getcs(void)
|
pascal@14257
|
222 {
|
pascal@14257
|
223 #asm
|
pascal@14257
|
224 mov ax, cs
|
pascal@14257
|
225 #endasm
|
pascal@14257
|
226 }
|
pascal@14257
|
227
|
pascal@17450
|
228 #define WORD(x) * (unsigned short *) (x)
|
pascal@17450
|
229 #define LONG(x) * (unsigned long *) (x)
|
pascal@17450
|
230 static unsigned setup_version = 0;
|
pascal@17160
|
231 static unsigned long kernel_version = 0;
|
pascal@14257
|
232 unsigned long loadkernel(void)
|
pascal@13691
|
233 {
|
pascal@17450
|
234 unsigned setup;
|
pascal@17450
|
235 #define LINUX001_SUPPORT
|
pascal@17450
|
236 #ifdef LINUX001_SUPPORT
|
pascal@17450
|
237 unsigned n = 512;
|
pascal@17450
|
238 #else
|
pascal@17450
|
239 unsigned n = BUFFERSZ;
|
pascal@17450
|
240 #endif
|
pascal@17160
|
241 unsigned long syssize = 0;
|
pascal@13691
|
242
|
pascal@13691
|
243 do {
|
pascal@13691
|
244 isoread(buffer, n);
|
pascal@13691
|
245 if (setupofs == 0) {
|
pascal@17450
|
246 if (WORD(buffer + BOOTFLAG) != 0xAA55)
|
pascal@13691
|
247 die("The kernel is not bootable");
|
pascal@17160
|
248 #asm
|
pascal@17160
|
249 int 0x12
|
pascal@17160
|
250 jc has640k
|
pascal@17160
|
251 dec ax
|
pascal@17160
|
252 and al, #0xC0
|
pascal@17160
|
253 mov cl, #6
|
pascal@17160
|
254 shl ax, cl
|
pascal@17160
|
255 cmp ax, _setupseg
|
pascal@17160
|
256 jnc has640k
|
pascal@17160
|
257 mov _setupseg, ax
|
pascal@17160
|
258 has640k:
|
pascal@17160
|
259 #endasm
|
pascal@17450
|
260 syssize = LONG(buffer + SYSSIZE) << 4;
|
pascal@17450
|
261 if (!syssize) syssize = 0x7F000;
|
pascal@13691
|
262 setup = (1 + buffer[SETUPSECTORS]) << 9;
|
pascal@17489
|
263 vgamode = WORD(buffer + VIDEOMODE);
|
pascal@17450
|
264 if (setup == 512) {
|
pascal@17450
|
265 #ifdef LINUX001_SUPPORT
|
pascal@17450
|
266 if (WORD(buffer + 0x3F) == 0x3AE8) /* linux 0.01 */
|
pascal@17450
|
267 goto linux001;
|
pascal@17450
|
268 #endif
|
pascal@17450
|
269 setup = 5 << 9;
|
pascal@17450
|
270 }
|
pascal@17450
|
271 #ifdef LINUX001_SUPPORT
|
pascal@17450
|
272 n = BUFFERSZ;
|
pascal@17450
|
273 isoread(buffer+512, BUFFERSZ-512);
|
pascal@17450
|
274 #endif
|
pascal@13691
|
275 #define HDRS 0x53726448
|
pascal@17450
|
276 if (LONG(buffer + HEADER) == HDRS)
|
pascal@17450
|
277 setup_version = WORD(buffer + VERSION);
|
pascal@17160
|
278 #define ELKS 0x534B4C45
|
pascal@17450
|
279 if (LONG(buffer + ELKSSIG) == ELKS)
|
pascal@17160
|
280 iselks = 1;
|
pascal@16022
|
281 if (setup_version < 0x204)
|
pascal@13733
|
282 syssize &= 0x000FFFFFUL;
|
pascal@16022
|
283 if (setup_version) {
|
pascal@13733
|
284 #ifdef REALMODE_SWITCH
|
pascal@13733
|
285 extern int far_realmode_switch();
|
pascal@13733
|
286 #asm
|
pascal@13733
|
287 jmp end_realmode_switch
|
pascal@13733
|
288 _far_realmode_switch:
|
pascal@14257
|
289 call REALMODE_SWITCH
|
pascal@13733
|
290 cli
|
pascal@13733
|
291 mov al, #0x80 // Disable NMI
|
pascal@13733
|
292 out 0x70, al
|
pascal@13733
|
293 retf
|
pascal@13733
|
294 end_realmode_switch:
|
pascal@13733
|
295 #endasm
|
pascal@17450
|
296 WORD(buffer + RMSWOFS) = far_realmode_switch;
|
pascal@17450
|
297 WORD(buffer + RMSWSEG) = getcs();
|
pascal@13733
|
298 #endif
|
pascal@17450
|
299 mem.base = LONG(buffer + SYSTEMCODE);
|
pascal@17450
|
300 WORD(buffer + HEAPPTR) = 0x9B00;
|
pascal@13733
|
301 // buffer[LOADFLAGS] |= 0x80;
|
pascal@17450
|
302 WORD(buffer + LOADERTYPE) |= 0x80FF;
|
pascal@13733
|
303 }
|
pascal@17450
|
304 #ifdef LINUX001_SUPPORT
|
pascal@17450
|
305 linux001:
|
pascal@17450
|
306 #endif
|
pascal@16022
|
307 if (!setup_version || !(buffer[LOADFLAGS] & 1)) {
|
pascal@16041
|
308 zimage = getss() + 0x1000;
|
pascal@16041
|
309 mem.base = zimage * 16L;
|
pascal@17160
|
310 if (mem.base + syssize > setupseg*16L - 32) {
|
pascal@17450
|
311 zimage = 0x9311;
|
pascal@17160
|
312 mem.base = 0x110000L; // 1M + 64K HMA
|
pascal@17160
|
313 }
|
pascal@13691
|
314 }
|
pascal@13691
|
315 }
|
pascal@13691
|
316 movesetup();
|
pascal@13691
|
317 setup -= n;
|
pascal@13691
|
318 n = (setup > BUFFERSZ) ? BUFFERSZ : setup;
|
pascal@13691
|
319 } while (setup > 0);
|
pascal@13691
|
320
|
pascal@14257
|
321 #asm
|
pascal@17160
|
322 push si
|
pascal@17160
|
323 mov si, #0x200
|
pascal@17160
|
324 cmp si, _setup_version
|
pascal@17160
|
325 jae noversion
|
pascal@17450
|
326 mov es, _setupseg
|
pascal@17450
|
327 seg es
|
pascal@14257
|
328 add si, [si+14]
|
pascal@17450
|
329 mov bx, #2
|
pascal@17450
|
330 mov cl, #4
|
pascal@17450
|
331 nextnumber:
|
pascal@17450
|
332 xor ax, ax
|
pascal@14257
|
333 nextdigit:
|
pascal@17450
|
334 shl al, cl
|
pascal@17450
|
335 shl ax, cl
|
pascal@17450
|
336 seg es
|
pascal@14257
|
337 lodsb
|
pascal@14257
|
338 sub al, #0x30
|
pascal@14257
|
339 cmp al, #9
|
pascal@14257
|
340 jbe nextdigit
|
pascal@17450
|
341 mov [bx+_kernel_version], ah
|
pascal@17450
|
342 dec bx
|
pascal@17450
|
343 jns nextnumber
|
pascal@14257
|
344 noversion:
|
pascal@17160
|
345 pop si
|
pascal@14257
|
346 #endasm
|
pascal@16022
|
347 load(syssize);
|
pascal@14268
|
348 return kernel_version;
|
pascal@13691
|
349 }
|
pascal@13691
|
350
|
pascal@13691
|
351 void loadinitrd(void)
|
pascal@13691
|
352 {
|
pascal@17160
|
353 if (setup_version)
|
pascal@16022
|
354 load(isofilesize);
|
pascal@13691
|
355 }
|
pascal@13691
|
356
|
pascal@13691
|
357 void bootlinux(char *cmdline)
|
pascal@13691
|
358 {
|
pascal@17489
|
359 char *s;
|
pascal@17489
|
360
|
pascal@17489
|
361 s = strstr(cmdline," vga=");
|
pascal@17489
|
362 if (s) {
|
pascal@17489
|
363 vgamode = -1;
|
pascal@17489
|
364 s += 5;
|
pascal@17489
|
365 switch (*s | 0x20) {
|
pascal@17489
|
366 case 'a' : vgamode--;
|
pascal@17489
|
367 case 'e' : vgamode--;
|
pascal@17489
|
368 case 'n' : break;
|
pascal@17489
|
369 default : vgamode = atoi(s);
|
pascal@17489
|
370 }
|
pascal@17489
|
371 }
|
pascal@17160
|
372 dosshutdown();
|
pascal@13691
|
373 #asm
|
pascal@17450
|
374 cld
|
pascal@17160
|
375 mov es, _setupseg
|
pascal@17489
|
376 mov ax, _vgamode
|
pascal@17489
|
377 seg es
|
pascal@17489
|
378 mov VIDEOMODE, ax
|
pascal@17450
|
379 mov ax, _setup_version
|
pascal@17450
|
380 cmp ax, #0x200
|
pascal@17450
|
381 jb noinitrd
|
pascal@17450
|
382 mov di, #0x218
|
pascal@17450
|
383 mov si, #_initrd_addr
|
pascal@17450
|
384 movsw
|
pascal@17450
|
385 movsw
|
pascal@17450
|
386 mov si, #_initrd_size
|
pascal@17450
|
387 movsw
|
pascal@17450
|
388 movsw
|
pascal@17450
|
389 noinitrd:
|
pascal@17460
|
390 mov si, [bp+4] // .bootlinux.cmdline[bp]
|
pascal@17450
|
391 or si, si
|
pascal@17450
|
392 jz nocmdline
|
pascal@17450
|
393 cmp ax, #0x201
|
pascal@13691
|
394 mov di, #0x0020
|
pascal@13691
|
395 mov ax, #0xA33F
|
pascal@17450
|
396 mov bx, #CMDLINE_OFFSET
|
pascal@17450
|
397 push bx
|
pascal@17450
|
398 jbe oldcmdline
|
pascal@17450
|
399 mov di, #0x0228
|
pascal@17450
|
400 mov ax, es
|
pascal@17450
|
401 mov cl, #12
|
pascal@17450
|
402 shr ax, cl
|
pascal@17450
|
403 xchg ax, bx
|
pascal@17450
|
404 oldcmdline:
|
pascal@13691
|
405 stosw
|
pascal@17450
|
406 xchg ax, bx
|
pascal@13691
|
407 stosw
|
pascal@17450
|
408 pop di
|
pascal@13691
|
409 copy:
|
pascal@13691
|
410 lodsb
|
pascal@13691
|
411 stosb
|
pascal@13691
|
412 or al,al
|
pascal@13691
|
413 jne copy
|
pascal@17450
|
414 nocmdline:
|
pascal@16025
|
415 push es
|
pascal@16025
|
416 pop ss
|
pascal@16025
|
417 mov sp, #CMDLINE_OFFSET
|
pascal@17160
|
418 mov ax, _mem
|
pascal@17160
|
419 mov dx, _mem+2
|
pascal@16041
|
420 mov bx, _zimage
|
pascal@17160
|
421 mov bp, _iselks
|
pascal@17160
|
422 mov si, #sysmove
|
pascal@17160
|
423 mov di, #SETUP_END
|
pascal@17160
|
424 mov cx, #endsysmove-sysmove
|
pascal@16041
|
425 or bx, bx
|
pascal@16041
|
426 jz notzimage
|
pascal@16022
|
427 push cs
|
pascal@16022
|
428 pop ds
|
pascal@16022
|
429 push es
|
pascal@16022
|
430 push di
|
pascal@16022
|
431 rep
|
pascal@16022
|
432 movsb
|
pascal@16022
|
433 retf
|
pascal@16022
|
434 sysmove:
|
pascal@17160
|
435 cmp dx, #0x0010
|
pascal@17160
|
436 jb lowsys
|
pascal@17160
|
437 // bx first 64k page, dx:ax last byte+1
|
pascal@17160
|
438 xchg ax, cx // clear ax
|
pascal@17160
|
439 jcxz aligned
|
pascal@16022
|
440 inc dx
|
pascal@17160
|
441 aligned:
|
pascal@16069
|
442 mov si, di
|
pascal@16069
|
443 mov cx, #0x18
|
pascal@16069
|
444 rep
|
pascal@16069
|
445 stosw
|
pascal@17160
|
446 push es
|
pascal@17160
|
447 pop ds
|
pascal@16069
|
448 dec cx
|
pascal@17160
|
449 mov [si+0x10], cx // limit = -1
|
pascal@17160
|
450 mov [si+0x18], cx // limit = -1
|
pascal@17160
|
451 mov cx, #0x9300+SYSTEM_SEGMENT/0x1000
|
pascal@17450
|
452 //mov bh, #0x93
|
pascal@16069
|
453 mvdown:
|
pascal@16069
|
454 mov [si+0x12+2], bx // srce
|
pascal@17160
|
455 mov [si+0x1A+2], cx // dest
|
pascal@17473
|
456 use16 286 // more than 1Mb => 286+
|
pascal@17473
|
457 pusha
|
pascal@16069
|
458 mov cx, #0x8000
|
pascal@16069
|
459 mov ah, #0x87
|
pascal@17160
|
460 int 0x15
|
pascal@16069
|
461 popa
|
pascal@17473
|
462 use16 86
|
pascal@16069
|
463 inc bx
|
pascal@17160
|
464 inc cx
|
pascal@17160
|
465 cmp dl, bl
|
pascal@17161
|
466 ja mvdown
|
pascal@17160
|
467 jmp notzimage
|
pascal@17160
|
468 lowsys:
|
pascal@17160
|
469 // bx first segment, dx:ax last byte+1 (paragraph aligned)
|
pascal@17450
|
470 mov cl, #4 // elks may run on a 8086
|
pascal@17160
|
471 shr ax, cl
|
pascal@17160
|
472 shl dx, cl
|
pascal@17450
|
473 or ah, dl // last segment+1
|
pascal@17160
|
474 mov dx, #SYSTEM_SEGMENT
|
pascal@17160
|
475 sub ax, bx // ax = paragraph count
|
pascal@17160
|
476 sub bx, dx
|
pascal@17160
|
477 jnc sysmovelp
|
pascal@17160
|
478 add dx, ax // top down
|
pascal@17160
|
479 dec dx
|
pascal@17160
|
480 sysmovelp: // move ax paragraphs from bx+dx:0 to dx:0
|
pascal@17160
|
481 mov es, dx
|
pascal@17450
|
482 mov si, dx
|
pascal@17450
|
483 add si, bx
|
pascal@17450
|
484 mov ds, si
|
pascal@17450
|
485 sbb si, si // si = 0 : -1
|
pascal@17160
|
486 cmc // C = 1 : 0
|
pascal@17450
|
487 adc dx, si
|
pascal@17450
|
488 mov cl, #8
|
pascal@17160
|
489 xor di, di
|
pascal@17160
|
490 xor si, si
|
pascal@17160
|
491 rep
|
pascal@17160
|
492 movsw
|
pascal@17160
|
493 dec ax
|
pascal@17160
|
494 jne sysmovelp
|
pascal@16041
|
495 notzimage:
|
pascal@17450
|
496 mov ax, ss
|
pascal@17450
|
497 mov ds, ax
|
pascal@17450
|
498 dec bp
|
pascal@17450
|
499 jnz notelks
|
pascal@17450
|
500 mov ah, #0x1
|
pascal@17450
|
501 mov ss, ax
|
pascal@17450
|
502 notelks:
|
pascal@17160
|
503 push ss
|
pascal@17450
|
504 pop es
|
pascal@17450
|
505 xor di, di
|
pascal@17160
|
506 xor si, si
|
pascal@17450
|
507 #ifdef LINUX001_SUPPORT
|
pascal@17450
|
508 mov cx, #0x0042
|
pascal@17450
|
509 cmp word ptr [si+0x3F], #0x3AE8
|
pascal@17450
|
510 je islinux001
|
pascal@17450
|
511 #endif
|
pascal@17450
|
512 mov cx, #0x7800 // do not overload SYSTEM_SEGMENT
|
pascal@17160
|
513 rep
|
pascal@17160
|
514 movsw
|
pascal@17450
|
515 push es
|
pascal@17450
|
516 pop ds
|
pascal@17450
|
517 xor al, #0x20
|
pascal@17450
|
518 islinux001:
|
pascal@17160
|
519 push ax
|
pascal@17450
|
520 push cx
|
pascal@17160
|
521 retf
|
pascal@16022
|
522 endsysmove:
|
pascal@13691
|
523 #endasm
|
pascal@13691
|
524 }
|