unit MainUnit; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ImgList, ExtCtrls, Buttons, ComCtrls; type TMainForm = class(TForm) Image1: TImage; Image2: TImage; Image3: TImage; Image4: TImage; Image5: TImage; Image6: TImage; Image7: TImage; Image8: TImage; Image9: TImage; Image10: TImage; Image11: TImage; Image12: TImage; Image13: TImage; Image14: TImage; Image15: TImage; Image16: TImage; Image17: TImage; Image18: TImage; Image19: TImage; Image20: TImage; Image21: TImage; Image22: TImage; Image23: TImage; Image24: TImage; Label1: TLabel; LevelImages: TImageList; Label2: TLabel; Label3: TLabel; Label4: TLabel; OutButtonA: TSpeedButton; OutButtonB: TSpeedButton; ReadTime: TTimer; TristateButton: TSpeedButton; BitLabelA7: TLabel; BitLabelA6: TLabel; BitLabelA5: TLabel; BitLabelA4: TLabel; BitLabelA3: TLabel; BitLabelA2: TLabel; BitLabelA1: TLabel; BitLabelA0: TLabel; BitLabelB7: TLabel; BitLabelB6: TLabel; BitLabelB5: TLabel; BitLabelB4: TLabel; BitLabelB3: TLabel; BitLabelB2: TLabel; BitLabelB1: TLabel; BitLabelB0: TLabel; BitLabelC7: TLabel; BitLabelC6: TLabel; BitLabelC5: TLabel; BitLabelC4: TLabel; BitLabelC3: TLabel; BitLabelC2: TLabel; BitLabelC1: TLabel; BitLabelC0: TLabel; Label5: TLabel; procedure FormCreate(Sender: TObject); procedure ReadTimeTimer(Sender: TObject); procedure LevelImageClick(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure OutButtonClick(Sender: TObject); procedure TristateButtonClick(Sender: TObject); protected public end; var MainForm: TMainForm; implementation {$R *.DFM} uses AIOUSB, DetectUnit; var DeviceIndex: LongWord; LevelImage: array[0..31] of TImage; OutButton: array[0..1] of TSpeedButton; LowLevel, HighLevel: TBitmap; DIOData: LongWord; DoUpdate: Boolean; procedure TMainForm.FormCreate(Sender: TObject); var DetectForm: TDetectForm; OutMask: Byte; I: Integer; Status: LongWord; begin LowLevel := TBitmap.Create; HighLevel := TBitmap.Create; DeviceIndex := diOnly; OutMask := $00; DIOData := $FFFFFFFF; Status := DIO_Configure(DeviceIndex, False, @OutMask, @DIOData); if Status <> ERROR_SUCCESS then begin DetectForm := TDetectForm.Create(Self); if DetectForm.ShowModal = mrOK then begin DeviceIndex := DetectForm.DeviceIndex; DetectForm.Free; end else begin DetectForm.Free; Application.Terminate; Exit; end; DIO_Configure(DeviceIndex, False, @OutMask, @DIOData); end; for I := 0 to 2 do begin CTR_8254Mode(DeviceIndex, I, 1, 2); CTR_8254Mode(DeviceIndex, I, 2, 3); end; LevelImage[ 0] := Image1; LevelImage[ 1] := Image2; LevelImage[ 2] := Image3; LevelImage[ 3] := Image4; LevelImage[ 4] := Image5; LevelImage[ 5] := Image6; LevelImage[ 6] := Image7; LevelImage[ 7] := Image8; LevelImage[ 8] := Image9; LevelImage[ 9] := Image10; LevelImage[10] := Image11; LevelImage[11] := Image12; LevelImage[12] := Image13; LevelImage[13] := Image14; LevelImage[14] := Image15; LevelImage[15] := Image16; LevelImage[16] := Image17; LevelImage[17] := Image18; LevelImage[18] := Image19; LevelImage[19] := Image20; LevelImage[20] := Image21; LevelImage[21] := Image22; LevelImage[22] := Image23; LevelImage[23] := Image24; OutButton[0] := OutButtonA; OutButton[1] := OutButtonB; LevelImages.GetBitmap(0, LowLevel); LevelImages.GetBitmap(1, HighLevel); DoUpdate := True; ReadTime.Enabled := True; end; procedure TMainForm.ReadTimeTimer(Sender: TObject); var I: Integer; oDIOData, Changes: LongWord; begin oDIOData := DIOData; DIO_ReadAll(DeviceIndex, @DIOData); Changes := DIOData xor oDIOData; if DoUpdate then begin Changes := $FFFFFFFF; DoUpdate := False; end; for I := 0 to 23 do if (Changes and (1 shl I)) <> 0 then begin if (DIOData and (1 shl I)) <> 0 then LevelImage[I].Picture.Assign(HighLevel) else LevelImage[I].Picture.Assign(LowLevel) end ; end; procedure TMainForm.LevelImageClick(Sender: TObject); var I: Integer; NewValue: Boolean; begin I := (Sender as TImage).Tag; DIOData := DIOData xor (1 shl I); //Toggle bit NewValue := (DIOData and (1 shl I)) <> 0; //Get bit value DIO_Write1(DeviceIndex, I, NewValue); DoUpdate := True; end; procedure TMainForm.FormDestroy(Sender: TObject); begin LowLevel.Free; HighLevel.Free; end; procedure TMainForm.OutButtonClick(Sender: TObject); var I: Integer; OutMask: Byte; begin OutMask := $00; for I := 0 to 1 do if OutButton[I].Down then OutMask := OutMask or (1 shl I) ; I := (Sender as TSpeedButton).Tag; DIOData := DIOData or ($FF shl (I * 8)); //Set new output byte high, in case user made a mistake DIO_Configure(DeviceIndex, TristateButton.Down, @OutMask, @DIOData); DoUpdate := True; end; procedure TMainForm.TristateButtonClick(Sender: TObject); var I: Integer; OutMask: Byte; begin OutMask := $00; for I := 0 to 1 do if OutButton[I].Down then OutMask := OutMask or (1 shl I) ; DIO_Configure(DeviceIndex, TristateButton.Down, @OutMask, @DIOData); end; end.