 .DEFINE Code1
 .DEFINE tabelle
 .SECTION Code1

irq0:           .word 0h 
irq1:           .word 0h
irq2:           .word 0              ; T1
irq3:           .word 0              ; T1
irq4:           .word 0              ; T1
irq5:           .word 0              ; T1

start:
	
	DI								; Disable Int
	SRP     #%F0 				; Control Registers
	CLR     p1              ; Port 1 = 0
	ld      R8, #%45			; P01M
	ld      p3, #3F       	; Port 3 = 0011.1111b
	ld      R7, #1				; P3M P34,P37 Comparator Output. P34 == PPI.PC4, P37 == CLK Out
	ld      R6, #%FF			; P2M alle pins input, P20 == PPI.PB2
	ld      R11, #0			; IMR alle INTS aus
	ld      R15, #%80			; SPH Stack = 0 SPL=%80
	srp     #0
	ld      R14, #4			; Bitmask für P32, PPI <--> this
	ld      R15, #8			; Bitmask für P33, PPI <--> this
	ld		R8, #0
	ld		%13, #0			; Scancode state
	ld		%14, #0			; Scancode state
	ei								; Enable Int
	di

Marke_000:
	CLR R11						; bits empfangen = 0
	CLR IRQ

Marke_001:
	LD R4, R3					; 
	TM R4, R14					; P32 PB6 ... Hold CLK low? 0=low
	JP Z, Reset_Keyb			; 
	TM R4, R15					; P33 PB7 .. Enable KB ? 0=enable
	JR NZ, Prep_Read_Switch  		; Schalter auslesen?=1
	CP R10, #%FF  				; modus? 0=startup, 255 = reset
	JR NZ, Marke_002  		;
	LD P01M, #%45  			; #69
	LD R3, #%1F  				; KBCLK, KBDAT frei .... P34=1 (PPI.PC4)

Marke_002:
	CP R8, #1
	JR NE, Marke_0021
	LD R8, #2
	JP SR1

Marke_0021:
	CLR R1
	TM IRQ, #%04  ; # poll IRQ2 ... KBCLK geht low? Startbit
	JR Z, Marke_001  ; nein
	LD R3, #%1F  ; P3 = 0001.1111 ... P37=0, P34=1 .. bereit zum empfangen von bit von tastatur

Samplen:
	CLR IRQ
	LD R13, R3
	INC R11 
	RRC R13
	RRC R12
	RRC R7
	CP R11, #11  ; 11 bits empfangen?
	JR GE, Fertig_empfangen  ; goto fertig

Marke_003:
	LD R4, R3
	TM R4, R14		; P32 
	JR Z, Reset_Keyb  ; 0 = hold KBclk low

	TM IRQ, #%04  ; auf fallende CLK warten
	JR NZ, Samplen  ;
	JP Marke_003  ;

Fertig_empfangen:
	LD R3, #%3F  ; fertig.   KBCLK low
	CLR IRQ
	TM R3, R15 	;P33 ??
	JR NZ, wait_for_PPI  ; goto Schalter einlesen
	CALL Scancode
	CLR R10
	CP R12, #0
	JP EQ, PC_Empfang_best
	LD R1, R12			; Ausgabe byte
	CP R12, #%AA
	JR NE, SR1
	CP R8, #0
	JR NE, SR1
	LD R8, #1
SR1:
	CP R8, #2
	JR NE, SR2
	LD R1, #%AA
	LD R8, #3
SR2:
	LD R3, #%7F  ; IRQ auslösen, CLK low

wait_for_PPI:					; Nach dem empfangen:
	LD R4, R3
	TM R4, R14
	JR Z, Reset_Keyb 
	TM IRQ, #%02  ; IRQ1 P33
	JR NZ, PC_Empfang_best  ; %0098
	TM R4, R15
	JR Z, wait_for_PPI  ; %0079
	CALL Read_Switch
	JR wait_for_PPI  ; %0079

Prep_Read_Switch: ; Schalter einlesen
	LD P01M, #%45  ; #69
	LD R3, #%3F  ; KBCLK low + PPI.PC4 = high
	CALL Read_Switch  ; Schalter einlesen
	JP Marke_000  ;			Zurück auf Anfang

PC_Empfang_best:
	CLR R1
	LD R3, #%1F  ; #159
	JP Marke_000  ; %0026

Read_Switch:				; Reihenfolge umkehren und Schalter auf P1 ausgeben
	LD R5, R0			; P0... Schalter einlesen
	LD R4, #%08			;counter i=8
Loop_ReadSwitch:
	RRC R5
	RLC R6
	DJNZ R4, Loop_ReadSwitch
	LD R1, R6
	RET

Reset_Keyb:
	LD R3, #%3F  		; KBCLK force low, KBData high, PC4 high
	TM R4, R15			; read sw = 1 (P33...PB7)
	JR NZ, Marke_012  	; goto read switch
	LD P01M, #%45  		; p1 out
	LD R4, R3
	AND R4, #%01  ; KDATA auf P1 ausgeben
	LD R1, R4
	JR Marke_013  ; %00C1

Marke_012:				; read switch
	LD P01M, #%4D  ; P0 in ,p1 in

Marke_013:
	LD R10, #%FF  ; #255
	JP Marke_000  ; %0026

Scancode:
	; R3 - 	1 = breakcode empfangen
	;		2 = E0 Code empfangen
	;		4 = E1 Code empfangen
	; R4 - E1 zähler
	RLC R7	 ; Paritybit und Stopbit löschen
	RLC R12	
	RLC R7
	RLC R12
	SRP #%10
	LD R1, 12			; empfangenes Zeichen in R1 kopieren
	LD R2, R1			; Ausgang = Eingang
	
	CP R1, #%E0
	JR EQ, SC_CodeE0
	CP R1, #%E1
	JR EQ, SC_CodeE1
	CP R1, #%F0
	JR EQ, SC_Break0
	

	TM R3, #2			;E0 Bit gesetzt?
	JR NZ, sc_E0gesetzt
	
	TM R3, #4			;E1 Bit gesetzt?
	JR NZ, SC_E1gesetzt
	
	LD R0, #%07			; Lookuptabelle bei 0x0700
	LDC R2, @RR0
	JR sc_codeok
	
SC_E1gesetzt:
	AND R3, #%FB		; E1 Bit löschen
	JR sc_codeok
	
sc_E0gesetzt:
	LD R0, #%06			; Lookuptabelle bei 0x0600
	LDC R2, @RR0
	AND R3, #%FD		; E0 Bit löschen
sc_codeok:
	CP R2, #%FF			
	JR NE, SC_Taste_OK
	LD R2, #0
	JR SC_Taste_OK2
SC_CodeE0:
	OR R3, #2			; E0  Bit in R3
	JR SC_Taste_OK2
	
SC_CodeE1:
	OR R3, #4			; E0  Bit in R3
	JR SC_Taste_OK2
	
SC_Break0:
	LD R2, #0
	OR R3, #1			; F0  Bit in R3
	JR SC_Taste_OK2
SC_Break1:
	OR R2, #%80
	AND R3, #%FE			; F0 Bit löschen
SC_Taste_OK:
	TM R3, #1
	JR NZ, SC_Break1
SC_Taste_OK2:

	LD 12, R2					;Ergebnis in 12 speichern
	SRP #%00
	RET

Send_To_Keyb:
; R2 - input - byte to send
	SRP #%20
	; Testen ob Leitungen bereit sind
		LD R0, P3
		TM R0, #1 	; Data high? ja = gut
		JR NZ, SK_goto1
		JP SK_exit
	SK_goto1:
		TM R0, #2 	; Clock high? ja = gut
		JR NZ, SK_goto2
		JP SK_exit
	SK_goto2:
	
		LD R15, R2
		CALL calc_parity ; ab hier parity in R15
		
		
		; bis hier Data+CLK = high
		; CLK low für ~100µs
		LD P3, #%3f
		LD R0, #200
		CALL delay_loop
		;CLK high...
		LD P3, #%bf		;CLK+DATA low

		LD P3, #%9F  ; KBDat low, startbit
		
		LD R1, #10	;sende 8 databits, 1 paritybit, 1 stopbit
	SK_start_sendbyte:
		LD R0, P3
		TM R0, #%20
		JR NZ, SK_start_sendbyte ; auf CLK low warten
		;clk ist jetzt low, von Keyboard
		CP R1, #2
		JR EQ, SK_putparity
		CP R1, #1
		JR EQ, SK_putstopbit
		TM R2, #%01
		JP SK_put_bit
	SK_putparity:
		TM R15, #%01
		JP SK_put_bit
	SK_putstopbit:
		LD P3, #%9F
		JP SK_put_finished
	SK_put_bit:
		JR Z, SK_put_zero
		LD P3, #%1F
		JR SK_put_finished
	SK_put_zero:
		LD P3, #%9F
	SK_put_finished:
		RR R2
	SK_wait_clk_hi:
		LD R0, P3
		TM R0, #%20
		JR Z, SK_wait_clk_hi ; auf CLK high warten

		DJNZ R1, SK_start_sendbyte	; loop ende, 10 bits gesendet
		
		
		LD R0, P3
		TM R0, #%20
		JR NZ, SK_start_sendbyte ; auf CLK low warten
		;clk ist jetzt low, von Keyboard
		; ACK samplen:
		LD R0, P3
		TM R0, #%10
		JR Z, SK_exit
	SK_exit:
	SRP #0
	RET

calc_parity: ;R15 - input, output
	LD R13, #0
	LD R14, #8
calcparloop:
	TM R15, #1
	JR Z, calcpar2
	inc R13
calcpar2:
	RR R15
	DJNZ R14, calcparloop
	COM R13
	AND R13, #%01
	LD R15, R13
	
	RET
	
	
delay_loop:
		NOP
		DJNZ R0, delay_loop
	RET