📄 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;
//-----------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -