TI-H: AVR+KBD+Calc=Fun
[Prev][Next][Index][Thread]
TI-H: AVR+KBD+Calc=Fun
Substitute the serial send routine for the TI send routine...
I hope you have fun... :)
;*****************************************************
;* *
;* 101 Key, IBM Keyboard Decoder for AVR series. *
;* *
;* Copyright 1998 - Grant Stockly *
;* 25th June 1998 *
;* *
;* Includes ALTDEC & CTRLHEX Routines *
;* *
;*****************************************************
.include "8515def.inc"
.equ nreset =4
.equ datain =0
.equ clkin =1
.equ dataout =2
.equ clkout =3
.equ TxD =1 ;Transmit pin is PD1
; Equates for LED Byte
.equ pscrlck =7 ; If true, Scroll Lock Pressed
.equ pnumlck =6 ; If true, Num Lock Pressed
.equ caplock =2 ; If true, Caps Lock is On (Active)
.equ numlock =1 ; If true, Num Lock is On (Active)
.equ scrlock =0 ; If true, Num Lock is On (Active)
; Equates for Status Flag, Byte
.equ rctrl =7 ; If true, Right Ctrl Pressed
.equ lctrl =6 ; If true, Left Ctrl Pressed
.equ ralt =5 ; If true, Right Alt Pressed
.equ lalt =4 ; If true, Left Alt Pressed
.equ caploc =2 ; If true, Caps Lock Pressed
.equ rshift =1 ; If true, Right Shift Key Pressed
.equ lshift =0 ; If true, Left Shift Key Pressed
.def byte =r18 ; Used to hold byte, during Trans & Rec
.def status =r19 ; Status Flags
.def LED =r20 ; LED Flags
.def delay =r21 ; delay
.def count =r22 ; counter
.def bitcnt =R23 ;bit counter
.def temp =R24 ;temporary storage register
.def Txbyte =R25 ;Data to be transmitted
.def RXbyte =R26 ;Received data
Start:
cbi PORTB, dataout
cbi PORTB, clkout
rjmp rstflag ;No Attempt to Reset Keyboard made
;as keyboard would still be
in POST
;or BAT Tests, if power
applied at
;the same time than the HC705.
;*****************************************************
;* *
;* reset - Sends a Reset Command to the Keyboard. *
;* Not a very good effort to reset keyboard, *
;* as it doesn't check for ACK or BAT *
;* Completion Code. I.e. Reset may not of *
;* even Worked! *
;* *
;*****************************************************
reset:
ldi byte, $FF ;Reset Keyboard
rcall transmit
;*****************************************************
;* *
;* rstflag - Resets Status and LED Flags. Used when *
;* a successful Bat Completion code is *
;* sent to sync keyboard's LED's to 705's *
;* status register *
;* *
;*****************************************************
rstflag:
clr status
clr LED
;*****************************************************
;* *
;* main - Main Keyboard Decoding Routine. Once key *
;* been decoded, program should return here *
;* *
;*****************************************************
main:
rcall Receive ;Get's a Single Byte from the Keyboard.
cpi byte, $F0 ;A Key has been Released
brne main1
rjmp release
main1:
cpi byte, $AA ;Successful Completion of BAT
brne main2
rjmp rstflag
main2:
cpi byte, $E0 ;Extended Keys
brne main3
rjmp extend
main3:
cpi byte, $12 ;Left Shift Key Pressed
brne main4
sbr status, lshift
main4:
cpi byte, $59 ;Right Shift Key Pressed
brne main5
sbr status, rshift
main5:
cpi byte, $14 ;Left Ctrl
brne main6
sbr status, lctrl
main6:
cpi byte, $11 ;Left Alt
brne main7
sbr status, lalt
main7:
cpi byte, $58 ;Caps Lock Pressed
brne main8
sbrs status, caploc
rcall caps
sbr status, caploc
main8:
cpi byte, $7E ;Scroll Lock Pressed
brne main9
sbrs status, pscrlck
rcall scrl
sbr status, pscrlck
main9:
cpi byte, $77 ;Num Lock Pressed
brne main10
sbrs status, pnumlck
rcall nums
sbr status, pnumlck
main10:
cpi byte, $8F ;Last Value in Look-Up Table
brlo main11
rjmp main ;Out of Bounds
main11:
sbrc LED, caplock
rcall caps_on
sbrc status, rshift
rcall shifton
sbrc status, lshift
rcall shifton
cancel:
rcall noshift ;Load Lower Case Values
rjmp main12
caps_on:
sbrc status, rshift ;If ShiftLock & Shift, Cancel
rjmp cancel
sbrc status, lshift
rjmp cancel
shifton:
rcall shift ;Load Upper Case Values
main12:
andi status, $30 ;Either Alt Key Pressed
breq main13
main13:
andi status, $C0 ;Either CTRL Key Pressed
breq main14
main14:
rcall putchar ;Send to RS232
return:
rjmp main
;*****************************************************
;* *
;* caps - Toggle Status of Caps lock and Echo to *
;* Keyboard *
;* *
;*****************************************************
caps:
sbr status, caploc ; Set caploc flag to prevent
routine being
; called again
ori LED, $04 ; Toggle Shift Lock Flag
rjmp LEDshow
;*****************************************************
;* *
;* nums - Toggle Status of Nums lock and Echo to *
;* Keyboard *
;* *
;*****************************************************
nums:
sbr status, pnumlck
ori LED, $02
rjmp LEDshow
;*****************************************************
;* *
;* scrl - Toggle Status of Scroll lock and Echo to *
;* Keyboard *
;* *
;*****************************************************
scrl:
sbr status, pscrlck
ori LED, $01
rjmp LEDshow
;*****************************************************
;* *
;* extend - An Extended Key has been Pressed *
;* *
;*****************************************************
extend:
rcall Receive ;Get Next byte
cpi byte, $F0 ;An Extended Key Has been Released
brne extend1
rjmp rel_ext
extend1:
cpi byte, $11 ;Right Alt Pressed
brne extend2
sbr status, ralt
extend2:
cpi byte, $14 ;Right Ctrl Pressed
brne extend3
sbr status, rctrl
extend3:
cpi byte, $71 ;Delete
brne extend4
andi status, $C0 ;Either Alt Key Pressed?
breq extend4
andi status, $30 ;Either Ctrl Key Pressed?
breq extend4
sbi PORTB, nreset
ldi delay, $FF
rcall delay
cbi PORTB, nreset
rjmp reset
extend4:
cpi byte, $5A ;Enter Key on Num Keypad
brne extend5
ldi byte, $0D
rcall putchar
extend5:
cpi byte, $4A ; '/' Key on Num Keypad
brne extend6
ldi byte, $2F
rcall putchar
extend6:
rjmp main ;Return to main
;*****************************************************
;* *
;* release - A Key has been Released *
;* *
;*****************************************************
release:
rcall Receive ;Release - Next Byte Garbage in many cases
releas3:
cpi byte, $12 ;Left Shift Key Released
brne releas4
cbr status, lshift
releas4:
cpi byte, $59 ;Right Shift Key Released
brne releas5
sbr status, rshift
releas5:
cpi byte, $14 ;Left Ctrl Released
brne releas6
cbr status, lctrl
releas6:
cpi byte, $11 ;Left Alt Released
brne releas7
cbr status, lalt
releas7:
cpi byte, $58 ;Caps Lock Released
brne releas8
cbr status, caploc
releas8:
cpi byte, $7E ;Scroll Lock Released
brne releas9
cbr status, pscrlck
releas9:
cbr byte, $77 ;Num Lock Released
brne relea10
cbr status, pnumlck
relea10:
rjmp main ;Return to Main
;*****************************************************
;* *
;* rel_ext - An Extended Key has been Released *
;* *
;*****************************************************
rel_ext:
rcall Receive ;Get Next byte
rel_ex2:
rel_ex3:
rjmp main ;Return to main
;*****************************************************
;* *
;* LEDshow - Copies the 3 LSB of the LED register to *
;* keyboard for the keyboards Status LED's *
;* E.g. Num Lock, Caps Lock, Scroll Lock *
;* Also makes their status present on *
;* PORTA *
;* *
;*****************************************************
LEDshow:
andi LED, $07
out PORTA, LED ;Made Status Avalible at PORTA
ldi byte, $ED
rcall transmit
rcall Receive
andi LED, $07
mov byte, LED
rcall transmit
rjmp main
;*****************************************************
;* *
;* Transmit - Send Data stored at Byte to the *
;* Keyboard. Result *
;* *
;*****************************************************
transmit:
cbi PORTB, clkout
cbi PORTB, dataout ;Make sure outputs are low.
ldi count, $08
sbi PORTB, clkout ;Set Clock Low
ldi delay, $13 ;Delay 64uS
rcall delay
sbi PORTB, dataout ;Set Data Low
cbi PORTB, clkout ;Release Clock Line
rcall highlow
loop:
ror byte
brcs mark
space:
sbi PORTB, dataout ; Clear Bit
rjmp next
mark:
cbi PORTB, dataout ; Clear Bit
inc byte ; Parity Calculation
next:
rcall highlow ; Wait for high to low transition
dec count
brne loop
andi byte, $01
brne clr_par
set_par:
cbi PORTB, dataout
rjmp tr_ackn
clr_par:
sbi PORTB, dataout
tr_ackn:
rcall highlow
cbi PORTB, dataout ;Release Data Line
rcall highlow
sbic PORTB, datain
rcall error ;Check for Ack
amy:
sbis PORTB, clkin
rjmp amy ;Wait for idle line
sbi PORTB, clkout ;Prevent Keyboard from sending data
;(Clear to Send)
ret
error:
ldi byte, $FF ;Reset
rcall transmit
ret
delay:
dec count ; Delay = 6[A] + 6
brne delay
ret
;*****************************************************
;* *
;* Receive - Get a Byte from the Keyboard. Result *
;* stored in byte. *
;* *
;*****************************************************
Receive:
ldi count, 08 ;Number of Bits
cbi PORTB, clkout ;Clear to Send
gantt:
sbic PORTB, clkin
rjmp gantt ;wait for idle Clock
sbic PORTB, datain
rjmp Receive ;False Start Bit, Restart
Recdata:
ror byte
rcall highlow ;Wait for high to low Transision
sbic PORTB, datain
rcall Recset
sbr byte, 7
rjmp Recnext
Recset:
sbr byte, 7
inc byte
Recnext:
dec count
brne Recdata ;Loop until 8 bits been received
rcall highlow
andi byte, $01
breq r_error
rjmp highlow
sbis PORTB, datain
rcall r_error ;Stop Bit Detection
sbi PORTB, clkout ;Prevent Keyboard from sending data
;(Clear to Send)
ret
r_error:
ldi byte, $FE ;Resend
rcall Transmit
rjmp Receive ;Try again
;*****************************************************
;* *
;* highlow - Waits for next High to Low Transistion *
;* on the Clock Line *
;* *
;*****************************************************
highlow:
sbis PORTB, clkin
rjmp highlow ;Loop until Clk High
yma:
sbic PORTB, clkin
rjmp yma ;Loop until Clk Low
ret
;*****************************************************
;* *
;* RS-232 NRZ 8N1 Transmit Routine. *
;* *
;* Uses a 4.00 Mhz Crystal (2 Mhz Bus Speed) *
;* to obtain a transmission speed of 9600 BPS *
;* *
;*****************************************************
;Its realy 19200 with 1 stop bit... :)
;***************************************************************************
;*
;* "putchar"
;*
;* This subroutine transmits the byte stored in the "Txbyte" register
;* The number of stop bits used is set with the sb constant
;*
;* Number of words :14 including return
;* Number of cycles :Depens on bit rate
;* Low registers used :None
;* High registers used :2 (bitcnt,Txbyte)
;* Pointers used :None
;*
;***************************************************************************
.equ sb =1 ;Number of stop bits (1, 2,
...)
putchar:
ldi bitcnt,9+sb ;1+8+sb (sb is # of stop bits)
com byte ;Inverte everything
sec ;Start bit
putchar0:
brcc putchar1 ;If carry set
cbi PORTD,TxD ;send a '0'
rjmp putchar2 ;else
putchar1:
sbi PORTD,TxD ;send a '1'
nop
putchar2:
rcall UART_delay ;One bit delay
rcall UART_delay
lsr byte ;Get next bit
dec bitcnt ;If not all bit sent
brne putchar0 ;send next
;else
ret ;return
;***************************************************************************
;*
;* "UART_delay"
;*
;* This delay subroutine generates the required delay between the bits when
;* transmitting and receiving bytes. The total execution time is set by the
;* constant "b":
;*
;* 3b + 7 cycles (including rcall and ret)
;*
;* Number of words :4 including return
;* Low registers used :None
;* High registers used :1 (temp)
;* Pointers used :None
;*
;***************************************************************************
; Some b values: (See also table in Appnote documentation)
;
; 1 MHz crystal:
; 9600 bps - b=14
; 19200 bps - b=5
; 28800 bps - b=2
;
; 2 MHz crystal:
; 19200 bps - b=14
; 28800 bps - b=8
; 57600 bps - b=2
; 4 MHz crystal:
; 19200 bps - b=31
; 28800 bps - b=19
; 57600 bps - b=8
; 115200 bps - b=2
.equ b =31 ;19200 bps @ 4 MHz crystal
UART_delay:
ldi temp,b
UART_delay1:
dec temp
brne UART_delay1
ret
;*****************************************************
;* *
;* No-Shift - Lookup Table when Shift not Pressed *
;* *
;*****************************************************
noshift:
ldi zl, low(noshifttbl*2)
ldi zh, high(noshifttbl*2)
add zl, byte
brcc amyg
inc zh
amyg:
lpm ;rezult in R0
mov byte, r0
ret
;*****************************************************
;* *
;* Shift - Lookup Table Used when Shift Pressed *
;* *
;*****************************************************
shift:
ldi zl, low(shifttbl*2)
ldi zh, high(shifttbl*2)
add zl, byte
brcc agantt
inc zh
agantt:
lpm ;rezult in R0
mov byte, r0
ret
.CSEG
noshifttbl:
.db $00 ; 00
.db $00 ; 01 F9
.db $00 ; 02
.db $00 ; 03 F5
.db $00 ; 04 F3
.db $00 ; 05 F1
.db $00 ; 06 F2
.db $00 ; 07 F12
.db $00 ; 08
.db $00 ; 09 F10
.db $00 ; 0A F8
.db $00 ; 0B F6
.db $00 ; 0C F4
.db $09 ; 0D TAB
.db '`' ; 0E ` or ~
.db $00 ; 0F
.db $00 ; 10
.db $00 ; 11 Left ALT
.db $00 ; 12 Left SHIFT
.db $00 ; 13
.db $00 ; 14 Left Ctrl
.db 'q' ; 15 Q
.db '1' ; 16 1 or !
.db $00 ; 17
.db $00 ; 18
.db $00 ; 19
.db 'z' ; 1A Z
.db 's' ; 1B S
.db 'a' ; 1C A
.db 'w' ; 1D W
.db '2' ; 1E 2 or @
.db $00 ; 1F
.db $00 ; 20
.db 'c' ; 21 C
.db 'x' ; 22 X
.db 'd' ; 23 D
.db 'e' ; 24 E
.db '4' ; 25 4 or $
.db '3' ; 26 3 or #
.db $00 ; 27
.db $00 ; 28
.db ' ' ; 29 Space
.db 'v' ; 2A V
.db 'f' ; 2B F
.db 't' ; 2C T
.db 'r' ; 2D R
.db '5' ; 2E 5 or %
.db $00 ; 2F
.db $00 ; 30
.db 'n' ; 31 N
.db 'b' ; 32 B
.db 'h' ; 33 H
.db 'g' ; 34 G
.db 'y' ; 35 Y
.db '6' ; 36 6 or ^
.db $00 ; 37
.db $00 ; 38
.db $00 ; 39
.db 'm' ; 3A M
.db 'j' ; 3B J
.db 'u' ; 3C U
.db '7' ; 3D 7 or &
.db '8' ; 3E 8 or *
.db $00 ; 3F
.db $00 ; 40
.db ',' ; 41 , or <
.db 'k' ; 42 K
.db 'i' ; 43 I
.db 'o' ; 44 O
.db '0' ; 45 0 or )
.db '9' ; 46 9 or (
.db $00 ; 47
.db $00 ; 48
.db '.' ; 49 . or >
.db '/' ; 4A / or ?
.db 'l' ; 4B L
.db ';' ; 4C ; or :
.db 'p' ; 4D P
.db '-' ; 4E - or _
.db $00 ; 4F
.db $00 ; 50
.db $00 ; 51
.db $27 ; 52 ' or "
.db $00 ; 53
.db '[' ; 54 [ or {
.db '=' ; 55 = OR +
.db $00 ; 56
.db $00 ; 57
.db $00 ; 58 Caps Lock
.db $00 ; 59 Right Shift
.db $0D ; 5A Enter
.db ']' ; 5B ] or }
.db $00 ; 5C
.db '\' ; 5D \ or |
.db $00 ; 5E
.db $00 ; 5F
.db $00 ; 60
.db $00 ; 61
.db $00 ; 62
.db $00 ; 63
.db $00 ; 64
.db $00 ; 65
.db $08 ; 66 Backspace
.db $00 ; 67
.db $00 ; 68
.db '1' ; 69 NUM - 1 or END
.db $00 ; 6A
.db '4' ; 6B NUM - 4 or LEFT
.db '7' ; 6C NUM - 7 or HOME
.db $00 ; 6D
.db $00 ; 6E
.db $00 ; 6F
.db '0' ; 70 NUM - 0 or INS
.db '.' ; 71 NUM - . or DEL
.db '2' ; 72 NUM - 2 or DOWN
.db '5' ; 73 NUM - 5
.db '6' ; 74 NUM - 6 or RIGHT
.db '8' ; 75 NUM - 8 or UP
.db $1B ; 76 ESC
.db $00 ; 77 NUM LOCK
.db $00 ; 78 F11
.db '+' ; 79 NUM - + (Plus)
.db '3' ; 7A NUM 3 or PAGE DOWN
.db '-' ; 7B NUM - - (Minus)
.db '*' ; 7C NUM - *
.db '9' ; 7D NUM - 9 or PAGE UP
.db $00 ; 7E SCROLL LOCK
.db $00 ; 7F
.db $00 ; 80
.db $00 ; 81
.db $00 ; 82
.db $00 ; 83 F7
.db $00 ; 84
.db $00 ; 85
.db $00 ; 86
.db $00 ; 87
.db $00 ; 88
.db $00 ; 89
.db $00 ; 8A
.db $00 ; 8B
.db $00 ; 8C
.db $00 ; 8D
.db $00 ; 8E
.db $00 ; 8F
shifttbl:
.db $00 ; 00
.db $00 ; 01 F9
.db $00 ; 02
.db $00 ; 03 F5
.db $00 ; 04 F3
.db $00 ; 05 F1
.db $00 ; 06 F2
.db $00 ; 07 F12
.db $00 ; 08
.db $00 ; 09 F10
.db $00 ; 0A F8
.db $00 ; 0B F6
.db $00 ; 0C F4
.db $09 ; 0D TAB
.db '~' ; 0E ` or ~
.db $00 ; 0F
.db $00 ; 10
.db $00 ; 11 Left ALT
.db $00 ; 12 Left SHIFT
.db $00 ; 13
.db $00 ; 14 Left Ctrl
.db 'Q' ; 15 Q
.db '!' ; 16 1 or !
.db $00 ; 17
.db $00 ; 18
.db $00 ; 19
.db 'Z' ; 1A Z
.db 'S' ; 1B S
.db 'A' ; 1C A
.db 'W' ; 1D W
.db '@' ; 1E 2 or @
.db $00 ; 1F
.db $00 ; 20
.db 'C' ; 21 C
.db 'X' ; 22 X
.db 'D' ; 23 D
.db 'E' ; 24 E
.db '$' ; 25 4 or $
.db '#' ; 26 3 or #
.db $00 ; 27
.db $00 ; 28
.db ' ' ; 29 Space
.db 'V' ; 2A V
.db 'F' ; 2B F
.db 'T' ; 2C T
.db 'R' ; 2D R
.db '%' ; 2E 5 or %
.db $00 ; 2F
.db $00 ; 30
.db 'N' ; 31 N
.db 'B' ; 32 B
.db 'H' ; 33 H
.db 'G' ; 34 G
.db 'Y' ; 35 Y
.db '^' ; 36 6 or ^
.db $00 ; 37
.db $00 ; 38
.db $00 ; 39
.db 'M' ; 3A M
.db 'J' ; 3B J
.db 'U' ; 3C U
.db '&' ; 3D 7 or &
.db '*' ; 3E 8 or *
.db $00 ; 3F
.db $00 ; 40
.db '<' ; 41 , or <
.db 'K' ; 42 K
.db 'I' ; 43 I
.db 'O' ; 44 O
.db ')' ; 45 0 or )
.db '(' ; 46 9 or (
.db $00 ; 47
.db $00 ; 48
.db '>' ; 49 > or .
.db '?' ; 4A / or ?
.db 'L' ; 4B L
.db ':' ; 4C ; or :
.db 'P' ; 4D P
.db '_' ; 4E - or _
.db $00 ; 4F
.db $00 ; 50
.db $00 ; 51
.db $22 ; 52 ' or "
.db $00 ; 53
.db '{' ; 54 [ or {
.db '+' ; 55 = OR +
.db $00 ; 56
.db $00 ; 57
.db $00 ; 58 Caps Lock
.db $00 ; 59 Right Shift
.db $0D ; 5A Enter
.db '}' ; 5B ] or }
.db $00 ; 5C
.db '|' ; 5D \ or |
.db $00 ; 5E
.db $00 ; 5F
.db $00 ; 60
.db $00 ; 61
.db $00 ; 62
.db $00 ; 63
.db $00 ; 64
.db $00 ; 65
.db $08 ; 66 Backspace
.db $00 ; 67
.db $00 ; 68
.db '1' ; 69 NUM - 1 or END
.db $00 ; 6A
.db '4' ; 6B NUM - 4 or LEFT
.db '7' ; 6C NUM - 7 or HOME
.db $00 ; 6D
.db $00 ; 6E
.db $00 ; 6F
.db '0' ; 70 NUM - 0 or INS
.db '.' ; 71 NUM - . or DEL
.db '2' ; 72 NUM - 2 or DOWN
.db '5' ; 73 NUM - 5
.db '6' ; 74 NUM - 6 or RIGHT
.db '8' ; 75 NUM - 8 or UP
.db $1B ; 76 ESC
.db $00 ; 77 NUM LOCK
.db $00 ; 78 F11
.db '+' ; 79 NUM - + (Plus)
.db '3' ; 7A NUM 3 or PAGE DOWN
.db '-' ; 7B NUM - - (Minus)
.db '*' ; 7C NUM - *
.db '9' ; 7D NUM - 9 or PAGE UP
.db $00 ; 7E SCROLL LOCK
.db $00 ; 7F
.db $00 ; 80
.db $00 ; 81
.db $00 ; 82
.db $00 ; 83 F7
.db $00 ; 84
.db $00 ; 85
.db $00 ; 86
.db $00 ; 87
.db $00 ; 88
.db $00 ; 89
.db $00 ; 8A
.db $00 ; 8B
.db $00 ; 8C
.db $00 ; 8D
.db $00 ; 8E
.db $00 ; 8F