; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; ; This PIC code implements a matchbox-size universal GKOS keyboard ; ; for a variety of devices, using several IR formats. All PC qwerty ; ; functions are available. The key codes are sent e.g. using the ; ; IrDA infrared frame structure at 9600bit/s. The same keycodes are ; ; also sent through the PIC UART port. A simple driver can receive ; ; these codes and convert them directly to corresponding key-up and ; ; key-down codes understood by the device (PDA, PC or alike). Other ; ; infrared formats available are Sony SIRCS IR code for MiniDisc ; ; remote control with a possibility to enter song titles, GKOS key ; ; code IR packets and the old GKOS chord packets for compatibility ; ; with previous GKOS projects (PS/2 mouse/keyboard PC interface). ; ; There is also a TV remote control operation as an example (ASA). ; ; ; ; As most of the latest GKOS PIC software, this implements also the ; ; intelligent key scan mechanism to allow for entering of chordons ; ; i.e. chord chains (chord on chord without release of common keys).; ; Ordinary way of GKOS typing is also possible (press keys for one ; ; character and release all keys before the next character) allowing; ; some overlap of successive chords. Shortcuts to whole words ; ; have also been included (There are many of them!). ; ; ; ; Reception of GKOS IR Mouse data is included but a physical mouse ; ; can not yet be connected. The GKOS keyboard can, however, be used ; ; as a pointer control (Press SHIFT/123-abc to enter that mode). ; ; ; ; IMPORTANT NOTE: ; ; This sofware can also receive same types of *GKOS* IR data ; ; it can transmit! Just add the TSOP... IR receiver in parallel ; ; with the keyboard (different pins of course). Use UART output ; ; to read the received Keycodes and Mouse data. ; ; ; ; ; ; This software implements a GKOS IR keyboard for PDA, MD, PC etc. ; ; ; ; "The Universal GKOS IR Keyboard" ; ; ; ; Assembly code generation on the PICmicro PIC16F876 with 4 MHz clock.; ; More at gkos.net ; ; ; ; ; ; This source code can be used according to ; ; the GNU GENERAL PUBLIC LICENSE Version 2, June 1991 ; ; ; ; Seppo Tiainen, Veikkola, Finland ; ; - Visit gkos.com for specs etc and gkos.net for building projects - ; ; ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * ; Filename: gpda100.asm * ; Date: 7 Nov 2005 * ; File Version: 1.00 * ; * ; Author: Seppo Tiainen, Veikkola, Finland * ; Website: gkos.net (building), gkos.com (specification) * ; Email: g k o s @ g k o s . c o m * ; * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; ; Version history: ; ; gpda100.asm First version with all functions (= gpda0999.asm), some shortcuts missing ; - This convention is used from this version on, for example: ; - IR receiver: gpda100i.asm; MD IR transm gpda100m.asm and Chord IR transm gpda100c.asm ; - meaning same version but different default parameter settings (=> gpda100m.hex etc. also) ; - i = IrDA, m = MD, c = Chord, g = GKOS Keycodes (referring to IR output) ; - Known bug: Extra characters appear at UART in IrDA mode. Do not use. Use g instead. ; - See line 740 below for default parameter settings (bsf/bcf) for different usage ; ; gpda0999.asm signal (all keys up) added in UART out ; gpda0998.asm Possibility to disable SLEEP function (param. SleepMode) ; gpda0997.asm Bug fix of n+1 error with last alphabet in shortcuts ; gpda0996.asm: ; - 'Keyboard as Mouse' function added (Kbd or IR input, UART output); ; - More reliable IR Mouse Data Packet reception (CheckIRend added) for ; receiving IR from GKOS kbd with TrackPoint or Stick pointer control. ; gpda0995.asm Reception of GKOS mouse IR packets and mouse UART output ; gpda0994.asm Chordon Shortcut functions expanded. 58 shortcuts now. ; gpda0993.asm IR reception of GKOS Key Code packets added ; gpda0992.asm MD Bug fixes (space after shortcut, apostrophe) ; gpda0991.asm National character optimized layout. Some Chordon shortcuts. ; gpda099.asm Chordon shortcut tables expanded. 40 kHz for MD IR. ; gpda098.asm Changing operating modes by [SYMB][Ctrl]m[ENTER] etc. ; gpda097.asm Chordon shortcut example added ('i => international) ; gpda096.asm TV remote commands; Lower/Upper case + Backspace for MD ; gpda095.asm IrDA frame format and GKOS key code transmission ; gpda09.asm SIRCS timing adjustments ; gpda08.asm SIRCS MD remote control working ; gpda07.asm UART key code transmission ok ; gpda06.asm development ; ... ; gpda03.asm character table updates ; gpda02.asm development ; gpda01.asm first version to test PDA IR code transmission ; glcd18.asm Used for the most part (GKOS LCD communicator) ; ;---------------------------------------------------------------------| ; | ; If interrupts are not used all code presented between the ORG | ; 0x004 directive and the label main can be removed. In addition | ; the variable assignments for 'w_temp' and 'status_temp' can | ; be removed. | ; | ; Refer to the MPASM User's Guide for additional information on | ; features of the assembler (Document DS33014). | ; | ; Refer to the respective PICmicro data sheet for additional | ; information on the instruction set. | ; | ;---------------------------------------------------------------------| ; | ; Files required: p16f876.inc | ; | ;---------------------------------------------------------------------| list p=16f876 ; list directive to define processor #include ; processor specific variable definitions __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _XT_OSC & _WRT_ENABLE_ON & _LVP_OFF & _CPD_OFF ; '__CONFIG' directive is used to embed configuration data within .asm file. ; The lables following the directive are located in the respective .inc file. ; See respective data sheet for additional information on configuration word. ; ; turn off crossing page boundary messages while running the assembler: ; ERRORLEVEL -306, -302 ; ; base frequency XTAL_FREQ EQU 4000000 ; OSC freq in Hz ; caulculates baudrate when BRGH = 1, adjust for rounding errors #define CALC_HIGH_BAUD(BaudRate) (((10*XTAL_FREQ/(16*BaudRate))+5)/10)-1 ; caulculates baudrate when BRGH = 0, adjust for rounding errors #define CALC_LOW_BAUD(BaudRate) (((10*XTAL_FREQ/(64*BaudRate))+5)/10)-1 ; ;============= GKOS INFORMATION ================= ; ; http://gkos.com (specifications) ; http://gkos.net (build project) ; ;--------Infrared control data format: ; ;This procedure is repeated continuously by the remote IR data transmitter: ; scan keys first time > wait 5ms > If needed send Mouse report > wait 5ms > ; scan keys second time > send Chord value packet > repeat ; ;IR DATA PACKET FORMATS: ; ;-Format of Chord value packet: ;[start] D0 D1 D2 D3 D4 D5 - 6 bits - ; G 1 A0 A1 A2 - 5 bits - G=toggle, 1=keyboard ; ;-Format of Mouse data packets: ;[start] D0 D1 D2 D3 D4 D5 - 6 bits - ; G 0 A0 A1 A2 A3 Z(=0) - 7 bits - G=toggle, 0=mouse, Z=0: pointer data ; X0 X1 X2 X3 X4 X5 X6 X7 - 8 bits - (pointer movement data) ; Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7 - 8 bits - ; or: ;[start] D0 D1 D2 D3 D4 D5 - 6 bits - ; G 0 A0 A1 A2 A3 Z(=1) - 7 bits - G=toggle, 0=mouse, Z=1: wheel data ; Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7 - 8 bits - (scroll wheel data) ;------------------------------------------- ; ;=================== VARIABLES: ============================== ;PIC 16F876 General Purpose Register locations are 0x20...0x7F (Bank 1) TempB0 EQU 0x20 ; Used to store bit locations in chord polling TempB1 EQU 0x21 TempB2 EQU 0x22 TEMP0 EQU 0x23 ; These TEMP1 to TEMP3 are used in the key polling TEMP1 EQU 0x24 ; timer checks (see KeyTime) TEMP2 EQU 0x25 ;*** GKOS specific definitions chord EQU 0x26 ; Chord at the reading moment maxchord EQU 0x27 ; Max pressed combination before all keys released finalchord EQU 0x28 ; Final key combination GKOSstatus EQU 0x29 ; GKOS keyboard status bits ; bit0=1: chord received ; bit1=1 typematic on ; bit2=1 activity on GKOS noticed ; bit3=IR toggle bit (expected) ; bit4= RXchordREADY, IR Chord is ready for output to PS/2 ; bit7-bit5: ; bit7=1 IR operation (IR receiver connected) NOT USED ; bit6=1 IR packet received correctly ; bit5=1 'Kbd as Mouse' operation / bit5=0 Keyboard operation GKOSref EQU 0x2A ; GKOS character ref.number based on finalchord ; (the specified GKOS ref.num) GKOSrefshift EQU 0x2B ; 0, 63 or 126 (abc, 123 or SYMB tables) + GKOSref GKOSmode EQU 0x2C ; bit0: abc-123 1=123, 0=abc ; bit2/bit1: SYMB, 10=SYMBon, 11=SYMBlock ; bit4/bit3: SHIFT, 10=SHIFTon, 11=SHIFTlock (CAPS LOCK) ; bit5: CTRL, 1=CTRLon ; bit6: ALT, 1=ALTon ; bit7: Paste on. (Still missing: NUMLOCK) keycode EQU 0x2D ; Based on GKOSref, this points to the ; proper scan code in table TempShift1 EQU 0x2E ; Temporary shift register ;**** Delay dcount1 EQU 0x2F ; Used in Delay subroutines dcount2 EQU 0x30 dcount3 EQU 0x31 dcount4 EQU 0x32 ;**** PS/2 data/clock line communications COUNTER EQU 0x33 ; bit counter for PS/2 comms PARITY EQU 0x34 ; parity for PS/2 comms RECEIVE EQU 0x35 ; PS/2 keyboard receiving buffer Offset EQU 0x36 ; Table offset (scan codes etc.) MRECEIVE EQU 0x37 ; PS/2 mouse receiving buffer ;********* ;LoopCounter EQU 0x38 ; Temporary counter in loops ZeroChords EQU 0x38 ; Zero Chord counter for wired GKOS keyboard polling routine temp_a EQU 0x39 ; Temporary IR reception delay counters temp_b EQU 0x3A temp_c EQU 0x3B ; Mouse bytes to be sent to Host (PC PS/2 lines): ; bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 ;MOUSE_BUTTONS EQU 0x3C ; Yovf Xovf Ysign Xsign '1' MidButt RButton LButton ;MOUSE_X EQU 0x3D ; X7... X0 ;MOUSE_Y EQU 0x3E ; Y7... Y0 ;MOUSE_Z EQU 0x3F ; '0' '0' 5thButton 4thButton Z3... Z0 ; - Z3...Z0 Scroll Wheel data zzzz, values: -8...+7 ;---more PS/2 kbd communications TEMPY EQU 0x3f ; a very local variable, LCD and IR TX TEMPX EQU 0x40 ; A local variable used in IR TX&RX and LCD output ;TXstatus EQU 0x41 ; spare (bit0=1 => Return from ByteOut without sending.) ; spare (bit1=1 <= There was Reception during ByteOut) SelectTable EQU 0x42 ; Select Chordon shortcut table based on flag bits Tmp2 EQU 0x43 ; Very temporary variable (for key up/down counter) Temp EQU 0x44 ; Very temporary variable (UART tx bits; Save at table calls) tempflags EQU 0x45 ; FLAGS: bit0=IR bit correctly received ; bit1=1 a Zero Chord must be sent when possible. ; bit2=1 if character comes from IR link; 0 for own keyboard ; - this is used to show the character on correct LCD line ; bit3 follows the value of bit2 to notice the change ; bit4 SpecialKey, For IR transmissions, indicates that ; Shifts are sent and no sub call is made to check Shifts ; bit5 Command Flag, [SYMB][Ctrl] has been pressed. ; bit6 has been sent for wired kbd ; bit7 has been sent for IR chord reception ;---PS2 flags---- PS2flags EQU 0x46 ; IRTXline: IR TX ouput line state, 1/0 to decide if 0 or 1 will follow ; bit1=1 (Mouse enable (M_ENABLE) received from Host) ; bit2=1 SleepMode, go to sleep after 5 min of inactiv. (was: LCD busy) ; bit3=1 US version of keyboard ; bit4=1 LCD 8-bit mode on ; bit7=1 MoreChords (in buffer RXfinalchord2) to be sent via PS2 GKOSref2 EQU 0x47 ; GKOS Ref for Chordon shortcut second character Tmp3 EQU 0x48 ; temp chord in check-back GKOScounter1 EQU 0x49 ; Counter for JustScanned indication, Wired GKOS kbd GKOScounter2 EQU 0x4A ; Counter for JustScanned indication, Wired GKOS kbd IRCounter EQU 0x4B ; Count repeats of IR SIRCS frames (for each byte to send) SCpointer EQU 0x4C ; Chordon Shortcut pointer ;---------- ;spare room ;--------- ;---IR parameters--- IR_mode EQU 0x4F ; bit0=1 => GKOS_IR_mode (just send keyboard status) ; bit1=1 => Byte_IR_mode (one byte per character) ; bit2=1 => IrDA_mode ; bit3=1 => SIRCS_MD_mode ; bit4=1 => SIRCS_MD_EDIT ; bit5=1 => GKOS_byte_mode ; bit6=1 => TV1_mode ; bit7=1 IRmaxchord EQU 0x50 RXfinalchord EQU 0x51 IRflags EQU 0x52 ;bit0=1 SIRCS20 IR frame is 20-bit ;bit1=1 LCD edge passed ;bit2=1 RXchordREADY ready to send character to host ;bit3=1 NoOutput (key polling) even if a key is released ;bit4=1 NewChar (key polling), output if key is released ;bit5=1 CheckBackOn ;bit6=1 TextOnly allowed, chord is within a chordon ;bit7=1 LCD_busycheck=1 => Busy flag can be tested RXchord EQU 0x53 ; Chord received from wired keyboard or IR link KeyTime0 EQU 0x54 ; Counter for Key down period (255 > 0) KeyTime1 EQU 0x55 ; Counter for Key down period (255 > 0) KeyTime2 EQU 0x56 ; Counter for Key down period (255 > 0) KeyTime3 EQU 0x57 ; Counter for Key down period (255 > 0) KeyTime4 EQU 0x58 ; Counter for Key down period (255 > 0) KeyTime5 EQU 0x59 ; Counter for Key down period (255 > 0) RXfinalchord2 EQU 0x5A ; Chord that was left in buffer because two chords must be output ; due to checking back in the key polling procedure ; PrevChord1 EQU 0x5B ; Previous chord for key polling procedure PrevChord2 EQU 0x5C ; 'Previous to previous' chord for key polling procedure ToggleCounter EQU 0x5D ; IR reception Toggle timer (polling, autorepeat) Downs EQU 0x5E ; Chord value to be output (keys down, polling) ;---Scancode parameters ;scancode EQU 0x5F ; temp place to store scancode AKUflags EQU 0x5F ; Bit 0: Latest received IR chord is Zero chord ; Bit 1: Latest received wired chord is Zero chord ; Bit 3: spare sc_buffer0 EQU 0x60 ; Buffer for the 2-character chordon shorcut sc_buffer1 EQU 0x61 ; Buffer for the 2-character chordon shorcut ;sc_buffer2 EQU 0x62 ;----------- ;--- more IR parameters IRdevice EQU 0x63 ; IR Device code in IR RX (xxxa aadg = xxx1 11xx) a:210 ;IRinfopart EQU 0x64 ; Received information part of the IR packet: ; x x x D6 D7 A0 A1 A2 (instead: use the IRByte2 received) ; The received IR data bytes: ; --------------------------- IRByte1 EQU 0x65 ; - chord value or mouse button etc data (extra bits A3 Z follow) ; Chord: - - D5 D4 D3 D2 D1 D0 ; Mouse: - - Yovf Xovf Ysign Xsign RButton LButton IRByte2 EQU 0x66 ; Device (A2-A0), mouse/chord bit d, toggle bit G (xxxa aadg) ; Chord: xxxa aa1g: - - - A2 A1 A0 '1' TOGGLE ; Mouse: xxxa aa0g: - - - A2 A1 A0 '0' MTOGGLE ; (Two bits A3 0/1 are sent here inbetween but not stored) IRByte3 EQU 0x67 ; X movement (X7...X0) or wheel data (0 0 0 0 Z3...Z0) IRByte4 EQU 0x68 ; Y movement data (Y7...Y0) ; Bytes to send to the PS/2 interface (Send Bit0 first) ; ----------------------------------- MouseByte1 EQU 0x69 ; Yovl Xovl Ysign Xsign '1' MButton RButton LButton (pointer) ;MouseByte2 EQU 0x6A ; Similar to IRByte3 (X7...X0) ;MouseByte3 EQU 0x6B ; Similar to IRByte4 (Y7...Y0) MouseByte4 EQU 0x6C ; '0' '0' 5thButton 4thButton Z3 Z2 Z1 Z0 (Scroll wheel data) KMouseByte1 EQU 0x6D ; Yovl Xovl Ysign Xsign '1' MButton RButton LButton, for kbd as Mouse WaitCounter EQU 0x6E ; counter for key polling, no not accept new key releases IRcode EQU 0x6F ; IR code info part to send by the remote control ;==== ;spare room ;==== ;Locations 0x71...0x7F (source: 16F876A template) w_temp EQU 0x71 ; variable used for context saving status_temp EQU 0x72 ; variable used for context saving pclath_temp EQU 0x73 ; variable used for context saving ; temp01 EQU 0x74 ; IR Transmission varable bitcounter EQU 0x75 ; IR Transmission varable CommandBuffer0 EQU 0x76 ; IR mode selection command buffer 0 (> 0 > 1 >) CommandBuffer1 EQU 0x77 ; IR mode selection command buffer 1 SLEEPcnt1 EQU 0x78 ;counter to goto sleep when no key activity SLEEPcnt2 EQU 0x79 ;counter to goto sleep when no key activity SLEEPcnt3 EQU 0x7a ;counter to goto sleep when no key activity ;==== ;spare room ;==== ; ;(max 0x7F) ; ; ------------------ Program memory pages: ------------------------------ ; Page 0: 0h - 7FFh 2k PCLATH need not be used for CALL and GOTO ; Page 1: 800h - FFFh 4k PCLATH<3> must be used (set PCLATH<3>) ; Page 2: 1000h - 17FFh 6k PCLATH<4,3> must be used (set PCLATH<4>) ; Page 3: 1800h - 1FFFh 8k -"- (set PCLATH<4,3>) ; See Chapter 6.2.6 of 33023a.pdf for more. ;------------------------------------------------------------------------ ; ;=================== DEFINITIONS: ;Note that PS/2 Data and Clock lines are brought to 0 (low) state by changing their ;appropriate I/O pins to output state. Original values must be 0 at those pins. ;Pull up resistors (4k7) are required if testing without connecting to a PC keyb socket. #define SLEEPdelay d'100' ;d'3' ; 1 => 3 sec (nx3s) Idle Time before going to sleep ; 5 min = 300 sec = 100 x 3s => SLEEPdelay = 100 ; For tests: 9 sec => SLEEPdelay = 3 ; LCD Data lines D7 D6 D5 D4 = PORTA, 2-5 (PORTA,0-1 are for mouse Yin Xin) #define SYNCH PORTC,1 ; Testpoint: Synchronisation for oscilloscope #define LCD_RS PORTC,2 ; LCD Register Select #define LCD_RW PORTC,3 ; LCD R/W #define LCD_E PORTC,4 ; LCD Enable #define SleepMode PS2flags,2 ; If set, goto to sleep after 5 min of inactivity ;#define LCD_busy PS2flags,2 ; LCD busy flag #define LCD_busycheck PS2flags,7 ; LCD busy flag can be checked #define TESTPOINT PORTC,7 ;4 ;=4>7 Test point (pin) for IR reception timing #define IRTXDATA PORTC,0 ; IR TX data output port pin ;#define MDEVICE b'00000111' ;A2-A0 = 111 (not used yet in this version) ; ---00aaa(- - - Z A3 A2 A1 A0) Z A3 = 00 (pointer data) ; IR TX device is defined here: #define DEVICE b'00011110' ;A2-A0 = 111, dg = 1 G ; xxxaaadg gdaaa gdaaa- ; b'00011110' => scope: 01111, ...011110 (=MD) gdaaa0 ; #define SDEVICE b'00001111' ; SIRCS MD address is 11110 (reverse order in SDEVICE) #define IRDATA PORTB,6 ; IR Data input. Low when IR pulse. Internal pull-up used. #define AutoRepeat GKOSstatus,1 ; autorepeat indication #define GKOS_IR_mode IR_mode,0 ; GKOS IR mode (chords = mode c) #define Byte_IR_mode IR_mode,1 ; Byte IR mode (one byte per character) #define IrDA_mode IR_mode,2 ; - IrDA frame mode (of Byte IR mode = mode i) #define SIRCS_MD_mode IR_mode,3 ; - SIRCS MD mode (of Byte IR mode = mode m) #define SIRCS_MD_EDIT IR_mode,4 ; - - SIRCS MD EDIT mode (20-bit codes), see also SIRCS20 #define GKOS_byte_mode IR_mode,5 ; - GKOS byte mode (of Byte IR mode = mode g), 8 data + 3 address bits #define TV1_mode IR_mode,6 ; - TV1 remote command mode (of Byte IR mode = mode t) #define SIRCS20 IRflags,0 ; SIRCS format is 20-bit (symbols), not 12-bit ;#define LCD_edge IRflags,1 ; LCD display edge has been passed, shift needed #define AV_mode IRflags,2 ; Remote command mode (any). Use codes 129...255 (IR) #define NoOutput IRflags,3 ; no character output even if a key is released (IR) #define NewChar IRflags,4 ; new character output if any key released (IR) #define CheckBackOn IRflags,5 ; Check-back is enabled. #define TextOnly IRflags,6 ; Chord is within a chordon. Text only allowed, or space. #define RXchordREADY GKOSstatus,4 ; bit4=1 IR Chord ready for output to PS/2 #define ZeroChordMissing tempflags,1 ; A zero chord must be sent as soon as possible ;#define RecChar tempflags,2 ; RecChar=1 if the character is received via IR link ; -show on LCD top line then ;#define RecCharPrev tempflags,3 ; Follows the value of RecChar to notice the change ; Next timing periods are N x 30 ms: #define SpecialKey tempflags,4 ; Do not make a sub call to check Shift status #define CommandFlag tempflags,5 ; [SYMB] [Ctrl], or just [Ctrl] in remote control mode, have ; been pressed. Wait for [Enter] to find out the command. #define AKUSent_WR tempflags,6 ; has been sent for wired kbd #define AKUSent_IR tempflags,7 ; has been sent for IR chords received #define ZeroChordIR AKUflags,0 ; Latest received IR chord is Zero chord #define ZeroChordWR AKUflags,1 ; Latest received wired chord is Zero chord #define TDelay d'30' ; (d'25') Autorepeat delay (cleverer polling) #define MTDelay d'7' ; (d'8') Mouse Autorepeat delay #define WaitPeriods d'5' ; (d'5'ok) WaitCounter value after key release (key polling) ; only valid in case of no check-back in use #define GKOSdelay d'25' ; Delay before re-scanning the wired GKOS #define IRrepeats d'2' ; Repeat every SICRS etc. frame N times #define IRTXline PS2flags,0 ; IR TX ouput line state, 1/0 to decide if 0 or 1 will follow ;#define M_ENABLE PS2flags,1 ; spare (Mouse ENABLE received from Host) #define US_version PS2flags,3 ; US version of keyboard in use #define Eight_bit_mode PS2flags,4 ; LCD 8-bit mode ON. ; ... #define MoreChords PS2flags,7 ; There is a chord in buffer RXfinalchord2 to be sent via PS2 #define KBDasMOUSE GKOSstatus,5 ; Mouse operation through GKOS keys is ON #define MODE123on GKOSmode,0 #define SYMBlock GKOSmode,1 #define SYMBon GKOSmode,2 #define SHIFTlock GKOSmode,3 #define SHIFTon GKOSmode,4 #define CTRLon GKOSmode,5 #define ALTon GKOSmode,6 #define PASTEon GKOSmode,7 ;********************************************************************** ORG 0x000 ; processor reset vector nop ; nop required for icd goto main ; go to beginning of program ;***** INTERRUPT ROUTINE: ********************************************* ORG 0x004 ; interrupt vector location movwf w_temp ; save off current W register contents movf STATUS,w ; move status register into W register movwf status_temp ; save off contents of STATUS register movf PCLATH,w ; move pclath register into w register movwf pclath_temp ; save off contents of PCLATH register ; isr code can go here or be located as a call subroutine elsewhere movf pclath_temp,w ; retrieve copy of PCLATH register movwf PCLATH ; restore pre-isr PCLATH register contents movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt ;================== Macros ======================================= Delay macro Time ;Delay instruction cycles if (Time==1) nop exitm endif if (Time==2) goto $ + 1 exitm endif if (Time==3) nop goto $ + 1 exitm endif if (Time==4) goto $ + 1 goto $ + 1 exitm endif if (Time==5) goto $ + 1 goto $ + 1 nop exitm endif if (Time==6) goto $ + 1 goto $ + 1 goto $ + 1 exitm endif if (Time==7) goto $ + 1 goto $ + 1 goto $ + 1 nop exitm endif if (Time%4==0) movlw (Time-4)/4 call Delay_Routine exitm endif if (Time%4==1) movlw (Time-5)/4 call Delay_Routine nop exitm endif if (Time%4==2) movlw (Time-6)/4 call Delay_Routine goto $ + 1 exitm endif if (Time%4==3) movlw (Time-7)/4 call Delay_Routine goto $ + 1 nop exitm endif endm ;===================== ....more macros... ;======================= ...end of macros =========================== ;********************** MAIN ***************************************** ; Memory blocks ; Reset vector 0000h (RAM) ; Interrupt vector 0004h (RAM) ; ; Program memory Pages (PROM): ; P0 0005h-07FFh Program... ; P1 0800h-0FFFh Enhanced key polling precedures. LCD encoding. More Program Code ; P2 1000h-17FFh (spare) ; P3 1800h-1FFFh Character and Scancode Tables ; ; ;*********************************************************************; ;__________________________ P0 0005h-07FFh Program..._________________; main ;===================== INITIALIZE PARAMETERS ========================= clrf PORTB ; clear port B ; Set Bank 1 registers ; -------------------- ; bsf STATUS,RP0 ; change to register bank 1 bcf STATUS,RP1 bcf OPTION_REG,7 ; ...for bank 1 OPTION_REG: clear bit 7 for pull-ups ; on port B (GKOS keys + IR input line) ; UART Bank 1 settings are here. ; for UART, the TRISC:6 and TRISC:7 must be set ; (as for output, but operates as input/output) bsf TRISC,6 bsf TRISC,7 ; Port C ; ------ movlw b'10100000' ; binary value, 1 bit per port bit movwf TRISC ; RC0 IR TX, (RC1 was LCD_power) ; RC1 SYNCH for oscilloscope tests ; RC2 LCD_RS (reg.sel.) RC3 LCD_RW ; RC4 LCD_enable (was: TEST POINT OUTPUT for IR timing) ; RC5 UART RXdata input ; RC6 UART TXdata ouput ; RC7 spare input ; Port B - GKOS keys ; ------ movlw b'01111111' ; binary value, 1 bit per port bit movwf TRISB ; RB0-RB6 set to digital inputs, GKOS keys + IR data in ; (RB7 is PORTB output, not used) ; RB0-RB5 Keyboard ; RB6 IR data input ; Port A - LCD data bus (+ mouse spare pins) ; ------ movlw b'11111111' ; binary value, 1 bit per port bit movwf TRISA ; RA0,1,6,7 set to inputs (2 spare pins, R0,1) ; RA2-5 outputs for LCD 4-bit data bus ;Any other settings for Bank 1 registers? ; Return to Bank 0 ; ---------------- bcf STATUS,RP0 ; change to register bank 0 call INIT_UART ;*** UART Transmission - write to reg. 19h TXREG movlw b'00111100' movwf PORTA ; ALL LEDS OFF/output to high state (CAPS, 123, SYMB, spare) ;clrf TXstatus ; Clear flags and parameter values clrf RECEIVE clrf chord clrf RXchord clrf RXfinalchord2 clrf PrevChord1 clrf PrevChord2 clrf Downs clrf WaitCounter clrf ZeroChords clrf maxchord clrf IRmaxchord clrf finalchord clrf RXfinalchord clrf GKOSstatus clrf GKOSref clrf GKOSrefshift clrf GKOSmode clrf PS2flags clrf IRflags clrf AKUflags clrf tempflags clrf MouseByte1 ; not used clrf KMouseByte1 clrf IR_mode movlw IRrepeats ; Repeat every IR frame (SIRCS etc.) N times (3) movwf IRCounter ; (update the value here too) bcf LCD_E clrf CommandBuffer0 ; Clear IR mode command buffers clrf CommandBuffer1 ; ... ;clrf CommandBuffer2 ; ... ;bsf LCD_power ; Turn on LCD and IR receiver power movlw TDelay ; Initialize autorepeat down counter. movwf ToggleCounter ; Use the kbd delay value. ;IR data formats. SIRCS spec: 01111 = MD ;MD 0001000 11110 / GKOS: 000100 01111(0) = cccccc gdaaa(0) ) ; PCLATH-- -PCLATL-- ; H HHHH LLLL LLLL ; 12 1098 7654 3210 movlw HIGH TestUART ; Get high 5 bits of address movwf PCLATH ; Load high address in latch call TestUART ; send text: GKOS to UART (pin RC6) movlw HIGH MainLoop ; Make sure PCLATH is pointing to this Page (0) movwf PCLATH ;movlw d'50' ;call DelayWx10ms ;================== SETTING DEFAULTS FOR MODES AND KEYBOARD LAYOUT ===================== ; ;---- Select here whether US or FIN/SWE keyboard layout is used --- ; ============================= ; US version has word shortcuts instead of the Scandinavian letters of the FIN/SWE layout. ; This sets the default national keyboard layout (US/UK or FIN/SWE) only. ; The layout can always be changed by typing [ALT] [123-ABC] ('Alternative mode') ; bsf US_version ; This selects US keyboard as default layout and ; must be a commented line for FIN/SWE kbd layout. ; Use [Alt] [123-ABC] to switch between modes ;-------------------------------------------------------------------------------- bsf CheckBackOn ; Enable check-back of missed chords (recommended) ; - comment the line to disable ;--------------------------------------------------------------------------------- ;---- Select here the default IR mode(s), bsf=yes, bcf=no ; =================================================== ; **To send IR data, select**: bcf GKOS_IR_mode ; GKOS IR mode = send CHORD VALUES continuously, ; (final key code on UART as well) ; This mode is compatible with the PS/2 GKOS IR ; interface for the PC. ; **or**: ; { bsf Byte_IR_mode ; Byte IR mode = send a one-byte KEY CODE per character = ; Enable IR transm. of key codes in general ; **and one of these**: bsf GKOS_byte_mode ; - GKOS Byte Mode, send IR using 11 SIRCS-coded bits: ; 8 data + 3 address (000) bits bcf IrDA_mode ; - IrDA frame mode (of Byte IR mode) to send key codes ; e.g. to a PDA IrDA receiver (driver needed on PDA) bcf SIRCS_MD_mode ; - SIRCS MD mode (of Byte IR mode) to remote control ; a MiniDisc player/recorder bcf SIRCS_MD_EDIT ; - - SIRCS MD EDIT state (20-bit codes), see also SIRCS20 ; (Select bcf always! Will be turned on automatically.) bcf TV1_mode ; - TV1 remote control mode (ASA) ; } ;------------------------------------------------------------------------------------ ; Do not change these: ; AV_mode = 0 is the normal text entry mode of GKOS, character codes 1...127 bcf AV_mode ; Default btfsc SIRCS_MD_mode ; Set AV_mode = 1 for all Remote Control modes bsf AV_mode ; Characters 129...255 will be used as default btfsc TV1_mode ; at UART. When MD text entry mode is used, AV_mode bsf AV_mode ; is cleared for that action elswhere. ;----------------------------------------------------------------------------------------- ; SELECT SLEEP MODE ***** bcf SleepMode ; bcf when used as an IR receiver, bsf when as a keyboard ;----------------------------------------------------------------------------------------- ;========================================================================================= ; ;--------- ; Details of modes: ; ; IR Packets D0 D1 D2 D3 D4 D5 G 1 A0 A1 A2 - ; =================================================== ; GKOS chord x x x x x x X 1 1 1 1 <= Chord value sent continuously ; (6 + 5 = 11 SIRCS-coded bits) ; SIRCS MD x x x x x x x 1 1 1 1 0 <= Sony MD remote commands ; (7 + 5 = 12 SIRCS-coded bits) ; GKOS keycode x x x x x x x x 0 0 0 <= GKOS final key code (0-255) sent ; as a single byte (8 + 3 bits); ; D0 D1 D2 D3 D4 D5 D6 D7 A0 A1 A2 - this can be used to send data ; to a PC with 3rd party IR ; reception software (PC remote ; control) ; ; GKOS chord mode: Send IR chords (keyboard status, 6 + 5 bits) continuously + ; send final key codes* on UART (8 bits) ; Byte_IR_mode: Send final key codes on UART (8 bits) + send final key codes ; as single bytes on IR (SIRCS, IrDA, GKOS byte or none) ; SIRCS MD mode: Send Sony MD remote commands (12 SIRCS-coded bits) on IR + ; send final key codes on UART (8 bits)** ; IrDA mode: Send final key codes as 3 IrDA frames (3 x 8 data bits): ; Header > IR device address > key code ; + send final key codes on UART (8 bits) as single bytes ; both IrDA and UART use 9600 bit/s. ; TV1 mode: Send ASA TV remote commands (for testing), 8-bit data + 8-bit IR address ; ; *) Final key codes (0-255) are the codes listed in a table. They are determined by ; intelligent key scanning techninques. One code represents one character, or function, ; that has been typed on the GKOS keyboard. Characters may be typed as single entries ; (press and release keys) or within chordons (no release of all keys needed between characters). ; ; **) Not optimal for fast typing (both UART and IR) because sending SIRCS remote commands ; takes time due to repeated IR packets. SIRCS reception only accepts characters if they are ; sent 2 or 3 times, this software sends 2 ;------------------------------------------------------------------------ ;============================== END OF SETTINGS =========================================== ; Prepare for SLEEP operation bcf INTCON, RBIF ; Clear Port B interrupt flag (just to make sure) bsf INTCON, RBIE ; Enable Port B interrupts movlw d'255' movwf SLEEPcnt1 movwf SLEEPcnt2 movlw SLEEPdelay ; This defines the ilde time before going to sleep movwf SLEEPcnt3 ; 1=> 5s, 5=> 26s, 50=> 4:10 60=> 5 min, 100=> 8:20 ;============================ PROGRAM ================================== ; The device should check 'request to send' from host (=DATA pulled low) ; at least every 10ms! MainLoop ; Delay d'100' ;delay 100us ;------------------------ ;===== PS/2 KEYBOARD ==== ;------------------------ MainL_Keyboard ; Principle: Cut out characters that cannot be within a chordon ; In case previous chord was zero, any next character must be allowed next ;bsf TextOnly ; << call SerTx1 ; bsf AKUSent_IR ; Set sent flag return CheckAKU_WR ; Same as above for the wired keyboard ; Was a zero chord received. btfss ZeroChordWR ; Latest received IR chord was a Zero Chord? return ; Not a Zero chord. ; Yes. Zero Chord. btfsc AKUSent_WR ; AKU Already sent? return ; Yes. movlw d'253' ; No, send it. Keycode indicating all keys up = call SerTx1 ; bsf AKUSent_WR ; Set sent flag return ;----------------------------------------------------------- ;-----MOUSE FUNCTIONS--------------------------------------- ;----------------------------------------------------------- UARTSendMov ; W = 0x02 POINTER MOVEMENT IR data received (bit1=1) ; Build MouseByte1 for sending to the host: ; IRByte1: - - Yovf Xovf Ysign Xsign RButton LButton <= Received from IR or local keyboard ; MouseByte1: Yovl Xovl Ysign Xsign '1' MButton RButton LButton <= To send to UART (= PS/2 format) movf IRByte1,W ; Get IRByte1 into TEMPX for actions movwf TEMPX movlw b'00001000' ; First, set the 'Allways 1' movwf MouseByte1 ; 0 0 0 0 1 0 0 0 movf TEMPX,W ; Second, move RButton and LButton bits andlw b'00000011' ; clear the rest 0 0 0 0 0 0 b b addwf MouseByte1,F ; and add the two bits 0 0 0 0 1 0 b b rlf TEMPX,F ; Next, Yovf Xovf Ysign Xsign rlf TEMPX,F ; y x y x b b 0 0 movf TEMPX,W andlw b'11110000' ; W: y x y x 0 0 0 0 addwf MouseByte1,F ; MouseByte1: y x y x 1 0 b b clrf MouseByte4 ; Clear Wheel data in this case UARTSendMov_1 ; Send the IR Mouse data packet to UART almost as received movlw d'128' ; Keycode indicating 4 bytes of Mouse Data call SerTx1 ; movf MouseByte1,W ; Buttons pressed etc call SerTx1 ; movf IRByte3,W ; X movement data call SerTx1 ; movf IRByte4,W ; Y movement data call SerTx1 ; movf MouseByte4,W ; Z = Scroll Wheel data call SerTx1 ; movlw d'255' ; Keycode indicating end of Mouse Data call SerTx1 ; goto MainLoop ;-------------------------------------------------------------- UARTSendScroll ; W = 0x04 SCROLL WHEEL IR data received (bit2=1) movlw b'00001000' ; First, set the 'Allways 1' movwf MouseByte1 ; 0 0 0 0 1 0 0 0 ; No buttons checked in this simple implementation ; Other bytes are then empty clrf IRByte3 clrf IRByte4 movf IRByte3,W ; Put the received Z data to last UART byte movwf MouseByte4 ; goto UARTSendMov_1 ; Send all 4 bytes plus start and stop ;********************************************************************** ;------END OF MOUSE FUNCTIONS--------------------------------- SendZeroChord ;call SendPause ; Pause 10 ms ;clrf finalchord ;Idle chord IR packet (chord=W=0) - takes about 18 ms to send call SendStart ;2200us pulse movlw d'0' call SendChord_W ;6 bits call SendDevice ;5 bits (00010 = Betamax) bcf ZeroChordMissing ; clear flag return ;------------- STRING OUTPUT ------------ Word_shortcuts ; For US layout and MD edit modes only btfsc MODE123on ; return if this is set goto Word_shortcuts_X btfsc SYMBon ; return if this is set goto Word_shortcuts_X btfsc CTRLon ; return if this is set goto Word_shortcuts_X btfsc ALTon ; return if this is set goto Word_shortcuts_X ; MD: Backspace = Left Arrow + Delete (MD edit mode) btfss SIRCS_MD_mode ; MD mode? goto Word_shortcuts_1b ; No. ; Yes. btfss SIRCS_MD_EDIT ; Editing MD song titles? goto Word_shortcuts_X ; No. Forget shortcuts. ; Yes, editing. Backspace = Left Arrow + Delete movf finalchord,W ; xorlw d'7' ; Test if chord = Backspace btfsc STATUS,Z ; Skip if Z=0. Skip if not equal. goto TXword_MD_backspace ; Word_shortcuts_1b btfss US_version ; If US version, check for other shortcuts too goto Word_shortcuts_X movf finalchord,W ; xorlw d'5' ;Test if chord=th btfsc STATUS,Z ;Skip if Z=0. Skip if not equal. goto TXword_th ; movf finalchord,W ; xorlw d'13' ;Test if chord=and_ btfsc STATUS,Z ;Skip if Z=0. Skip if not equal. goto TXword_and ; movf finalchord,W ; xorlw d'21' ;Test if chord=the_ btfsc STATUS,Z ;Skip if Z=0. Skip if not equal. goto TXword_the ; movf finalchord,W ; xorlw d'37' ;Test if chord=of_ btfsc STATUS,Z ;Skip if Z=0. Skip if not equal. goto TXword_of ; movf finalchord,W ; xorlw d'29' ;Test if chord=a_ btfsc STATUS,Z ;Skip if Z=0. Skip if not equal. goto TXword_a ; movf finalchord,W ; xorlw d'53' ;Test if chord=to_ btfsc STATUS,Z ;Skip if Z=0. Skip if not equal. goto TXword_to ; movf finalchord,W ; chord must be in W goto Word_shortcuts_X ; --- TXword_MD_backspace movlw d'47' ; Left Arrow call CharOutput movlw d'100' ; Extra delay call DelayWx1ms bcf TextOnly ; This would otherwise be set movlw d'57' ; Delete call CharOutput return TXword_th movlw d'20' ; t ; 'th' (this was 'with' before) call CharOutput movlw d'8' ; h call CharOutput return TXword_and movlw d'1' ; a call CharOutput movlw d'14' ; n call CharOutput movlw d'4' ; d call CharOutput movlw d'50' ; space call CharOutput return TXword_the movlw d'20' ; t call CharOutput movlw d'8' ; h call CharOutput movlw d'5' ; e call CharOutput movlw d'50' ; space call CharOutput return TXword_of movlw d'15' ; o 'of' (his was 'that' before) call CharOutput movlw d'6' ; f call CharOutput movlw d'50' ; space call CharOutput return TXword_a movlw d'1' ; a 'a' (this was 'have' before) call CharOutput movlw d'50' ; space call CharOutput return TXword_to movlw d'20' ; t 'to' (this was 'which' before) call CharOutput movlw d'15' ; o call CharOutput movlw d'50' ; space call CharOutput return ; Send Chordon Shortcut words from table TXshortcutword ; Enter with SCpointer start value in W ; call ShortcutToGKOSrefs with SCpointer, result in Temp, end = 0 bcf MoreChords ; Do not send the original character movwf SCpointer ; Point to table (start of shortcut word first) TXshortcutword_1 call ShortcutToGKOSrefs ; Call the table => get one character of sc word incf Temp,f ; Result in Temp decfsz Temp,f ; = 0? goto TXshortcutword_C ; No. Continue by sending the character. ; Yes. movlw d'50' ; Send GKOSref for space at the end. call CharOutput clrf RXfinalchord ; Clear chord buffers clrf RXfinalchord2 return ; Exit. The whole word was sent. TXshortcutword_C movf Temp,W ; Send GKOSref. call CharOutput incf SCpointer,f movf GKOSref,W ; Was it ShiftON? xorlw d'59' bnz $ + 2 bsf SHIFTon ; Yes. Set parameter SHIFTon so that it will be cleared goto TXshortcutword_1 ; --- CharOutput movwf GKOSref movlw d'3' call DelayWx1ms ; minimum delay between chords bcf TextOnly ; Send all types of characters this time (like 'don't') goto Output_GKOSref ;---------------------------------------- ; From IR reception and from wired GKOS: ; NOTE This is a SUB since version gkp21.asm !!! UARTSendChord ; W = 0x01 CHORD VALUE IR data received (bit0=1) ;movlw d'1' ;debug ;call SerTx ; ;------ ; THIS IS A FAR CALL, SO PROGRAM MEMORY PAGE MUST BE CHANGED movlw HIGH GetChordParams ; Get high 5 bits of address movwf PCLATH ; Next Page... call GetChordParams ; Do the common IR/wired keyboard procedure movlw HIGH UARTSendChord ; Make sure PCLATH is pointing to this Page (0) movwf PCLATH ;------zxcvb btfss RXchordREADY ; A chord to send? return ; No. ; Yes. UARTSendChord_2 ; Check if NUL (due to polling back in time) movf RXfinalchord,W ; xorlw d'0' ; Test if chord=NUL btfsc STATUS,Z ; Skip if Z=0. Skip if not equal. return ; Return to MainLoop movf RXfinalchord,W movwf finalchord ; ---------------------------- ; The chord has been confirmed ; ---------------------------- btfss KBDasMOUSE ; Is the GKOS keyboard simulating a mouse? goto UARTSendChord_3 ; No. Send scan codes via UART and IR ; Yes. Send corresponding button/movement data via UART movlw HIGH KeyboardMouse ; Get high 5 bits of address movwf PCLATH ; Calling Next Code Page... call KeyboardMouse ; According to chord received, send corresponding mouse data (UART) movlw HIGH UARTSendChord_3 ; Make sure PCLATH is pointing back to this Page (0) movwf PCLATH ; Hopefully not too many nested calls! return ; goto MainLoop ; Return to MainLoop UARTSendChord_3 ; ------------------------ movf finalchord,W ; is this really needed? call SerTx ;debug ; In all cases, Chord is in W and finalchord ; finalchord must be in W btfsc US_version ; If US version, check for national word shortcuts goto Word_shortcuts btfsc SIRCS_MD_EDIT ; MD remote control EDIT mode? goto Word_shortcuts ; Yes. Always use shortcuts. Word_shortcuts_X ; --------------------------------------------------------- ; Test if IR mode change command expected ; --------------------------------------------------------- btfss CommandFlag ; Has [SYMB] [Ctrl] been pressed? goto Word_shortcuts_X1 ; No. ;movf CommandBuffer1,w ; Yes. Buffer the command until [ENTER] received ;movwf CommandBuffer2 ; this 3rd buffer has not yet been defined movf CommandBuffer0,w movwf CommandBuffer1 movf finalchord,w movwf CommandBuffer0 ; e.g. [SYMB] [Ctrl] m [ENTER] sets SIRCS MD remote control mode ; At the moment, IR mode commands are only one character long (c, i, m, g, t or r): ; mode c GKOS_IR_mode (chords = mode c), compatibility mode for PS/2 rec. ; mode i IrDA_mode (of Byte IR mode = mode i) ; mode m SIRCS_MD_mode (of Byte IR mode = mode m) ; mode g GKOS_byte_mode (of Byte IR mode = mode g), 8 data + 3 address bits ; mode t TV1_mode (of Byte IR mode = mode t) ; mode r RS232 mode = the same as IrDA mode Word_shortcuts_X1 btfss SIRCS_MD_mode ; MD mode? goto Word_shortcuts_X11 ; No. Just continue. ; Yes. btfss SIRCS_MD_EDIT ; Editing MD song titles? goto W_s_X_1 ; No. Forget also chordon shortcuts, ; and check the special functions. Word_shortcuts_X11 ; ----------------------------------------------------- ; Test for Chordon Shortcuts ; ----------------------------------------------------- ;btfss MoreChords ; two chords waiting for ouput? (NOT ALWAYS CORRECT!) ;goto W_s_X_1 ; No. Check the special functions. ; Yes. ; Check if RXfinalchord2 exists incf RXfinalchord2,f ; = 0? decfsz RXfinalchord2,f goto $ + 2 ; It does. Check chordon shortcuts goto W_s_X_1 ; Does not. Check the special functions. ;TEST without the table: 'for' = .r ; movf RXfinalchord,w ; RXfinalchord = . ? ; xorlw d'34' ; Test if chord = . ; btfsc STATUS,Z ; Skip if Z=0. Skip if not equal. ; goto SC_period ; Yes. ; GKOSref to SCpointer (set SelectTable=1) > ; TXshortcutword: ShortcutToGKOSrefs, chars output > ; return ; No. ;END OF TEST ; Chordon Shortcut tables need parameters GKOSref and GKOSref2 movf RXfinalchord,w ; RXfinalchord => call WtoGKOSref ; movwf GKOSref ; Corresponding GKOSref movf RXfinalchord2,w ; RXfinalchord2 => call WtoGKOSref ; movwf GKOSref2 ; Corresponding GKOSref2 ;TEST without the table: 'are' = ?r ; movf GKOSref,w ; GKOSref = '?' ? ; xorlw d'33' ; Test if char = '?' ; btfsc STATUS,Z ; Skip if Z=0. Skip if not equal. ; goto SC_question ; Yes. ; No. ;END OF TEST ; a b c d e f g h i j k l m n o p q r s t u v w x y z u å ä ö ; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 34 35 36 27 28 29 30 ; ; . , ! ? - ' Up Dn Shift ; 31 32 33 34 35 36 42 43 59 ; SUBWF: C=1 if result is positive or zero; C=0 if negative (borrow); Z=1 only when zero ; GKOSref or GKOSref2 > 30? If not, this is not a chordon shortcut (goto W_s_X_1 then) movlw d'31' ; GKOSref >= 31? subwf GKOSref,W ; GKOSref - 31 = positive or zero? btfsc STATUS,C ; Carry staying zero? Note: C = complement of Borrow goto SpecCharFirst ; GKOSref >= 31 (No borrow) ; GKOSref < 31 (Borrow) movlw d'31' ; GKOSref2 >= 31? subwf GKOSref2,W ; GKOSref2 - 31 = positive or zero? btfsc STATUS,C ; Carry staying zero? Note: C = complement of Borrow goto SpecCharLast ; GKOSref2 >= 31 (No borrow) ; GKOSref2 < 31 (Borrow) goto W_s_X_1 ; No special character included, just letters SpecCharFirst ; -a ,v 's -i '- ?Up !. , (spec char + letter OR spec char) movf GKOSref,w ; (GKOSref = 31...63) movwf Temp ; Temp = 31...63 movlw d'30' ; Temp = 1...33 subwf Temp,f ; sub w from file call SetShortcutFlags btfss Temp,7 ; Is this special char included in shortcut spec chars? goto W_s_X_1 ; No. btfsc Temp,6 goto Arrows_etc btfsc Temp,0 goto SC_period btfsc Temp,1 goto SC_comma btfsc Temp,2 goto SC_exclamation btfsc Temp,3 goto SC_question btfsc Temp,4 goto SC_hyphen btfsc Temp,5 goto SC_asterisk Arrows_etc btfsc Temp,0 goto SC_uparrow btfsc Temp,1 goto SC_downarrow btfsc Temp,2 goto SC_SHIFT goto W_s_X_1 ; just to make sure SpecCharLast ; a- v. f! (ONLY the last one is a spec char) movf GKOSref2,w ; (GKOSref2 = 31...63) movwf Temp ; Temp = 31...63 movlw d'30' ; Temp = 1...33 subwf Temp,f ; sub w from file call SetShortcutFlags btfss Temp,7 ; Is this special char included in shortcut spec chars? goto W_s_X_1 ; No. btfsc Temp,6 goto Arrows_etc2 btfsc Temp,0 goto SC_period2 btfsc Temp,1 goto SC_comma2 btfsc Temp,2 goto SC_exclamation2 btfsc Temp,3 goto SC_question2 btfsc Temp,4 goto SC_hyphen2 btfsc Temp,5 goto SC_asterisk2 Arrows_etc2 btfsc Temp,0 goto SC_uparrow2 btfsc Temp,1 goto SC_downarrow2 btfsc Temp,2 goto SC_SHIFT2 goto W_s_X_1 ; just to make sure ; Set flags for shortcut tables a-ö + spec.char. and spec.char + a-ö. Bit7 = 1 for shortcut char's SetShortcutFlags ; Offset in Temp (GKOSref or GKOSref2) => result in Temp ; Convert GKOSref to flags indicating group (, . ! ?...) ; This code allows accessing a table anywhere in program memory movlw LOW Table_SetSCFlags ;Get low 8 bits of address addwf Temp,F ;Offset, do an 8-bit add operation movlw HIGH Table_SetSCFlags ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf Temp,W ;load computed Offset in W reg call Table_SetSCFlags ;call table on another Page movwf Temp ;save movlw HIGH SetShortcutFlags ;Make sure PCLATH points back to this Page (0) movwf PCLATH return ; ; Chordon shortcuts are checked here if MoreChords = 1 ; Check RXfinalchord + RXfinalchord2, e.g. _ + i makes: international, SCpointer=1... ; Goto TXshortcutword with SCpointer start value in W ; it will call ShortcutToGKOSrefs with SCpointer and send the characters ;goto PS2SC_2b ; Skip the special functions ; goto W_s_X_1 ; Check the special functions next ; First character is the special char, second char may also be (=> Table length 43 to find the char) SC_asterisk ; ' + as a chordon ;0 10 20 30 ; 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 ; a b c d e f g h i=is j k l m n o p q r s t u v w x y=you z ü x y z movlw b'00000001' ; Select Table A (' - .) movwf SelectTable movlw LOW Table_SC_asterisk ;Get low 8 bits of address addwf GKOSref2,F ;Offset, do an 8-bit add operation movlw HIGH Table_SC_asterisk ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref2,W ;load computed Offset in W reg call Table_SC_asterisk ;call table on another Page movwf Temp ;save SCpointer movlw HIGH SC_asterisk ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (SCpointer=0 -> no shortcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table SC_hyphen ; a b c d e f g h i j k l m n o p q r s t u v w x y z ü å ä ö movlw b'00000001' ; Select Table A (' - .) movwf SelectTable movlw LOW Table_SC_hyphen ;Get low 8 bits of address addwf GKOSref2,F ;Offset, do an 8-bit add operation movlw HIGH Table_SC_hyphen ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref2,W ;load computed Offset in W reg call Table_SC_hyphen ;call table on another Page movwf Temp ;save movlw HIGH SC_hyphen ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (no shorcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table SC_period ; a b c d e f g h i j k l m n o p q r=for s t u v w x y z ü å ä ö movlw b'00000001' ; Select Table A (' - .) movwf SelectTable movlw LOW Table_SC_period ;Get low 8 bits of address addwf GKOSref2,F ;Offset, do an 8-bit add operation movlw HIGH Table_SC_period ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref2,W ;load computed Offset in W reg call Table_SC_period ;call table on another Page, GKOSref to SCpointer movwf Temp ;save movlw HIGH SC_period ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (no shorcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table SC_comma ; a b c d e f g h i j k l m n o p q r s t u v w x y z ü å ä ö movlw b'00000010' ; Select Table B (, ? !) movwf SelectTable movlw LOW Table_SC_comma ;Get low 8 bits of address addwf GKOSref2,F ;Offset, do an 8-bit add operation movlw HIGH Table_SC_comma ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref2,W ;load computed Offset in W reg call Table_SC_comma ;call table on another Page movwf Temp ;save movlw HIGH SC_comma ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (no shorcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table SC_exclamation ; a b c d e f g h i j k l m n o p q r s t u v w x y=yes z ü å ä ö movlw b'00000010' ; Select Table B (, ? !) movwf SelectTable movlw LOW Table_SC_exclamation ;Get low 8 bits of address addwf GKOSref2,F ;Offset, do an 8-bit add operation movlw HIGH Table_SC_exclamation ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref2,W ;load computed Offset in W reg call Table_SC_exclamation ;call table on another Page movwf Temp ;save movlw HIGH SC_exclamation ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (no shorcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table SC_question ; a b c d e f g h i j k l m n o p q r=are s t u v w x=what y z ü å ä ö movlw b'00000010' ; Select Table B (, ? !) movwf SelectTable movlw LOW Table_SC_question ;Get low 8 bits of address addwf GKOSref2,F ;Offset, do an 8-bit add operation movlw HIGH Table_SC_question ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref2,W ;load computed Offset in W reg call Table_SC_question ;call table on another Page movwf Temp ;save movlw HIGH SC_question ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (no shorcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table SC_uparrow ; a b c d e f g h i j k l m n o p q r s t u v w x y z ü å ä ö movlw b'00000100' ; Select Table C (Up Dn Shift) movwf SelectTable movlw LOW Table_SC_uparrow ;Get low 8 bits of address addwf GKOSref2,F ;Offset, do an 8-bit add operation movlw HIGH Table_SC_uparrow ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref2,W ;load computed Offset in W reg call Table_SC_uparrow ;call table on another Page movwf Temp ;save movlw HIGH SC_uparrow ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (no shorcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table SC_downarrow ; a b c d e f g h i j k l m n=not o p q r s t u v w x y z ü å ä ö movlw b'00000100' ; Select Table C (Up Dn Shift) movwf SelectTable movlw LOW Table_SC_downarrow ;Get low 8 bits of address addwf GKOSref2,F ;Offset, do an 8-bit add operation movlw HIGH Table_SC_downarrow ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref2,W ;load computed Offset in W reg call Table_SC_downarrow ;call table on another Page movwf Temp ;save movlw HIGH SC_downarrow ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (no shorcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table SC_SHIFT ; a b c d e f g h i j k l m n o p q r s t u v w x y z ü å ä ö movlw b'00000100' ; Select Table C (Up Dn Shift) movwf SelectTable movlw LOW Table_SC_shift ;Get low 8 bits of address addwf GKOSref2,F ;Offset, do an 8-bit add operation movlw HIGH Table_SC_shift ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref2,W ;load computed Offset in W reg call Table_SC_shift ;call table on another Page movwf Temp ;save movlw HIGH SC_SHIFT ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (no shorcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table ; Only the second character is the special character (=> Table length 30 to find the first char) SC_asterisk2 ; + ' as a chordon ;0 10 20 30 ; 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 ; a b c d e f g h i=is j k l m n o p q r s t u v w x y=you z ü x y z movlw b'00000001' ; Select Table A (' - .) movwf SelectTable movlw LOW Table2_SC_asterisk ;Get low 8 bits of address addwf GKOSref,F ;Offset, do an 8-bit add operation movlw HIGH Table2_SC_asterisk ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref,W ;load computed Offset in W reg call Table2_SC_asterisk ;call table on another Page movwf Temp ;save SCpointer movlw HIGH SC_asterisk2 ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (SCpointer=0 -> no shorcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table SC_hyphen2 ; a b c d e f g h i j k l m n o p q r s t u v w x y z ü å ä ö movlw b'00000001' ; Select Table A (' - .) movwf SelectTable movlw LOW Table2_SC_hyphen ;Get low 8 bits of address addwf GKOSref,F ;Offset, do an 8-bit add operation movlw HIGH Table2_SC_hyphen ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref,W ;load computed Offset in W reg call Table2_SC_hyphen ;call table on another Page movwf Temp ;save movlw HIGH SC_hyphen2 ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (no shorcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table SC_period2 ; a b c d e f g h i j k l m n o p q r=for s t u v w x y z ü å ä ö movlw b'00000001' ; Select Table A (' - .) movwf SelectTable movlw LOW Table2_SC_period ;Get low 8 bits of address addwf GKOSref,F ;Offset, do an 8-bit add operation movlw HIGH Table2_SC_period ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref,W ;load computed Offset in W reg call Table2_SC_period ;call table on another Page movwf Temp ;save movlw HIGH SC_period2 ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (no shorcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table SC_comma2 ; a b c d e f g h i j k l m n o p q r s t u v w x y z ü å ä ö movlw b'00000010' ; Select Table B (, ? !) movwf SelectTable movlw LOW Table2_SC_comma ;Get low 8 bits of address addwf GKOSref,F ;Offset, do an 8-bit add operation movlw HIGH Table2_SC_comma ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref,W ;load computed Offset in W reg call Table2_SC_comma ;call table on another Page movwf Temp ;save movlw HIGH SC_comma2 ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (no shorcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table SC_exclamation2 ; a b c d e f g h i j k l m n o p q r s t u v w x y=yes z ü å ä ö movlw b'00000010' ; Select Table B (, ? !) movwf SelectTable movlw LOW Table2_SC_exclamation ;Get low 8 bits of address addwf GKOSref,F ;Offset, do an 8-bit add operation movlw HIGH Table2_SC_exclamation ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref,W ;load computed Offset in W reg call Table2_SC_exclamation ;call table on another Page movwf Temp ;save movlw HIGH SC_exclamation2 ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (no shorcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table SC_question2 ; a b c d e f g h i j k l m n o p q r=are s t u v w x=what y z ü å ä ö movlw b'00000010' ; Select Table B (, ? !) movwf SelectTable movlw LOW Table2_SC_question ;Get low 8 bits of address addwf GKOSref,F ;Offset, do an 8-bit add operation movlw HIGH Table2_SC_question ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref,W ;load computed Offset in W reg call Table2_SC_question ;call table on another Page movwf Temp ;save movlw HIGH SC_question2 ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (no shorcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table SC_uparrow2 ; a b c d e f g h i j k l m n o p q r s t u v w x y z ü å ä ö movlw b'00000100' ; Select Table C (Up Dn Shift) movwf SelectTable movlw LOW Table2_SC_uparrow ;Get low 8 bits of address addwf GKOSref,F ;Offset, do an 8-bit add operation movlw HIGH Table2_SC_uparrow ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref,W ;load computed Offset in W reg call Table2_SC_uparrow ;call table on another Page movwf Temp ;save movlw HIGH SC_uparrow2 ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (no shorcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table SC_downarrow2 ; a b c d e f g h i j k l m n=not o p q r s t u v w x y z ü å ä ö movlw b'00000100' ; Select Table C (Up Dn Shift) movwf SelectTable movlw LOW Table2_SC_downarrow ;Get low 8 bits of address addwf GKOSref,F ;Offset, do an 8-bit add operation movlw HIGH Table2_SC_downarrow ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref,W ;load computed Offset in W reg call Table2_SC_downarrow ;call table on another Page movwf Temp ;save movlw HIGH SC_downarrow2 ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (no shorcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table SC_SHIFT2 ; a b c d e f g h i j k l m n o p q r s t u v w x y z ü å ä ö movlw b'00000100' ; Select Table C (Up Dn Shift) movwf SelectTable movlw LOW Table2_SC_shift ;Get low 8 bits of address addwf GKOSref,F ;Offset, do an 8-bit add operation movlw HIGH Table2_SC_shift ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSref,W ;load computed Offset in W reg call Table2_SC_shift ;call table on another Page movwf Temp ;save movlw HIGH SC_SHIFT2 ;Make sure PCLATH points back to this Page (0) movwf PCLATH incf Temp,f ; Temp = 0? (no shorcut word) decfsz Temp,f goto $ + 2 goto PS2SC_2b ; Yes. Exit. ; No. Do the output. movf Temp,w ; Set Shortcut start address goto TXshortcutword ; Output from table ; ----------------------------------------------------------- W_s_X_1 movf finalchord,W ; xorlw d'63' ;Test if chord=123-abc btfsc STATUS,Z ;Skip if Z=0. Skip if not equal. goto abc123Pressed ; movf finalchord,W ; xorlw d'45' ;Test if chord=SYMB btfsc STATUS,Z ;Skip if Z=0. Skip if not equal. goto SymbPressed ; movf finalchord,W ; xorlw d'18' ;Test if chord=SHIFT btfsc STATUS,Z ;Skip if Z=0. Skip if not equal. goto ShiftPressed ; movf finalchord,W ; xorlw d'47' ;Test if chord=CTRL btfsc STATUS,Z ;Skip if Z=0. Skip if not equal. goto CtrlPressed ; movf finalchord,W ; xorlw d'55' ;Test if chord=ALT btfsc STATUS,Z ;Skip if Z=0. Skip if not equal. goto AltPressed ; movf finalchord,W ; xorlw d'59' ;Test if chord=ENTER btfss STATUS,Z ;Skip if Z=1. Skip if equal. goto PS2SC_2b ; No. ; Yes. EnterPressed bcf SIRCS_MD_EDIT ; Yes. After entering song title, return btfsc SIRCS_MD_mode ; In case of MD remote control... bsf AV_mode ; ...use codes 129...255. btfss CommandFlag ; Is a command expected before [Enter]? goto PS2SC_2b ; No. ; Yes. ; READ IR MODE SELECTION COMMAND HERE ; e.g. [SYMB] [Ctrl] c [ENTER] ; mode c GKOS_IR_mode (chords = mode c), compatibility mode for PS/2 rec. ; mode i IrDA_mode (of Byte IR mode = mode i) ; mode m SIRCS_MD_mode (of Byte IR mode = mode m) ; mode g GKOS_byte_mode (of Byte IR mode = mode g), 8 data + 3 address bits ; mode t TV1_mode (of Byte IR mode = mode t) ; mode u UART mode (RS232 mode) = the same as IrDA mode ;CommandBc movf CommandBuffer1,w ; xorlw d'4' ;Test if command = c (GKOS_IR_mode, compatible chord mode) btfss STATUS,Z ;Skip if Z=1. Skip if equal. goto CommandBi ; No. ; Yes. bsf GKOS_IR_mode ; GKOS IR mode = send CHORD VALUES continuously, ; **or**: bcf Byte_IR_mode ; Byte IR mode = send a one-byte KEY CODE per character = ; **and one of these**: bcf GKOS_byte_mode ; - GKOS Byte Mode, send IR using 11 SIRCS-coded bits: bcf IrDA_mode ; - IrDA frame mode (of Byte IR mode) to send key codes bcf SIRCS_MD_mode ; - SIRCS MD mode (of Byte IR mode) to remote control bcf TV1_mode ; - TV1 remote control mode (ASA) goto CommandBX CommandBi movf CommandBuffer1,w ; xorlw d'26' ;Test if command = i (IrDA_mode) btfss STATUS,Z ;Skip if Z=1. Skip if equal. goto CommandBm ; No. ; Yes. bcf GKOS_IR_mode ; GKOS IR mode = send CHORD VALUES continuously, ; **or**: bsf Byte_IR_mode ; Byte IR mode = send a one-byte KEY CODE per character = ; **and one of these**: bcf GKOS_byte_mode ; - GKOS Byte Mode, send IR using 11 SIRCS-coded bits: bsf IrDA_mode ; - IrDA frame mode (of Byte IR mode) to send key codes bcf SIRCS_MD_mode ; - SIRCS MD mode (of Byte IR mode) to remote control bcf TV1_mode ; - TV1 remote control mode (ASA) goto CommandBX CommandBm movf CommandBuffer1,w ; xorlw d'50' ;Test if command = m (SIRCS_MD_mode) btfss STATUS,Z ;Skip if Z=1. Skip if equal. goto CommandBg ; No. ; Yes. bcf GKOS_IR_mode ; GKOS IR mode = send CHORD VALUES continuously, ; **or**: bsf Byte_IR_mode ; Byte IR mode = send a one-byte KEY CODE per character = ; **and one of these**: bcf GKOS_byte_mode ; - GKOS Byte Mode, send IR using 11 SIRCS-coded bits: bcf IrDA_mode ; - IrDA frame mode (of Byte IR mode) to send key codes bsf SIRCS_MD_mode ; - SIRCS MD mode (of Byte IR mode) to remote control bcf TV1_mode ; - TV1 remote control mode (ASA) goto CommandBX CommandBg movf CommandBuffer1,w ; xorlw d'24' ;Test if command = g (GKOS_byte_mode) btfss STATUS,Z ;Skip if Z=1. Skip if equal. goto CommandBt ; No. ; Yes. bcf GKOS_IR_mode ; GKOS IR mode = send CHORD VALUES continuously, ; **or**: bsf Byte_IR_mode ; Byte IR mode = send a one-byte KEY CODE per character = ; **and one of these**: bsf GKOS_byte_mode ; - GKOS Byte Mode, send IR using 11 SIRCS-coded bits: bcf IrDA_mode ; - IrDA frame mode (of Byte IR mode) to send key codes bcf SIRCS_MD_mode ; - SIRCS MD mode (of Byte IR mode) to remote control bcf TV1_mode ; - TV1 remote control mode (ASA) goto CommandBX CommandBt movf CommandBuffer1,w ; xorlw d'14' ;Test if command = t (TV1_mode) btfss STATUS,Z ;Skip if Z=1. Skip if equal. goto CommandBr ; No. ; Yes. bcf GKOS_IR_mode ; GKOS IR mode = send CHORD VALUES continuously, ; **or**: bsf Byte_IR_mode ; Byte IR mode = send a one-byte KEY CODE per character = ; **and one of these**: bcf GKOS_byte_mode ; - GKOS Byte Mode, send IR using 11 SIRCS-coded bits: bcf IrDA_mode ; - IrDA frame mode (of Byte IR mode) to send key codes bcf SIRCS_MD_mode ; - SIRCS MD mode (of Byte IR mode) to remote control bsf TV1_mode ; - TV1 remote control mode (a rare brand: ASA) goto CommandBX CommandBr movf CommandBuffer1,w ; xorlw d'22' ;Test if command = u (UART_mode, same as IrDA mode) btfss STATUS,Z ;Skip if Z=1. Skip if equal. goto CommandBX ; No. ; Yes. bcf GKOS_IR_mode ; GKOS IR mode = send CHORD VALUES continuously, ; **or**: bsf Byte_IR_mode ; Byte IR mode = send a one-byte KEY CODE per character = ; **and one of these**: bcf GKOS_byte_mode ; - GKOS Byte Mode, send IR using 11 SIRCS-coded bits: bsf IrDA_mode ; - IrDA frame mode (of Byte IR mode) to send key codes bcf SIRCS_MD_mode ; - SIRCS MD mode (of Byte IR mode) to remote control bcf TV1_mode ; - TV1 remote control mode (a rare brand: ASA) CommandBX bcf CommandFlag PS2SC_2b ;====================== USE THE TABLES ========================= CharOutput_0 ; Enter here when Sending a character of a shortcut string (chord in W) ;*** Check the tables for proper scan codes *** ;Functioning like this: finalchord => GKOSref => key code (for IrDA etc.) => SIRCS character (in IRcode) ;Based on finalchord: call FinalChordToGKOSref ; Get the corresponfing GKOS Reference number movwf GKOSref ; result in W -> save in GKOSref ; Key Polling: test if GKOSref > 30 ; If TextOnly=1 then do not accept functions (within chordons) Output_GKOSref clrf GKOSrefshift ; Clear table shift (offset) to start with btfss TextOnly ; Chord within a chordon? goto ChordonOK ; No. Accept any character. ; Yes. movlw d'31' ; Discard characters if GKOSref > 30 subwf GKOSref,W ; GKOSref - 31 = positive or zero? btfss STATUS,C ; Carry staying zero? Note: C = complement of Borrow goto ChordonOK ; No. Carry set. Then GKOSref < 31. No more action. ; Yes. GKOSref > 30. ; Check if 'space': GKOSref = 50? movf GKOSref,W ; xorlw d'50' ; GKOSref=50? btfsc STATUS,Z ; Skip if Z=0. Skip if not equal. goto ChordonOK ; Send, this is Space. return ; GKOSref <> 50. Just send nothing. ChordonOK bsf TextOnly ; Set default for next character: ; Send only GKOS chars 1-30 or space until zero chord found. ; Assumed: chord is within a chordon. ;Select proper GKOS character set based on SYMB and 123-abc ;************* Choose GKOS symbol set ************* btfss MODE123on ;123-mode on? goto CheckSymb ;if not, continue movlw d'63' ;if yes, use next table (123-table) movwf GKOSrefshift ;Move down to 123-mode table btfss SYMBon ;In addition to 123 mode, is SYMB on? goto CheckX ;No. No more action then. movlw d'0' ;Yes, SYMB is on in addition to 123 on. <> 26.4.2002 movwf GKOSrefshift ;...move back to abc set then movlw d'31' ; but still use SYMB table if GKOSref>30 (:;_ etc) subwf GKOSref,W ;GKOSref - 31 = positive or zero? btfss STATUS,C ;Carry staying zero? Note: C = complement of Borrow goto CheckX ;No. Carry set. Then GKOSref < 31. No more action. movlw d'126' ;Yes. Use SYMB set (GKOSref . movwf GKOSrefshift ;Shift to SYMB set. goto CheckX CheckSymb ;This SYMB check is in abc mode only (see above for 123 mode) btfss SYMBon ;bits2&1: 10,11 goto CheckShift ;no, just continue movlw d'126' ;yes, use SYMB table movwf GKOSrefshift ;Mode two sets down to SYMB table goto CheckX CheckShift ; GKOSref = 1...30? movlw d'31' ; subwf GKOSref,W ; GKOSref - 31 = positive or zero? btfsc STATUS,C ; Carry staying zero? Note: C = complement of Borrow goto CheckX ; Carry not set. Then GKOSref > 31. No more action. btfss SHIFTon ; goto CheckX movlw d'189' ; yes, use SHIFT table movwf GKOSrefshift ; CheckX movf GKOSref,W ;use the selected shift in tables (abc,123,SYMB) addwf GKOSrefshift,F ;GKOSrefshift The final pointer = ref + shift now call GKOSrefToKeycode ;Get the corresponding key code ; keycode = scancode ; ******************************** UART TRANSMISSION ***************************** ; txtxtxtx ; ------------------------------- Always send via UART --------------------------- UART_Send movf keycode,W ; Different codes for UART and IR! btfsc AV_mode ; AV mode? addlw d'128' ; Yes. Use remote commands keycodes 129...255 call SerTx1 ; Send via UART (always send key code) call StayAwake btfsc Byte_IR_mode ; Any IR character transmission in general? goto Byte_IR_TX ; Yes. ; No. Only IR chords might be sent (if GKOS_IR_mode is set). btfss SpecialKey ; Sendig a Shift? call ClearModes ; No. Remove shifts but keep CAPS bcf SpecialKey return ; ;----- SendSpecKey ; enter this with key code in W (shifts...) bsf SpecialKey ; This is a shift so do not make certain sub calls movwf keycode ; All shifts, too, must be sent via UART goto UART_Send ; ******************************** BYTE IR TRANSMISSIONS ************************** Byte_IR_TX btfsc IrDA_mode ; IrDA mode? goto IRDA_Send ; Yes. ; No. btfsc SIRCS_MD_mode ; SIRCS MD mode? goto SIRCS_Send ; Yes. ; No. btfsc GKOS_byte_mode ; GKOS byte mode? 8 + 11 bits goto Byte_GKOS_Send ; Yes. btfsc TV1_mode ; TV1 mode? goto TV1_Send ; Yes. ; No. ; No mode active: btfss SpecialKey ; Sendig a Shift? call ClearModes ; Remove shifts but keep CAPS bcf SpecialKey return ; No. ; ******************************** GKOS Byte Send ******************************** Byte_GKOS_Send ; 11 bits = 8 data bits + 3 address bits ; [start] dddddddd 000 call SendStart ; Send IR Start Pulse of 2200us pulse movf keycode,W ; ** Send keycode = Key Code to send ; call SendByte <= this cannot be used because of too many nested sub calls! movwf TEMPX ;TEMPX = byte to send (bit0 first) movlw d'8' movwf bitcounter ;set counter for 8 bits (data byte) call SendChord_a ; W contents will be sent movlw b'00000011' ; ** Send Address bits of GKOS byte mode (110) movwf TEMPX ; TEMPX = byte to send (bit0 first) movlw d'3' movwf bitcounter ; set counter for 3 bits (data byte) call SendChord_a ; Send 1 1 0 (A0 A1 A2) ;call Send_1 ; Send Address bits of GKOS byte mode (000) ;call Send_1 ; A0 A1 A2 ;call Send_0 ; 1 1 0 for key code packet (chord packet: 1 1 1) movlw d'7' ; Have a 10ms pause after each IR packet call DelayWx1ms btfss SpecialKey ; Sending a Shift? call ClearModes ; No. Remove shifts but keep CAPS bcf SpecialKey return ; ******************************** SIRCS TRANSMISSION **************************** SIRCS_Send btfsc SIRCS_MD_EDIT ; SIRCS MD EDIT mode? (entering letters, numbers and symbols) goto CheckX_EDIT ; Yes. ; No. bcf SIRCS20 ; Clear SIRCS20 to indicate 15-bit transmissions movf keycode,W ; Convert keycode into IR remote ctrl code call ScanCodeToIRCode_S ; value is in IRcode after return - CONTROL MODE TABLE goto CheckXX ; NOTE: codes 42-63 WILL BE SENT IN 15-BIT MODE BUT FROM EDIT MODE TABLE CheckX_EDIT bsf SIRCS20 ; Set SIRCS20 to indicate 20-bit transmissions movf keycode,W ; Convert keycode into IR remote ctrl code call ScanCodeToIRCode ; value is in IRcode after return - EDIT MODE TABLE (ASCII) ; If keycode = 1...30 (a...zuåäö) then check case ; Upper Case: bit5=0 in IRcode movlw d'31' ; No more action if keycode > 30 subwf keycode,W ; keycode - 31 = positive or zero? btfsc STATUS,C ; Carry staying zero? Note: C = complement of Borrow goto CheckXX ; Yes. No more action ; No. Carry set. Then keycode < 31. Check case. btfsc GKOSmode,4 ; bit4 in GKOSmode is 0 for CAPS or SHIFT bcf IRcode,5 ; Send Upper Case MD 20-bit letter IR code CheckXX ; SIRCS code to send is now in IRcode movlw IRrepeats ; Repeat every SIRCS IR frame 3 times movwf IRCounter ; ; ------------------------------------------- call SendSIRCS ; Send IRcode btfss SpecialKey ; Sendig a Shift? call ClearModes ; No. Remove shifts but keep CAPS bcf SpecialKey return ; ******************************** IrDA TRANSMISSION **************************** IRDA_Send movlw b'00111100' ; Send Header call Send_IRDA movlw b'11110000' ; Send IR Device Address call Send_IRDA movf keycode,W ; Send Key Code call Send_IRDA movlw d'3' ; Delay after each byte call DelayWx1ms btfss SpecialKey ; Sendig a Shift? call ClearModes ; No. Remove shifts but keep CAPS bcf SpecialKey return ; ********************************* TV1 IR TRANSMISSION ************************* TV1_Send ; TV1 / Control mode / 129-255, (send only these key codes?) ; but first subtract 128 ; Convert keycode into IR remote ctrl code movf keycode,W ; This is a common TV table to point to specific tables call Keycode_to_TVcode ; TV TABLE ; result in IRcode ; If IRcode = 0xff then do not send anything movf IRcode,W ; IRcode xorlw 0xff ; Test if IRcode = 0xff (nothing to send) btfsc STATUS,Z ; Skip if Z=0. Skip if not equal. goto TV1_Send_X ; Yes. Equal. Do not send. ; Not equal movf IRcode,W ; These device-specific tables are shorter. call TVcode_to_TV1code ; TV1 TABLE ; result in IRcode movlw b'00000000' ; Device Address = 0000 0000 movwf TEMPY movlw b'00000011' ; First transmission is always 1100 0000 0000 0000 call Send_TV1 movlw d'14' call DelayWx1ms ;one repeat after 14ms movlw b'00000011' ; Device Address = real device address movwf TEMPY movf IRcode, W call Send_TV1 TV1_Send_X movlw d'14' ; Delay after each IR packet. call DelayWx1ms btfss SpecialKey ; Sendig a Shift? call ClearModes ; No. Remove shifts but keep CAPS bcf SpecialKey return ; ******************************************************************************** SendSIRCS ; Send via IR, SIRCS format (send IRcode) ; If IRcode = 0xff then do not send anything movf IRcode,W ; IRcode xorlw 0xff ; Test if IRcode = 0xff (nothing to send) btfsc STATUS,Z ; Skip if Z=0. Skip if not equal. goto SendSIRCS_SX ; Yes. Equal. Do not send. Just check the chord. ; Not equal ;------ ; If 41105 then use always 5 bits device (SIRCS20=0) ;öäöäöä ;------ ; Check first if it is a space (keycode = d'50') ; If space and EDIT mode then change IRcode 0x4c to 0x20 movf keycode,W ; keycode xorlw d'50' ; Test if keycode = d'50' (space) btfss STATUS,Z ; Skip if Z=1. Skip if equal. goto SendSIRCS_01 ; No. Not equal. Leave SIRCS20=1 ; Equal. Send space always with SIRCS20=0 ; btfss SIRCS_MD_EDIT ; SIRCS MD EDIT mode? (entering letters, numbers and symbols) goto SendSIRCS_S ; No. (space, 13 bits, IRcode = 0x4c) movlw 0x20 ; Yes. (space, 20 bits, IRcode = 0x20) movwf IRcode goto SendSIRCS_S SendSIRCS_01 ;------ movf keycode,W ; keycode = Key Code movwf TEMPX ; movlw d'42' ; values larger than 42 subwf TEMPX,W ; TEMPX-42<0? btfsc STATUS,C ; Carry? goto SendSIRCS_1 ; No. TEMPX>=42 goto SendSIRCS_S ; Yes. TEMPX<42. Leave SIRCS20=1 (if it is =1) SendSIRCS_1 movf keycode,W ; keycode = Key Code movwf TEMPX ; movlw d'64' ; values larger than 64 subwf TEMPX,W ; TEMPX-64<0? btfsc STATUS,C ; Carry? goto SendSIRCS_2 ; No. TEMPX>=64 bcf SIRCS20 ; Yes. 41=106. Always SIRCS20=0 then goto SendSIRCS_S ; Yes. TEMPX<106. Leave SIRCS20=1 (if it is =1) ;------ SendSIRCS_S btfsc AutoRepeat ; Autorepeat on? goto SendSIRCS_S0 ; Yes. Send as fast as possible. ; No. ; btfss MoreChords ; More chords to be sent? Due to Check-back. ; goto SendSIRCS_S0 ; No. No extra delay needed between IR packets movlw d'50' ; Yes. Add SIRCS delay between IR packets (different chars) call DelayWx1ms SendSIRCS_rpt movlw d'24' ; Add SIRCS delay between IR packets (same char) call DelayWx1ms SendSIRCS_S0 ;call SendStart ; 2200us pulse 36 kHz call SendStart40 ; 2200us pulse 40 kHz movf IRcode,W ; IRcode info part must be in W call SendSChord_W ; 7 bits call SendSDevice ; 5 or 13 bits depending on bit SIRCS20 ; <><><> ; Repeat IR frames? decfsz IRCounter,f ; IR counter reached zero? (4...1) goto SendSIRCS_rpt ; No. Repeat same RXfinalchord as before. ; Yes. No more need to resend IR frame. incf IRCounter,f ; Leave counter as it was (0). SendSIRCS_SX ; Was it a 'T'? If yes. EDIT mode must be ON now. movf finalchord,W ; xorlw d'14' ; Test if chord='T' btfsc STATUS,Z ; Skip if Z=0. Skip if not equal. bsf SIRCS_MD_EDIT ; Yes. Set MD EDIT mode ON (20-bit, ASCII). ; Was it 'Esc'? If yes. EDIT mode must be OFF now. movf finalchord,W ; xorlw d'31' ; Test if chord='Esc' btfsc STATUS,Z ; Skip if Z=0. Skip if not equal. bcf SIRCS_MD_EDIT ; Yes. Set MD EDIT mode OFF (15-bit, remote codes). ; Update AV mode bsf AV_mode ; Use codes 128-255 at UART btfsc SIRCS_MD_EDIT ; MD Edit mode = 1 => AV mode = 0 bcf AV_mode ; Use codes 1-127 at UART return StayAwake ; display is used => initialize SLEEP counters movlw d'255' movwf SLEEPcnt1 movwf SLEEPcnt2 movlw SLEEPdelay ; This defines the ilde time before going to sleep movwf SLEEPcnt3 ; 1 => 3 sec return ; ------------- call a procedure on Code Page 2---------------- ; movlw HIGH Page2_proc ; Get high 5 bits of address ; movwf PCLATH ; Load high address in latch ; call Page2_proc ; Call a Page2 precedure ; movlw HIGH MainL_IR ; Make sure PCLATH is pointing to this Page (0) ; movwf PCLATH ;--------------------- THE TABLE CALLS ARE HERE --------------- ;Read data ;Table_ChordToRef => Table_GKOSrefToKeycode => Table_ScanCodeToIRCode FinalChordToGKOSref ;FIRST convert finalchord to GKOSref ;This code allows accessing a table anywhere in program memory movf finalchord,W WtoGKOSref movwf Temp TempToGKOSref movlw LOW Table_ChordToRef ;Get low 8 bits of address addwf Temp,F ;Offset, do an 8-bit add operation movlw HIGH Table_ChordToRef ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf Temp,W ;load computed Offset in W reg call Table_ChordToRef ;call table on another Page movwf Temp ;returning with value in W, save it first in Temp ;calling Table on Page 3 movlw HIGH FinalChordToGKOSref ;Make sure PCLATH is pointing to this Page (0) movwf PCLATH movf Temp,w ; Result saved in Temp and W (= value for GKOSref) return GKOSrefToKeycode ;THEN convert the GKOSref to keycode ;This code allows accessing a table anywhere in program memory movlw LOW Table_GKOSrefToKeycode ;Get low 8 bits of address addwf GKOSrefshift,F ;Offset, do an 8-bit add operation movlw HIGH Table_GKOSrefToKeycode ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf GKOSrefshift,W ;load computed Offset in W reg call Table_GKOSrefToKeycode ;call table on another Page movwf keycode ;save keycode ;calling FIN/SWE version Table on Page 3 movlw HIGH GKOSrefToKeycode ;Make sure PCLATH is pointing to this Page (0) movwf PCLATH return ShortcutToGKOSrefs ; Offset in SCpointer btfsc SelectTable,1 ; Select one of the sc word tables goto ScTGr_B ; b'0000 0001 btfsc SelectTable,2 goto ScTGr_C ; b'0000 0010 ;ELSE: SelectTable,0 = 1 ;THEN convert SCpointer to finalchord value ;This code allows accessing a table anywhere in program memory ; 'a -a .a movlw LOW TableA_shortcuts ;Get low 8 bits of address addwf SCpointer,F ;Offset, do an 8-bit add operation movlw HIGH TableA_shortcuts ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf SCpointer,W ;load computed Offset in W reg call TableA_shortcuts ;call table on another Page movwf Temp ;save for sending movlw HIGH ShortcutToGKOSrefs ;Make sure PCLATH points back to this Page (0) movwf PCLATH return ScTGr_B ; ,a ?a !a movlw LOW TableB_shortcuts ;Get low 8 bits of address addwf SCpointer,F ;Offset, do an 8-bit add operation movlw HIGH TableB_shortcuts ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf SCpointer,W ;load computed Offset in W reg call TableB_shortcuts ;call table on another Page movwf Temp ;save for sending movlw HIGH ShortcutToGKOSrefs ;Make sure PCLATH points back to this Page (0) movwf PCLATH return ScTGr_C ; a a a = Ua Da Sa movlw LOW TableC_shortcuts ;Get low 8 bits of address addwf SCpointer,F ;Offset, do an 8-bit add operation movlw HIGH TableC_shortcuts ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf SCpointer,W ;load computed Offset in W reg call TableC_shortcuts ;call table on another Page movwf Temp ;save for sending movlw HIGH ShortcutToGKOSrefs ;Make sure PCLATH points back to this Page (0) movwf PCLATH return ScanCodeToIRCode ; Symbols area - EDIT MODE ;LAST convert the keycode to Scan Code ;This code allows accessing a table anywhere in program memory movf keycode,W movwf TEMPX movlw LOW Table_ScanCodeToIRCode ;Get low 8 bits of address addwf TEMPX,F ;Offset, do an 8-bit add operation movlw HIGH Table_ScanCodeToIRCode ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf TEMPX,W ;load computed Offset in W reg ; call Table_ScanCodeToIRCode movwf IRcode ;store IRcode ;calling Table on Page 3 movlw HIGH ScanCodeToIRCode ;Make sure PCLATH is pointing to this Page (0) movwf PCLATH return ScanCodeToIRCode_S ; Remote control code area - CONTROL MODE ;LAST convert the keycode to Scan Code ;This code allows accessing a table anywhere in program memory ; movf keycode,W ; max 253, SYMB => 254 movf keycode,W movwf TEMPX movlw LOW Table_ScanCodeToIRCode_S ;Get low 8 bits of address addwf TEMPX,F ;Offset, do an 8-bit add operation movlw HIGH Table_ScanCodeToIRCode_S ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf TEMPX,W ;load computed Offset in W reg ; call Table_ScanCodeToIRCode_S movwf IRcode ;store IRcode ;calling Table on Page 3 movlw HIGH ScanCodeToIRCode_S ;Make sure PCLATH is pointing to this Page (0) movwf PCLATH return ;Use Table_Keycode_to_TVcode Keycode_to_TVcode ; TV Remote commands ; Enter with code in W ;This code allows accessing a table anywhere in program memory movwf TEMPX movlw LOW Table_Keycode_to_TVcode ;Get low 8 bits of address addwf TEMPX,F ;Offset, do an 8-bit add operation movlw HIGH Table_Keycode_to_TVcode ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf TEMPX,W ;load computed Offset in W reg ; call Table_Keycode_to_TVcode movwf IRcode ;store IRcode ;calling Table on Page 3 movlw HIGH Keycode_to_TVcode ;Make sure PCLATH is pointing to this Page (0) movwf PCLATH return ;Use Table_TVcode_to_TV1code TVcode_to_TV1code ; TV Remote commands ; Enter with code in W ;This code allows accessing a table anywhere in program memory movwf TEMPX movlw LOW Table_TVcode_to_TV1code ;Get low 8 bits of address addwf TEMPX,F ;Offset, do an 8-bit add operation movlw HIGH Table_TVcode_to_TV1code ;get high 5 bits of address btfsc STATUS,C ;Page crossed? addlw 1 ;Yes. Then increment high address movwf PCLATH ;load high address in latch movf TEMPX,W ;load computed Offset in W reg ; call Table_TVcode_to_TV1code movwf IRcode ;store IRcode ;calling Table on Page 3 movlw HIGH Keycode_to_TVcode ;Make sure PCLATH is pointing to this Page (0) movwf PCLATH return ; ******************* SHIFTs PRESSED ****************** ;-----sub------ ; Only FIN/SWE and US/UK modes can be selected AltModes btfsc MODE123on ; return if this is set return btfsc SYMBon ; return if this is set return btfsc CTRLon ; return if this is set return bcf PASTEon bcf ALTon ; Forget ALT btfss US_version ; US/UK mode already on? goto AltModes_1 ; No. Turn it on. bcf US_version ; Yes. Back to FIN/SWE mode. return AltModes_1 bsf US_version ; Set US/UK mode return ;-------------- abc123Pressed ;bit0 movlw d'61' call SendSpecKey bcf KBDasMOUSE ;Always clear this flag 'Keyboard as Mouse' operation btfsc ALTon ;Alt on? goto AltModes ;Alternative modes... ;btfss CTRLon ;Ctrl on? ;goto Braille mode... ;btfss SYMBon ;Symb on? ;goto btfss SHIFTon ;SHIFT on? goto abc123Pressed_a btfsc SHIFTlock ;But not SHIFT LOCK? goto abc123Pressed_a ;Yes. *** START KBDasMOUSE OPERATION *** bcf SHIFTon ;Clear SHIFT bcf PASTEon ;Clear pasting also movlw d'187' ;SHIFT OFF call SendSpecKey bsf KBDasMOUSE ;Flag 'Keyboard as Mouse' operation return ;goto MainLoop abc123Pressed_a btfss MODE123on ;123mode already on? goto Setabc123 ;No, set it. bcf MODE123on ;Yes, so clear it 123-abc=>0 ;bsf ABC123_LED ; Turn GKOS 123 LED OFF return ; goto MainLoop ; Setabc123 bsf MODE123on ;bcf ABC123_LED ; Turn GKOS 123 LED ON return ; goto MainLoop MenuPressed movlw d'121' call SendSpecKey call ClearModes return ; goto SendMenuKey ;--- SymbPressed ;bits2&1 10 / 11(LOCKED) movlw d'126' call SendSpecKey btfsc ALTon ;Alt on? goto WinKeyPressed ;Yes. System menu. ; bit4/bit3: SHIFT, 10=SHIFTon, 11=SHIFTlock btfss SHIFTon ;SHIFT on? goto SymbPressed_a btfsc SHIFTlock ;But not SHIFT LOCK? goto SymbPressed_a goto MenuPressed ;Yes, application menu. SymbPressed_a btfss SYMBon ;Symb already on? goto SetSymb ;No, set it. ; btfss SYMBlock ;Yes, Symb is on but is it LOCKED?. (11?) goto LockSymb ;It is not LOCKED. Go lock it. (01->11) bcf SYMBon ;Yes, LOCKED. Clear both Symb bits =>00 ;bsf SYMB_LED ; Turn GKOS SYMB LED OFF bcf SYMBlock ; return ; goto MainLoop ;(no need to send anything) SetSymb bsf SYMBon ;bcf SYMB_LED ; Turn GKOS SYMB LED ON return ; goto MainLoop LockSymb bsf SYMBlock return ; goto MainLoop WinKeyPressed movlw d'122' call SendSpecKey call ClearModes return ; goto SendWinKey ;--- ShiftPressed ;SHIFT: bits4&3 10 / 11 btfsc SHIFTlock ;SHIFT LOCK ON? goto ClearShiftLock ;Yes. Clear SHIFT LOCK. btfsc PASTEon ;Was Pasting on? goto ClearShift ;Yes. Clear SHIFT. btfss SHIFTon ;No. Shift already on? (x1?) goto SetShift ;No (x0), set it. ; bsf SHIFTon ;Yes. Set SHIFT LOCK. bsf SHIFTlock movlw d'187' ; SHIFT OFF call SendSpecKey movlw d'119' ; CAPS ON call SendSpecKey ;bcf CAPS_LED ; Turn GKOS CAPS LED ON ; call SendCapsMake ; Note that here inbetween, the LEDs will be turned on. ; call ByteIn ; receive LED order ; call SendACK ; call ByteIn ; receive LED status byte ; call SendACK ; call SendCapsBreak ;call SendShiftMake ;corresponds to press and release SHIFT key ;call SendShiftBreak ;send just Shift here return ; goto MainLoop ClearShift bcf PASTEon ;Clear pasting also! bcf SHIFTon bcf SHIFTlock movlw d'187' call SendSpecKey ;bsf CAPS_LED ; Turn GKOS CAPS LED OFF return ; goto MainLoop ClearShiftLock ;bsf CAPS_LED ; Turn GKOS CAPS LED OFF ; call SendCapsMake ; Note that here inbetween, the LEDs will be turned off. ; call ByteIn ; receive LED order ; call SendACK ; call ByteIn ; receive LED status byte ; call SendACK ; call SendCapsBreak bcf SHIFTon bcf SHIFTlock movlw d'247' call SendSpecKey ;bsf CAPS_LED ; Turn GKOS CAPS LED OFF return ; goto MainLoop SetShift bsf SHIFTon movlw d'59' call SendSpecKey return ; goto MainLoop ;--- CtrlPressed ;bit5 btfss CTRLon ;Ctrl on? goto SetCtrl ;No, set it. bcf CTRLon ;Yes, so clear it Ctrl=>00 movlw d'190' call SendSpecKey ; call SendCtrlMake ;corresponds to press and release Ctrl key ; call SendCtrlBreak ;SEND Ctrl here return ; goto MainLoop ; SetCtrl ; SYMB ON? If yes, start looking for a command ; [SYMB] [Ctrl] .......xxx [Enter] => xxx = command btfsc SYMBon ; Symb on? bsf CommandFlag ; Yes. Set Command Flag. Clear it after [Enter] ; No. btfsc SIRCS_MD_mode ; Remote control mode? bsf CommandFlag ; Yes. Set Command Flag. Clear it after [Enter] ; No. bsf CTRLon movlw d'62' call SendSpecKey return ; goto MainLoop ;--- AltPressed ;bit6 btfss ALTon ;Alt on? goto SetAlt ;No, set it. bcf ALTon ;Yes, so clear it Alt=>0 movlw d'191' call SendSpecKey ;call SendAltMake ;correponds to pres and release Alt key ;call SendAltBreak ;SEND Alt return ; goto MainLoop ; SetAlt bsf ALTon movlw d'63' call SendSpecKey return ; goto MainLoop ; bit0: abc-123 1=123, 0=abc ; bit2/bit1: SYMB, 10=SYMBon, 11=SYMBlock ; bit4/bit3: SHIFT, 10=SHIFTon, 11=SHIFTlock ; bit5: CTRL, 1=CTRLon - bit6: ALT, 1=ALTon ; bit7: Used for Paste On (it was reserved for CAPSLOCK or NUMLOCK) ClearModes ;clrf GKOSmode btfss CTRLon ; Ctrl on? goto CM_1X ; No, next. bcf CTRLon ; clear CTRL movlw d'190' call SendSpecKey CM_1X btfss ALTon ; Alt on? goto CM_2X ; No, next. bcf ALTon ; clear ALT movlw d'191' call SendSpecKey CM_2X btfsc SYMBlock ; SYMBlock on? goto CM_3X ; Yes, next. btfss SYMBon ; SYMB on? goto CM_3X ; No, next. bcf SYMBon ; Yes. Clear SYMBon. ;movlw d'126' ; SYMB pressed (=IR info) ;call SendSpecKey CM_3X ;bcf SYMBon ;No. ;bsf SYMB_LED ; Turn GKOS SYMB LED OFF btfsc SHIFTlock ;SHIFT lock on? return ;Yes. Continue and leave SHIFT LOCK on. ;No. Clear SHIFT unless arrows/words/PgUp&PgDn (pasting) btfss SHIFTon ;..but is SHIFT on?! return ;No. Might return as well... ;Yes SHIFT is ON: ;GKOSref: 42...53 are navigating except 50 and 46 (=space, backsp) ;PASTE function movlw d'42' ;Test if GKOSref is lower than 42 subwf GKOSref,W ;GKOSref - 42 btfss STATUS,C ;Note: C = complement of Borrow goto ClearModesX_C ;Yes, lower, clear SHIFT and exit ;No. not lower, might be pasting. movf GKOSref,W ;Test if higher than 53 sublw d'53' ; 53 - W (=GKOSref) btfss STATUS,C ;Note: C = complement of Borrow goto ClearModesX_C ;Yes, higher, clear SHIFT and exit ;test if 50 or 46 movlw d'50' xorwf GKOSref,W btfsc STATUS,Z ;equal? goto ClearModesX_C ;yes, exit and clear SHIFT movlw d'46' xorwf GKOSref,W btfsc STATUS,Z ;equal? goto ClearModesX_C ;yes, exit and clear SHIFT ;leave SHIFT ON (pasting) bsf PASTEon ;Yes. Leave SHIFT ON. Set Pasting on. Paste. return ClearModesX_C bcf SHIFTon ;Clear SHIFT if not pasting movlw d'187' call SendSpecKey return ;-------------------------------------------------------------- ; bit0: abc-123 1=123, 0=abc ; bit2/bit1: SYMB, 10=SYMBon, 11=SYMBlock ; bit4/bit3: SHIFT, 10=SHIFTon, 11=SHIFTlock ; bit5: CTRL, 1=CTRLon - bit6: ALT, 1=ALTon ; bit7: Used for Paste On (it was reserved for CAPSLOCK or NUMLOCK) ;********************* IR RECEPTION *********************************** CheckIR btfsc IRDATA ; IR Pulse there? TEST FOR ANY IR PULSE goto CheckIRX ; No. Exit. call ReadIRstart ; Yes. Is it a Start pulse? xorlw 0x00 ; Start pulse ok? bnz CheckIRX ; No. Exit. clrf IRByte1 ; Yes. Clear the first IR byte buffer call ReadIR6bits ; Receive 6 bits: --54 3210 (D5...D0) xorlw 0x00 ; 6 bits received ok? bnz CheckIRX ; No. Exit. movf TEMPX,w ; Yes. Save value. === IRByte1 === movwf IRByte1 ; clrf IRByte2 ; Clear rest of the IR byte buffers clrf IRByte3 clrf IRByte4 call ReadIR5bits ; Receive 5 bits: xxxa aadg (A2 A1 A0 1/0 toggle) 1=chord xorlw 0x00 ; 5 bits received ok? bnz CheckIRX ; No. Exit. ; ; IRByte1: --54 3210 (D5...D0) ; IRByte2: xxxa aadg (A2 A1 A0 1/0 toggle) ; ^ A2=0: Key code packet ; ... A2 A1 A0 1/0... ; 1 x x 0 ... Mouse packet ; 1 x x 1 ... Chord value packet ; ... 0 x x D7... Key code packet ;0 0 0 A2 A1 A0 D7 D6 The received IRByte2 ;0 0 D5 D4 D3 D2 D1 D0 The received IRByte1 ; 1 1 = default (of x x) movf TEMPX,w ; Yes. Save value. === IRByte2 === movwf IRByte2 ; (if 1/0 = 0, continue receiving mouse packet) ; ** Check if GKOS Key Code byte received bcf IRdevice,4 ; xxx0 aadg (A2 A1 A0 1/0 toggle) movf IRByte2,w ; While IRByte2 in W, check if device info is correct. andlw b'00011100' ; 000a aa00 = 0000 1100? (in IRByte2 for Key Code packet) xorwf IRdevice,w ; (IRdevice = 0001 1100 for chord or mouse packets) bnz CheckIR_1 ; If not, check for other GKOS IR packet formats (chord/mouse) ; Yes. This is GKOS Key Code packet. btfsc IRByte2,0 ; Move two bits from IRbyte2 to IRbyte1 bsf IRByte1,6 ; 0 0 0 A2 A1 A0 D7 D6 The received IRByte2 btfsc IRByte2,1 ; 0 0 D5 D4 D3 D2 D1 D0 The received IRByte1 bsf IRByte1,7 ; Now, IRByte1 is the GKOS Key Code byte bsf IRdevice,4 ; Change back the A2 bit in IRdevice retlw 0x08 ; KEY CODE data received OK EXIT. bit3=1 ; IRByte1 = 8-bit GKOS Key Code received by IR CheckIR_1 ; ** Check if GKOS Chord or Mouse data received bsf IRdevice,4 ; Change back the A2 bit in IRdevice movf IRByte2,w ; While IRByte2 in W, check if device info is correct. andlw b'00011100' ; 000a aa00 = 0001 1100? in IRByte2 xorwf IRdevice,w ; (IRdevice = 0001 1100 for chord or mouse packets) bnz CheckIRX btfss IRByte2,1 ; bit1=1? (1=chord IR packet) goto CheckIRMouse ; No. Continue by receiving mouse packet data. ; Yes. Chord value has been received OK. movf IRByte1,W ; Save Chord in param. RXchord movwf RXchord ; ;call ShowIRpackets ;debug retlw 0x01 ; CHORD value received OK EXIT => bit0=1 CheckIRMouse ; Two extra bits A3 and Z are received here for deciding ; whether XY movement (Z=0) or wheel data (Z=1)follows call ReadIRbit ; Read bit A3 (for future use) btfsc tempflags,0 ; Error in bit reception? goto CheckIRX ; Yes. IR bit error *** call ReadIRbit ; Read bit Z (0/1 = movement/wheel data indication) btfsc tempflags,0 ; Error in bit reception? goto CheckIRX ; Yes. IR bit error *** ;'1' => 1000 0000 in W (0x80) scroll wheel ;'0' => 0000 0000 in W (0x00) movement xorlw 0x80 ; Decide on movement or scroll wheel reception bz CheckIRscroll ; Receive Movement data ; ===================== call ReadIR8bits ; Receive 8 bits. X movement data. xorlw 0x00 ; 8 bits received ok? bnz CheckIRX ; No. Exit. movf TEMPX,w ; Yes. Save value. === IRByte3 === movwf IRByte3 ; call ReadIR8bits ; Receive 8 bits. Y movement data. xorlw 0x00 ; 8 bits received ok? bnz CheckIRX ; No. Exit. movf TEMPX,w ; Yes. Save value. === IRByte4 === movwf IRByte4 ; call CheckIRend ; Check that IR transmission has ended correctly xorlw 0x00 ; Silence after last IR data bits? bnz CheckIRX ; No. Error exit. CheckIRmovOK ;call ShowIRpackets ;debug retlw 0x02 ; MOVEMENT data received OK EXIT => bit1=1 ; Receive Scroll Wheel Data ; ========================= CheckIRscroll call ReadIR8bits ; Receive 8 bits. Wheel data. xorlw 0x00 ; 8 bits received ok? bnz CheckIRX ; No. Exit. movf TEMPX,w ; Yes. Save value. === IRByte3 === movwf IRByte3 ; call CheckIRend ; Check that IR transmission has ended correctly xorlw 0x00 ; Silence after last IR data bits? bnz CheckIRX ; No. Error exit. ;call ShowIRpackets ;debug retlw 0x04 ; SCROLL WHEEL data received OK EXIT. bit2=1 CheckIRX retlw 0x80 ;IR reception UNSUCCESSFUL EXIT => bit7=1 ;****************** IR TRANSMISSION ********************************* ; Start of SIRCS ; MD 0001000 11110 / GKOS: 000100 01111(0) = cccccc gdaaa(0) ; MD: 7 + 5 = 12 bits / GKOS: 6 + 5 = 11 bits. Received order: xxxa aadg ; GKOS: ; movlw b'00011100' ;Set the default IR device code in reverse order (xxxa aadg) ; movwf IRdevice ;Sending order: x x x A2 A1 A0 D7 D6; SIRCS spec: 01111 = MD ;D6=G (character toggle bit) ;D7=1 for keyboard and 0 for mouse. A0-A2 = device address ; xxxaaadg gdaaa gdaaa- ; b'00011110' => scope: 01111, ...011110 (=MD) gdaaa0 ; SIRCS set device to b'00001111' (MD) ; ^sending starts here, 5 bits sent: 11110 ;********************** SendSChord ; Send SIRCS info bits movf finalchord,w ; Sends finalchord through IR link SendSChord_W ;Enter here if only W contents will be sent movwf TEMPX ;TEMPX = byte to send (7 bits only, bit0 first) movlw d'7' movwf bitcounter ;set counter for 6 bits SendSChord_a btfss TEMPX,0 ;bit0=1? goto SendSChord_0 ;No call Send_1 ;Yes SEND '1' ;call Send40_1 ;Yes SEND '1' rrf TEMPX,f ;Next bit decfsz bitcounter,f ;All 7 bits sent? goto SendSChord_a ;No. return ;yes, return SendSChord_0 ;call Send_0 ;SEND '0' call Send40_0 rrf TEMPX,f ;Next bit decfsz bitcounter,f ;All 7 bits sent? goto SendSChord_a ;No. return ;Yes, return ;------------------- SendSDevice ; either 12-bit or 20-bit SIRCS frames btfss SIRCS20 ; is this SIRCS 20-bit frame? goto SendS12Device ; No ; Yes. SendS20Device ; For symbols, numbers and letters (ASCII), SIRCS 20-bit frames: ; Send SIRCS 13-bit Device information (+ 7 info bits = 20 bits) ; 0110 0001 1101 0010 0000 (LSB first) e.g.[space] = 010 0000 ; 5555 5333 aaaa addd dddd 7 data + 5 device + 8 device movlw d'5' ; N=5 aaaa a movwf bitcounter ; Set counter for 5 bits ;(the IR controlled device ID) movlw b'00011010' ; Use SIRCS device (SDEVICE) definition in IR TX movwf TEMPX ; 01011... (LSB first) call SendSDevice_a movlw d'8' ; N=8 0110 0001 movwf bitcounter ; Set counter for 8 bits ;(the IR controlled device ID) movlw b'01100001' ; Use SIRCS device (SDEVICE) definition in IR TX movwf TEMPX ; ...1000 0110... (LSB first) call SendSDevice_a return SendS12Device ;Send SIRCS 5-bit Device information movlw d'5' ; N=5 movwf bitcounter ; Set counter for 5 bits ;(the IR controlled device ID) movlw SDEVICE ; Use SIRCS device (SDEVICE) definition in IR TX movwf TEMPX ; 00001111 (LSB first) SendSDevice_a btfss TEMPX,0 ;bit0=1? goto SendSDevice_0 ;No ;call Send_1 ;Yes call Send40_1 ;Yes rrf TEMPX,f ;Next bit decfsz bitcounter,f ;All N bits sent? goto SendSDevice_a ;No. return ;yes, return SendSDevice_0 ;call Send_0 call Send40_0 rrf TEMPX,f ;Next bit decfsz bitcounter,f ;All N bits sent? goto SendSDevice_a ;No. return ;Yes, return ; End of SIRCS ;********************** ; ------------- GKOS BYTE ----------- ; Send GKOS IR BYTE info bits + address ; Sends just the Key Code through IR link, once ; Enter with keycode in W SendByte ;Enter here, W contents will be sent movwf TEMPX ;TEMPX = byte to send (bit0 first) movlw d'8' movwf bitcounter ;set counter for 8 bits (data byte) call SendChord_a return ; ------------- GKOS CHORD ---------- For compatibility with old GKOS IR receivers SendChord ; Send GKOS IR format info bits movf finalchord,w ; Sends finalchord through IR link SendChord_W ;Enter here if only W contents will be sent movwf TEMPX ;TEMPX = byte to send (6 bits only, bit0 first) movlw d'6' movwf bitcounter ;set counter for 6 bits SendChord_a btfss TEMPX,0 ;bit0=1? goto SendChord_0 ;No call Send_1 ;Yes SEND '1' rrf TEMPX,f ;Next bit decfsz bitcounter,f ;All 3/6/8 bits sent? goto SendChord_a ;No. return ;yes, return SendChord_0 call Send_0 ;SEND '0' rrf TEMPX,f ;Next bit decfsz bitcounter,f ;All 6/8 bits sent? goto SendChord_a ;No. return ;Yes, return ;------------------- SendDevice ;Send GKOS IR Device information ;(the IR controlled device ID) movlw DEVICE ; Use DEVICE definition in IR TX ;movf IRdevice,W ; IRdevice does not have the mouse/kbd bit defined movwf TEMPX movlw d'5' movwf bitcounter ;set counter for 5 bits SendDevice_a btfss TEMPX,0 ;bit0=1? goto SendDevice_0 ;No call Send_1 ;Yes rrf TEMPX,f ;Next bit decfsz bitcounter,f ;All 5 bits sent? goto SendDevice_a ;No. return ;yes, return SendDevice_0 call Send_0 rrf TEMPX,f ;Next bit decfsz bitcounter,f ;All 5 bits sent? goto SendDevice_a ;No. return ;Yes, return ;*************************** 40 kHz ************************************* SendStart40 ;gap T (550us), pulse 4T (2200us) bcf IRTXDATA call Delay40T ; 19 cycles per T -> 35.7kHz (19.5 => 36kHz) ; ; One cycle: 14us high + 14us low ; Cycle counter for 40 kHz: 40/36 x 78 = 86,6 = ca.87 movlw d'87' ;d'78' ;**<78<=Oscilloscope** ;set cycle counter to 4T = 4 x 19.5 = 78 movwf temp01 ;78 x 28us = 2184 (16us missing) goto SendPulse40 ;----------- Send40_1 ;gap T (550us), pulse 2T (1100us) bcf IRTXDATA call Delay40T ;19 cycles per T -> 35.7kHz ;One cycle: 14us high + 14us low ; cycle counter for 40 kHz: 40/36 x 43 = 47,8 = ca.48 movlw d'48' ;d'43';**<43<=Oscilloscope** ;set cycle counter to 2T = 2 x 19 = 38 movwf temp01 ;38 x 28us = 1064us (36us missing) goto SendPulse40 ;---------------------- Send40_0 ;gap T (550us), pulse T (550us) bcf IRTXDATA call Delay40T ;19 cycles per T -> 35.7kHz ;One cycle: 14us high + 14us low ; Cycle counter for 40 kHz: 40/36 x 22 = 24,4 = ca.24 Delay d'11' ;'10' ;the missing 18us - 8us for program lines calling movlw d'25' ;d'22';**<22<=Oscilloscope** ;set cycle counter to T = 1 x 19 = 19 movwf temp01 ;19 x 28us = 532us (18us missing) goto SendPulse40 ;----------------------- ; This sets the Carrier Frequency! Adjusted by Oscilloscope. Do not change! ; temp01 sets pulse length (d'??' gives SIRCS pulse length) SendPulse40 ;Common procedure to send n cycles (n = temp01) bsf IRTXDATA ;1 Delay 0x0c ;0x0d; **0x0d>14us<=Oscilloscope** 13 ;1+13 = 14us bcf IRTXDATA ;1 Delay 0x08 ;0x0a; **0x0a>14us<=Oscilloscope** ;>14us; ;1+11 decfsz temp01,f ;1+1+11 goto SendPulse40 ;1+1+1+11 = 14us return ;*************************** 36 kHz ************************************* SendStart ;gap T (550us), pulse 4T (2200us) bcf IRTXDATA call DelayT ;19 cycles per T -> 35.7kHz (19.5 => 36kHz) ;One cycle: 14us high + 14us low movlw d'78' ;**<78<=Oscilloscope** ;set cycle counter to 4T = 4 x 19.5 = 78 movwf temp01 ;78 x 28us = 2184 (16us missing) goto SendPulse ;----------- Send_1 ;gap T (550us), pulse 2T (1100us) bcf IRTXDATA call DelayT ;19 cycles per T -> 35.7kHz ;One cycle: 14us high + 14us low movlw d'43';**<43<=Oscilloscope** ;set cycle counter to 2T = 2 x 19 = 38 movwf temp01 ;38 x 28us = 1064us (36us missing) goto SendPulse ;---------------------- Send_0 ;gap T (550us), pulse T (550us) bcf IRTXDATA call DelayT ;19 cycles per T -> 35.7kHz ;One cycle: 14us high + 14us low Delay d'10' ;the missing 18us - 8us for program lines calling movlw d'22';**<22<=Oscilloscope** ;set cycle counter to T = 1 x 19 = 19 movwf temp01 ;19 x 28us = 532us (18us missing) goto SendPulse ;----------------------- ; This sets the Carrier Frequency! Adjusted by Oscilloscope. Do not change! ; temp01 sets pulse length (d'43' gives SIRCS pulse length) SendPulse ;Common procedure to send n cycles (n = temp01) bsf IRTXDATA ;1 Delay 0x0d; **0x0d>14us<=Oscilloscope** 13 ;1+13 = 14us bcf IRTXDATA ;1 Delay 0x0a; **0x0a>14us<=Oscilloscope** ;>14us; ;1+11 decfsz temp01,f ;1+1+11 goto SendPulse ;1+1+1+11 = 14us return ;******************************************************************* DelayT ;GKOS IR pulse Basic time period T = 550us Delay d'200' Delay d'200' Delay d'150';<150 return Delay40T ;SIRCS 40 kHz IR pulse Basic time period T = 550us Delay d'200' Delay d'200' Delay d'160' return ;DelayTplus ;IR pulse data bit check period = 825us ; Delay d'200' ; Delay d'200' ; Delay d'200' ; Delay d'200' ; Delay d'25' ; return ;**************************************************************** ;SendIRPause24 ;Pause between chord packets = 24ms ; bcf IRTXDATA ; movlw d'24' ; call DelayWx1ms ; return ;------ ;------------------------------------------------------------------- ; TV1 (ASA) ;------------------------------------------------------------------- ; ; Phase shift keying, 36kHz carrier (||||) pulses (= bursts) ; 1 = half cycle of 2kHz (pulse or pause) ; 0 = one cycle of 1kHz (pulse+pause or pause+pulse) ; |||_________________||______||__||||__||____||__|| ; ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^1^ ^0^ ^1^ ^0^ ^1^ ^0^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ;0.5ms 3ms 0.5ms ;---------------------------------------------------------------------- ; This is the IR frame for an ASA television TestW ;<< 0.5ms, 35 => 1.0ms, 108 => 3.0ms ; ;_____________|||||||||||||________________|||||||||||||____________ ; Pause Pulse Pause Pulse Pause SendPauseW ; Pause value in W (2us + W x 28us) ; W=35 => 0.9804ms (+ other delays 20us = 1.0ms) ; W=17 => 0.4762ms (+ other delays 24us = 0.5ms) movwf temp01 ; 1us SendPauseW_1 ; (Same delays as in SendPulseW) bcf IRTXDATA ;1, Turn OFF IR LED Delay 0x0d ;1+13 nop ;14+1 Delay 0x0a ;15+10 decfsz temp01,f ;25+1 goto SendPauseW_1 ;+2 = 28us x W return ; 1us ;---------- SendPulseW ; Common procedure to send W cycles of 36kHz (35,7kHz) ; W=35 => 0.9804ms (+ other delays 20us = 1.0ms) ; W=17 => 0.4762ms (+ other delays 24us = 0.5ms) movwf temp01 ; 1us SendPulseW_1 ; This sets the carrier frequency!!! (35,7kHz = ca.36kHz) bsf IRTXDATA ;1 Delay 0x0d ; <=Oscilloscope** 13 ;1+13 = 14 bcf IRTXDATA ;14+ 1 Delay 0x0a ; <=Oscilloscope** ; 15+10 decfsz temp01,f ;25+1 goto SendPulseW_1 ;+2 = 28us x W return ; 1us ;------------------------------------------------ ;SendPulse40W ; Common procedure to send W cycles of 40kHz ; ; W=39 => (0.9750ms) (+ other delays 20us = 1.0ms) 30 ; ; W=19 => (0.4750ms) (+ other delays 24us = 0.5ms) 19/20 ; ; sum = 1.450ms ; 0.475+0.5=0.975 (+25) Pulse=19, Pause=20 ; ; 0.975+0.5=1.475 ; movwf temp01 ; 1us ; 40kH carrier: (1/0.028 = 35,7; 1/0.025 = 40kHz, 3 cycles less) ;SendPulse40W_1 ; This sets the carrier frequency!!! (35,7kHz = ca.36kHz) ; bsf IRTXDATA ;1 ; Delay 0x0c; 0x0d ; 13 ;1+13 = 14 (14 => 13) ; bcf IRTXDATA ;14+ 1 ; Delay 0x08 ;0x0a ; 15+10 ; decfsz temp01,f ;25+1 ; goto SendPulse40W_1 ;+2 = 28us x W (14 => 12) ; return ; 1us ; ;------------------------------------------------ ;----------------------------------- ; IrDA: ;----------------------------------- Send_IRDA ; Send one IrDA frame of 10 bits (0 + 8 data bits + 1) ; Byte to send is in W movwf TEMPX call Send_0i ; Send START BIT (= '0') ;movf finalchord,w ; Send 8 info bits ;movwf TEMPX ; TEMPX = byte to send (6 bits only, bit0 first) movlw d'8' ; 8 data bits to send movwf bitcounter ; set counter for 8; 6 bits Send_IRDA_a btfss TEMPX,0 ;bit0=1? goto Send_IRDA_0 ;No call Send_1i ;Yes SEND '1' rrf TEMPX,f ;Next bit decfsz bitcounter,f ;All 8 bits sent? goto Send_IRDA_a ;No. call Send_1i ; SEND STOP BIT (= '1') return ;yes, return Send_IRDA_0 call Send_0i ;SEND '0' rrf TEMPX,f ;Next bit decfsz bitcounter,f ;All 8 bits sent? goto Send_IRDA_a ; No. ; Yes. call Send_1i ; SEND STOP BIT (= '1') return ;---------------------- Send_1i ; Send no Pulse, 1/1 bit time (0,0001042s = 0,1042 ms = 104,2us) bcf IRTXDATA Delay d'95' ; 104us pause (bit time 1/9600 = 0,000104167 = 104,167us) return ; (subtract 7 + 2 command lines per bit) ;---------------------- Send_0i ; Send a Pulse, 3/16 bit time (19,5us) + no pulse 13/16 (84,66us) bit time bsf IRTXDATA Delay d'20' ; 20us pulse bcf IRTXDATA Delay d'74' ; 84us pause (subtract 7 + 3 command lines per bit) return ;----------------------- ;************************* END OF IR RX & TX ********************************** ;======================= GKOS & Mouse SUBROUTINES ====================== ;----- ; WIRED GKOS SCANNING ; =================== ReadGKOSchord ;-LATEST KEY POLLING ROUTINE- 4/2004 ; This can use the same enhanced chord ; detection routines as with IR reception clrf maxchord ; Default: no chord clrf RXchord ; Default: no chord bcf GKOSstatus,0 ; Default: chord received indicator bit0 = 0 decfsz GKOScounter1,f ; Too soon to re-scan? return ; Yes, no scan yet. movlw GKOSdelay ; No. It may be time to scan. movwf GKOScounter1 ; Initialize counter. decfsz GKOScounter2,f ; Too soon to re-scan? return ; Yes, no scan yet. movlw GKOSdelay ; No. It's be time to scan now. movwf GKOScounter2 ; Initialize counter. ;----- NEW CODE to use the same key polling procedure as with IR reception movf PORTB,W ; Read GKOS Chord into param. chord xorlw 0xFF ; invert bits (pull-up function) andlw b'00111111' ; clear RB7 & RB6 positions movwf chord ; store chord pressed at the moment movwf maxchord ; save chord for re-check movlw 0x00 ; Is it zero (no keys down at the moment) xorwf chord,W ; btfss STATUS,Z ; chord equal to 0? goto ReadGKOSchord_1 ; No. ; Yes. bsf ZeroChordWR ; For : Zero chord ; Send 32 (was 5) zero chords after release of keys due to enhanced key polling clrf RXchord ; Indicate zero in RXchord too incf ZeroChords,f ; Zero Chord counter (5...0) decfsz ZeroChords,f ; was it zero already? btfsc STATUS,Z ; ZeroChord counter Equal to 0? return ; Yes. Exit right away. All GKOS keys are up. ; No. decf ZeroChords,f ; Decrement counter and send a Zero Chord. goto ReadGKOSchord_1b ; Non-zero chord value received ReadGKOSchord_1 bcf ZeroChordWR ; For : Non-zero chord bcf AKUSent_WR ; Set default: AKU not sent for the next wired kbd Zero Chord. movlw d'32' ; Initialize Zero Chord counter ;movlw d'5' ; Initialize Zero Chord counter movwf ZeroChords ; when non-zero chords are detected ReadGKOSchord_1b movf chord,w movwf RXchord ; Save the chord as parameter RXchord bsf GKOSstatus,0 ; Chord received indicator bit0 = 1 return ;------------------------------------------------------------------------------ ; IR RECEPTION ; ============ ReadIRstart ;Sony Format (SIRCS) ;IR data formats. SIRCS spec: 01111 = MD ;MD 0001000 11110 / GKOS: 000100 01111(0) = cccccc gdaaa(0) Check at 0.825ms: high=>'0', low=>'1' ;then wait for no pulse (high) and again for a pulse, ;7 bits (chord value) + 5 bits (device = 00010, Betamax) ;(Timing: 275/550/825/1100) ; ___ ;_________/ pulse =0 / no pulse =1 ; ^ ====================== ReadIRstart_b ;=Wait for no pulse= btfss IRDATA ;Low? (=pulse?) goto ReadIRstart_b ;Yes. Still wait... PULL-UPs required else FREEZING HERE ;No. The Start Pulse has reached the end. Line is high. ; ___ _____ ;_________/ \___/___\_ pulse =0 / no pulse =1 ; ^ |--first bit Delay d'275' ; Wait until middle of the first gap to match timing ahead bsf TESTPOINT ;--TP: high (no burst) ; ___ _____ ;_________/ \___/___\_ pulse =0 / no pulse =1 ; ^ |--first bit retlw 0x00 ;SUCCESSFUL RETURN W=0x00 ****** ;------------------- ;---IR Receive 8 bits ReadIR8bits clrf TEMPX ;Clear register for byte reception movlw d'8' ;Set Counter (temp_b) to 6 (bits), GKOS Chord value movwf temp_b ReadIR8bits_a rrf TEMPX,f ;rotate right bcf TEMPX,7 ;Make sure bit7=0 call ReadIRbit ;Read one bit into W (b000 0000) btfsc tempflags,0 ;Error in bit reception? retlw 0xEE ;Yes. *** ERROR RETURN W=0xEE *** addwf TEMPX,f ;No, add the received bit to the byte decfsz temp_b,f ;All 8 bits received? goto ReadIR8bits_a ;No. ;Yes. movf TEMPX,w ; ;movf TEMPX,w ;debug ;call SerTx ;debug retlw 0x00 ;SUCCESSFUL RETURN W=0x00, bits in TEMPX: 7654 3210 ;-------- ;--IR receive 7 bits ReadIR7bits clrf TEMPX ;Clear register for byte reception movlw d'7' ;Set Counter (temp_b) to 7 (bits), GKOS Chord value movwf temp_b ReadIR7bits_a call ReadIRbit ;Read one bit into W (b000 0000) btfsc tempflags,0 ;Error in bit reception? retlw 0xEE ;Yes. *** ERROR RETURN W=0xEE *** addwf TEMPX,f ;No, add the received bit to the byte rrf TEMPX,f ;rotate right bcf TEMPX,7 ;Make sure bit7=0 decfsz temp_b,f ;All 7 bits received? goto ReadIR7bits_a ;No. ;Yes. movf TEMPX,w ; ;movf TEMPX,w ;debug ;call SerTx ;debug retlw 0x00 ;SUCCESSFUL RETURN W=0x00, bits in TEMPX: -654 3210 ;------- ;---IR Receive 6 bits ReadIR6bits clrf TEMPX ;Clear register for byte reception movlw d'6' ;Set Counter (temp_b) to 6 (bits), GKOS Chord value movwf temp_b ReadIR6bits_a call ReadIRbit ;Read one bit into W (b000 0000) btfsc tempflags,0 ;Error in bit reception? retlw 0xEE ;Yes. *** ERROR RETURN W=0xEE *** addwf TEMPX,f ;No, add the received bit to the byte rrf TEMPX,f ;rotate right bcf TEMPX,7 ;Make sure bit7=0 decfsz temp_b,f ;All 6 bits received? goto ReadIR6bits_a ;No. ;Yes. One more shift (6 bits of data) rrf TEMPX,f ;rotate right bcf TEMPX,7 ;Make sure bit7=0 movf TEMPX,w ; ;movf TEMPX,w ;debug ;call SerTx ;debug retlw 0x00 ;SUCCESSFUL RETURN W=0x00, bits in TEMPX: --54 3210 ;------- ;---IR Receive 5 bits ReadIR5bits ;Receive the Toggle bit G (=D7) and Device information part correctly clrf TEMPX ;Clear register for byte reception movlw d'5' ;Set Counter (temp_b) to 5 (bits), Device info movwf temp_b ReadIR5bits_a call ReadIRbit ;Read one bit into W (b000 0000) btfsc tempflags,0 ;Error in bit reception? retlw 0xEE ;Yes. *** ERROR RETURN W=0xEE *** addwf TEMPX,f ;No, add the received bit to the byte rrf TEMPX,f ;rotate right bcf TEMPX,7 ;Make sure bit7=0 decfsz temp_b,f ;All 5 bits received? goto ReadIR5bits_a ;No. ;Yes. Two more shifts (5 bits of data) rrf TEMPX,f ;rotate right bcf TEMPX,7 ;Make sure bit7=0 rrf TEMPX,f ;rotate right bcf TEMPX,7 ;Make sure bit7=0 movf TEMPX,w ; ;movf TEMPX,w ;debug ;call SerTx ;debug retlw 0x00 ;SUCCESSFUL RETURN W=0x00, bits in TEMPX: ---4 3210 ;--------- ;--------- ReadIRbit bcf tempflags,0 ;Set flag: Default = 0 = Success ;low = IR pulse, high = no IR ; ___ ___ ;___/ \___/ \___/ ; |---0---| ; ___ ___ ;___/ \_______/ \___/ ; |-----1-----| ; ^decide here if 0 or 1 ; ; Starting points: ;low = IR pulse, high = no IR ; ___ ;___/ ; ^ after Start Pulse or '0' ; ___ ;___/ ; ^ after '1' ;Make sure there is no pulse first ; Make sure not to have to wait too long (it would be a reception error) ; - max 375us (>275us) - (if previous bit was a '1', else it is no pulse already) movlw d'29' ;Number of 13us loops: 29 x 13us = 377us (gap = 0,550ms) movwf temp_a ;Set counter to around 375us (375us/13us = 29) ReadIRbitNP btfsc IRDATA ;Pulse (line low) still there? 1us goto ReadIRbitNX ;No. No more pulse. Delay d'10' ;Yes, ... loop back. 10us decfsz temp_a,f ;No. Counter=0? 1us goto ReadIRbitNP ;No. 1us => 13us bsf tempflags,0 ;Yes. Timeout. Flag the error return ;This is an ERROR return. No end of IR pulse found. ReadIRbitNX ; Wait for a new pulse (low), then wait 825 us and check state (low='1', hight='0') ;No more pulse. Line high now. bsf TESTPOINT ;--TP: no burst (high) ;movlw d'100' ;Number of 10us loops: 100 x 10us = 1ms (gap = 0,550ms) movlw d'54' ;Number of 13us loops: 54 x 13us = 702us (gap = 0,550ms) movwf temp_a ;Set counter to around 700us (700us/13us = 54) ReadIRbit_a ;low = IR pulse, high = no IR ; ___ ;___/ \_ ; ^ ; Wait for IR pulse (low) to start ; Make sure not to have to wait too long (it would be a reception error) ; max - 700us - Delay d'10' ;Check it every 10us 10us btfss IRDATA ;Any pulse (low) appearing there? 1us goto ReadIRbit_b ;Yes! Data bit starting... decfsz temp_a,f ;No. Counter=0? 1us goto ReadIRbit_a ;No. 1us => 13us bsf tempflags,0 ;Yes. Timeout. Flag the error return ; This is an ERROR return. IR pulse start missing. ReadIRbit_b ; ___ ___ ;___/ \___/___ ; ^ ; |-----> ; 825us (delay counter value = 70) bcf TESTPOINT ;--TP: burst (low) ; Wait 825us and check IR data line state ----------- movlw d'70' ; Number of 10us's to wait (4 MHz XT OSC) ; 70 = Oscilloscope-adjusted value using TESTPOINT movwf temp_a ;Set counter ReadIRbit_bb Delay d'10' ; Wait 10us each time 10us decfsz temp_a,f ; Counter=0? (70 => 0) 1us + 1us goto ReadIRbit_bb ; No. loop back 70 x 12us = 840us ; Yes. bsf TESTPOINT ;--TP: no burst (high) to test reading time point btfss IRDATA ; Pulse(=low) ended? => '0' goto ReadIRbit_1 ; No. '1' received retlw 0x00 ; Yes. '0' received ; ___ ___ ;___/ \___/ \___ ; |-------| ; ^test=>'0' (Timing: 275/550/825/1100) ReadIRbit_1 ;'1' => 1000 0000 in W (0x80) retlw 0x80 ;'0' => 0000 0000 in W (0x00) ; ___ ___ ;___/ \_______/ \___ ; |-----------| ; ^test=>'1' ;********************* ; Make sure the transmission ends (checked after mouse data) ; Low = IR pulse CheckIRend ;=Wait for ending of last pulse= btfss IRDATA ;Low? (=pulse?) goto CheckIRend ;Yes. Still wait... PULL-UPs required else FREEZING HERE ;No. The last IR pulse has reached the end. Line is high. ; ___ _____ ;_________/ \___/___\_ pulse =0 / no pulse =1 ; ^ |--first extra bit will start here latest ; | | | | ; 0 0.55 1.1 1.65ms ; Check that there are no more IR pulses during 1.1 ms after end of the last pulse movlw d'84' ; Number of 13us loops: 84 x 13us = 1092us (gap = 1.1 ms) movwf temp_a ; Set counter to around 1100us (1100us/13us = 84) ; 1650us/13us = 126 ReadIRendNP btfss IRDATA ; Silence (line up) still there? 1us goto ReadIRendNX ; No, a pulse was found! Delay d'10' ; Yes, silence... loop back. 10us decfsz temp_a,f ; Counter=0? 1us goto ReadIRendNP ; No. 1us => 13us retlw 0x00 ; Yes. This OK return. No more IR pulses found. ReadIRendNX ;bsf tempflags,0 ; Flag the error (this flag may not be needed) retlw 0xEE ; ERROR return. There are still IR pulses after the end of transm. ;--------------------------------------------------------------------------------------------- ;PS/2 Keyboard Byte Transmission ByteOut ; FUNCTION DELETED return ;********************* ;PS/2 Keyboard Byte Reception ; FUNCTION DELETED ByteIn0 return ByteIn return ByteIn1 return ;==================== PS/2 MOUSE COMMUNICATIONS: ;--------------------------------------------------------------------------------------------- ; PS/2 Mouse Byte Transmission ; FUNCTION DELETED ; MByteOut ; This is on Page 1 now (UART used)! ; return ;*************************************************** ;PS/2 Mouse Byte Reception ; FUNCTION DELETED ;MByteIn0 ; return ;MByteIn ; return ;MByteIn1 return ;======================= COMMON SUBROUTINES =============================== DelayWx10ms movwf dcount1 ; dcount1 = W movlw 0x64 movwf dcount2 movlw 0x20 movwf dcount3 decfsz dcount3,F ; delay of > ((((3 * dcount3)+3)*dcount2)+3*W) goto $ - 1 ; * instruction cycle time (1us for 4MHz) decfsz dcount2,F goto $ - 5 ; so currently W x 10ms decfsz dcount1,F goto $ - 9 return ;********************* ; Delays 4w+4 cycles (including call,return, and movlw) (0=256) Delay_Routine addlw -1 ;Precise delays used in I/O btfss STATUS, Z goto Delay_Routine return ;********************* DelayWx1ms movwf dcount1 ; dcount1 = W movlw 0x0a movwf dcount2 movlw 0x20 movwf dcount3 decfsz dcount3,F ; delay of > ((((3 * dcount3)+3)*dcount2)+3*W) goto $ - 1 ; * instruction cycle time (1us for 4MHz) decfsz dcount2,F goto $ - 5 ; so currently W x 1ms decfsz dcount1,F goto $ - 9 return ;******************************************************************* ; INIT_UART - Initialises UART ; Enables COM Port receiver and transmitter ; Make sure to be at Bank 0 INIT_UART ;Page 357 of 33023a.pdf (PIC Manual): BSF STATUS, RP0 ; Go to Bank1 ; =========== MOVLW d'25' ; Set Baud Rate to 9600 (BRGH=1) or 2400 (BRGH=0) MOVWF SPBRG ; 7 6 5 4 3 2 1 0 ;TXSTA: CSRC TX9 TXEN SYNC - BRGH TRMT TX9D ; TXEN= Transmit Enable bit ; BRGH= High Baud Rate Select bit (1= High speed) ;RCSTA: SPEN RX9 SREN CREN - FERR OERR RX9D ; SPEN= serial Port Enable bit ; CREN= Continuous Receive Enable bit MOVLW 0x24 ; 8-bit transmit, transmitter enabled, BRGH=1 MOVWF TXSTA ; Asynchronous mode, high speed mode ;BSF PIE1, TXIE ; Enable transmit interrupts ;BSF PIE1, RCIE ; Enable receive interrupts BCF STATUS, RP0 ; Go to Bank 0 ; ============ MOVLW 0x80 ; (8-bit receive, receive enabled > 0x90) MOVWF RCSTA ; Just Serial Port enabled > 0x80 ;----- ;*** UART Transmission - write to reg. 19h TXREG (Bank 0) ; enable recevier ;MOVLW (1< 0x00 - 0x0f ; 0x10 - 0x1f ; sp! " # $ % & ' 0x20 - 0x27 ; ( ) * + , - . / 0x28 - 0x2f ; 0 1 2... 9 0x30 - 0x39 ; : ; < = > ? 0x3a - 0x3f ; @ A B C ... O 0x40 - 0x4f ; P Q R S ... Z 0x50 - 0x5a ; [ ] ^ _ 0x5b - 0x5f ; ` a b c ... o 0x60 - 0x6f ; p q r s ... z 0x70 - 0x7a ; { | } -> <- 0x7b - 0x7f ; 0xdb ; ä 0xe1 ; ü 0xf5 ; ö 0xff ; ; ;---------------- ; ASCII CODES: ;000 (nul) 016 (dle) 032 sp 048 0 064 @ 080 P 096 ` 112 p ;001 (soh) 017 (dc1) 033 ! 049 1 065 A 081 Q 097 a 113 q ;002 (stx) 018 (dc2) 034 " 050 2 066 B 082 R 098 b 114 r ;003 (etx) 019 (dc3) 035 # 051 3 067 C 083 S 099 c 115 s ;004 (eot) 020 (dc4) 036 $ 052 4 068 D 084 T 100 d 116 t ;005 (enq) 021 (nak) 037 % 053 5 069 E 085 U 101 e 117 u ;006 (ack) 022 (syn) 038 & 054 6 070 F 086 V 102 f 118 v ;007 (bel) 023 (etb) 039 ' 055 7 071 G 087 W 103 g 119 w ;008 (bs) 024 (can) 040 ( 056 8 072 H 088 X 104 h 120 x ;009 (tab) 025 (em) 041 ) 057 9 073 I 089 Y 105 i 121 y ;010 (lf) 026 (eof) 042 * 058 : 074 J 090 Z 106 j 122 z ;011 (vt) 027 (esc) 043 + 059 ; 075 K 091 [ 107 k 123 { ;012 (np) 028 (fs) 044 , 060 < 076 L 092 108 l 124 | ;013 (cr) 029 (gs) 045 - 061 = 077 M 093 ] 109 m 125 } ;014 (so) 030 (rs) 046 . 062 > 078 N 094 ^ 110 n 126 ~ ;015 (si) 031 (us) 047 / 063 ? 079 O 095 _ 111 o 127 (del) ShowIRpackets movf IRByte1,w ; call SerTx ; movf IRByte2,w ; call SerTx ; movf IRByte3,w ; call SerTx ; movf IRByte4,w ; call SerTx ; movlw d'219' ; end sign call SerTx ; return ;******************************************************************************** SLEEP_loop decfsz SLEEPcnt1,f ; return movlw d'255' movwf SLEEPcnt1 decfsz SLEEPcnt2,f ; return ; movlw d'255' movwf SLEEPcnt2 decfsz SLEEPcnt3,f ; return movlw SLEEPdelay ; This defines the ilde time before going to sleep movwf SLEEPcnt3 ; 1 => 3 seconds ; decfsz SLEEPcnt3,f ; return ; Clear all lines to LCD ; - bus lines are in input state already bcf LCD_RS bcf LCD_RW bcf LCD_E ;bcf LCD_power ; turn off LCD and IR receiver power ; let IR input settle before sleep movlw d'255' ;1/4 sec DELAY call DelayWx1ms movlw d'255' ;1/4 sec DELAY call DelayWx1ms ; Define RB6 as output for sleep period because ; it is pulled low by the IR receiver and would ; cause the wakeup. bsf STATUS,RP0 ; change to Register bank 1 bcf STATUS,RP1 ; =============== movlw b'00111111' ; binary value, 1 bit per port bit movwf TRISB ; RB0-RB6 set to digital inputs, GKOS keys + IR data in bcf STATUS,RP0 ; change back to Register bank 0 ; =============== ; bcf PORTB,6 ; Pin RB6 = 0 (same as IR data from IR receiver) movlw d'255' ;1/4 sec DELAY call DelayWx1ms movlw d'255' ;1/4 sec DELAY call DelayWx1ms movlw d'255' ;1/4 sec DELAY call DelayWx1ms movlw d'255' ;1/4 sec DELAY call DelayWx1ms bcf INTCON, RBIF ; Clear Port B interrupt flag (just to make sure) ;bcf ADCON0,ADON ; turn off D/A converter to save power SLEEP nop ; *** ROUTINES for wakeup: ; Change 'IR data in' back to input bsf STATUS,RP0 ; change to Register bank 1 bcf STATUS,RP1 ; =============== movlw b'01111111' ; binary value, 1 bit per port bit movwf TRISB ; RB0-RB6 set to digital inputs, GKOS keys + IR data in bcf STATUS,RP0 ; change back to Register bank 0 ; =============== ; Read port RB movf PORTB,W ; Read GKOS chord into W ; Clear flag bit RBIF bcf INTCON, RBIF ; ; *** ;bsf LCD_power ; turn back on LCD power ; Delay 1s for key release (4 x 255ms) ;bsf ADCON0,ADON ; turn back on D/A converter movlw d'255' ;1/4 sec DELAY call DelayWx1ms ; call SetMouseBias ; Initialize TrackPoint mouse bias voltage ; to provide 1.8V at Yin when mouse is idle ; INITIALIZE LCD ; parameters bcf LCD_E clrf CommandBuffer0 ; Clear IR mode command buffers clrf CommandBuffer1 ; ... ;clrf CommandBuffer2 ; ... ;bcf LCD_edge ; Display window edge not passed. ;bsf LCD_power ; Turn on LCD and IR receiver power ; Wait 1 seconds for the LCD to start ;movlw d'100' ;call DelayWx10ms ;movlw HIGH LCD_set ; Get high 5 bits of address ;movwf PCLATH ; Next Page... ;call LCD_set ; Init procedure ;movlw HIGH SLEEP_loop ; Make sure PCLATH is pointing to this Page (0) ;movwf PCLATH movlw d'255' ;1/4 sec DELAY call DelayWx1ms return ;=== KEYBOARD AS MOUSE operation ==== ; FUNCTION DELETED ;KeyboardMouse ; it is now on Page 1 ; return ;******************************************************************************** ;===END OF SUBROUTINES=== ;mmmmmmm ;=====================================================================================; ;_____________________ Page1 0800h-0FFFh More Program code____________________________; ; PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP11111111111111111111111111111111111111111111111 org 0x800 ; Start of program memory page 1 ;------------------------------------------------------------------------------------- ; This is for check-back timer monitoring SerTx2 RETURN ; DISABLE THIS DEBUG FUNCTION SerTxM ; This sends Mouse data via UART (KeyboardMouse) btfss PIR1, TXIF ; check if ready goto $-1 movwf TXREG ; transmit byte return TestUART ;Send text 'GKOS' and a carriage return movlw d'71' ;0x47 ;'G' call SerTx2 movlw d'75' ;0x4B ;'K' call SerTx2 movlw d'79' ;0x4F ;'O' call SerTx2 movlw d'83' ;0x53 ;'S' call SerTx2 movlw d'13' ;0x0D ; call SerTx2 return ClearAutorepeat ; Mouse simulation? ; Keyboard/mouse delay movlw TDelay ; Initialize Toggle counter because chord = 0. btfsc KBDasMOUSE ; Is Keyboard operating as mouse (mouse simulation)? movlw MTDelay ; Yes. Use a different delay value. movwf ToggleCounter ; No. Use the kbd delay value as planned. bcf AutoRepeat ; clear autorepeat indication movlw HIGH ClearModes ; Get high 5 bits of address movwf PCLATH ; Previous Page... call ClearModes ; clear SYMB, Alt etc. movlw HIGH GetChordParams ;Make sure PCLATH is pointing to this Page (1) movwf PCLATH return ;======================================================================================= ; START OF The intelligent keyboard scanning procedure ;======================================================================================= ; BETTER WAY OF POLLING KEYBOARD STATUS received from IR and wired GKOS keyboard ; xxxxxxx (<= to find this point by search) GetChordParams bcf RXchordREADY ; Default: Tell GKOSloop that no output shall not be made ;movf PrevChord2,w ; Get the chord (may be NUL sometimes!) 2 steps back movf Downs,w ; Get the chord = PrevChord1 AND PrevChord2 (may be NUL!) movwf RXfinalchord ; update IR final chord ****THE CHORD TO SEND**** ; Zero cord? incf RXchord,f ; RXchord = 0? decfsz RXchord,f goto GCP1 ; No. goto GCP2 ; Yes. ; Repeated chords? GCP1 ; For AUTOREPEAT, check if previous chord is equal (<>0) movf RXchord,w movwf Temp movf PrevChord1,w subwf Temp,w btfss STATUS,2 ; Z=1?, Equal? goto UCP0 ; No. ; Yes. ; Autorepeat? decfsz ToggleCounter,f ; Toggle counter reached zero? goto UCP0 ; No. incf ToggleCounter,f ; Yes. Leave as it was. bsf RXchordREADY ; Indicate that char will be output in any case bsf AutoRepeat ; set autorepeat indication bcf TextOnly ; Repeat any character goto UCP0_1 GCP2 ; RXchord = 0 ; Update Key down Timer for each key (decreasing values) UCP0 ; Previous chord is not equal (RXchord<>PrevChord1) btfsc AutoRepeat ; Autorepeat on? call ClearAutorepeat ; Yes. Turn it off. UCP0_1 btfss RXchord,0 ; Chord bit0 = 1? goto UCP1 ; No. Go on with the next chord bit. incf KeyTime0,f ; add 1 in order to set key counter to 1 if 0 decfsz KeyTime0,f ; Decrement key time counter (127...0 !), Zero? decf KeyTime0,f ; Not zero. Decrement if not zero in the beginning ; Zero. The key has been down long. Do not decrement. UCP1 btfss RXchord,1 ; Chord bit1 = 1? goto UCP2 ; No. Go on with the next chord bit. incf KeyTime1,f ; add 1 in order to set key counter to 1 if 0 decfsz KeyTime1,f ; Decrement key time counter (127...0 !), Zero? decf KeyTime1,f ; Not zero. Decrement if not zero in the beginning ; Zero. The key has been down long. Do not decrement. UCP2 btfss RXchord,2 ; Chord bit2 = 1? goto UCP3 ; No. Go on with the next chord bit. incf KeyTime2,f ; add 1 in order to set key counter to 1 if 0 decfsz KeyTime2,f ; Decrement key time counter (127...0 !), Zero? decf KeyTime2,f ; Not zero. Decrement if not zero in the beginning ; Zero. The key has been down long. Do not decrement. UCP3 btfss RXchord,3 ; Chord bit3 = 1? goto UCP4 ; No. Go on with the next chord bit. incf KeyTime3,f ; add 1 in order to set key counter to 1 if 0 decfsz KeyTime3,f ; Decrement key time counter (127...0 !), Zero? decf KeyTime3,f ; Not zero. Decrement if not zero in the beginning ; Zero. The key has been down long. Do not decrement. UCP4 btfss RXchord,4 ; Chord bit4 = 1? goto UCP5 ; No. Go on with the next chord bit. incf KeyTime4,f ; add 1 in order to set key counter to 1 if 0 decfsz KeyTime4,f ; Decrement key time counter (127...0 !), Zero? decf KeyTime4,f ; Not zero. Decrement if not zero in the beginning ; Zero. The key has been down long. Do not decrement. UCP5 btfss RXchord,5 ; Chord bit5 = 1? goto UCP6 ; No. Go on. incf KeyTime5,f ; add 1 in order to set key counter to 1 if 0 decfsz KeyTime5,f ; Decrement key time counter (127...0 !), Zero? decf KeyTime5,f ; Not zero. Decrement if not zero in the beginning ; Zero. The key has been down long. Do not decrement. ;---- UCP6 ;============ new code in Paris, September 2003 ============ ; This key polling procedure allows some overlapping of chords as well as ; holding down keys between chords supposing at least one key is released. KeyPoll ; Check-back enabled? ; CHECK-BACK IS ALWAYS DONE BUT SELECT LATER IF THE RESULT WILL BE OUTPUT ;---- ; Any key released? (Check-back enabled) KeyPoll_CB ;btfss NoOutput ; Is this too soon after previous output? incf WaitCounter,f ; Is WaitCounter = 0 or... decfsz WaitCounter,f ; ...is this too soon after previous output? goto KP0 ; Yes. To soon. ;bcf NoOutput ; Output allowed from now on goto KP1 ; KP0 ;bcf NoOutput ; Yes. Too soon. decf WaitCounter,f ; goto KP_newchar KP1 ; Is there any change in chord? movf RXchord,w ; RXchord = PrevChord1? movwf Temp ; PrevChord1 011100 movf PrevChord1,w ; RXchord 001101 XORWF Temp,f ; bits that changed 010001 (XOR) ANDWF Temp,f ; bits that were cleared 010000 (AND) btfsc STATUS,2 ; Z=0?, non-zero?, Keys released? goto KP_newchar ; No. ; Yes. bsf RXchordREADY ; Indicate to GKOSloop that output shall be made. movlw WaitPeriods ; Ignore a key release next N periods. ** ONLY VALID IF NO CHECK-BACK ** movwf WaitCounter ; WaitCounter is made relative to chord period C now! bsf NoOutput ; Ignore a key release next time (just 1 period). bcf NewChar ; No more output before a new key is pressed. ; Keyboard/mouse autorepeat delay movlw TDelay ; Initialize Toggle counter due to output of character. btfsc KBDasMOUSE ; Is Keyboard operating as mouse (mouse simulation)? movlw MTDelay ; Yes. Use a different delay value. movwf ToggleCounter ; No. Use the kbd delay value as planned. bcf AutoRepeat ; clear autorepeat indication KP_newchar ; Any new key pressed? movf PrevChord2,w ; PrevChord1 = PrevChord2? movwf Temp ; PrevChord2 011100 movf PrevChord1,w ; PrevChord1 001101 XORWF Temp,f ; bits that changed 010001 (XOR) ANDWF Temp,f ; bits that were set 000001 (AND) btfss STATUS,2 ; Z=0?, non-zero?, New keys pressed? bsf NewChar ; Yes. Indicate that next key release will cause char output. ; No. A key release will not result in outputting a character. UpdateDowns ; Update the chord value that might be output next time movf PrevChord1,w ; RXchord AND PrevChord1 movwf Downs ; PrevChord1 011100 movf RXchord,w ; RXchord 001101 ANDWF Downs,f ; bits that were common 001100 (AND) ; The previous Downs will be the chord to send! Not yet this ANDed value above. ; The previous Downs has already been moved to RXfinalchord for sending ;============ end of new code in Paris 9/2003 ===== ; Check back for double values to indicate missed characters (due to no key released) ;=========================== Code for check-back starts here =========================== ; ADD: control functions like PageUp, UpArrow shall not be accepted unless preceded ; by all keys up. Also if check back gives PageUp atc. they shall be rejected. ; ccccccc btfss RXchordREADY ; Is it time to output a character? goto KP_X ; No. Just skip the check-back procedure. ; Yes. Then check back if there was a missed chord ; before the actual one to send. ; 1) Find the shortest KeyTime in PrevChord1 (=C). ; They must be below 127 because they have been decremented at least once. ; It is in fact the largest value of KeyTime *down* counters ; (max 3 counters for letters/numbers/punctuation). ; defaults: clrf Tmp3 ; Clear temp storage of check-back chord value bcf MoreChords ; Indicate that there is no second chord to send ; in the buffer. clrf TempB0 ; single keys in chord clrf TempB1 clrf TempB2 movlw d'127' movwf TEMP0 ; Three timers in chord. Set initial values movwf TEMP1 ; for down counters (127...0) movwf TEMP2 ; Code below is long but fast! ; check PrevChord1 because it does not yet include the key release CheckBit5 btfss RXfinalchord,5 goto CheckBit4 movlw b'100000' movwf TempB0 movf KeyTime5,W movwf TEMP0 goto CheckBit4B CheckBit4 btfss RXfinalchord,4 goto CheckBit3 movlw b'010000' movwf TempB0 movf KeyTime4,W movwf TEMP0 goto CheckBit3B CheckBit3 btfss RXfinalchord,3 goto CheckBit2 movlw b'001000' movwf TempB0 movf KeyTime3,W movwf TEMP0 goto CheckBit2B CheckBit2 btfss RXfinalchord,2 goto CheckBit1 movlw b'000100' movwf TempB0 movf KeyTime2,W movwf TEMP0 goto CheckBit1B CheckBit1 btfss RXfinalchord,1 goto CheckBit0 movlw b'000010' movwf TempB0 movf KeyTime1,W movwf TEMP0 goto CheckBit0B CheckBit0 btfss RXfinalchord,0 goto CheckBitX movlw b'000001' movwf TempB0 movf KeyTime0,W movwf TEMP0 goto CheckBitX ;------------------ CheckBit4B btfss RXfinalchord,4 goto CheckBit3B movlw b'010000' movwf TempB1 movf KeyTime4,W movwf TEMP1 goto CheckBit3C CheckBit3B btfss RXfinalchord,3 goto CheckBit2B movlw b'001000' movwf TempB1 movf KeyTime3,W movwf TEMP1 goto CheckBit2C CheckBit2B btfss RXfinalchord,2 goto CheckBit1B movlw b'000100' movwf TempB1 movf KeyTime2,W movwf TEMP1 goto CheckBit1C CheckBit1B btfss RXfinalchord,1 goto CheckBit0B movlw b'000010' movwf TempB1 movf KeyTime1,W movwf TEMP1 goto CheckBit0C CheckBit0B btfss RXfinalchord,0 goto CheckBitX movlw b'000001' movwf TempB1 movf KeyTime0,W movwf TEMP1 goto CheckBitX ;------------------- CheckBit3C btfss RXfinalchord,3 goto CheckBit2C movlw b'001000' movwf TempB2 movf KeyTime3,W movwf TEMP2 goto CheckBitX CheckBit2C btfss RXfinalchord,2 goto CheckBit1C movlw b'000100' movwf TempB2 movf KeyTime2,W movwf TEMP2 goto CheckBitX CheckBit1C btfss RXfinalchord,1 goto CheckBit0C movlw b'000010' movwf TempB2 movf KeyTime1,W movwf TEMP2 goto CheckBitX CheckBit0C btfss RXfinalchord,0 goto CheckBitX movlw b'000001' movwf TempB2 movf KeyTime0,W movwf TEMP2 ;goto CheckBitX ;---------- ; 3) Find those KeyTime values that exceed (P% x C = 50% x C to start with). ; They will define a second character that must be output before the actual RXfinalchord. ; C = the shortest KeyTime in the original chord CheckBitX ; Here is now each of the one-to-three keys and the correponding timer values ; Keys: TempB0, TempB1, TempB2, e.g. 010000, 000100, 000010 (FECDBA) ; Timer values: TEMP0, TEMP1, TEMP2, e.g. 119(min), 115, 103(max) ; subwf examples: ; reg=3, w=2 => C=1, Z=0 (+) ; reg=2, w=2 => C=1, Z=1 (0) ; reg=1, w=2 => C=0, Z=0 (-) ; Subtract each TEMPn from 127 to get real length movlw d'255' ; movlw d'13' ;0x0D = To show start of data in debug window call SerTx2 ;Debug movf TEMP0,W sublw d'127' ; 127-119=8 (subtract W *from* literal) movwf TEMP0 ; (min in the example) call SerTx2 ;Debug movf TEMP1,W sublw d'127' ; 127-115=12 (subtract W *from* literal) movwf TEMP1 call SerTx2 ;Debug movf TEMP2,W sublw d'127' ; 127-103=24 (subtract W *from* literal) movwf TEMP2 ; (max in the example) call SerTx2 ;Debug ;------ CTEMP0_TEMP1 ; Compare TEMP0 and TEMP1 movf TEMP0,W ; TEMP0=0? XORLW d'0' btfsc STATUS,Z goto CTEMP1_TEMP2 ; Yes. ; No. movf TEMP1,W ; TEMP1=0? XORLW d'0' btfsc STATUS,Z goto CTEMP0_TEMP2 ; Yes. ; No. movf TEMP1,W subwf TEMP0,W ; compare TEMP1 and TEMP0: TEMP0-TEMP1 btfsc STATUS,Z ; goto CTEMP1_TEMP2 ; Z=1 (TEMP0=TEMP1) ??? btfsc STATUS,C goto CTEMP1_TEMP2 ; C=1 (TEMP0>TEMP1) goto CTEMP0_TEMP2 ; C=0 (TEMP0TEMP2) goto T1smallest ; C=0 (TEMP1TEMP2) goto T0smallest ; C=0 (TEMP04 then decrement by one movlw d'4' ; to adjust larger than 4 values subwf Tmp2,W ; Tmp2-4<0? btfsc STATUS,C ; Carry? decf Tmp2,f ; No. Tmp2>=4 ; Yes. Tmp2<4. movf TEMP0,W ; TEMP1-TEMP0>0.5 x TEMP0? subwf TEMP1,W ; TEMP1=TEMP1-TEMP0 (result) subwf Tmp2,W ; Tmp2 - result =? btfsc STATUS,C ; Second chord found? goto T0s2 ; C=1 Tmp2 > result (not found) bsf MoreChords ; C=0 Tmp2 < result ***FOUND ; get the bit from TempB1 into second chord movf TempB1,W movwf Tmp3 T0s2 movf TEMP0,W ; TEMP2-TEMP0>0.5 x TEMP0? subwf TEMP2,W ; TEMP2=TEMP2-TEMP0 (result) subwf Tmp2,W ; Tmp2 - result =? btfsc STATUS,C ; Second chord found? goto PrepareOutput ; C=1 Tmp2 > result (not found) bsf MoreChords ; C=0 Tmp2 < result ***FOUND ; get the bit from TempB2 into second chord movf TempB2,W addwf Tmp3,F goto PrepareOutput ; Output two chords T1smallest movf TEMP1,W ; divide TEMP1 by two and save into Tmp2 movwf Tmp2 ; xxxx xxxx movwf WaitCounter ; Update Guard time rrf WaitCounter,f ; divide by 2 bcf WaitCounter,7 ; 0xxx xxxx clrf WaitCounter ; Use fixed value bsf WaitCounter,1 ; Make sure it is at least 3 (0xxx xx1x) bsf WaitCounter,0 ; Make sure it is at least 3 (0xxx xx11) ; If Tmp2>4 then decrement by one movlw d'4' ; to adjust larger than 4 values subwf Tmp2,W ; Tmp2-4<0? btfsc STATUS,C ; Carry? decf Tmp2,f ; No. Tmp2>=4 ; Yes. Tmp2<4. movf TEMP1,W ; TEMP0-TEMP1>0.5 x TEMP1? subwf TEMP0,W ; TEMP0=TEMP0-TEMP1 (result) subwf Tmp2,W ; Tmp2 - result < 0 ? btfsc STATUS,C ; Second chord found? goto T1s2 ; C=1 Tmp2 > result (not found) bsf MoreChords ; C=0 Tmp2 < result ***FOUND ; get the bit from TempB0 into second chord movf TempB0,W movwf Tmp3 T1s2 movf TEMP1,W ; TEMP2-TEMP1>0.5 x TEMP1? subwf TEMP2,W ; TEMP2=TEMP2-TEMP1 (result) subwf Tmp2,W ; Tmp2 - result =? btfsc STATUS,C ; Second chord found? goto PrepareOutput ; C=1 Tmp2 > result (not found) bsf MoreChords ; C=0 Tmp2 < result ***FOUND ; get the bit from TempB2 into second chord movf TempB2,W addwf Tmp3,F goto PrepareOutput ; Output two chords T2smallest movf TEMP2,W ; divide TEMP2 by two and save into Tmp2 movwf Tmp2 ; xxxx xxxx movwf WaitCounter ; Update Guard time rrf WaitCounter,f ; divide by 2 bcf WaitCounter,7 ; 0xxx xxxx clrf WaitCounter ; Use fixed value bsf WaitCounter,1 ; Make sure it is at least 3 (0xxx xx1x) bsf WaitCounter,0 ; Make sure it is at least 3 (0xxx xx11) ; If Tmp2>4 then decrement by one movlw d'4' ; to adjust larger than 4 values subwf Tmp2,W ; Tmp2-4<0? btfsc STATUS,C ; Carry? decf Tmp2,f ; No. Tmp2>=4 ; Yes. Tmp2<4. movf TEMP2,W ; TEMP1-TEMP2>0.5 x TEMP2? subwf TEMP1,W ; TEMP1=TEMP1-TEMP2 (result) subwf Tmp2,W ; Tmp2 - result =? btfsc STATUS,C ; Second chord found? goto T2s2 ; C=1 Tmp2 > result (not found) bsf MoreChords ; C=0 Tmp2 < result ***FOUND ; get the bit from TempB1 into second chord movf TempB1,W movwf Tmp3 T2s2 movf TEMP2,W ; TEMP0-TEMP2>0.5 x TEMP2? subwf TEMP0,W ; TEMP0=TEMP0-TEMP2 (result) subwf Tmp2,W ; Tmp2 - result =? btfsc STATUS,C ; Second chord found? goto PrepareOutput ; C=1 Tmp2 > result (not found) bsf MoreChords ; C=0 Tmp2 < result ***FOUND ; get the bit from TempB0 into second chord movf TempB0,W addwf Tmp3,F ;goto PrepareOutput ; Output two chords ; ... ; 4) Prepare to output two charaters! ; First, change RXfinalchord to the previous character and then ; put the actual RXfinalchord to a buffer (RXfinalchord2) that ; must be output first thing when polling (MainLoop) starts again. PrepareOutput btfsc CheckBackOn ; Is check-back output in use? goto PrO_1 ; Yes. bcf MoreChords ; No. Indicate no additional chord to send goto CLT_0 ; PrO_1 btfss MoreChords ; Second chord found? goto CLT_0 ; No. movf RXfinalchord,W ; Yes. Get the actual chord to send. movwf Temp ; Save temporarily the original chord movwf RXfinalchord2 ; Put it on hold into the buffer for a while. movf Tmp3,W ; get the second chord found through check-back movwf RXfinalchord ; This is the chord to be sent first instead. ; Sedn order: RXfinalchord > RXfinalchord2 goto ClearKeyTimes ; ... ; Clear counters for keys in the original chord (includes the second ; chord also) Original chord must be in Temp CLT_0 ; This is when only the original chord is sent movf RXfinalchord,W ; Get the actual chord to send. movwf Temp ; Save temporarily original chord ; This is both cases ; Clear counters of keys in the original chord ClearKeyTimes movlw d'127' ; Counter is running 127 -> 0 if key is held down btfsc Temp,0 ; Chord bit0 = 1? (Key up?) movwf KeyTime0 ; Yes. Init counter. (set to 127 if up) btfsc Temp,1 ; Chord bit1 = 1? movwf KeyTime1 ; Yes. Init counter. btfsc Temp,2 ; Chord bit2 = 1? movwf KeyTime2 ; Yes. Init counter. btfsc Temp,3 ; Chord bit3 = 1? movwf KeyTime3 ; Yes. Init counter. btfsc Temp,4 ; Chord bit4 = 1? movwf KeyTime4 ; Yes. Init counter. btfsc Temp,5 ; Chord bit5 = 1? movwf KeyTime5 ; Yes. Init counter. KP_X ; ======================= Code for check-back ends here ============================= ; Update consecutive chord values movf PrevChord1,w ; Two chords back movwf PrevChord2 ; Save chord as previous chord for next time movf RXchord,w ; One chord back movwf PrevChord1 ; Save chord as previous chord for next time ; Initialize the key counter values for those keys that were up movlw d'127' ; Counter is running 127 -> 0 if key is held down btfss RXchord,0 ; Chord bit0 = 1? movwf KeyTime0 ; No. Init counter. btfss RXchord,1 ; Chord bit1 = 1? movwf KeyTime1 ; No. Init counter. btfss RXchord,2 ; Chord bit2 = 1? movwf KeyTime2 ; No. Init counter. btfss RXchord,3 ; Chord bit3 = 1? movwf KeyTime3 ; No. Init counter. btfss RXchord,4 ; Chord bit4 = 1? movwf KeyTime4 ; No. Init counter. btfss RXchord,5 ; Chord bit5 = 1? movwf KeyTime5 ; No. Init counter. return ;============================================================================= ; END OF The intelligent keyboard scanning procedure ;============================================================================= ; second time for this page (in fact this now on Page1 and not needed, use DelayWx1ms) DelayWx1ms2 movwf dcount1 ; dcount1 = W movlw 0x0a movwf dcount2 movlw 0x20 movwf dcount3 decfsz dcount3,F ; delay of > ((((3 * dcount3)+3)*dcount2)+3*W) goto $ - 1 ; * instruction cycle time (1us for 4MHz) decfsz dcount2,F goto $ - 5 ; so currently W x 1ms decfsz dcount1,F goto $ - 9 return ; Page 1 continues... ;================================================================================== ; START OF KEYBOARD AS MOUSE (...on Page 1: 800-8FF, far call needed) ;================================================================================== ;=== KEYBOARD AS MOUSE operation ==== ; SUBS (do not enter here first): MByteOutS ; 0x80 d'128' = 4 mouse bytes follow at UART movwf Temp ; Send first mouse byte... =START= movlw d'128' call SerTxM ; movf Temp,W ; Restore mouse byte in W MByteOut ; Send button and dx mouse bytes via UART =1,2= call SerTxM return MByteOutE ; Send dy mouse byte followed by scroll wheel data (=0) =3= call SerTxM ; ...and end of mouse data indication 0xff movlw d'0' ; Scroll wheel data (0 for the moment) =4= call SerTxM movlw d'255' ; 0xff d'255' = end of 4 mouse bytes at UART =END= call SerTxM return ;================================================================== ; Bit KBDasMOUSE must be set to end up here. ; Chord in finalchord ; ----------------- ENTER HERE BY A FAR CALL FROM PAGE 0 ---------- KeyboardMouse movlw d'63' ; End of mouse operation pressed? xorwf finalchord,w ; bnz KeybMouse2 ; No. Go ahead. bcf KBDasMOUSE ; Yes. End this mouse simulation. movlw d'50' ;This dealay is required! Still!!! call DelayWx10ms ;Do not be too hasty.... XMainLoop ; Exit to MainLoop and clear chord buffer clrf PrevChord1 ; not to send more chords right away clrf PrevChord2 clrf Downs return ; goto MainLoop KeybMouse2 ; btfss M_ENABLE ; Are the mouse PS/2 lines ready for mouse data? ; goto MBAT ; No. Try doing the Mouse BAT then (0,5 sec). ; ;goto MainLoop ; No. Do not send movement data. ; Yes. Movement data can be sent via mouse lines. movlw d'63' ; End of mouse operation? xorwf finalchord,w ; bnz MouseAction ; No. bcf KBDasMOUSE ; Yes. End the mouse simulation. ; No. Go on... ;goto MainLoop ;=============================================== ;MOUSE OPERATION ;Chord values for the Mouse ;up = a+d = 1+8 = 9 ;right up = d = 8 ;right = e = 16 ;right down = f = 32 ;down = c+f = 4+32 = 36 ;left down = c = 4 ;left = b = 2 ;left up = a = 1 ;Press and Release Left button = a+b+c = 1+2+4 = 7 (left click) ;Press and Release Middle button= b+e (shift) = 2+16 = 18 ;Press and Release Right button = d+e+f = 8+16+32 = 56 (right click) ;Press and Hold Left Button = a+c = 1+4 = 5 (now used for left click) ;Press and Hold Right Button = d+f = 8+32 = 40(now used for right click) ;Esc = 31 ;Enter = 59 (double click) ;123-abc= 63 ;======= MOVING MOUSE POINTER WITH KEYBOARD ===== ;MouseOperation ;call MouseAction ;goto MainLoop ; nop ;MouseAction ; movf finalchord,W ;abc-123 (to exit Mouse Operation) ; xorlw d'63' ;Test if chord=123-abc ; btfsc STATUS,Z ;Skip if Z=0. Skip if not equal. ; goto MouseExit ; ;movf finalchord,W ;Esc (to exit Mouse Operation) ;xorlw d'31' ;Test if chord=123-abc ;btfsc STATUS,Z ;Skip if Z=0. Skip if not equal. ;goto MouseExit ; ; btfss AutoRepeat ;Typematic repeat (Autorepeat on)? ; goto MouseAction_aa ; movlw 0x01 ;Faster Autorepeat steps ; movwf YstepUp ; movwf XstepRight ; movlw 0xff ; movwf YstepDown ; movwf XstepLeft ; goto MouseAction_a ;MouseAction_aa ; movlw 0x01 ;Default steps ; movwf YstepUp ; movwf XstepRight ; movlw 0xff ; movwf YstepDown ; movwf XstepLeft ;MouseAction_a MouseAction movf finalchord,W; ;Up? xorlw d'9' ; btfsc STATUS,Z ; goto MoveUp ;Yes. movf finalchord,W; ;FUp? xorlw d'27' ;A+B+D+E=1+2+8+16=27 btfsc STATUS,Z ; goto FMoveUp ;Yes. movf finalchord,W; ;UpRight? xorlw d'8' ;'D' btfsc STATUS,Z ; goto MoveUpRight ;Yes. movf finalchord,W; ;FUpRight? xorlw d'25' ;'A'+'D'+'E' 1+8+16 btfsc STATUS,Z ; goto FMoveUpRight ;Yes. movf finalchord,W; ;UpRRight? xorlw d'24' ;'D+E' 8+16 btfsc STATUS,Z ; ;goto MoveUpRRight ;Yes. goto FMoveUpRight ;Yes. movf finalchord,W; ;Right? xorlw d'16' ; btfsc STATUS,Z ; goto MoveRight ;Yes. movf finalchord,W; ;FRight? xorlw d'56' ;D+E+F=56 btfsc STATUS,Z ; goto FMoveRight ;Yes. movf finalchord,W; ;DownRRight? xorlw d'48' ;'F'+'E' 16+32 btfsc STATUS,Z ; ;goto MoveDRRight ;Yes. goto FMoveDRight ;Yes. movf finalchord,W; ;DownRight? xorlw d'32' ;'F' btfsc STATUS,Z ; goto MoveDRight ;Yes. movf finalchord,W; ;FDownRight? xorlw d'52' ;E+F+C=16+32+4=52 btfsc STATUS,Z ; goto FMoveDRight ;Yes. movf finalchord,W; ;Down? xorlw d'36' ; btfsc STATUS,Z ; goto MoveDown ;Yes. movf finalchord,W; ;FDown? xorlw d'54' ;B+C+E+F=2+4+16+32=54 btfsc STATUS,Z ; goto FMoveDown ;Yes. movf finalchord,W; ;DownLeft? xorlw d'4' ;'C' btfsc STATUS,Z ; goto MoveDownLeft ;Yes. movf finalchord,W; ;FDownLeft? xorlw d'38' ;B+C+F=2+4+32=38 btfsc STATUS,Z ; goto FMoveDownLeft ;Yes. movf finalchord,W; ;DownLLeft? xorlw d'6' ;'B'+'C' 2+4 btfsc STATUS,Z ; ;goto MoveDownLLeft ;Yes. goto FMoveDownLeft ;Yes. movf finalchord,W; ;Left? xorlw d'2' ; btfsc STATUS,Z ; goto MoveLeft ;Yes. movf finalchord,W; ;FLeft? xorlw d'7' ;A+B+C=1+2+4=7 btfsc STATUS,Z ; goto FMoveLeft ;Yes. movf finalchord,W; ;UpLLeft? xorlw d'3' ;'A'+'B' 1+2 btfsc STATUS,Z ; ;goto MoveUpLLeft ;Yes goto FMoveUpLeft ;Yes. movf finalchord,W; ;UpLeft? xorlw d'1' ;'A' btfsc STATUS,Z ; goto MoveUpLeft ;Yes. movf finalchord,W; ;FUpLeft? xorlw d'11' ;A+B+D=1+2+8=11 btfsc STATUS,Z ; goto FMoveUpLeft ;Yes. ;Typematic on? btfsc AutoRepeat ;For chords below this point NO AUTOREPEAT please! return ; goto MainLoop ;--- alternatives 1 for left and right mouse buttons: ENTER and ESC ---- ;yyyyy movf finalchord,W; ;Left Button pressed&released? xorlw d'59' ;ENTER = A+B+D+E+F=1+2+8+16+32=59 btfsc STATUS,Z ;A+C=5 goto PressLeftButton ;Yes. movf finalchord,W; ;Right Button pressed&released? xorlw d'31' ;D+E+F=56; ESC = 31 btfsc STATUS,Z ;D+F=8+32=40 goto PressRightButton ;Yes. ;--- alternatives 2 for left and right mouse buttons: A+C (U-uml) and D+F (W)---- movf finalchord,W; ;Left Button pressed&released? xorlw d'5' ; btfsc STATUS,Z ;A+C=5 goto PressLeftButton ;Yes. movf finalchord,W; ;Right Button pressed&released? xorlw d'40' ; btfsc STATUS,Z ;D+F=8+32=40 goto PressRightButton ;Yes. ;--- alternative 3 for left mouse button: SHIFT ---- movf finalchord,W; ;Left Button pressed&released? xorlw d'18' ;SHIFT = B+E=2+16=18 btfsc STATUS,Z ;A+C=5 goto PressLeftButton ;Yes. ; movf finalchord,W; ;Right Button pressed&released? ; xorlw d'40' ;D+E+F=56; ESC = 31 ; btfsc STATUS,Z ;D+F=8+32=40 ; goto PressRightButton ;Yes. ;--- Just press left button down for dragging etc. movf finalchord,W; ;Left Button pressed down? xorlw d'45' ;A+C+D+F = 1+4+8+32 = 45 btfsc STATUS,Z ; '?' goto LeftButtonDown ;Yes. ;--- Release left (or any) any button movf finalchord,W; ;Left (or any) Button released? xorlw d'12' ;C+D = 12 btfsc STATUS,Z ; '!' goto ReleaseAnyButton ;Yes. ; ADD POSSIBLE OTHER MOUSE FUNCTIONS HERE... return ; goto XMainLoop ;MouseExit ; movlw d'50' ;This dealay is required! Still!!! ; call DelayWx10ms ;Do not be too hasty.... ;Else there will be possily keystrokes sent before Keyboard operation is enabled ; bcf KBDasMOUSE ;***Exit Mouse mode*** ; call SendBATsuccessful ;Reset into Keyboard mode!!! ; goto MainLoop MoveUp ;movlw 0x08 (no buttons pressed) movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x08 call MByteOutS movlw 0x00 call MByteOut movlw 0x05 ;YstepUp call MByteOutE return ; goto MainLoop FMoveUp ;movlw 0x08 (no buttons pressed) movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x08 call MByteOutS movlw 0x00 call MByteOut movlw 0x0F ;YstepUp call MByteOutE return ; goto MainLoop MoveUpRight ;movlw 0x08 (no buttons pressed) movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x08 call MByteOutS movlw 0x03 call MByteOut movlw 0x03 ;YstepUp call MByteOutE return ; goto MainLoop FMoveUpRight ;movlw 0x08 (no buttons pressed) movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x08 call MByteOutS movlw 0x0a call MByteOut movlw 0x0a ;YstepUp call MByteOutE return ; goto MainLoop MoveUpRRight ;movlw 0x08 (no buttons pressed) movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x08 call MByteOutS movlw 0x04 call MByteOut movlw 0x02 ;YstepUp call MByteOutE return ; goto MainLoop ; Up/Right: 1 2 3 4 5 6 7 8 9 A B C D E F ;Down/Left: F E D C B A 9 8 7 6 5 4 3 2 1 MoveRight ;movlw 0x08 (no buttons pressed) movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x08 call MByteOutS movlw 0x05 ;XstepRight call MByteOut movlw 0x00 call MByteOutE return ; goto MainLoop FMoveRight ;movlw 0x08 (no buttons pressed) movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x08 call MByteOutS movlw 0x0F ;XstepRight call MByteOut movlw 0x00 call MByteOutE return ; goto MainLoop MoveDRRight ;movlw 0x28 ;bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x28 call MByteOutS;Yovf Xovf Ysign Xsign =1 middle right left Buttons movlw 0x04 ; 2 8 call MByteOut movlw 0xFE ;YstepDown call MByteOutE return ; goto MainLoop MoveDRight ;0010 1000 ; 0 0 1 0 1 0 0 0 ;movlw 0x28 ;bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x28 call MByteOutS;Yovf Xovf Ysign Xsign =1 middle right left Buttons movlw 0x03 ; 2 8 call MByteOut movlw 0xFD ;YstepDown call MByteOutE return ; goto MainLoop FMoveDRight ;0010 1000 ; 0 0 1 0 1 0 0 0 ;movlw 0x28 ;bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x28 call MByteOutS;Yovf Xovf Ysign Xsign =1 middle right left Buttons movlw 0x0a ; 2 8 call MByteOut movlw 0xF6 ;YstepDown call MByteOutE return ; goto MainLoop MoveDown ;movlw 0x28 ;0010 1000 movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x28 call MByteOutS movlw 0x00 call MByteOut movlw 0xFB ;YstepDown call MByteOutE return ; goto MainLoop FMoveDown ;movlw 0x28 ;0010 1000 movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x28 call MByteOutS movlw 0x00 call MByteOut movlw 0xF0 ;YstepDown call MByteOutE return ; goto MainLoop MoveDownLeft ;movlw 0x38 ;0011 1000 OK movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x38 call MByteOutS movlw 0xFD ;XstepLeft call MByteOut movlw 0xFD call MByteOutE return ; goto MainLoop FMoveDownLeft ;movlw 0x38 ;0011 1000 OK movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x38 call MByteOutS movlw 0xF6 ;XstepLeft call MByteOut movlw 0xF6 call MByteOutE return ; goto MainLoop MoveDownLLeft ;movlw 0x38 ;0011 1000 OK movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x38 call MByteOutS movlw 0xFC ;XstepLeft call MByteOut movlw 0xFE call MByteOutE return ; goto MainLoop MoveLeft ;movlw 0x18 ;0001 1000 movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x18 call MByteOutS movlw 0xFB ;XstepLeft call MByteOut movlw 0x00 call MByteOutE return ; goto MainLoop FMoveLeft ;movlw 0x18 ;0001 1000 movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x18 call MByteOutS movlw 0xF0 ;XstepLeft call MByteOut movlw 0x00 call MByteOutE return ; goto MainLoop MoveUpLLeft ;movlw 0x18 ;0001 1000 movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x18 call MByteOutS movlw 0xFC ;XstepLeft call MByteOut movlw 0x02 call MByteOutE return ; goto MainLoop MoveUpLeft ;movlw 0x18 ;0001 1000 movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x18 call MByteOutS movlw 0xFC ;XstepLeft call MByteOut movlw 0x04 call MByteOutE return ; goto MainLoop FMoveUpLeft ;movlw 0x18 ;0001 1000 movf KMouseByte1,W ; Buttons pressed etc ADDLW 0x18 call MByteOutS movlw 0xF6 ;XstepLeft call MByteOut movlw 0x0A call MByteOutE return ; goto MainLoop PressLeftButton movlw d'30' ; reduced from 50 to 30 for making double click possible call DelayWx10ms ; Do not be too hasty to resend movlw 0x09 ; Due to frequent key scanning call MByteOutS movlw 0x00 call MByteOut movlw 0x00 call MByteOutE movlw 0x01 movwf KMouseByte1 ;;ReleaseAnyButton movlw 0x08 call MByteOutS movlw 0x00 call MByteOut movlw 0x00 call MByteOutE clrf KMouseByte1 goto XMainLoop ; Exit and clear chord buffer LeftButtonDown movlw d'30' ; reduced from 50 to 30 call DelayWx10ms ; Do not be too hasty to resend movlw 0x09 ; Due to frequent key scanning call MByteOutS movlw 0x00 call MByteOut movlw 0x00 call MByteOutE movlw 0x01 movwf KMouseByte1 goto XMainLoop ; Exit and clear chord buffer PressMiddleButton movlw d'50' call DelayWx10ms ;Do not be too hasty to resend movlw 0x0c call MByteOutS movlw 0x00 call MByteOut movlw 0x00 call MByteOutE movlw 0x04 movwf KMouseByte1 goto XMainLoop ; Exit and clear chord buffer PressRightButton movlw d'50' call DelayWx10ms ;Do not be too hasty to resend movlw 0x0a call MByteOutS movlw 0x00 call MByteOut movlw 0x00 call MByteOutE movlw 0x01 movwf KMouseByte1 ;;ReleaseAnyButton movlw 0x08 call MByteOutS movlw 0x00 call MByteOut movlw 0x00 call MByteOutE clrf KMouseByte1 goto XMainLoop ; Exit and clear chord buffer ReleaseAnyButton movlw d'50' call DelayWx10ms ;Do not be too hasty to resend movlw 0x08 call MByteOutS movlw 0x00 call MByteOut movlw 0x00 call MByteOutE clrf KMouseByte1 goto XMainLoop ; Exit and clear chord buffer ;******************************************************************************** ;============================================================================== ; END OF KEYBOARD AS MOUSE ;============================================================================== ;------------------------------------------------------------------------------- ; (<= intelligent key scanning) ;___________________________end of Page1 0800h-07FFf__________________________________________ ;Page0: main program ;Page1: intelligent key scanning ;Page2: Shortcut tables ;Page3: Tables ;PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP222222222222222222222222222222222222222222222 ;___________________________ Page2 1000h-17FFh ____________________________________ ; shortcut tables org 0x1000 ;Start of Program Memory Page2 ;Page2_proc ; return ; CHORDON SHORTCUT TABLES ON THIS PAGE ; Space for one table is 256 bytes: e.g. 1000 - 10FF Table_SetSCFlags movwf PCL retlw 0x81 ; 31 . 1000 0001 retlw 0x82 ; 32 , 1000 0010 retlw 0x84 ; 33 ! 1000 0100 retlw 0x88 ; 34 ? 1000 1000 retlw 0x90 ; 35 - 1001 0000 retlw 0xa0 ; 36 ' 1010 0000 retlw 0x00 ; 37 retlw 0x00 ; 38 retlw 0x00 ; 39 retlw 0x00 ; 40 retlw 0x00 ; 41 retlw 0xc1 ; 42 Up Arrow 1100 0001 retlw 0xc2 ; 43 Down Arrow 1100 0010 retlw 0x00 ; 44 retlw 0x00 ; 45 retlw 0x00 ; 46 retlw 0x00 ; 47 retlw 0x00 ; 48 retlw 0x00 ; 49 retlw 0x00 ; 50 retlw 0x00 ; 51 retlw 0x00 ; 51 retlw 0x00 ; 53 retlw 0x00 ; 54 retlw 0x00 ; 55 retlw 0x00 ; 56 retlw 0x00 ; 57 retlw 0x00 ; 58 retlw 0xc4 ; 59 SHIFT 1100 0100 retlw 0x00 ; 60 retlw 0x00 ; 61 retlw 0x00 ; 62 retlw 0x00 ; 63 return ; not needed when this works ok (no n+1 error) Table_SC_asterisk ; 'a movwf PCL retlw 0x00 ; a retlw 0x00 ; b retlw 0x00 ; c retlw 0x00 ; d retlw 0x00 ; e retlw 0x00 ; f retlw 0x00 ; g retlw 0x00 ; h retlw d'5' ; i 'is' retlw 0x00 ; j retlw 0x00 ; k retlw 0x00 ; l retlw 0x00 ; m retlw 0x00 ; n retlw 0x00 ; o retlw d'1' ; p 'put' retlw 0x00 ; q retlw 0x00 ; r retlw 0x00 ; s retlw d'8' ; t 'that' retlw 0x00 ; u retlw 0x00 ; v retlw 0x00 ; w retlw 0x00 ; x retlw d'13' ; y 'you' retlw 0x00 ; z retlw 0x00 ; ü retlw 0x00 ; å retlw 0x00 ; ä retlw 0x00 ; ö retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow Table2_SC_asterisk ; a' movwf PCL retlw 0x00 ; a retlw d'17' ; b 'but' retlw 0x00 ; c retlw d'21' ; d 'do' retlw 0x00 ; e retlw 0x00 ; f retlw 0x00 ; g retlw 0x00 ; h retlw 0x00 ; i retlw 0x00 ; j retlw 0x00 ; k retlw 0x00 ; l retlw 0x00 ; m retlw 0x00 ; n retlw 0x00 ; o retlw 0x00 ; p retlw 0x00 ; q retlw 0x00 ; r retlw 0x00 ; s retlw 0x00 ; t retlw 0x00 ; u retlw 0x00 ; v retlw 0x00 ; w retlw 0x00 ; x retlw 0x00 ; y retlw 0x00 ; z retlw 0x00 ; ü retlw 0x00 ; å retlw 0x00 ; ä retlw 0x00 ; ö retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow Table_SC_hyphen ; -a movwf PCL retlw 0x00 ; a retlw 0x00 ; b retlw 0x00 ; c retlw 0x00 ; d retlw 0x00 ; e retlw 0x00 ; f retlw 0x00 ; g retlw d'30' ; h 'he' retlw 0x00 ; i retlw 0x00 ; j retlw 0x00 ; k retlw d'33' ; l 'like' retlw 0x00 ; m retlw 0x00 ; n retlw 0x00 ; o retlw 0x00 ; p retlw d'24' ; q 'quite' retlw 0x00 ; r retlw 0x00 ; s retlw 0x00 ; t retlw 0x00 ; u retlw 0x00 ; v retlw 0x00 ; w retlw 0x00 ; x retlw 0x00 ; y retlw 0x00 ; z retlw 0x00 ; ü retlw 0x00 ; å retlw d'38' ; ä 'they' retlw 0x00 ; ö retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow Table2_SC_hyphen ; a- movwf PCL retlw d'43' ; a 'am' retlw 0x00 ; b retlw 0x00 ; c retlw 0x00 ; d retlw d'46' ; e 'every' retlw 0x00 ; f retlw 0x00 ; g retlw 0x00 ; h retlw 0x00 ; i retlw 0x00 ; j retlw 0x00 ; k retlw 0x00 ; l retlw 0x00 ; m retlw 0x00 ; n retlw 0x00 ; o retlw 0x00 ; p retlw 0x00 ; q retlw 0x00 ; r retlw 0x00 ; s retlw 0x00 ; t retlw 0x00 ; u retlw 0x00 ; v retlw 0x00 ; w retlw 0x00 ; x retlw 0x00 ; y retlw 0x00 ; z retlw 0x00 ; ü retlw 0x00 ; å retlw 0x00 ; ä retlw 0x00 ; ö retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow ; ...0x10CE ;org 0x1100 ;Start of Table TEST!!!! Table_SC_period ; .a movwf PCL retlw 0x00 ; a retlw 0x00 ; b retlw 0x00 ; c retlw 0x00 ; d retlw 0x00 ; e retlw 0x00 ; f retlw 0x00 ; g retlw 0x00 ; h retlw 0x00 ; i retlw 0x00 ; j retlw 0x00 ; k retlw 0x00 ; l retlw d'57' ; m 'much' .m retlw 0x00 ; n retlw 0x00 ; o retlw 0x00 ; p retlw 0x00 ; q retlw d'62' ; r 'right' .r retlw 0x00 ; s retlw 0x00 ; t retlw 0x00 ; u retlw d'52' ; v 'very' .v retlw 0x00 ; w retlw 0x00 ; x retlw d'68' ; y 'yes' .y retlw 0x00 ; z retlw 0x00 ; ü retlw 0x00 ; å retlw 0x00 ; ä retlw 0x00 ; ö retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow Table2_SC_period ; a. movwf PCL retlw 0x00 ; a retlw d'72' ; b 'been' retlw 0x00 ; c retlw 0x00 ; d retlw 0x00 ; e retlw d'77' ; f 'from' retlw 0x00 ; g retlw 0x00 ; h retlw 0x00 ; i retlw 0x00 ; j retlw 0x00 ; k retlw 0x00 ; l retlw 0x00 ; m retlw 0x00 ; n retlw 0x00 ; o retlw 0x00 ; p retlw 0x00 ; q retlw 0x00 ; r retlw 0x00 ; s retlw 0x00 ; t retlw 0x00 ; u retlw 0x00 ; v retlw 0x00 ; w retlw 0x00 ; x retlw 0x00 ; y retlw 0x00 ; z retlw 0x00 ; ü retlw 0x00 ; å retlw 0x00 ; ä retlw 0x00 ; ö retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow Table_SC_comma ; ,a movwf PCL retlw 0x00 ; a retlw 0x00 ; b retlw 0x00 ; c retlw 0x00 ; d retlw 0x00 ; e retlw 0x00 ; f retlw 0x00 ; g retlw 0x00 ; h retlw 0x00 ; i retlw d'7' ; j 'certain' retlw 0x00 ; k retlw 0x00 ; l retlw 0x00 ; m retlw d'4' ; n 'no' retlw 0x00 ; o retlw 0x00 ; p retlw 0x00 ; q retlw 0x00 ; r retlw 0x00 ; s retlw 0x00 ; t retlw d'1' ; u 'up' retlw 0x00 ; v retlw 0x00 ; w retlw 0x00 ; x retlw 0x00 ; y retlw 0x00 ; z retlw 0x00 ; ü retlw 0x00 ; å retlw d'15' ; ä 'there' ,the_ retlw 0x00 ; ö retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow Table2_SC_comma ; a, movwf PCL retlw 0x00 ; a retlw 0x00 ; b retlw d'21' ; c 'come' retlw 0x00 ; d retlw d'89' ; e 'every' retlw 0x00 ; f retlw 0x00 ; g retlw 0x00 ; h retlw 0x00 ; i retlw 0x00 ; j retlw 0x00 ; k retlw 0x00 ; l retlw 0x00 ; m retlw 0x00 ; n retlw 0x00 ; o retlw 0x00 ; p retlw 0x00 ; q retlw 0x00 ; r retlw 0x00 ; s retlw 0x00 ; t retlw 0x00 ; u retlw 0x00 ; v retlw 0x00 ; w retlw 0x00 ; x retlw 0x00 ; y retlw 0x00 ; z retlw 0x00 ; ü retlw 0x00 ; å retlw 0x00 ; ä retlw 0x00 ; ö retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow Table_SC_question ; ?a movwf PCL retlw 0x00 ; a retlw 0x00 ; b retlw 0x00 ; c retlw 0x00 ; d retlw 0x00 ; e retlw 0x00 ; f retlw 0x00 ; g retlw 0x00 ; h retlw 0x00 ; i retlw 0x00 ; j retlw 0x00 ; k retlw d'35' ; l 'long' retlw 0x00 ; m retlw 0x00 ; n retlw 0x00 ; o retlw 0x00 ; p retlw 0x00 ; q retlw d'31' ; r 'are' retlw 0x00 ; s retlw 0x00 ; t retlw 0x00 ; u retlw 0x00 ; v retlw 0x00 ; w retlw d'40' ; x 'example' retlw 0x00 ; y retlw 0x00 ; z retlw 0x00 ; ü retlw 0x00 ; å retlw 0x00 ; ä retlw d'48' ; ö 'off' retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow Table2_SC_question ; a? movwf PCL retlw d'52' ; a 'all' retlw 0x00 ; b retlw 0x00 ; c retlw 0x00 ; d retlw 0x00 ; e retlw d'56' ; f 'first' retlw 0x00 ; g retlw 0x00 ; h retlw 0x00 ; i retlw 0x00 ; j retlw 0x00 ; k retlw 0x00 ; l retlw 0x00 ; m retlw 0x00 ; n retlw 0x00 ; o retlw 0x00 ; p retlw 0x00 ; q retlw 0x00 ; r retlw 0x00 ; s retlw 0x00 ; t retlw 0x00 ; u retlw 0x00 ; v retlw 0x00 ; w retlw 0x00 ; x retlw 0x00 ; y retlw 0x00 ; z retlw 0x00 ; ü retlw 0x00 ; å retlw 0x00 ; ä retlw 0x00 ; ö retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow Table_SC_exclamation ; !a movwf PCL retlw 0x00 ; a retlw 0x00 ; b retlw 0x00 ; c retlw 0x00 ; d retlw 0x00 ; e retlw 0x00 ; f retlw 0x00 ; g retlw 0x00 ; h retlw 0x00 ; i retlw d'66' ; j 'just' retlw 0x00 ; k retlw 0x00 ; l retlw 0x00 ; m retlw 0x00 ; n retlw 0x00 ; o retlw 0x00 ; p retlw 0x00 ; q retlw d'0' ; r retlw 0x00 ; s retlw d'62' ; t 'too' retlw 0x00 ; u retlw 0x00 ; v retlw 0x00 ; w retlw 0x00 ; x retlw 0x00 ; y retlw d'75' ; z 'we' retlw 0x00 ; ü retlw d'71' ; å 'any' retlw 0x00 ; ä retlw 0x00 ; ö retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow Table2_SC_exclamation ; a! movwf PCL retlw 0x00 ; a retlw 0x00 ; b retlw d'78' ; c 'came' retlw d'83' ; d 'don't' retlw 0x00 ; e retlw 0x00 ; f retlw 0x00 ; g retlw 0x00 ; h retlw 0x00 ; i retlw 0x00 ; j retlw 0x00 ; k retlw 0x00 ; l retlw 0x00 ; m retlw 0x00 ; n retlw 0x00 ; o retlw 0x00 ; p retlw 0x00 ; q retlw 0x00 ; r retlw 0x00 ; s retlw 0x00 ; t retlw 0x00 ; u retlw 0x00 ; v retlw 0x00 ; w retlw 0x00 ; x retlw 0x00 ; y retlw 0x00 ; z retlw 0x00 ; ü retlw 0x00 ; å retlw 0x00 ; ä retlw 0x00 ; ö retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow Table_SC_uparrow ; a movwf PCL retlw 0x00 ; a retlw 0x00 ; b retlw 0x00 ; c retlw 0x00 ; d retlw 0x00 ; e retlw 0x00 ; f retlw 0x00 ; g retlw d'8' ; h 'have' retlw 0x00 ; i retlw 0x00 ; j retlw 0x00 ; k retlw 0x00 ; l retlw 0x00 ; m retlw 0x00 ; n retlw 0x00 ; o retlw d'1' ; p 'people' retlw 0x00 ; q retlw 0x00 ; r retlw 0x00 ; s retlw 0x00 ; t retlw 0x00 ; u retlw 0x00 ; v retlw 0x00 ; w retlw d'13' ; x 'excuse' retlw 0x00 ; y retlw 0x00 ; z retlw 0x00 ; ü retlw d'20' ; å 'an' retlw 0x00 ; ä retlw 0x00 ; ö retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow Table2_SC_uparrow ; a movwf PCL retlw d'23' ; a 'at' retlw 0x00 ; b retlw 0x00 ; c retlw d'26' ; d 'during' retlw 0x00 ; e retlw 0x00 ; f retlw 0x00 ; g retlw 0x00 ; h retlw 0x00 ; i retlw 0x00 ; j retlw 0x00 ; k retlw 0x00 ; l retlw 0x00 ; m retlw 0x00 ; n retlw 0x00 ; o retlw 0x00 ; p retlw 0x00 ; q retlw 0x00 ; r retlw 0x00 ; s retlw 0x00 ; t retlw 0x00 ; u retlw 0x00 ; v retlw 0x00 ; w retlw 0x00 ; x retlw 0x00 ; y retlw 0x00 ; z retlw 0x00 ; ü retlw 0x00 ; å retlw 0x00 ; ä retlw 0x00 ; ö retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow Table_SC_downarrow ; a movwf PCL retlw 0x00 ; a 1 retlw 0x00 ; b retlw 0x00 ; c retlw 0x00 ; d retlw 0x00 ; e retlw 0x00 ; f retlw 0x00 ; g retlw 0x00 ; h retlw 0x00 ; i retlw 0x00 ; j retlw 0x00 ; k retlw 0x00 ; l retlw 0x00 ; m retlw d'39' ; n 'not' retlw 0x00 ; o retlw 0x00 ; p retlw 0x00 ; q retlw 0x00 ; r retlw 0x00 ; s retlw 0x00 ; t retlw 0x00 ; u retlw d'33' ; v 'visit' retlw 0x00 ; w retlw 0x00 ; x retlw 0x00 ; y retlw d'49' ; z 'when' retlw 0x00 ; ü retlw 0x00 ; å retlw 0x00 ; ä retlw d'43' ; ö 'often' retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow Table2_SC_downarrow ; a movwf PCL retlw 0x00 ; a retlw 0x00 ; b retlw d'54' ; c 'change' retlw 0x00 ; d retlw 0x00 ; e retlw d'61' ; f 'for' retlw 0x00 ; g retlw 0x00 ; h retlw 0x00 ; i retlw 0x00 ; j retlw 0x00 ; k retlw 0x00 ; l retlw 0x00 ; m retlw 0x00 ; n retlw 0x00 ; o retlw 0x00 ; p retlw 0x00 ; q retlw 0x00 ; r retlw 0x00 ; s retlw 0x00 ; t retlw 0x00 ; u retlw 0x00 ; v retlw 0x00 ; w retlw 0x00 ; x retlw 0x00 ; y retlw 0x00 ; z retlw 0x00 ; ü retlw 0x00 ; å retlw 0x00 ; ä retlw 0x00 ; ö retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow Table_SC_shift ; a movwf PCL retlw 0x00 ; a retlw 0x00 ; b retlw 0x00 ; c retlw 0x00 ; d retlw 0x00 ; e retlw 0x00 ; f retlw 0x00 ; g retlw 0x00 ; h retlw d'74' ; i 'I' retlw 0x00 ; j retlw 0x00 ; k retlw 0x00 ; l retlw d'81' ; m 'me' retlw 0x00 ; n retlw 0x00 ; o retlw 0x00 ; p retlw d'65' ; q 'question' retlw 0x00 ; r retlw 0x00 ; s retlw 0x00 ; t retlw d'78' ; u 'us' retlw 0x00 ; v retlw 0x00 ; w retlw 0x00 ; x retlw 0x00 ; y retlw 0x00 ; z retlw 0x00 ; ü retlw 0x00 ; å retlw 0x00 ; ä retlw 0x00 ; ö retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow Table2_SC_shift ; a movwf PCL retlw 0x00 ; a retlw d'84' ; b 'be' retlw 0x00 ; c retlw 0x00 ; d retlw d'87' ; e 'even' retlw 0x00 ; f retlw 0x00 ; g retlw 0x00 ; h retlw 0x00 ; i retlw 0x00 ; j retlw 0x00 ; k retlw 0x00 ; l retlw 0x00 ; m retlw 0x00 ; n retlw 0x00 ; o retlw 0x00 ; p retlw 0x00 ; q retlw 0x00 ; r retlw 0x00 ; s retlw 0x00 ; t retlw 0x00 ; u retlw 0x00 ; v retlw 0x00 ; w retlw 0x00 ; x retlw 0x00 ; y retlw 0x00 ; z retlw 0x00 ; ü retlw 0x00 ; å retlw 0x00 ; ä retlw 0x00 ; ö retlw 0x00 ; . retlw 0x00 ; , retlw 0x00 ; ! retlw 0x00 ; ? retlw 0x00 ; - retlw 0x00 ; ' retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; retlw 0x00 ; Up Arrow retlw 0x00 ; Down Arrow ;---------------------------------------------------------------------------- ; << Room for additional program code and tables for chordon shortcut words ;---------------------------------------------------------------------------- ;______________________end of Page2 1000h-17FFf____________________________________ ; ;PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP3333333333333333333333333333333333333333333333 ;_____________________ Page3 1800h-1FFFh (tables)__________________________________ ;================ OTHER TABLES are on Page 3 (1800h-1FFFh) ======================== ; ; ; These figures convert the chord value 1-63 to the GKOS character reference number 1-63 ; (continues up to 105 in the table) ; ; The GKOS Character set is logically arranged (alphabetical and numerical order) ; ; Three tables are used to convert the chord all the way to scan codes and IR codes: ; Table_ChordToRef => Table_GKOSrefToKeycode => Table_ScanCodeToIRCode ; ; ;===========================================================================; ; Page3: ; 0x1800 256 ; 0x1900 256 ; 0x1A00 256 ; 0x1B00 256 ; 0x1C00 256 ; 0x1D00 256 ; 0x1E00 256 ; 0x1F00 256 org 0x1800 ;Start of Program Memory Page 3 ; Table space: 1800-18FF ;the GKOS chord value is converted into GKOS ref.num. (GKOS specification) Table_ChordToRef ; Table is at 0x1800 to 0x18FF (256 items) movwf PCL retlw d'1' ;Convert Chord value to GKOS Reference number retlw d'2' retlw d'15' retlw d'3' retlw d'27' retlw d'19' retlw d'46' retlw d'4' retlw d'42' retlw d'36'; 10 retlw d'16' retlw d'33' retlw d'28' retlw d'20' retlw d'47' retlw d'5' retlw d'35' retlw d'59';SHIFT (chord=)18 retlw d'17' retlw d'32'; 20 retlw d'29' retlw d'21' retlw d'48' retlw d'7' retlw d'8' retlw d'9' retlw d'44' retlw d'10' retlw d'41' retlw d'38'; 30 retlw d'56' retlw d'6' retlw d'34' retlw d'31' retlw d'18' retlw d'43' retlw d'30' retlw d'22' retlw d'49' retlw d'23'; 40 retlw d'24' retlw d'25' retlw d'58' retlw d'26' retlw d'60';SYMB (chord=)45 retlw d'40' retlw d'62';CTRL (chord=)47 retlw d'11' retlw d'12' retlw d'13'; 50 retlw d'37' retlw d'14' retlw d'39' retlw d'45' retlw d'63';ALT (chord=)55 retlw d'50' retlw d'51' retlw d'52' retlw d'54' retlw d'53'; 60 retlw d'55' retlw d'57' retlw d'61' ;123-abc (chord=)63 retlw d'0' retlw d'0' ;return with offset in register W indicating the GKOS ref.num of the chord ; ********** Here is room for tables (256 - 64 bytes free) ;Common TV commands to device TV-specific IR codes ;tv1tv1tv1 Table_TVcode_to_TV1code ; Table is at 0x1866... (256 - 64 items) movwf PCL retlw b'00010101' ; Power ON/OFF /1 retlw b'00010011' ; P + (programmed channels) retlw b'00010000' ; P - (programmed channels) retlw b'00111011' ; Volume + retlw b'00111000' ; Volume - /5 retlw b'00000000' ; Balance Right retlw b'00000000' ; Balance Left retlw b'01111001' ; Mute retlw b'00000000' ; Bass + retlw b'00000000' ; Bass - /10 retlw b'00000000' ; Treble + retlw b'00000000' ; Treble - retlw b'00000000' ; Color + retlw b'00000000' ; Color - retlw b'00000000' ; Contrast +, Picture + /15 retlw b'00000000' ; Contrast -, Picture - retlw b'00000000' ; Brightness + retlw b'00000000' ; Brightness - retlw b'00000000' ; Hue + retlw b'00000000' ; Hue - /20 retlw b'00000000' ; Scan + (frequencies) retlw b'00000000' ; Scan - (frequencies) retlw b'00000000' ; Navi key Right retlw b'00000000' ; Navi key Left retlw b'00000000' ; Navi key Up /25 retlw b'00000000' ; Navi key Down retlw b'00000000' ; OK retlw b'00000000' ; SELECT retlw b'00000000' ; Enter retlw b'00000000' ; PRG, Program /30 retlw b'00000000' ; Normal (default settings) retlw b'00010110' ; TV (return from Text TV) retlw b'01010100' ; TTN, Text TV, videotext retlw b'01010111' ; TTM, Text TV, videotext, mixed with TV retlw b'00000000' ; Hold /35 retlw b'00000000' ; Step + retlw b'00000000' ; Step - retlw b'00000000' ; Time (clock) retlw b'00000000' ; Guide Menu retlw b'00000000' ; Video Menu /40 retlw b'00000000' ; Audio Menu retlw b'00000000' ; Exit Menu retlw b'00011100' ; P/C, Program<=>Channel retlw b'00000000' ; STR, Store retlw b'00000000' ; TP /45 retlw b'00000000' ; SIZE retlw b'00000000' ; Hold retlw b'00000000' ; INV retlw b'00000000' ; INFO retlw b'00000000' ; /50 retlw b'00000010' ; 1 /51 retlw b'00000111' ; 2 retlw b'00000100' ; 3 retlw b'00001101' ; 4 retlw b'00001110' ; 5 retlw b'00001011' ; 6 retlw b'00001000' ; 7 retlw b'00011001' ; 8 retlw b'00011010' ; 9 /59 retlw b'00000001' ; 0 /60 retlw b'00011111' ; -- / >9 retlw b'00000000' ; AUX retlw b'00000000' ; SAT retlw b'00000000' ; VCR /64 ; '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' org 0x1900 ; Space for a new table of 256 bytes: ; Starts at Program Memory Page 3 + 2x256 bytes ; Table space: 1900-19FF ;-------- ;The table below converts the GKOS ref.num into Scan Code Pointer value ;In 123 mode, the GKOS character ref.num = GKOS ref.num + 64 ; Table_GKOSrefToKeycode movwf PCL ;---------------- abc mode ------------------------ retlw 0x01 ;a /0 SYMB mode table is 128 steps down. retlw 0x02 ;b Add 128 to GKOSref if using SYMB table. retlw 0x03 ;c retlw 0x04 ;d Same goes for 123-mode but GKOSref values retlw 0x05 ;e but add only 64 to GKOSref retlw 0x06 ;f retlw 0x07 ;g SHIFT can be only applied to GKOSref retlw 0x08 ;h values 0-30 (a-ö)??? retlw 0x09 ;i retlw 0x0a ;j /10 retlw 0x0b ;k retlw 0x0c ;l retlw 0x0d ;m retlw 0x0e ;n retlw 0x0f ;o retlw 0x10 ;p retlw 0x11 ;q retlw 0x12 ;r retlw 0x13 ;s retlw 0x14 ;t /20 retlw 0x15 ;u retlw 0x16 ;v retlw 0x17 ;w retlw 0x18 ;x retlw 0x19 ;y retlw 0x1a ;z retlw 0x1b ;u (umlaut) retlw 0x1c ;å <> retlw 0x1d ;ä retlw 0x1e ;ö /30 retlw 0x1f ; . retlw 0x20 ; , retlw 0x21 ; ! retlw 0x22 ; ? retlw 0x23 ; - 35 retlw 0x24 ; ' retlw 0x25 ; \ retlw 0x26 ; / retlw 0x27 ; ¨ <> retlw 0x28 ; ~ /40 <> retlw 0x29 ; ^ <> ;ALL MODES retlw 0x2a ;Arrow up -- NAVIGATING retlw 0x2b ;Arrow down retlw 0x2c ;PgUp retlw 0x2d ;PgDn retlw 0x2e ;Backspace retlw 0x2f ;Arrow left retlw 0x30 ;Word left retlw 0x31 ;Home retlw 0x32 ;Space /50 retlw 0x33 ;Arrow right retlw 0x34 ;Word right retlw 0x35 ;End ;controls retlw 0x36 ;Enter retlw 0x37 ;Tab retlw 0x38 ;Esc retlw 0x39 ;Del1 retlw 0x3a ;Ins retlw 0x3b ;Shift (RIGHT) retlw 0x3c ;SYMB /60 (0xe8) GKOS only retlw 0x3d ;123-abc (0xe9) GKOS only retlw 0x3e ;Ctrl (LEFT) retlw 0x3f ;Alt /64 ;123 mode, add 64 to GKOS ref.num ;------------------ 123 mode ------------------------- retlw 0x40 ;1 /65 retlw 0x41 ;2 retlw 0x42 ;3 retlw 0x43 ;4 retlw 0x44 ;5 retlw 0x45 ;6 /70 retlw 0x46 ;0 retlw 0x47 ;7 retlw 0x48 ;8 retlw 0x49 ;9 retlw 0x4a ; # retlw 0x4b ; ½ <> retlw 0x4c ; & retlw 0x4d ; @ retlw 0x4e ; + retlw 0x4f ; % /80 retlw 0x50 ; = retlw 0x51 ; Y (yen) just 'y' retlw 0x52 ; * retlw 0x53 ; € <> retlw 0x54 ; $ retlw 0x55 ; £ <> retlw 0x56 ; ( retlw 0x57 ; [ retlw 0x58 ; < retlw 0x59 ; { /90 retlw 0x5a ; ) retlw 0x5b ; ] retlw 0x5c ; > retlw 0x5d ; } ; ;Down from here the same as in abc mode... retlw 0x1f ; . retlw 0x20 ; , retlw 0x21 ; ! retlw 0x22 ; ? retlw 0x23 ; - 35 retlw 0x24 ; ' retlw 0x25 ; \ retlw 0x26 ; / <> retlw 0x27 ; ¨ <> retlw 0x28 ; ~ /40 <> retlw 0x29 ; ^ <> ;ALL MODES retlw 0x2a ;Arrow up -- NAVIGATING retlw 0x2b ;Arrow down retlw 0x2c ;PgUp retlw 0x2d ;PgDn retlw 0x2e ;Backspace retlw 0x2f ;Arrow left retlw 0x30 ;Word left retlw 0x31 ;Home retlw 0x32 ;Space /50 retlw 0x33 ;Arrow right retlw 0x34 ;Word right retlw 0x35 ;End ;controls retlw 0x36 ;Enter retlw 0x37 ;Tab retlw 0x38 ;Esc retlw 0x39 ;Del1 retlw 0x3a ;Ins retlw 0x3b ;Shift (RIGHT) retlw 0x3c ;SYMB /60 (0xe8) GKOS only retlw 0x3d ;123-abc (0xe9) GKOS only retlw 0x3e ;Ctrl (LEFT) retlw 0x3f ;Alt /64 ;--------------------- SYMB mode ---------------------------- retlw 0x40 ;1 /65 retlw 0x41 ;2 retlw 0x42 ;3 retlw 0x43 ;4 retlw 0x44 ;5 retlw 0x45 ;6 /70 retlw 0x46 ;0 retlw 0x47 ;7 retlw 0x48 ;8 retlw 0x49 ;9 retlw 0x4a ; # retlw 0x4b ; ½ <> retlw 0x4c ; & retlw 0x4d ; @ retlw 0x4e ; + retlw 0x4f ; % /80 retlw 0x50 ; = retlw 0x51 ; Y (yen) just 'y' retlw 0x52 ; * retlw 0x53 ; € <> retlw 0x54 ; $ retlw 0x55 ; £ <> retlw 0x56 ; ( retlw 0x57 ; [ retlw 0x58 ; < retlw 0x59 ; { /90 retlw 0x5a ; ) retlw 0x5b ; ] retlw 0x5c ; > retlw 0x5d ; } ;symbols only in SYMB mode (GKOSref 95-105): retlw 0x5e ; : /95 retlw 0x5f ; ; retlw 0x60 ;inverted ! <> /160 retlw 0x61 ;inverted ? <> retlw 0x62 ; _ retlw 0x63 ; " retlw 0x64 ; ´ <> apostrophe instead retlw 0x65 ; ` retlw 0x66 ; | retlw 0x67 ; § <> retlw 0x68 ; ¤ <> ; retlw 0x69 ; inv.^ DOES NOT BELONG HERE BUT IS ON THE IR TABLE ;ALL MODES retlw 0x2a ;Arrow up -- NAVIGATING retlw 0x2b ;Arrow down retlw 0x2c ;PgUp retlw 0x2d ;PgDn retlw 0x2e ;Backspace retlw 0x2f ;Arrow left retlw 0x30 ;Word left retlw 0x31 ;Home retlw 0x32 ;Space /50 retlw 0x33 ;Arrow right retlw 0x34 ;Word right retlw 0x35 ;End ;controls retlw 0x36 ;Enter retlw 0x37 ;Tab retlw 0x38 ;Esc retlw 0x39 ;Del1 retlw 0x3a ;Ins retlw 0x3b ;Shift (RIGHT) retlw 0x3c ;SYMB /60 (0xe8) GKOS only retlw 0x3d ;123-abc (0xe9) GKOS only retlw 0x3e ;Ctrl (LEFT) retlw 0x3f ;Alt /63 ;------------------- end of SYMB mode ------------------- ; ABOVE, THERE IS ROOM FOR AT LEAST 3 CONSECUTIVE TABLES: ; 3 X 64 = 192 (4 X 64 = 256) ; They are the complete abc, 123 and SYMB tables. ; All include the same control codes ENTER, CTRL, TAB, at ; the end part of each table ; ; This table was LCD application specific (capitals)and used always when SHIFT ; is on and GKOSref = 1...30. For PDA, lower case is sent here too. ;---------------- abc mode ------------------------ ;/181 SHIFT mode in on and GKOSref = 1...30 ;Add 180 to GKOSref if using SYMB table. retlw 0x01 ;a /0 SYMB mode table is 128 steps down. retlw 0x02 ;b Add 128 to GKOSref if using SYMB table. retlw 0x03 ;c retlw 0x04 ;d Same goes for 123-mode but GKOSref values retlw 0x05 ;e but add only 64 to GKOSref retlw 0x06 ;f retlw 0x07 ;g SHIFT can be only applied to GKOSref retlw 0x08 ;h values 0-30 (a-ö)??? retlw 0x09 ;i retlw 0x0a ;j /10 retlw 0x0b ;k retlw 0x0c ;l retlw 0x0d ;m retlw 0x0e ;n retlw 0x0f ;o retlw 0x10 ;p retlw 0x11 ;q retlw 0x12 ;r retlw 0x13 ;s retlw 0x14 ;t /20 retlw 0x15 ;u retlw 0x16 ;v retlw 0x17 ;w retlw 0x18 ;x retlw 0x19 ;y retlw 0x1a ;z retlw 0x1b ;u (umlaut) retlw 0x1c ;å <> retlw 0x1d ;ä retlw 0x1e ;ö /30 ;------------ END OF SHIFT TABLE ------------ org 0x1A00 ; Table space: 1A00-1AFF ; SONY SIRCS codes for MD ; Convert key scan code value to IRcode ; In Control mode: add 128 Table_ScanCodeToIRCode ; ; MD / Edit mode / Write name / 1-63 movwf PCL ;EDIT MODE /Scan code ; 20-bit SIRCS: retlw 0x61 ;a /1 retlw 0x62 ;b /2 retlw 0x63 ;c retlw 0x64 ;d retlw 0x65 ;e retlw 0x66 ;f retlw 0x67 ;g retlw 0x68 ;h retlw 0x69 ;i retlw 0x6a ;j /10 retlw 0x6b ;k retlw 0x6c ;l retlw 0x6d ;m retlw 0x6e ;n retlw 0x6f ;o retlw 0x70 ;p retlw 0x71 ;q retlw 0x72 ;r retlw 0x73 ;s retlw 0x74 ;t /20 retlw 0x75 ;u retlw 0x76 ;v retlw 0x77 ;w retlw 0x78 ;x retlw 0x79 ;y retlw 0x7a ;z /26 retlw 0x75 ;ü (u) retlw 0x61 ;å (a) retlw 0x61 ;ä (a) retlw 0x6f ;ö (o) /30 retlw 0x2e ;. retlw 0x2c ;, retlw 0x21 ;! retlw 0x3f ;? retlw 0x2d ;- retlw 0x27 ;' retlw 0x5c ;\ (just ASCII) retlw 0x2f ;/ retlw 0x20 ;¨ (space) retlw 0x7e ;~ (just ASCII) /40 retlw 0x5e ;^ (just ASCII) ;---- always 13-bit SIRCS: retlw 0xff ;Arrow up retlw 0x1d ;Arrow down Continue to play retlw 0x16 ;Page up Eject retlw 0x15 ;Page down Power ON/OFF retlw 0x2b ;Backspace (STOP) Rewind (= cursor left) retlw 0x2b ;Arrow left (Skip-) Rewind (= cursor left) retlw 0x2b ;Word left (Skip-) retlw 0x2b ;Home Rewind retlw 0x4c ;Space (Play) Space (= cursor right) retlw 0x2c ;Arrow right (Skip+) Forward (= cursor right) retlw 0x2c ;Word right (Skip-) retlw 0x2c ;End Forward retlw 0x3c ;Enter (Enter) Write Name (= store name) retlw 0x18 ;Tab Display/Char retlw 0xff ;Esc STOP (and return to command mode) retlw 0x0f ;Delete Clear retlw 0xff ;Insert retlw 0xff ;(Shift ON) retlw 0xff ;(Header for IR link) retlw 0xff ;(123-ABC) retlw 0xff ;(Ctrl ON) retlw 0xff ;(Alt ON) ; MD / Edit mode / Write num / 64-128 ; 20-bit SIRCS: retlw 0x31 ;1 /64 retlw 0x32 ;2 retlw 0x33 ;3 retlw 0x34 ;4 retlw 0x35 ;5 retlw 0x36 ;6 retlw 0x30 ;0 /70 retlw 0x37 ;7 retlw 0x38 ;8 retlw 0x39 ;9 retlw 0x0a ;(0x23 = #) -- / >25 retlw 0x20 ;½ (Space) (0x1f = Program) retlw 0x26 ;& retlw 0x0a ;@ -- / >25 retlw 0x2b ;+ retlw 0x25 ;% retlw 0x20 ;= /80 retlw 0x20 ;yen retlw 0x2a ;* retlw 0x20 ;€ retlw 0x24 ;$ retlw 0x20 ;£ retlw 0x28 ;( retlw 0x28 ;[ retlw 0x3c ;< retlw 0x29 ;{ retlw 0x29 ;) /90 retlw 0x29 ;] retlw 0x3e ;> retlw 0x29 ;} retlw 0x3a ;: retlw 0x3b ;; retlw 0x20 ;inv.! retlw 0x20 ;inv.? retlw 0x20 ;_ retlw 0x22 ;" retlw 0x2a ;´(') /100 retlw 0x2a ;`(') retlw 0x20 ;| retlw 0x20 ;§ retlw 0x20 ;¤ retlw 0x20 ;inv.^ ; Always 13-bit SIRCS: retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; /110 retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; /120 retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; /128 ; MD / Control mode / 129-255 Table_ScanCodeToIRCode_S movwf PCL ; ; 13-bit SIRCS: retlw 0xff ;A Vol+ /129 ddd dddd retlw 0x20 ;B Skip- /130 0010 0000 retlw 0xff ;C Vol- 0001 1001 retlw 0xff ;D Ch+ retlw 0x21 ;E Skip+ retlw 0xff ;F Ch- retlw 0xff ;G retlw 0x1e ;H Shuffle retlw 0xff ;I retlw 0xff ;J retlw 0x0a ;K Num (>25) retlw 0x19 ;L Scroll /140 retlw 0x1f ;M Program retlw 0x0a ;N Num (>25) retlw 0x29 ;O Pause retlw 0x29 ;P Pause retlw 0xff ;Q retlw 0x2d ;R RECORD retlw 0x19 ;S Scroll retlw 0x3c ;T Name (Title) retlw 0xff ;U retlw 0xff ;V /150 retlw 0x2c ;W Foreward retlw 0xff ;X retlw 0x18 ;Y Display/Char retlw 0xff ;Z retlw 0x2b ;Ü Rewind retlw 0xff ;Å retlw 0xff ;Ä retlw 0xff ;Ö retlw 0xff ;. retlw 0xff ;, /160 retlw 0xff ;! retlw 0xff ;? retlw 0xff ;- retlw 0xff ;' retlw 0xff ;\ retlw 0xff ;/ retlw 0xff ;¨ retlw 0xff ;~ retlw 0xff ;^ retlw 0xff ;Arrow up /170 retlw 0x1d ;Arrow down Continue to play retlw 0x16 ;Page up Eject retlw 0x15 ;Page down Power ON/OFF retlw 0x28 ;Backspace STOP retlw 0x20 ;Arrow left Skip- retlw 0x20 ;Word left Skip- retlw 0x2b ;Home Rewind retlw 0x2a ;Space Play retlw 0x21 ;Arrow right Skip+ retlw 0x21 ;Word right Skip+ /180 retlw 0x2c ;End Forward retlw 0x3b ;Enter Enter retlw 0x18 ;Tab Display/Char retlw 0x28 ;Esc STOP retlw 0x0f ;Delete Clear retlw 0xff ;Insert ; next 5 not to be used for Remote control retlw 0xff ;Shift OFF retlw 0xff ;(Header + 128) retlw 0xff ;123-ABC (just change symbol set) retlw 0xff ;Ctrl OFF /190 retlw 0xff ;Alt OFF ; Remote control mode / numbers retlw 0x00 ;1 1... retlw 0x01 ;2 retlw 0x02 ;3 retlw 0x03 ;4 retlw 0x04 ;5 retlw 0x05 ;6 retlw 0x09 ;0 retlw 0x06 ;7 retlw 0x07 ;8 /200 retlw 0x08 ;9 ...9 retlw 0x0a ;# --/>25 (--/>9) retlw 0xff ;½ retlw 0xff ;& retlw 0xff ;@ retlw 0xff ;+ retlw 0xff ;% retlw 0xff ;= retlw 0xff ;yen retlw 0xff ;* /210 retlw 0xff ;€ retlw 0xff ;$ retlw 0xff ;£ retlw 0xff ;( retlw 0xff ;[ retlw 0xff ;< retlw 0xff ;{ retlw 0xff ;) retlw 0xff ;] retlw 0xff ;> /220 retlw 0xff ;} retlw 0xff ;: retlw 0xff ;; retlw 0xff ;inv.! retlw 0xff ;inv.? retlw 0xff ;_ retlw 0xff ;" retlw 0xff ;´ retlw 0xff ;` retlw 0xff ;| /230 retlw 0xff ;§ retlw 0xff ;¤ retlw 0xff ;inv.^ retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ;IR Device Address 6 retlw 0xff ;IR Device Address 7 retlw 0xff ;IR Device Address 0 /240 retlw 0xff ;IR Device Address 1 retlw 0xff ;IR Device Address 2 retlw 0xff ;IR Device Address 3 retlw 0xff ;IR Device Address 4 retlw 0xff ;IR Device Address 5 retlw 0xff ;AltGr OFF retlw 0xff ;CAPS OFF retlw 0xff ; retlw 0xff ; retlw 0xff ; /250 retlw 0xff ; /251 retlw 0xff ; /252 retlw 0xff ; /253 retlw 0xff ; Last item is removed because the table must be max 256 bytes long ; retlw 0xff ; /255 (254 = SYMB!!!) ; 255 items + 2 x PCL = 257 => remove one line at the end to fit 256 bytes ; last item is number 254 (SYMB) ;---------------------------------------------- org 0x1B00 ; Space for a new table of 256 bytes: ; Starts at Program Memory Page 3 + 3x256 bytes ; Table space: 1B00-1BFF ; TV / Control mode / 129-255 ;tktktktk Table_Keycode_to_TVcode movwf PCL ; retlw 0x04 ;A Vol+ /129 ddd dddd retlw 0x24 ;B Navi key L /130 0010 0000 retlw 0x05 ;C Vol- 0001 1001 retlw 0x02 ;D P+ retlw 0x23 ;E Navi key R retlw 0x03 ;F P- retlw 0xff ;G retlw 0xff ;H (MD: shuffle) retlw 0xff ;I retlw 0xff ;J retlw 0x0a ;K Num (>25) retlw 0x19 ;L Scroll /140 retlw 0x1f ;M Program retlw 0x0a ;N Num (>25) retlw 0x29 ;O Pause retlw 0x29 ;P Pause retlw 0xff ;Q retlw 0x2d ;R RECORD retlw 0x19 ;S Scroll retlw 0x3c ;T Name (Title) retlw 0xff ;U retlw 0xff ;V /150 retlw 0x2c ;W Foreward retlw 0xff ;X retlw 0x18 ;Y Display/Char retlw 0xff ;Z retlw 0x2b ;Ü Rewind retlw 0xff ;Å retlw 0xff ;Ä retlw 0xff ;Ö retlw 0xff ;. retlw 0xff ;, /160 retlw 0xff ;! retlw 0xff ;? retlw 0xff ;- retlw 0xff ;' retlw 0xff ;\ retlw 0xff ;/ retlw 0xff ;¨ retlw 0xff ;~ retlw 0xff ;^ retlw 0xff ;Arrow up /170 retlw 0x1d ;Arrow down Continue to play retlw 0x16 ;Page up Eject retlw 0x01 ;Page down Power ON/OFF retlw 0x28 ;Backspace STOP retlw 0x20 ;Arrow left Skip- retlw 0x20 ;Word left Skip- retlw 0x2b ;Home Rewind retlw 0x2a ;Space Play retlw 0x21 ;Arrow right Skip+ retlw 0x21 ;Word right Skip+ /180 retlw 0x2c ;End Forward retlw 0x3b ;Enter Enter retlw 0x18 ;Tab Display/Char retlw 0x28 ;Esc STOP retlw 0x0f ;Delete Clear retlw 0xff ;Insert ; next 5 not to be used for Remote control retlw 0xff ;Shift OFF retlw 0xff ;(Header + 128) retlw 0xff ;123-ABC --/>25 retlw 0xff ;Ctrl OFF /190 retlw 0xff ;Alt OFF ; Remote control mode / numbers retlw 0x00 ;1 1... retlw 0x01 ;2 retlw 0x02 ;3 retlw 0x03 ;4 retlw 0x04 ;5 retlw 0x05 ;6 retlw 0x09 ;0 retlw 0x06 ;7 retlw 0x07 ;8 /200 retlw 0x08 ;9 ...9 retlw 0x0a ;# --/>25 (--/>9) retlw 0xff ;½ retlw 0xff ;& retlw 0xff ;@ retlw 0xff ;+ retlw 0xff ;% retlw 0xff ;= retlw 0xff ;yen retlw 0xff ;* /210 retlw 0xff ;€ retlw 0xff ;$ retlw 0xff ;£ retlw 0xff ;( retlw 0xff ;[ retlw 0xff ;< retlw 0xff ;{ retlw 0xff ;) retlw 0xff ;] retlw 0xff ;> /220 retlw 0xff ;} retlw 0xff ;: retlw 0xff ;; retlw 0xff ;inv.! retlw 0xff ;inv.? retlw 0xff ;_ retlw 0xff ;" retlw 0xff ;´ retlw 0xff ;` retlw 0xff ;| /230 retlw 0xff ;§ retlw 0xff ;¤ retlw 0xff ;inv.^ retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ;IR Device Address 6 retlw 0xff ;IR Device Address 7 retlw 0xff ;IR Device Address 0 /240 retlw 0xff ;IR Device Address 1 retlw 0xff ;IR Device Address 2 retlw 0xff ;IR Device Address 3 retlw 0xff ;IR Device Address 4 retlw 0xff ;IR Device Address 5 retlw 0xff ;AltGr OFF retlw 0xff ;CAPS OFF retlw 0xff ; retlw 0xff ; retlw 0xff ; /250 retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; retlw 0xff ; /255 ; last item is number 255 ; Table for Chordon Shortcuts org 0x1c00 ; Space for a table of 256 bytes: 1C00 - 1CFF ; Chord values for shortcut words, ending with 0x00 TableA_shortcuts ; FOR ' - . movwf PCL retlw d'16' ;'p' 1 'put' 'p retlw d'21' ;'u' retlw d'20' ;'t' retlw d'0' ;'end' retlw d'9' ;'i' 5 'is' 'i retlw d'19' ;'s' retlw d'0' ;'end' retlw d'20' ;'t' 8 'that' 't retlw d'8' ;'h' retlw d'1' ;'a' retlw d'20' ;'t' retlw d'0' ;'end' retlw d'25' ;'y' 13 'you' 'y retlw d'15' ;'o' retlw d'21' ;'u' retlw d'0' ;'end' retlw d'2' ;'b' 17 'but' b' retlw d'21' ;'u' retlw d'20' ;'t' retlw d'0' ;'end' retlw d'4' ;'d' 21 'do' d' retlw d'15' ;'o' retlw d'0' ;'end' retlw d'17' ;'q' 24 'quite' -q retlw d'21' ;'u' retlw d'9' ;'i' retlw d'20' ;'t' retlw d'5' ;'e' retlw d'0' ;'end' retlw d'8' ;'h' 30 'he' -h retlw d'5' ;'e' retlw d'0' ;'end' retlw d'12' ;'l' 33 'like' -l retlw d'9' ;'i' retlw d'11' ;'k' retlw d'5' ;'e' retlw d'0' ;'end' retlw d'20' ;'t' 38 'they' -the_ retlw d'8' ;'h' retlw d'5' ;'e' retlw d'25' ;'y' retlw d'0' ;'end' retlw d'1' ;'a' 43 'am' a- retlw d'13' ;'m' retlw d'0' ;'end' retlw d'5' ;'e' 46 'each' e- retlw d'1' ;'a' retlw d'3' ;'c' retlw d'8' ;'h' retlw d'0' ;'end' retlw d'0' ;'end' retlw d'22' ;'v' 52 'very' .v retlw d'5' ;'e' retlw d'18' ;'r' retlw d'25' ;'y' retlw d'0' ;'end' retlw d'13' ;'m' 57 'much' .m retlw d'21' ;'u' retlw d'3' ;'c' retlw d'8' ;'h' retlw d'0' ;'end' retlw d'18' ;'r' 62 'right' .r retlw d'9' ;'i' retlw d'7' ;'g' retlw d'8' ;'h' retlw d'20' ;'t' retlw d'0' ;'end' retlw d'25' ;'y' 68 'yes' .y retlw d'5' ;'e' retlw d'19' ;'s' retlw d'0' ;'end' retlw d'2' ;'b' 72 'been' b. retlw d'5' ;'e' retlw d'5' ;'e' retlw d'14' ;'n' retlw d'0' ;'end' retlw d'6' ;'f' 77 'from' f. retlw d'18' ;'r' retlw d'15' ;'o' retlw d'13' ;'m' 80 retlw d'0' ;'end' retlw d'0' ;'' 82 retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' 90 retlw d'0' ;'' 91 retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' 100 retlw d'0' ;'' 101 retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' 110 retlw d'0' ;'' 111 retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' 120 retlw d'0' ;'' 121 retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' 126 org 0x1d00 ; Space for a table of 256 bytes: 1D00 - 1DFF TableB_shortcuts ; FOR , ? ! movwf PCL retlw d'21' ;'u' 1 'up' ,u retlw d'16' ;'p' retlw d'0' ;'end' retlw d'14' ;'n' 4 'no' ,n retlw d'15' ;'o' retlw d'0' ;'end' retlw d'3' ;'c' 7 'certain' ,j retlw d'5' ;'e' retlw d'18' ;'r' retlw d'20' ;'t' 10 retlw d'1' ;'a' 11 retlw d'9' ;'i' retlw d'14' ;'n' retlw d'0' ;'end' retlw d'20' ;'t' 15 'there' ,the_ retlw d'8' ;'h' retlw d'5' ;'e' retlw d'18' ;'r' retlw d'5' ;'e' retlw d'0' ;'end' retlw d'3' ;'c' 21 'come' c, retlw d'15' ;'o' retlw d'13' ;'m' retlw d'5' ;'e' retlw d'0' ;'end' retlw d'0' ;'' 26 retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'end' retlw d'1' ;'a' 31 'are' ?r retlw d'18' ;'r' retlw d'5' ;'e' retlw d'0' ;'end' retlw d'12' ;'l' 35 'long' ?l retlw d'15' ;'o' retlw d'14' ;'n' retlw d'7' ;'g' retlw d'0' ;'end' retlw d'5' ;'e' 40 'example' ?x retlw d'24' ;'x' 41 retlw d'1' ;'a' retlw d'13' ;'m' retlw d'16' ;'p' retlw d'12' ;'l' retlw d'5' ;'e' retlw d'0' ;'end' retlw d'15' ;'o' 48 'off' ?of_ retlw d'6' ;'f' retlw d'6' ;'f' retlw d'0' ;'end' retlw d'1' ;'a' 52 'all' a? retlw d'12' ;'l' retlw d'12' ;'l' retlw d'0' ;'end' retlw d'6' ;'f' 56 'first' f? retlw d'9' ;'i' retlw d'18' ;'r' retlw d'19' ;'s' retlw d'20' ;'t' retlw d'0' ;'end' 61 retlw d'20' ;'t' 62 'too' !t retlw d'15' ;'o' retlw d'15' ;'o' retlw d'0' ;'end' retlw d'10' ;'j' 66 'just' !j retlw d'21' ;'u' retlw d'19' ;'s' retlw d'20' ;'t' retlw d'0' ;'end' retlw d'1' ;'a' 71 'any' !and_ retlw d'14' ;'n' retlw d'25' ;'y' retlw d'0' ;'end' retlw d'23' ;'w' 75 'we' !z retlw d'5' ;'e' retlw d'0' ;'end' retlw d'3' ;'c' 78 'came' c! retlw d'1' ;'a' retlw d'13' ;'m' retlw d'5' ;'e' 81 retlw d'0' ;'end' retlw d'4' ;'d' 83 'don't' d! retlw d'15' ;'o' retlw d'14' ;'n' retlw d'36' ;''' retlw d'20' ;'t' retlw d'0' ;'end' retlw d'5' ;'e' 89 'every' retlw d'22' ;'v' retlw d'5' ;'e' 90 retlw d'18' ;'r' 91 retlw d'25' ;'y' retlw d'0' ;'end' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' 100 retlw d'0' ;'' 101 retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' 110 retlw d'0' ;'' 111 retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' 120 retlw d'0' ;'' 121 retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' 126 org 0x1e00 ; Space for a table of 256 bytes: 1E00 - 1EFF TableC_shortcuts ; FOR Up Dn Shift movwf PCL retlw d'16' ;'p' 1 'people' Up retlw d'5' ;'e' retlw d'15' ;'o' retlw d'16' ;'p' retlw d'12' ;'l' retlw d'5' ;'e' retlw d'0' ;'end' retlw d'8' ;'h' 8 'have' Uh retlw d'1' ;'a' retlw d'22' ;'v' 10 retlw d'5' ;'e' 11 retlw d'0' ;'end' retlw d'5' ;'e' 13 'excuse' Ux retlw d'24' ;'x' retlw d'3' ;'c' retlw d'21' ;'u' retlw d'19' ;'s' retlw d'5' ;'e' retlw d'0' ;'end' retlw d'1' ;'a' 20 'an' Uand_ retlw d'14' ;'n' 21 retlw d'0' ;'end' retlw d'1' ;'a' 23 'at' aU retlw d'20' ;'t' retlw d'0' ;'end' retlw d'4' ;'d' 26 'during' Du retlw d'21' ;'u' retlw d'18' ;'r' retlw d'9' ;'i' retlw d'14' ;'n' retlw d'7' ;'g' 31 retlw d'0' ;'end' retlw d'22' ;'v' 33 'visit' Dv retlw d'9' ;'i' retlw d'19' ;'s' retlw d'9' ;'i' retlw d'20' ;'t' retlw d'0' ;'end' retlw d'14' ;'n' 39 'not' Dn retlw d'15' ;'o' retlw d'20' ;'t' 41 retlw d'0' ;'end' retlw d'15' ;'o' 43 'often' Dof_ retlw d'6' ;'f' retlw d'20' ;'t' retlw d'5' ;'e' retlw d'14' ;'n' retlw d'0' ;'end' retlw d'23' ;'w' 49 'when' Dz retlw d'8' ;'h' retlw d'5' ;'e' 51 retlw d'14' ;'n' retlw d'0' ;'end' retlw d'3' ;'c' 54 'change' cD retlw d'8' ;'h' retlw d'1' ;'a' retlw d'14' ;'n' retlw d'7' ;'g' retlw d'5' ;'e' retlw d'0' ;'end' retlw d'6' ;'f' 61 'for' fD retlw d'15' ;'o' retlw d'18' ;'r' retlw d'0' ;'end' retlw d'17' ;'q' 65 'question' fD retlw d'21' ;'u' retlw d'5' ;'e' retlw d'19' ;'s' retlw d'20' ;'t' retlw d'9' ;'i' retlw d'15' ;'o' 71 retlw d'14' ;'n' retlw d'0' ;'end' retlw d'59' ;'ShiftON' 74 'I' Si retlw d'9' ;'i' retlw d'0' ;'ShiftOFF' (186?) retlw d'0' ;'end' retlw d'21' ;'u' 78 'us' Su retlw d'19' ;'s' retlw d'0' ;'end' retlw d'13' ;'m' 81 'me' Sm retlw d'5' ;'e' retlw d'0' ;'end' retlw d'2' ;'b' 84 'be' bS retlw d'5' ;'e' retlw d'0' ;'and' retlw d'5' ;'e' 87 'even' eS retlw d'22' ;'v' retlw d'5' ;'e' retlw d'14' ;'n' retlw d'0' ;'end' 90 retlw d'0' ;'' 91 retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' 100 retlw d'0' ;'' 101 retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' 110 retlw d'0' ;'' 111 retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' 120 retlw d'0' ;'' 121 retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' retlw d'0' ;'' 126 ; Serial port Message example: ; movwf PCL ; retlw 'o' ;ASCII 'o' ; retlw 'k' ;ASCII 'k' ; retlw '!' ;ASCII '!' ; retlw d'0' ;decimal zero ; ========== START OF MEMORY PAGE 3 KEYBOARD TABLE==================== ; ; ; org 0x1A00 ; later in program Memory Page 3, after FIN/SWE table END ; directive 'end of program'