;================================================================================================== ; RS232 - transmitting through AY-3-8912 with waiting for CTS from receiving side ; ; 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 ; musí běžet v rychlé RAM START di ; 4T nesmí být zpomalováno a přerušováno ; ld a,7 ; DEBUG ; out (254),a ; DEBUG ld hl,DATA ; 10T adresa dat ld de,DATA_LENGTH ; 10T počet bytů k přenesení TRANS_SET_AY_IN exx ; 4T přepni na sekundární sadu 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 exx ; 4T přepni na primární sadu ; nastavení portu AY trvá 4+10+7+12+4+7+12+4+7+12+4+7+12+4+4 = 110T WAIT_FOR_CTS exx ; 4T přepni na sekundární sadu ld hl,64 ; 10T H = 0 počítadlo, L = 01000000, maska pro bit 6, vstup CTS ld b,255 ; 7T BC = 65533, to je port, který lze číst, ne 49149 ; připraven číst I/O port WAIT_FOR_CTS_L in a,(c) ; 12T čti AY I/O port 14 z 65533, čekáme na CTS and l ; 4T ponech jen bit 6 jp z,TRANSIEVE57600 ; 10T ; když je CTS v 0 4+10+7 + 12+4+10 = 47T a skok dec h ; 4T sniž počítadlo do 256 jp nz, WAIT_FOR_CTS_L ; 10T ; čtení portu probíhá 256x 12+4+10+4+10 = 40T, pak se testuje mezerník ld a,127 ; 7T port 32766 (klávesy B, N, M, SSHIFT, SPACE) in a,(254) ; 11T + zpomalení, protože pomalý port? rra ; 4T rotuj bit mezerníku vpravo skrz carry jp nc,END ; 10T NC = mezerník stisknutý (0 v bitu 0) jp WAIT_FOR_CTS_L ; 10T ; každý 256. cyklus 12+4+10+4+10+7+11+4+10+10 = 82T při občasném testu mezerníku TRANSIEVE57600 ld b,191 ; 7T BC = 49149, bude se zapisovat do I/O portu ld h,8 ; 7T H poslouží jako počítadlo 8 bitů exx ; 4T přepni na primární sadu ld a,(hl) ; 7T data k odeslání do A exx ; 4T přepni na sekundární sadu ld l,a ; 4T zkopíruj data z A do L rrc l ; 8T 4x rotuj data vpravo (LSB na pozici bitu 3) rrc l ; 8T dvě rotace před outem, aby vyšly takty ld a, 11110111b ; 7T maska ; příprava 7+7+4+7+4+4+8+8+7 = 56T ; start bit out (c),a ; 12T zapiš na port, začíná start bit rrc l ; 8T a dvě rotace ze 4 po outu rrc l ; 8T ; datové bity TRANSIEV_LOOP ld a,0 ; 7T zpoždění ld a,0 ; 7T zpoždění rrc l ; 8T další bit na pozici bitu 3 ld a,11110111b ; 7T připrav masku or l ; 4T přidej masku ; od začátku start bitu 12+8+8+7+7+8+7+4 = 61T ; od minulého bitu 12+4+12+7+7+8+7+4 = 61T out (c),a ; 12T zapiš na port dec h ; 4T počítadlo bitů jr nz,TRANSIEV_LOOP ; 12/7T opakuj ld a,(ix+0) ; 19T zpoždění nop ; 4T zpoždění nop ; 4T zpoždění ld a,11111111b ; 7T log. 1 do bitu 3 pro stop bit exx ; 4T přepni na primární sadu (BC, DE, HL) ; od posledního outu v cyklu 12+4+7+19+4+4+7+4 = 61T, trvání MSB ; stop bit out (c),a ; 12T zapiš na port inc hl ; 6T další adresa dec de ; 6T o byte míň ld a,d ; 4T testuj, jestli je počet na nule or e ; 4T jp nz,WAIT_FOR_CTS ; 10T opakuj, dokud nejsou přeneseny všechny byty ; od outu do skoku 12+6+6+4+4+10=42 ; ld a,6 ; 7T DEBUG ; out (254),a ; 11T DEBUG ei ; 4T povol přerušení ret ; 10T běžné ukončení přenosu ; od outu 12+6+6+4+4+10 = 42 ; při opakování bytu se prodlouží o trvání detekce stavu CTS a další režii na začátku kódu ; celkem při opakování s CTS trvale aktivním 42+47+56=145T víc než dva stop bity, ale ne o mnoho (145-122 = 23T) END exx ; 4T přepni na primární sadu ei ; 4T povol přerušení ; ld a,2 ; 7T DEBUG ; out (254),a ; 11T DEBUG ret ; 10T ukončení přenosu při stisku mezerníku nenastane-li CTS DATA db "Hello RS232 world! ZX Spectrum 128 is sending data." db 13,10 ; CR, LF ; db "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789" ; db 13,10 ; CR, LF DATA_LENGTH equ $ - DATA ; naměřeno má být (bez DEBUG barvy okraje) ; bit log. 0 16.40μs 17.361μs (ideální čas) ; bit log. 1 18.04μs 17.361μs (ideální čas) ; stop bit mezi byty 41.71μs 40.880μs (výpočtem ze 145T) ; ; šedá +2 má tendenci generovat log. 1 delší