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@16041
|
142 static unsigned 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@17450
|
263 if (setup == 512) {
|
pascal@17450
|
264 #ifdef LINUX001_SUPPORT
|
pascal@17450
|
265 if (WORD(buffer + 0x3F) == 0x3AE8) /* linux 0.01 */
|
pascal@17450
|
266 goto linux001;
|
pascal@17450
|
267 #endif
|
pascal@17450
|
268 setup = 5 << 9;
|
pascal@17450
|
269 }
|
pascal@17450
|
270 #ifdef LINUX001_SUPPORT
|
pascal@17450
|
271 n = BUFFERSZ;
|
pascal@17450
|
272 isoread(buffer+512, BUFFERSZ-512);
|
pascal@17450
|
273 #endif
|
pascal@13691
|
274 #define HDRS 0x53726448
|
pascal@17450
|
275 if (LONG(buffer + HEADER) == HDRS)
|
pascal@17450
|
276 setup_version = WORD(buffer + VERSION);
|
pascal@17160
|
277 #define ELKS 0x534B4C45
|
pascal@17450
|
278 if (LONG(buffer + ELKSSIG) == ELKS)
|
pascal@17160
|
279 iselks = 1;
|
pascal@16022
|
280 if (setup_version < 0x204)
|
pascal@13733
|
281 syssize &= 0x000FFFFFUL;
|
pascal@16022
|
282 if (setup_version) {
|
pascal@13733
|
283 #ifdef REALMODE_SWITCH
|
pascal@13733
|
284 extern int far_realmode_switch();
|
pascal@13733
|
285 #asm
|
pascal@13733
|
286 jmp end_realmode_switch
|
pascal@13733
|
287 _far_realmode_switch:
|
pascal@14257
|
288 call REALMODE_SWITCH
|
pascal@13733
|
289 cli
|
pascal@13733
|
290 mov al, #0x80 // Disable NMI
|
pascal@13733
|
291 out 0x70, al
|
pascal@13733
|
292 retf
|
pascal@13733
|
293 end_realmode_switch:
|
pascal@13733
|
294 #endasm
|
pascal@17450
|
295 WORD(buffer + RMSWOFS) = far_realmode_switch;
|
pascal@17450
|
296 WORD(buffer + RMSWSEG) = getcs();
|
pascal@13733
|
297 #endif
|
pascal@17450
|
298 mem.base = LONG(buffer + SYSTEMCODE);
|
pascal@17450
|
299 WORD(buffer + HEAPPTR) = 0x9B00;
|
pascal@13733
|
300 // buffer[LOADFLAGS] |= 0x80;
|
pascal@17450
|
301 WORD(buffer + LOADERTYPE) |= 0x80FF;
|
pascal@13733
|
302 }
|
pascal@17450
|
303 #ifdef LINUX001_SUPPORT
|
pascal@17450
|
304 linux001:
|
pascal@17450
|
305 #endif
|
pascal@16022
|
306 if (!setup_version || !(buffer[LOADFLAGS] & 1)) {
|
pascal@16041
|
307 zimage = getss() + 0x1000;
|
pascal@16041
|
308 mem.base = zimage * 16L;
|
pascal@17160
|
309 if (mem.base + syssize > setupseg*16L - 32) {
|
pascal@17450
|
310 zimage = 0x9311;
|
pascal@17160
|
311 mem.base = 0x110000L; // 1M + 64K HMA
|
pascal@17160
|
312 }
|
pascal@13691
|
313 }
|
pascal@13691
|
314 }
|
pascal@13691
|
315 movesetup();
|
pascal@13691
|
316 setup -= n;
|
pascal@13691
|
317 n = (setup > BUFFERSZ) ? BUFFERSZ : setup;
|
pascal@13691
|
318 } while (setup > 0);
|
pascal@13691
|
319
|
pascal@14257
|
320 #asm
|
pascal@17160
|
321 push si
|
pascal@17160
|
322 mov si, #0x200
|
pascal@17160
|
323 cmp si, _setup_version
|
pascal@17160
|
324 jae noversion
|
pascal@17450
|
325 mov es, _setupseg
|
pascal@17450
|
326 seg es
|
pascal@14257
|
327 add si, [si+14]
|
pascal@17450
|
328 mov bx, #2
|
pascal@17450
|
329 mov cl, #4
|
pascal@17450
|
330 nextnumber:
|
pascal@17450
|
331 xor ax, ax
|
pascal@14257
|
332 nextdigit:
|
pascal@17450
|
333 shl al, cl
|
pascal@17450
|
334 shl ax, cl
|
pascal@17450
|
335 seg es
|
pascal@14257
|
336 lodsb
|
pascal@14257
|
337 sub al, #0x30
|
pascal@14257
|
338 cmp al, #9
|
pascal@14257
|
339 jbe nextdigit
|
pascal@17450
|
340 mov [bx+_kernel_version], ah
|
pascal@17450
|
341 dec bx
|
pascal@17450
|
342 jns nextnumber
|
pascal@14257
|
343 noversion:
|
pascal@17160
|
344 pop si
|
pascal@14257
|
345 #endasm
|
pascal@16022
|
346 load(syssize);
|
pascal@14268
|
347 return kernel_version;
|
pascal@13691
|
348 }
|
pascal@13691
|
349
|
pascal@13691
|
350 void loadinitrd(void)
|
pascal@13691
|
351 {
|
pascal@17160
|
352 if (setup_version)
|
pascal@16022
|
353 load(isofilesize);
|
pascal@13691
|
354 }
|
pascal@13691
|
355
|
pascal@13691
|
356 void bootlinux(char *cmdline)
|
pascal@13691
|
357 {
|
pascal@17160
|
358 dosshutdown();
|
pascal@13691
|
359 #asm
|
pascal@17450
|
360 cld
|
pascal@17160
|
361 mov es, _setupseg
|
pascal@17450
|
362 mov ax, _setup_version
|
pascal@17450
|
363 cmp ax, #0x200
|
pascal@17450
|
364 jb noinitrd
|
pascal@17450
|
365 mov di, #0x218
|
pascal@17450
|
366 mov si, #_initrd_addr
|
pascal@17450
|
367 movsw
|
pascal@17450
|
368 movsw
|
pascal@17450
|
369 mov si, #_initrd_size
|
pascal@17450
|
370 movsw
|
pascal@17450
|
371 movsw
|
pascal@17450
|
372 noinitrd:
|
pascal@17460
|
373 mov si, [bp+4] // .bootlinux.cmdline[bp]
|
pascal@17450
|
374 or si, si
|
pascal@17450
|
375 jz nocmdline
|
pascal@17450
|
376 cmp ax, #0x201
|
pascal@13691
|
377 mov di, #0x0020
|
pascal@13691
|
378 mov ax, #0xA33F
|
pascal@17450
|
379 mov bx, #CMDLINE_OFFSET
|
pascal@17450
|
380 push bx
|
pascal@17450
|
381 jbe oldcmdline
|
pascal@17450
|
382 mov di, #0x0228
|
pascal@17450
|
383 mov ax, es
|
pascal@17450
|
384 mov cl, #12
|
pascal@17450
|
385 shr ax, cl
|
pascal@17450
|
386 xchg ax, bx
|
pascal@17450
|
387 oldcmdline:
|
pascal@13691
|
388 stosw
|
pascal@17450
|
389 xchg ax, bx
|
pascal@13691
|
390 stosw
|
pascal@17450
|
391 pop di
|
pascal@13691
|
392 copy:
|
pascal@13691
|
393 lodsb
|
pascal@13691
|
394 stosb
|
pascal@13691
|
395 or al,al
|
pascal@13691
|
396 jne copy
|
pascal@17450
|
397 nocmdline:
|
pascal@16025
|
398 push es
|
pascal@16025
|
399 pop ss
|
pascal@16025
|
400 mov sp, #CMDLINE_OFFSET
|
pascal@17160
|
401 mov ax, _mem
|
pascal@17160
|
402 mov dx, _mem+2
|
pascal@16041
|
403 mov bx, _zimage
|
pascal@17160
|
404 mov bp, _iselks
|
pascal@17160
|
405 mov si, #sysmove
|
pascal@17160
|
406 mov di, #SETUP_END
|
pascal@17160
|
407 mov cx, #endsysmove-sysmove
|
pascal@16041
|
408 or bx, bx
|
pascal@16041
|
409 jz notzimage
|
pascal@16022
|
410 push cs
|
pascal@16022
|
411 pop ds
|
pascal@16022
|
412 push es
|
pascal@16022
|
413 push di
|
pascal@16022
|
414 rep
|
pascal@16022
|
415 movsb
|
pascal@16022
|
416 retf
|
pascal@16022
|
417 sysmove:
|
pascal@17160
|
418 cmp dx, #0x0010
|
pascal@17160
|
419 jb lowsys
|
pascal@17160
|
420 // bx first 64k page, dx:ax last byte+1
|
pascal@17160
|
421 xchg ax, cx // clear ax
|
pascal@17160
|
422 jcxz aligned
|
pascal@16022
|
423 inc dx
|
pascal@17160
|
424 aligned:
|
pascal@16069
|
425 mov si, di
|
pascal@16069
|
426 mov cx, #0x18
|
pascal@16069
|
427 rep
|
pascal@16069
|
428 stosw
|
pascal@17160
|
429 push es
|
pascal@17160
|
430 pop ds
|
pascal@16069
|
431 dec cx
|
pascal@17160
|
432 mov [si+0x10], cx // limit = -1
|
pascal@17160
|
433 mov [si+0x18], cx // limit = -1
|
pascal@17160
|
434 mov cx, #0x9300+SYSTEM_SEGMENT/0x1000
|
pascal@17450
|
435 //mov bh, #0x93
|
pascal@16069
|
436 mvdown:
|
pascal@16069
|
437 mov [si+0x12+2], bx // srce
|
pascal@17160
|
438 mov [si+0x1A+2], cx // dest
|
pascal@17473
|
439 use16 286 // more than 1Mb => 286+
|
pascal@17473
|
440 pusha
|
pascal@16069
|
441 mov cx, #0x8000
|
pascal@16069
|
442 mov ah, #0x87
|
pascal@17160
|
443 int 0x15
|
pascal@16069
|
444 popa
|
pascal@17473
|
445 use16 86
|
pascal@16069
|
446 inc bx
|
pascal@17160
|
447 inc cx
|
pascal@17160
|
448 cmp dl, bl
|
pascal@17161
|
449 ja mvdown
|
pascal@17160
|
450 jmp notzimage
|
pascal@17160
|
451 lowsys:
|
pascal@17160
|
452 // bx first segment, dx:ax last byte+1 (paragraph aligned)
|
pascal@17450
|
453 mov cl, #4 // elks may run on a 8086
|
pascal@17160
|
454 shr ax, cl
|
pascal@17160
|
455 shl dx, cl
|
pascal@17450
|
456 or ah, dl // last segment+1
|
pascal@17160
|
457 mov dx, #SYSTEM_SEGMENT
|
pascal@17160
|
458 sub ax, bx // ax = paragraph count
|
pascal@17160
|
459 sub bx, dx
|
pascal@17160
|
460 jnc sysmovelp
|
pascal@17160
|
461 add dx, ax // top down
|
pascal@17160
|
462 dec dx
|
pascal@17160
|
463 sysmovelp: // move ax paragraphs from bx+dx:0 to dx:0
|
pascal@17160
|
464 mov es, dx
|
pascal@17450
|
465 mov si, dx
|
pascal@17450
|
466 add si, bx
|
pascal@17450
|
467 mov ds, si
|
pascal@17450
|
468 sbb si, si // si = 0 : -1
|
pascal@17160
|
469 cmc // C = 1 : 0
|
pascal@17450
|
470 adc dx, si
|
pascal@17450
|
471 mov cl, #8
|
pascal@17160
|
472 xor di, di
|
pascal@17160
|
473 xor si, si
|
pascal@17160
|
474 rep
|
pascal@17160
|
475 movsw
|
pascal@17160
|
476 dec ax
|
pascal@17160
|
477 jne sysmovelp
|
pascal@16041
|
478 notzimage:
|
pascal@17450
|
479 mov ax, ss
|
pascal@17450
|
480 mov ds, ax
|
pascal@17450
|
481 dec bp
|
pascal@17450
|
482 jnz notelks
|
pascal@17450
|
483 mov ah, #0x1
|
pascal@17450
|
484 mov ss, ax
|
pascal@17450
|
485 notelks:
|
pascal@17160
|
486 push ss
|
pascal@17450
|
487 pop es
|
pascal@17450
|
488 xor di, di
|
pascal@17160
|
489 xor si, si
|
pascal@17450
|
490 #ifdef LINUX001_SUPPORT
|
pascal@17450
|
491 mov cx, #0x0042
|
pascal@17450
|
492 cmp word ptr [si+0x3F], #0x3AE8
|
pascal@17450
|
493 je islinux001
|
pascal@17450
|
494 #endif
|
pascal@17450
|
495 mov cx, #0x7800 // do not overload SYSTEM_SEGMENT
|
pascal@17160
|
496 rep
|
pascal@17160
|
497 movsw
|
pascal@17450
|
498 push es
|
pascal@17450
|
499 pop ds
|
pascal@17450
|
500 xor al, #0x20
|
pascal@17450
|
501 islinux001:
|
pascal@17160
|
502 push ax
|
pascal@17450
|
503 push cx
|
pascal@17160
|
504 retf
|
pascal@16022
|
505 endsysmove:
|
pascal@13691
|
506 #endasm
|
pascal@13691
|
507 }
|