static void dump(Vga*, Ctlr* ctlr) { printitem(ctlr->name, "Advfunc"); Bprint(&stdout, "%9.4uX\n", inportw(Advfunc)); printitem(ctlr->name, "Subsys"); Bprint(&stdout, "%9.4uX\n", inportw(Subsys)); }
int mccl_read (const char *filename, unsigned int parport) { unsigned char buffer[0x1760], inbyte; char dest_name[FILENAME_MAX]; int count = 0; time_t starttime; parport_print_info (); puts ("Resetting device"); do { outportb (CONTROL, 0x24); while ((inportb (STATUS) & 0x20) == 0) ; } while ((inportw (DATA) & 0xf) != 4); outportb (CONTROL, 0x22); while ((inportb (STATUS) & 0x20) != 0) ; outportb (CONTROL, 0x26); printf ("Receive: %d Bytes (%.4f Mb)\n\n", 0x1760, (float) 0x1760 / MBIT); starttime = time (NULL); do { outportb (CONTROL, 0x26); while ((inportb (STATUS) & 0x20) == 0) ; inbyte = (unsigned char) (inportw (DATA) & 0xf); outportb (CONTROL, 0x22); while ((inportb (STATUS) & 0x20) != 0) ; outportb (CONTROL, 0x26); while ((inportb (STATUS) & 0x20) == 0) ; inbyte |= (unsigned char) ((inportw (DATA) & 0xf) << 4); outportb (CONTROL, 0x22); while ((inportb (STATUS) & 0x20) != 0) ; buffer[count++] = inbyte; if ((count & 0x1f) == 0) ucon64_gauge (starttime, count, 0x1760); } while (count < 0x1760); strcpy (dest_name, filename); ucon64_file_handler (dest_name, NULL, 0); ucon64_fwrite (buffer, 0, count, dest_name, "wb"); printf (ucon64_msg[WROTE], dest_name); return 0; }
void ttt_read_rom_w (int addr, unsigned char *buf) // original name: read_buff { int count; set_addr_read (addr); for (count = 0; count < 0x80; count++) #ifdef WORDS_BIGENDIAN ((unsigned short int *) buf)[count] = bswap_16 (inportw (port_c)); // read_dataw () #else ((unsigned short int *) buf)[count] = inportw (port_c); // read_dataw () #endif }
static inline unsigned int read_dword(int reg,int channel,int port) { int in_port,a,b; in_port=_emu8k_baseport; switch(port) { case 0: in_port+=0x0000; break; case 1: in_port+=0x0400; break; case 2: in_port+=0x0402; break; case 3: in_port+=0x0800; break; default: return 0; } outportw(_emu8k_baseport+0x802,(reg<<5)+(channel&0x1f)); a=inportw(in_port); b=inportw(in_port+2); return ((b<<16)+a); }
/* * Read a block at the logical block number indicated. */ int read_sector(unsigned char *buf, int drive_num, unsigned int lba, unsigned int num_sectors) { int i; unsigned short *wordbuf; /* Initialize the command block registers */ outportb(IDE_SECTOR_COUNT, num_sectors); outportb(IDE_SECTOR_NUMBER, LBA_LOW_BYTE(lba)); outportb(IDE_CYLINDER_LOW, LBA_HIGH_BYTE(lba)); outportb(IDE_CYLINDER_HIGH, LBA_EXTENDED_LOW_BYTE(lba)); if (drive_num == 0) outportb(IDE_DRIVE_HEAD, IDE_DRIVE0 | LBA_EXTENDED_HIGH_BYTE(lba)); else if (drive_num == 1) outportb(IDE_DRIVE_HEAD, IDE_DRIVE1 | LBA_EXTENDED_HIGH_BYTE(lba)); /* Load command register with the read command code */ outportb(IDE_COMMAND, IDE_CMD_READ_SECTORS_RETRY); while (inportb(IDE_STATUS) & IDE_STATUS_BUSY) /* wait for the drive */ ; if (inportb(IDE_STATUS) & IDE_STATUS_ERROR) return IDE_ERR_IO_ERROR; wordbuf = (unsigned short *) buf; for (i = 0; i < 256 * num_sectors; i++) wordbuf[i] = inportw(IDE_DATA_PORT); return IDE_ERR_NOERROR; }
uint32_t PCI::read_word(uint32_t bus, uint32_t slot, uint32_t func, uint32_t offset) { uint32_t id = ((bus) << 16) | ((slot) << 11) | ((func) << 8); uint32_t addr = 0x80000000 | id | (offset & 0xfc); outportd(0xCF8, addr); uint32 val = inportw(0xCFC + (offset & 0x02)); return val; }
uint16_t pci_read_word(uint8_t bus, uint8_t slot, uint8_t func, uint32_t offset) { uint32_t id = ((bus) << 16) | ((slot) << 11) | ((func) << 8); uint32_t addr = 0x80000000 | id | (offset & 0xfc); outportl(0xCF8, addr); return inportw(0xCFC + (offset & 0x02)); }
uint16 pci_read_conf16(uint8 bus, uint8 dev, uint8 func, uint8 reg) { uint16 ret; uint32 port = (0x80000000U)|(bus<<16)|(dev<<11)|(func<<8)|(reg); outportl(0xcf8, port); ret = inportw((uint16)(0xcfc + (reg&2))); return ret; }
void ttt_read_ram_w (int addr, unsigned char *buf) // original name: readpagerambuff { int count; set_addr_read (addr); for (count = 0; count < 0x80; count++) ((unsigned short int *) buf)[count] = inportw (port_c); // read_dataw (); data is doubled for MD-PRO => no problems with endianess }
void ata_read_pio_sector(unsigned short *in_buffer) { int i; unsigned short port; if (controller==1) port = REG_DATEN; else port = REG2_DATEN; for (i=0; i<256; i++, in_buffer++) { *in_buffer=inportw(port); } }
void ata_read_pio_identify(struct __ata_info *ata_info) { unsigned short i; unsigned short *ata_info_pointer; unsigned short port; if (controller==1) port = REG_DATEN; else port = REG2_DATEN; ata_info_pointer=(unsigned short*)ata_info; for (i=0; i < 256; i++, *ata_info_pointer++) { *ata_info_pointer=inportw(port); } }
/* * Gather info about the ide drives present. */ int probe_ide_drives(void) { int i; int status; short buffer[256]; int drive; num_ide_drives = 0; for (drive = 0; drive < 2; drive++) { outportb(IDE_DRIVE_HEAD, (drive == 0) ? IDE_DRIVE0 : IDE_DRIVE1); outportb(IDE_COMMAND, IDE_CMD_IDENT_DRIVE); while (inportb(IDE_STATUS) & IDE_STATUS_BUSY); status = inportb(IDE_STATUS); /* * simulate failure * status = 0x50; */ if ((status & IDE_STATUS_DATA_REQUEST)) { /* drive responded to ATA probe */ for (i = 0; i < 256; i++) buffer[i] = inportw(IDE_DATA_PORT); ide_drive[drive].num_cylinders = buffer[IDE_IDENT_NUM_CYLINDERS]; ide_drive[drive].num_heads = buffer[IDE_IDENT_NUM_HEADS]; ide_drive[drive].num_sectors_per_track = buffer[IDE_IDENT_NUM_SECTORS_TRACK]; ide_drive[drive].num_bytes_per_sector = buffer[IDE_IDENT_NUM_BYTES_SECTOR]; num_ide_drives++; } else { /* try for ATAPI */ outportb(IDE_FEATURE_REG, 0); /* disable dma & overlap */ outportb(IDE_DRIVE_HEAD, (drive == 0) ? IDE_DRIVE0 : IDE_DRIVE1); outportb(IDE_COMMAND, IDE_CMD_ATAPI_IDENT_DRIVE); while (inportb(IDE_STATUS) & IDE_STATUS_BUSY); status = inportb(IDE_STATUS); } } if (!num_ide_drives) return IDE_ERR_DRIVE_NOT_FOUND; return 0; }
uint64 init_nic_pcnet(struct pci_dev *d) { uint32 io = d->bars[0].addr; uint16 t16; uint32 i; struct pcnet_private *priv = NULL; struct eth_dev *eth; priv = (struct pcnet_private *)kmalloc_align(sizeof(struct pcnet_private), "pcnet_private", NULL); if(priv == NULL) { printf("init_nic: cannot allocate pcnet_private\n"); goto fail; } priv->dev = d; priv->init = (struct pcnet_init_32 *)kmalloc_align(sizeof(struct pcnet_init_32), "pcnet_init", NULL); if(priv->init == NULL) { printf("init_nic: cannot allocate pcnet_init\n"); goto fail_free_private; } priv->rx = (struct pcnet_rx_32 *)kmalloc_align(sizeof(struct pcnet_rx_32) * DRE_COUNT, "pcnet_rx", NULL); if(priv->rx == NULL) { printf("init_nic: cannot allocate pcnet_rx\n"); goto fail_free_init; } priv->tx = (struct pcnet_tx_32 *)kmalloc_align(sizeof(struct pcnet_tx_32) * DRE_COUNT, "pcnet_tx", NULL); if(priv->tx == NULL) { printf("init_nic: cannot allocate pcnet_tx\n"); goto fail_free_rx; } eth = eth_alloc(priv, &pcnet_ops); if(eth == NULL) { printf("init_nic: failed to allocate eth\n"); goto fail_free_tx; } priv->eth = eth; t16 = pci_read_conf16(d->bus, d->dev, d->func, PCI_CMD_REG); if(!(t16 & PCI_CMD_MASTER)) { t16 |= PCI_CMD_MASTER|PCI_CMD_IO|PCI_CMD_MEMORY; pci_write_conf16(d->bus, d->dev, d->func, PCI_CMD_REG, t16); t16 = pci_read_conf16(d->bus, d->dev, d->func, PCI_CMD_REG); printf("init_nic: enabling PCI master bit\n"); } //writeCSR(io, 0, 0x04); // this switches to 32bit too early printf("init_nic: eth%x mac_addr=", eth->unit); for (i=0; i<6; i++) { printf("%x", eth->addr[i] = priv->init->PADR[i] = inportb(io+i)); if(i!=5) printf(":"); //else printf("\n"); } // Put the NIC in STOP outportw(io + 0x12, 0); outportw(io + 0x10, CSR0_STOP); // Reset the NIC inportw(io + 0x14); // Switch to DWORD mode outportl(io + 0x10, 0x00); // Switch to 32bit and PCNET_PCI_II style writeBCR(io, 20, CSR58_SSIZE32|CSR58_PCNET_PCII); // Obtain the chip version(s) priv->chip_version_lo = readCSR(io, 88); printf(" ver=%x:", priv->chip_version_lo); priv->chip_version_up = (readCSR(io, 89) & 0x0000ffff); printf("%x", priv->chip_version_up); // Set-up the initialisation block priv->init->MODE = 0; priv->init->RLEN = TX_TLEN; priv->init->TLEN = RX_RLEN; priv->init->LADRF = 0x0; priv->init->RDRA = (uint32)(uint64)priv->rx; priv->init->TDRA = (uint32)(uint64)priv->tx; for(i=0; i<DRE_COUNT; i++) { priv->rx[i].RBADR = (uint32)(uint64)kmalloc_align(1544, "pcnet rx", NULL); priv->rx[i].BCNT = SECOND_COMP(1544); priv->rx[i].ones = 0xf; priv->rx[i].OWN = 1; priv->tx[i].TBADR = 0; priv->tx[i].ones = 0xf; } // Tell the NIC where the init block is writeCSR(io, 1, ((uint32)(uint64)priv->init) & 0x0000ffff); writeCSR(io, 2, (((uint32)(uint64)priv->init) & 0xffff0000) >> 16); // Switch NIC state to INIT writeCSR(io, 0, (readCSR(io, 0) | CSR0_INIT) & ~ CSR0_STOP); printf(" INIT"); writeCSR(io, 4, (readCSR(io, 4)|CSR4_DMA_PLUSA|CSR4_APAD_XMIT|CSR4_TXSTRTM) & ~CSR4_DPOLL); writeBCR(io, 2, readBCR(io, 2)|BCR2_ASEL); //writeCSR(io, 3, (readCSR(io, 3)) & ~CSR3_ALL_INTS); //writeCSR(io, 4, (readCSR(io, 4)) & ~CSR4_ALL_INTS); // Switch NIC state to START, enable RX/TX, disable STOP and enable interrupts writeCSR(io, 0, (readCSR(io, 0)|CSR0_STRT|/*CSR0_IENA|*/CSR0_RXON|CSR0_TXON) & ~CSR0_STOP); printf(" STRT\n"); return 0; //fail_free_eth: // eth_free(eth); fail_free_tx: kfree(priv->tx); fail_free_rx: kfree(priv->rx); fail_free_init: kfree(priv->init); fail_free_private: kfree(priv); fail: return -1; }
uint16_t pci_read16(uint32_t id, uint32_t reg) { uint32_t addr = 0x80000000 | id | (reg & 0xfc); outportl(PCI_CONFIG_ADDR, addr); return inportw(PCI_CONFIG_DATA + (reg & 0x02)); }
static uint16_t rddm16(CMI8738_Driver_t* ds, uint32_t offset) { return inportw(ds->base_addr + offset); }
irqreturn_t nic_8019_rx(int irq, void *dev_id, struct pt_regs *regs) { u8 RxPageBeg, RxPageEnd; u8 RxNextPage; u8 RxStatus; u16 *data,temp; u16 i, RxLength,RxLen; struct sk_buff *skb; struct net_device *dev = (struct net_device *) dev_id; struct nic_8019_priv *priv = (struct nic_8019_priv *) dev->priv; TRACE("TX/RX Interupt!\n"); spin_lock(&priv->lock); SetRegPage(0); outportb(BNRY, rBNRY); //??? RxStatus = inportb(ISR); if (RxStatus & 2) { outportb(ISR, 0x2); //clr TX interupt priv->stats.tx_packets++; TRACE("transmit one packet complete!\n"); } if (RxStatus & 1) { TRACE("Receivex packet....\n"); outportb(ISR, 0x1); //clr Rx interupt SetRegPage(1); RxPageEnd = inportb(CURR); SetRegPage(0); RxPageBeg = rBNRY+1; if(RxPageBeg>=RPSTOP) RxPageBeg = RPSTART; outportb(BaseAddr, 0x22); // stop remote dma //outport(RSAR0, RxPageBeg<<8); //outport(RBCR0, 256); outportb(RSAR0, 0); outportb(RSAR1, RxPageBeg); outportb(RBCR0, 4); outportb(RBCR1, 0); outportb(BaseAddr, 0xa); #ifdef RTL8019_OP_16 temp = inportw(RWPORT); RxNextPage = temp>>8; RxStatus = temp&0xff; RxLength = inportw(RWPORT); #else RxStatus = inportb(RWPORT); RxNextPage = inportb(RWPORT); RxLength = inportb(RWPORT); RxLength |= inportb(RWPORT)<<8; #endif TRACE("\nRxBeg = %x, RxEnd = %x, nextpage = %x, size = %i\n", RxPageBeg, RxPageEnd, RxNextPage, RxLength); RxLength -= 4; if (RxLength>ETH_FRAME_LEN) { if (RxPageEnd==RPSTART) rBNRY = RPSTOP-1; else rBNRY = RxPageEnd-1; outportb(BNRY, rBNRY); TRACE("RxLength more long than %x\n", ETH_FRAME_LEN); return IRQ_HANDLED; } skb = dev_alloc_skb(RxLength+2); if (!skb) { TRACE("Rtl8019as eth: low on mem - packet dropped\n"); priv->stats.rx_dropped++; return IRQ_HANDLED; } skb->dev = dev; skb_reserve(skb, 2); skb_put(skb, RxLength); data = ( u16 *)skb->data; // eth_copy_and_sum(skb, data, len, 0); outportb(RSAR0, 4); outportb(RSAR1, RxPageBeg); outportb(RBCR0, RxLength); outportb(RBCR1, RxLength>>8); outportb(BaseAddr, 0xa); #ifdef RTL8019_OP_16 i = 2; data -= 2; RxLen=(RxLength+1)/2; #else i = 4; data -= 4; RxLen=RxLength; #endif for(; RxLen--;) { #ifdef RTL8019_OP_16 static const int cmp_val = 0x7f; #else static const int cmp_val = 0xff; #endif if (!(i & cmp_val)) { outportb(BNRY, RxPageBeg); RxPageBeg++; if(RxPageBeg>=RPSTOP) RxPageBeg = RPSTART; } #ifdef RTL8019_OP_16 data[i++] = inportw(RWPORT); TRACE("%2X,%2X,", data[i-1]&0xff,data[i-1]>>8); #else data[i++] = inportb(RWPORT); TRACE("%2X,", data[i-1]); #endif } TRACE("\n"); outportb(BNRY, RxPageBeg); rBNRY = RxPageBeg; skb->protocol = eth_type_trans(skb, dev); TRACE("\nprotocol=%x\n", skb->protocol); priv->stats.rx_packets++; priv->stats.rx_bytes +=RxLength; netif_rx(skb); } else {
inline uint16_t regin(uint16_t reg){ outportw(0x01CE,reg); return inportw(0x01CF); }
int vm86_emulate(struct vm86_context *vm86ctx) { int eaten = 1; int data32 = 0, addr32 = 0, rep = 0, segp = 0; int done = 0; uint16_t ip = LOWORD(vm86ctx->eip), sp = LOWORD(vm86ctx->esp); do { switch(*(uint8_t *)LADDR(vm86ctx->cs, ip)) { case 0x66: /*32-bit data*/ data32=1; break; case 0x67: /*32-bit addr*/ addr32=1; break; case 0xf2: /*REPNZ/REPNE*/ rep=1; break; case 0xf3: /*REP/REPZ/REPE*/ rep=1; break; case 0x2e: /*CS*/ segp=56; break; case 0x3e: /*DS*/ segp=76; break; case 0x26: /*ES*/ segp=72; break; case 0x36: /*SS*/ segp=68; break; case 0x65: /*GS*/ segp=84; break; case 0x64: /*FS*/ segp=80; break; case 0xf0: /*LOCK*/ break; default: done = 1; break; } if(done) break; ip++; } while(1); switch(*(uint8_t *)LADDR(vm86ctx->cs, ip)) { case 0xfa: /*CLI*/ vm86ctx->eflags &= ~EFLAGS_IF; ip++; break; case 0xfb: /*STI*/ vm86ctx->eflags |= EFLAGS_IF; ip++; break; case 0x9c: /*PUSHF*/ if(data32) { sp -= 4; *(uint32_t *)LADDR(vm86ctx->ss, sp) = vm86ctx->eflags & 0x001cffff; } else { sp -= 2; *(uint16_t *)LADDR(vm86ctx->ss, sp) = (uint16_t)vm86ctx->eflags; } ip++; break; case 0x9d: /*POPF*/ if(data32) { uint32_t eflags = *(uint32_t *)LADDR(vm86ctx->ss, sp); vm86ctx->eflags &= 0x1b3000/*VM, RF, IOPL, VIP, VIF*/; eflags &= ~0x1b3000; vm86ctx->eflags |= eflags; sp += 4; } else { uint32_t eflags = *(uint16_t *)LADDR(vm86ctx->ss, sp); vm86ctx->eflags &= 0xffff3000/*IOPL*/; eflags &= ~0xffff3000; vm86ctx->eflags |= eflags; sp += 2; } ip++; break; case 0xcd: /*INT*/ sp -= 2; *(uint16_t *)LADDR(vm86ctx->ss, sp) = (uint16_t)vm86ctx->eflags; sp -= 2; *(uint16_t *)LADDR(vm86ctx->ss, sp) = vm86ctx->cs; sp -= 2; *(uint16_t *)LADDR(vm86ctx->ss, sp) = ip + 2; { uint16_t *ivt = (uint16_t *)0; uint8_t x = *(uint8_t *)LADDR(vm86ctx->cs, ip + 1); ip = ivt[x * 2 + 0]; vm86ctx->cs = ivt[x * 2 + 1]; } break; case 0xcf: /*IRET*/ if(data32) { ip = *(uint32_t *)LADDR(vm86ctx->ss, sp); sp += 4; vm86ctx->cs = *(uint32_t *)LADDR(vm86ctx->ss, sp); sp += 4; uint32_t eflags = *(uint32_t *)LADDR(vm86ctx->ss, sp); vm86ctx->eflags &= 0x1a3000/*VM, IOPL, VIP, VIF*/; eflags &= ~0x1a3000; vm86ctx->eflags |= eflags; sp += 4; } else { ip = *(uint16_t *)LADDR(vm86ctx->ss, sp); sp += 2; vm86ctx->cs = *(uint16_t *)LADDR(vm86ctx->ss, sp); sp += 2; uint32_t eflags = *(uint16_t *)LADDR(vm86ctx->ss, sp); vm86ctx->eflags &= 0xffff3000/*IOPL*/; eflags &= ~0xffff3000; vm86ctx->eflags |= eflags; sp += 2; } break; case 0xe6:/*OUT imm8, AL*/ outportb(*(uint8_t *)LADDR(vm86ctx->cs, ip + 1), LOBYTE(LOWORD(vm86ctx->eax))); ip += 2; break; case 0xe7:/*OUT imm8, (E)AX*/ if(data32) { outportl(*(uint8_t *)LADDR(vm86ctx->cs, ip + 1), vm86ctx->eax); } else { outportw(*(uint8_t *)LADDR(vm86ctx->cs, ip + 1), LOWORD(vm86ctx->eax)); } ip += 2; break; case 0xee:/*OUT DX, AL*/ outportb(LOWORD(vm86ctx->edx), LOBYTE(LOWORD(vm86ctx->eax))); ip++; break; case 0xef:/*OUT DX, (E)AX*/ if(data32) { outportl(LOWORD(vm86ctx->edx), vm86ctx->eax); } else { outportw(LOWORD(vm86ctx->edx), LOWORD(vm86ctx->eax)); } ip++; break; case 0xe4:/*IN AL, imm8*/ { uint8_t al = inportb(*(uint8_t *)LADDR(vm86ctx->cs, ip + 1)); vm86ctx->eax = (vm86ctx->eax & 0xffffff00) | al; } ip += 2; break; case 0xe5:/*IN (E)AX, imm8*/ if(data32) { vm86ctx->eax = inportl(*(uint8_t *)LADDR(vm86ctx->cs, ip + 1)); } else { uint16_t ax = inportw(*(uint8_t *)LADDR(vm86ctx->cs, ip + 1)); vm86ctx->eax = (vm86ctx->eax & 0xffff0000) | ax; } ip += 2; break; case 0xec:/*IN AL, DX*/ { uint8_t al = inportb(LOWORD(vm86ctx->edx)); vm86ctx->eax = (vm86ctx->eax & 0xffffff00) | al; } ip += 1; break; case 0xed:/*IN (E)AX, DX*/ if(data32) { vm86ctx->eax = inportl(LOWORD(vm86ctx->edx)); } else { uint16_t ax = inportw(LOWORD(vm86ctx->edx)); vm86ctx->eax = (vm86ctx->eax & 0xffff0000) | ax; } ip++; break; case 0x6c:/*INSB; INS m8, DX*/ { if(addr32) { uint32_t ecx = rep ? vm86ctx->ecx : 1; while(ecx) { *(uint8_t *)LADDR(vm86ctx->es, vm86ctx->edi/*XXX*/) = inportb(LOWORD(vm86ctx->edx)); ecx--; vm86ctx->edi += (vm86ctx->eflags & 0x400)?-1:1; } if(rep) vm86ctx->ecx = ecx; } else { uint16_t cx=rep ? LOWORD(vm86ctx->ecx) : 1, di=LOWORD(vm86ctx->edi); while(cx) { *(uint8_t *)LADDR(vm86ctx->es, di) = inportb(LOWORD(vm86ctx->edx)); cx--; di += (vm86ctx->eflags & 0x400)?-1:1; } if(rep) vm86ctx->ecx = (vm86ctx->ecx & 0xffff0000) | cx; vm86ctx->edi = (vm86ctx->edi & 0xffff0000) | di; } } ip++; break; case 0x6d:/*INSW; INSD; INS m16/m32, DX*/ { if(addr32) { uint32_t ecx = rep ? vm86ctx->ecx : 1; while(ecx) { if(data32) { *(uint32_t *)LADDR(vm86ctx->es, vm86ctx->edi/*XXX*/) = inportl(LOWORD(vm86ctx->edx)); vm86ctx->edi += (vm86ctx->eflags & 0x400)?-4:4; } else { *(uint16_t *)LADDR(vm86ctx->es, vm86ctx->edi/*XXX*/) = inportw(LOWORD(vm86ctx->edx)); vm86ctx->edi += (vm86ctx->eflags & 0x400)?-2:2; } ecx--; } if(rep) vm86ctx->ecx = ecx; } else { uint16_t cx=rep ? LOWORD(vm86ctx->ecx) : 1, di=LOWORD(vm86ctx->edi); while(cx) { if(data32) { *(uint32_t *)LADDR(vm86ctx->es, di) = inportl(LOWORD(vm86ctx->edx)); di += (vm86ctx->eflags & 0x400)?-4:4; } else { *(uint16_t *)LADDR(vm86ctx->es, di) = inportw(LOWORD(vm86ctx->edx)); di += (vm86ctx->eflags & 0x400)?-2:2; } cx--; } if(rep) vm86ctx->ecx = (vm86ctx->ecx & 0xffff0000) | cx; vm86ctx->edi = (vm86ctx->edi & 0xffff0000) | di; } } ip++; break; case 0x6e:/*OUTSB; OUTS DX, m8*/ { uint16_t seg = vm86ctx->ds; if(segp) seg = *(uint16_t *)(((uint8_t *)vm86ctx)+segp); if(addr32) { uint32_t ecx = rep ? vm86ctx->ecx : 1; while(ecx) { outportb(LOWORD(vm86ctx->edx), *(uint8_t *)LADDR(seg, vm86ctx->esi/*XXX*/)); ecx--; vm86ctx->esi += (vm86ctx->eflags & 0x400)?-1:1; } if(rep) vm86ctx->ecx = ecx; } else { uint16_t cx=rep ? LOWORD(vm86ctx->ecx) : 1, si=LOWORD(vm86ctx->esi); while(cx) { outportb(LOWORD(vm86ctx->edx), *(uint8_t *)LADDR(seg, si)); cx--; si += (vm86ctx->eflags & 0x400)?-1:1; } if(rep) vm86ctx->ecx = (vm86ctx->ecx & 0xffff0000) | cx; vm86ctx->esi = (vm86ctx->esi & 0xffff0000) | si; } } ip++; break; case 0x6f:/*OUTSW; OUTSD; OUTS DX, m16/32*/ { uint16_t seg = vm86ctx->ds; if(segp) seg = *(uint16_t *)(((uint8_t *)vm86ctx)+segp); if(addr32) { uint32_t ecx = rep ? vm86ctx->ecx : 1; while(ecx) { if(data32) { outportl(LOWORD(vm86ctx->edx), *(uint32_t *)LADDR(seg, vm86ctx->esi/*XXX*/)); vm86ctx->esi += (vm86ctx->eflags & 0x400)?-4:4; } else { outportw(LOWORD(vm86ctx->edx), *(uint16_t *)LADDR(seg, vm86ctx->esi/*XXX*/)); vm86ctx->esi += (vm86ctx->eflags & 0x400)?-2:2; } ecx--; } if(rep) vm86ctx->ecx = ecx; } else { uint16_t cx=rep ? LOWORD(vm86ctx->ecx) : 1, si=LOWORD(vm86ctx->esi); while(cx) { if(data32) { outportl(LOWORD(vm86ctx->edx), *(uint32_t *)LADDR(seg, si)); si += (vm86ctx->eflags & 0x400)?-4:4; } else { outportw(LOWORD(vm86ctx->edx), *(uint16_t *)LADDR(seg, si)); si += (vm86ctx->eflags & 0x400)?-2:2; } cx--; } if(rep) vm86ctx->ecx = (vm86ctx->ecx & 0xffff0000) | cx; vm86ctx->esi = (vm86ctx->esi & 0xffff0000) | si; } } ip++; break; default: eaten = 0; break; } vm86ctx->eip = (vm86ctx->eip & 0xffff0000) | ip; vm86ctx->esp = (vm86ctx->esp & 0xffff0000) | sp; return eaten; }