;------------------------------------------------------------------------------- ;@doc:file ; ; === Keypad.asm === ; ; Provides methods for reading keys from the keypad. ; ;@doc:end ;------------------------------------------------------------------------------- .module Keypad ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Keypad.Reset === ; ; Resets the keypad. ; ; DESTROYED ; REGISTERS: ; * A ; ;@doc:end ;------------------------------------------------------------------------------- Reset push hl push de push bc ld hl,InjectBuffer ld de,InjectBuffer+1 ld bc,16-1 ld (hl),0 ldir ld a,0 ld (ExecHandle),a ld (LoadTextHandle),a ld (CursorEditingMode),a ;ld (EmersonKeyboardEnabled),a ld a,32 ld (RepeatDelayInitial),a ld a,8 ld (RepeatDelayHeld),a pop bc pop de pop hl ret ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Keypad.GetCurrentKey === ; ; Gets the currently pressed key. ; ; OUTPUTS ; REGISTERS: ; * A - The six least significant bits represent the key value; the two most ; significant bits represent the states of the modifiers. Returns zero ; if no keys or more than one key is pressed. ; ; DESTROYED ; REGISTERS: ; * F ; ;@doc:end ;------------------------------------------------------------------------------- GetCurrentKey push hl push de push bc .fcall "Speed.SlowDown" xor a out (1),a nop in a,(1) inc a jr nz,+ .fcall "Speed.SpeedUp" xor a pop bc pop de pop hl ret + ld d,1 ; Current polling key. ld e,0 ; Last matched key. ld c,$FE ; Group mask. ScanNextGroup ld a,$FF push ix pop ix out (1),a ld a,c push ix pop ix out (1),a push ix pop ix in a,(1) ld l,a ld b,8 - srl l jr c,NoKeyPressed ; So, a bit is set. ld a,d cp skAlpha jr nz,NotScannedAlpha ld a,%01000000 or e ld e,a jr NoKeyPressed NotScannedAlpha cp sk2nd jr nz,NotScanned2nd ld a,%10000000 or e ld e,a jr NoKeyPressed NotScanned2nd ld a,e and %00111111 jr z,FirstKeyFound ; A key is already pressed. ld e,0 jr FinishedScanning FirstKeyFound ld a,e or d ld e,a NoKeyPressed inc d ; Next key djnz - rlc c jr c,ScanNextGroup FinishedScanning ld a,e or a push af .fcall "Speed.SpeedUp" pop af pop bc pop de pop hl ret ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Keypad.GetKey === ; ; Inputs a key. If a key is held it will return the key value periodically ; based on the keypad repeat rate settings (rather than return it every time ; this function is called). ; ; OUTPUTS ; REGISTERS: ; * A - The six least significant bits represent the key value; the two most ; significant bits represent the states of the modifiers. Returns zero ; if no keys or more than one key is pressed. ; ; DESTROYED ; REGISTERS: ; * F ; ;@doc:end ;------------------------------------------------------------------------------- GetKey push bc ld a,(LastKey) ld b,a ld c,$FF - call GetCurrentKey cp c jr z,+ ld c,a jr - + ld (LastKey),a cp b jr nz,KeyNotHeld ; So, the key is held. ; Can it repeat? ld a,(RepeatDelayInitial) or a jr z,KeyNotHeld ld a,(RepeatTimeout) or a jr z,KeyCanRepeat xor a jr GetKeyHandled KeyCanRepeat ld a,(RepeatDelayHeld) ld (RepeatTimeout),a ld a,(LastKey) jr GetKeyHandled KeyNotHeld push af ld a,(RepeatDelayInitial) ld (RepeatTimeout),a pop af GetKeyHandled pop bc or a ret ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Keypad.GetEscapeState === ; ; Gets the state of the Escape key. ; ; OUTPUTS ; REGISTERS: ; * F - Z if Escape was not pressed. ; - NZ and C if Escape was pressed and set the Escape condition. ; - NZ and NC if Escape was pressed but did not set the Escape condition. ; ; DESTROYED ; REGISTERS: ; * AF ; ;@doc:end ;------------------------------------------------------------------------------- GetEscapeState di ld a,(Interrupt.OnKey) or a jr nz,+ ei ret + bit 1,a jr z,+ ei scf ret + ; Standard Escape pressing. ld a,(Host.EscapeBreakEffect) bit 0,a jr nz,+ ei xor a inc a scf ret + ; Escape pressed, but it's disabled. ; Clear Escape flag... xor a ld (Interrupt.OnKey),a ei inc a or a ret ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Keypad.GetCharNoHelper === ; ; Reads a character from the keypad. This routine does not allow the command ; helper to be shown. Characters are injected from the queue if appropriate. ; ; OUTPUTS ; REGISTERS: ; * F - Z if a key was pressed, NZ otherwise. If S is set then this is an ; extended (non-printable) key. ; * A - The character of the key pressed (when S is reset) or an extended key ; (when S is set). ; ; DESTROYED ; REGISTERS: ; * F ; ;@doc:end ;------------------------------------------------------------------------------- GetCharNoHelper di ld a,(Interrupt.OnKey) or a jr z,GetCharNotEsc bit 1,a jr nz,+ ; Standard Escape pressing. ld a,(Host.EscapeBreakEffect) bit 0,a jr z,+ ; Escape pressed, but it's disabled. ; Clear Escape flag... xor a ld (Interrupt.OnKey),a push bc ld bc,(Keycode.Escape * 256) + %01000000 ; Z jr GetCharNonBreakingEsc + push bc ld bc,(Keycode.Escape * 256) + %11000001 ; SZC GetCharNonBreakingEsc push bc pop af pop bc ei ret GetCharNotEsc ei ld a,(ExecHandle) or a jr z,NoExecHandle push hl push de dec a ld e,a .fcall "File.ReadByte" jr c,ExecHandleError jr nz,ExecHandleError ; Byte was read! cp a pop de pop hl ret ExecHandleError ; Either EOF or error reading file; either way, close its handle. push bc push ix ld a,(ExecHandle) dec a ld e,a .fcall "File.Close" xor a ld (ExecHandle),a pop ix pop bc pop de pop hl NoExecHandle ld a,(InjectBuffer) or a jr z,+ xor a ld a,(InjectBuffer) push af push hl push de push bc ld hl,InjectBuffer+1 ld de,InjectBuffer ld bc,16-1 ldir xor a ld (de),a pop bc pop de pop hl pop af ret + push hl push de ld a,(Keyboard.Enabled) or a jr z,Keyboard.NotEnabled push bc .fcall "Speed.SlowDown" .fcall "Emerson.Keyboard.GetKey" push af .fcall "Speed.SpeedUp" pop af jr nz,Keyboard.NoKey ; No key pressed. jr c,Keyboard.NoKey ; Key is being released, not pressed. jp m,Keyboard.NoKey ; "Extended" key. ei pop bc jr MappedChar Keyboard.NoKey ei pop bc Keyboard.NotEnabled call GetKey jr nz,KeyPressed cp 1 ; a = 0, so this forces nz. pop de pop hl ret KeyPressed ld l,a ld h,0 ld de,KeyMaps-1 add hl,de ld a,(hl) or a jr nz,MappedChar cp 1 ; a = 0, so this forces nz. pop de pop hl ret MappedChar or a jp p,+ ld d,a ld e,%11000000 ; s = 1, z = 1 ld a,(CursorEditingMode) or a jr z,NormalCursorEditingMode bit 0,a \ jr z,NotDisabledHard ; *FX 4,1 ld a,d cp KeyCode.Copy jr c,NormalCursorEditingMode cp KeyCode.Up+1 jr nc,NormalCursorEditingMode res 7,e ; Reset S flag. jr NormalCursorEditingMode NotDisabledHard bit 1,a \ jr z,NotDisabledSoft ; *FX 4,2 ld e,0 ; No soft key support as yet. NotDisabledSoft NormalCursorEditingMode push de pop af pop de pop hl ret + pop de pop hl cp a ; Force z ret ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Keypad.GetChar === ; ; Reads a character from the keypad. This routine will allow the user to ; display the command helper. ; ; OUTPUTS ; REGISTERS: ; * F - Z if a key was pressed, NZ otherwise. ; - If C is set then Escape was pressed. ; - If S is set then this is an extended (non-printable) key. ; * A - The character of the key pressed (when S is reset) or an extended key ; (when S is set). ; ; DESTROYED ; REGISTERS: ; * F ; ;@doc:end ;------------------------------------------------------------------------------- GetChar = GetCharNoHelper ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Keypad.OSKey === ; ; INKEY routine. ; ; INPUTS: ; REGISTERS ; * HL - time limit (centiseconds). If HL = 0 return immediately. ; ; OUTPUTS: ; REGISTERS ; * F - Carry flag set if a key was detected. ; - Carry flag reset and zero set if timed out. ; - Carry flag reset and zero reset on Escape. ; * A - ASCII code of key pressed. ; ;@doc:end ;------------------------------------------------------------------------------- OSKey bit 7,h jr nz,DirectOSKEY di ld (InKeyTimer),hl ei .fcall "Vdu.Text.BeforeCursorDraw" .fcall "Vdu.Text.Cursor.ResetBlink" .fcall "Speed.SlowDown" - .fcall "Keypad.GetCharNoHelper" jr z,InKeyPressed di ld hl,(InKeyTimer) ei ld a,h or l jr nz,+ ; Timed out. push af .fcall "Speed.SpeedUp" pop af xor a ret + .fcall "Vdu.Text.Cursor.PutBlinking" halt jr - InKeyPressed push af .fcall "Speed.SpeedUp" pop af jr nc,+ ; Escape pressed. .fcall "Vdu.Text.AfterCursorDraw" ld a,1 or a ret + jp m,- .fcall "Vdu.Text.AfterCursorDraw" scf ret DirectOSKEY ld a,l neg jr nz,+ ; INKEY(-256) ld a,(OS.Version.Major) add a,$82 scf ret + jp p,+ ; INKEY(-128)..INKEY(-255) xor a ld l,a ret + ld l,a ld h,0 push de ld de,DirectKeyTable-1 add hl,de pop de .fcall "Speed.SlowDown" push bc ld a,$FF out (1),a ld a,(hl) or a jr nz,+ .fcall "Speed.SpeedUp" pop bc xor a scf ret + dec a srl a srl a srl a ld b,a ld a,$FE jr z,+ - sl1 a djnz - + out (1),a nop in a,(1) ld c,a ld a,(hl) dec a and 7 ld b,a ld a,1 jr z,+ - add a,a djnz - + and c pop bc push af .fcall "Speed.SpeedUp" pop af ld l,-1 scf ld a,0 ret nz xor a ret DirectKeyTable /* Shift -1 */ .db sk2nd /* Ctrl -2 */ .db skAlpha /* Alt -3 */ .db skVars /* -4 */ .db 0 /* -5 */ .db 0 /* -6 */ .db 0 /* -7 */ .db 0 /* -8 */ .db 0 /* -9 */ .db 0 /* -10 */ .db 0 /* -11 */ .db 0 /* -12 */ .db 0 /* -13 */ .db 0 /* -14 */ .db 0 /* -15 */ .db 0 /* -16 */ .db 0 /* Q -17 */ .db sk9 /* 3 -18 */ .db sk3 /* 4 -19 */ .db sk4 /* 5 -20 */ .db sk5 /* f4 -21 */ .db skTrace /* 8 -22 */ .db sk8 /* f7 -23 */ .db 0 /* - -24 */ .db skChs /* -25 */ .db 0 /* Left -26 */ .db skLeft /* 6 -27 */ .db sk6 /* 7 -28 */ .db sk7 /* f11 -29 */ .db 0 /* f12 -30 */ .db 0 /* f10 -31 */ .db 0 /* -32 */ .db 0 /* Print -33 */ .db 0 /* W -34 */ .db skSub /* E -35 */ .db skSin /* T -36 */ .db sk4 /* 7 -37 */ .db sk7 /* I -38 */ .db skSquare /* 9 -39 */ .db sk9 /* 0 -40 */ .db sk0 /* -41 */ .db 0 /* Down -42 */ .db skDown /* 8 -43 */ .db sk8 /* 9 -44 */ .db sk9 /* -45 */ .db 0 /* ` -46 */ .db 0 /* -47 */ .db 0 /* Bksp -48 */ .db skClear /* 1 -49 */ .db sk1 /* 2 -50 */ .db sk2 /* D -51 */ .db skRecip /* R -52 */ .db skMul /* 6 -53 */ .db sk6 /* U -54 */ .db sk5 /* O -55 */ .db sk7 /* P -56 */ .db sk8 /* [ -57 */ .db skLParen /* Up -58 */ .db skUp /* + -59 */ .db skadd /* - -60 */ .db skSub /* Enter -61 */ .db skEnter /* Ins -62 */ .db skDel /* Home -63 */ .db skStat /* PgUp -64 */ .db 0 /* Caps -65 */ .db 0 /* A -66 */ .db skMath /* X -67 */ .db skStore /* F -68 */ .db skCos /* Y -69 */ .db sk1 /* J -70 */ .db skComma /* K -71 */ .db skLParen /* -72 */ .db 0 /* -73 */ .db 0 /* Enter -74 */ .db skEnter /* / -75 */ .db skDiv /* -76 */ .db 0 /* . -77 */ .db skDecPnt /* Num -78 */ .db 0 /* PgDn -79 */ .db 0 /* ' -80 */ .db 0 /* -81 */ .db 0 /* S -82 */ .db skLn /* C -83 */ .db skPrgm /* G -84 */ .db skTan /* H -85 */ .db skPower /* N -86 */ .db skLog /* L -87 */ .db skRParen /* ; -88 */ .db 0 /* ] -89 */ .db skRParen /* Del -90 */ .db skDel /* # -91 */ .db 0 /* * -92 */ .db skMul /* -93 */ .db 0 /* = -94 */ .db 0 /* -95 */ .db 0 /* -96 */ .db 0 /* Tab -97 */ .db 0 /* Z -98 */ .db sk2 /* Space -99 */ .db sk0 /* V -100 */ .db sk6 /* B -101 */ .db skMatrix /* M -102 */ .db skDiv /* , -103 */ .db skComma /* . -104 */ .db skDecPnt /* / -105 */ .db skDiv /* End -106 */ .db skGraphvar /* 0 -107 */ .db sk0 /* 1 -108 */ .db sk1 /* 3 -109 */ .db sk3 /* -110 */ .db 0 /* -111 */ .db 0 /* -112 */ .db 0 /* Esc -113 */ .db skMode /* f1 -114 */ .db skYEqu /* f2 -115 */ .db skWindow /* f3 -116 */ .db skZoom /* f5 -117 */ .db skGraph /* f6 -118 */ .db 0 /* f8 -119 */ .db 0 /* f9 -120 */ .db 0 /* \ -121 */ .db skDiv /* Right -122 */ .db skRight /* 4 -123 */ .db sk4 /* 5 -124 */ .db sk5 /* 2 -125 */ .db sk2 /* -126 */ .db 0 /* -127 */ .db 0 /* -128 */ .db 0 KeyMaps ; Without modifiers. .db Keycode.Down,Keycode.Left,Keycode.Right,Keycode.Up,0,0,0,0 .db "\r\"WRMH",Keycode.Escape,0 .db "!@VQLG",0,0 .db ".ZUPKFC",0 .db " YTOJEB",Keycode.Copy .db 0,"XSNIDA",0 .db 0,0,0,0,0,0,0,127 .db 0,0,0,0,0,0,0,0 ; +Alpha. .db Keycode.PageDown,Keycode.Left,Keycode.Right,Keycode.PageUp,0,0,0,0 .db "=+-*/^",Keycode.Escape,0 .db "_369)>",0,0 .db ":258(<%",0 .db "0147,",$60,"&",Keycode.Copy .db 0,"=$%!?@",0 .db 0,0,0,0,0,0,0,127 .db 0,0,0,0,0,0,0,0 ; +2nd. .db 0,Keycode.Home,Keycode.End,0,0,0,0,0 .db "\r\"wrmh",Keycode.Escape,0 .db "?#vqlg",0,0 .db ";zupkfc",0 .db Keycode.CommandList,"ytojeb",Keycode.Copy .db 0,"xsnida",0 .db 0,0,0,0,0,0,Keycode.Escape,127 .db 0,0,0,0,0,0,0,0 ; +2nd+Alpha. .db 0,0,0,0,0,0,0,0 .db "='][\\%",Keycode.Escape,0 .db "~369}>",0,0 .db "|258{<_",0 .db "0147;",$60,"&",Keycode.Copy .db 0,"=$%!?@",0 .db 0,0,0,0,0,0,0,127 .db 0,0,0,0,0,0,0,0 .endmodule