IBM-AT-Tastatur an Palmpilot

Anschluss einer IBM-AT Tastatur an den Palmpilot


Basteln mit dem Palmpilot

von Olaf Kaluza (und leichten Verbesserungen von Bodo Bellut)


Sicher haben sich schon viele von euch gefragt wie man denn laengere Texte in den Palmpilot eingeben kann. Eine neue Moeglichkeit soll hier gezeigt werden. Es geht darum eine ganz normale PC/AT Tastatur an den Palmpilot anzuschliessen wie sie sicher jeder zuhause rumliegen hat, oder wie man sie fuer wenig Geld ueberall kaufen kann. Ja eigentlich benoetigt man noch nichtmal eine eigene Tastatur. Schliesslich gibt es fast keinen Ort der Welt mehr wo man nicht mal eben eine Tastatur von einem vorhandenen Rechner abziehen kann. So braucht man sich nicht unnoetig abzuschleppen.



Copyright


Saemtliche Rechte der gezeigten Schaltung und des Sourcecodes liegen bei mir. Ich erlaube es aber jedem Privat und zu seinem Vergnuegen diese Schaltung nachzubauen. Ich moechte nicht das diese Anleitung auf fremde Seiten kopiert wird oder in andere Sprachen uebersetzt wird ohne das ich expliziet meine Erlaubnis dazu gegeben habe. Ich moechte nicht das sie auf CD-Roms oder anderweitig als durch Hinweiss auf diese Seite verbreitet wird. Sollte jemand zu bloed zum nachbauen sein und seinen Piloten killen so ist dies allein sein Problem.



Kontakt zum Autor


Ich freue mich ueber jede konstruktive Mail, ueber gefundene Bugs, Verbesserungsvoschlaege, Danksagungen oder auch nur allgemeines blabla. Ich moechte jedoch dringend bitten von bloeden Fragen abzusehen. Ich vertreibe keine gebrannten Microcontoller, es gibt keine Platine und ich weiss auch nicht warum die Schaltung gerade bei dir nicht laeuft!



Funktionsweise

Die Funktion der Schaltung ist relativ simpel. Es wird lediglich das Datenformat einer IBM-AT-Tastatur, also nicht die einer alten XT-Tastatur in das Format einer Apple-Newton-Tastatur umgesetzt. Danach kann man dann einen der zahlreichen vorhandenen Treiber verwenden und die Tastatur am Palmpilot nutzen. Ich verwende hierzu den Freekey Treiber.


Schaltplan

Wie man sieht ist die Schaltung genauso simpel wie die Funktion. Sollte jeder von euch auf einem Stueck Lochraster hinfaedeln koennen. Wer das nicht kann sollte es besser lassen bevor ihr noch euren kleinen Freund killt.
Ihr werdet vielleicht bemerkt haben das der Ausgang zum Palmpilot nicht so ganz der RS232 Norm entspricht. Macht aber nix, der Palmpilot akzeptiert auch 0V als 1, wir koennen uns also einen Pegelwandler sparen.
Zum Anschluss kann entweder das Craddle benutzt werden, oder aber ihr bastelt euch einen eigenen Stecker fuer den Port. Die Schaltung zeigt ersteres, ich selber habe aber nur letzteres getestet.

Stromversorgung

Eigentlich benoetigen sowohl die Schaltung wie auch die angeschlossene Tastatur 5V. Damit muss man es aber nicht so genau nehmen. Ich betreibe meine Schaltung mit einem 4.2V Lithiumakku. Sicherlich wuerden es aber 4NC-Akkus genauso tun.
Ich empfehle auch nicht zu alte AT-Tastaturen zu verwenden da der Stromverbrauch der Schaltung ueberwiegend durch die Tastatur bestimmt wird. Aeltere Tastaturen benoetigen 10-100mal soviel Strom wie aktuelle!

Sourcecode des Microcontrollers

;Konverter fuer PC-Tastatur nach Palmpilot/Newton-Key
;Programm laeuft mit 24Mhz
;
;
;
;
; 9.04.99
;

         .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




Das war also der Source. Da gibt es nichts weiter zu zusagen, er ist selbsterklaerend. Er basiert noch zum Teil auf eine Applikation von Philips wo sie gezeigt haben wie man eine Tastatur an einen MCS51 haengt. Darauf bezieht sich mein Copyright natuerlich nicht!



Sourcecode und Binfile 4kb ZIP



Bodo hat netterweise einen kleinen Bug in meinem Programm gefunden. Bei Verwendung eines deutschen Tastaturtreibers koennte es passieren das der Kontroller staendig mit einem falschen Zeichen nervt.
Im folgenden mal mein Originalcode wo ich Bodos Verbesserungen eingearbeitet habe.

Sourcecode und Binfile der verbesserten Version fuer den TASM 4kb ZIP



Ausserdem noch Bodos Originalcode welchen er fuer Alfred Arnolds AS angepasst hat.

Bodos Sosse fuer den AS 4kb ZIP
Solltet ihr hierzu fragen habe, ja dann fragt doch einfach Bodo selber. (bodo@bellut.net)


Nun solltet ihr eine funktionierende Tastatur mit amerikanischer Belegung haben. Mir reicht das da ich eh an allen meinen Rechnern amerikanische Tastas habe. Solltet ihr das anders sehen dann muesst ihr Freekey selber patchen. Das ist aber nicht schwierig.

Viel Spass.



Nachtrag: Ich werde gelegentlich gefragt was es mit den Files global.inc und sysmacro.inc auf sich hat welche ich in meinem Code einlese.
Bei global.inc handelt es sich um die Beschreibung der Register eines MCS51. Diese Datei ist Teil des TASM. Solltet ihr den benutzten dann habt ihr die schon, benutzt ihr einen anderen Assembler dann braucht ihr sie nicht.
Bei sysmacro.inc handelt es sich um meine Macrodatei. Ich benutze aber keines der Macros darin in diesem Source. Ich koennt die also einfach loeschen.