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

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

//device interface support
public use object DEVICE

//device name
DeviceName="Spectrum Keyboard"
DebugName="KBC_SPEC"

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

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

//Read ports
public function PORTS(Index as word) as byte
 if (Index and 1)=0 then  //read key states
  Result=0xFF 'key pressed, if bit cleared 
  select case Index
   case 0xFEFE //SHIFT, Z, X, C, V
    if vkey_state(VK_LSHIFT) then Result=Result and (not 0x01) //LSHIFT
    if vkey_state(VK_Z)      then Result=Result and (not 0x02) //Z
    if vkey_state(VK_X)      then Result=Result and (not 0x04) //X
    if vkey_state(VK_C)      then Result=Result and (not 0x08) //C
    if vkey_state(VK_V)      then Result=Result and (not 0x10) //V
    if vkey_state(VK_BACK)   then Result=Result and (not 0x01) //*EASY BACKSPACE
  case 0xFDFE //A, S, D, F, G
    if vkey_state(VK_A)      then Result=Result and (not 0x01) //A
    if vkey_state(VK_S)      then Result=Result and (not 0x02) //S
    if vkey_state(VK_D)      then Result=Result and (not 0x04) //D
    if vkey_state(VK_F)      then Result=Result and (not 0x08) //F
    if vkey_state(VK_G)      then Result=Result and (not 0x10) //G
  case 0xFBFE //Q, W, E, R, T
    if vkey_state(VK_Q)      then Result=Result and (not 0x01) //Q
    if vkey_state(VK_W)      then Result=Result and (not 0x02) //W
    if vkey_state(VK_E)      then Result=Result and (not 0x04) //E
    if vkey_state(VK_R)      then Result=Result and (not 0x08) //R
    if vkey_state(VK_T)      then Result=Result and (not 0x10) //T
  case 0xF7FE //1, 2, 3, 4, 5
    if vkey_state(VK_1)      then Result=Result and (not 0x01) //1
    if vkey_state(VK_2)      then Result=Result and (not 0x02) //2
    if vkey_state(VK_3)      then Result=Result and (not 0x04) //3
    if vkey_state(VK_4)      then Result=Result and (not 0x08) //4
    if vkey_state(VK_5)      then Result=Result and (not 0x10) //5
  case 0xEFFE //0, 9, 8, 7, 6
    if vkey_state(VK_0)      then Result=Result and (not 0x01) //0
    if vkey_state(VK_9)      then Result=Result and (not 0x02) //9
    if vkey_state(VK_8)      then Result=Result and (not 0x04) //8
    if vkey_state(VK_7)      then Result=Result and (not 0x08) //7
    if vkey_state(VK_6)      then Result=Result and (not 0x10) //6
    if vkey_state(VK_BACK)   then Result=Result and (not 0x01) //*EASY BACKSPACE
  case 0xDFFE //P, O, I, U, Y
    if vkey_state(VK_P)      then Result=Result and (not 0x01) //P
    if vkey_state(VK_O)      then Result=Result and (not 0x02) //O
    if vkey_state(VK_I)      then Result=Result and (not 0x04) //I
    if vkey_state(VK_U)      then Result=Result and (not 0x08) //U
    if vkey_state(VK_Y)      then Result=Result and (not 0x10) //Y
  case 0xBFFE //ENTER, L, K, J, H
    if vkey_state(VK_RETURN) then Result=Result and (not 0x01) //ENTER
    if vkey_state(VK_L)      then Result=Result and (not 0x02) //L
    if vkey_state(VK_K)      then Result=Result and (not 0x04) //K
    if vkey_state(VK_J)      then Result=Result and (not 0x08) //J
    if vkey_state(VK_H)      then Result=Result and (not 0x10) //H
  case 0x7FFE //SPACE, SYM SHFT, M, N, B
    if vkey_state(VK_SPACE)  then Result=Result and (not 0x01) //SPACE
    if vkey_state(VK_RSHIFT) then Result=Result and (not 0x02) //RSHIFT
    if vkey_state(VK_M)      then Result=Result and (not 0x04) //M
    if vkey_state(VK_N)      then Result=Result and (not 0x08) //N
    if vkey_state(VK_B)      then Result=Result and (not 0x10) //B
  end select
 else : result=0 : end if
 ?? DebugPrefix;"<Port[";Hex(Index,4);"h]=";Hex(result,2);"h"
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

       
