415
01.02.2016, 12:26 Uhr
holm
|
Ich habe nun eine Weile mit den SIO Treibern gekämpft, genauer gesagt mit der Hardware Flußcontrolle des Kanals B (Kein Unterschied zu A). Ich habe mehrmals gedacht ich habe eine Macke, aber das Problem scheint prinzipieller Natur bei der SIO zu sein. Üblicherweise verdrahtet man RTS und CTS gekreuzt zu Flußcontrolle, aber bei der SIO hat die Sache einen Haken, nämlich den hier: "Sobald das RTS-BIT eines Kanals gesetzt ist, geht die zugehörige RTS-Leitung in den Low-Zustand über. Wird das RTS-BIT in der asynchronen Betriebsart rückgesetzt, geht die zugehörige RTS-Leitung in den High-Zustand, sobald das Senderegister leer ist. In der synchronen Betriebsart..."
D.h. RTS macht nicht so recht was ich mit ihm machen will sondern geht eigene Wege, was daran liegt das RTS ursprünglich einen anderen Zweck hatte und wohl deshalb dieses Verhalten zeigt weil z.B. die ACIA des 6800 Systems da einen fetten Bug hat, die bricht nämlich die Übertragung nicht nach einem gesendeten Byte ab, sondern mitten drin :-~ was zwangsläufig zu Kauderwelsch auf im Empfänger führt.
Bei RTS/CTS Handshake dient der RTS Ausgang aber nicht der Bitte Senden zu dürfen sondern als Signal an den gegenüberliegenden Sender ggf. das Senden einzustellen weil der Empfangspuffer voll ist, das bedeutet das RTS hier ein ziemlich suboptimaler Ausgang der SIO zu diesem Zweck ist. Ich habe ne Weile gesucht, andere Leute haben das damit gelöst das sie nicht den RTS Ausgang genutzt haben sondern den frei programmierbaren DTR.
Ich habe das mal umverdrahtet und damit funktioniert bei 4800 Baud die Empfangsroutine störungsfrei, mit RTS ist zu erwarten das immer dann wenn der Sender noch was zu tun hat das Empfangen in die Hose geht, also z.B: dann wenn man ein Basic Programm über die Console hochlädt in dem man ein Basic Programm einfach mit drag&drop in das Terminalfenster fallen läßt, jedes eingegebene Zeichen wird ja dann über den Sender der SIO an die Console geechoet und damit geht RTS einfach nicht auf inaktiv und der PC hört nicht auf Daten zu senden.
Interessanter Weise kann die Sio das im Sendebetrieb aber fehlerfrei mit interner Hardware (autoenable). Sie kümmert sich gewissermaßen liebevoll um ihre Partner und kommt selber zu kurz da die meisten PC UARTs auch noch zu doof sind anzuhalten bevor deren FIFOs leer sind.
Quellcode: | RUN HI! I'M ELIZA. WHAT'S YOUR PROBLEM? ? FLOW CONTROL SAY, DO YOU HAVE ANY PSYCHOLOGICAL PROBLEMS? ? NO ARE YOU SAYING NO JUST TO BE NEGATIVE? ? YES ARE YOU SURE? ?
|
Das Einlesen funktioniert jedenfalls fehlerfrei.
Hat noch Jeamnd Hinweise?
Quellcode: | ;============================================================== ; check console status ckstb: push hl push bc ld hl,rxbwp ; write pointer ld b,a ld a,(rxbrp) ; read pointer cp (hl) ; set zero flag ld a,b pop bc pop hl ret ;============================================================== bufst: ld a,(rxbwp) ; write pointer ld hl,rxbrp ; (hl)read pointer sub (hl) ; difference jr z,bufst1 ; wp == rp jr nc,bufst1 ; wp > rp add a,BUFSIZ ; wp < rp, wrap around and BUFSIZ-1 ; mask relevant bits bufst1: ld (rxbchr),a ; save it ret ;============================================================== ; ; get char from channel B using int's ; crtin: call ckstb jr z,crtin ; wait for char push hl ld a,(rxbrp) ; read pointer call bufadd ; build phys addr and a ld (rxbrp),a ; update read pointer ld a,(hl) ; address in hl push af ; save data call bufst ; buffer status cp LOWMARK ; almost empty? jr nc, crti1 ; no ; RTS ON ld a,5 ; yes, switch on RTS out (siobc),a ; address WR5 ld a,(sbw5) ; init value WR5 out (siobc),a ; write WR5 crti1: ei pop af ; get data back pop hl ret ;============================================================== ; receiver interrupt routine channel B rxbisr: push af push hl call bufst cp BUFSIZ-1 ; Buffer full? jr z,rxbex ; we lose a char.. in a,(siobd) ; get data push af ; save it ld a,(rxbwp) ; buffer address call bufadd ld (rxbwp),a ; update address pop af ; get data back ld (hl),a ; insert into ring buffer ; RTS OFF call bufst ; buffer status cp HIMARK ; almost full? jr c,rxbex ld a,5 ; switch off RTS out (siobc),a ; address WR5 ld a,(sbw5) ; init value WR5 and 07bh ; reset DTR & RTS bit out (siobc),a ; write WR5 rxbex: pop hl isrend: pop af ei reti
;============================================================== ; ; ISR reset extern status ints ; errisr: push af ld a,1 ; RR1 out (siobc),a in a,(siobc) ; get error status ld a,0011000b ; WR0 error reset ld a,0011000b ; WR0 error reset out (siobc),a in a,(siobd) ; get data jr isrend
;==============================================================
|
Eines der 1. beiden Unterprogramme ist ziemlich redundant, kann sicher Eins entfallen. Code der verhindert das die Flußcontrolle mehrfach ein- bzw. ausgeschaltet wird habe ich wieder raus geschmissen, der ist genauso lang wie die verhinderte Redundanz..also Blödsinn.
Gruß,
Holm -- float R,y=1.5,x,r,A,P,B;int u,h=80,n=80,s;main(c,v)int c;char **v; {s=(c>1?(h=atoi(v[1])):h)*h/2;for(R=6./h;s%h||(y-=R,x=-2),s;4<(P=B*B)+ (r=A*A)|++u==n&&putchar(*(((--s%h)?(u<n?--u%6:6):7)+"World! \n"))&& (A=B=P=u=r=0,x+=R/2))A=B*2*A+y,B=P+x-r;} Dieser Beitrag wurde am 01.02.2016 um 12:34 Uhr von holm editiert. |