;===================================================================================================
; RS232 - receiving data through AY-3-8912 without flow control - 2 stop bits
;
; 57600bps (17,3611μs)	61.57813T na ZX128k, 61T bude trvat 17.19811μs, chyba -0.9% (58146bps)
;			60.76389T na ZX48k,  61T bude trvat 17.42857μs, chyba +0,4% (57377bps)
;===================================================================================================
;	AY I/O	ZX name	dir.	better name
;
;	A2	CTS	out	RTS	->
;	A3	RxD	out	TxD
;	A6	DTR	in	CTS
;	A7	TxD	in	RxD	<-

		cpu	z80undoc
		org	32768

START		di				; 4T
		exx				; 4T	sekundární sada
		push	hl			; 11T
		exx				; 4T	primární sada
		call	AY_INIT			;	dlouho
		ld	hl,16384		; 10T	data buffer - sem se bude ukládat
		ld	de,6912			; 10T	a uloží se 6912 bytů
		call	RECEIVE57600		;	mělo by trvat zhruba 1.32s (6912*11/57600)

; 		ld	hl,49152		; 10T	načtená data zkopíruj do VRAM, pokud nejsou
; 		ld	de,16384		; 10T
; 		ld	bc,6912			; 10T
; 		ldir				; 21*6911+16 = 145147T (40.9ms, tj. 2/50s)

		exx				; 4T	sekundární sada
		pop	hl			; 10T	obnov HL', BASIC potřebuje
		exx				; 4T	primární sada
		ei				; 4T
		ret				; 10T

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

RECEIVE57600	dec	hl			; 6T	bude zvýšeno během čekání
		ld	bc,65533		; 10T	datový port AY-3-8912 do BC

; kontrola jestli nezačal přenos - pak by byla špatně synchronizace se start bitem
RECEIVE_START	in	a,(c)			; 12T	čti port, nastaví sign flag dle MSB
		jp	p,RECEIVE_ERROR		; 10T	chyba, RxD má být v log. 1 (klidový stav/stop bit)
; zpoždění detekcí 12+10 = 22T

; čekání na start bit
RECEIVE_WFSB	in	a,(c)			; 12T	čti port
		rlca				; 4T	bit 7 do carry flagu
		jp	c,RECEIVE_WFSB		; 10T	opakuj do start bitu

; smyčka čekání 12+4+10 = 26T

; start bit začal, čeká se na bit 0
; dlzka cakania je zvolena tak, aby bit 0 bol niekde vo svojej polovici
; od hrany startbitu uplynulo najmenej 15T, najviac 41T, berieme priemer 28T
; treba este cakat 1.5 x 61T - 28T = 63.5T (z toho 11T na dalsiu instrukciu IN)

		dec	de			; 6T	sniž počítadlo bytů, testovat se bude později
		inc	hl			; 6T	zvyš adresu v RAM, kam se byte uloží
		exx				; 4T	sekundární sada
		ld	bc,65533		; 10T	datový port AY-3-8912 do BC' (a zpoždění zároveň)
		inc	hl			; 6T	zpoždění
		dec	hl			; 6T	zpoždění
		ld	a,0			; 7T	zpoždění
		ld	h,7			; 7T	v cyklu bude čteno 7 bitů a 8. po skončení cyklu

; 6+6+4+10+6+6+7+7 = 52T
; teraz je bit 0 niekde v polovici, mozme citat 8 krat s odstupom 61T

RECEIVE_LOOP	in	a,(c)			; 12T	načti port
		rlca				; 4T	bit 7 do carry flagu
		rr	l			; 8T	buduj bajt v L
		ld	a,0			; 7T	zpoždění
		ld	a,0			; 7T	zpoždění
		ld	a,r			; 9T	zpoždění
		dec	h			; 4T	počítadlo
		jp	nz,RECEIVE_LOOP		; 10T	čti další bity

; 12+4+8+7+7+9+4+10 = 61T opakuje-li se (bity 0 až 6)

; následuje čtení MSB, bit 7
		in	a,(c)			; 12T	načti port (MSB je někde v půlce trvání, do stopbitu cca 31 ± 13T ± 2T odchylka přesnosti 3%)
		rlca				; 4T	bit 7 do carry flagu
		ld	a,l			; 4T	téměř sestavený byte do A
		rra				; 4T	narotuj MSB do bitu 7 v A

; 12+4+4+4 = 24T

		exx				; 4T	primární sada
		ld	(hl),a			; 7T	ulož byte do RAM
		ld	a,d			; 4T	všechny byty přijaté?
		or	e			; 4T	zkontroluj
		jp	nz,RECEIVE_WFSB		; 10T	čekej na další byte
		ret				; 10T

; uložení bytu trvá 4+7+4+4+10 = 29T
; celkem 24+29=53T
; včetně detekce stavu linky, 75T s ověřením před start bitem
; jinak lze rovnou čekat na další startbit

RECEIVE_ERROR	exx				; 4T	primární sada
		ld	a,2			; 7T	DEBUG
		out	(254),a			; 11T	DEBUG
		ei				; 4T
		ret				; 10T

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

AY_INIT		ld	bc,65533		; 10T	BC = 65533 (11111111 11111101)
		ld	a,7			; 7T	zvol registr 7 v AY
		out	(c),a			; 12T	65533,7

		ld	a,b			; 4T	A = 255, vypni zvuk a nastav I/O port jako výstup (bit 6 v log. 1)
		ld	b,191		; 	; 7T	BC = 49149 (10111111 11111101)
		out	(c),a			; 12T	49149,255

		ld	b,a			; 4T	BC = 65533
		ld	a,14			; 7T	zvol registr 14 v AY
		out	(c),a			; 12T	65533,14

		ld	a,b			; 4T	A = 255
		ld	b,191			; 7T	BC = 45149
		out	(c),a			; 12T	49149,255 = zapiš 255 a nastav pullupy na H, teď je možné port i číst

		ret				; 10T

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -