PofoWiki

Die ultimative Informationsquelle zum ATARI Portfolio

Benutzer-Werkzeuge

Webseiten-Werkzeuge


hardware:doku:techrefguide:abschnitt4

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
hardware:doku:techrefguide:abschnitt4 [23/09/2010 21:09]
uxt ergänzt
hardware:doku:techrefguide:abschnitt4 [23/09/2010 00:09] (aktuell)
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 450: Zeile 451:
 </​code>​ </​code>​
 \\ \\
-FIXME Quellcode von TMIO.ASM ​einfügen+**TMIO.ASM**\\ 
-\\+ 
 +<code asm> 
 + 
 +name tmio 
 + 
 +;​*******************************************************;​ 
 +;​ tmio ;​ 
 +; Dieses Modul ist die Schnittstelle zum ; 
 +; seriellen Port ;​ 
 +; ; 
 +; Die Interrupt-Routine setzt voraus,​dass ;​ 
 +; 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/​keine Parität wird vorausgesetzt ;​ 
 +; 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:​ word 
 + 
 +include tm.inc 
 + 
 +code segment byte public 
 + assume cs:​code,​ ds:code 
 + 
 +;​*******************************************************;​ 
 +;​ tmio_char ;​ 
 +; Sendet ein Zeichen zum seriellen Port ; 
 +; ; 
 +;​ Parameter:​ ;​ 
 +; al: zu sendendes ASCII Zeichen ; 
 +;​ Rückgabe:​ ;​ 
 +;​ Keine ;​ 
 +;​ Zerstört:​ ;​ 
 +;​ Nichts ;​ 
 +;​*******************************************************;​ 
 + 
 +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 ;​ Schleife wenn nicht 
 + 
 + 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 
 + 
 +;​*******************************************************;​ 
 +;​ tmio_init ;​ 
 +; Führt Initialisierung des seriellen Ports durch ; 
 +; ; 
 +; Port wird auf 1200 Baud, 8 bits, keine Parität ;​ 
 +;​ initialisiert. ;​ 
 +; DTR wird auf highgesetzt: ​ immer bereit ; 
 +;​ Interrupt-Register im Port-Setup ist INT_REG ; 
 +; ; 
 +;​ Parameter:​ ;​ 
 +;​ Keine ;​ 
 +;​ Rückgabe:​ ;​ 
 +;​ Keine ;​ 
 +;​ Zerstört:​ ;​ 
 +;​ Nichts ;​ 
 +;​*******************************************************;​ 
 + 
 +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:​[SER_BASE] ;​ Basis von Com1 ermitteln 
 + pop ds ;​ ds auf Lokal zurücksetzen 
 + mov tmio_base,​ di ; Basis-Addresse speichern 
 + 
 + call tmio_inof ;​ serielle Interrupts unterbinden 
 + 
 + mov al, PORT_DEFAULT ;​ Port wie im Header konfigurieren 
 + call tmio_inpt ;​ 80c50 konfigurieren 
 + 
 +; 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 ;​ seriellen Interrupt konfigurieren 
 + 
 +; 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 ;​ serielle Interrupts aktivieren 
 + 
 + mov dx, di ; Eingangspuffer des 82C50 löschen 
 + in al, dx 
 + 
 + pop di 
 + pop dx 
 + pop si 
 + pop ax 
 + ret 
 + 
 +tmio_init endp 
 + 
 + 
 +;​*******************************************************;​ 
 +;​ tmio_inon ;​ 
 +; Aktiviert die seriellen Interrupts ;​ 
 +; ; 
 +;​ Parameter:​ ;​ 
 +;​ Keine ;​ 
 +;​ Rückgabe:​ ;​ 
 +;​ Keine ;​ 
 +;​ Zerstört:​ ;​ 
 +; al, dx ; 
 +; ; 
 +;​*******************************************************;​ 
 + 
 +tmio_inon proc near 
 +  
 + mov dx, IER ; Register der Interrupt Aktivierung 
 + add dx, cs:​tmio_base 
 + mov al, INT_ON ; Interrupt aktiviert 
 + out dx, al 
 + 
 + ret 
 + 
 +tmio_inon endp 
 + 
 +;​*******************************************************;​ 
 +;​ tmio_inof ;​ 
 +; serielle Interrupts unterbinden ;​ 
 +; ; 
 +;​ Parameter:​ ;​ 
 +;​ Keine ;​ 
 +;​ Rückgabe:​ ;​ 
 +;​ Keine ;​ 
 +;​ Zerstört:​ ;​ 
 +; al, dx ; 
 +; ; 
 +;​*******************************************************;​ 
 + 
 +tmio_inof proc near 
 +  
 + mov dx, IER ; Register der Interrupt Aktivierung 
 + add dx, cs:​tmio_base 
 + mov al, INT_OFF ; Interrupts unterbinden 
 + out dx, al 
 + 
 + ret 
 + 
 +tmio_inof endp 
 + 
 + 
 +;​*******************************************************;​ 
 +;​ tmio_intc ;​ 
 +; Service des seriellen Lese Interrupts ;​ 
 +; ; 
 +; Wird bei vollem Eingangs Register aufgerufen ;​ 
 +; Paltziert Zeichen in Puffer und kehrt zurück ; 
 +; ; 
 +;​ Parameter:​ ;​ 
 +;​ Keine ;​ 
 +;​ Rückgabe:​ ;​ 
 +;​ Keine ;​ 
 +;​ Zerstört:​ ;​ 
 +;​ Nichts ;​ 
 +;​*******************************************************;​ 
 + 
 +tmio_intc proc near 
 + 
 + push ax 
 + push dx 
 + push di 
 + 
 + mov dx, RBR ; Adresse des Receiver-Puffers 
 + add dx, cs:​tmio_base 
 + in al, dx ; empfangenes Zeichen in al schreiben 
 + 
 + and al, STRP_TOP ;​ oberstes Bit löschen 
 + 
 + mov di, cs:​tmdp_bptr ;​ Zeichen an oberste Stelle 
 + mov cs:​[di],​ al ; des Puffers platzieren 
 + inc cs:​tmdp_bptr ;​ Puffer-Zeiger erhöhen 
 + 
 +; 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 
 + 
 + 
 +;​*******************************************************;​ 
 +;​ tmio_exit ;​ 
 +;​ Gewährleistet den sicheren Ausstieg ;​ 
 +; aus dem Terminal-Emulator ;​ 
 +; ; 
 +;​ Parameter:​ ;​ 
 +;​ Keine ;​ 
 +;​ Rückgabe:​ ;​ 
 +;​ Keine ;​ 
 +;​ Zerstört:​ ;​ 
 +;​ Nichts ;​ 
 +;​*******************************************************;​ 
 + 
 +tmio_exit proc near 
 + 
 + push ax 
 + push bx 
 + push dx 
 + 
 + call tmio_inof ;​ Interupts unterbinden 
 + 
 +; ursprüngliche Interrupt-Routine Wiederherstellen 
 + 
 + push ds 
 + mov ds, tmio_segc ;​ altes Segment zurücklesen 
 + mov dx, tmio_offc ;​ alten Offset zrücklesen 
 + mov ax, 250ch 
 + int 21h ;​ seriellen Interrupt umleiten 
 + pop ds 
 + 
 + mov al, 48h ; default Interrupt-Vektor zurücksetzen 
 + call tmio_sint 
 + 
 + pop dx 
 + pop bx 
 + pop ax 
 + ret 
 + 
 +tmio_exit endp 
 + 
 + 
 +;​*******************************************************;​ 
 +;​ tmio_sint ;​ 
 +; Interrupt Vektor Register setzen ; 
 +; ; 
 +; Wird wenn möglich existierenden Eintrag ersetzen; 
 +; Diese Routine verwendet int 61h service 1ch um ; 
 +;​ sicherzustellen,​ dass ein Ausschalten das ; 
 +;​ Vektor-Register des seriellen Ports nicht ; 
 +;​ verändert ;​ 
 +; ; 
 +;​ Parameter:​ ;​ 
 +; al: Interrupt Nummer ;​ 
 +;​ Rückgabe:​ ;​ 
 +;​ Keine ;​ 
 +;​ Zerstört:​ ;​ 
 +;​ nichts ;​ 
 +;​*******************************************************;​ 
 + 
 +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 ;​ wenn hierher verzweigt, dann kein Eintrag vorhanden 
 + 
 + mov ax, 1c01h ; Tabelleneintrag auslesen 
 + mov bh, cl ; Nummer des Tabelleneintrags 
 + int 61h ;​ Tabelleneintrag auslesen 
 + 
 +; prüfen, ob SIVR schon einmal eingerichtet wurde 
 + 
 + cmp dx, INT_REG ; Stelle des Tabelleneintrags gefunden? 
 + jne sint_srch ;​ wenn nein dann immer ersetzten 
 + 
 +; Stelle des Tabelleneintrags für die Interrupt-Vektor Nummer gefunden 
 + 
 +sint_wral:​ 
 + pop ax ;​ Interrupt Nummer zurückholen 
 + 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:​ ;​ leeren Tabelleneinrag finden 
 + mov cl, 3 ; erster zu prüfender Eintrag 
 +sint_sr00:​  
 + inc cl 
 + cmp cl, 11 ; max Tabelleneintrag +1 
 + je sint_bodg ;​ wenn hierher verzweigt, dann Eintrag nicht vorhanden 
 + 
 + mov ax, 1c01h ; Tabelleneintrag auslesen 
 + mov bh, cl ; Nummer des Tabelleneintrags 
 + int 61h ;​ Tabelleneintrag auslesen 
 + 
 + cmp dx, 0 ; leere Stelle in Tabelle gefunden? 
 + jne sint_sr00 ;​ wenn nein, dann immer ersetzen 
 + jmp sint_wral ;​ wenn ja, dann verzweigen und schreiben 
 +sint_bodg:​ ;​ kein Tabelleneintrag 
 + 
 +; 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 
 + 
 + 
 +;​*******************************************************;​ 
 +;​ tmio_inpt ;​ 
 +; 80c50 initialisieren (auf dem int 14h service 0 basierend) ;​ 
 +; ; 
 +;​ Parameter:​ ;​ 
 +; al: Port Parameter (wie int 14h) ; 
 +; Bits 7, 6, 5 BAUD RATE ; 
 +;      ​0 0 ​ 0 110 ; 
 +;      ​0 0 ​ 1 150 ; 
 +;      ​0 1 ​ 0 300 ; 
 +;      ​0 1 ​ 1 600 ; 
 +;      ​1 0 ​ 0 1200 ; 
 +;      ​1 0 ​ 1 2400 ; 
 +;      ​1 1 ​ 0 4800 ; 
 +;      ​1 1 ​ 1 9600 ; 
 +; ; 
 +; Bits 4, 3 PARITÄT ;​ 
 +;      ​x 0 keine ;​ 
 +;      ​0 1 ungerade ;​ 
 +;      ​1 1 gerade ;​ 
 +; ; 
 +;​ Bit 2 STOP BITS ; 
 +; 0 1 bit ; 
 +; 1 2 bit ; 
 +; ; 
 +; Bits 1, 0 WORT LÄNGE ; 
 +;      1 0 7 bit ; 
 +;      1 1 8 bit ; 
 +;​ Rückgabe:​ ;​ 
 +;​ keine ;​ 
 +;​ Zerstörtung:​ ;​ 
 +;​ keine ;​ 
 +;​*******************************************************;​ 
 + 
 +tmio_inpt proc near 
 + 
 + push ax ;​ Parameter sichern 
 + 
 + mov cl, 5 ; Zähler für Schieben einrichten 
 + shr al, cl ; Zähler für Schieben setzen 
 + jz init_spec ;​ Spezialfall 110 Baud 
 + 
 + 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 ;​ Basis Addresse 
 + add dx, LCR ; Port des Leitungskontrollregisters holen 
 + mov al, 80h ; Zugriff auf die Register des Zählers 
 + out dx, al 
 + 
 + mov dx, tmio_base ;​ Latch des unteren Teilers 
 + mov al, cl ; unteren Teiler lesen 
 + out dx, al ; Teiler schreiben 
 + 
 + inc dx ;​ Latch des oberen Teilers 
 + mov al, ch ; oberen Teiler lesen 
 + out dx, al ; Teiler schreiben 
 + 
 + pop ax ;​ Parameter wiederherstellen 
 + 
 + and al, 1fh ; Bits 4 bis 0 holen 
 + mov dx, tmio_base ;​ Basis Addresse 
 + add dx, LCR ; Port des Leitungskontrollregisters 
 + out dx, al ; Daten schreiben 
 + 
 + ret 
 + 
 +tmio_inpt endp 
 + 
 +tmio_base dw 0 ;​ basis Addresse 
 +tmio_offc dw 0 ;​ Offset des alten int 0ch 
 +tmio_segc dw 0 ;​ Segment des alten int 0ch 
 + 
 +code ends 
 + end 
 + 
 +</​code>​\\
  
  
hardware/doku/techrefguide/abschnitt4.txt · Zuletzt geändert: 23/09/2010 00:09 (Externe Bearbeitung)