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