Example #1
0
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));
}
Example #2
0
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;
}
Example #3
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
}
Example #4
0
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);
}
Example #5
0
/*
 * 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;
}
Example #6
0
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;
}
Example #7
0
File: pci.c Project: levex/levos5
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));

}
Example #8
0
File: pci.c Project: juur/FailOS
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;
}
Example #9
0
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
}
Example #10
0
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);
	}
}
Example #11
0
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);
	}
}
Example #12
0
/*
 * 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;
}
Example #13
0
File: pcnet.c Project: juur/FailOS
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;
}
Example #14
0
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));
}
Example #15
0
static uint16_t rddm16(CMI8738_Driver_t* ds, uint32_t offset)
{
    return inportw(ds->base_addr + offset);
}
Example #16
0
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 {
Example #17
0
File: boc2.cpp Project: neri/op05
inline uint16_t regin(uint16_t reg){
	outportw(0x01CE,reg);
	return inportw(0x01CF);
}
Example #18
0
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;
}