'******************************************************************************
'* 
'* MSX KEYBOARD CONTROLLER (CHIP DEVICE)
'*
'* Supported platform/bus: MSX
'* 
'* Version history:
'*  - 2007,2009 by WadiM (initial emulation)
'*
'****************************************************************************** 

//DEBUG.ON 'uncomment to enable debug messages (can be slow for hi-freq events)

//device interface support
public use object DEVICE

//device name
DeviceName="MSX Keyboard"
DebugName="KEYB"

//Matrix of virtual key states
dim vkey_state(256) as boolean 'pressed/released currently

'-------------------------------- H/W Interface -------------------------------

//Read active keys for selected keyline
public function GetKeyLine(Index as byte) as byte
  Result=0 'key pressed, if bit set
  select case Index
   case 0
    if vkey_state(VK_0) then Result=Result or 0x01 //0
    if vkey_state(VK_1) then Result=Result or 0x02 //1
    if vkey_state(VK_2) then Result=Result or 0x04 //2
    if vkey_state(VK_3) then Result=Result or 0x08 //3
    if vkey_state(VK_4) then Result=Result or 0x10 //4
    if vkey_state(VK_5) then Result=Result or 0x20 //5
    if vkey_state(VK_6) then Result=Result or 0x40 //6
    if vkey_state(VK_7) then Result=Result or 0x80 //7
   case 1
    if vkey_state(VK_8)          then Result=Result or 0x01 //8
    if vkey_state(VK_9)          then Result=Result or 0x02 //9
    if vkey_state(VK_MINUS)      then Result=Result or 0x04 //-
    if vkey_state(VK_PLUS)       then Result=Result or 0x08 //=
    if vkey_state(VK_BACK_SLASH) then Result=Result or 0x10 //\
    if vkey_state(VK_LBRACKET)   then Result=Result or 0x20 //[
    if vkey_state(VK_RBRACKET)   then Result=Result or 0x40 //]
    if vkey_state(VK_COLON)      then Result=Result or 0x80 //;
   case 2
    if vkey_state(VK_QUOTE)      then Result=Result or 0x01 //'
    if vkey_state(VK_BACK_QUOTE) then Result=Result or 0x02 //`
    if vkey_state(VK_COMMA)      then Result=Result or 0x04 //,
    if vkey_state(VK_PERIOD)     then Result=Result or 0x08 //.
    if vkey_state(VK_SLASH)      then Result=Result or 0x10 ///
    //if vkey_state(VK_)         then Result=Result or 0x20 //???
    if vkey_state(VK_A)          then Result=Result or 0x40 //A
    if vkey_state(VK_B)          then Result=Result or 0x80 //B
   case 3
    if vkey_state(VK_C) then Result=Result or 0x01 //C
    if vkey_state(VK_D) then Result=Result or 0x02 //D
    if vkey_state(VK_E) then Result=Result or 0x04 //E
    if vkey_state(VK_F) then Result=Result or 0x08 //F
    if vkey_state(VK_G) then Result=Result or 0x10 //G
    if vkey_state(VK_H) then Result=Result or 0x20 //H
    if vkey_state(VK_I) then Result=Result or 0x40 //I
    if vkey_state(VK_J) then Result=Result or 0x80 //J
   case 4
    if vkey_state(VK_K) then Result=Result or 0x01 //K
    if vkey_state(VK_L) then Result=Result or 0x02 //L
    if vkey_state(VK_M) then Result=Result or 0x04 //M
    if vkey_state(VK_N) then Result=Result or 0x08 //N
    if vkey_state(VK_O) then Result=Result or 0x10 //O
    if vkey_state(VK_P) then Result=Result or 0x20 //P
    if vkey_state(VK_Q) then Result=Result or 0x40 //Q
    if vkey_state(VK_R) then Result=Result or 0x80 //R
   case 5
    if vkey_state(VK_S) then Result=Result or 0x01 //S
    if vkey_state(VK_T) then Result=Result or 0x02 //T
    if vkey_state(VK_U) then Result=Result or 0x04 //U
    if vkey_state(VK_V) then Result=Result or 0x08 //V
    if vkey_state(VK_W) then Result=Result or 0x10 //W
    if vkey_state(VK_X) then Result=Result or 0x20 //X
    if vkey_state(VK_Y) then Result=Result or 0x40 //Y
    if vkey_state(VK_Z) then Result=Result or 0x80 //Z
   case 6
    if vkey_state(VK_LSHIFT) or vkey_state(VK_RSHIFT) then //Shift
       Result=Result or 0x01 : end if
    if vkey_state(VK_LCTRL) or vkey_state(VK_RCTRL) then //Ctrl
       Result=Result or 0x02 : end if
    if vkey_state(VK_LALT)    then Result=Result or 0x04 //Graph
    if vkey_state(VK_CAPITAL) then Result=Result or 0x08 //Cap
    if vkey_state(VK_RALT)    then Result=Result or 0x10 //Code
    if vkey_state(VK_F1)      then Result=Result or 0x20 //F1
    if vkey_state(VK_F2)      then Result=Result or 0x40 //F2
    if vkey_state(VK_F3)      then Result=Result or 0x80 //F3
   case 7
    if vkey_state(VK_F4)     then Result=Result or 0x01 //F4
    if vkey_state(VK_F5)     then Result=Result or 0x02 //F5
    if vkey_state(VK_ESCAPE) then Result=Result or 0x04 //Esc
    if vkey_state(VK_TAB)    then Result=Result or 0x08 //Tab
    if vkey_state(VK_PAUSE)  then Result=Result or 0x10 //Stop
    if vkey_state(VK_BACK)   then Result=Result or 0x20 //Backspace
    if vkey_state(VK_PRNSCR) then Result=Result or 0x40 //Select
    if vkey_state(VK_RETURN) or vkey_state(VK_EXTRETURN) then //Return
       Result=Result or 0x80 : end if
   case 8
    if vkey_state(VK_SPACE)  then Result=Result or 0x01 //Space
    if vkey_state(VK_HOME)   then Result=Result or 0x02 //Home
    if vkey_state(VK_INSERT) then Result=Result or 0x04 //Insert
    if vkey_state(VK_DELETE) then Result=Result or 0x08 //Delete
    if vkey_state(VK_LEFT)   then Result=Result or 0x10 //Left
    if vkey_state(VK_UP)     then Result=Result or 0x20 //Up
    if vkey_state(VK_DOWN)   then Result=Result or 0x40 //Down
    if vkey_state(VK_RIGHT)  then Result=Result or 0x80 //Right
   case 9
    if vkey_state(VK_MULTIPLY) then Result=Result or 0x01 //Num*
    if vkey_state(VK_ADD)      then Result=Result or 0x02 //Num+
    if vkey_state(VK_DIVIDE)   then Result=Result or 0x04 //Num/
    if vkey_state(VK_NUMPAD0)  then Result=Result or 0x08 //Num0
    if vkey_state(VK_NUMPAD1)  then Result=Result or 0x10 //Num1
    if vkey_state(VK_NUMPAD2)  then Result=Result or 0x20 //Num2
    if vkey_state(VK_NUMPAD3)  then Result=Result or 0x40 //Num3
    if vkey_state(VK_NUMPAD4)  then Result=Result or 0x80 //Num4
   case 10
    if vkey_state(VK_NUMPAD5)  then Result=Result or 0x01 //Num5
    if vkey_state(VK_NUMPAD6)  then Result=Result or 0x02 //Num6
    if vkey_state(VK_NUMPAD7)  then Result=Result or 0x04 //Num7
    if vkey_state(VK_NUMPAD8)  then Result=Result or 0x08 //Num8
    if vkey_state(VK_NUMPAD9)  then Result=Result or 0x10 //Num9
    if vkey_state(VK_SUBTRACT) then Result=Result or 0x20 //Num-
    if vkey_state(VK_COMMA)    then Result=Result or 0x40 //Num,
    if vkey_state(VK_DECIMAL)  then Result=Result or 0x80 //Num.
  end select
 ?? DebugPrefix;"<GetKeyLine(";Index;")=";Hex(result,2);"h"
 result=not result 'invert bits
end

//Handle key from emulator
public procedure HandleKey(vkey as byte, pressed as boolean)
 ?? DebugPrefix;">VKey=";Hex(vkey,2);"h (";iif(pressed,"DOWN","UP");")"
 vkey_state(vkey)=pressed
end

       
