wok diff runcom/stuff/runcom.c @ rev 19563
linld: fix previous commit
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Sat Dec 17 19:13:29 2016 +0100 (2016-12-17) |
parents | b6347c31b319 |
children | ac7aeefa3415 |
line diff
1.1 --- a/runcom/stuff/runcom.c Sat Apr 28 13:04:22 2012 +0200 1.2 +++ b/runcom/stuff/runcom.c Sat Dec 17 19:13:29 2016 +0100 1.3 @@ -13,10 +13,13 @@ 1.4 #include <sys/time.h> 1.5 #include <sys/types.h> 1.6 #include <sys/stat.h> 1.7 +#include <sys/statfs.h> 1.8 #include <signal.h> 1.9 #include <errno.h> 1.10 #include <ctype.h> 1.11 #include <termios.h> 1.12 +#include <dirent.h> 1.13 +#include <fnmatch.h> 1.14 1.15 #include <sys/syscall.h> 1.16 #include <asm/vm86.h> 1.17 @@ -87,6 +90,9 @@ 1.18 fprintf(stderr,"\n"); 1.19 } 1.20 1.21 +static int argflags; 1.22 +#define DEBUG 1 1.23 + 1.24 #define DOS_FD_MAX 256 1.25 typedef struct { 1.26 int fd; /* -1 means closed */ 1.27 @@ -94,6 +100,8 @@ 1.28 1.29 DOSFile dos_files[DOS_FD_MAX]; 1.30 uint16_t cur_psp; 1.31 +uint16_t cur_dta_seg; 1.32 +uint16_t cur_dta_ofs; 1.33 1.34 void dos_init(void) 1.35 { 1.36 @@ -155,6 +163,8 @@ 1.37 offset++; 1.38 } 1.39 *q = '\0'; 1.40 + if (buf[1] == ':') 1.41 + strcpy(buf, buf+2); 1.42 return buf; 1.43 } 1.44 1.45 @@ -163,6 +173,15 @@ 1.46 return get_filename1(r, buf, buf_size, r->ds, r->edx & 0xffff); 1.47 } 1.48 1.49 +static char *upcase(const char *s) 1.50 +{ 1.51 + static char buffer[80]; 1.52 + int i; 1.53 + for (i = 0; i < sizeof(buffer)-1; i++, s++) 1.54 + buffer[i] = (*s >= 'a' && *s <= 'z') ? *s + 'A' - 'a' : *s; 1.55 + return buffer; 1.56 +} 1.57 + 1.58 typedef struct __attribute__((packed)) { 1.59 uint8_t drive_num; 1.60 uint8_t file_name[8]; 1.61 @@ -187,6 +206,22 @@ 1.62 uint16_t ip, cs; 1.63 } ExecParamBlock; 1.64 1.65 +typedef struct __attribute__((packed)) { 1.66 + /* internals */ 1.67 + uint8_t attr; /* 00 */ 1.68 + uint8_t drive_letter; /* 01 */ 1.69 + uint8_t template[11]; /* 02 */ 1.70 + uint16_t entry_count; /* 0D */ 1.71 + uint32_t dta_address; /* 0F */ 1.72 + uint16_t cluster_parent_dir; /* 13 */ 1.73 + /* output */ 1.74 + uint8_t attr_found; /* 15 */ 1.75 + uint16_t file_time; /* 16 */ 1.76 + uint16_t file_date; /* 18 */ 1.77 + uint32_t file_size; /* 1A */ 1.78 + uint8_t filename[13]; /* 1E */ 1.79 +} dirdta; 1.80 + 1.81 typedef struct MemBlock { 1.82 struct MemBlock *next; 1.83 uint16_t seg; 1.84 @@ -340,7 +375,8 @@ 1.85 header.min_extra_paragraphs += (size-1)/16; 1.86 1.87 /* address of last segment allocated */ 1.88 - *(uint16_t *)seg_to_linear(psp, 2) = psp + header.min_extra_paragraphs; 1.89 + //*(uint16_t *)seg_to_linear(psp, 2) = psp + header.min_extra_paragraphs; 1.90 + *(uint16_t *)seg_to_linear(psp, 2) = 0x9fff; 1.91 1.92 if (pfile_size) 1.93 *pfile_size = size; 1.94 @@ -378,6 +414,8 @@ 1.95 1.96 /* load the MSDOS .com executable */ 1.97 fd = open(filename, O_RDONLY); 1.98 + if (fd < 0) 1.99 + fd = open(upcase(filename), O_RDONLY); 1.100 if (fd < 0) { 1.101 return -1; 1.102 } 1.103 @@ -394,10 +432,10 @@ 1.104 /* reset the PSP */ 1.105 memset(seg_to_linear(psp, 0), 0, 0x100); 1.106 1.107 - *seg_to_linear(psp, 0) = 0xcd; /* int $0x20 */ 1.108 - *seg_to_linear(psp, 1) = 0x20; 1.109 + * (uint16_t *) seg_to_linear(psp, 0) = 0x20CD; /* int $0x20 */ 1.110 /* address of last segment allocated */ 1.111 - *(uint16_t *)seg_to_linear(psp, 2) = psp + 0xfff; 1.112 + //*(uint16_t *)seg_to_linear(psp, 2) = psp + 0xfff; 1.113 + *(uint16_t *)seg_to_linear(psp, 2) = 0x9fff; 1.114 1.115 if (argc) { 1.116 int i, p; 1.117 @@ -499,18 +537,98 @@ 1.118 } 1.119 } 1.120 1.121 +#define ESC "\033" 1.122 void do_int10(struct vm86_regs *r) 1.123 { 1.124 uint8_t ah; 1.125 + char buf[20]; 1.126 + static unsigned cursorlines = 0x0607; 1.127 + static unsigned activepage = 0; 1.128 + static uint8_t cursrow, curscol; 1.129 1.130 ah = (r->eax >> 8); 1.131 switch(ah) { 1.132 + case 0x02: /* set cursor position (BH == page number) */ 1.133 + cursrow = r->edx >> 8; 1.134 + curscol = r->edx; 1.135 + * (uint16_t *) seg_to_linear(0x40, 0x50 + 2*((r->ebx >> 8) & 0xFF)) = r->edx; 1.136 + sprintf(buf,ESC"[%u;%uH",cursrow + 1, curscol + 1); 1.137 + write(1, buf, strlen(buf)); 1.138 + break; 1.139 + case 0x03: /* get cursor position (BH == page number) */ 1.140 + r->eax = 0; 1.141 + r->ecx = cursorlines; 1.142 + r->edx &= ~0xFFFF; 1.143 + r->edx |= * (uint16_t *) seg_to_linear(0x40, 0x50 + 2*((r->ebx >> 8) & 0xFF)); 1.144 + sprintf(buf,ESC"[%u;%uH",cursrow + 1, curscol + 1); 1.145 + write(1, buf, strlen(buf)); 1.146 + break; 1.147 + case 0x05: /* set active page */ 1.148 + activepage = r->eax & 0xFF; 1.149 + break; 1.150 + case 0x06: /* scroll up */ 1.151 + case 0x07: /* scroll down */ 1.152 + { 1.153 + int i = r->eax & 0xFF; 1.154 + if (i == 0) i = 50; 1.155 + /* FIXME assume full row, ignore colums in CL, DL */ 1.156 + sprintf(buf,ESC"[%u;%ur",1+(r->ecx >> 8) & 0xFF, 1+(r->edx >> 8) & 0xFF); 1.157 + write(1, buf, strlen(buf)); 1.158 + buf[2] = (ah != 6) ? 'T' : 'S'; 1.159 + while (i--) write(1,buf,3); 1.160 + } 1.161 + break; 1.162 + case 0x09: /* write char and attribute at cursor position (BH == page number) */ 1.163 + { 1.164 + static char color[8] = "04261537"; 1.165 + char extra[5], *s = extra; 1.166 + uint8_t c = r->eax; 1.167 + uint16_t n = r->ecx; 1.168 + int i; 1.169 + 1.170 + if (r->ebx & 0x8) { *s++ = '1'; *s++ = ';'; } // bold 1.171 + if (r->ebx & 0x80) { *s++ = '5'; *s++ = ';'; } // blink 1.172 + *s = 0; 1.173 + sprintf(buf,ESC"[0;%s4%c;3%cm",extra, 1.174 + color[(r->ebx & 0x70) >> 4],color[r->ebx & 0x7]); 1.175 + write(1, buf, strlen(buf)); 1.176 + for (i = 0; i < n; i++) 1.177 + write(1, &c, 1); 1.178 + write(1, ESC"[0m", 4); /* restore attributes */ 1.179 + } 1.180 + break; 1.181 case 0x0E: /* write char */ 1.182 { 1.183 uint8_t c = r->eax; 1.184 write(1, &c, 1); 1.185 } 1.186 break; 1.187 + case 0x0F: /* get current video mode */ 1.188 + { 1.189 + r->eax &= ~0xFFFF; 1.190 + r->eax |= 0x5003; /* color or 5007 mono */ 1.191 + r->ebx &= ~0xFF00; 1.192 + r->ebx |= activepage << 8; 1.193 + } 1.194 + break; 1.195 + case 0x11: /* get window coordonates */ 1.196 + r->ecx &= ~0xFFFF; 1.197 + r->edx &= ~0xFFFF; 1.198 + r->edx |= ~0x1950; /* 80x25 */ 1.199 + break; 1.200 + case 0x12: /* get blanking attribute (for scroll) */ 1.201 + r->ebx &= ~0xFF00; 1.202 + break; 1.203 + case 0x1A: /* get display combination code */ 1.204 +#if 0 1.205 + set_error(r, 1); 1.206 +#else 1.207 + r->eax &= ~0xFF; 1.208 + r->eax |= ~0x1A; 1.209 + r->ebx &= ~0xFFFF; 1.210 + r->ebx |= ~0x0202; // CGA + color display 1.211 +#endif 1.212 + break; 1.213 default: 1.214 unsupported_function(r, 0x10, ah); 1.215 } 1.216 @@ -684,6 +802,8 @@ 1.217 void do_int21(struct vm86_regs *r) 1.218 { 1.219 uint8_t ah; 1.220 + DIR *dirp; 1.221 + dirdta *dta; 1.222 1.223 ah = (r->eax >> 8); 1.224 switch(ah) { 1.225 @@ -695,6 +815,11 @@ 1.226 write(1, &c, 1); 1.227 } 1.228 break; 1.229 + case 0x08: /* read stdin */ 1.230 + { 1.231 + read(0,&r->eax,1); 1.232 + } 1.233 + break; 1.234 case 0x09: /* write string */ 1.235 { 1.236 uint8_t c; 1.237 @@ -738,6 +863,34 @@ 1.238 *seg_to_linear(r->ds, off + 2 + cur_len) = '\r'; 1.239 } 1.240 break; 1.241 + case 0x0b: /* get stdin status */ 1.242 + { 1.243 + r->eax &= ~0xFF; /* no character available */ 1.244 + } 1.245 + break; 1.246 + case 0x0d: /* disk reset */ 1.247 + { 1.248 + sync(); 1.249 + } 1.250 + break; 1.251 + case 0x0e: /* select default disk */ 1.252 + { 1.253 + r->eax &= ~0xFF; 1.254 + r->eax |= 3; /* A: B: & C: valid */ 1.255 + } 1.256 + break; 1.257 + case 0x19: /* get current default drive */ 1.258 + { 1.259 + r->eax &= ~0xFF; 1.260 + r->eax |= 2; /* C: */ 1.261 + } 1.262 + break; 1.263 + case 0x1a: /* set DTA (disk transfert address) */ 1.264 + { 1.265 + cur_dta_seg = r->ds; 1.266 + cur_dta_ofs = r->edx; 1.267 + } 1.268 + break; 1.269 case 0x25: /* set interrupt vector */ 1.270 { 1.271 uint16_t *ptr; 1.272 @@ -851,6 +1004,12 @@ 1.273 r->edx = (tim.tv_sec * 256) + tim.tv_usec/10000; 1.274 } 1.275 break; 1.276 + case 0x2f: /* get DTA (disk transfert address */ 1.277 + { 1.278 + r->es = cur_dta_seg; 1.279 + r->ebx = cur_dta_ofs; 1.280 + } 1.281 + break; 1.282 case 0x30: /* get dos version */ 1.283 { 1.284 int major, minor, serial, oem; 1.285 @@ -864,6 +1023,11 @@ 1.286 r->ebx = (r->ebx & ~0xffff) | (serial & 0xff) | (0x66 << 8); 1.287 } 1.288 break; 1.289 + case 0x33: /* extended break checking */ 1.290 + { 1.291 + r->edx &= ~0xFFFF; 1.292 + } 1.293 + break; 1.294 case 0x35: /* get interrupt vector */ 1.295 { 1.296 uint16_t *ptr; 1.297 @@ -872,6 +1036,25 @@ 1.298 r->es = ptr[1]; 1.299 } 1.300 break; 1.301 + case 0x36: /* get free disk space */ 1.302 + { 1.303 + struct statfs buf; 1.304 + 1.305 + if (statfs(".", &buf)) { 1.306 + r->eax |= 0xFFFF; 1.307 + } 1.308 + else { 1.309 + r->eax &= ~0xFFFF; 1.310 + r->eax |= buf.f_bsize / 512; /* sectors per cluster */ 1.311 + r->ebx &= ~0xFFFF; 1.312 + r->ebx |= buf.f_bavail; 1.313 + r->ecx &= ~0xFFFF; 1.314 + r->ecx |= 512; /* bytes per sector */ 1.315 + r->edx &= ~0xFFFF; 1.316 + r->edx |= buf.f_blocks; 1.317 + } 1.318 + } 1.319 + break; 1.320 case 0x37: 1.321 { 1.322 switch(r->eax & 0xff) { 1.323 @@ -884,6 +1067,15 @@ 1.324 } 1.325 } 1.326 break; 1.327 + case 0x3B: 1.328 + { 1.329 + char filename[1024]; 1.330 + 1.331 + get_filename(r, filename, sizeof(filename)); 1.332 + if (chdir(filename)) 1.333 + set_error(r, 0x03); /* path not found */ 1.334 + } 1.335 + break; 1.336 case 0x3c: /* create or truncate file */ 1.337 { 1.338 char filename[1024]; 1.339 @@ -899,6 +1091,8 @@ 1.340 else 1.341 flags = 0777; 1.342 fd = open(filename, O_RDWR | O_TRUNC | O_CREAT, flags); 1.343 + if (fd < 0) 1.344 + fd = open(upcase(filename), O_RDWR | O_TRUNC | O_CREAT, flags); 1.345 #ifdef DUMP_INT21 1.346 printf("int21: create: file='%s' cx=0x%04x ret=%d\n", 1.347 filename, (int)(r->ecx & 0xffff), h); 1.348 @@ -923,11 +1117,9 @@ 1.349 set_error(r, 0x04); /* too many open files */ 1.350 } else { 1.351 get_filename(r, filename, sizeof(filename)); 1.352 -#ifdef DUMP_INT21 1.353 - printf("int21: open: file='%s' al=0x%02x ret=%d\n", 1.354 - filename, (int)(r->eax & 0xff), h); 1.355 -#endif 1.356 fd = open(filename, r->eax & 3); 1.357 + if (fd < 1) 1.358 + fd = open(upcase(filename), r->eax & 3); 1.359 if (fd < 0) { 1.360 set_error(r, 0x02); /* file not found */ 1.361 } else { 1.362 @@ -1031,7 +1223,7 @@ 1.363 { 1.364 char filename[1024]; 1.365 get_filename(r, filename, sizeof(filename)); 1.366 - if (unlink(filename) < 0) { 1.367 + if (unlink(filename) < 0 && unlink(upcase(filename))) { 1.368 set_error(r, 0x02); /* file not found */ 1.369 } else { 1.370 set_error(r, 0); 1.371 @@ -1062,6 +1254,20 @@ 1.372 } 1.373 } 1.374 break; 1.375 + case 0x43: /* get attribute */ 1.376 + { 1.377 + struct stat statbuf; 1.378 + char filename[1024]; 1.379 + get_filename(r, filename, sizeof(filename)); 1.380 + if (stat(filename, &statbuf) && stat(upcase(filename), &statbuf)) { 1.381 + set_error(r, 5); 1.382 + } 1.383 + else { 1.384 + r->ecx &= ~0xFFFF; 1.385 + if (S_ISDIR(statbuf.st_mode)) r->ecx |= 0x10; 1.386 + } 1.387 + } 1.388 + break; 1.389 case 0x44: /* ioctl */ 1.390 switch(r->eax & 0xff) { 1.391 case 0x00: /* get device information */ 1.392 @@ -1084,11 +1290,23 @@ 1.393 set_error(r, 0); 1.394 } 1.395 } 1.396 + case 0x01: /* set device information */ 1.397 break; 1.398 default: 1.399 goto unsupported; 1.400 } 1.401 break; 1.402 + case 0x47: /* get current directory (DL drive)*/ 1.403 + { 1.404 + char *s = seg_to_linear(r->ds, r->esi); 1.405 + getcwd(s,64); 1.406 + strcpy(s,s+1); 1.407 + while (*s) 1.408 + if (*s++ == '/') 1.409 + s[-1] = '\\'; 1.410 + r->eax = 0x100; 1.411 + } 1.412 + break; 1.413 case 0x48: /* allocate memory */ 1.414 { 1.415 int ret, max_size; 1.416 @@ -1144,10 +1362,13 @@ 1.417 get_filename(r, filename, sizeof(filename)); 1.418 blk = (ExecParamBlock *)seg_to_linear(r->es, r->ebx); 1.419 ret = load_com(blk, filename, NULL, 0, NULL); 1.420 + if (ret < 0) 1.421 + ret = load_com(blk, upcase(filename), NULL, 0, NULL); 1.422 if (ret < 0) { 1.423 set_error(r, 0x02); /* file not found */ 1.424 } else { 1.425 - cur_psp = ret; 1.426 + cur_dta_seg = cur_psp = ret; 1.427 + cur_dta_ofs = 0x80; 1.428 set_error(r, 0); 1.429 } 1.430 } 1.431 @@ -1155,6 +1376,53 @@ 1.432 case 0x4c: /* exit with return code */ 1.433 exit(r->eax & 0xff); 1.434 break; 1.435 + case 0x4e: /* find first matching file */ 1.436 +// TODO AL input support 1.437 + dirp = opendir("."); 1.438 + if (dirp == NULL) { 1.439 + set_error(r, (errno == ENOTDIR) ? 0x03 /* path not found */ 1.440 + : 0x02 /* file not found */ ); 1.441 + goto pattern_found; 1.442 + } 1.443 + else { 1.444 + struct dirent *dp; 1.445 + char *s; 1.446 + 1.447 + dta = (dirdta *) seg_to_linear(cur_dta_seg, cur_dta_ofs); 1.448 + dta->attr = r->ecx; 1.449 + * (DIR **) &dta->entry_count = dirp; 1.450 + s = seg_to_linear(r->ds, r->edx); 1.451 + if (s[1] == ':') s+= 2; 1.452 + if (s[0] == '\\') s++; 1.453 + strncpy(dta->template, s, 11); 1.454 + // NO break; 1.455 + case 0x4f: /* find next matching file */ 1.456 + dta = (dirdta *) seg_to_linear(cur_dta_seg, cur_dta_ofs); 1.457 + dirp = * (DIR **) &dta->entry_count; 1.458 + while ((dp = readdir(dirp)) != NULL) { 1.459 + if (!fnmatch(dta->template, dp->d_name, 0)) { 1.460 + struct stat statbuf; 1.461 + 1.462 + r->eflags &= ~CF_MASK; 1.463 + strncpy(dta->filename, dp->d_name, 13); 1.464 + stat(dp->d_name, &statbuf); 1.465 + dta->file_size = statbuf.st_size; 1.466 + dta->file_date = 0; //DOSDATE(statbuf.st_mtime); 1.467 + dta->file_time = 0; //DOSIME(statbuf.st_mtime); 1.468 + dta->attr_found = S_ISDIR(statbuf.st_mode) ? 1.469 + 0x10 /*aDvshr*/ : 0x20 /*Advshr*/; 1.470 +#if 0 1.471 + if ((dta->attr_found ^ dta->attr) & 0x16) 1.472 + continue; 1.473 +#endif 1.474 + goto pattern_found; 1.475 + } 1.476 + } 1.477 + } 1.478 + closedir(dirp); 1.479 + set_error(r, 0x12 /* no more files */); 1.480 +pattern_found: 1.481 + break; 1.482 case 0x50: /* set PSP address */ 1.483 #ifdef DUMP_INT21 1.484 printf("int21: set PSP: 0x%04x\n", (uint16_t)r->ebx); 1.485 @@ -1182,6 +1450,11 @@ 1.486 r->eax = (r->eax & ~0xff); 1.487 } 1.488 break; 1.489 + case 0x56: /* rename file (CL attribute mask) */ 1.490 + if (rename((char *) seg_to_linear(r->ds, r->edx), 1.491 + (char *) seg_to_linear(r->es, r->edi))) 1.492 + set_error(r, 0x5 /* access denied or 2,3,0x11 */); 1.493 + break; 1.494 default: 1.495 unsupported: 1.496 unsupported_function(r, 0x21, ah); 1.497 @@ -1194,26 +1467,45 @@ 1.498 write(1, &c, 1); 1.499 } 1.500 1.501 +static int int8pending; 1.502 + 1.503 void raise_interrupt(int number) 1.504 { 1.505 if (* (uint32_t *) seg_to_linear(0, number * 4) == 0) 1.506 return; 1.507 - // FIXME VM86_SIGNAL 1.508 + int8pending++; 1.509 } 1.510 1.511 void biosclock() 1.512 { 1.513 - uint32_t *timer = (uint32_t *) seg_to_linear(0, 0x46C); 1.514 - ++*timer; 1.515 + //uint32_t *timer = (uint32_t *) seg_to_linear(0, 0x46C); 1.516 + //++*timer; 1.517 raise_interrupt(8); 1.518 - raise_interrupt(0x1C); 1.519 + //raise_interrupt(0x1C); 1.520 +} 1.521 + 1.522 +static void exec_int(struct vm86_regs *r, unsigned num) 1.523 +{ 1.524 + uint16_t *int_vector; 1.525 + uint32_t eflags; 1.526 + 1.527 + eflags = r->eflags & ~IF_MASK; 1.528 + if (r->eflags & VIF_MASK) 1.529 + eflags |= IF_MASK; 1.530 + pushw(r, eflags); 1.531 + pushw(r, r->cs); 1.532 + pushw(r, r->eip); 1.533 + int_vector = (uint16_t *)seg_to_linear(0, num * 4); 1.534 + r->eip = int_vector[0]; 1.535 + r->cs = int_vector[1]; 1.536 + r->eflags &= ~(VIF_MASK | TF_MASK | AC_MASK); 1.537 } 1.538 1.539 int main(int argc, char **argv) 1.540 { 1.541 uint8_t *vm86_mem; 1.542 const char *filename; 1.543 - int ret; 1.544 + int i, ret; 1.545 uint32_t file_size; 1.546 struct sigaction sa; 1.547 struct itimerval timerval; 1.548 @@ -1221,6 +1513,16 @@ 1.549 struct vm86_regs *r; 1.550 ExecParamBlock blk1, *blk = &blk1; 1.551 1.552 + for (argflags = 0; *argv[1] == '-'; argv++) { 1.553 + char *s = argv[1]; 1.554 + 1.555 + while (1) 1.556 + switch (*++s) { 1.557 + case 'd' : argflags |= DEBUG; break; 1.558 + case 0 : goto nextargv; 1.559 + } 1.560 +nextargv:; 1.561 + } 1.562 if (argc < 2) 1.563 usage(); 1.564 filename = argv[1]; 1.565 @@ -1253,7 +1555,8 @@ 1.566 perror(filename); 1.567 exit(1); 1.568 } 1.569 - cur_psp = ret; 1.570 + cur_dta_seg = cur_psp = ret; 1.571 + cur_dta_ofs = 0x80; 1.572 1.573 /* init basic registers */ 1.574 r->eip = blk->ip; 1.575 @@ -1291,6 +1594,13 @@ 1.576 timerval.it_interval.tv_usec = timerval.it_value.tv_usec = 10000000 / 182; 1.577 setitimer (ITIMER_REAL, &timerval, NULL); 1.578 } 1.579 + *(uint8_t *)seg_to_linear(0xF000, 0) = 0xCF; 1.580 + for (i = 0; i < 16; i++) 1.581 + *(uint32_t *)seg_to_linear(0, i * 4) = 0xF0000000; 1.582 + *(uint32_t *)seg_to_linear(0, 0x18 * 4) = 0xF0000000; /* Basic */ 1.583 + *(uint32_t *)seg_to_linear(0, 0x1B * 4) = 0xF0000000; /* Keyboard Ctrl-Break */ 1.584 + *(uint32_t *)seg_to_linear(0, 0x23 * 4) = 0xF0000000; /* DOS Ctrl-Break */ 1.585 + *(uint32_t *)seg_to_linear(0, 0x24 * 4) = 0xF0000000; /* Critical error */ 1.586 1.587 for(;;) { 1.588 ret = vm86(VM86_ENTER, &ctx); 1.589 @@ -1300,6 +1610,9 @@ 1.590 int int_num; 1.591 1.592 int_num = VM86_ARG(ret); 1.593 + if (argflags & 1) 1.594 + fprintf(stderr,"Int%02X: CS:IP=%04X:%04X AX=%04X\n", 1.595 + int_num, r->cs, r->eip, r->eax); 1.596 switch(int_num) { 1.597 case 0x10: 1.598 do_int10(r); 1.599 @@ -1334,27 +1647,32 @@ 1.600 break; 1.601 case VM86_SIGNAL: 1.602 /* a signal came, we just ignore that */ 1.603 + if (int8pending) { 1.604 + int8pending--; 1.605 + exec_int(r, 8); 1.606 + } 1.607 break; 1.608 case VM86_STI: 1.609 break; 1.610 case VM86_TRAP: 1.611 /* just executes the interruption */ 1.612 - { 1.613 - uint16_t *int_vector; 1.614 - uint32_t eflags; 1.615 - 1.616 - eflags = r->eflags & ~IF_MASK; 1.617 - if (r->eflags & VIF_MASK) 1.618 - eflags |= IF_MASK; 1.619 - pushw(r, eflags); 1.620 - pushw(r, r->cs); 1.621 - pushw(r, r->eip); 1.622 - int_vector = (uint16_t *)seg_to_linear(0, VM86_ARG(ret) * 4); 1.623 - r->eip = int_vector[0]; 1.624 - r->cs = int_vector[1]; 1.625 - r->eflags &= ~(VIF_MASK | TF_MASK | AC_MASK); 1.626 + exec_int(r, VM86_ARG(ret)); 1.627 + break; 1.628 + case VM86_UNKNOWN: 1.629 + switch ( *(uint8_t *)seg_to_linear(r->cs, r->eip) ) { 1.630 + case 0xE4: /* inx portb,al */ 1.631 + case 0xE5: /* in portb,ax */ 1.632 + case 0xE6: /* out al,portb */ 1.633 + case 0xE7: /* out ax,portb */ 1.634 + r->eip += 2; 1.635 + continue; 1.636 + case 0xEC: /* in dx,al */ 1.637 + case 0xED: /* in dx,ax */ 1.638 + case 0xEE: /* out al,dx */ 1.639 + case 0xEF: /* out ax,dx */ 1.640 + r->eip++; 1.641 + continue; 1.642 } 1.643 - break; 1.644 default: 1.645 fprintf(stderr, "unhandled vm86 return code (0x%x)\n", ret); 1.646 dump_regs(&ctx.regs);