/** This routine returns the current interrupt status and/or the transmitted buffer addresses. If the current interrupt status is returned, pending interrupts will be acknowledged by this command. Transmitted buffer addresses that are written to the DB are removed from the transmit buffer queue. Normally, this command would be polled with interrupts disabled. The transmit buffers are returned in CdbPtr->DBaddr->TxBufer[0 - NumEntries]. The interrupt status is returned in CdbPtr->StatFlags. @param CdbPtr Pointer to the command descriptor block. @param AdapterInfo Pointer to the NIC data structure information which the UNDI driver is layering on.. @return None **/ VOID UNDI_Status ( IN PXE_CDB *CdbPtr, IN NIC_DATA_INSTANCE *AdapterInfo ) { PXE_DB_GET_STATUS *DbPtr; PXE_DB_GET_STATUS TmpGetStatus; UINT16 Index; UINT16 Status; UINT16 NumEntries; RxFD *RxPtr; // // Fill in temporary GetStatus storage. // RxPtr = &AdapterInfo->rx_ring[AdapterInfo->cur_rx_ind]; if ((RxPtr->cb_header.status & RX_COMPLETE) != 0) { TmpGetStatus.RxFrameLen = RxPtr->ActualCount & 0x3fff; } else { TmpGetStatus.RxFrameLen = 0; } TmpGetStatus.reserved = 0; // // Fill in size of next available receive packet and // reserved field in caller's DB storage. // DbPtr = (PXE_DB_GET_STATUS *) (UINTN) CdbPtr->DBaddr; if (CdbPtr->DBsize > 0 && CdbPtr->DBsize < sizeof (UINT32) * 2) { CopyMem (DbPtr, &TmpGetStatus, CdbPtr->DBsize); } else { CopyMem (DbPtr, &TmpGetStatus, sizeof (UINT32) * 2); } // // // if ((CdbPtr->OpFlags & PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS) != 0) { // // DBsize of zero is invalid if Tx buffers are requested. // if (CdbPtr->DBsize == 0) { CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED; CdbPtr->StatCode = PXE_STATCODE_INVALID_CDB; return ; } // // remember this b4 we overwrite // NumEntries = (UINT16) (CdbPtr->DBsize - sizeof (UINT64)); // // We already filled in 2 UINT32s. // CdbPtr->DBsize = sizeof (UINT32) * 2; // // will claim any hanging free CBs // CheckCBList (AdapterInfo); if (AdapterInfo->xmit_done_head == AdapterInfo->xmit_done_tail) { CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY; } else { for (Index = 0; NumEntries >= sizeof (UINT64); Index++, NumEntries -= sizeof (UINT64)) { if (AdapterInfo->xmit_done_head != AdapterInfo->xmit_done_tail) { DbPtr->TxBuffer[Index] = AdapterInfo->xmit_done[AdapterInfo->xmit_done_head]; AdapterInfo->xmit_done_head = next (AdapterInfo->xmit_done_head); CdbPtr->DBsize += sizeof (UINT64); } else { break; } } } if (AdapterInfo->xmit_done_head != AdapterInfo->xmit_done_tail) { CdbPtr->StatFlags |= PXE_STATFLAGS_DB_WRITE_TRUNCATED; } // // check for a receive buffer and give it's size in db // } // // // if ((CdbPtr->OpFlags & PXE_OPFLAGS_GET_INTERRUPT_STATUS) != 0) { Status = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus); AdapterInfo->Int_Status = (UINT16) (AdapterInfo->Int_Status | Status); // // acknoledge the interrupts // OutWord (AdapterInfo, (UINT16) (Status & 0xfc00), (UINT32) (AdapterInfo->ioaddr + SCBStatus)); // // report all the outstanding interrupts // Status = AdapterInfo->Int_Status; if ((Status & SCB_STATUS_FR) != 0) { CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_RECEIVE; } if ((Status & SCB_STATUS_SWI) != 0) { CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_SOFTWARE; } } // // Return current media status // if ((CdbPtr->OpFlags & PXE_OPFLAGS_GET_MEDIA_STATUS) != 0) { AdapterInfo->PhyAddress = 0xFF; AdapterInfo->CableDetect = 1; if (!PhyDetect (AdapterInfo)) { CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_NO_MEDIA; } } return ; }
int V86HandleOpcode (struct ContextState *state) { bool is_operand32 = FALSE; bool is_address32 = FALSE; uint32 *sp32; uint16 *sp16; uint32 eflags; uint8 *ip; uint32 new_ip; uint32 new_cs; uint8 *vector; while (1) { ip = V86GetAddress (state->return_eip, state->return_cs); switch (*ip) { case PREFIX_O32: is_operand32 = TRUE; state->return_eip = (state->return_eip + 1) & 0x0000ffff; continue; case PREFIX_A32: is_address32 = TRUE; ip++; state->return_eip = (state->return_eip + 1) & 0x0000ffff; continue; case OPCODE_PUSHF: if (is_operand32 == TRUE) { state->return_esp = ((state->return_esp & 0x0000ffff) - 4) & 0x0000ffff; sp32 = V86GetAddress (state->return_esp, state->return_ss); eflags = state->return_eflags & V86_EFLAG_MASK; *sp32 = (v86_if == TRUE) ? eflags | EFLAG_IF : eflags & ~EFLAG_IF; } else { state->return_esp = ((state->return_esp & 0x0000ffff) - 2) & 0x0000ffff; sp16 = V86GetAddress (state->return_esp, state->return_ss); eflags = state->return_eflags & V86_EFLAG_MASK; *sp16 = (uint16) (v86_if == TRUE) ? eflags | EFLAG_IF : eflags & ~EFLAG_IF; } state->return_eip = (state->return_eip + 1) & 0x0000ffff; return 0; case OPCODE_POPF: if (is_operand32 == TRUE) { sp32 = V86GetAddress (state->return_esp, state->return_ss); eflags = *sp32; state->return_eflags = (eflags & V86_EFLAG_MASK) | EFLAG_IF | EFLAG_VM; v86_if = (eflags & EFLAG_IF) ? TRUE : FALSE; state->return_esp = ((state->return_esp & 0x0000ffff) + 4) & 0x0000ffff; } else { sp16 = V86GetAddress (state->return_esp, state->return_ss); eflags = *sp16; state->return_eflags = (eflags & V86_EFLAG_MASK) | EFLAG_IF | EFLAG_VM; v86_if = (eflags & EFLAG_IF) ? TRUE : FALSE; state->return_esp = ((state->return_esp & 0x0000ffff) + 2) & 0x0000ffff; } state->return_eip = (state->return_eip + 1) & 0x0000ffff; return 0; case OPCODE_INT: { state->return_eip = (state->return_eip + 1) & 0x0000ffff; vector = V86GetAddress (state->return_eip, state->return_cs); V86GetInterruptVector (*vector, &new_ip, &new_cs); state->return_eip = (state->return_eip + 1) & 0x0000ffff; state->return_esp = ((state->return_esp & 0x0000ffff) - 2) & 0x0000ffff; sp16 = V86GetAddress (state->return_esp, state->return_ss); *sp16 = (uint16) state->return_eip; state->return_esp = ((state->return_esp & 0x0000ffff) - 2) & 0x0000ffff; sp16 = V86GetAddress (state->return_esp, state->return_ss); *sp16 = (uint16) state->return_cs; state->return_esp = ((state->return_esp & 0x0000ffff) - 2) & 0x0000ffff; sp16 = V86GetAddress (state->return_esp, state->return_ss); eflags = (v86_if == TRUE) ? (state->return_eflags & V86_EFLAG_MASK) | EFLAG_IF : (state->return_eflags & V86_EFLAG_MASK) & ~EFLAG_IF; *sp16 = (uint16) eflags; state->return_eflags = (state->return_eflags & ~(EFLAG_IF | EFLAG_TF | EFLAG_AC)) | EFLAG_VM; v86_if = FALSE; state->return_eip = new_ip & 0x0000ffff; state->return_cs = new_cs & 0x0000ffff; return 0; } case OPCODE_IRET: if (state->return_eip == 0x0002 && state->return_cs == 0x1000) { return 1; } else { sp16 = V86GetAddress (state->return_esp, state->return_ss); eflags = *sp16; eflags = (eflags & 0x257fd5) | (state->return_eflags & 0x1a0000); state->return_eflags = eflags | EFLAG_IF | EFLAG_VM; v86_if = (eflags & EFLAG_IF) ? TRUE : FALSE; state->return_esp = ((state->return_esp & 0x0000ffff) + 2) & 0x0000ffff; sp16 = V86GetAddress (state->return_esp, state->return_ss); state->return_cs = *sp16; state->return_esp = ((state->return_esp & 0x0000ffff) + 2) & 0x0000ffff; sp16 = V86GetAddress (state->return_esp, state->return_ss); state->return_eip = *sp16; state->return_esp = ((state->return_esp & 0x0000ffff) + 2) & 0x0000ffff; return 0; } case OPCODE_CLI: v86_if = FALSE; state->return_eip = (state->return_eip + 1) & 0x0000ffff; return 0; case OPCODE_STI: v86_if = TRUE; state->return_eip = (state->return_eip + 1) & 0x0000ffff; return 0; case OPCODE_OUTB: OutByte (state->edx, state->eax); state->return_eip = (state->return_eip + 1) & 0x0000ffff; return 0; case OPCODE_INB: state->eax = InByte (state->edx); state->return_eip = (state->return_eip + 1) & 0x0000ffff; return 0; case OPCODE_OUTWL: if(is_operand32 == FALSE) OutWord (state->edx, state->eax); else OutLong (state->edx, state->eax); state->return_eip = (state->return_eip + 1) & 0x0000ffff; return 0; case OPCODE_INWL: if(is_operand32 == FALSE) state->eax = InWord (state->edx); else state->eax = InLong (state->edx); state->return_eip = (state->return_eip + 1) & 0x0000ffff; return 0; case OPCODE_OUTB_AL_NN: OutByte (*(ip+1), state->eax); state->return_eip = (state->return_eip + 2) & 0x0000ffff; return 0; case OPCODE_INB_NN_AL: state->eax = InByte (*(ip+1)); state->return_eip = (state->return_eip + 2) & 0x0000ffff; return 0; case OPCODE_OUTWL_EAX_NN: if (is_operand32 == FALSE) OutWord (*(ip+1), state->eax); else OutLong (*(ip+1), state->eax); state->return_eip = (state->return_eip + 2) & 0x0000ffff; return 0; case OPCODE_INWL_NN_EAX: if(is_operand32 == FALSE) state->eax = InWord (*(ip+1)); else state->eax = InLong (*(ip+1)); state->return_eip = (state->return_eip + 2) & 0x0000ffff; return 0; case OPCODE_HLT: { KPANIC ("Halt in V86"); } default: { KPRINTF ("opcode = %#010x", *ip); KPANIC ("#GP Unknown V86 opcode"); } } } }
static XmTextPosition Scan(XmTextSource source, XmTextPosition pos, XmTextScanType type, XmTextScanDirection dir, int count, Boolean inc) { XmSourceData d = source->data; Boolean found = False; char *ptr; #ifdef VERBOSE__LtDebug XmTextPosition ipos = pos; #endif if (pos > d->length) { #if 0 /* This is reported to be a bad idea. */ pos = d->length; #endif return(pos); } if (count < 0) { count = d->length; } /* * This may not be completely right. * If you start in whitespace, move towards non-whitespace before * doing anything else. * Currently, do this for XmSELECT_WORD. * It may be appropriate to do this for other selections as well. * Danny 4/6/97 */ if (dir == XmsdLeft && type == XmSELECT_WORD) { ptr = StrPtr(d, pos - 1); while (count > 0 && pos > 0 && InWhiteSpace(*ptr)) { pos--; ptr = StrPtr(d, pos - 1); } } else if (dir == XmsdRight && type == XmSELECT_WORD) { ptr = StrPtr(d, pos); while (count > 0 && pos < d->length && InWhiteSpace(*ptr)) { pos++; ptr = StrPtr(d, pos); } } /* End initial whitespace treatment */ if (dir == XmsdLeft) { while (count > 0 && pos > 0) { ptr = StrPtr(d, pos - 1); switch (type) { case XmSELECT_WHITESPACE: if (!InWhiteSpace(*ptr)) { found = True; } break; case XmSELECT_WORD: if (!InWord(*ptr)) { found = True; } break; case XmSELECT_LINE: if (*ptr == '\n') { found = True; } break; case XmSELECT_PARAGRAPH: if (*ptr == '\n') { found = True; } break; case XmSELECT_ALL: /*CP: probably a bit too simple */ found = True; pos = 0; break; default: found = True; break; } if (found) { #ifdef VERBOSE__LtDebug DEBUGOUT(_LtDebug(__FILE__, (Widget)d->widgets[0], "Scan(%d)=>%d\n", ipos, pos)); #endif count--; if ( count == 0 ) return ( inc ? pos - 1 : pos ); found = False; } pos--; } } else { /* dir == XmsdRight */ while (count > 0 && pos < d->length) { ptr = StrPtr(d, pos); switch (type) { case XmSELECT_WHITESPACE: if (!InWhiteSpace(*ptr)) { found = True; } break; case XmSELECT_WORD: if (!InWord(*ptr)) { found = True; } break; case XmSELECT_LINE: if (*ptr == '\n') { found = True; } break; case XmSELECT_PARAGRAPH: if (*ptr == '\n') { found = True; } break; case XmSELECT_ALL: if (! *ptr ) { found = True; } break; default: found = True; break; } if (found) { #ifdef VERBOSE__LtDebug DEBUGOUT(_LtDebug(__FILE__, (Widget)d->widgets[0], "Scan(%d)=>%d\n", ipos, pos)); #endif count--; if ( count == 0 ) return ( inc ? pos+1 : pos ); found = False; if ( type == XmSELECT_WORD ) while ( InWhiteSpace(*ptr ) ) { pos++; ptr = StrPtr(d, pos); } } pos++; } } #ifdef VERBOSE__LtDebug DEBUGOUT(_LtDebug(__FILE__, (Widget)d->widgets[0], "Scan(%d)=>%d\n", ipos, pos)); #endif if ( dir == XmsdRight && pos != d->length ) return ( inc ? pos+1 : pos ); if ( dir == XmsdLeft && pos != 0 ) return ( inc ? pos - 1 : pos ); return pos; }