*----------------------------------------------------------------------------*
* Gestion clavier pour le setup: c'est une version lite d'IKBD pour Dolmen.
* on ne gŠre que les touches du clavier (souris et joystick d‚sactiv‚s) et
* la r‚p‚tion clavier.
*----------------------------------------------------------------------------*
		TEXT
*----------------------------------------------------------------------------*

		*-------------*
		* a0: pointe sur le header de BORIS
		*-------------*
		cnop	0,16
INIT_KBD
		movem.l	d0-a6,-(sp)

	*-------------*
	* installe le vecteur clavier
		move.l	#Acia_kbd,aciaInt.w	;vecteur ACIA
		and.b	#~mfpacia_es,MFP_BASE+AER.w	;aer: acia kbd
		and.b	#~mfpacia_es,MFP_BASE+DDR.w	;ddr: acia kbd
		or.b	#mfpacia,MFP_BASE+IERB.w	;IERB: acia kbd
		or.b	#mfpacia,MFP_BASE+IMRB.w	;ImrB: acia kbd

	*-------------*
	* init ikbd
			; RTTSSSCC
		move.b	#%10010110,ACIAKBD_BASE+ACIA_CTRL.w
			;Rx=1:interruption
			;autoris‚e
			;TTx=0: RTS niveau bas,
			;       IRQ emetteur inhib‚
			;SSS=5:sans parit‚, 8 bits de donn‚es 1 bit de stop
			;CC=2:clock(500kHz)/64=7812.5 bauds

	* reset clavier
		lea	init_ikbd(pc),a0
		move	(a0)+,d0
		bsr	write_ikbd

	* attente de l'init du controleur clavier
		move	#300*192/20,d1	;300 ms (192 ticks pour le
					;compteur du timerc
					;qui donne 20ms)
.time_out
		move.b	MFP_BASE+TCDR.w,d0

.wait		cmp.b	MFP_BASE+TCDR.w,d0
		beq	.wait

		btst	#ACIA_RDRF,ACIAKBD_BASE+ACIA_CTRL.w
		bne.s	.rec
		btst	#ACIA_IRQ,ACIAKBD_BASE+ACIA_CTRL.w
		bne.s	.rec

		subq	#1,d1
		bne	.time_out

		bra.s	.suite		;error
.rec
		tst.b	ACIAKBD_BASE+ACIA_DATA.w

	* flush ikbd
		btst	#ACIA_RDRF,ACIAKBD_BASE+ACIA_CTRL.w
		bne.s	.rec

	* coupe les p‚riph‚riques externes (souris et joystick)
		lea	init_ext(pc),a0
		move	(a0)+,d0
		bsr	write_ikbd
.suite
	* reset vars en cas de reset pendant le lancement d'un boot
		bsr	reset_buf
	
	*---------------*
	* vecteur li‚ au timerc/4
		move.l	ETV_TIMER.w,repeat_old_vec
		move.l	#Repeat_vec,ETV_TIMER.w

	* vide le clavier (j'ai un doute)
		move	#100*192/20,d1	;100 ms (192 ticks pour le
					;compteur du timerc
					;qui donne 20ms)
.time_out2
		move.b	MFP_BASE+TCDR.w,d0

.wait2		cmp.b	MFP_BASE+TCDR.w,d0
		beq	.wait2

		btst	#ACIA_RDRF,ACIAKBD_BASE+ACIA_CTRL.w
		beq.s	.dec_time
		btst	#ACIA_IRQ,ACIAKBD_BASE+ACIA_CTRL.w
		beq.s	.dec_time
		
		move.b	ACIAKBD_BASE+ACIA_DATA.w,d0
		cmp.b	#$62,d0
		seq	open_setup(a6)
.dec_time
		subq	#1,d1
		bne	.time_out2
	
		*-------------*

		movem.l	(sp)+,d0-a6
		rts

		*-------------*

*----------------------------------------------------------------------------*

		*------------*
		* Vecteur pour l'ACIA du clavier
		*------------*
		dc.b	"KEYBOARD'S ACIA VECTOR"
		cnop	0,16
acia_kbd
		movem.l	d0-d3/a0-a3,-(sp)	;registres pour les routines??

		*------------*
		* teste le clavier
.interrupt
		move.b	ACIAKBD_BASE+ACIA_CTRL.w,d0		;reg d'‚tat
		btst	#ACIA_IRQ,d0		;Interrupt Request
		beq.s	.kbd_out
		
		btst	#ACIA_RDRF,d0		;Reg de donn‚es re‡ues plein
		beq.s	.kbd_int_err

		moveq	#_ACIAFE+_ACIAOVRN+_ACIAPE,d1
		and.b	d0,d1
		bne.s	.kbd_err
		
		move.b	ACIAKBD_BASE+ACIA_DATA.w,d0
		
		bsr	ikbd_sys
		
		moveq	#_ACIAFE+_ACIAOVRN+_ACIAPE,d0
		and.b	ACIAKBD_BASE+ACIA_CTRL.w,d0
		beq.s	.interrupt
.kbd_err
		tst.b	ACIAKBD_BASE+ACIA_DATA.w	;flush...
		bra.s	.interrupt
.kbd_int_err
		*------------*
.kbd_out		
		move.b	#~mfpacia,MFP_BASE+ISRB.w	;interruption trait‚e

		*------------*

		movem.l	(sp)+,d0-d3/a0-a3
		rte

		*------------*

*----------------------------------------------------------------------------*

		*-------------*
		* Routine qui ‚crit dans le clavier
		*-------------*
		* A0: pointe sur le buffer … ‚crire
		* D0: nb de car-1
		*-------------*
		dc.b	"Write Ikbd"
		cnop	0,16
write_ikbd
.wait
		btst.b	#acia_tdre,aciakbd_base+acia_ctrl.w
		beq.s	.wait

		move.b	(a0)+,aciakbd_base+acia_data.w
		dbra	d0,.wait

		rts

		*-------------*

*----------------------------------------------------------------------------*

		*-------------*
		* Vecteur se chargeant de la r‚p‚tition du clavier
		*  pour les caractŠres (composition comprise) et
		*  les joysticks 0 et 1
		*-------------*
repeat_old_vec	dc.l	0
		dc.b	"RepeatSys"
		cnop	0,16
Repeat_vec
		tst.b	key_repeat_on(pc)
		beq.s	.pas_key

		tst	key2repeat(pc)
		beq.s	.pas_key
		
		tst.b	key_delay_tmp(pc)
		beq.s	.repeat

		subq.b	#1,key_delay_tmp
		bne.s	.pas_key
.repeat
		subq.b	#1,key_repeat_tmp
		bne.s	.pas_key

		move.b	key_repeat(pc),key_repeat_tmp

		move	key2repeat(pc),d0
		bsr	touche_gest
.pas_key
		*-------------*

		jmp	([repeat_old_vec.w,pc])

		*-------------*

*----------------------------------------------------------------------------*

		*-------------*
		* routine appel‚ en cas d'interuption clavier
		* ne re‡oit pas noramlement des trucs comme souris
		* joystick ou autres
		* d0= touche re‡ue
		*-------------*
		dc.b	"Ikbdsys"
		cnop	0,16

*----------------------------------------------------------------------------*

		*-------------*
		* Routine systŠme clavier proprement dite
		*-------------*
		* D0.b: code scan de la touche 
		*       bit 7=0 pour touche baiss‚e
		*       bit 7=1 pour touche relev‚e
		*-------------*
		dc.b	"Ikbdvec"
		cnop	0,16
ikbd_sys
ikbd_vec
		lea	touches_mortes(pc),a0
		move.b	(a0),d2
		moveq	#$7f,d1
		and	d0,d1

		*-------------*

*----------------------------------------------------------------------------*

		*-------------*
		* Gestion des touches mortes
		*-------------*
DeadKey
		tst.b	d0
		bmi	.mort_vivant

		moveq	#1,d3

		cmp.b	#$36,d1	;shift droit
		beq.s	.change

		add	d3,d3

		cmp.b	#$2a,d1	;shift gauche
		beq.s	.change

		add	d3,d3

		cmp.b	#$1d,d1	;control
		beq.s	.change

		add	d3,d3

		cmp.b	#$38,d1	;alt
		beq.s	.change

		cmp.b	#$3a,d1
		bne.s	touche_repet
		
		add	d3,d3
		eor	d3,d2
		move.b	d2,(a0)
		rts
.change
		or	d3,d2
		move.b	d2,(a0)
		rts

		*-------------*
.mort_vivant
		moveq	#1,d3

		cmp.b	#$36,d1	;shift droit
		beq	.change2

		add	d3,d3

		cmp.b	#$2a,d1	;shift gauche
		beq.s	.change2

		add	d3,d3

		cmp.b	#$1d,d1	;control
		beq.s	.change2
		
		add	d3,d3

		cmp.b	#$38,d1		;pas de capslock
		bne	touche_repet	;donc test fini

	* mort-vivant explos‚
.change2
		not	d3
		and	d3,d2
		move.b	d2,(a0)
.fin
		rts

		*-------------*

*-------------------------------------------------------------------------*

		*-------------*
		* Valide la r‚p‚tition des touches
		*-------------*
		cnop	0,16
Touche_repet
		lea	key2repeat(pc),a0
		tst.b	d0
		bpl.s	.down

		cmp	key2repeat(pc),d1
		bne.s	.coupe_pas

		clr	(a0)
.coupe_pas
		rts

		*-------------*
.down
		move	d1,d0

		move	d0,(a0)
		move	key_delay(pc),key_delay_tmp

		*-------------*

*-------------------------------------------------------------------------*

		*-------------*
		* GŠre le code scan re‡ue par l'Acia ou par
		*  le vecteur de r‚p‚tition
		*-------------*
		* d0: code scan
		*-------------*
touche_gest

*-------------------------------------------------------------------------*

		*-------------*
		* Ecrit dans le buffer circulaire sp‚cifique au clavier.
		*-------------*
		* d0.w: code scan 
		* d1.w: code ascii
write_conin
		*-------------*
		* cr‚ation du caractŠre systŠme

		or	touches_mortes(pc),d0

		*-------------*
		* gestion du buffer circulaire

		move	d0,d1
		beq.s	.pas_write

		* cas particulier
		and	#$fff,d1	;pas de capslock

	* reset systŠme
		cmp	#$c53,d1
		beq	reset_chaud
		cmp	#$d53,d1
		beq	reset_froid

	* reset buffer
		cmp	#$401,d1
		beq	reset_buf

	* buffer plein?
		lea	buf_conin(pc),a0
		move	ibuftl(a0),d1
		move	d1,d2
		addq	#2,d2
		cmp	ibufsize(a0),d2
		bne.s	.around
		moveq	#0,d2
.around
		cmp	ibufhd(a0),d2
		beq.s	.pas_write
		
		move	d2,ibuftl(a0)
		move	d0,([ibuf,a0],d1)
		
		*-------------*
.pas_write
		rts

		*-------------*
		* paf le buffer!
		cnop	0,16
reset_buf
		moveq	#0,d0
		move.b	d0,touches_mortes
		move	d0,key2repeat
		move.l	d0,buf_conin+ibufhd

		rts

		*-------------*
		* brrrrrrr.......
		cnop	0,16
reset_froid
		clr.l	memvalid.w
		clr.l	memval2.w
		clr.l	memval3.w
		clr.l	ramvalid.w

		* hot!!!!
reset_chaud
		jmp	fast_dol_start+dol_header

		*-------------*

*-------------------------------------------------------------------------*
		DATA
*-------------------------------------------------------------------------*

		*-------------*
		* VARIABLES GLOBALES
		cnop	0,16
touches_mortes	dc.b	0	* touches mortes:
				*  bit 0: shift droit
				*  bit 1: shift gauche
				*  bit 2: control
				*  bit 3: alternate
				*  bit 4: capslock
				*  bit 5: clr home->bouton droit de la souris
				*  bit 6: insert->bouton gauche de la souris
				*  bit 7: r‚serv‚
		dc.b	0	;pour l'ORer avec le scan

		*-------------*

		cnop	0,16
		* init le clavier
init_ikbd		dc.w	2-1	;nb de car-1
		dc.b	$80,$01	;Reset

		cnop	0,16
		* init les extentions
Init_ext		dc.w	2-1
		dc.b	$12	;coupe la souris
		dc.b	$1a	;coupe les joysticks
		even

		*-------------*
		* VARIABLES DE GESTION DU BUFFER
		cnop	0,16
key2repeat	dc.w	0
key_repeat_on	dc.b	$ff		r‚p‚tion active par d‚faut
key_delay		dc.b	10
key_repeat	dc.b	1
key_delay_tmp	dc.b	0
key_repeat_tmp	dc.b	0

		cnop	0,16
buf_conin		dc.l	adr_conin		;adr du buffer
		dc.w	size_conin	;taille du buffer
		dc.w	0,0		;hd / tl
		
		*-------------*

*-------------------------------------------------------------------------*
		BSS
*-------------------------------------------------------------------------*

		*-------------*

adr_conin		ds.b	size_conin
adr_conin_end

		*-------------*

*-------------------------------------------------------------------------*
