00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00023 #include <wdm.h>
00024 #include "cbm_driver.h"
00025 #include "i_iec.h"
00026
00029 IEC_TIMEOUTS libiec_global_timeouts;
00030
00032 #define READ_TIMEOUT_VALUE(_what_, _default_) \
00033 do { \
00034 libiec_global_timeouts._what_ = _default_; \
00035 if (HKey) cbm_registry_read_ulong(*HKey, L#_what_, &libiec_global_timeouts._what_); \
00036 } while (0)
00037
00038
00047 static VOID
00048 cbmiec_timeouts_init(IN PHANDLE HKey)
00049 {
00050 HANDLE hKey;
00051
00052
00053
00054 READ_TIMEOUT_VALUE(T_holdreset, 100000);
00055 READ_TIMEOUT_VALUE(T_afterreset, 2000000);
00056
00057
00058
00059 READ_TIMEOUT_VALUE(T_WaitForListener_Granu_T_H, 10);
00060
00061
00062
00063 READ_TIMEOUT_VALUE(T_1_RECV_WAIT_CLK_LOW_DATA_READY_GRANU, 20);
00064 READ_TIMEOUT_VALUE(T_2_Times, 80);
00065 READ_TIMEOUT_VALUE(T_2_RECV_WAIT_CLK_HIGH_T_NE, 10);
00066 READ_TIMEOUT_VALUE(T_3_RECV_EOI_RECOGNIZED, 70);
00067 READ_TIMEOUT_VALUE(T_4_Times, 200);
00068 READ_TIMEOUT_VALUE(T_4_RECV_WAIT_CLK_HIGH_AFTER_EOI_GRANU, 20);
00069 READ_TIMEOUT_VALUE(T_5_Times, 5000);
00070 READ_TIMEOUT_VALUE(T_5_RECV_BIT_WAIT_CLK_HIGH, 1);
00071 READ_TIMEOUT_VALUE(T_6_Times, 100);
00072 READ_TIMEOUT_VALUE(T_6_RECV_BIT_WAIT_CLK_LOW, 20);
00073 READ_TIMEOUT_VALUE(T_7_RECV_INTER_BYTE_DELAY, 70);
00074
00075
00076
00077 READ_TIMEOUT_VALUE(T_8_IEC_WAIT_LONG_DELAY, 20);
00078 READ_TIMEOUT_VALUE(T_8_IEC_WAIT_SHORT_DELAY, 10);
00079
00080
00081
00082 READ_TIMEOUT_VALUE(T_9_Times, 100);
00083 READ_TIMEOUT_VALUE(T_9_SEND_WAIT_DEVICES_T_AT, 10);
00084 READ_TIMEOUT_VALUE(T_10_SEND_BEFORE_1ST_BYTE, 20);
00085 READ_TIMEOUT_VALUE(T_11_SEND_BEFORE_BYTE_DELAY, 50);
00086 READ_TIMEOUT_VALUE(T_12_SEND_AFTER_BYTE_DELAY, 100);
00087 READ_TIMEOUT_VALUE(T_13_SEND_TURN_AROUND_LISTENER_TALKER_T_TK, 20);
00088 READ_TIMEOUT_VALUE(T_14_SEND_AT_END_DELAY, 100);
00089
00090
00091
00092 READ_TIMEOUT_VALUE(T_15_SEND_BEFORE_BIT_DELAY_T_S, 70);
00093 READ_TIMEOUT_VALUE(T_16_SEND_BIT_TIME_T_V, 20);
00094 READ_TIMEOUT_VALUE(T_17_Times, 20);
00095 READ_TIMEOUT_VALUE(T_17_SEND_FRAME_HANDSHAKE_T_F, 100);
00096
00097
00098
00099 READ_TIMEOUT_VALUE(T_PARALLEL_BURST_READ_BYTE_HANDSHAKED, 300000);
00100 READ_TIMEOUT_VALUE(T_PARALLEL_BURST_WRITE_BYTE_HANDSHAKED, 300000);
00101 }
00102 #undef READ_TIMEOUT_VALUE
00103
00121 static NTSTATUS
00122 cbmiec_testcable(PDEVICE_EXTENSION Pdx)
00123 {
00124 const wchar_t *msgAuto = L"";
00125 const wchar_t *msgCable;
00126 UCHAR in, out;
00127
00128 FUNC_ENTER();
00129
00132 switch (Pdx->IecCable)
00133 {
00134 case IEC_CABLETYPE_XM:
00135
00136
00137 case IEC_CABLETYPE_XA:
00138 break;
00139
00140 default:
00141 in = CBMIEC_GET(PP_ATN_IN);
00142 out = (READ_PORT_UCHAR(OUT_PORT) & PP_ATN_OUT) ? 1 : 0;
00143 Pdx->IecCable = (in != out) ? IEC_CABLETYPE_XA : IEC_CABLETYPE_XM;
00144 msgAuto = L" (auto)";
00145 break;
00146 }
00147
00148 switch (Pdx->IecCable)
00149 {
00150 case IEC_CABLETYPE_XM:
00151 msgCable = L"passive (XM1541)";
00152 break;
00153
00154 case IEC_CABLETYPE_XA:
00155 msgCable = L"active (XA1541)";
00156 break;
00157 }
00158
00159 Pdx->IecOutEor = Pdx->IecCable ? 0xcb : 0xc4;
00160
00161 DBG_SUCCESS((DBG_PREFIX "using %ws cable%ws",
00162 Pdx->IecCable ? L"active (XA1541)" : L"passive (XM1541)",
00163 msgAuto));
00164
00165 LogErrorString(Pdx->Fdo, CBM_IEC_INIT, msgCable, msgAuto);
00166
00167 Pdx->IecOutBits = (READ_PORT_UCHAR(OUT_PORT) ^ Pdx->IecOutEor)
00168 & (PP_DATA_OUT|PP_CLK_OUT|PP_ATN_OUT|PP_RESET_OUT);
00169
00170
00171
00172
00173
00174
00175
00176
00177 FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
00178 }
00179
00180
00192 NTSTATUS
00193 cbmiec_cleanup(IN PDEVICE_EXTENSION Pdx)
00194 {
00195 FUNC_ENTER();
00196
00197 if (!Pdx->DoNotReleaseBus)
00198 {
00199 cbmiec_release_bus(Pdx);
00200 }
00201
00202 FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
00203 }
00204
00215 NTSTATUS
00216 cbmiec_set_cabletype(IN PDEVICE_EXTENSION Pdx, IN IEC_CABLETYPE CableType)
00217 {
00218 FUNC_ENTER();
00219
00220 Pdx->IecCable = CableType;
00221
00222 FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
00223 }
00224
00238 NTSTATUS
00239 cbmiec_init(IN PDEVICE_EXTENSION Pdx)
00240 {
00241 NTSTATUS ntStatus;
00242
00243 FUNC_ENTER();
00244
00245
00246
00247
00248 DBG_IRQL( == PASSIVE_LEVEL);
00249 KeInitializeEvent(&Pdx->EventWaitForListener, SynchronizationEvent, FALSE);
00250
00251 #ifdef USE_DPC
00252
00253
00254
00255
00256 DBG_IRQL( == PASSIVE_LEVEL)
00257 IoInitializeDpcRequest(Pdx->Fdo, cbmiec_dpc);
00258
00259 #endif // #ifdef USE_DPC
00260
00261 ntStatus = cbmiec_testcable(Pdx);
00262
00263 if (!NT_SUCCESS(ntStatus)) {
00264 FUNC_LEAVE_NTSTATUS(ntStatus);
00265 }
00266
00267 Pdx->IecBusy = FALSE;
00268
00269 if (!Pdx->DoNotReleaseBus)
00270 {
00271 CBMIEC_RELEASE(PP_RESET_OUT | PP_DATA_OUT | PP_ATN_OUT | PP_LP_BIDIR | PP_LP_IRQ);
00272 CBMIEC_SET(PP_CLK_OUT);
00273 }
00274
00275 FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
00276 }
00277
00290 NTSTATUS
00291 cbmiec_global_init(IN PHANDLE HKey)
00292 {
00293 FUNC_ENTER();
00294
00295
00296
00297 cbmiec_timeouts_init(HKey);
00298
00299 FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
00300 }