Commit bcb499b5 authored by Jeffrey Lee's avatar Jeffrey Lee
Browse files

Add support for new extended internal key codes, low level key codes, and key handler format

Detail:
  s/Middle - Added OS_ReadSysInfo 13 to allow the kernel to validate a key handler before the owner attempts to install it
  Resources/UK/Messages - Text for new "Bad key handler" error
  s/GetAll, s/PMF/Def - Get rid of now obsolete s/PMF/Def file. It only contained definitions for pre-HAL hardware, and for the key handler layout (now in Hdr:Keyboard)
  hdr/KeyWS - Increased size of KeysDown array so it can hold 768 keys instead of 160. Trim a couple of obsolete variables, and increase CurrKey/OldKey from 1 byte to 4 bytes.
  s/PMF/key, s/PMF/osbyte - Main bulk of the changes for the new key handling. All the important interfaces are now able to deal with extended (i.e. > 8 bit) internal key numbers, and the kernel is able to cope with key handlers which use 16 bit internal/low level key numbers instead of 8 bit.
Admin:
  Tested on Pandora & BB-xM
  Requires HdrSrc-2_20


Version 5.35, 4.79.2.178. Tagged as 'Kernel-5_35-4_79_2_178'
parent 80d476ae
......@@ -163,6 +163,7 @@ SNoMask:Mask or Palette operations not supported in this display depth
BadVIDCDiv:Bad VIDC divider value
BadPlatReas:Unknown OS_PlatformFeatures reason code
UnConv:Unsupported conversion
BadKeyHandler:Bad key handler
600:ARM 600 Processor
610:ARM 610 Processor
......
......@@ -13,11 +13,11 @@
GBLS Module_ComponentPath
Module_MajorVersion SETS "5.35"
Module_Version SETA 535
Module_MinorVersion SETS "4.79.2.177"
Module_Date SETS "21 Nov 2012"
Module_ApplicationDate SETS "21-Nov-12"
Module_MinorVersion SETS "4.79.2.178"
Module_Date SETS "05 Dec 2012"
Module_ApplicationDate SETS "05-Dec-12"
Module_ComponentName SETS "Kernel"
Module_ComponentPath SETS "castle/RiscOS/Sources/Kernel"
Module_FullVersion SETS "5.35 (4.79.2.177)"
Module_HelpVersion SETS "5.35 (21 Nov 2012) 4.79.2.177"
Module_FullVersion SETS "5.35 (4.79.2.178)"
Module_HelpVersion SETS "5.35 (05 Dec 2012) 4.79.2.178"
END
......@@ -5,19 +5,19 @@
*
*/
#define Module_MajorVersion_CMHG 5.35
#define Module_MinorVersion_CMHG 4.79.2.177
#define Module_Date_CMHG 21 Nov 2012
#define Module_MinorVersion_CMHG 4.79.2.178
#define Module_Date_CMHG 05 Dec 2012
#define Module_MajorVersion "5.35"
#define Module_Version 535
#define Module_MinorVersion "4.79.2.177"
#define Module_Date "21 Nov 2012"
#define Module_MinorVersion "4.79.2.178"
#define Module_Date "05 Dec 2012"
#define Module_ApplicationDate "21-Nov-12"
#define Module_ApplicationDate "05-Dec-12"
#define Module_ComponentName "Kernel"
#define Module_ComponentPath "castle/RiscOS/Sources/Kernel"
#define Module_FullVersion "5.35 (4.79.2.177)"
#define Module_HelpVersion "5.35 (21 Nov 2012) 4.79.2.177"
#define Module_FullVersion "5.35 (4.79.2.178)"
#define Module_HelpVersion "5.35 (05 Dec 2012) 4.79.2.178"
#define Module_LibraryVersionInfo "5:35"
......@@ -32,19 +32,19 @@ keyprefix SETS "Key$"
^ 0, R11
CurrKey # 1 ; current key in two key rollover
OldKey # 1 ; old key in two key rollover
CurrKey # 4 ; current key in two key rollover
OldKey # 4 ; old key in two key rollover
KbId # 1
LastKbId # 1
AutoRepeatCount # 1
Debouncing # 1 ; NZ => do delay next, Z => do repeat
MouseButtons # 1 ; bit0=R, bit1=C, bit2=L
PendingAltType # 1 ; 1 => A, 2 => SA, 3 => CA, 4 => CSA
ModulesOK # 1 ; bit0=1 => modules are initialised
; bit1=1 => we have offered service
LastLED # 1 ; last request for LED change, so we don't send repeated ones
MouseType # 1 ; current pointer device type
[ STB
MousePresent # 1 ; mouse detected
]
MouseReporting # 1 ; mouse is sending reports itself
NoDebounce # 1 ; NZ => no kernel key debounce
; set if R2="NoKd" on KeyV 0 entry
......@@ -66,7 +66,7 @@ MouseBoundBRow * MouseBounds+4
MouseBoundRCol * MouseBounds+8
MouseBoundTRow * MouseBounds+12
KeysDown # 20 ; bitmap of all down keys
KeysDown # &300/8 ; bitmap of all down keys
SoftKeyName # 3 + :LEN:(keyprefix) ; up to 2 digits + terminator
......
......@@ -75,8 +75,7 @@
GET Hdr:nvram
GET Hdr:PortMan
GET Hdr:SerialOp
GET s.PMF.DEF ; Common with 6502 code in the keyboard
Protocol
GET Hdr:Keyboard
; now the main parts of the MOS
......
......@@ -1291,7 +1291,7 @@ dhte
; Out r0 = sysinfo for r0in
ReadSysInfo_Code ROUT
CMP r0,#13 ;R0 > 12, so illegal value
CMP r0,#14 ;R0 > 13, so illegal value
ADDLO PC, PC, R0,LSL #2
B ReadSysInfo_InvalidReason
......@@ -1308,6 +1308,7 @@ ReadSysInfo_Code ROUT
B ReadSysInfo_InvalidReason ; ROL's "read OS version" call
B %FT110
B %FT120
B %FT130
ReadSysInfo_InvalidReason
ADR r0, ErrorBlock_BadReadSysInfo
......@@ -2111,6 +2112,39 @@ RSI_DebugRX
Pull "r1-r3,r9,r14"
ExitSWIHandler
; OS_ReadSysInfo 13 - Validate key handler
;
; On entry:
; r0 = 13 (reason code 13)
; r1 = key handler address (0 to just return valid flags)
;
; On exit:
; r0 = Mask of supported key handler flags
; Or pointer to error block
;
130
LDR R0, =KeyHandler_Flag_Wide
CMP R1, #0
ExitSWIHandler EQ
Push "R2"
LDR R2, [R1, #KeyHandler_KeyTranSize]
TST R2, #KeyHandler_HasFlags
LDRNE R2, [R1, #KeyHandler_Flags]
BICNES R2, R2, R0
Pull "R2"
ExitSWIHandler EQ
ADR R0, ErrorBlock_BadKeyHandler
[ International
Push "lr"
BL TranslateError
Pull "lr"
]
ORR lr, lr, #V_bit
ExitSWIHandler
MakeErrorBlock BadKeyHandler
;
; Extended ROM footer functions
;
......
; Copyright 1996 Acorn Computers Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; > $.Source.PMF.Def
MACRO
Protocol
;
; Protocol constants
;
; 4 bit codes for input commands
;
LEDON * &00
LEDOFF * &10
REQUEST * &20
ACK * &30
SPDDATA * &40 ;Bottom four bits are data to convert
RSTREQ * &80 ;Request for reset
;
; 4 bit input data types
;
; Requests
;
KBID * 0
SPDRESET * 1
MDATA * 2 ;New mouse position, even if it hasn't moved
;
; Acks
;
BYTE * 0
SCAN * 1
MOUSE * 2
ALL * 3
;
; data output
;
; Type d7 d6 d5 d4 d3 d2 d1 d0 number of bytes
; Reset 1 x x x x x x x 1
; Key up 0 0 1 1 x x x x 2 (row then column)
; Key down 0 0 1 0 x x x x 2 (row then column)
; Mouse change 0 1 x x x x x x 2 (X, Y)
; SPD data 0 0 0 0 x x x x 8
; KB Ids 0 0 0 1 x x x x 2 (low nibble then high nibble)
;
; The keyboard type
;
IDTYPE * &10
KBTYPE * 0 ;This is keyboard 0
;
; Key transitions
;
KEYDOWN * &20
KEYUP * &30
;
; Mouse transitions
;
MMOVED * &40
;
; SPD converted data
;
SPDDONE * 0
;
; Reset types
;
HRDRESET * &FF
RST1ACK * &FE
RST2ACK * &FD
; New keyboard protocols
; Keyboard -> ARM
K1mdat * &00 ; 0xxx xxxx Mouse data from keyboard
K1kbid * &80 ; 10xx xxxx Keyboard ID from keyboard
K1kdda * &C0 ; 1100 xxxx Key down data
K1kuda * &D0 ; 1101 xxxx Key up data
K1pdat * &E0 ; 1110 xxxx SPD data from keyboard (won't happen)
K1rak2 * &FD ; 1111 1101 Reset acknowledge 2
K1rak1 * &FE ; 1111 1110 Reset acknowledge 1
K1hrst * &FF ; 1111 1111 Hard reset
K1kbidmask * &3F ; 0011 1111 Valid bits in keyboard id
K1notmousedata * &80
; ARM -> Keyboard
;
; The IOC registers
;
^ &04, R12
KARTTx # 0
KARTRx # 0
^ &20, R12
IRQStatusB # 4
IRQReqB # 4
IRQMaskB # 4
^ &70, R12
Timer3Low # 4
Timer3High # 4
Timer3Go # 4
Timer3Latch # 4
; Register bits
KARTRxBit * &80
KARTTxBit * &40
KARTIRQBits * KARTTxBit :OR: KARTRxBit
K1leds * &00 ; 0000 0xxx Set LED states
K1rqid * &20 ; 0010 0000 Request keyboard id
K1prst * &21 ; 0010 0001 SPD reset
K1rqmp * &22 ; 0010 0010 Request mouse position
K1nack * &30 ; 0011 0000 Acknowledge (keys- mouse-)
K1sack * &31 ; 0011 0001 Acknowledge (keys+ mouse-)
K1mack * &32 ; 0011 0010 Acknowledge (keys- mouse+)
K1smak * &33 ; 0011 0011 Acknowledge (keys+ mouse+)
K1back * &3F ; 0011 1111 Byte acknowledge (between 2 data bytes)
K1rqpd * &40 ; 0100 xxxx Request SPD data conversion
; Keyboard vector offsets
^ 0
KVKeyTran # 4
KVKeyTranSize # 4
KVInkeyTran # 4
KVShiftingList # 4
KVSpecialList # 4
KVSpecialCodeTable # 4
KVInit # 4
KVPendingAltCode # 4
KVPendingAltSpecial # 4 ; Used only internally
MEND
END
......@@ -114,30 +114,30 @@ KeyPostInit ROUT
; *****************************************************************************
ClearKbd ROUT
Push R14
Entry "R1-R2"
MOV R0, #&FF
STRB R0, CurrKey ; no current key
STRB R0, OldKey
STR R0, CurrKey ; no current key
STR R0, OldKey
STRB R0, LastLED
; Set up keyboard table
MOV R0, #0 ; All keys up
STR R0, KeysDown ; zero 160 bits = 5 words
STR R0, KeysDown +4
STR R0, KeysDown +8
STR R0, KeysDown +12
STR R0, KeysDown +16
MOV R1, #?KeysDown
ADR R2, KeysDown
10
SUBS R1, R1, #4
STR R0, [R2], #4
BNE %BT10
Pull PC
EXIT
; *****************************************************************************
;
; UpdateLEDs - Update the LED(s) from the keyboard status byte
;
; in: R11 -> keyboard workspace
; R12 -> IOC
;
; out: R0, R1 corrupted
;
......@@ -165,7 +165,6 @@ UpdateLEDs ROUT
;
; in: R1 = desired LED state (bit 0 = caps lock, 1 = num lock, 2 = scroll lock)
; R11 -> keyboard workspace
; R12 -> IOC
;
; out: R0, R1 corrupted
;
......@@ -279,7 +278,7 @@ KeyboardEnable
STRB r1, LastKbId ; Remember last keyboard id that initialised.
LDR r8, [r0, #KVInit] ; Initialise key handler.
LDR r8, [r0, #KeyHandler_Init] ; Initialise key handler.
ADD r8, r8, r0
BL CallUserKeyCode
......@@ -325,7 +324,7 @@ GotKey ROUT
MOV r2, r1
SUB r1, r0, #1
CMP R2, #&A0
CMP R2, #?KeysDown*8
BCS %FT05
ADR R0, KeysDown
MOV lr, R2, LSR #5
......@@ -356,17 +355,17 @@ GotKey ROUT
TEQ r1, #0 ; if key up then
BEQ %FT30 ; go and deal with it
LDRB R0, CurrKey
LDR R0, CurrKey
TEQ R0, #&FF ; have we got a current key ?
BEQ %FT20
LDRB R1, OldKey
LDR R1, OldKey
TEQ R1, #&FF ; have we got an old key ?
BNE %FT50 ; ignore new - we've got 2 down already
STRB R0, OldKey ; make current key old
STR R0, OldKey ; make current key old
20
STRB R2, CurrKey ; update current
STR R2, CurrKey ; update current
LDRB r1, NoDebounce ; check debouncing?
TEQ r1, #0
MOVEQ R0, #2 ; Eq.. normal kernel debounce
......@@ -381,31 +380,32 @@ GotKey ROUT
B %FT50
30
LDRB R0, OldKey
LDR R0, OldKey
TEQ R0, R2 ; is it old key going up ?
BNE %FT40
; Old key going up
LDRB R0, CurrKey ; current key is one to ignore in scan
LDR R0, CurrKey ; current key is one to ignore in scan
BL ScanKeys
STRPLB R0, OldKey ; found key, so current -> old
STRPL R0, OldKey ; found key, so current -> old
BPL %BT20 ; and R2 -> current
MOV R0, #&FF ; else mark old key invalid
STRB R0, OldKey
STR R0, OldKey
B %FT50 ; and return
40
LDRB R1, CurrKey
LDR R1, CurrKey
TEQ R1, R2 ; is it current key going up ?
BNE %FT50 ; not interested if not
BL ScanKeys ; R0 was OldKey
BPL %BT20 ; was a key so make that current
STRB R2, CurrKey ; mark current key up (R2 = -1)
MOV R2, #&FF
STR R2, CurrKey ; mark current key up
50
[ AssembleKEYV
......@@ -441,8 +441,10 @@ KeyboardEvent ROUT
ScanKeys ROUT
Push "R0, R14"
ADR R1, KeysDown
MOV R2, #4
MOV R2, #(?KeysDown/4)-1
10
TEQ R2, #&200/32
MOVEQ R2, #4 ; skip extension key range &100
LDR R3, [R1, R2, LSL #2] ; get the word
TEQ R3, #0 ; if any keys in this down, skip
BNE %FT20
......@@ -491,15 +493,21 @@ CheckForShiftingKey ROUT
LDR R0, KeyVec
CMP R0, #-1
MOVEQ PC, R14
LDR R3, [R0, #KVKeyTranSize] ; maximum internal key number +1
LDR R3, [R0, #KeyHandler_KeyTranSize] ; maximum internal key number +1
TST R3, #KeyHandler_HasFlags
BIC R3, R3, #KeyHandler_HasFlags
LDRNE R5, [R0, #KeyHandler_Flags]
TSTNE R5, #KeyHandler_Flag_Wide
BNE %FT20 ; Use wide version of routine
CMP R2, R3 ; is it outside table ?
LDRCC R3, [R0, #KVKeyTran] ; no, R3 := offset to keytran
LDRCC R3, [R0, #KeyHandler_KeyTran] ; no, R3 := offset to keytran
ADDCC R3, R3, R0 ; R3 -> keytran
LDRCC R3, [R3, R2, LSL #2] ; R3 = table word for this key
CMNCC R3, #1 ; C=1 <=> outside table or is special
MOVCC PC, R14 ; can't be shifting key
LDR R3, [R0, #KVShiftingList] ; R3 = offset to shifting key list
LDR R3, [R0, #KeyHandler_ShiftingList] ; R3 = offset to shifting key list
LDRB R4, [R3, R0]! ; R4 = length of shifting key list
TEQ R4, #0
10
......@@ -511,6 +519,45 @@ CheckForShiftingKey ROUT
CMP R4, #1 ; C=1 <=> shifting key
MOV PC, R14 ; not one of the shifting keys
20
CMP R2, R3 ; is it outside table ?
LDRCC R3, [R0, #KeyHandler_KeyTran] ; no, R3 := offset to keytran
ADDCC R3, R3, R0 ; R3 -> keytran
LDRCC R4, =&FF00FF00
ADDCC R3, R3, R2, LSL #3 ; R3 = table address for this key
LDMCCIA R3, {R3, R5} ; R3, R5 = table entry for this key
EORCC R3, R3, R4
EORCC R5, R5, R4
ANDCC R3, R3, R5
CMNCC R3, #1 ; C=1 <=> outside table or is special
MOVCC PC, R14 ; can't be shifting key
LDR R3, [R0, #KeyHandler_ShiftingList] ; R3 = offset to shifting key list
[ NoARMv4
LDRB R4, [R3, R0]!
LDRB R5, [R3, #1]
ORRS R4, R4, R5, LSL #8 ; R4 = length of shifting key list
|
LDRH R4, [R3, R0]!
TEQ R4, #0 ; R4 = length of shifting key list
]
30
[ NoARMv4
ASSERT :LNOT: NoUnaligned
LDRNE R5, [R3, R4, LSL #1]
MOVNE R5, R5, LSL #16
TEQNE R5, R2, LSL #16
|
ADDNE R5, R3, R4, LSL #1
LDRNEH R5, [R5]
TEQNE R5, R2
]
SUBNES R4, R4, #1
BNE %BT30
CMP R4, #1 ; C=1 <=> shifting key
MOV PC, R14 ; not one of the shifting keys
; *****************************************************************************
;
; CallSpecialCode - Call code for a special key
......@@ -521,8 +568,13 @@ CheckForShiftingKey ROUT
;
CallSpecialCode ROUT
LDR R3, [R0, #KeyHandler_KeyTranSize]
ADR R6, NullCharList
LDR R3, [R0, #KVSpecialList] ; R3 = offset to special list
TST R3, #KeyHandler_HasFlags
LDRNE R3, [R0, #KeyHandler_Flags]
TSTNE R3, #KeyHandler_Flag_Wide
LDR R3, [R0, #KeyHandler_SpecialList] ; R3 = offset to special list
BNE CallSpecialCodeWide
LDRB R4, [R3, R0]! ; R4 = length of special list
TEQ R4, #0
MOVEQ PC, R14 ; no special keys, so can't be one
......@@ -534,8 +586,26 @@ CallSpecialCode ROUT
BNE %BT10
MOV PC, R14
CallSpecialCodeWide
[ NoARMv4
LDRB R4, [R3, R0]!
LDRB R5, [R3], #1
ORR R4, R4, R5, LSL #8 ; R4 = length of special list
|
LDRH R4, [R3, R0]! ; R4 = length of special list
]
TEQ R4, #0
MOVEQ PC, R14 ; no special keys, so can't be one
15
LDHA R5, R3, R4, R8
TEQ R5, R2
BEQ %FT20
SUBS R4, R4, #1
BNE %BT15
MOV PC, R14
20
LDR R3, [R0, #KVSpecialCodeTable] ; R3 = offset to special table
LDR R3, [R0, #KeyHandler_SpecialCodeTable] ; R3 = offset to special table
ADD R3, R3, R0 ; R3 -> special code table
SUB R5, R3, #4 ; 0th entry is for 1st special
......@@ -557,7 +627,6 @@ CallUserKeyCode ROUT
BLNE OfferKeyStatusUpCall
STROSB R5, KeyBdStatus, R12
Pull R14
MOV R12, #IOC
B UpdateLEDs
10
......@@ -629,7 +698,7 @@ CentiSecondTick ROUT
SUBS R0, R0, #1 ; decrement
STRCS R0, InkeyCounter ; store back unless was frozen at 0
LDRB R2, CurrKey
LDR R2, CurrKey
TEQ R2, #&FF
Pull "R11,PC", EQ ; no current key, so no auto-repeat
......@@ -747,24 +816,43 @@ GenerateChar ROUT
LDR R0, KeyVec
CMP R0, #-1
Pull PC,EQ
LDR R3, [R0, #KVKeyTranSize] ; get size
LDR R5, [R0, #KeyHandler_KeyTranSize] ; get size
BIC R3, R5, #KeyHandler_HasFlags
CMP R2, R3 ; if outside table
BCS %FT04 ; then assume special
LDR R3, [R0, #KVKeyTran] ; R3 = offset to KeyTran
LDR R3, [R0, #KeyHandler_KeyTran] ; R3 = offset to KeyTran
ADD R3, R3, R0 ; R3 -> KeyTran
TST R5, #KeyHandler_HasFlags
LDRNE R6, [R0, #KeyHandler_Flags]
TSTNE R6, #KeyHandler_Flag_Wide
MOVEQ R6, #1
MOVNE R6, #2
ADDNE R3, R3, R2, LSL #2
; now modify for CTRL and SHIFT
LDROSB R5, KeyBdStatus
TST R5, #KBStat_CtrlEngaged
ADDNE R3, R3, #2
ADDNE R3, R3, R6, LSL #1
TST R5, #KBStat_ShiftEngaged
ADDNE R3, R3, #1
LDRB R3, [R3, R2, LSL #2] ; get real code
ADDNE R3, R3, R6
TEQ R6, #1
[ NoARMv4
ASSERT :LNOT: NoUnaligned
LDR R3, [R3, R2, LSL #2] ; get real code
MOVNE R3, R3, LSL #16
ANDEQ R3, R3, #255
MOVNE R3, R3, LSR #16
|
ADD R3, R3, R2, LSL #2
LDREQB R3, [R3]
LDRNEH R3, [R3]
]
; apply CAPS lock modifying
......@@ -893,7 +981,7 @@ NULNULList ; list for returning NUL NUL
ProcessPendingAlt
ADR R6, NullCharList
LDR R8, [R0, #KVPendingAltCode]
LDR R8, [R0, #KeyHandler_PendingAltCode]
ADD R8, R8, R0
BL CallUserKeyCode
B ReturnNChars
......@@ -1332,6 +1420,7 @@ NewInkeyPos
NewInkeyNeg
EOR R1, R1, #&7F ; invert bits for scan call
EOR R2, R2, #&7F
BL BBCScanKeys
Pull PC
......@@ -1339,20 +1428,22 @@ NewInkeyNeg
;
; BBCScanKeys - Test individual key or scan for key depression
;
; in: R1 = 0..&7F => scan keyboard from BBC internal key R1
; in: R1 = 0..&7F => scan keyboard from BBC internal key R1+(R2<<8)
; out: C=0 => R1 = BBC internal key found
; C=1 => R1 = &FF (no key found)
;
; in: R1 = &80..&FF => test if BBC internal key (R1 EOR &80) is down
; in: R1 = &80..&FF => test if BBC internal key ((R1+(R2<<8)) EOR &80) is down
; out: C=0, R1=R2=&00 => key is up
; C=1, R1=R2=&FF => key is down
;
BBCScanKeys ROUT
Push R11
Push "R10, R11, LR"
LDR R11, =ZeroPage+KeyWorkSpace
AND R1, R1, #&FF ; trap wallies
AND R10, R2, #&7F
LDR R2, KeyVec
TST R1, #&80 ; >=&80 => test single key
......@@ -1362,13 +1453,25 @@ BBCScanKeys ROUT
ADD R0, R2, #1
CMP R0, #1 ; if no key handler then
MOVCC R1, #0 ; return key up (C=0)
BCC ExitBBCScan
BCC ExitBBCTest
LDR R0, [R2, #KVInkeyTran]
TEQ R1, #&80+13 ; extension range?
TEQNE R1, #&80+15
BEQ DoBBCTestExtension
LDR R0, [R2, #KeyHandler_InkeyTran]
ADD R0, R2, R0 ; R0 -> InkeyTran or InkeyTran2
ADD R0, R0, #4 * &FF ; R0 -> InkeyTran+4*&FF
LDR R0, [R0, -R1, LSL #2] ; get word of indexes into KeysDown
LDR R10, [R2, #KeyHandler_KeyTranSize]
TST R10, #KeyHandler_HasFlags
LDRNE R10, [R2, #KeyHandler_Flags]
TSTNE R10, #KeyHandler_Flag_Wide
MOVNE R2, #&FF0000
BNE DoBBCTestWide
MOV R2, #&FF000000
02
CMP R0, #-1 ; is it all FF's
......@@ -1384,26 +1487,71 @@ BBCScanKeys ROUT
MOVS R1, R3, LSR #31 ; R1 = 0 if up, 1 if down
ORREQ R0, R2, R0, LSR #8 ; shift down, putting FF in top byte
BEQ %BT02
04
CMP R1, #1 ; C=1 <=> at least one of keys down
MOVCC R1, #0
MOVCS R1, #&FF
MOV R2, R1
ExitBBCScan
Pull R11
MOV PC, R14
ExitBBCTest
Pull "R10, R11, PC"
DoBBCTestWide
MOV R1, R0, LSL #16 ; get bottom entry
CMP R1, #&FF0000 ; is it FF?
MOVEQ R1, #0 ; if so then none of keys down
BEQ %BT04
DoBBCScan
ADR R3, KeysDown ; look up in KeysDown
MOV R1, R1, LSR #5+16
LDR R3, [R3, R1, LSL #2] ; get word of 32 bits
AND R1, R0, #31
MOV R3, R3, LSL R1 ; put relevant bit into top bit
MOVS R1, R3, LSR #31 ; R1 = 0 if up, 1 if down
ORREQ R0, R2, R0, LSR #16 ; shift down, putting FF in top entry
BEQ DoBBCTestWide
B %BT04
DoBBCTestExtension
TST R1, #2
ADDEQ R10, R10, #&100 ; EQ -> (R1 AND &7F) = 13
ADDNE R10, R10, #&200 ; NE -> (R1 AND &7F) = 15
ADR R3, KeysDown
MOV R1, R10, LSR #5
LDR R3, [R3, R1, LSL #2]
AND R1, R10, #31
MOV R3, R3, LSL R1
MOV R1, R3, LSR #31
B %BT04
DoBBCScan ROUT
CMP R2, #-1 ; if no key handler then
MOVEQ r1, #&FF ; return all keys up (C=1)
BEQ ExitBBCScan
LDR R0, [R2, #KVInkeyTran]
BEQ ExitBBCTest
Push "R4, R5"
; Check for extension key range and include R10 if necessary
TEQ R1, #13
TEQNE R1, #15
ORREQ R1, R1, R10, LSL #8
LDR R0, [R2, #KeyHandler_InkeyTran]
ADD R0, R2, R0 ; R0 -> InkeyTran or InkeyTran2
Push "R4, R5"
ADD R0, R0, #4 * &7F ; R0 -> InkeyTran+4*&7F
LDR R4, [R2, #KeyHandler_KeyTranSize]
TST R4, #KeyHandler_HasFlags
LDRNE R4, [R2, #KeyHandler_Flags]
TSTNE R4, #KeyHandler_Flag_Wide
MOVNE R4, #&FF0000
BNE DoBBCScanWide
MOV R4, #&FF000000
10
AND R3, R1, #&7F-2
TEQ R3, #13 ; 13 or 15?
BLEQ DoBBCScanExtension ; handle extension range scan
LDR R3, [R0, -R1, LSL #2] ; get word of indexes into KeysDown
15
CMP R3, #-1 ; all FFs ?
......@@ -1416,7 +1564,7 @@ DoBBCScan
AND R5, R3, #31
MOV R2, R2, LSL R5 ; put relevant bit into top bit
MOVS R5, R2, LSR #31 ; R5 = 0 for up, 1 for down
BNE %FT20 ; [down, so stop]
BNE ExitBBCScan ; [down, so stop]
ORR R3, R4, R3, LSR #8 ; up -> shift down putting FF in top
B %BT15
18
......@@ -1424,10 +1572,90 @@ DoBBCScan
TEQ R1, #&80 ; if not run out of keys
BNE %BT10 ; then loop
MOV R1, #&FF ; indicate no key
ExitBBCScan
MOV R2, #0
TEQ R1, #&FF
MOVEQ R2, #C_bit
MSR CPSR_f, R2 ; C=0 <=> found key
Pull "R4,R5,R10,R11,PC"
DoBBCScanWide ROUT
AND R3, R1, #&7F-2
TEQ R3, #13 ; 13 or 15?
BLEQ DoBBCScanExtension ; handle extension range scan
LDR R3, [R0, -R1, LSL #2] ; get word of indexes into KeysDown
15
MOV R5, R3, LSL #16 ; get bottom entry
CMP R5, #&FF0000 ; is it FF?
BEQ %FT18 ; then not one of these keys
ADR R2, KeysDown
MOV R5, R5, LSR #5+16
LDR R2, [R2, R5, LSL #2] ; get word of bits
AND R5, R3, #31
MOV R2, R2, LSL R5 ; put relevant bit into top bit
MOVS R5, R2, LSR #31 ; R5 = 0 for up, 1 for down
BNE ExitBBCScan ; [down, so stop]
ORR R3, R4, R3, LSR #16 ; up -> shift down putting FF in top
B %BT15
18
ADD R1, R1, #1 ; go to next key
TEQ R1, #&80 ; if not run out of keys
BNE DoBBCScanWide ; then loop
MOV R1, #&FF ; indicate no key
B ExitBBCScan
DoBBCScanExtension ROUT
; R2, R3, R5, R10 corruptible
; Return to LR if no key found
MOV R10, R1, LSR #8
TST R1, #2
ADDEQ R10, R10, #&100 ; EQ -> (R1 AND &7F) = 13
ADDNE R10, R10, #&200 ; NE -> (R1 AND &7F) = 15
ADR R2, KeysDown
10
MOV R3, R10, LSR #5
LDR R3, [R2, R3, LSL #2]
AND R5, R10, #31
MOVS R3, R3, LSL R5
BNE %FT20 ; found one
BIC R10, R10, #31 ; skip to next word
ADD R10, R10, #32
TEQ R10, #&300
BNE %BT10
; Ran out of extension keys
MOV R1, #16
MOV PC, LR
20
CMP R1, #&FF ; C=0 <=> found key
Pull "R4,R5,R11"
MOV PC, R14
[ NoARMv5
CMP R3, #1<<16
ADDLO R10, R10, #16
MOVLO R3, R3, LSL #16
CMP R3, #1<<24
ADDLO R10, R10, #8
MOVLO R3, R3, LSL #8
CMP R3, #1<<28
ADDLO R10, R10, #4
MOVLO R3, R3, LSL #4
CMP R3, #1<<30
ADDLO R10, R10, #2
MOVLO R3, R3, LSL #2
TST R3, #1<<31
ADDEQ R10, R10, #1
|
CLZ R3, R3
ADD R10, R10, R3
]
; Convert back to inkey key
TST R10, #&100
MOVNE R1, #13
MOVEQ R1, #15
ORR R1, R1, R10, LSL #8
BIC R1, R1, #&FF0000
B ExitBBCScan
; *****************************************************************************
;
......@@ -1437,38 +1665,58 @@ DoBBCScan
; R2 = Old key (------------""------------)
;
; out: R1, R2 preserved
; R3 corrupt
;
; Note: Doesn't deal with extended key numbers
;
WriteKeysDown ROUT
Push R14
LDR R11, =ZeroPage+KeyWorkSpace
MOV R0, R1
AND R0, R1, #&FF ; mask off any extension bits
BL ConvertInternalKey
STRB R0, CurrKey
MOV R0, R2
STR R0, CurrKey
AND R0, R2, #&FF
BL ConvertInternalKey
STRB R0, OldKey
STR R0, OldKey
Pull PC
ConvertInternalKey
; in: R0 = INKEY code EOR &FF
; out: R0 = internal low level key number
; R3 corrupt
ConvertInternalKey ROUT
TST R0, #&80 ; if not in range &80..&FF
MOVEQ R0, #&FF ; return value &FF (key not valid)
MOVEQ PC, R14
EOR R0, R0, #&7F ; else convert to inkey value
Push R4
LDR R3, KeyVec
CMP R3, #-1 ; if no key handler then
MOVEQ R0, #&FF ; return no key
MOVEQ PC, R14
LDR R4, [R3, #KVInkeyTran]
ADD R3, R3, R4 ; R3 -> InkeyTran or InkeyTran2
Pull R4
Push R4
LDR R4, [R3, #KeyHandler_KeyTranSize]
TST R4, #KeyHandler_HasFlags
LDRNE R4, [R3, #KeyHandler_Flags]
TSTNE R4, #KeyHandler_Flag_Wide
LDR R4, [R3, #KeyHandler_InkeyTran]
ADD R3, R3, R0, LSL #2
SUB R3, R3, #&80*4 ; R3 -> InkeyTran-4*&80
LDRB R0, [R3, R0, LSL #2] ; convert to ARM internal key
[ NoARMv4
LDRB R0, [R3, R4]! ; convert to ARM internal key
; (just get 1st key for this key)
LDRNEB R4, [R3, #1]
ORRNE R0, R0, R4, LSL #8
|
LDREQB R0, [R3, R4]
LDRNEH R0, [R3, R4]
]
Pull R4
MOV PC, R14
......
......@@ -815,9 +815,9 @@ Osbyte78
BL WriteKeysDown
MyOsbyte
; Perform Keyboard Scan from 16
; Perform Keyboard Scan from 15
Osbyte7A
MOV R1, #&10
MOV R1, #&0F
; and drop thru to ...
; Perform Keyboard Scan
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment