diff options
author | nalin <nalin> | 1999-07-21 03:17:21 +0000 |
---|---|---|
committer | nalin <nalin> | 1999-07-21 03:17:21 +0000 |
commit | 4cc6ee7a17bc72328c618798b48d965b619f74a0 (patch) | |
tree | 09a5580a7a524b23aef49ae9a2a050d296ae255a | |
parent | c05513eaf60ffb0cc3021ae67b2b1973b2a31b5d (diff) | |
download | anaconda-4cc6ee7a17bc72328c618798b48d965b619f74a0.tar.gz anaconda-4cc6ee7a17bc72328c618798b48d965b619f74a0.tar.xz anaconda-4cc6ee7a17bc72328c618798b48d965b619f74a0.zip |
updates to emulation; smaller ram
-rw-r--r-- | ddcprobe/bioscall.c | 95 |
1 files changed, 90 insertions, 5 deletions
diff --git a/ddcprobe/bioscall.c b/ddcprobe/bioscall.c index e7109f688..52f9c7898 100644 --- a/ddcprobe/bioscall.c +++ b/ddcprobe/bioscall.c @@ -15,6 +15,15 @@ #include "bioscall.h" #ident "$Id$" +#define DFLAG 0x0400 +#define IFLAG 0x0200 +#define TFLAG 0x0100 +#define SFLAG 0x0080 +#define ZFLAG 0x0040 +#define AFLAG 0x0010 +#define PFLAG 0x0004 +#define CFLAG 0x0001 + /* Dump some of the interesting parts of a register struct to stdout. */ void dump_regs(struct vm86_regs *regs) { @@ -55,7 +64,7 @@ void do_vm86(struct vm86_struct *vm, char *memory, unsigned stop_eip) { ret = syscall(SYS_vm86old, vm); while((vm->regs.cs * 16 + vm->regs.eip) != (start_cs * 16 + stop_eip)) { ip = &memory[vm->regs.cs * 16 + vm->regs.eip]; -#ifdef DEBUG +#ifdef DEBUG2 printf("Unexpected return:\n"); dump_regs(&vm->regs); printf("Offending instructions: %02x %02x %02x %02x\n", @@ -97,13 +106,83 @@ void do_vm86(struct vm86_struct *vm, char *memory, unsigned stop_eip) { vm->regs.eip++; break; } + case 0x6c: { /* insb */ + unsigned char *result = (unsigned char*) + &memory[vm->regs.es*16 + vm->regs.edi]; + *result = inb(vm->regs.edx & 0xffff); + if(vm->regs.eflags & DFLAG) { + vm->regs.edi -= 1; + } else { + vm->regs.edi += 1; + } + if(ip[-1] == 0xf3) { /* rep'ped */ + vm->regs.ecx--; + vm->regs.eip--; + } else { + vm->regs.eip++; + } + break; + } + case 0x6d: { /* insw */ + u_int16_t *result = (u_int16_t*) + &memory[vm->regs.es*16 + vm->regs.edi]; + *result = inw(vm->regs.edx & 0xffff); + if(vm->regs.eflags & DFLAG) { + vm->regs.edi -= 2; + } else { + vm->regs.edi += 2; + } + if(ip[-1] == 0xf3) { /* rep'ped */ + vm->regs.ecx--; + vm->regs.eip--; + } else { + vm->regs.eip++; + } + break; + } + case 0x6e: { /* outsb */ + unsigned char *result = (unsigned char*) + &memory[vm->regs.es*16 + vm->regs.edi]; + outb(*result, + vm->regs.edx & 0xffff); + if(vm->regs.eflags & DFLAG) { + vm->regs.edi -= 1; + } else { + vm->regs.edi += 1; + } + if(ip[-1] == 0xf3) { /* rep'ped */ + vm->regs.ecx--; + vm->regs.eip--; + } else { + vm->regs.eip++; + } + break; + } + case 0x6f: { /* outsw */ + u_int16_t *result = (u_int16_t*) + &memory[vm->regs.es*16 + vm->regs.edi]; + outw(*result, + vm->regs.edx & 0xffff); + if(vm->regs.eflags & DFLAG) { + vm->regs.edi -= 2; + } else { + vm->regs.edi += 2; + } + if(ip[-1] == 0xf3) { /* rep'ped */ + vm->regs.ecx--; + vm->regs.eip--; + } else { + vm->regs.eip++; + } + break; + } case 0xfa: { /* cli */ - vm->regs.eflags &= ~(0x0200); + vm->regs.eflags &= ~(IFLAG); vm->regs.eip++; break; } case 0xfb: { /* sti */ - vm->regs.eflags |= ~(0x0200); + vm->regs.eflags |= ~(IFLAG); vm->regs.eip++; break; } @@ -231,7 +310,11 @@ unsigned char *vm86_ram_alloc() perror("reading kernel memory"); return MAP_FAILED; } - read(fd, memory, 0x110000); + // read(fd, memory, 0x110000); + lseek(fd, 0, SEEK_SET); + read(fd, &memory[0], 0x10000); + lseek(fd, 0xa0000, SEEK_SET); + read(fd, &memory[0xa0000], 0x50000); close(fd); return memory; @@ -250,7 +333,9 @@ void bioscall(unsigned char int_no, struct vm86_regs *regs, unsigned char *mem) memcpy(&vm.regs, regs, sizeof(vm.regs)); vm.regs.cs = BIOSCALL_START_SEG; vm.regs.eip = BIOSCALL_START_OFS; - vm.flags = VM_MASK | IOPL_MASK; + vm.regs.ss = BIOSCALL_START_SEG; + vm.regs.esp = 0xfff0 - BIOSCALL_START_OFS; + vm.regs.eflags = VM_MASK | IOPL_MASK; memcpy(&mem[BIOSCALL_START_SEG * 16 + BIOSCALL_START_OFS], call, sizeof(call)); do_vm86(&vm, mem, BIOSCALL_START_OFS + sizeof(call)); |