📄 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,Worldplus
//Current Version: V1.0
//Written Date: 2002/10/30
//-----------------------------------------------------------------------
.public F_KeyScan
.public F_KeyTimerService
.public F_StartKeyScan
//-----------------------------------------------------------------------
.RAM
RW_KeyScanFlag: .DW 0 //b0~b7 - read portA buffer
//b8~11 - state machine
//b12~15 - current scan line
SW_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
RPtr_KeyQueueBuf: .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
SW_KeyQueueBuf: .DW 0,0,0,0
RW_Date: .DW 0
RW_Time: .DW 0
//-----------------------------------------------------------------------
.code
F_KeyTimerService:
r1 = [RPtr_KeyQueueBuf]
test r1,0xE000
jz ?L_KeyTimeOver
r1-= 0x2000
[RPtr_KeyQueueBuf] = r1
?L_KeyTimeOver:
retf
//-----------------------------------------------------------------------
// 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 = [RW_KeyScanFlag]
r1 = r1 lsr 4
r1 = r1 lsr 4
r1&= 0x000F
r1+= V_KeyScan
pc = [r1]
//----------------------------------------------------------------------------//
F_ReadKeyBeforeBounce: //the first read
bp = P_IOA_Data
r1 = [bp]
r1^= 0x001F
r1&= 0x001F //b0~4 of r1 is result
r2 = [RW_KeyScanFlag]
r2&= 0xF000
r2|= S_ReadKeyAfterBounce
[RW_KeyScanFlag] = r2|r1
r1 = [RPtr_KeyQueueBuf] //send debounce time
r1&= 0x1FFF
r1|= KeyDebounceTime
[RPtr_KeyQueueBuf] = r1
retf
//----------------------------------------------------------------------------//
F_ReadKeyAfterBounce: //the second read after bounce time
r1 = [RPtr_KeyQueueBuf]
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 = [RW_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+= SW_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 = [RW_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
[RW_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
[RW_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+SW_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 = SW_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,SW_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 = [RPtr_KeyQueueBuf]
test r2,0x0800
jnz ?L_ReStartScanKey //KeyQueueBuf is full
?L_KeyBufNotFull:
r2 = r2 lsr 4
r2&= 0x0007 //write pointer
r3 = r2 lsr 1
r3+= SW_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 = [RPtr_KeyQueueBuf]
r1+= 0x0110 //increase writer pointer & size
r1&= 0xFF7F
[RPtr_KeyQueueBuf] = r1
?L_ReStartScanKey:
call F_ClrKeyStatusBuf
r1 = S_ReadKeyBeforeBounce //initialize RW_KeyScanFlag
[RW_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_Four, C_Seven, C_Star, C_Flash
.DW C_Two, C_Five, C_Eight, C_Zero, C_Store
.DW C_Three, C_Six, C_Nine, C_Pound, C_Redial
.DW C_Recall, C_Nop, C_Pause, C_IP, C_HandFree
.DW C_Del, C_Out, C_Down, C_Up, C_Hold
//-------------------------------------------------------------------------------
// IOB0 IOB1 IOB2 IOB3 IOB4 IOA5(Opt1) IOA6(Opt2)
// +--------+-------+--------+----------+---------+-----------+-----------+
// IOA0 | 1 | 2 | 3 | Recall | Delete | lock 0 | PPS |
// +--------+-------+--------+----------+---------+-----------+-----------+
// IOA1 | 4 | 5 | 6 | AC | Out | lock all | M/B |
// +--------+-------+--------+----------+---------+-----------+-----------+
// IOA2 | 7 | 8 | 9 | Pause | Down | P/T | Lock0,9 |
// +--------+-------+--------+----------+---------+-----------+-----------+
// IOA3 |*(P-->T)| 0 | # | IP | Up | Enalarm | --- |
// +--------+-------+--------+----------+---------+-----------+-----------+
// IOA4 | Flash | Store | Redial | HandFree | Hold | Tel/Box | --- |
// +--------+-------+--------+----------+---------+-----------+-----------+
//-------------------------------------------------------------------------------
F_StartKeyScan: //initialize key scan
r1 = 0 //clear KeyStatusBuf
[RPtr_KeyQueueBuf] = r1 //clear KeyQueueBufPtr
call F_ClrKeyStatusBuf
r1 = S_ReadKeyBeforeBounce //initialize KeyScanFlag
[RW_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 = SW_KeyStatusBuf
r1 = 0x00FF
?L_ClrBufLoop:
r2 = [bp]
r2&= r1
[bp++] = r2
cmp bp,SW_KeyStatusBuf+5
jb ?L_ClrBufLoop
retf
//-----------------------------------------------------------------------
//Key code constants
.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 = 0x0010
.const C_Store = 0x0012
.const C_Set = 0x0012
.const C_Recall = 0x0013
.const C_Search = 0x0013
.const C_Out = 0x0014
.const C_Up = 0x0016
.const C_Down = 0x0017
.const C_Del = 0x0018
.const C_IP = 0x0019
.const C_HandFree = 0x001A
.const C_Hold = 0x001B
.const C_Redial = 0x001C
.const C_Nop = 0x0000
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -