void mc68681_device::update_interrupts() { /* update SR state and update interrupt ISR state for the following bits: SRn: bits 7-4: handled elsewhere. SRn: bit 3 (TxEMTn) (we can assume since we're not actually emulating the delay/timing of sending bits, that as long as TxRDYn is set, TxEMTn is also set since the transmit byte has 'already happened', therefore TxEMTn is always 1 assuming tx is enabled on channel n and the MSR2n mode is 0 or 2; in mode 1 it is explicitly zeroed, and mode 3 is undefined) SRn: bit 2 (TxRDYn) (we COULD assume since we're not emulating delay and timing output, that as long as tx is enabled on channel n, TxRDY is 1 for channel n and the MSR2n mode is 0 or 2; in mode 1 it is explicitly zeroed, and mode 3 is undefined; however, tx_ready is already nicely handled for us elsewhere, so we can use that instead for now, though we may need to retool that code as well) SRn: bit 1 (FFULLn) (this bit we actually emulate; if the receive fifo for channel n is full, this bit is 1, otherwise it is 0. the receive fifo should be three words long.) SRn: bit 0 (RxRDYn) (this bit we also emulate; the bit is always asserted if the receive fifo is not empty) ISR: bit 7: Input Port change; this should be handled elsewhere, on the input port handler ISR: bit 6: Delta Break B; this should be handled elsewhere, on the data receive handler ISR: bit 5: RxRDYB/FFULLB: this is handled here; depending on whether MSR1B bit 6 is 0 or 1, this bit holds the state of SRB bit 0 or bit 1 respectively ISR: bit 4: TxRDYB: this is handled here; it mirrors SRB bit 2 ISR: bit 3: Counter ready; this should be handled by the timer generator ISR: bit 2: Delta Break A; this should be handled elsewhere, on the data receive handler ISR: bit 1: RxRDYA/FFULLA: this is handled here; depending on whether MSR1A bit 6 is 0 or 1, this bit holds the state of SRA bit 0 or bit 1 respectively ISR: bit 0: TxRDYA: this is handled here; it mirrors SRA bit 2 */ if ( (ISR & IMR) != 0 ) { LOG(( "68681: Interrupt line active (IMR & ISR = %02X)\n", (ISR & IMR) )); write_irq(ASSERT_LINE); } else { LOG(( "68681: Interrupt line not active (IMR & ISR = %02X)\n", ISR & IMR)); write_irq(CLEAR_LINE); m_read_vector = false; // clear IACK too } };
void duart_base_device::device_reset() { ACR = 0; /* Interrupt Vector Register */ IMR = 0; /* Interrupt Mask Register */ ISR = 0; /* Interrupt Status Register */ OPCR = 0; /* Output Port Conf. Register */ OPR = 0; /* Output Port Register */ CTR.d = 0; /* Counter/Timer Preset Value */ // "reset clears internal registers (SRA, SRB, IMR, ISR, OPR, OPCR) puts OP0-7 in the high state, stops the counter/timer, and puts channels a/b in the inactive state" IPCR = 0; write_irq(CLEAR_LINE); write_outport(OPR ^ 0xff); }
virtual void write( nes_time_t time, nes_addr_t addr, int data ) { switch ( addr & 0xE000 ) { case 0x8000: command = data & 0x0F; break; case 0xA000: if ( command < 0x0D ) write_register( command, data ); else write_irq( time, command, data ); break; case 0xC000: sound.write_latch( data ); break; case 0xE000: sound.write_data( time, data ); break; } }
/* Open/initialize the board. This is called (in the current kernel) sometime after booting when the 'ifconfig' program is run. This routine should set everything up anew at each open, even registers that "should" only need to be set once at boot, so that there is non-reboot way to recover if something goes wrong. */ static int net_open(struct device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int result = 0; // int i; write_irq(dev, lp->chip_type, 0); irq2dev_map[/* FIXME */ 0] = dev; writereg(dev, PP_BusCTL, 0); /* ints off! */ #ifdef CONFIG_UCSIMM *(volatile unsigned short *)0xfffff302 |= 0x0080; /* +ve pol irq */ if (request_irq(IRQ_MACHSPEC | IRQ5_IRQ_NUM, cs8900_interrupt, IRQ_FLG_STD, "CrystalLAN_cs8900a", NULL)) panic("Unable to attach cs8900 intr\n"); #endif #ifdef CONFIG_ARCH_ATMEL /* We use IRQ_IRQ1 for the network interrupt */ if (request_irq(IRQ_MACHSPEC | IRQ_IRQ1, cs8900_interrupt, IRQ_FLG_STD, "CrystalLAN_cs8900a", NULL)) panic("Unable to attach cs8900 intr\n"); #endif #ifdef CONFIG_ALMA_ANS /* We use positive polarity IRQ3 as a network interrupt */ ICR |= ICR_POL3; if (request_irq(IRQ_MACHSPEC | IRQ3_IRQ_NUM, cs8900_interrupt, IRQ_FLG_STD, "CrystalLAN_cs8900a", NULL)) panic("Unable to attach cs8900 intr\n"); #endif #ifdef CONFIG_MWI /* We use vector position 28 as network interrupt */ if (request_irq(IRQ_MACHSPEC| 28, cs8900_interrupt, IRQ_FLG_STD, "cs8900a", NULL)) panic("Unable to attach cs8900 intr\n"); /* setup porte */ *(volatile unsigned char *)0xfffa15 &= 0xfb; *(volatile unsigned char *)0xfffa17 |= 0x04; /* setup portf */ *(volatile unsigned char *)0xfffa1d &= 0x7f; *(volatile unsigned char *)0xfffa1f |= 0x10; #endif /* set the Ethernet address */ set_mac_address(dev, dev->dev_addr); /* Set the LineCTL */ lp->linectl = 0; /* check to make sure that they have the "right" hardware available */ switch(lp->adapter_cnf & A_CNF_MEDIA_TYPE) { case A_CNF_MEDIA_10B_T: result = lp->adapter_cnf & A_CNF_10B_T; break; case A_CNF_MEDIA_AUI: result = lp->adapter_cnf & A_CNF_AUI; break; case A_CNF_MEDIA_10B_2: result = lp->adapter_cnf & A_CNF_10B_2; break; default: result = lp->adapter_cnf & (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2); } if (!result) { printk("%s: EEPROM is configured for unavailable media\n", dev->name); release_irq: writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON)); irq2dev_map[dev->irq] = 0; return -EAGAIN; } /* set the hardware to the configured choice */ switch(lp->adapter_cnf & A_CNF_MEDIA_TYPE) { case A_CNF_MEDIA_10B_T: result = detect_tp(dev); if (!result) printk("%s: 10Base-T (RJ-45) has no cable\n", dev->name); if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */ result = A_CNF_MEDIA_10B_T; /* Yes! I don't care if I see a link pulse */ break; case A_CNF_MEDIA_AUI: printk("AUI? What stinking AUI?\n"); break; case A_CNF_MEDIA_10B_2: printk("10Base2? What stinking 10Base2?\n"); break; case A_CNF_MEDIA_AUTO: writereg(dev, PP_LineCTL, lp->linectl | AUTO_AUI_10BASET); if (lp->adapter_cnf & A_CNF_10B_T) if ((result = detect_tp(dev)) != 0) break; printk("%s: no media detected\n", dev->name); goto release_irq; } switch(result) { case 0: printk("%s: no network cable attached to configured media\n", dev->name); goto release_irq; case A_CNF_MEDIA_10B_T: printk("%s: using 10Base-T (RJ-45)\n", dev->name);break; case A_CNF_MEDIA_AUI: printk("%s: using 10Base-5 (AUI)\n", dev->name);break; case A_CNF_MEDIA_10B_2: printk("%s: using 10Base-2 (BNC)\n", dev->name);break; default: printk("%s: unexpected result was %x\n", dev->name, result); goto release_irq; } /* Turn on both receive and transmit operations */ writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON); /* Receive only error free packets addressed to this card */ lp->rx_mode = 0; writereg(dev, PP_RxCTL, DEF_RX_ACCEPT); lp->curr_rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL; if (lp->isa_config & STREAM_TRANSFER) lp->curr_rx_cfg |= RX_STREAM_ENBL; writereg(dev, PP_RxCFG, lp->curr_rx_cfg); writereg(dev, PP_TxCFG, TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL | TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL); writereg(dev, PP_BufCFG, READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL | TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL); /* now that we've got our act together, enable everything */ writereg(dev, PP_BusCTL, ENABLE_IRQ ); dev->tbusy = 0; dev->interrupt = 0; dev->start = 1; return 0; }
/* Open/initialize the board. This is called (in the current kernel) sometime after booting when the 'ifconfig' program is run. This routine should set everything up anew at each open, even registers that "should" only need to be set once at boot, so that there is non-reboot way to recover if something goes wrong. */ static int net_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int result = 0; write_irq(dev, lp->chip_type, 0); /* irq2dev_map[0] = dev; */ writereg(dev, PP_BusCTL, 0); /* ints off! */ #ifdef CONFIG_UCSIMM *(volatile unsigned short *)0xfffff302 |= 0x0080; /* +ve pol irq */ dev->irq = IRQ5_IRQ_NUM; if (request_irq(dev->irq | IRQ_MACHSPEC, cs8900_interrupt, IRQ_FLG_STD, "CrystalLAN_cs8900a", NULL)) panic("Unable to attach cs8900 intr\n"); #endif #ifdef CONFIG_ARCH_ATMEL /* Set IRQ1 with high level sensitive & priority level 6. */ *(volatile unsigned int *) AIC_SMR(IRQ_IRQ1) = 0x46; /* We use IRQ_IRQ1 for the network interrupt */ dev->irq = IRQ_IRQ1; if (request_irq(dev->irq, cs8900_interrupt, IRQ_FLG_STD, "CrystalLAN_cs8900a", NULL)) panic("Unable to attach cs8900 intr\n"); #endif #if defined (CONFIG_BOARD_UCLINKII) || \ defined (CONFIG_BOARD_EVS3C4530LII) || \ defined (CONFIG_BOARD_EVS3C4530HEI) *(volatile unsigned int *)IOPCON0 |= (xINTREQ0_ENABLE | xINTREQ0_ACT_HI); dev->irq = _IRQ0; if (request_irq (dev->irq, cs8900_interrupt, 0, "Crystal_CS8900", dev)) panic("Unable to attach cs8900 intr\n"); #endif #ifdef CONFIG_ALMA_ANS /* We use positive polarity IRQ3 as a network interrupt */ ICR |= ICR_POL3; dev->irq = IRQ3_IRQ_NUM; if (request_irq(dev->irq | IRQ_MACHSPEC, cs8900_interrupt, IRQ_FLG_STD, "CrystalLAN_cs8900a", NULL)) panic("Unable to attach cs8900 intr\n"); #endif /* set the Ethernet address */ set_mac_address(dev, dev->dev_addr); /* Set the LineCTL */ lp->linectl = 0; /* check to make sure that they have the "right" hardware available */ switch(lp->adapter_cnf & A_CNF_MEDIA_TYPE) { case A_CNF_MEDIA_10B_T: result = lp->adapter_cnf & A_CNF_10B_T; break; case A_CNF_MEDIA_AUI: result = lp->adapter_cnf & A_CNF_AUI; break; case A_CNF_MEDIA_10B_2: result = lp->adapter_cnf & A_CNF_10B_2; break; default: result = lp->adapter_cnf & (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2); } if (!result) { printk("%s: EEPROM is configured for unavailable media\n", dev->name); release_irq: writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON)); /* so subsequent opens don't fail we release the IRQ ...MaTed--- */ free_irq( dev->irq, dev); /* irq2dev_map[dev->irq] = 0; */ return -EAGAIN; } /* set the hardware to the configured choice */ switch(lp->adapter_cnf & A_CNF_MEDIA_TYPE) { case A_CNF_MEDIA_10B_T: result = detect_tp(dev); if (!result) { printk("%s: 10Base-T (RJ-45) has no cable\n", dev->name); if (lp->auto_neg_cnf & IMM_BIT) { /* check "ignore missing media" bit */ printk("%s: but ignore the fact.\n", dev->name); result = A_CNF_MEDIA_10B_T; /* Yes! I don't care if I see a link pulse */ } } break; case A_CNF_MEDIA_AUI: printk("AUI is not supported by uCcs8900\n"); break; case A_CNF_MEDIA_10B_2: printk("10Base2 is not supported by uCcs8900\n"); break; case A_CNF_MEDIA_AUTO: writereg(dev, PP_LineCTL, lp->linectl | AUTO_AUI_10BASET); if (lp->adapter_cnf & A_CNF_10B_T) if ((result = detect_tp(dev)) != 0) break; printk("%s: no media detected\n", dev->name); goto release_irq; } switch(result) { case 0: printk("%s: no network cable attached to configured media\n", dev->name); goto release_irq; case A_CNF_MEDIA_10B_T: printk("%s: using 10Base-T (RJ-45)\n", dev->name);break; case A_CNF_MEDIA_AUI: printk("%s: using 10Base-5 (AUI)\n", dev->name);break; case A_CNF_MEDIA_10B_2: printk("%s: using 10Base-2 (BNC)\n", dev->name);break; default: printk("%s: unexpected result was %x\n", dev->name, result); goto release_irq; } /* Turn on both receive and transmit operations */ writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON); /* Receive only error free packets addressed to this card */ lp->rx_mode = 0; writereg(dev, PP_RxCTL, DEF_RX_ACCEPT); lp->curr_rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL; if (lp->isa_config & STREAM_TRANSFER) lp->curr_rx_cfg |= RX_STREAM_ENBL; writereg(dev, PP_RxCFG, lp->curr_rx_cfg); writereg(dev, PP_TxCFG, TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL | TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL); writereg(dev, PP_BufCFG, READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL | TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL); /* now that we've got our act together, enable everything */ writereg(dev, PP_BusCTL, ENABLE_IRQ ); netif_start_queue(dev); return 0; }