hardware:doku:techrefguide:abschnitt4
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
hardware:doku:techrefguide:abschnitt4 [23/09/2007 17:09] – Formatierung uxt | hardware:doku:techrefguide:abschnitt4 [13/06/2020 18:06] (aktuell) – [4.1.4 Weitere nützliche Informationen] karlmueller | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== | + | ====== |
===== 4.1 SERIELLE KOMMUNIKATION DES PORTFOLIO ===== | ===== 4.1 SERIELLE KOMMUNIKATION DES PORTFOLIO ===== | ||
Zeile 18: | Zeile 18: | ||
7 RTS Sendeaufforderung | 7 RTS Sendeaufforderung | ||
8 CTS Sendebereit | 8 CTS Sendebereit | ||
+ | |||
| | ||
| | ||
Zeile 48: | Zeile 48: | ||
Da der Portfolio keinen 8259-kompatiblen Interrupt-Controller beinhaltet werden Interrupts anders gehandhabt als bei dem IBM-PC/ | Da der Portfolio keinen 8259-kompatiblen Interrupt-Controller beinhaltet werden Interrupts anders gehandhabt als bei dem IBM-PC/ | ||
- | Der serielle Port hat ein Register das Serielles Interrupt Vektor Register (SIVR) genannt wird. Es kann eiene 8-bit Zahl in dieses Register geschrieben werden. Der Wert ist die Interrupt-Zahl die mit dem seriellen Port verwendet werden soll. Jeder Interrupt ist ein Doppelwort Zeiger, die Adresse ist somit das vierfache der Interrupt-Nummer. Schreibt man z.B. die Zahl 10 ins SIVR, so wird ein Aufruf des an der Adresse 10x4 gespeicherten Doppelwort-Zeigers durchgeführt.\\ | + | Der serielle Port hat ein Register das Serielles Interrupt Vektor Register (SIVR) genannt wird. Es kann eine 8-bit Zahl in dieses Register geschrieben werden. Der Wert ist die Interrupt-Zahl, die mit dem seriellen Port verwendet werden soll. Jeder Interrupt ist ein Doppelwort Zeiger, die Adresse ist somit das vierfache der Interrupt-Nummer. Schreibt man z.B. die Zahl 10 ins SIVR, so wird ein Aufruf des an der Adresse 10x4 gespeicherten Doppelwort-Zeigers durchgeführt.\\ |
SIVR ist an der I/O Adresse 807FH und ein nur-lese-Register. Es sollte voreingestellt sein bevor 82C50A-Interrupts eingesetzt werden.\\ | SIVR ist an der I/O Adresse 807FH und ein nur-lese-Register. Es sollte voreingestellt sein bevor 82C50A-Interrupts eingesetzt werden.\\ | ||
- | Wenn der 82C50A einen Interrupt auslöst wird dieser zur CPU weitergeleitet. Wenn keine anderen Interrupts anstehen wird die CPU den Inhalt des SIVR auslesen und die entsprechende Interrupt-Nummer ausführen).\\ | + | Wenn der 82C50A einen Interrupt auslöst, wird dieser zur CPU weitergeleitet. Wenn keine anderen Interrupts anstehen, wird die CPU den Inhalt des SIVR auslesen und die entsprechende Interrupt-Nummer ausführen).\\ |
- | Interrupts werden durch einen Zugriff auf das 82C50A und das Auslesen des IIR bestätigt. Dies ermöglicht die notwendige Aufgabe den zu bestimmenden Interrupt auszuführen und zu bestätigen.\\ | + | Interrupts werden durch einen Zugriff auf das 82C50A und das Auslesen des IIR bestätigt. Dies ermöglicht die notwendige Aufgabe, den zu bestimmenden Interrupt auszuführen und zu bestätigen.\\ |
==== 4.1.4 Weitere nützliche Informationen ==== | ==== 4.1.4 Weitere nützliche Informationen ==== | ||
- | Um festzustellen ob eine serielle Schnittstelle angeschlossen ist empfielt | + | Um festzustellen ob eine serielle Schnittstelle angeschlossen, ist empfiehlt |
Wärend der Portfolio versucht sich nach dem Warten auf einen Tastendruck auszuschalten (Int 16H Fn 00H), kann eine Terminal Emulation die Tatstatur per Software so lange pollen bis ein Tastendruck im Puffer wartet (Int 16H Fn 01H). Beachten sie, da dies das automatische Ausschalten des Portfolios verhindert und den Prozessor im Run-Modus hält, anstatt im " | Wärend der Portfolio versucht sich nach dem Warten auf einen Tastendruck auszuschalten (Int 16H Fn 00H), kann eine Terminal Emulation die Tatstatur per Software so lange pollen bis ein Tastendruck im Puffer wartet (Int 16H Fn 01H). Beachten sie, da dies das automatische Ausschalten des Portfolios verhindert und den Prozessor im Run-Modus hält, anstatt im " | ||
Zeile 74: | Zeile 74: | ||
Um eine zukünftige Kompatibilität zu erhalten ist es ratsam die Adresse des oben verwendeten Tabelleneintrags auf null zu setzen bevor das Programm beendet wird. Darauf sollte ein schreiben von 48H in I/O 807FH folgen.\\ | Um eine zukünftige Kompatibilität zu erhalten ist es ratsam die Adresse des oben verwendeten Tabelleneintrags auf null zu setzen bevor das Programm beendet wird. Darauf sollte ein schreiben von 48H in I/O 807FH folgen.\\ | ||
+ | |||
+ | |||
+ | |||
+ | |||
Zeile 94: | Zeile 98: | ||
Alt_Q kann verwendet werden um das Programm zu verlassen.\\ | Alt_Q kann verwendet werden um das Programm zu verlassen.\\ | ||
+ | \\ | ||
+ | \\ | ||
+ | **TM.INC**\\ | ||
+ | <code asm> | ||
+ | ; | ||
+ | ; tm ; | ||
+ | ; | ||
+ | ; | ||
+ | |||
+ | ; Definitionen für den Zugriff auf den 82C50 des seriellen Ports | ||
+ | |||
+ | SER_BASE equ 400h ; | ||
+ | |||
+ | ; Offsets von der Basis-Adresse der Kontroll-Register des 82C50 | ||
+ | |||
+ | RBR equ 0h ; Register des Receiver-Puffers | ||
+ | THR equ 0h ; | ||
+ | IER equ 1h ; | ||
+ | IIR equ 2h ; | ||
+ | LCR equ 3h ; | ||
+ | MCR equ 4h ; | ||
+ | LSR equ 5h ; | ||
+ | MSR equ 6h ; | ||
+ | |||
+ | ; Interrupt Controller | ||
+ | INT_REG equ 807fh ; | ||
+ | INT_ON equ 01h ; | ||
+ | INT_OFF equ 00h ; | ||
+ | INT_NUM equ 0ch ; | ||
+ | |||
+ | ; Kontroll-Bytes | ||
+ | |||
+ | DTR equ 01h ; | ||
+ | RTS equ 02h ; | ||
+ | THRE_MASK equ 20h ; | ||
+ | |||
+ | ; Speicherzuweisungsblöcke | ||
+ | |||
+ | BUF_LEN equ 100h ; | ||
+ | STK_LEN equ 200h ; | ||
+ | |||
+ | ; diverse Definitionen | ||
+ | |||
+ | CR equ 0dh ; | ||
+ | LF equ 0ah ; | ||
+ | PORT_DEFAULT equ 83h ; | ||
+ | STRP_TOP equ 7fh ; | ||
+ | |||
+ | </ | ||
\\ | \\ | ||
\\ | \\ | ||
+ | **TMTM.ASM**\\ | ||
+ | <code asm> | ||
+ | name tmtm | ||
+ | |||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; ; | ||
+ | ; Dieser Terminal-Emulator ist vollständig interrupt ; | ||
+ | ; gesteuert und zeigt wie Anwendungen für den seriellen ; | ||
+ | ; Port des Pocket PC geschrieben werden können ; | ||
+ | ; ; | ||
+ | ; Dieses Modul sollte am Anfang von gelinkten Objekten ; | ||
+ | ; | ||
+ | ; ; | ||
+ | ; | ||
+ | |||
+ | extrn tmio_inon: | ||
+ | extrn tmio_init: | ||
+ | extrn tmky_gtky: | ||
+ | extrn tmio_char: | ||
+ | extrn tmio_intc: | ||
+ | extrn tmio_offc: | ||
+ | extrn tmio_segc: | ||
+ | |||
+ | include tm.inc | ||
+ | |||
+ | code segment byte public | ||
+ | |||
+ | org 100h | ||
+ | |||
+ | code ends | ||
+ | |||
+ | ; pgroup erlaubt das Linken mehrerer Module so, dass die gesamte | ||
+ | ; Code-Größe ermittelt werden kann | ||
+ | |||
+ | pgroup group code, | ||
+ | assume cs: | ||
+ | |||
+ | code segment byte public | ||
+ | |||
+ | |||
+ | tmtm_main proc near | ||
+ | |||
+ | ; Geben sie unbenötigten Speicher frei damit die eingebauten Anwendungen | ||
+ | ; aufgerufen werden können | ||
+ | |||
+ | mov ah, 4ah ; Speicherzuweisung modifizieren | ||
+ | mov bx, offset pgroup: | ||
+ | mov cx, 4 | ||
+ | shr bx, cl ; durch 10h teilen; bx enthält Paragraphen | ||
+ | int 21h ; | ||
+ | jnc tmtm_mmok ; | ||
+ | |||
+ | ; Modifikation der Speicherzuweisung fehlgeschlagen: | ||
+ | |||
+ | mov ah, 9h ; Meldung ausgeben | ||
+ | mov dx, offset tmtm_fail ; Zuweisung fehlgeschlagen | ||
+ | int 21h | ||
+ | |||
+ | mov ax, 4c00h ; Programm beenden | ||
+ | int 21h | ||
+ | |||
+ | ; Speichermodifikation erfolgreich: | ||
+ | |||
+ | tmtm_mmok: | ||
+ | |||
+ | ; Stapel in zugewiesenem Bereich einrichten | ||
+ | |||
+ | mov sp, offset pgroup: | ||
+ | |||
+ | ; Pocket PC LCD Bildschirm unter Verwendung DIP spezifischer Funktionen initialisieren | ||
+ | |||
+ | mov ax, 0e01h ; externen Bildschirmmodus auf | ||
+ | mov dl, 02 ; 80*25 dynamisch setzen | ||
+ | int 61h | ||
+ | |||
+ | mov ax, 1001h ; Position des Bildschirmausschnittes | ||
+ | mov dx, 0 ; auf obere linke Ecke des Bildschirms setzen | ||
+ | int 61h | ||
+ | |||
+ | mov ah, 9 ; Start-Up Meldung ausgeben | ||
+ | mov dx, offset tmtm_strt | ||
+ | int 21h | ||
+ | |||
+ | ; Interrupt 0ch (COM1 Interrupt Service-Routine) abgreifen | ||
+ | |||
+ | cli ; Interrupts unterbinden | ||
+ | push bx | ||
+ | push es | ||
+ | mov ax, 350ch ; aktuellen Int 0ch Vector ermitteln | ||
+ | int 21h | ||
+ | mov tmio_offc, | ||
+ | mov tmio_segc, | ||
+ | pop es | ||
+ | pop bx | ||
+ | |||
+ | mov dx, offset tmio_intc ; eigene 0Ch Service-Routine | ||
+ | mov ax, 250ch ; als tmio_intc aufbauen | ||
+ | int 21h | ||
+ | sti | ||
+ | |||
+ | call tmio_init ; | ||
+ | call tmio_inon ; | ||
+ | |||
+ | ; Hauptroutine des Emulators: Programmaustieg ist durch tmky_gtky | ||
+ | |||
+ | main_next: | ||
+ | call tmky_gtky ; | ||
+ | call tmio_char ; | ||
+ | jmp main_next | ||
+ | |||
+ | tmtm_main endp | ||
+ | |||
+ | ; Tabelle der Meldungen | ||
+ | |||
+ | tmtm_fail db ' | ||
+ | tmtm_strt db ' | ||
+ | |||
+ | code ends | ||
+ | |||
+ | ; endseg ist ein Dummy-Segment das am Ende des Terminal-Emulators erscheint | ||
+ | |||
+ | endseg segment byte public | ||
+ | |||
+ | last_byte: | ||
+ | |||
+ | endseg ends | ||
+ | |||
+ | end tmtm_main | ||
+ | |||
+ | </ | ||
\\ | \\ | ||
+ | \\ | ||
+ | **TMKY.ASM**\\ | ||
+ | <code asm> | ||
+ | name tmky | ||
+ | |||
+ | ; | ||
+ | ; | ||
+ | ; Terminal Tastatur Handler ; | ||
+ | ; ; | ||
+ | ; Dieses Modul steuert die Terminal Tastatur ; | ||
+ | ; es erlaubt den Emulator mit ALT Q zu verlassen ; | ||
+ | ; ; | ||
+ | ; | ||
+ | |||
+ | public tmky_gtky | ||
+ | |||
+ | extrn tmdp_prbf: | ||
+ | extrn tmio_exit: | ||
+ | |||
+ | include tm.inc | ||
+ | |||
+ | code segment byte public | ||
+ | assume cs: | ||
+ | |||
+ | ; | ||
+ | ; | ||
+ | ; Terminal Tastatur Handler ; | ||
+ | ; ; | ||
+ | ; wartet und verarbeitet Tartendruck ; | ||
+ | ; gibt ASCII-Zeichen in AL zurück | ||
+ | ; ; | ||
+ | ; ALT ruft Command Key auf ; | ||
+ | ; ALT Q beendet Programm | ||
+ | ; ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | |||
+ | tmky_gtky proc near | ||
+ | |||
+ | gtky_wtky: | ||
+ | call tmdp_prbf ; | ||
+ | |||
+ | mov ah, 1 ; prüfe Tasten-Status auf Tastendruck | ||
+ | int 16h ; | ||
+ | jz gtky_wtky ; | ||
+ | |||
+ | mov ah, 0 ; Taste bereit, also aus dem | ||
+ | int 16h ; | ||
+ | |||
+ | or al, al ; erweiterter Code? | ||
+ | jz gtky_test ; | ||
+ | |||
+ | ret | ||
+ | |||
+ | ;auf ALT-Codes prüfen | ||
+ | |||
+ | gtky_test: | ||
+ | cmp ah, 10h ; prüfe auf ALT Q | ||
+ | jne gtky_wtky ; | ||
+ | |||
+ | call tmio_exit ; | ||
+ | int 20h ; | ||
+ | |||
+ | tmky_gtky endp | ||
+ | |||
+ | code ends | ||
+ | end | ||
+ | </ | ||
+ | \\ | ||
+ | **TMDP.ASM**\\ | ||
+ | <code asm> | ||
+ | name tmdp | ||
+ | |||
+ | ; | ||
+ | ; | ||
+ | ; Dieses Modul steuert die Bildschirmausgabe ; | ||
+ | ; ; | ||
+ | ; | ||
+ | |||
+ | public tmdp_prbf | ||
+ | public tmdp_bptr | ||
+ | |||
+ | include tm.inc | ||
+ | |||
+ | code segment byte public | ||
+ | assume cs: | ||
+ | |||
+ | ; | ||
+ | ; | ||
+ | ; Inhalt des seriellen Eingangspuffer ausgeben ; | ||
+ | ; ; | ||
+ | ; Der Interrupt kann zusätzliche Zeichen in den ; | ||
+ | ; Puffer platzieren, außer wenn der Puffer ; | ||
+ | ; gerade modifiziert wird. ; | ||
+ | ; ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; ; | ||
+ | ; | ||
+ | |||
+ | tmdp_prbf proc near | ||
+ | |||
+ | push ax | ||
+ | push dx | ||
+ | push si | ||
+ | prbf_next: | ||
+ | |||
+ | ; sind wir am Anfang des seriellen Eingangspuffers? | ||
+ | |||
+ | cmp tmdp_bptr, | ||
+ | jne prbf_char ; | ||
+ | |||
+ | pop si | ||
+ | pop dx | ||
+ | pop ax | ||
+ | ret | ||
+ | |||
+ | ; mindestens ein Zeichen muss ausgegeben werden | ||
+ | |||
+ | prbf_char: | ||
+ | mov di, offset tmdp_cbuf ; | ||
+ | mov dl, [di] ; schreibe erstes Zeichen | ||
+ | mov ah, 2 ; in AH | ||
+ | int 21h ; | ||
+ | |||
+ | ; seriellen Puffer nachschieben | ||
+ | ; zuerst Interrupts unterbinden, | ||
+ | ; hinzugefügt werden wärend der Puffer modifiziert wird | ||
+ | |||
+ | cli ; | ||
+ | cld ; | ||
+ | mov cx, tmdp_bptr ; | ||
+ | dec cx ; | ||
+ | sub cx, offset tmdp_cbuf ; | ||
+ | mov si, offset tmdp_cbuf+1 ; | ||
+ | |||
+ | ; zu diesem Zeitpunkt zeigt es:di auf den Puffer und | ||
+ | ; ds:si zeigt auf ein Eingangszeichen. Der Puffer wird durch movsb um ein Zeichen | ||
+ | ; nach unten verschoben. | ||
+ | |||
+ | rep movsb ; | ||
+ | dec tmdp_bptr ; | ||
+ | sti ; | ||
+ | |||
+ | ; Puffer kann wieder Zeichen empfangen | ||
+ | |||
+ | jmp prbf_next ; | ||
+ | |||
+ | tmdp_prbf endp | ||
+ | |||
+ | ; Pufferspeicher | ||
+ | |||
+ | tmdp_cbuf db BUF_LEN dup (00) ; | ||
+ | tmdp_bptr dw offset tmdp_cbuf ; | ||
+ | |||
+ | code ends | ||
+ | end | ||
+ | </ | ||
+ | \\ | ||
+ | **TMIO.ASM**\\ | ||
+ | |||
+ | <code asm> | ||
+ | |||
+ | name tmio | ||
+ | |||
+ | ; | ||
+ | ; | ||
+ | ; Dieses Modul ist die Schnittstelle zum ; | ||
+ | ; seriellen Port ; | ||
+ | ; ; | ||
+ | ; Die Interrupt-Routine setzt voraus, | ||
+ | ; ein Interrupt die Anwesenheit eines Zeichens ; | ||
+ | ; am seriellen Eingang bedeutet ; | ||
+ | ; ; | ||
+ | ; Der Emulator führt keinen Handschake durch ; | ||
+ | ; Eine Baud-Rate von 1200 wird vorausgesetzt ; | ||
+ | ; 8 Datenbits/ | ||
+ | ; Oberstes Datenbit wird entfernt ; | ||
+ | ; ; | ||
+ | ; | ||
+ | |||
+ | public tmio_char | ||
+ | public tmio_init | ||
+ | public tmio_inon | ||
+ | public tmio_inof | ||
+ | public tmio_exit | ||
+ | public tmio_intc | ||
+ | public tmio_offc | ||
+ | public tmio_segc | ||
+ | |||
+ | extrn tmdp_bptr: | ||
+ | |||
+ | include tm.inc | ||
+ | |||
+ | code segment byte public | ||
+ | assume cs: | ||
+ | |||
+ | ; | ||
+ | ; | ||
+ | ; Sendet ein Zeichen zum seriellen Port ; | ||
+ | ; ; | ||
+ | ; | ||
+ | ; al: zu sendendes ASCII Zeichen ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | |||
+ | tmio_char proc near | ||
+ | |||
+ | push dx | ||
+ | push di | ||
+ | push ax | ||
+ | |||
+ | mov di, tmio_base ; Basisadresse von COM1 82C50 ermitteln | ||
+ | |||
+ | mov dx, LSR ; Leitungs-Status-Register | ||
+ | add dx, di | ||
+ | char_wthr: | ||
+ | in al, dx ; warte auf Transmitter-Bereitschaft | ||
+ | test al, THRE_MASK | ||
+ | jz char_wthr ; | ||
+ | |||
+ | pop ax | ||
+ | |||
+ | mov dx, THR ; Adresse des Transmitter Holding | ||
+ | add dx, di ; Register | ||
+ | out dx, al ; Zeichen an seriellen Port senden | ||
+ | |||
+ | pop di | ||
+ | pop dx | ||
+ | ret | ||
+ | |||
+ | tmio_char endp | ||
+ | |||
+ | ; | ||
+ | ; | ||
+ | ; Führt Initialisierung des seriellen Ports durch ; | ||
+ | ; ; | ||
+ | ; Port wird auf 1200 Baud, 8 bits, keine Parität ; | ||
+ | ; | ||
+ | ; DTR wird auf highgesetzt: | ||
+ | ; | ||
+ | ; ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | |||
+ | tmio_init proc near | ||
+ | |||
+ | push ax | ||
+ | push si | ||
+ | push dx | ||
+ | push di | ||
+ | |||
+ | xor ax, ax | ||
+ | push ds | ||
+ | mov ds, ax ; Segment Null | ||
+ | mov di, ds: | ||
+ | pop ds ; | ||
+ | mov tmio_base, | ||
+ | |||
+ | call tmio_inof ; | ||
+ | |||
+ | mov al, PORT_DEFAULT ; | ||
+ | call tmio_inpt ; | ||
+ | |||
+ | ; Interrupts für den seriellen Port konfigurieren | ||
+ | |||
+ | ; Auf einem IBM PC könnte folgender Code verwendet werden | ||
+ | ; | ||
+ | ; in al, 21h ; Zugriff auf 82C59 PIC | ||
+ | ; and al, 0efh ; int 0ch zulassen | ||
+ | ; out 21h, al | ||
+ | ; | ||
+ | ; Dies funktioniert nicht auf dem Pocket PC, aber folgender Code kann benutzt werden | ||
+ | |||
+ | mov ax, INT_NUM ; Interrupt Nummer | ||
+ | call tmio_sint ; | ||
+ | |||
+ | ; Modem Kontroll Register konfigurieren | ||
+ | |||
+ | mov dx, MCR ; sage der Welt wir sind bereit | ||
+ | add dx, di | ||
+ | |||
+ | mov al, DTR or RTS ; RTS/DTR setzen | ||
+ | |||
+ | ; Auf einem IBM PC muss die Interrupt-Leitung aktiviert werden: | ||
+ | ; | ||
+ | ; mov al, DTR or RTS or 8 | ||
+ | ; | ||
+ | |||
+ | out dx, al ; Modem Kontroll Register konfigurieren | ||
+ | call tmio_inon ; | ||
+ | |||
+ | mov dx, di ; Eingangspuffer des 82C50 löschen | ||
+ | in al, dx | ||
+ | |||
+ | pop di | ||
+ | pop dx | ||
+ | pop si | ||
+ | pop ax | ||
+ | ret | ||
+ | |||
+ | tmio_init endp | ||
+ | |||
+ | |||
+ | ; | ||
+ | ; | ||
+ | ; Aktiviert die seriellen Interrupts ; | ||
+ | ; ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; al, dx ; | ||
+ | ; ; | ||
+ | ; | ||
+ | |||
+ | tmio_inon proc near | ||
+ | |||
+ | mov dx, IER ; Register der Interrupt Aktivierung | ||
+ | add dx, cs: | ||
+ | mov al, INT_ON ; Interrupt aktiviert | ||
+ | out dx, al | ||
+ | |||
+ | ret | ||
+ | |||
+ | tmio_inon endp | ||
+ | |||
+ | ; | ||
+ | ; | ||
+ | ; serielle Interrupts unterbinden ; | ||
+ | ; ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; al, dx ; | ||
+ | ; ; | ||
+ | ; | ||
+ | |||
+ | tmio_inof proc near | ||
+ | |||
+ | mov dx, IER ; Register der Interrupt Aktivierung | ||
+ | add dx, cs: | ||
+ | mov al, INT_OFF ; Interrupts unterbinden | ||
+ | out dx, al | ||
+ | |||
+ | ret | ||
+ | |||
+ | tmio_inof endp | ||
+ | |||
+ | |||
+ | ; | ||
+ | ; | ||
+ | ; Service des seriellen Lese Interrupts ; | ||
+ | ; ; | ||
+ | ; Wird bei vollem Eingangs Register aufgerufen ; | ||
+ | ; Paltziert Zeichen in Puffer und kehrt zurück ; | ||
+ | ; ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | |||
+ | tmio_intc proc near | ||
+ | |||
+ | push ax | ||
+ | push dx | ||
+ | push di | ||
+ | |||
+ | mov dx, RBR ; Adresse des Receiver-Puffers | ||
+ | add dx, cs: | ||
+ | in al, dx ; empfangenes Zeichen in al schreiben | ||
+ | |||
+ | and al, STRP_TOP ; | ||
+ | |||
+ | mov di, cs: | ||
+ | mov cs: | ||
+ | inc cs: | ||
+ | |||
+ | ; Auf einem IBM PC muss der Interrupt durch folgenden Code bestätigt werden: | ||
+ | ; | ||
+ | ; mov al, 20h | ||
+ | ; out 20h, al | ||
+ | ; | ||
+ | ; Auf dem Pocket PC ist dies nicht notwendig | ||
+ | |||
+ | pop di | ||
+ | pop dx | ||
+ | pop ax | ||
+ | |||
+ | iret | ||
+ | |||
+ | tmio_intc endp | ||
+ | |||
+ | |||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; aus dem Terminal-Emulator ; | ||
+ | ; ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | |||
+ | tmio_exit proc near | ||
+ | |||
+ | push ax | ||
+ | push bx | ||
+ | push dx | ||
+ | |||
+ | call tmio_inof ; | ||
+ | |||
+ | ; ursprüngliche Interrupt-Routine Wiederherstellen | ||
+ | |||
+ | push ds | ||
+ | mov ds, tmio_segc ; | ||
+ | mov dx, tmio_offc ; | ||
+ | mov ax, 250ch | ||
+ | int 21h ; | ||
+ | pop ds | ||
+ | |||
+ | mov al, 48h ; default Interrupt-Vektor zurücksetzen | ||
+ | call tmio_sint | ||
+ | |||
+ | pop dx | ||
+ | pop bx | ||
+ | pop ax | ||
+ | ret | ||
+ | |||
+ | tmio_exit endp | ||
+ | |||
+ | |||
+ | ; | ||
+ | ; | ||
+ | ; Interrupt Vektor Register setzen ; | ||
+ | ; ; | ||
+ | ; Wird wenn möglich existierenden Eintrag ersetzen; | ||
+ | ; Diese Routine verwendet int 61h service 1ch um ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; ; | ||
+ | ; | ||
+ | ; al: Interrupt Nummer ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | |||
+ | tmio_sint proc near | ||
+ | |||
+ | push ax | ||
+ | push bx | ||
+ | push cx | ||
+ | push dx | ||
+ | |||
+ | ; prüfen ob Vector bereits gesetzt wird | ||
+ | |||
+ | push ax | ||
+ | mov cl, 3 ; erster nicht reservierter Eintrag | ||
+ | sint_srch: | ||
+ | inc cl | ||
+ | cmp cl, 11 ; max Tabelleneinträge +1 | ||
+ | je sint_seti ; | ||
+ | |||
+ | mov ax, 1c01h ; Tabelleneintrag auslesen | ||
+ | mov bh, cl ; Nummer des Tabelleneintrags | ||
+ | int 61h ; | ||
+ | |||
+ | ; prüfen, ob SIVR schon einmal eingerichtet wurde | ||
+ | |||
+ | cmp dx, INT_REG ; Stelle des Tabelleneintrags gefunden? | ||
+ | jne sint_srch ; | ||
+ | |||
+ | ; Stelle des Tabelleneintrags für die Interrupt-Vektor Nummer gefunden | ||
+ | |||
+ | sint_wral: | ||
+ | pop ax ; | ||
+ | mov bl, al ; Wert für an bl übergeben | ||
+ | mov bh, cl ; zu verwendender Tabelleneintrag | ||
+ | mov dx, INT_REG ; Addreses des SIVR | ||
+ | mov ax, 1c00h ; Eintragsnummer schreiben | ||
+ | int 61h | ||
+ | |||
+ | jmp sint_exit | ||
+ | |||
+ | ; zu verwendende leere Eintragstabelle finden | ||
+ | |||
+ | sint_seti: | ||
+ | mov cl, 3 ; erster zu prüfender Eintrag | ||
+ | sint_sr00: | ||
+ | inc cl | ||
+ | cmp cl, 11 ; max Tabelleneintrag +1 | ||
+ | je sint_bodg ; | ||
+ | |||
+ | mov ax, 1c01h ; Tabelleneintrag auslesen | ||
+ | mov bh, cl ; Nummer des Tabelleneintrags | ||
+ | int 61h ; | ||
+ | |||
+ | cmp dx, 0 ; leere Stelle in Tabelle gefunden? | ||
+ | jne sint_sr00 ; | ||
+ | jmp sint_wral ; | ||
+ | sint_bodg: | ||
+ | |||
+ | ; es wurde kein Tabelleneintrag gefunden um es falsch zu machen | ||
+ | |||
+ | pop ax | ||
+ | mov dx, INT_REG ; SIVR könnte beim Ausschalten | ||
+ | out dx, al ; beschädigt werden | ||
+ | sint_exit: | ||
+ | pop dx | ||
+ | pop cx | ||
+ | pop bx | ||
+ | pop ax | ||
+ | ret | ||
+ | |||
+ | tmio_sint endp | ||
+ | |||
+ | |||
+ | ; | ||
+ | ; | ||
+ | ; 80c50 initialisieren (auf dem int 14h service 0 basierend) ; | ||
+ | ; ; | ||
+ | ; | ||
+ | ; al: Port Parameter (wie int 14h) ; | ||
+ | ; Bits 7, 6, 5 BAUD RATE ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; ; | ||
+ | ; Bits 4, 3 PARITÄT ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; ; | ||
+ | ; | ||
+ | ; 0 1 bit ; | ||
+ | ; 1 2 bit ; | ||
+ | ; ; | ||
+ | ; Bits 1, 0 WORT LÄNGE ; | ||
+ | ; 1 0 7 bit ; | ||
+ | ; 1 1 8 bit ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | ; | ||
+ | |||
+ | tmio_inpt proc near | ||
+ | |||
+ | push ax ; | ||
+ | |||
+ | mov cl, 5 ; Zähler für Schieben einrichten | ||
+ | shr al, cl ; Zähler für Schieben setzen | ||
+ | jz init_spec ; | ||
+ | |||
+ | mov cl, al ; Zähler in CL holen | ||
+ | mov ch, 06h | ||
+ | shr cx, cl ; Teiler nach CX holen | ||
+ | jmp short init_norm | ||
+ | init_spec: | ||
+ | mov cx, 417h ; Teiler für 110 Baud | ||
+ | init_norm: | ||
+ | mov dx, tmio_base ; | ||
+ | add dx, LCR ; Port des Leitungskontrollregisters holen | ||
+ | mov al, 80h ; Zugriff auf die Register des Zählers | ||
+ | out dx, al | ||
+ | |||
+ | mov dx, tmio_base ; | ||
+ | mov al, cl ; unteren Teiler lesen | ||
+ | out dx, al ; Teiler schreiben | ||
+ | |||
+ | inc dx ; | ||
+ | mov al, ch ; oberen Teiler lesen | ||
+ | out dx, al ; Teiler schreiben | ||
+ | |||
+ | pop ax ; | ||
+ | |||
+ | and al, 1fh ; Bits 4 bis 0 holen | ||
+ | mov dx, tmio_base ; | ||
+ | add dx, LCR ; Port des Leitungskontrollregisters | ||
+ | out dx, al ; Daten schreiben | ||
+ | |||
+ | ret | ||
+ | |||
+ | tmio_inpt endp | ||
+ | |||
+ | tmio_base dw 0 ; | ||
+ | tmio_offc dw 0 ; | ||
+ | tmio_segc dw 0 ; | ||
+ | |||
+ | code ends | ||
+ | end | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
Zeile 104: | Zeile 918: | ||
Der IBM PC und viele andere Kompatible haben unidirektionale Centronics Parallel-Ports. Um eine kostengünstige aber nützliche Schnittstelle zu ermöglichen wurde entschieden, | Der IBM PC und viele andere Kompatible haben unidirektionale Centronics Parallel-Ports. Um eine kostengünstige aber nützliche Schnittstelle zu ermöglichen wurde entschieden, | ||
- | Das BIOS für die Dateiübertragung sollte unter den folgenden Erwägungen verwendet werden (siehe Abschnitt 3.3.1):\\ | + | Das BIOS für die Dateiübertragung sollte unter den folgenden Erwägungen verwendet werden (siehe Abschnitt |
* Vor dem Senden oder Empfangen sollten die Ports geöffnet werden. | * Vor dem Senden oder Empfangen sollten die Ports geöffnet werden. | ||
* Das Senden eines Blocks setzt voraus, dass die andere Seite einen Block emfängt und umgekehrt. | * Das Senden eines Blocks setzt voraus, dass die andere Seite einen Block emfängt und umgekehrt. | ||
Zeile 117: | Zeile 931: | ||
| | ||
+ | |||
2 Daten vom PC | 2 Daten vom PC | ||
3 Takt vom PC | 3 Takt vom PC | ||
Zeile 141: | Zeile 955: | ||
| | ||
- | 64KB | + | 64KB 27C512 verwenden |
| | ||
hardware/doku/techrefguide/abschnitt4.1190559806.txt.gz · Zuletzt geändert: 16/02/2024 17:02 (Externe Bearbeitung)