Here is a program I use to send key presses to the PC with various switches and encoders. You should be able to get the drift of what needs to happen to get caps, Ctrl, Alt etc.

Code:
'Byte Description
'0 Modifier keys
'1 Reserved
'2 Keycode 1
'3 Keycode 2
'4 Keycode 3
'5 Keycode 4
'6 Keycode 5
'7 Keycode 6

'Bit Key
'0 LEFT CTRL    0x01
'1 LEFT SHIFT   0x02
'2 LEFT ALT     0x04
'3 LEFT GUI
'4 RIGHT CTRL   0x10
'5 RIGHT SHIFT  0x20
'6 RIGHT ALT    0x40
'7 RIGHT GUI

'               USB Key Code
'Key    Mod     make           Action
'                0x00           No Action
' 1     0        0x1E           5 NM
' 2     0        0x1F           10
' 3     0        0x20           20
' 4     0        0x21           40
' 5     0        0x22           80
' 6     0        0x23          160
' 7     0        0x24          320
' 8     0        0x25          640
' F2    0        0x3B          NAV
' F3    0        0x3C          AIRPORTS
' F4    0        0x3D          WAYPOINTS
'CTRL-D 4        0x07           Toggle FLight Director
' G     0        0x0A           TO/GA Switch
' Q     0        0x14          Left NAV
' SHft-Q 2       0x14           ADF
'CTRL-q  4       0z14           VOR1
'CTRL-S  4       0x16           ND Center
'



'*******************************************************************************
    '   Interrupt definition
    '   ====================
        '   USB interrupt used to keep USB connection alive
INCLUDE "DT_INTS-18.bas"    ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas"     ' Include if using PBP interrupts
ASM
INT_LIST  macro    ; IntSource,         Label,  Type, ResetFlag?
        INT_Handler    USB_INT,  _DoUSBService,   ASM,  yes
        ;INT_Handler    RBC_INT,  _Selector,   PBP,  yes
        ;INT_Handler    INT1_INT,  _cent,   PBP,  yes
        ;INT_Handler    INT0_INT,  _CHK_Matrix,   PBP,  yes
    endm
    INT_CREATE               ; Creates the interrupt processor
ENDASM





' ************************************************************
' * main program loop - remember, you must keep the USB      *
' * connection alive with a call to USBService every couple  *
' * of milliseconds or so...                                 *
' ************************************************************
pause 500 
usbinit ' initialise USB...
USBService                                    ' keep connection alive
UIE = $7F
UEIE = $9F
@   INT_ENABLE  USB_INT
;@   INT_ENABLE  RBC_INT
;@   INT_ENABLE   INT1_INT 
;@   INT_ENABLE   INT2_INT
gosub dousbin
gosub dousbout
sel_old = sel
baro = PORTD & %00110000
Baro_old = baro
pta = porta
pta_old = pta
ptb_old = ptb
na1 = portc & %11000000
na1_old = na1
na2 = portd & %00001100
na2_old = na2
'gosub selector
'gosub barometric
'gosub toggle1
'gosub toggle2



goto ProgramStart
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
'                                                                           '
'  Jump to main program                                                     '
'                                                                           '
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
'
'      Sub Routines
'
'
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@



' ************************************************************
' * Send data to USB bus                            *
' ************************************************************
Make:
usbbuffer(0)= ModKey
usbbuffer(1)= 0
usbbuffer(2)= Key
gosub Dousbout
modkey = 0
key = 0                                                             


usbbuffer(0)= 0     'Clear buffer to stom multible key outputs
usbbuffer(1)= 0
usbbuffer(2)= 0

gosub Dousbout
return

ClrBuffer:         ' Clear usb buffer
usbbuffer(0)= 0
usbbuffer(1)= 0
usbbuffer(2)= 0
usbbuffer(3)= 0
usbbuffer(4)= 0
usbbuffer(5)= 0
usbbuffer(6)= 0
usbbuffer(7)= 0

return

' ************************************************************
' * receive data from the USB bus                            *
' ************************************************************
DoUSBIn:
   USBBufferCount = USBBufferSizeRX              ' RX buffer size
   'USBService                                    ' keep connection alive
   USBIn 1, USBBuffer, USBBufferCount, DoUSBIn   ' read data, if available
   return
    
' ************************************************************
' * wait for USB interface to attach                         *
' ************************************************************
DoUSBOut:
   USBBufferCount = USBBufferSizeTX              ' TX buffer size
   'USBService                                    ' keep connection alive
   USBOut 1, USBBuffer, USBBufferCount, DoUSBOut ' if bus available, transmit data
   return

'###############################################################################
Rot_Encoder:


     RotEncDir = New_Bits.3 ^ Old_Bits.2
     if RotEncDir = 1 then

          RotEnc1_val = RotEnc1_val + 1
          if RotEnc1_val > 8 then RotEnc1_val = 8
     ELSE
          RotEnc1_val = RotEnc1_val - 1
    
          if RotEnc1_val < 1 then RotEnc1_val = 1
     ENDIF


select case  RotEnc1_val         ' encoder counts from 1 to 8 and down from 8 to 1
    Case 1
    modkey = 0
    key = $1E
    Case 2
    modkey = 0
    key = $1F
    case 3
    modkey = 0
    key = $20
    case 4
    modkey = 0
    key = $21
    case 5
    modkey = 0
    key = $22
    case 6
    modkey = 0
    key = $23
    case 7
    modkey = 0
    key = $24
    case 8
    modkey = 0
    key = $25

end select
gosub make
Old_Bits = New_Bits

Return

'###############################################################################
   
   DoUSBService:    'Keeps USB alive
    usbservice
@   INT_RETURN

'###############################################################################
Selector:
sel = portb & %11110000

select case sel 

case $D0
modkey = 0
KEY = $10      'M   ND map mode

case $B0 
modkey = 2
KEY = $10      ' Shift M  ND VOR mode

case $70
modkey = 1
KEY = $10      'CTRL M  ND APP mde

end select
gosub make
sel_old = sel
return
'###############################################################################
BaroMetric:
if baro = $10 then
modkey = 0
KEY = $1A       ' W Toggle barimetric pressure to US in
gosub make
endif

if baro = $20 then
modkey = 0
KEY = $19       ' V Toggle barimetric pressure to Euro
gosub make

endif

baro_old = baro
Return
'###############################################################################
'Minimums:
'if mins =  $40 then

'endif

'if mins = $80 then

'endif

'mins_old = mins

'Return
'###############################################################################

Push_Buttons:
 
        if porta.0 = 0 then  'Map NAV  F2
        modkey = 0
        KEY = $3B     'F2   Toggle mapstation display ND
        gosub make
        endif
        
        if porta.1 = 0 then 'Map APPT F3
        modkey = 0
        KEY = $3C     'F3   Toggle Airports ND
        gosub make
        endif  
        
        if porta.2 = 0 then 'Map WPT F4
        modkey = 0
        KEY = $3D     'F4   Toggle waypoints ND
        gosub make 
        endif
        
        if porta.3 = 0 then    ' MTRS
        modkey = 0
        KEY = $18   ' U Altitude metric mode   
        endif
        
        if porta.4 = 0 then    ' Toggle FPV
        modkey = 1
        KEY = $5   ' CRTL B 
        endif 
        pta_old = pta

return
'###############################################################################
Toggle1:
    if na1 = %11000000 then
        modkey = 0
        key = $14
        gosub make
    endif   
    if na1 = %01000000 then
        modkey = 2
        key = $14
        gosub make
    endif   
    if na1 = %10000000  then
        modkey = 1
        key = $14
        gosub make
    endif    
      
na1_old = Na1   

return

Toggle2:
    if na2 = %00001100 then
        modkey = 0
        key = $15
        gosub make
    endif   
    if na2 = %00000100 then
        modkey = 2
        key = $15
        gosub make
    endif   
    if na2 = %00001000  then 
        modkey = 1
        key = $15
        gosub make
    endif    
      
na2_old = Na2   

Return

'******************************************************************************
'        End Sub Routines
'
'*****************************************************************************





ProgramStart: 

 baro = PORTD & %00110000
 if baro != baro_old then gosub barometric        ' Two position selector switch
   
'' mins = PORTD & %11000000
'' if mins != mins_old then gosub Minimums   


New_Bits = PORTB & %00001100   'check to see if any encoder has changes
IF New_Bits != Old_Bits  then gosub rot_encoder    ' if changed process encoder   


   
ptb = portb.1               'Switch on Encoder circle
if ptb != Ptb_old then
   If portb.1 = 0 then

    modkey = 1
    key = $16
    gosub make
    endif
  ptb_old = ptb
endif   
   
sel = Portb & %11110000
if sel_old != sel then gosub selector        ' 4 position selector switch
   
  
  
 pta = porta
 if pta != pta_old then  gosub Push_Buttons     'Push buttons
   
na1 = portc & %11000000
if na1 != na1_old then  gosub Toggle1          'Toggle switches

na2 = portd & %00001100
if na2 != na2_old then gosub Toggle2


  
goto ProgramStart
I had to take out a few lines so I did not exceed the post size limit