

;PIC16C84 keybord controller for Amiga keybords
;pressed keys are located in table and send in serial ascii format (19200baud)
;
;Dirk Duesterberg duesterb@unixserv.rz.fh-hannover.de
;                 http://linux.rz.fh-hannover.de/~duesterb


	list	p=PIC16C84, r=dec, s=on


	device	HS_OSC, WDT_OFF
	xtal	4000000

PortA	= 05h
PortB	= 06h
pcl	= 02h



#define	ACLK	PortA,0
#define	ADAT	PortA,1

#define	TXD	PortA,2
#define c	3,0
#define z	3,2

RA	=	5		;PortA is register 5




	CBLOCK	0ch

	   count0
	   count1
	   Akeydat
	   serbuf

	ENDC



	movlw	11111011b		;pin 2 is output (TXD)
	tris	PortA

	movlw	0			;PortB is output
	tris	PortB

	goto	Reset



rawkeys	movf	Akeydat,w
	andlw	7fh			;clr bit 7 (make/break or pressed/unpressed)
	addwf	pcl,f


; characters, numbers and spezial keys
; $00-$3F

	retlw	00h			;00h
	retlw	00h			;01h
	retlw	00h			;02h
	retlw	00h			;03h
	retlw	00h			;04h
	retlw	00h			;05h
	retlw	00h			;06h
	retlw	00h			;07h

	retlw	00h			;08h
	retlw	00h			;09h
	retlw	00h			;0Ah
	retlw	00h			;0Bh
	retlw	00h			;0Ch
	retlw	00h			;0Dh
	retlw	00h			;0Eh	
	retlw	00h			;0Fh



	retlw	"q"			;10h
	retlw	"w"			;11h
	retlw	"e"			;12h
	retlw	"r"			;13h
	retlw	"t"			;14h
	retlw	"z"			;15h
	retlw	"u"			;16h
	retlw	"i"			;17h

	retlw	"o"			;18h
	retlw	"p"			;19h
	retlw	"ü"			;1Ah
	retlw	"+"			;1Bh
	retlw	00h			;1Ch
	retlw	00h			;1Dh
	retlw	00h			;1Eh
	retlw	00h			;1Fh



	retlw	"a"			;20h
	retlw	"s"			;21h
	retlw	"d"			;22h
	retlw	"f"			;23h
	retlw	"g"			;24h
	retlw	"h"			;25h
	retlw	"j"			;26h
	retlw	"k"			;27h

	retlw	"l"			;28h
	retlw	"ö"			;29h
	retlw	"ä"			;2Ah
	retlw	00h			;2Bh
	retlw	00h			;2Ch
	retlw	00h			;2Dh
	retlw	00h			;2Eh
	retlw	00h			;2Fh



	retlw	00h			;30h
	retlw	00h			;31h
	retlw	00h			;32h
	retlw	00h			;33h
	retlw	00h			;34h
	retlw	00h			;35h
	retlw	00h			;36h
	retlw	00h			;37h

	retlw	00h			;38h
	retlw	00h			;39h
	retlw	00h			;3Ah
	retlw	00h			;3Bh
	retlw	00h			;3Ch
	retlw	00h			;3Dh
	retlw	00h			;3Eh
	retlw	00h			;3Fh

; other spezial keys (space, TAB, Return)
; $40-$4F

	retlw	00h			;40h
	retlw	00h			;41h
	retlw	00h			;42h
	retlw	00h			;43h
	retlw	00h			;44h
	retlw	00h			;45h
	retlw	00h			;46h
	retlw	00h			;47h

	retlw	00h			;48h
	retlw	00h			;49h
	retlw	00h			;4Ah
	retlw	00h			;4Bh
	retlw	00h			;4Ch
	retlw	00h			;4Dh
	retlw	00h			;4Eh
	retlw	00h			;4Fh


; Function keys, Help etc.
; $50-$5F

	retlw	00h			;50h
	retlw	00h			;51h
	retlw	00h			;52h
	retlw	00h			;53h
	retlw	00h			;54h
	retlw	00h			;55h
	retlw	00h			;56h
	retlw	00h			;57h

	retlw	00h			;58h
	retlw	00h			;59h
	retlw	00h			;5Ah
	retlw	00h			;5Bh
	retlw	00h			;5Ch
	retlw	00h			;5Dh
	retlw	00h			;5Eh
	retlw	00h			;5Fh



; shifting keys like shift, amiga, Alternate and Control
; $60-6F
	
	retlw	00h			;60h
	retlw	00h			;61h
	retlw	00h			;62h
	retlw	00h			;63h
	retlw	00h			;64h
	retlw	00h			;65h
	retlw	00h			;66h
	retlw	00h			;67h

	retlw	00h			;68h
	retlw	00h			;69h
	retlw	00h			;6Ah
	retlw	00h			;6Bh
	retlw	00h			;6Ch
	retlw	00h			;6Dh
	retlw	00h			;6Eh
	retlw	00h			;6Fh


;spezial keybord commandos
; $70-$7F

	retlw	00h			;70h	
	retlw	00h			;71h
	retlw	00h			;72h
	retlw	00h			;73h
	retlw	00h			;74h
	retlw	00h			;75h
	retlw	00h			;76h
	retlw	00h			;77h

	retlw	00h			;78h
	retlw	00h			;79h=F9h= letzter tasten code war fehlerhaft
	retlw	00h			;7Ah=FAh= tastenpuffer im keybord voll
	retlw	00h			;7Bh
	retlw	00h			;7Ch=FCh= selbsttest der tastatur war fehlerhaft
	retlw	00h			;7Dh=FDh= beginn der beim Einschalten gedrueckten Tasten
	retlw	00h			;7Eh=FEh= ende der beim Einschalten gedrueckten Tasten
	retlw	00h			;7Fh

	






















Reset	clrf	Akeydat			;Akeydat is used as character counter

check	movlw	11
	subwf	Akeydat,w		;how many characters ?
	btfsc	z
	goto	ready

	call	dat
	movwf	serbuf
	call	sendb			;send letter
	incf	Akeydat,f
	goto	check



dat	movf	Akeydat,w		;letter to w routine
	addwf	pcl,f			;jump in table
	retlw	"mache RESET"







ready	call	sync




rcADAT	movlw	7
	movwf	count0

:loop	call	wACLK			;wait for Amiga CLK
	rlf	Akeydat,f		;rotate bits into register
	decfsz	count0,f
	goto	:loop			;format is x6543210


	rlf	Akeydat,f		;format is 6543210x
	call	wACLK			;wait for Amiga CLK
	rrf	Akeydat,f		;format is 76543210, jippije
	comf	Akeydat,f		;data is inverted

	movlw	5
	call	wms			;wait 5 ms

;	mov	serbuf,Akeydat
;	call	sendb			;send raw data


	call	rawkeys
	movwf	serbuf

	btfss	Akeydat,7		;no sending if key up flag is set
	call	sendb			;send the in table found code

	call	AHshake			;all data OK, do the Handshake
	goto	rcADAT			;receive next byte from keybord











sync	call	wACLK			;wait for clock and do no Acknowledge
	
	movlw	250
	call	wms			;wait 250 ms (we want the sync mode!)

	call	wACLK			;wait for Amiga CLK for Handshake

	movlw	1
	call	wms			;wait 1 ms

	call	AHshake			;now we do the shake!
	return


 



wms	movwf	count0

:loop	movlw	248
	movwf	count1
:do_it	nop

	decfsz	count1,f
	goto	:do_it

	decfsz	count0,f
	goto	:loop

	return






AHshake	movlw	11111001b		;bit1 = ADAT = output
	tris	RA

	bcf	ADAT			;clr Amiga data line
	
	movlw	40
	movwf	count0			;40 * 3 = 120cycles = 120 µs (min 75µs)
:do_it	decfsz	count0,f
	goto	:do_it

	movlw	11111011b		;bit1 = ADAT = input
	tris	RA
	return






wACLK	btfsc	ACLK			;wait for neg clock pulse
	goto	wACLK

	btfss	ADAT
	bcf	c
	btfsc	ADAT
	bsf	c			;mov the data to carry bit

wACLK2	btfss	ACLK			;wait for pos clock pulse
	goto	wACLK2
	return







sendb	call	wbit			;this are stop bits from previous sending
	call	wbit

	bsf	TXD			;send startbit
	movlw	8
	movwf	count0			;8 bits to send
	comf	serbuf,f		;invert serbuf

s_it	call	wbit
	rrf	serbuf,f

	btfss	c
	bcf	TXD
	btfsc	c
	bsf	TXD

	decfsz	count0,f
	goto	s_it			;all bits send ? decrement the bitcounter

	call	wbit
	bcf	TXD			;clear TXD, stopbit, lenght is defined by 
					;next sending
	return





wbit	movlw	13
	movwf	count1			;19200 at 4 Mhz
:loop	decfsz	count1,f
	goto	:loop
	nop
	return

