DWORD SAA7146_BitmapWrite(HANDLE hWD, DWORD Addresse, DWORD Offset, DWORD count) { DWORD Length=(count << 17) | (Addresse & 0xffff); DWORD PokeReg=(2 << 16) | 2; WD_TRANSFER trans; if ( SAA7146_SET.ComAddress == 0 ) return(0); if (SAA7146_SET.bitmapmem == 0 ) return(0); // SAA7146_WriteDword(hSAA7146, SAA7146_AD_BAR0, DEBI_CONFIG,config ); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + DEBI_CONFIG; trans.Data.Dword=DEBISWAB; WD_Transfer(hWD,&trans); // SAA7146_WriteDword(hSAA7146, SAA7146_AD_BAR0, DEBI_AD,(unsigned long)debi_mem_dma.Page[0].pPhysicalAddr); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + DEBI_AD; trans.Data.Dword=SAA7146_SET.bitmapmem + Offset; WD_Transfer(hWD,&trans); // SAA7146_WriteDword(hSAA7146, SAA7146_AD_BAR0, DEBI_COMMAND,Length); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + DEBI_COMMAND; trans.Data.Dword=Length; WD_Transfer(hWD,&trans); // SAA7146_WriteDword(hSAA7146, SAA7146_AD_BAR0, MC2,PokeReg); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + MC2; trans.Data.Dword=PokeReg; WD_Transfer(hWD,&trans); return 0; }
DWORD SAA7146_DebiCommandWrite(HANDLE hWD, DWORD config, DWORD addr, DWORD val, DWORD count) { DWORD Length=(count << 17) | (addr & 0xffff); DWORD PokeReg=(2 << 16) | 2; WD_TRANSFER trans; if ( SAA7146_SET.ComAddress == 0 ) return(-1); if ( count > 4 ) count=4; trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + DEBI_CONFIG; trans.Data.Dword=config; WD_Transfer(hWD,&trans); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + DEBI_AD; trans.Data.Dword=val; WD_Transfer(hWD,&trans); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + DEBI_COMMAND; trans.Data.Dword=Length; WD_Transfer(hWD,&trans); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + MC2; trans.Data.Dword=PokeReg; WD_Transfer(hWD,&trans); return 0; }
int SAA7146_Wait_for_Debi_done(HANDLE hWD) { DWORD i; WD_TRANSFER trans; DWORD result; if ( SAA7146_SET.ComAddress == 0 ) return(0); /* wait for registers to be programmed */ for (i = 0; i < SAA7146_Timing.Debi_done_MC2; i++) { // if ( SAA7146_ReadDword(hSAA7146, SAA7146_AD_BAR0, MC2) & 2) break; trans.cmdTrans = RM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + MC2; WD_Transfer(hWD,&trans); result=trans.Data.Dword; if ((result&2) != 0 ) break; }; if ( i >= SAA7146_Timing.Debi_done_MC2 ) SAA7146_ISR.Debi_Done_MC2=(DWORD)0x01; /* wait for transfer to complete */ for (i = 0; i < SAA7146_Timing.Debi_done_PSR; i++ ) { trans.cmdTrans = RM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + PSR; WD_Transfer(hWD,&trans); result=trans.Data.Dword; if ((result&SPCI_DEBI_S) == 0 ) break; trans.cmdTrans = RM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + MC2; WD_Transfer(hWD,&trans); }; if ( i >= SAA7146_Timing.Debi_done_PSR ) SAA7146_ISR.Debi_Done_PSR=0x01; return 0; }
// returns TRUE if needs DPC. // this function is called at IRQL level - at physical interrupt handler. // most library calls are NOT allowed, for example: // NO WD_xxxx() calls, except WD_Transfer(), // NO malloc, // NO free // YES WD_Transfer // YES your functions, as long as they dont call library functions // YES specific kernel functions, that the Win DDK specifically allows them to be // called at IRQL BOOL __cdecl KP_IntAtIrql(PVOID pIntContext, BOOL *pfIsMyInterrupt) { DWORD isr_status; DWORD isr_reset; BOOL ret1=FALSE; BOOL ret2=FALSE; BOOL ret3=FALSE; WD_TRANSFER trans; HANDLE hWD=(HANDLE)pIntContext; *pfIsMyInterrupt = FALSE; if ( SAA7146_SET.ComAddress == 0 ) return(FALSE); trans.cmdTrans = RM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + ISR; WD_Transfer(hWD,&trans); isr_status=trans.Data.Dword; SAA7146_ISR.PictureSet=0; isr_reset=0; if ((isr_status&0x00080000) == 0x00080000) { isr_reset+=0x00080000; *pfIsMyInterrupt = TRUE; ret1=debiirq(hWD); } if ((isr_status&0x00000008) == 0x00000008 ) { isr_reset+=0x00000008; *pfIsMyInterrupt = TRUE; if ( LockStateExtern == 0 ) ret2=gpioirq(hWD); else { Hold_GPIO_Irq=1; Debi_On_Set=0; } }; if ( (isr_status&0x08000000) == 0x08000000) { *pfIsMyInterrupt = TRUE; ret3=TRUE; isr_reset+=0x08000000; SAA7146_ISR.PictureSet=(DWORD)0x01; }; trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + ISR; if ( SAA7146_SET.Sharing == 0 ) trans.Data.Dword=isr_reset; else trans.Data.Dword=isr_status; WD_Transfer(hWD,&trans); if ((ret1==TRUE) || (ret2==TRUE) || (ret3==TRUE)) return(TRUE); return(FALSE); }
DWORD SAA7146_DebiRead(HANDLE hWD, DWORD config, DWORD addr, DWORD count) { DWORD result = 0; DWORD Length=(count << 17) | 0x10000 | (addr & 0xffff); DWORD PokeReg=(2 << 16) | 2; WD_TRANSFER trans; if (count > 0x1000 || count <= 0) count=0x04; if ( SAA7146_SET.ComAddress == 0 ) return(-1); if (SAA7146_SET.debimem == 0 ) return(-1); SAA7146_Wait_for_Debi_done(hWD); // SAA7146_WriteDword(hSAA7146, SAA7146_AD_BAR0, DEBI_AD,(DWORD)debi_mem_dma.Page[0].pPhysicalAddr); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + DEBI_AD; trans.Data.Dword=SAA7146_SET.debimem; WD_Transfer(hWD,&trans); // SAA7146_WriteDword(hSAA7146, SAA7146_AD_BAR0, DEBI_COMMAND,Length); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + DEBI_COMMAND; trans.Data.Dword=Length; WD_Transfer(hWD,&trans); // SAA7146_WriteDword(hSAA7146, SAA7146_AD_BAR0, DEBI_CONFIG,config ); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + DEBI_CONFIG; trans.Data.Dword=config; WD_Transfer(hWD,&trans); // SAA7146_WriteDword(hSAA7146, SAA7146_AD_BAR0, MC2,PokeReg); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + MC2; trans.Data.Dword=PokeReg; WD_Transfer(hWD,&trans); if (count > 4) return count; SAA7146_Wait_for_Debi_done(hWD); // result = SAA7146_ReadDword(hSAA7146, SAA7146_AD_BAR0, DEBI_AD); trans.cmdTrans = RM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + DEBI_AD; WD_Transfer(hWD,&trans); result=trans.Data.Dword; result &= (0xffffffffUL >> ((4-count)*8)); return result; }
void Debi_Off(HANDLE hWD) { DWORD result; WD_TRANSFER trans; if ( SAA7146_SET.ComAddress == 0 ) return; trans.cmdTrans = RM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + IER; WD_Transfer(hWD,&trans); result=trans.Data.Dword; trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + IER; trans.Data.Dword=(result&~MASK_19); WD_Transfer(hWD,&trans); };
void SAA7146_SetGPIO( HANDLE hWD, DWORD port, DWORD data) { DWORD val; WD_TRANSFER trans; trans.cmdTrans = RM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + GPIO_CTRL; WD_Transfer(hWD,&trans); val=trans.Data.Dword; val&=~(0xff << (8*(port))); val|=(data)<<(8*(port)); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + GPIO_CTRL; trans.Data.Dword=val; WD_Transfer(hWD,&trans); };
// Function: LPT_ReadWriteBlock() // Read/Write data from/to the card's memory/IO into/from a given buffer. // Parameters: // hLPT [in] handle to the card as received from LPT_Open(). // addrSpace [in] the address space of the card to access. // dwOffset [in] offset relative to the beginning of the address space to access. // fRead [in] direction of operation: // TRUE indicates read from the card's memory/IO into the given buffer. // FALSE indicates write from the given buffer to the card's memory/IO. // buf [in/out] a caller allocated buffer to read/write to/from. // dwBytes [in] the number of bytes to read/write. The allocated buffer should be at least dwBytes long. // mode [in] perform the data transfer byte by byte / word by word / dword by dword. // Return Value: // None. void LPT_ReadWriteBlock(LPT_HANDLE hLPT, LPT_ADDR addrSpace, DWORD dwOffset, BOOL fRead, PVOID buf, DWORD dwBytes, LPT_MODE mode) { WD_TRANSFER trans; BOOL fMem = hLPT->cardReg.Card.Item[addrSpace].item==ITEM_MEMORY; BZERO(trans); if (fRead) { if (mode==LPT_MODE_BYTE) trans.cmdTrans = fMem ? RM_SBYTE : RP_SBYTE; else if (mode==LPT_MODE_WORD) trans.cmdTrans = fMem ? RM_SWORD : RP_SWORD; else if (mode==LPT_MODE_DWORD) trans.cmdTrans = fMem ? RM_SDWORD : RP_SDWORD; else if (mode==LPT_MODE_QWORD) trans.cmdTrans = fMem ? RM_SQWORD : RP_SQWORD; } else { if (mode==LPT_MODE_BYTE) trans.cmdTrans = fMem ? WM_SBYTE : WP_SBYTE; else if (mode==LPT_MODE_WORD) trans.cmdTrans = fMem ? WM_SWORD : WP_SWORD; else if (mode==LPT_MODE_DWORD) trans.cmdTrans = fMem ? WM_SDWORD : WP_SDWORD; else if (mode==LPT_MODE_QWORD) trans.cmdTrans = fMem ? WM_SQWORD : WP_SQWORD; } if (fMem) trans.dwPort = hLPT->cardReg.Card.Item[addrSpace].I.Mem.dwTransAddr; else trans.dwPort = hLPT->cardReg.Card.Item[addrSpace].I.IO.dwAddr; trans.dwPort += dwOffset; trans.fAutoinc = TRUE; trans.dwBytes = dwBytes; trans.dwOptions = 0; trans.Data.pBuffer = buf; WD_Transfer (hLPT->hWD, &trans); }
DWORD SAA7146_DebiWrite(HANDLE hWD, DWORD config, DWORD addr, DWORD val, DWORD count) { DWORD Length=(count << 17) | (addr & 0xffff); DWORD PokeReg=(2 << 16) | 2; WD_TRANSFER trans; if ( SAA7146_SET.ComAddress == 0 ) return(-1); if (( count > 4 ) && (SAA7146_SET.debimem == 0 )) return(-1); if (count > 0x1000 || count <= 0) count=0x08; SAA7146_Wait_for_Debi_done(hWD); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + DEBI_CONFIG; trans.Data.Dword=config; WD_Transfer(hWD,&trans); if (count <= 4) { // SAA7146_WriteDword(hSAA7146, SAA7146_AD_BAR0, DEBI_AD,val); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + DEBI_AD; trans.Data.Dword=val; WD_Transfer(hWD,&trans); } else { // SAA7146_WriteDword(hSAA7146, SAA7146_AD_BAR0, DEBI_AD,(unsigned long)debi_mem_dma.Page[0].pPhysicalAddr); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + DEBI_AD; trans.Data.Dword=SAA7146_SET.debimem; WD_Transfer(hWD,&trans); }; // SAA7146_WriteDword(hSAA7146, SAA7146_AD_BAR0, DEBI_COMMAND,Length); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + DEBI_COMMAND; trans.Data.Dword=Length; WD_Transfer(hWD,&trans); // SAA7146_WriteDword(hSAA7146, SAA7146_AD_BAR0, MC2,PokeReg); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + MC2; trans.Data.Dword=PokeReg; WD_Transfer(hWD,&trans); return 0; }
void Release_Spin_Lock( HANDLE hWD ) { WD_TRANSFER trans; LockStateExtern=0x00000000; if ( Hold_GPIO_Irq == 1 ) { trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + PSR; trans.Data.Dword=0x00000008; WD_Transfer(hWD,&trans); } };
DWORD SAA7146_IPMPERead(HANDLE hWD, DWORD Addresse, DWORD count) { DWORD result = 0; DWORD Length=(count << 17) | 0x10000 | (Addresse & 0xffff); DWORD PokeReg=(2 << 16) | 2; WD_TRANSFER trans; if (count > 0x1000 || count <= 0) count=8; if ( SAA7146_SET.ComAddress == 0 ) return(0); if (SAA7146_SET.ipmpemem == 0 ) return(0); SAA7146_Wait_for_Debi_done(hWD); // SAA7146_WriteDword(hSAA7146, SAA7146_AD_BAR0, DEBI_AD,(DWORD)debi_mem_dma.Page[0].pPhysicalAddr); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + DEBI_AD; trans.Data.Dword=SAA7146_SET.ipmpemem; WD_Transfer(hWD,&trans); // SAA7146_WriteDword(hSAA7146, SAA7146_AD_BAR0, DEBI_COMMAND,Length); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + DEBI_COMMAND; trans.Data.Dword=Length; WD_Transfer(hWD,&trans); // SAA7146_WriteDword(hSAA7146, SAA7146_AD_BAR0, DEBI_CONFIG,config ); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + DEBI_CONFIG; trans.Data.Dword=DEBISWAB; WD_Transfer(hWD,&trans); // SAA7146_WriteDword(hSAA7146, SAA7146_AD_BAR0, MC2,PokeReg); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + MC2; trans.Data.Dword=PokeReg; WD_Transfer(hWD,&trans); return count; }
// called when WD_KernelPlugInCall() is called void __cdecl KP_Call(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall, BOOL fIsKernelMode) { HANDLE hWD=(HANDLE)pDrvContext; WD_TRANSFER trans; kpCall->dwResult = SAA7146_OK; switch ( kpCall->dwMessage ) { case SAA7146_IOCTL_VERSION: // GetVersion message { SAA7146_VERSION *ver = (SAA7146_VERSION *) kpCall->pData; COPY_TO_USER_OR_KERNEL(ver->cVer, "SAA7146-Kernel-Driver V2.70", sizeof("SAA7146-Kernel-Driver V2.70")+1, fIsKernelMode); kpCall->dwResult = SAA7146_OK; return; } case SAA7146_IOCTL_SET_INIT: // Set message { SAA7146_SET_IO *adr = (SAA7146_SET_IO *) kpCall->pData; COPY_TO_USER_OR_KERNEL(&SAA7146_SET.ComAddress,&adr->ComAddress, sizeof(SAA7146_SET_IO), fIsKernelMode); kpCall->dwResult = SAA7146_OK; return; } case SAA7146_IOCTL_GET_ISR: // Get message { SAA7146_ISR_IO *adr = (SAA7146_ISR_IO *) kpCall->pData; COPY_TO_USER_OR_KERNEL(&adr->PictureSet,&SAA7146_ISR.PictureSet, sizeof(SAA7146_ISR_IO), fIsKernelMode); SAA7146_ISR.debistatus=0; SAA7146_ISR.Debi_Done_PSR=0; SAA7146_ISR.Debi_Done_MC2=0; kpCall->dwResult = SAA7146_OK; return; } case SAA7146_IOCTL_WRITETEXT: // Get message { SAA7146_WRITETEXT_IO *TextInfo = (SAA7146_WRITETEXT_IO *) kpCall->pData; COPY_TO_USER_OR_KERNEL(&SAA7146_WriteText_Buffer.CommandLength,&TextInfo->CommandLength,sizeof(SAA7146_WRITETEXT_IO), fIsKernelMode); kpCall->dwResult=SAA7146_WriteText(hWD,SAA7146_WriteText_Buffer.CommandLength,SAA7146_WriteText_Buffer.CommandBuffer,SAA7146_WriteText_Buffer.TextLength,SAA7146_WriteText_Buffer.TextBuffer); return; } case SAA7146_IOCTL_COMMAND: // Get message { SAA7146_COMMAND_IO *CommandInfo = (SAA7146_COMMAND_IO *) kpCall->pData; COPY_TO_USER_OR_KERNEL(&SAA7146_Command_Buffer.CommandLength,&CommandInfo->CommandLength,sizeof(SAA7146_COMMAND_IO), fIsKernelMode); kpCall->dwResult=SAA7146_OutCommand(hWD,SAA7146_Command_Buffer.CommandBuffer,SAA7146_Command_Buffer.CommandLength); return; } case SAA7146_IOCTL_COMMANDREQUEST: // Get message { SAA7146_COMMANDREQUEST_IO *CommandRequest = (SAA7146_COMMANDREQUEST_IO *) kpCall->pData; COPY_TO_USER_OR_KERNEL(&SAA7146_CommandRequest_Buffer.OutBuf[0],&CommandRequest->OutBuf[0],sizeof(SAA7146_COMMANDREQUEST_IO), fIsKernelMode); kpCall->dwResult=SAA7146_CommandRequest(hWD,&SAA7146_CommandRequest_Buffer.OutBuf[0],SAA7146_CommandRequest_Buffer.OutLength,&SAA7146_CommandRequest_Buffer.InBuf[0],SAA7146_CommandRequest_Buffer.InLength); COPY_TO_USER_OR_KERNEL(&CommandRequest->OutBuf[0],&SAA7146_CommandRequest_Buffer.OutBuf[0],sizeof(SAA7146_COMMANDREQUEST_IO), fIsKernelMode); return; } case SAA7146_IOCTL_SET_TIMEING: { SAA7146_TIMING_IO *TimerInfo = (SAA7146_TIMING_IO *) kpCall->pData; COPY_TO_USER_OR_KERNEL(&SAA7146_Timing.Cmd_Time_Out,&TimerInfo->Cmd_Time_Out,sizeof(SAA7146_TIMING_IO), fIsKernelMode); kpCall->dwResult=SAA7146_OK; return; } case SAA7146_IOCTL_ARM_CLEARMAILBOX: // Get message { ARM_ClearMailBox(hWD); kpCall->dwResult = SAA7146_OK; return; } case SAA7146_IOCTL_ARM_RESETMAILBOX: // Get message { ARM_ResetMailBox(hWD); kpCall->dwResult = SAA7146_OK; return; } case SAA7146_IOCTL_ARM_CLEARIRQ: // Get message { ARM_ClearIrq(hWD); kpCall->dwResult = SAA7146_OK; return; } case SAA7146_IOCTL_ARM_SET_IRQ_STATE_EXT: // Get message { SAA7146_SHORTSEND_IO *CommandInfo = (SAA7146_SHORTSEND_IO *) kpCall->pData; COPY_TO_USER_OR_KERNEL(&SAA7146_ShortSend_Buffer.value,&CommandInfo->value,sizeof(SAA7146_SHORTSEND_IO), fIsKernelMode); ARM_Set_IRQ_STATE_EXT(hWD,SAA7146_ShortSend_Buffer.value); kpCall->dwResult = SAA7146_OK; return; } case SAA7146_IOCTL_ARM_SET_SEND: // Get message { SAA7146_SHORTSEND_IO *CommandInfo = (SAA7146_SHORTSEND_IO *) kpCall->pData; COPY_TO_USER_OR_KERNEL(&SAA7146_ShortSend_Buffer.value,&CommandInfo->value,sizeof(SAA7146_SHORTSEND_IO), fIsKernelMode); ARM_Set_IRQ_STATE_EXT(hWD,SAA7146_ShortSend_Buffer.value); ARM_Set_TX_LEN(hWD,SAA7146_ShortSend_Buffer.value); ARM_Set_TX_BUFF(hWD,SAA7146_ShortSend_Buffer.value); kpCall->dwResult = SAA7146_OK; return; } case SAA7146_IOCTL_CLEAR_RECEIVE: // Get message { ARM_Set_RX_BUFF(hWD,0); ARM_ResetMailBox(hWD); kpCall->dwResult = SAA7146_OK; return; } case SAA7146_IOCTL_ARM_SET_RECEIVE: // Get message { SAA7146_SHORTSEND_IO *CommandInfo = (SAA7146_SHORTSEND_IO *) kpCall->pData; COPY_TO_USER_OR_KERNEL(&SAA7146_ShortSend_Buffer.value,&CommandInfo->value,sizeof(SAA7146_SHORTSEND_IO), fIsKernelMode); ARM_Set_RX_BUFF(hWD,SAA7146_ShortSend_Buffer.value); kpCall->dwResult = SAA7146_OK; return; } case SAA7146_IOCTL_SEND_CA: // Get message { SAA7146_SHORTSEND_IO *CommandInfo = (SAA7146_SHORTSEND_IO *) kpCall->pData; SAA7146_ISR.debistatus=(DWORD)0; COPY_TO_USER_OR_KERNEL(&SAA7146_ShortSend_Buffer.value,&CommandInfo->value,sizeof(SAA7146_SHORTSEND_IO), fIsKernelMode); ARM_Set_TX_LEN(hWD,SAA7146_ShortSend_Buffer.value); ARM_Set_IRQ_STATE_EXT(hWD,SAA7146_ShortSend_Buffer.value); Debi_On(hWD); SAA7146_CAWrite(hWD, DPRAM_BASE+txbuf,SAA7146_ShortSend_Buffer.value); kpCall->dwResult = SAA7146_OK; return; } case SAA7146_IOCTL_PLAY_BUFFER: // Get message { SAA7146_SHORTSEND_IO *CommandInfo = (SAA7146_SHORTSEND_IO *) kpCall->pData; SAA7146_ISR.debistatus=(DWORD)0; COPY_TO_USER_OR_KERNEL(&SAA7146_ShortSend_Buffer.value,&CommandInfo->value,sizeof(SAA7146_SHORTSEND_IO), fIsKernelMode); ARM_Set_TX_LEN(hWD,SAA7146_ShortSend_Buffer.value); ARM_Set_IRQ_STATE_EXT(hWD,SAA7146_ShortSend_Buffer.value); Debi_On(hWD); SAA7146_RecordWrite(hWD, DPRAM_BASE+txbuf,SAA7146_ShortSend_Buffer.value); kpCall->dwResult = SAA7146_OK; return; } case SAA7146_IOCTL_LOAD_BITMAP: // Get message { SAA7146_SHORTSEND_IO *CommandInfo = (SAA7146_SHORTSEND_IO *) kpCall->pData; COPY_TO_USER_OR_KERNEL(&SAA7146_ShortSend_Buffer.value,&CommandInfo->value,sizeof(SAA7146_SHORTSEND_IO), fIsKernelMode); BitmapOffset=0; BitmapLength=SAA7146_ShortSend_Buffer.Addresse; kpCall->dwResult = SAA7146_OK; return; } case SAA7146_IOCTL_SET_SPIN_LOCK: // Get message { Hold_GPIO_Irq=0; LockStateExtern=0x00000001; kpCall->dwResult = SAA7146_OK; return; } case SAA7146_IOCTL_RELEASE_SPIN_LOCK: // Get message { LockStateExtern=0x00000000; if ( Hold_GPIO_Irq == 1 ) { // SAA7146_WriteDword(hSAA7146, SAA7146_AD_BAR0, PSR, 0x8); trans.cmdTrans = WM_DWORD; trans.dwPort = SAA7146_SET.ComAddress + PSR; trans.Data.Dword=0x00000008; WD_Transfer(hWD,&trans); } kpCall->dwResult = SAA7146_OK; return; } // you can implement here other messages default: kpCall->dwResult = SAA7146_WRONG_MESSAGE; return; } }