/************************************************************************\
 * File Version Information
 * $Header: /Altair32v2/fpdll.h 8     11/08/06 9:22p Racini $
 ************************************************************************/
/************************************************************************\
  MITS Altair Emulator
  Physical front panel DLL header
 
  Copyright (c) 2004-2005 Howard Harte/Harte Technologies
  Copyright (c) 2005-2006 Richard A. Cini (Altair32-specific changes)


Change Log:
  2005/04/22  RAC -- Created header file
  2006/03/16  RAC -- Added stuff
  2006/05/12  RAC -- RELEASE MARKER -- v3.10.0200
  2006/11/15 RAC -- RELEASE MARKER -- v3.20.0400
\************************************************************************/
#ifndef _FPDLL_H_
#define _FPDLL_H_

#include "setupapi.h"

#define USBFP_USB_VENDOR_ID	0x8080
#define USBFP_USB_DEVICE_ID	0x8085
#define USBFP_USB_VERSION		1
#define USBFP_USB_SIGNATURE		0xAA551234

/** Types of USB Front Panels */
typedef enum {
	PANEL_TYPE_IMSAI8080 = 1,		/**< IMSAI 8080 Front Panel */
	PANEL_TYPE_IMSAI_S2,			/**< IMSAI Series Two Front Panel */
	PANEL_TYPE_ALTAIR32,			/**< Altair32 Front Panel */
	PANEL_TYPE_PDP1140,				/**< PDP-11/40 (also 11/35) Front Panel */
	PANEL_TYPE_PDP1145,				/**< PDP-11/45 (also 11/50, 11/55) Front Panel */
	PANEL_TYPE_PDP1170,				/**< PDP-11/70 Front Panel */
	PANEL_TYPE_PDP1134,				/**< PDP-11/34 Front Panel */
	PANEL_TYPE_PDP1160,				/**< PDP-11/60 Front Panel */
	PANEL_TYPE_UNKNOWN = 0xFFFFFFFF /**< Unknown/Unsupported Front Panel */
} USBFP_PANEL_TYPE ;

typedef enum {
    USBFP_KEYBOARD = 1,				/**< HID Report number for a Keyboard Command */
    USBFP_PANEL,                    /**< HID Report number for a Front Panel (lights/switches) Command */
    USBFP_SERIAL0,                  /**< HID Report number for a Serial Port 0 I/O Command */
    USBFP_SERIAL1,                  /**< HID Report number for a Serial Port 1 I/O Command */
    USBFP_ZDI                       /**< HID Report number for a ZDI Command */
} USBFP_REPORT_TYPE ;

typedef enum {
    USBFP_UPDATE_IND = 1,
    USBFP_SWITCH_REQ
} USBFP_PANEL_COMMAND_TYPE ;

enum {
    SERIAL_DATA = 1,
    SERIAL_BAUDRATE,
	SERIAL_LOOPBACK
 } ;

// Zdi interface stuff
#define CMD_GET					0x80
#define REG_PRIME				0x01
#define SAVE_SET_ADL			0x02
#define CMD_REG					0x10
#define CMD_MEM					0x20

#define ICE_CMD_SET_REG			(CMD_REG | SAVE_SET_ADL)
#define ICE_CMD_SET_REG_PRIME	(ICE_CMD_SET_REG | REG_PRIME)
#define ICE_CMD_SET_ZDI_STAT	(0x20)
#define ICE_CMD_SET_IEF2		(0x30)
#define ICE_CMD_SET_SPS			(0x40)
#define ICE_CMD_SET_PC			(0x50)
#define ICE_CMD_RESET			(0x60)

#define ICE_CMD_GET_REG			(ICE_CMD_SET_REG | CMD_GET)
#define ICE_CMD_GET_REG_PRIME	(ICE_CMD_SET_REG_PRIME | CMD_GET)
#define ICE_CMD_GET_ZDI_STAT	(ICE_CMD_SET_REG_STAT | CMD_GET)
#define ICE_CMD_GET_IEF2		(ICE_CMD_SET_REG_IEF2 | CMD_GET)
#define ICE_CMD_GET_SPS			(ICE_CMD_SET_REG_SPS | CMD_GET)
#define ICE_CMD_GET_PC			(ICE_CMD_SET_REG_PC | CMD_GET)

#define ICE_CMD_SET_CODERAM		(CMD_MEM)
#define ICE_CMD_GET_CODERAM		(ICE_CMD_SET_CODERAM | CMD_GET)

#define REG_MAF                 0x00
#define REG_BC                  0x01
#define REG_DE                  0x02
#define REG_HL                  0x03
#define REG_IX                  0x04
#define REG_IY                  0x05
#define REG_SP                  0x06
#define REG_AF_P                0x80
#define REG_BC_P                0x81
#define REG_DE_P                0x82
#define REG_HL_P                0x83
#define REG_READ_PC				0x07
#define REG_WRITE_PC			0x87

/* IMSAI
#define AUX2_UP_SW		0x80
#define AUX2_DN_SW		0x8000
#define AUX1_UP_SW		0x40
#define AUX1_DN_SW		0x4000
#define EXAM_SW			0x20
#define EXAM_NXT_SW		0x2000
#define DEP_SW			0x10
#define DEP_NXT_SW		0x1000
#define MODE_SW			0x08
#define LOAD_ADRS_SW	0x0800
#define STEP_UP_SW		0x04
#define STEP_DN_SW      0x0400
#define RUN_SW			0x02
#define STOP_SW	        0x0200
#define RESET_SW		0x01
#define PWR_OFF_SW      0x0100
*/
#define AUX2_UP_SW		0x0001
#define AUX2_DN_SW		0x0100
#define STOP_SW			0x02
#define RUN_SW	        0x0200
#define STEP_UP_SW		0x04
#define STEP_DN_SW      0x0400
#define RESET_SW		0x08
#define LOAD_ADRS_SW	0x0800		// CLR on Altair32 Panel
#define DEP_SW			0x10
#define DEP_NXT_SW		0x1000
#define EXAM_SW			0x20
#define EXAM_NXT_SW		0x2000
#define PROT_SW			0x40
#define UNPROT_SW		0x4000
#define AUX1_UP_SW		0x0080
#define AUX1_DN_SW		0x8000

#define PWR_OFF_SW      0xFFFF
#define MODE_SW			0xFFFE

#define MAX_SERIAL_XFR_SIZE     60
#define MAX_PANEL_XFR_SIZE      60
#define MAX_ZDI_XFR_SIZE        58

#pragma pack (push)
#pragma pack (1)
typedef	struct _USBFP_INDICATORS   // Bit       Panel       Altair32    IMSAI8080
{ //               IMSAI S2           Offset    Port.Bit    Indicator   Indicator
    volatile WORD  Address : 16;   // [15:0]	[0],[1]     A[15:0]     A[15:0]		59,58
	volatile WORD  Data : 8;	   // [23:16]	[2]         D[7:0]      D[7:0]		57
	volatile WORD  ssINT : 1;	   // [24]	    [3.0]       INT         INTA		56
	volatile WORD  sWO : 1;	       // [25]      [3.1]       WO          sWO
	volatile WORD  sStack : 1;	   // [26]      [3.2]       STACK       STACK
	volatile WORD  sHLTA : 1;      // [27]      [3.3]       HLTA        HLTA
	volatile WORD  sOutp : 1;      // [28]      [3.4]       OUT         OUT
	volatile WORD  sM1 : 1;	       // [29]      [3.5]       M1          M1
	volatile WORD  sInp : 1;	   // [30]      [3.6]       INP         INP
	volatile WORD  sMemr : 1;      // [31]      [3.7]       MEMR        MEMR
    volatile WORD  Hold : 1;       // [32]      [4.0]       N/A         TP10		55
    volatile WORD  Phantom : 1;    // [33]		[4.1]       N/A         TP9
    volatile WORD  IE : 1;         // [34]      [4.2]       INTE        HOLD
    volatile WORD  Prot : 1;       // [35]      [4.3]       PROT        RUN
    volatile WORD  Wait : 1;	   // [36]      [4.4]       WAIT        WAIT
    volatile WORD  MADL : 1;       // [37]      [4.5]       N/A         IE
    volatile WORD  Run : 1;        // [38]      [4.6]       RUN         N/A
    volatile WORD  HoldA : 1;      // [39]      [4.7]       HLDA        TP8
	volatile WORD  PgmOut : 8;     // [47:40]	[5]         N/A         PO[7:0]		54
    volatile WORD  USB : 1;        // [48]	    [6.0]       N/A         N/A			53
    volatile WORD  Brkpt : 1;      // [49]		[6.1]       N/A         N/A
    volatile WORD  Stack : 1;      // [50]      [6.2]       N/A         N/A
    volatile WORD  Register : 1;   // [51]      [6.3]       N/A         N/A
    volatile WORD  IO : 1;         // [52]      [6.4]       N/A         N/A
    volatile WORD  Memory : 1;     // [53]      [6.5]       N/A         N/A
    volatile WORD  LinkAct : 1;    // [54]      [6.6]       N/A         TP7
    volatile WORD  ADL : 1;        // [55]      [6.7]       N/A         N/A
    volatile WORD  ParPort : 8;    // [63:56]   [7]         ParPort     ParPort		52
} USBFP_INDICATORS, *PUSBFP_INDICATORS ;
#pragma pack (pop)

#ifdef __cplusplus
extern "C" {
#endif
#include "d:\winddk\3790.1830\inc\wxp\hidsdi.h"
#include <setupapi.h>
#ifdef __cplusplus
}
#endif

typedef DWORD (*PUSBFP_SWITCH_CALLBACK_ROUTINE)(
	HANDLE hInstance,
	PVOID pContext
) ;

/**
 * Structure containing callback routines and a callback parameter.
 */
typedef struct _USBFP_DATA {  /*      IMSAI S2 Panel          IMSAI 8080  Altair32 */
    PVOID							lpCallbackParameter;	/**< parameter passed to the callback function.  Usually this is the USB Front Panel's Context handle. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnExamine;				/**< Callback function for when the Examine switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnExamineNext;			/**< Callback function for when the Examine Next switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnDeposit;				/**< Callback function for when the Deposit switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnDepositNext; 			/**< Callback function for when the Deposit Next switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnMode;					/**< Callback function for when the Mode switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnLoadAddress;			/**< Callback function for when the Load Address Next switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnExtClr;				/**< Callback function for when the Ext Clear switch is pressed. */
	PUSBFP_SWITCH_CALLBACK_ROUTINE  OnStepUp;				/**< Callback function for when the Step (Up) switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnStepDown;				/**< Callback function for when the Step (Down) switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnRun;					/**< Callback function for when the Run switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnStop;					/**< Callback function for when the Stop switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnReset;				/**< Callback function for when the Reset switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnPowerOff;				/**< Callback function for when the Power Off switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnAddressSwitches;		/**< Callback function for when the any of the Address switches change. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnAux1Up;				/**< Callback function for when the Aux1 (Up) switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnAux1Down;				/**< Callback function for when the Aux1 (Down) switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnAux2Up;				/**< Callback function for when the Aux2 (Up) switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnAux2Down;				/**< Callback function for when the Aux2 (Down) switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnProtect;				/**< Callback function for when the Protect switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnUnprotect;			/**< Callback function for when the Unprotect switch is pressed. */
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnUndefined;        

    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnExamineReleased;
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnExamineNextReleased;
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnDepositReleased;
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnDepositNextReleased;
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnModeReleased;
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnLoadAddressReleased;
	PUSBFP_SWITCH_CALLBACK_ROUTINE  OnExtClrReleased;			//  Ext Clear   Ext Clear
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnStepUpReleased;
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnStepDownReleased;
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnRunReleased;
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnStopReleased;
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnResetReleased;
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnPowerOffReleased;
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnAux1UpReleased;   
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnAux1DownReleased; 
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnAux2UpReleased;   
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnAux2DownReleased; 
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnProtectReleased;  
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnUnprotectReleased;
    PUSBFP_SWITCH_CALLBACK_ROUTINE  OnUndefinedReleased;
} USBFP_DATA, *PUSBFP_DATA ;

// Serial port queue
typedef struct _USBFP_BYTE_QUEUE
{
    BYTE   cData[128] ;
    BYTE   *ReadPtr ;
    BYTE   *WritePtr ;
    unsigned nElements ;
} USBFP_BYTE_QUEUE, *P_USBFP_BYTE_QUEUE ;

typedef struct _USBFP_SWITCH_BUF
{
    volatile BYTE   cAdrsLo ;
    volatile BYTE   cAdrsHi ;
    volatile BYTE   cReserved2 ;
    volatile BYTE   cReserved3 ;
    volatile BYTE   cActionSwUp ;
    volatile BYTE   cActionSwDn ;
    volatile BYTE   cReserved6 ;
    volatile BYTE   cReserved7 ;
} USBFP_SWITCH_BUF, *P_USBFP_SWITCH_BUF ;

struct _USBFP_USB_CONTEXT ;

/** USB Front Panel Hardware Information Structure */
typedef struct _USB_FPANEL_INFO
{
	WORD		wVendorID ;				/**< Vendor ID */
	WORD		wProductID ;			/**< Product ID */
	WORD		wFwVersion ;			/**< Firmware Version */
	char		szSerialNum[17] ;		/**< Serial Number String (ASCII) */
	USBFP_PANEL_TYPE	PanelType ;		/**< Panel Type */
	char		szDevicePath[255] ;		/**< Panel Device Path */
} USB_FPANEL_INFO, *PUSB_FPANEL_INFO ;

//HidP_GetCaps
struct _USBFP_USB_CONTEXT
{
	DWORD		dwVersion ;
	HANDLE		hDeviceHandle ;
    HANDLE		hReadHandle ;
	int			nInstance ;
    HANDLE		HidReportReadThreadHandle ;
    DWORD		HidReportReadThreadIdentifier ;
    DWORD		HidReportReadThreadAlive ;
    DWORD       HidCommunicationOk ;
    CRITICAL_SECTION HidCriticalSection ;
	OVERLAPPED	Overlap ;
	HIDP_CAPS	Capabilities ;
    USBFP_BYTE_QUEUE  Ser0RxQ ;
    USBFP_BYTE_QUEUE  Ser0TxQ ;
    USBFP_BYTE_QUEUE  Ser1RxQ ;
    USBFP_BYTE_QUEUE  Ser1TxQ ;
    USBFP_SWITCH_BUF  Switches ;
    PUSBFP_DATA   pCpcData ;
	USB_FPANEL_INFO FPanelInfo ;
	DWORD		dwSig ;
} ;

typedef struct _USBFP_USB_CONTEXT     USBFP_USB_CONTEXT, *P_USBFP_USB_CONTEXT ;

// Zdi command structure
typedef struct _USBFP_ZDI_COMMAND
{
    volatile BYTE   cReportNum ;
    volatile BYTE   cCmdValue ;
    volatile BYTE   cRegAddress ;
    volatile BYTE   cReg_L ;
    volatile BYTE   cReg_H ;
    volatile BYTE   cReg_U ;
    volatile BYTE   cData[MAX_ZDI_XFR_SIZE] ;
} USBFP_ZDI_COMMAND, *P_USBFP_ZDI_COMMAND ;

typedef struct _USBFP_PANEL_COMMAND
{
    volatile BYTE   cReportNum ;
    volatile BYTE   cCmdValue ;
    volatile BYTE   cSeqNum ;
    volatile BYTE   cReserved ;
    volatile BYTE   cData[MAX_PANEL_XFR_SIZE] ;
} USBFP_PANEL_COMMAND, *P_USBFP_PANEL_COMMAND ;

typedef struct _USBFP_SERIAL_COMMAND
{
    volatile BYTE   cReportNum ;
    volatile BYTE   cCmdValue ;
    volatile BYTE   cSeqNum ;
    volatile BYTE   cNumChars ;
    volatile BYTE   cData[MAX_SERIAL_XFR_SIZE] ;
} USBFP_SERIAL_COMMAND, *P_USBFP_SERIAL_COMMAND ;


#ifdef USBFP_EXPORTS

#define CPCUSB_API __declspec(dllexport)
#else
#define CPCUSB_API __declspec(dllimport)
#endif

extern CPCUSB_API int nUsbFPanelDll ;

#ifdef __cplusplus
extern "C" {
#endif
// Prototypes used when implicitly linking with dll's lib.
HANDLE CPCUSB_API _stdcall UsbFPanelInitContext(void) ;
void CPCUSB_API _stdcall UsbFPanelDestroyContext(HANDLE pContext) ;

BOOL CPCUSB_API _stdcall UsbFPanelFindAndOpenDevice(HANDLE pContext, IN int nInstance, IN int nVID, IN int nPID) ;
BOOL CPCUSB_API _stdcall UsbFPanelCloseDevice(IN HANDLE hInstance) ;
int CPCUSB_API _stdcall UsbFPanelGetDeviceInstance(IN P_USBFP_USB_CONTEXT pContext) ;
HANDLE CPCUSB_API _stdcall UsbFPanelGetHandle(IN P_USBFP_USB_CONTEXT pContext) ;
BOOL CPCUSB_API _stdcall UsbFPanelGetHardwareInfo(IN HANDLE hInstance, IN USB_FPANEL_INFO *pPanelInfo) ;
CPCUSB_API int _stdcall UsbFPanelResetZdi(IN HANDLE hInstance) ;
CPCUSB_API int _stdcall UsbFPanelWriteZdiRegister(IN HANDLE hInstance, IN BYTE cRegisterAddr, unsigned long dwValue) ;
CPCUSB_API unsigned long _stdcall UsbFPanelReadZdiRegister(IN HANDLE hInstance, IN BYTE cRegisterAddr) ;

CPCUSB_API int _stdcall UsbFPanelUpdateLEDs(IN HANDLE hInstance, IN BYTE *pLEDArray) ;
CPCUSB_API int _stdcall UsbFPanelGetSwitchValues(IN HANDLE hInstance) ;
CPCUSB_API int _stdcall UsbFPanelGetSR(IN HANDLE hInstance, OUT WORD *pSR) ;
CPCUSB_API int _stdcall UsbFPanelSendSerial(IN HANDLE hInstance, IN BYTE cPortNum, IN BYTE nCharCount, IN BYTE *pBuffer) ;
CPCUSB_API BOOL _stdcall UsbFPanelGetChar(IN HANDLE hInstance, IN BYTE cPortNum, OUT BYTE *nCharCount, OUT BYTE *cData) ;
CPCUSB_API int _stdcall UsbFPanelInitialize(IN HANDLE hInstance, IN PUSBFP_DATA pUsbfpData) ;
#ifdef __cplusplus
}
#endif

BOOL _stdcall UsbFPanelFindDevice(OUT PCHAR DevicePath, IN int nInstance, IN int nVID, IN int nPID, OUT int *nFoundInstance) ;
BOOL _stdcall UsbFPanelCheckDevice(IN PCHAR DevicePath, int nVID, int nPID) ;
BOOL _stdcall UsbFPanelOpenDevice(IN HANDLE hInstance, IN PCHAR DevicePath, int nInstance, int nVID, int nPID) ;
BOOL _stdcall UsbFPanelGetDeviceInfo(IN HANDLE hInstance) ;

// Extended error information
#define FP_DISCONNECTED			0xFFFFFFFF	// not connected
#define FP_CONN_ACTIVE			0x00000000	// connected and active
#define FP_CONN_INACTIVE		0x00000001	// connected but disabled
#define FP_ERR_DLLNOTFOUND		0x80000000	// DLL not found/installed
#define FP_ERR_CONNECT			0x80000001	// formerly _ACTIVE but problems
#define FP_ERR_OUTOFMEMORY		0x80000002	// insufficient memory for dll_init
#define FP_ERR_INVALIDHANDLE	0x80000003	// bad handle
#define FP_ERR_NO_THREAD		0x80000004	// can't allocate thread
#define FP_ERR_BADCOMMAND		0x80000005	// bad command


// handle stored in simstate.hFrontPanel
extern BOOL bLampTest ;
extern DWORD UsbFPanelChanged ;
extern WORD SR ;				// switch register
extern int UsbFPanelUpdate(void) ;
extern int UsbFPanelUpdateDataLeds(unsigned short Data, unsigned short Addr) ;
extern HANDLE FP_OpenFrontPanel(void) ;
extern BOOL FP_CloseFrontPanel(HANDLE) ;
extern DWORD FP_GetFrontPanelStatus(HANDLE) ;
extern BOOL FP_LampTest(HANDLE) ;
extern BOOL FP_AllLampsOff(HANDLE) ;
extern BOOL FP_UpdateLedStatus(HANDLE) ;
extern BOOL FP_SetLedBrightness(HANDLE, int) ;
extern int fp_s14h(int, int) ;				// routines to tie CPU
extern int fp_s15h(int, int) ;				// IN/OUT handlers
extern int fp_s16h(int, int) ;				// to front panel
extern int fp_s17h(int, int) ;				// serial handlers 

#endif
/* end of file: fpdll.h */
