+ tUHCI_Controller *Host = Ptr;
+ int frame = (_InWord(Host, FRNUM) - 1) & 0x3FF;
+ Uint16 status = _InWord(Host, USBSTS);
+// Log_Debug("UHCI", "UHIC Interrupt, status = 0x%x, frame = %i", status, frame);
+
+ // Interrupt-on-completion
+ if( status & 1 )
+ {
+ tPAddr link;
+
+ for( int i = 0; i < 10; i ++ )
+ {
+ link = Host->FrameList[frame];
+ Host->FrameList[frame] = 1;
+ while( !(link & 1) )
+ {
+ tUHCI_TD *td = UHCI_int_GetTDFromPhys(link);
+ int byte_count = (td->Control&0x7FF)+1;
+ LOG("link = 0x%x, td = %p, byte_count = %i", link, td, byte_count);
+ // Handle non-page aligned destination
+ // TODO: This will break if the destination is not in global memory
+ if(td->_info.bCopyData)
+ {
+ void *ptr = (void*)MM_MapTemp(td->BufferPointer);
+ memcpy(td->_info.DataPtr, ptr, byte_count);
+ MM_FreeTemp((tVAddr)ptr);
+ }
+ // Callback
+ if(td->_info.Callback && td->_info.Callback != INVLPTR)
+ {
+ LOG("Calling cb %p", td->_info.Callback);
+ td->_info.Callback(td->_info.CallbackPtr, td->_info.DataPtr, byte_count);
+ td->_info.Callback = NULL;
+ }
+ link = td->Link;
+ if( td->_info.Callback != INVLPTR )
+ td->Link = 1;
+ }
+
+ if(frame == 0)
+ frame = 0x3ff;
+ else
+ frame --;
+ }
+
+// Host->LastCleanedFrame = frame;
+ }
+
+ LOG("status = 0x%02x", status);
+ _OutWord(Host, USBSTS, status);
+}
+
+void _OutByte(tUHCI_Controller *Host, int Reg, Uint8 Value)
+{
+ if( Host->MemIOMap )
+ ((Uint8*)Host->MemIOMap)[Reg] = Value;
+ else
+ outb(Host->IOBase + Reg, Value);