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