Zurück zu den JOYCE-Aktivitäten |
|
Werner Cirsovius, durch seine Firmware-Artikel in NEWS 2+3/87 bereits bestens bekannt, beschreibt hier die Serielle Schnittstelle und ihre Programmierung. In Unterschied zu manch anderen Listings, vorwiegend in Pascal geschrieben und daher nicht von jedem verwendbar, wird in der NEWS nicht der Source-Asssemblerkode oder der Basic-Lader auf Diskette veröffentlicht, sondern das Ergebnis dieses Artikels, ein speziell von Werner für den JOYCE angepaßtes Datenübertragungsprogramm aus dem Public-Domain-Tool: KERMIT! |
BIT | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
SC1 | SC0 | RL1 | RL0 | M2 | M1 | M0 | BCD |
T = fCPU / (32*BAUD) |
timer equ 0e7h baud0 equ 0e4h word equ 0011$0110b value equ 417 doit: mvi a,wrd out timer mvi a,low value out baud0 mvi a,high value out baud0 ret |
1000 baud=300 1010 value=4000000!/(32*baud) 1020 OUT &HE7,&H36 1030 OUT &HE4,value MOD 256 1040 OUT &HE4,value\256 1050 RETURN |
program BaudRate; const Word = $36; Baud0 = $E4; Value = 417; procedure bd_set(Word, Baud0, Value : integer); const Timer = $E7; begin port[Timer] := Word; port[Baud0] := lo(Value); port[Baud0] := hi(Value); end; begin bd_set(Word, Baud0, Value); end. |
CALL USERF DW XBIOS_FUNDie Funktionen im XBIOS können unterteilt werden in:
XBIOS_FUN: | 00B6H | |
Subfunktion: | UART Werte setzen | |
Register: | Accu | Gewählter Modus |
00H: Kein Handshake | ||
FFH: Handshake | ||
D | Anzahl Stop Bits | |
0 : 1 Stop Bit | ||
1 : 1,5 Stop Bits | ||
2 : 2 Stop Bits | ||
E | Parität | |
0 : Keine | ||
1 : Ungerade | ||
2 : Gerade | ||
H | Anzahl Datenbits des Enpfängers | |
L | Anzahl Datenbits des Senders (5, 6, 7 o. 8) | |
Subfunktion: | UART Bits DTR und RTS setzen/löschen | |
Register: | Accu | 7DH RTS ein |
7EH RTS aus | ||
7FH DTR ein | ||
80H DTR aus |
XBIOS_FUN: | 00B9H |
Register: | H kodierte Baudrate für Empfänger |
L kodierte Baudrate für Sender |
Code: | 0: | — | 8: | 1200 Bd |
1: | 50 Bd | 9: | 1800 Bd | |
2: | 75 Bd | 10: | 2400 Bd | |
3: | 110 Bd | 11: | 3600 Bd | |
4: | 134,5 Bd | 12: | 4800 Bd | |
5: | 150 Bd | 13: | 7200 Bd | |
6: | 300 Bd | 14: | 9600 Bd | |
7: | 600 Bd | 15: | 19200 Bd |
XBIOS_FUN: | 00BCH | |
Nach Aufruf dieser Funktion sind die Register wie folgt belegt: | ||
Accu | 00H: kein Handshake | |
FFH: Handshake | ||
B | Kodierte Epfänger Baudrate | |
C | Kodierte Sender Baudrate | |
D | Stop Bits (s.o.) | |
E | Parität (s.o.) | |
H | Datenbits des Empfängers (s.o.) | |
L | Datenbits des Senders (s.o.) |
CALL USERF ;Laden der UART Werte DW 00BCH MOV H,B ;Empfänger so lassen MVI L,6 ;Sender 300 Baud CALL USERF ;Rate setzen DW 00B9HBleibt noch die Frage zu klären, wie das Unterprogramm "USERF" aussehen muß. Hierzu sollte der BIOS Vektor der Funktion 30 am Programmanfang initialisiert werden
INIT: LHLD 1 ;BIOS Basis Adresse LXI B,3*(30-1) ;Offset laden DAD B ;Vektor berechnen SHLD USERF+1 ;Als Sprungziel speichern RET USERF: JMP $-$ ;Sprung zur BIOS Funktion 30
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Bit |
— | — | — | — | — | TxBE | — | RxCA | RR0 |
OUTPUT: PUSH PSW ; Zeichen retten WAIT: IN 0E1H ; Warten bis Zeichen da ANI 0000$0100B JZ WAIT POP PSW OUT 0E0H ; Ausgabe RETFunktion 2 : Anzeige ob Übertragungsfehler vorliegt
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Bit |
— | FE | OE | PE | — | — | — | — | RR1 |
ERROR: MVI A,1 OUT 0E1H ; RR1 adressieren IN 0E1H ; Fehler einlesen PUSH PSW MVI A,0 OUT 0E1H ; RR0 adressieren POP PSW ANI 0111$0000B ; Zero Flag beeinflussen RETFunktion 3 : Anzeige von externen Leitungszuständen
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Bit |
— | — | CTS | DSR | DCD | — | — | — | RR0 |
STATUS: MVI A,0001$0000B OUT 0E1H ; Reset einmal OUT 0E1H ; .. zweimal IN 0E1H ; Externe Signale lesen ANI 0011$1000B ; Bits maskieren RET
Zusatz zum gedruckten Artikel:In einigen Anwendungen ist es notwendig, ein BREAK-Signal abzusenden. Dies ist ein Signal, dass die Sendeleitung für ca. 300 Millisekunden (ms) aktiviert, wodurch auf der Empfangsseite eine Unterbrechung ausgelöst wird. Beim Z80 UART funktioniert dies über das Schreibregister WR5.
SENDBR: MVI D,1001$1010B ; Maske für BREAK MVI E,30 ; Länge des BREAK-Signals ist ; 300 Millisekunden SNDBR1: MVI A,1 ; RR1 adressieren OUT 0E1H IN 0E1H ; Einlesen ANI 0000$0001B ; Testen des "ALL DONE" Bits JZ SNDBR1 ; Warten bis gesetzt ; ; Nun wird das BREAK-Signal gesendet ; SETBIT: MVI A,5 ; WR5 adressieren OUT 0E1H LDA TXBITS ; Bits für Sender laden ; Diese Bits stehen wie folgt: ; x00x$xxxx 5 Bits ; x01x$xxxx 7 Bits ; x10x$xxxx 6 Bits ; x11x$xxxx 8 Bits ORA D ; Ausgabe BREAK, OUT 0E1H ; TXENABLE, RTS ; ; Jetzt Verzögerung von 300 Millisekunden durchführen ; MOV A,E ; Verzögerungswert CALL DELAY ; ; Die Zeit ist abgelaufen. ; Sender in den normalen Zustand versetzen. ; MVI A,5 ; WR5 adressieren OUT 0E1H LDA TXBITS ; Bits für Sender erneut laden ORI 1000$1010B ; Kein BREAK OUT 0E1H ; Aber TXENABLE und RTS RET ; Fertig ; ; Beispiel für eine Verzögerungsroutine ; Hier für 10 Millisekunden ; DELAY: LD C,40 ; Entspricht 4 MHz DELAY2: LD B,70 DELAY3: DEC B JP NZ,DELAY3 DEC C JP NZ,DELAY2 DEC A JP NZ,DELAY RET |
Nachbemerkung der Redaktion: Wir sind interessiert an Erfahrungsberichten über DFÜ, Mailboxen, Schnittstellen...... |