/*! \brief Write some bytes to the IEC bus \param Pdx Pointer to the device extension. \param Buffer Pointer to a buffer where the read bytes are written to. \param Size Maximum number of characters to read from the bus. \param Written Pointer to the variable which will hold the number of written bytes. \return If the routine succeeds, it returns STATUS_SUCCESS. Otherwise, it returns one of the error status values. ATN is released on return of this routine */ NTSTATUS cbmiec_raw_write(IN PDEVICE_EXTENSION Pdx, IN const PUCHAR Buffer, IN ULONG Size, OUT ULONG *Written) { NTSTATUS ntStatus; #if DBG unsigned i; #endif FUNC_ENTER(); PERF_EVENT_VERBOSE(0x1000, 0); FUNC_PARAM((DBG_PREFIX "Buffer = 0x%p, Size = 0x%04x", Buffer, Size)); #if DBG for (i=0;i<Size;i++) { FUNC_PARAM((DBG_PREFIX " output %2u: 0x%02x '%c'", i, (unsigned int) Buffer[i], (UCHAR) Buffer[i])); } #endif PERF_EVENT_VERBOSE(0x1001, 0); ntStatus = cbmiec_i_raw_write(Pdx, Buffer, Size, Written, 0, 0); PERF_EVENT_VERBOSE(0x1002, 0); FUNC_LEAVE_NTSTATUS(ntStatus); }
/*! \brief Read some bytes from the IEC bus This function reads some bytes from the IEC bus. If debugging of function parameters is defined, output the given parameters and the returned values. \param Pdx Pointer to the device extension. \param Buffer Pointer to a buffer where the read bytes are written to. \param Size Maximum number of characters to read from the bus. \param Read Pointer to the variable which will hold the read bytes. \return If the routine succeeds, it returns STATUS_SUCCESS. Otherwise, it returns one of the error status values. */ NTSTATUS cbmiec_raw_read(IN PDEVICE_EXTENSION Pdx, OUT PUCHAR Buffer, IN ULONG Size, OUT ULONG* Read) { NTSTATUS ntStatus; #if DBG USHORT i; #endif FUNC_ENTER(); FUNC_PARAM((DBG_PREFIX "Buffer = 0x%p, Size = 0x%04x", Buffer, Size)); ntStatus = cbmiec_i_raw_read(Pdx, Buffer, Size, Read); #if DBG for (i=0;i<*Read;i++) { FUNC_PARAM((DBG_PREFIX " input %2u: 0x%02x '%c'", i, (unsigned int) Buffer[i], (UCHAR) Buffer[i])); } #endif FUNC_LEAVE_NTSTATUS(ntStatus); }
/*! \brief Wait for a line to have a specific value This function waits until a listener is ready. \param Pdx Pointer to the device extension. \param Line Which line has to be monitored (one of IEC_DATA, IEC_CLOCK, IEC_ATN) \param State Type of wait \n =1: Wait until that line is set \n =0: Wait until that line is unset \param Result Pointer to a variable which will hold the value of the IEC bus */ NTSTATUS cbmiec_iec_wait(IN PDEVICE_EXTENSION Pdx, IN UCHAR Line, IN UCHAR State, OUT PUCHAR Result) { NTSTATUS ntStatus; UCHAR mask; ULONG i; FUNC_ENTER(); FUNC_PARAM((DBG_PREFIX "line = 0x%02x, state = 0x%02x", Line, State)); // Find the correct mask for the line which has to be tested switch (Line) { case IEC_LINE_DATA: mask = PP_DATA_IN; break; case IEC_LINE_CLOCK: mask = PP_CLK_IN; break; case IEC_LINE_ATN: mask = PP_ATN_IN; break; default: FUNC_LEAVE_NTSTATUS_CONST(STATUS_INVALID_PARAMETER); } // For which state do we have to wait: Set (= mask) or unset State = State ? mask : 0; i = 0; while ((READ_PORT_UCHAR(IN_PORT) & mask) == State) { if(i >= 20) { cbmiec_schedule_timeout(libiec_global_timeouts.T_8_IEC_WAIT_LONG_DELAY); if (QueueShouldCancelCurrentIrp(&Pdx->IrpQueue)) { FUNC_LEAVE_NTSTATUS_CONST(STATUS_TIMEOUT); } } else { i++; cbmiec_udelay(libiec_global_timeouts.T_8_IEC_WAIT_SHORT_DELAY); } } ntStatus = cbmiec_iec_poll(Pdx, Result); FUNC_LEAVE_NTSTATUS(ntStatus); }
/*! \brief Activate and deactive a line on the IEC serial bus This function activates (sets to 0V, L) and deactivates (set to 5V, H) lines on the IEC serial bus. \param Pdx Pointer to the device extension. \param Set The mask of which lines should be set. This has to be a bitwise OR between the constants IEC_DATA, IEC_CLOCK, IEC_ATN, and IEC_RESET \param Release The mask of which lines should be released. This has to be a bitwise OR between the constants IEC_DATA, IEC_CLOCK, IEC_ATN, and IEC_RESET \return If the routine succeeds, it returns STATUS_SUCCESS. Otherwise, it returns one of the error status values. \remark If a bit is specified in the Set as well as in the Release mask, the effect is undefined. */ NTSTATUS cbmiec_iec_setrelease(IN PDEVICE_EXTENSION Pdx, IN USHORT Set, IN USHORT Release) { NTSTATUS ntStatus; FUNC_ENTER(); FUNC_PARAM((DBG_PREFIX "set = 0x%02x, release = 0x%02x", Set, Release)); ntStatus = STATUS_SUCCESS; DBG_ASSERT((Set & Release) == 0); // Set the correct line as given by the call if ( (Set & ~(IEC_LINE_DATA | IEC_LINE_CLOCK | IEC_LINE_ATN | IEC_LINE_RESET)) || (Release & ~(IEC_LINE_DATA | IEC_LINE_CLOCK | IEC_LINE_ATN | IEC_LINE_RESET))) { // there was some bit set that is not recognized, return // with an error ntStatus = STATUS_INVALID_PARAMETER; } else { ULONG set_mask = 0; ULONG release_mask = 0; SET_RELEASE_LINE(DATA, DATA); SET_RELEASE_LINE(CLOCK, CLK); SET_RELEASE_LINE(ATN, ATN); SET_RELEASE_LINE(RESET, RESET); #ifdef TEST_BIDIR #define PP_BIDIR_OUT PP_LP_BIDIR #define IEC_LINE_BIDIR PP_BIDIR_OUT SET_RELEASE_LINE(BIDIR, BIDIR); #undef PP_BIDIR_OUT #undef IEC_LINE_BIDIR #endif // #ifdef TEST_BIDIR CBMIEC_SET_RELEASE(set_mask, release_mask); } FUNC_LEAVE_NTSTATUS(ntStatus ); }
// // INIT_WORD_INDEX_Debug: C // void INIT_WORD_INDEX_Debug(RELVAL *v, REBCNT i) { assert(ANY_WORD(v)); assert(GET_VAL_FLAG((v), WORD_FLAG_BOUND)); if (IS_RELATIVE(v)) assert( VAL_WORD_CANON(v) == VAL_PARAM_CANON(FUNC_PARAM(VAL_WORD_FUNC(v), i)) ); else assert( VAL_WORD_CANON(v) == CTX_KEY_CANON(VAL_WORD_CONTEXT(KNOWN(v)), i) ); v->payload.any_word.index = i; }
/*! \brief Send a TALK over the IEC bus This function sends a TALK to the IEC bus. \param Pdx Pointer to the device extension. \param Device Device (primary) address \param Secaddr Secondary address \return If the routine succeeds, it returns STATUS_SUCCESS. Otherwise, it returns one of the error status values. */ NTSTATUS cbmiec_talk(IN PDEVICE_EXTENSION Pdx, IN UCHAR Device, IN UCHAR Secaddr) { NTSTATUS ntStatus; ULONG sent; UCHAR buffer[2]; FUNC_ENTER(); FUNC_PARAM((DBG_PREFIX "Device = 0x%02x, Secaddr = 0x%02x", (int)Device, (int)Secaddr)); // send a 0x4x / 0x6y (talk device x, secaddr y) under control of ATN buffer[0] = 0x40 | Device; buffer[1] = 0x60 | Secaddr; ntStatus = cbmiec_i_raw_write(Pdx, buffer, 2, &sent, 1, 1); Pdx->DoNotReleaseBus = TRUE; FUNC_LEAVE_NTSTATUS(ntStatus); }