.org 0000H ;Assemblerinterne Variable besetzen #include "/home/olaf/anwendungen/elektronik/tasm/global.inc" #include "/home/olaf/anwendungen/elektronik/tasm/sysmacro.inc" ; baud_const = 256 - (crystal / (12 * 16 * baud)) baud_const .EQU 243 ;9600 baud mit 24 MHz #define idle orl PCON,#00000001b STACK .EQU 04fH ;Beginn des Systemstack-1 #define KEYDAT P3.3 ;Datenleitung der Tastatur ;Als Eingang fuer die Taktleitung ;wird Int0/P3.2 benutzt FLAGS .equ 040h ; Wir benutzen dieses Bytes fuer Flags Ctrl .equ (FLAGS-20h)+0 ; control key flag Shift .equ (FLAGS-20h)+1 ; shift key flag Alt .equ (FLAGS-20h)+2 ; alt key flag RCtrl .equ (FLAGS-20h)+3 ; alt key flag RShift .equ (FLAGS-20h)+4 ; alt key flag RAlt .equ (FLAGS-20h)+5 ; alt key flag E0cod .equ (FLAGS-20h)+6 ; alt key flag lastkey .equ 041h ; Letzter Tastendruck NBits .equ 042h ; Bitcounter keytemp .equ 043h ; Temporaerer Tastencode NBytes .equ 044h ; !=0 gibt Zeichen im Bufferbyte an keybuff .equ 045h ; Ubergabepuffer fuer Translatet Code ajmp anfang ;Programmanfang nach Reset .org 0003H ;Externer Interrupt 0, INT0 ajmp kbd ;Die Tastatur kam mal wieder mit einem Bit rueber .org 000BH ;Ueberlauf Counter/Timer 0 nop .org 0013H ;Externer Interrupt 1, INT1 NOP .org 001BH ;Ueberlauf Counter/Timer 1 NOP .org 0023H ;Interrupt, Serieller Port NOP .org 0026H ;Hauptprogramm ;Hauptprogramm, zuersteinmal ein paar Initialisierungen anfang mov SP,#STACK ;Stackpointer hochsetzen ;Und platz fuer Registerbank zu schaffen ;Voreinstellungen damit wird die RS232 als Ausgang mit 9600B bei 24Mhz nutzen koennen orl PCON,#10000000b ;Doppelte Baudrate einschalten MOV TMOD,#00100001b MOV SCON,#01000000b ; Set Serial for mode 1 & disable reception mov a, #baud_const mov TH1, a orl TCON,#01010010b ; Start timer 1 both timer setb TI ;ti is normally set in this program orl TCON,#00000001b ; Int0 soll flankengetriggert sein mov IP,#00000001b ; Int0 bekommt hoechsten Level mov IE,#10000001b ; Int0 freigeben clr Shift ; clear keyboard Flags clr Ctrl clr Alt clr RShift clr RCtrl clr RAlt clr E0cod mov NBytes,#0 mov NBits,#0 ;Ab hier der Workingcode mainl mov a,NBytes ; Wurden Tasten gedrueckt? jz mainl ; Nein? Dann warten. anl IE,#01111110b ; IRQs verbieten mov NBytes,#0 mov a,keybuff orl IE,#10000001b ; Int0 freigeben jz mainl ; Verbotene Tasten senden eine Null acall cout ; Taste an Palmpilot senden mov a,#8ah ; Tastendruck aufheben acall cout ; da Palmpilot Softwareautorepeat macht idle ;Stromsparen bis wir wieder gebraucht werden sjmp mainl ;Senden eines Bytes ueber die RS232 cout jnb TI, cout clr TI mov SBUF, a ret ;Dies ist die KBD-Routine fuer den Interrupt 0 kbd: push psw ;Benutzte Register retten push acc mov acc,NBits ; NBits=Bitnummer die als naechstes von der Tastatur kommt cjne a,#0,bit1_8 ; if not bit 0 then bit 1 to 8 bit0: ajmp bump ; Bit0 ignorieren wir da es das STart-Bit ist bit1_8: cjne a,#9,$+3 ; Pruefen ob es das 9Bit ist jnc bit9 mov c,KEYDAT ; Das aktuelle Bit lesen mov a,keytemp ; Eventuell letzte Bits holen rr a ; Und Platz fuer das neue Bit schaffen mov ACC.7,c ; Bit eintragen. mov keytemp,acc ajmp bump bit9: cjne a,#9,bit10 ajmp bump ;Wir verzichten erstmal auf den Paritycheck ;Das Stoppbit ist da, also sind wir komplett und koennen konvertieren bit10: mov acc,keytemp ;Letzte reingekommen Scancode holen jb E0cod,noe0 ;Sind wir schon im erweiterten E0-Modi? cjne a,#0e0h,noe01 ;Wird es ein erweiterter E0-Code? setb E0cod ajmp tidy ;Wir sind innerhalb eines E0-Codes noe0: mov acc,lastkey cjne a,#0f0h,noe0no clr E0cod ;Es wurde eine Taste mit E0 losgelassen mov lastkey,#0 mov acc,keytemp cjne a,#75h,notCUr ;War es Cursor-UP mov a,#126 ajmp Not0 notCUr: cjne a,#72h,noCDr ;Wurde Cursor-Down losgelassen? mov a,#125 ajmp Not0 noCDr: cjne a,#6bh,noCLr ;War es Cursor-Left? mov a,#123 ajmp Not0 noCLr: cjne a,#74h,noCRr ;War es Cursor-Right? mov a,#124 ajmp Not0 noCRr: cjne a,#11h,noAltgr ;War es die rechte ALT-Taste? mov a,#58 ajmp Not0 noAltgr:cjne a,#14,noCtrrr ;Rechte Ctrl? mov a,#59 ajmp Not0 noCtrrr: ajmp tidy ;Unbekannter Code, nichts machen noe0no: ;Es wurde eine Taste mit E0 gedrueckt mov acc,keytemp cjne a,#0f0h,noe3 ;Ist es etwa jetzt gerade F0? mov lastkey,keytemp ajmp tidy ;Erstmal nix machen wenn es F0 ist noe3: clr E0cod ;Wir wissen jetzt welche Taste gedrueckt wurde cjne a,#75h,noCU ;War es Cursor-Up? mov a,#-2 ajmp Not0 noCU: cjne a,#72h,noCD ;Was es Cursor-Down? mov a,#-3 ajmp Not0 noCD: cjne a,#6bh,noCL ;War es Cursor-Left? mov a,#-5 ajmp Not0 noCL: cjne a,#74h,noCR ;War es Cursor-Right? mov a,#-4 ajmp Not0 noCR: cjne a,#11h,noAltg ;War es die rechte ALT-Taste? mov a,#-70 ;Wir senden OptionsUP ajmp Not0 noAltg: cjne a,#14h,noCtrr ;War es die rechte Ctrl-Taste? mov a,#-69 ajmp Not0 noCtrr: ajmp tidy ;Es wuerde eine unbekannte Taste gedrueckt ;Ab hier wird das druecken und loslassen der nicht-E0 Tasten bearbeitet noe01: cjne a,#12h,notls ; War es die linke Shift-Taste? mov acc,lastkey ; Wenn der letzte Code cjne a,#0f0h,makels ; $f0 war dann wurde die Shifttaste losgelassen clr Shift ; Also Shiftbit loeschen mov lastkey,#12h ; Und Scancode in den Buffer des letzten Zeichen mov a,#56 ajmp Not0 makels: setb Shift ; Die naechste Taste wird geshiftet mov lastkey,#12h ; Scancode in den Buffer des letzten Zeichen mov a,#-72 sjmp Not0 sjmp tidy notls: cjne a,#59h,notrs ; War es die rechte Shift-Taste? mov acc,lastkey ; Ist es ein Breakcode? cjne a,#0f0h,makers clr RShift mov lastkey,#59h mov a,#60 ;Taste wurde losgelassen sjmp Not0 makers: setb RShift mov lastkey,#59h mov a,#-68 ;Rechte Shiftaste gedrueckt sjmp Not0 notrs: cjne a,#14h,notctrl ;War es vielleicht die Ctrl-Taste? mov acc,lastkey cjne a,#0f0h,mkctr clr Ctrl mov lastkey,#14h mov a,#59 sjmp Not0 mkctr: setb Ctrl mov lastkey,#14h mov a,#-69 sjmp Not0 notctrl: cjne a,#11h,notalt ;War es die Alt-Taste? mov acc,lastkey cjne a,#0f0h,mkalt clr Alt mov lastkey,#11h mov a,#55 sjmp Not0 mkalt: setb Alt mov lastkey,#11h mov a,#-73 sjmp Not0 notalt: cjne a,#0f0h,notbreak ; War es ein Breakcode? (Taste wurde losgelassen) mov lastkey,a ;Merken sjmp tidy ;but don't store in the buffer notbreak: mov acc,lastkey ; Wenn die letzte Taste 0xf0 war cjne a,#0f0h,not_f0 ;Scancode ignorieren da es ein Break code ist mov lastkey,#0 ;Dummywert sjmp tidy ;Alle Sonderfaelle sind durch, also kann es nur eine normale Taste sein not_f0: mov a,keytemp ;Aktuellen Key holen mov lastkey,a ;und zum letzten Code machen push dph ; Wir brauchen dptr fuer den Tabellenzugriff push dpl mov dptr,#keytab ;Ja, also andere Tabelle movc a,@a+dptr ;Code uebersetzen pop dpl ;Wir brauchen dptr nicht mehr pop dph Not0: mov keybuff,a ; Zeichen in keyboard-Buffer mov NBytes,#1 ; Und Merker fuer aussenliegende Funktionen tidy: mov NBits,#0 ; Alles fuer naechsten Tastendruck fertigmachen mov keytemp,#0 sjmp intdone bump: inc NBits ;fuer naechstes Bit bereitmachen intdone:pop acc pop psw reti ;Dies ist die Ubersetztungstabelle die IBM-AT Tastencodes im Code-Set2 c't6/88 s.152 ;nach Newton Codes uebersetzt ; 0 1 2 3 4 5 6 7 8 9 A B C D E F keytab .db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,0b0h,0b2h,000h ;0x00 .db 000h,-73 ,-72 ,000h,-69 ,08ch,092h,000h,000h,000h,086h,081h,080h,08dh,093h,000h ;0x10 .db 000h,088h,087h,082h,08eh,095h,094h,000h,000h,0b1h,089h,083h,091h,08fh,097h,000h ;0x20 .db 000h,0adh,08bh,084h,085h,090h,096h,000h,000h,000h,0aeh,0a6h,0a0h,09ah,09ch,000h ;0x30 .db 000h,0abh,0a8h,0a2h,09fh,09dh,099h,000h,000h,0afh,0ach,0a5h,0a9h,0a3h,09bh,000h ;0x40 .db 000h,000h,0a7h,000h,0a1h,098h,000h,000h,-71 ,000h,0a4h,09eh,000h,0aah,000h,000h ;0x50 .db 000h,000h,000h,000h,000h,000h,0b3h,000h,000h,000h,000h,000h,000h,000h,000h,000h ;0x60 .db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h ;0x70 .db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h ;0x80 .db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h ;0x90 .db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h ;0xa0 .db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h ;0xb0 .db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h ;0xc0 .db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h ;0xd0 .db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h ;0xe0 .db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h ;0xf0 .end