//--------------------------------------------------------------------------- #include #pragma hdrstop #include "Unit1.h" #include "AIOWDM.h" #include #include "TIRQThread.h" #include "ACCES32.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TMainForm *MainForm; struct TCardData { unsigned long Base; unsigned long PPIs; bool IsWDG; unsigned long IRQCount; TCOSData LastCOSData[10]; AnsiString Log; unsigned long WDGPets; }; TCardData CardData[64]; //--------------------------------------------------------------------------- __fastcall TMainForm::TMainForm(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TMainForm::FormCreate(TObject *Sender) { signed int NumCards, CardNum, I, J; unsigned long DeviceID, Base; unsigned long NameSize; AnsiString Name; if (InPortB(0x61) == 0xAA55) { Application->MessageBox("ACCESNT.SYS not detected. Please copy ACCESNT.SYS into [NT]/system32/drivers and re-run this sample.", "Warning", IDOK); } int count; for(count = 0; count < 64; count++) { CardData[count].Base = 0; CardData[count].PPIs = 0; CardData[count].IRQCount = 0; CardData[count].WDGPets = 0; CardData[count].IsWDG = FALSE; for(I = 0; I < 4; I++) { CardData[count].LastCOSData[I].A = 0; CardData[count].LastCOSData[I].B = 0; CardData[count].LastCOSData[I].C = 0; } }; CardCombo->Items->Clear(); NumCards = GetNumCards(); if (NumCards == 0) { GenGroup->Visible = false; COSGroup->Visible = false; WDGGroup->Visible = false; for (I = 0; I != ControlPanel->ControlCount - 1; I++) for (J = 0; J != ((TWinControl *)(ControlPanel->Controls[I]))->ControlCount - 1; J++) ((TWinControl *)(ControlPanel->Controls[I]))->Controls[J]->Enabled = False; LogMemo->Text = "No cards found. The cards may not be installed, or they may be installed using a driver other than AIOWDM.sys."; } else { for (CardNum = 0; CardNum != NumCards ; CardNum++) { NameSize = 256; Name.SetLength(NameSize); QueryCardInfo(CardNum, &DeviceID, &Base, &NameSize, Name.c_str()); Name.SetLength(NameSize - 1); CardCombo->Items->Add(Name + "[" + IntToHex(int(Base), 3) + "]"); CardData[CardNum].Base = Base; switch (DeviceID) { case 0x0E50: //PCI-DIO-24S CardData[CardNum].PPIs = 1; break; case 0x0E60: //PCI-DIO-48S CardData[CardNum].PPIs = 2; break; case 0x22C0: case 0x25C0: case 0x2FC0: case 0x2FC1: //PCI-WDG-CSM, P104-WDG-E, P104-WDG-CSM, and P104-WDG-CSMA CardData[CardNum].IsWDG = True; WDGInit(CardNum); break; default:; } if (CardData[CardNum].PPIs != 0){ CardData[CardNum].Log = ("AIOWDM provides generic IRQ-handling functions for all cards " "and special IRQ-handling functions for COS cards like this one. \r\n\r\n" "Click 'Detect Generic IRQs' to handle IRQs generically for the card selected above, " "or 'Detect COS IRQs' to handle IRQs for the card selected above by updating COS data. \r\n\r\n"); } else { if (CardData[CardNum].IsWDG){ CardData[CardNum].Log = ("AIOWDM provides generic IRQ-handling functions for all cards " "and special functions for watchdog cards like this one.\r\n\r\n" "Click 'Detect Generic IRQs' to handle IRQs generically for the card selected above, " "or 'Handle Watchdog IRQ' to handle the next IRQ for the card selected above with the selected action.\r\n\r\n" "You can also click 'Test Watchdog Timing' to set the watchdog timer, pet it a few times, then let it time out, " "'Read Temp' to read the temperature(if installed)," "'Read Status' to read the card''s status byte," "or 'Reboot' to quickly reboot your computer.\r\n\r\n"); } else { CardData[CardNum].Log = ("AIOWDM provides generic IRQ-handling functions for all cards. \r\n\r\n" "Click 'Detect Generic IRQs' to handle IRQs for the card selected above.\r\n\r\n"); }} } CardCombo->ItemIndex = 0; CardComboChange(CardCombo); } } //--------------------------------------------------------------------------- void __fastcall TMainForm::CardComboChange(TObject *Sender) { int CardNum; unsigned long I; AnsiString Buf; CardNum = CardCombo->ItemIndex; LogMemo->Text = CardData[CardNum].Log; LogMemo->SelStart = CardData[CardNum].Log.Length(); LogMemo->SelLength = 1; //Generic IRQs if (CardData[CardNum].IRQCount == 0){ GenIRQLabel->Caption = ""; } else { GenIRQLabel->Caption = (IntToStr(CardData[CardNum].IRQCount) + " IRQ(s) detected"); } //COS IRQs if (CardData[CardNum].PPIs != 0) { Buf = ""; for (I = 0; I < CardData[CardNum].PPIs; I++) Buf = (Buf + " " + IntToHex(CardData[CardNum].LastCOSData[I].A, 2) + " " + IntToHex(CardData[CardNum].LastCOSData[I].B, 2) + " " + IntToHex(CardData[CardNum].LastCOSData[I].C, 2)); COSDataLabel->Caption = Buf; COSGroup->Visible = True; OutPortB(CardData[CardNum].Base+11,0x00); } else { COSGroup->Visible = False; //Hide COS IRQ stuff if it's not a COS card } //Hide watchdog stuff if it's not a watchdog card WDGGroup->Visible = CardData[CardNum].IsWDG; TempLabel->Caption = ""; StatusLabel->Caption = ""; } //--------------------------------------------------------------------------- void __fastcall TMainForm::GenIRQButtonClick(TObject *Sender) { int CardNum; TIRQThread *Thrd; CardNum = CardCombo->ItemIndex; Thrd = new TIRQThread(True); Thrd->COSPPIs = 0; Thrd->CardNum = CardNum; Thrd->Resume(); AddLine(CardNum, "Detecting generic IRQs; generate IRQs to see this sample count them. Press 'Abort IRQ Detect' to cancel when done."); } //--------------------------------------------------------------------------- void __fastcall TMainForm::AddLine(int CardNum, AnsiString Line) { CardData[CardNum].Log = (CardData[CardNum].Log + Line + "\r\n"); if (CardNum == CardCombo->ItemIndex) CardComboChange(CardCombo); } //--------------------------------------------------------------------------- void __fastcall TMainForm::AbortButtonClick(TObject *Sender) { int CardNum; CardNum = CardCombo->ItemIndex; if (AbortRequest(CardNum) != 0 ) AddLine(CardNum, "Aborting IRQ detection..."); else AddLine(CardNum, "No IRQ request to abort."); } //--------------------------------------------------------------------------- void __fastcall TMainForm::COSIRQButtonClick(TObject *Sender) { TIRQThread *Thrd; int CardNum; CardNum = CardCombo->ItemIndex; Thrd = new TIRQThread(True); Thrd->CardNum = CardNum; Thrd->COSPPIs = CardData[CardNum].PPIs; Thrd->Resume(); AddLine(CardNum, "Detecting COS IRQs; change the input data to see the COS data update. Press 'Abort IRQ Detect' to cancel when done."); } //--------------------------------------------------------------------------- void __fastcall TMainForm::FormCloseQuery(TObject *Sender, bool &CanClose) { int CardNum; /* Abort all pending IRQ requests. If we don't do this before exiting, later when an IRQ comes in or somebody else calls AbortRequest the pending IRQ request will attempt to unlock a thread that no longer exists, which is bad. (We can AbortRequest for a card with no pending requests, it'll just tell us that, and it's easier than remembering which cards have pending requests.) */ for (CardNum = 0; CardNum < GetNumCards(); CardNum++) AbortRequest(CardNum); } //--------------------------------------------------------------------------- void __fastcall TMainForm::ReceiveCOSData(int CardNum, TCOSData COSData[]) { unsigned long I; for (I = 0; I < CardData[CardNum].PPIs; I++) { CardData[CardNum].LastCOSData[I].A = COSData[I].A; CardData[CardNum].LastCOSData[I].B = COSData[I].B; CardData[CardNum].LastCOSData[I].C = COSData[I].C; } if (CardNum == CardCombo->ItemIndex) CardComboChange(CardCombo); } //--------------------------------------------------------------------------- void __fastcall TMainForm::ReceiveGenIRQ(int CardNum) { CardData[CardNum].IRQCount++; if (CardNum == CardCombo->ItemIndex) CardComboChange(CardCombo); } //--------------------------------------------------------------------------- void __fastcall TMainForm::WDGIRQButtonClick(TObject *Sender) { unsigned long Action; int CardNum; CardNum = CardCombo->ItemIndex; if (SoftRestartRadio->Checked) Action = WDG_ACTION_SOFT_RESTART; else if (MostlySoftRestartRadio->Checked) Action = WDG_ACTION_MOSTLY_SOFT_RESTART; else Action = WDG_ACTION_IGNORE; if (DisableWDGCheck->Checked) Action = Action + WDG_ACTION_DISABLE; WDGHandleIRQ(CardNum, Action); AddLine(CardNum, "Watchdog IRQ handler started, press 'Abort IRQ Detect' to cancel."); } //--------------------------------------------------------------------------- void __fastcall TMainForm::GoWDGButtonClick(TObject *Sender) { int CardNum; CardNum = CardCombo->ItemIndex; WDGSetTimeout(CardNum, 2 * 1000, PCI_WDG_CSM_RATE); //2 sec timeout, infinite reset //WDGSetResetDuration(CardNum, 31, PCI_WDG_CSM_RATE); //31 ms reset WDGStart(CardNum); AddLine(CardNum, "Watchdog timing started..."); CardData[CardNum].WDGPets = 0; WDGTime->Tag = CardNum; WDGTime->OnTimer = WDGPetTimer; WDGTime->Interval = 1000; WDGTime->Enabled = True; } //--------------------------------------------------------------------------- void __fastcall TMainForm::WDGPetTimer(TObject *Sender) { int CardNum; CardNum = WDGTime->Tag; if (InPortB(CardData[CardNum].Base + 4) & 0x01 == 0) { AddLine(CardNum, "Watchdog timed out early!"); WDGTime->Enabled = False; return; } CardData[CardNum].WDGPets++; if (CardData[CardNum].WDGPets >= 4) { AddLine(CardNum, "Waiting for timeout..."); WDGTime->OnTimer = WDGWaitTimer; WDGTime->Interval = 100; } else { WDGPet(CardNum); AddLine(CardNum, "Petting watchdog, pet " + IntToStr(CardData[CardNum].WDGPets ) + " of 3..."); } } //--------------------------------------------------------------------------- void __fastcall TMainForm::WDGWaitTimer(TObject *Sender) { if (InPortB(CardData[WDGTime->Tag].Base + 4) & 0x01 == 0) { AddLine(WDGTime->Tag, "Watchdog timed out."); WDGTime->Enabled = False; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::CancelWDGButtonClick(TObject *Sender) { int CardNum; CardNum = CardCombo->ItemIndex; WDGStop(CardNum); WDGTime->Enabled = False; AddLine(CardNum, "Watchdog timing cancelled."); } //--------------------------------------------------------------------------- void __fastcall TMainForm::TempButtonClick(TObject *Sender) { TempLabel->Caption = FloatToStr(WDGReadTemp(CardCombo->ItemIndex)); } //--------------------------------------------------------------------------- void __fastcall TMainForm::StatusButtonClick(TObject *Sender) { StatusLabel->Caption = IntToHex(int(WDGReadStatus(CardCombo->ItemIndex)), 2); } //--------------------------------------------------------------------------- void __fastcall TMainForm::RebootButtonClick(TObject *Sender) { if (EmergencyReboot != 0) AddLine(CardCombo->ItemIndex, "Rebooting..."); else AddLine(CardCombo->ItemIndex, "Reboot failed."); } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestButtonClick(TObject *Sender) { InPortB(CardData[CardCombo->ItemIndex].Base+3); CtrMode(CardData[CardCombo->ItemIndex].Base+0x24, 0, 2); CtrLoad(CardData[CardCombo->ItemIndex].Base+0x24, 0, 1000); CtrMode(CardData[CardCombo->ItemIndex].Base+0x24, 1, 2); CtrLoad(CardData[CardCombo->ItemIndex].Base+0x24, 1, 1000); } //--------------------------------------------------------------------------- void __fastcall TMainForm::CtrMode(long addr, char cntr, char mode) { OutPortB(addr+3, (cntr << 6) | 0x30 | (mode << 1)); } //--------------------------------------------------------------------------- void __fastcall TMainForm::CtrLoad(long addr, long c, long val) { OutPortB(addr+c, val & 0x00FF); OutPortB(addr+c, (val >> 8) & 0x00FF); } //---------------------------------------------------------------------------