www.pudn.com > Midimidim.rar > KeyScan.ASM


//----------------------------------------------------------------------- 
//Program Name:		KeyScan.ASM 
//Applied Body:		SPT6604Aretf 
//Project Description:	This is a simple demo code for key scan. 
//Compile:		Sunplus u'nSP IDE 
//Programmer:		WangXu 
//Current Version:	V1.0 
//Written Date:		2002/10/30 
//----------------------------------------------------------------------- 
//----------------------------------------------------------------------- 
.RAM 
KeyScanFlag:		.DW	0 //b0~b7 - read portA buffer 
				//b8~11 - state machine 
				//b12~15 - current scan line 
 
KeyStatusBuf:		.DW	0,0,0,0,0 
				//5 words - for key status 
				//the high byte represents corresponding key is changed from 'released' to 'pressed' 
				//the low byte represents corresponding key is pressed 
 
KeyQueueBufPtr:		.DW	0 //b0~3 - read pointer 
				//b4~7 - writer pointer 
				//b8~11 - key queue size in use 
				//b12~15- Key Bounce Timer 
.const	KeyDebounceTime	=	3*8192;		//( 3/512Hz = 6ms) 
 
KeyQueueBuf:		.DW	0,0,0,0 
//----------------------------------------------------------------------- 
.code 
F_KeyTimerService: 
	r1 =	[KeyQueueBufPtr]   
	test	r1,0xE000 
	jz	?L_KeyTimeOver 
	r1-=	0x2000 
	[KeyQueueBufPtr] = r1  
?L_KeyTimeOver: 
	retf 
 
//*****************************************************************************/ 
// Purpose : Keyboard Scanner State Machine                                   */ 
//                 F_StartKeyScan                                             */ 
//                        \|/      F_ReScanKey <-----+                        */ 
//                 Scan R-option   (F_KeyCodeMapping)|                        */ 
//                        \|/         \|/            |                        */ 
//                 +---> F_PrepareNextScanLine       |                        */ 
//                 |          \|/                    |                        */ 
//                 |     F_ReadKeyBeforeBounce       |                        */ 
//                 |          \|/                    |                        */ 
//                 |     F_ReadKeyAfterBounce        |                        */ 
//                 |          \|/                    |                        */ 
//                 |     F_NextScanLine              |                        */ 
//                 | no       \|/               yes  |                        */ 
//                 +---- the last scan line ? -------+                        */ 
//*****************************************************************************/ 
//----------------------------------------------------------------------- 
// State and vector definitions for keyboard scan 
// The format is as follows: 
// V_StateVector	   .DW      Address of Subroutine 
// .const  S_StateName	      = State Number 
V_KeyScan: 
V_ReadKeyBeforeBounce:     .DW      F_ReadKeyBeforeBounce 
.const   S_ReadKeyBeforeBounce      = (V_ReadKeyBeforeBounce-V_KeyScan)*256 
V_ReadKeyAfterBounce:      .DW      F_ReadKeyAfterBounce 
.const   S_ReadKeyAfterBounce       = (V_ReadKeyAfterBounce-V_KeyScan)*256 
V_KeyCodeMapping:	  .DW      F_KeyCodeMapping 
.const   S_KeyCodeMapping	   = (V_KeyCodeMapping-V_KeyScan)*256 
//----------------------------------------------------------------------------// 
F_KeyScan: 
	r1 =	[KeyScanFlag] 
	r1 =	r1 lsr 4 
	r1 =	r1 lsr 4 
	r1&=	0x000F 
	r1+=	V_KeyScan 
	pc =	[r1] 
//----------------------------------------------------------------------------// 
F_ReadKeyBeforeBounce:	      		//the first read 
	r1 =	[P_IOA_Data] 
	r1^=	0x001F 
	r1&=	0x001F			//b0~4 of r1 is result 
	r2 =	[KeyScanFlag] 
	r2&=	0xF000 
	r2|=	S_ReadKeyAfterBounce 
	[KeyScanFlag] = r2|r1 
	r1 =	[KeyQueueBufPtr]     //send debounce time 
	r1&=	0x1FFF 
	r1|=	KeyDebounceTime 
	[KeyQueueBufPtr] = r1 
	retf 
//----------------------------------------------------------------------------// 
F_ReadKeyAfterBounce:			//the second read after bounce time 
	r1 =	[KeyQueueBufPtr] 
	test    r1,0xE000 
	jz      ?L_BounceTimeOut 
	goto	?L_ReadKeyOver 
?L_BounceTimeOut: 
	bp =	P_IOA_Data 
	r1 =	[bp] 
	r1^=	0x001F 
	r1&=	0x001F			//b0~4 of R1 is result 
	r2 =	[KeyScanFlag] 
	r3 =	r2 & 0x001F 
	cmp     r1,r3 
	jnz	?L_KeyStatusOk		//ignore, not equal 
	bp =	r2 lsr 4 
	bp =	bp lsr 4 
	bp =	bp lsr 4		//the current scan line 
	bp+=	KeyStatusBuf 
	r3|=	[bp] 
	r3^=	[bp]			//'0' -- '1',the corresponding bit is '1' 
	r3 =	r3 LSL 4 
	r1|=	r3 LSL 4 
	[bp]	= r1 
?L_KeyStatusOk: 
	r1 =	[KeyScanFlag] 
	r1+=	0x1000 
	r1&=	0xF000 
	cmp	r1,0x5000		//have all lines scanned? 
	jge	?L_KeyScanLineOver	//check key and scan again 
	r1|=	S_ReadKeyBeforeBounce	//check next line 
	[KeyScanFlag] = r1 
?L_PrepareNextScanLine: 
	r1 =	r1 lsr 4 
	r1 =	r1 lsr 4 
	r1 =	r1 lsr 4 
	r1+=	TW_ScanLine 
	r1 =	[r1] 
	int	off 
	r2 =	[P_IOB_Buf] 
	r2&=	0x00E0 
	r2|=	r1 
	[P_IOB_Data] = r2		  //Set scan line 
	int	fiq,irq 
	jmp	?L_ReadKeyOver 
?L_KeyScanLineOver: 
	r1 |= S_KeyCodeMapping 
	[KeyScanFlag] = r1 
?L_ReadKeyOver: 
	retf 
//------------------------------------------------------------------------------- 
TW_ScanLine: 
	.DW      0x001F - 0x0001	// IOB0 = 0 
	.DW      0x001F - 0x0002	// IOB1 = 0 
	.DW      0x001F - 0x0004	// IOB2 = 0 
	.DW      0x001F - 0x0008	// IOB3 = 0 
	.DW      0x001F - 0x0010	// IOB4 = 0 
//----------------------------------------------------------------------------// 
F_KeyCodeMapping: 
	r1 =	0x0000			//r1 - column number 
?L_SearchKeyLoop: 
	bp =	r1+KeyStatusBuf 
	r2 =	[bp] 
	test	r2,0x1F00 
	jnz	?L_FindKeyChanged	//key is changed to be pressed from release 
	r1+=	0x0001 
	cmp	r1,0x0005 
	jl	?L_SearchKeyLoop 
	goto	?L_ReStartScanKey 
?L_FindKeyChanged:			//r1 - column number 
	r3 =	r2 lsr 4 
	r3 =	r3 lsr 4 
	r3&=	0x001F 
	r3^=	0x001F 
	r3&=	r2 
	jz	?L_ChangePressSameKey 
	goto	?L_ReStartScanKey 
?L_ChangePressSameKey: 
//---------------------------------------------------------------------------- 
//Check if other key is pressed 
	r4 = KeyStatusBuf 
?L_SearchOtherKeyLoop: 
	cmp	r4,bp 
	jz      ?L_SearchNextLine 
	r3 =	[r4] 
	test    r3,0x001F 
	jz	?L_SearchNextLine 
	goto	?L_ReStartScanKey	//other key is still pressed 
?L_SearchNextLine: 
	r4+=	0x0001 
	cmp     r4,KeyStatusBuf+0x0005 
	jl	?L_SearchOtherKeyLoop 
//---------------------------------------------------------------------------- 
	bp =	TB_KeyNumber		//r2 - key status buffer's value 
	bp+=	r1 
	r3 =	[bp] 
	r2&=	0x1F00 
	r2 =	r2 LSL 2 
?L_GetRowNumberLoop: 
	r3-=	0x0001 
	r2 =	r2 LSL 1 
	jpl	?L_GetRowNumberLoop 
	test	r2,0x7FFF 
	jz	?L_NoOtherKey 
	goto	?L_ReStartScanKey 
?L_NoOtherKey: 
	r3+=	TB_KeyCode 
	r1 =	[r3]			//get key_code 
 
	r2 = [KeyQueueBufPtr] 
	test    r2,0x0800 
	jnz	?L_ReStartScanKey	//KeyQueueBuf is full 
?L_KeyBufNotFull: 
	r2 =	r2 lsr 4 
	r2&=	0x0007			//write pointer 
	r3 =	r2 lsr 1 
	r3+=	KeyQueueBuf 
	r4 =	[r3] 
	test    r2,0x0001 
	jz      ?L_SaveKeyLowByte 
	r4&=	0x00FF 
	r1 =	r1 LSL 4 
	r1 =	r1 LSL 4 
	jmp     ?L_KeyValueIsOk 
?L_SaveKeyLowByte: 
	r4&=	0xFF00 
?L_KeyValueIsOk: 
	r1|=	r4 
	[r3]	= r1			//store key 
	r1 =	[KeyQueueBufPtr] 
	r1+=	0x0110			//increase writer pointer & size 
	r1&=	0xFF7F 
	[KeyQueueBufPtr] = r1 
?L_ReStartScanKey: 
	call    F_ClrKeyStatusBuf 
	r1 = S_ReadKeyBeforeBounce	//initialize KeyScanFlag 
	[KeyScanFlag] = r1		//scan from R-option line 
	r1 =	TW_ScanLine 
	r1 =	[r1] 
	int	off 
	r2 =	[P_IOB_Buf] 
	r2&=	0x00E0 
	r2|=	r1 
	[P_IOB_Data] = r2		//Set scan line 
	int	fiq,irq 
	retf 
//------------------------------------------------------------------------------- 
TB_KeyNumber: 
	.DW    5 
	.DW    10 
	.DW    15 
	.DW    20 
	.DW    25 
//------------------------------------------------------------------------------- 
TB_KeyCode: 
         .DW      C_One,      C_Two,   C_Three, C_Redial, C_Check; 
         .DW      C_Four,     C_Five,  C_Six,   C_Pause,  C_Vip;    
         .DW      C_Seven,    C_Eight, C_Nine,  C_Store,  C_Hold;   
         .DW      C_Star,     C_Zero,  C_Pound, C_Flash,  C_Review; 
         .DW      C_HandFree, C_Up,    C_Down,  C_Delete, C_Dummy; 
//------------------------------------------------------------------------------- 
//                  IOB0      IOB1     IOB2       IOB3       IOB4      
//              +----------+--------+--------+-----------+-----------+ 
//        IOA0  |    1     |   2    |   3    |Redial/Auto| Check     | 
//              +----------+--------+--------+-----------+-----------+ 
//        IOA1  |    4     |   5    |   6    |Pause/Inhib|  VIP      | 
//              +----------+--------+--------+-----------+-----------+ 
//        IOA2  |    7     |   8    |   9    |   Store   |Hold       | 
//              +----------+--------+--------+-----------+-----------+ 
//        IOA3  | * / P->T |   0    |   #    |Flash/Clear|Review/Next| 
//              +----------+--------+--------+-----------+-----------+ 
//        IOA4  | HandFree |   Up   |  Down  |   Delete  |   Dummy   | 
//              +----------+--------+--------+-----------+-----------+ 
// 
//------------------------------------------------------------------------------- 
F_StartKeyScan:				//initialize key scan 
	r1 = 0				//clear KeyStatusBuf 
	[KeyQueueBufPtr] = r1	//clear KeyQueueBufPtr 
	call    F_ClrKeyStatusBuf 
	r1 = S_ReadKeyBeforeBounce	//initialize KeyScanFlag 
	[KeyScanFlag] = r1		//scan from R-option line 
	r1 =	TW_ScanLine 
	r1 =	[r1] 
	r2 =	[P_IOB_Buf] 
	r2&=	0x00E0 
	r2|=	r1 
	[P_IOB_Data] = r2		//Set scan line 
	retf 
//------------------------------------------------------------------------------- 
F_ClrKeyStatusBuf: 
	bp =	KeyStatusBuf 
	r1 =	0x00FF 
?L_ClrBufLoop: 
	r2 =	[bp] 
	r2&=	r1 
	[bp++]	= r2 
	cmp	bp,KeyStatusBuf+5 
	jb	?L_ClrBufLoop 
	retf 
//----------------------------------------------------------------------- 
//Key code constants 
.const   C_Dummy           =0x0000; 
.const   C_One             =0x0001; 
.const   C_Two             =0x0002; 
.const   C_Three           =0x0003; 
.const   C_Four            =0x0004; 
.const   C_Five            =0x0005; 
.const   C_Six             =0x0006; 
.const   C_Seven           =0x0007; 
.const   C_Eight           =0x0008; 
.const   C_Nine            =0x0009; 
.const   C_Zero            =0x000A; 
.const   C_Star            =0x000B; 
.const   C_Pound           =0x000C; 
 
.const   C_Pause           =0x000D; 
.const   C_Flash           =0x001F; 
 
.const   C_Redial          =0x0020; 
.const   C_Store           =0x0021; 
.const   C_Up              =0x0023; 
.const   C_Down            =0x0024; 
.const   C_Recall          =0x0026; 
.const   C_Review          =0x0027; 
.const   C_Hold            =0x0028; 
.const   C_HandFree        =0x0029; 
.const   C_Delete          =0x002A; 
.const   C_Vip             =0x002C; 
.const   C_Check           =0x0032; 
//-----------------------------------------------------------------------