====== ABSCHNITT 4: PERIPHERIE ======
===== 4.1 SERIELLE KOMMUNIKATION DES PORTFOLIO =====
==== 4.1.1 Hardware Spezifikation ====
Standard: EIA RS232C kompatibel
Leitungsspannungen: ±9V
Stromschleife: nicht unterstützt
Anschluss: 9 Pin D-Sub Stecker (AT-kompatibel)
Anschlussbelegung: Pin Name
1 CD Träger-Erkennung
2 RD Empfangsdaten
3 TD Sendedaten
4 DTR Datenterminal bereit
5 GND Masse
6 DSR Datensetzen bereit
7 RTS Sendeaufforderung
8 CTS Sendebereit
Schnittstellen-IC: 82C50A
Basisadresse des 82C50A: an Speicheradresse 400H gespeichert.
Unterstützung von Interrupts: Ja (siehe unten)
Teilertakt: 1.8432 MHz
typische Stromentnahme: 10 mA
maximale Stromentnahme: 15 mA
==== 4.1.2 I/O Register ====
Da der Portfolio und der IBM PC/AT die gleichen Schnittstellen verwenden (bis auf das das Interrupt handling), haben die I/O Register auch die selbe Funktion. Die Basisadresse für die serielle Schnittstelle ist unter der Speicheradresse 40:0H des BIOS Datenbereichs abgelegt. Wenn der Wert an dieser Speicheradresse XXXXH ist, dann sind die I/O Register folgendermaßen:\\
I/O Adresse Register des 82C50A
XXXX+0 R RBR Register des Empfängerpuffers
W TBR Register des Senderpuffers
XXXX+1 R/W IER Interrupt enable Register
XXXX+2 R/W IIR Interrupt Identifizierungsregister
XXXX+3 R/W LCR Register der Leitungssteuerung
XXXX+4 R/W MCR Modem Steuerregister
XXXX+5 R/W LSR Register des Leitungsstatus
XXXX+6 R/W MSR Modem Statusregister
XXXX+7 R/W SCR Scratch Register
==== 4.1.3 Unterstützung von Interrupts ====
Da der Portfolio keinen 8259-kompatiblen Interrupt-Controller beinhaltet werden Interrupts anders gehandhabt als bei dem IBM-PC/AT.\\
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.\\
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.\\
==== 4.1.4 Weitere nützliche Informationen ====
Um festzustellen ob eine serielle Schnittstelle angeschlossen, ist empfiehlt es sich, den BIOS Int 11H (Ausstattungsliste ausgeben) zu verwenden.\\
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 "Standby", wird der Stromverbrauch enorm gesteigert.\\
Um SIVR einzustellen ist die Verwendung des Interrupt 61H, Fn 1CH zu empfehlen:\\
AH=1CH
AL=0 ;I/O Adresse bestimmen
BH=5 ;I/O Tabelleneintrag 5
BL=zu schreibendes Byte
DX=I/O Adresse
Die Verwendung dieser Funktion stellt sicher, dass SIVR immer richtig eingestellt ist (es sei denn, der Tabelleneintrag 5 wird für eine andere Adresse wiederverwendet).\\
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.\\
==== 4.1.5 Verwendung des seriellen Ports: Beispielprogramm TMTM.COM ====
Der folgende Abschnitt enthält das Listing für ein Interrupt-gesteuertes Terminal-Programm. Dieses Programm zeigt wie der serielle Port in einem Anwendungsprogramm benutzt werden kann. Die Routinen des seriellen Ports (TMIO.ASM) enthalten Kommentare die zeigen wie das Gleiche auf einem IBM PC durchgeführt werden kann. Dies wird Anwendern die mit dem IBM PC vertraut sind zeigen, wie bereits existierende Software modifiziert werden muss.
Das Programm besteht aus mehreren Dateien:\\
TM.INC Equates
TMTM.ASM Hauptroutine
TMKY.ASM Tastatur-Routinen
TMDP.ASM Bildschirm-Routinen
TMIO.ASM Routinen des seriellen Ports
TMIO.ASM wird für diejenigen die Software für den seriellen Port entwickeln von größtem Interesse sein. Die anderen Dateien werden der Vollständigkeit halber aufgeführt.TMTM.ASM sollte als erstes Modul eingelinkt werden um TMTM.COM zu erzeugen.\\
Das Programm wird den seriellen Port auf 1200 baud, 8 Datenbits, 1 Stoppbit und keine Parität einstellen. Das oberste Datenbit wird gelöscht.\\
Alt_Q kann verwendet werden um das Programm zu verlassen.\\
\\
\\
**TM.INC**\\
;*******************************************************;
; tm ;
; Include-Datei für Demo Terminal-Emulator ;
;*******************************************************;
; Definitionen für den Zugriff auf den 82C50 des seriellen Ports
SER_BASE equ 400h ; serielle Basis-Adresse im ROM
; Offsets von der Basis-Adresse der Kontroll-Register des 82C50
RBR equ 0h ; Register des Receiver-Puffers
THR equ 0h ; Hold-Register des Transmitters
IER equ 1h ; Interrupt-Enable Register
IIR equ 2h ; Interrupt-Identifikations-Register
LCR equ 3h ; Leitungs-Kontroll-Register
MCR equ 4h ; Modem-Kontroll-Register
LSR equ 5h ; Leitungs-Status-Register
MSR equ 6h ; Modem Status-Register
; Interrupt Controller
INT_REG equ 807fh ; Adresse des seriellen Vector-Registers (SIVR)
INT_ON equ 01h ; Interrupt bei ankommendem Zeichen
INT_OFF equ 00h ; alle seriellen Interrupts unterbinden
INT_NUM equ 0ch ; Interruptnummer für seriellen Port
; Kontroll-Bytes
DTR equ 01h ; Bit in MCR für DTR
RTS equ 02h ; Bit in MCR für RTS
THRE_MASK equ 20h ; Bit in LSR für Transmitter bereit
; Speicherzuweisungsblöcke
BUF_LEN equ 100h ; Länge des seriellen Eingangspuffers
STK_LEN equ 200h ; Länge des Programm-Stapels
; diverse Definitionen
CR equ 0dh ; Zeichen für Wagenrücklauf
LF equ 0ah ; Zeichen für Zeilenvorschub
PORT_DEFAULT equ 83h ; standard-Werte des seriellen Ports
STRP_TOP equ 7fh ; oberstes Bit löschen
\\
\\
**TMTM.ASM**\\
name tmtm
;***************************************************************;
; tmtm_main ;
; Terminal-Emulator für Pocket PCs Seriellen Port ;
; ;
; 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 ;
; erscheinen tmtm_main ist der Einstiegspunkt ;
; ;
;***************************************************************;
extrn tmio_inon: near
extrn tmio_init: near
extrn tmky_gtky: near
extrn tmio_char: near
extrn tmio_intc: near
extrn tmio_offc: word
extrn tmio_segc: word
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, endseg
assume cs:pgroup, ds:pgroup
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:last_byte + STK_LEN + 0fh
mov cx, 4
shr bx, cl ; durch 10h teilen; bx enthält Paragraphen
int 21h ; durchführen
jnc tmtm_mmok ; Sprung wenn Modifikation in Ordnung
; Modifikation der Speicherzuweisung fehlgeschlagen: Meldung ausgeben und beenden.
mov ah, 9h ; Meldung ausgeben
mov dx, offset tmtm_fail ; Zuweisung fehlgeschlagen
int 21h
mov ax, 4c00h ; Programm beenden
int 21h
; Speichermodifikation erfolgreich: Start-Up fortführen
tmtm_mmok:
; Stapel in zugewiesenem Bereich einrichten
mov sp, offset pgroup:last_byte + STK_LEN
; 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, bx ; Offset speichern
mov tmio_segc, es ; Segment speichern
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 ; Terminal-Emulator initialisieren
call tmio_inon ; serielle Interrupts aktivieren
; Hauptroutine des Emulators: Programmaustieg ist durch tmky_gtky
main_next:
call tmky_gtky ; ASCII-Zeichen der Tastatur in al
call tmio_char ; zum sereillen Port senden
jmp main_next
tmtm_main endp
; Tabelle der Meldungen
tmtm_fail db 'Speicherzuweisung fehlgeschlagen', CR, LF, '$'
tmtm_strt db 'DIP PPC Terminal-Emulator Demo-Programm', CR, LF, '$'
code ends
; endseg ist ein Dummy-Segment das am Ende des Terminal-Emulators erscheint
endseg segment byte public
last_byte: ;Programmende
endseg ends
end tmtm_main
\\
\\
**TMKY.ASM**\\
name tmky
;*******************************************************;
; 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: near
extrn tmio_exit: near
include tm.inc
code segment byte public
assume cs:code, ds:code
;*******************************************************;
; tmky_gtky ;
; Terminal Tastatur Handler ;
; ;
; wartet und verarbeitet Tartendruck ;
; gibt ASCII-Zeichen in AL zurück ;
; ;
; ALT ruft Command Key auf ;
; ALT Q beendet Programm ;
; ;
; Parameter: ;
; Keine ;
; Rückkehr: ;
; al: ASCII Zeichen-Code ;
; Zerstört: ;
; nichts ;
;*******************************************************;
tmky_gtky proc near
gtky_wtky:
call tmdp_prbf ; prüfe und zeige Eingangspuffer an
mov ah, 1 ; prüfe Tasten-Status auf Tastendruck
int 16h ; bereit
jz gtky_wtky ; warte auf Taste (kein Ausschalten!)
mov ah, 0 ; Taste bereit, also aus dem
int 16h ; Tastaturpuffer holen
or al, al ; erweiterter Code?
jz gtky_test ; behandle erweiterte Codes als Sonder-Code
ret
;auf ALT-Codes prüfen
gtky_test:
cmp ah, 10h ; prüfe auf ALT Q
jne gtky_wtky ; Sprung wenn nicht ALT Q
call tmio_exit ; Verlassen des Terminal-Emulators vorbereiten
int 20h ; verlassen
tmky_gtky endp
code ends
end
\\
**TMDP.ASM**\\
name tmdp
;*******************************************************;
; tmdp ;
; Dieses Modul steuert die Bildschirmausgabe ;
; ;
;*******************************************************;
public tmdp_prbf
public tmdp_bptr
include tm.inc
code segment byte public
assume cs:code, ds:code
;*******************************************************;
; tmdp_prbf ;
; Inhalt des seriellen Eingangspuffer ausgeben ;
; ;
; Der Interrupt kann zusätzliche Zeichen in den ;
; Puffer platzieren, außer wenn der Puffer ;
; gerade modifiziert wird. ;
; ;
; Parameter: ;
; KEINE ;
; Rückgabe: ;
; KEINE ;
; Zerstört: ;
; NICHTS ;
; ;
;*******************************************************;
tmdp_prbf proc near
push ax
push dx
push si
prbf_next:
; sind wir am Anfang des seriellen Eingangspuffers?
cmp tmdp_bptr, offset tmdp_cbuf
jne prbf_char ; wenn nicht, Inhalt ausgeben
pop si
pop dx
pop ax
ret
; mindestens ein Zeichen muss ausgegeben werden
prbf_char:
mov di, offset tmdp_cbuf ; Start des Puffers
mov dl, [di] ; schreibe erstes Zeichen
mov ah, 2 ; in AH
int 21h ; Zeichen ausgeben
; seriellen Puffer nachschieben
; zuerst Interrupts unterbinden, um zu verhindern, dass neue Zeichen
; hinzugefügt werden wärend der Puffer modifiziert wird
cli ;Interrupts unterbinden
cld ;aufwärts
mov cx, tmdp_bptr ;Pufferende+1
dec cx ;letztes Zeichen in Puffer
sub cx, offset tmdp_cbuf ;Anzahl zu verschiebender Bytes in CX
mov si, offset tmdp_cbuf+1 ;Anfang der zu verschiebenden Zeichenkette
; 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 ;[ds:si] --> [es:di] CX mal
dec tmdp_bptr ;neues Pufferende
sti ;Interrupts wieder zulassen
; Puffer kann wieder Zeichen empfangen
jmp prbf_next ; Schleife für nächstes Zeichen
tmdp_prbf endp
; Pufferspeicher
tmdp_cbuf db BUF_LEN dup (00) ;serieller Eingangspuffer
tmdp_bptr dw offset tmdp_cbuf ;Zeiger auf Anfang des Eingangspuffers
code ends
end
\\
**TMIO.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
\\
===== 4.2 BESCHREIBUNG DES DATEIÜBERTRAGUNGSPROTOKOLLS DER INTELLIGENTEN PARALLELEN SCHNITTSTELLE =====
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, dass die parallele Centronics-Schnittstelle des Portfolio ein Senden zu und von dem IBM PC, wie zu Druckern möglich machen sollte. Dies wird durch den Einsatz eines seriellen Transferprotokolls erreicht. Statusleitungen auf dem IBM PC, die über das BIOS angesprochen werden können, werden auf dem PC als Eingänge benutzt. Portfolios paralleler Port ist voll bidirektional.\\
Das BIOS für die Dateiübertragung sollte unter den folgenden Erwägungen verwendet werden (siehe Abschnitt [[hardware:doku:techrefguide:abschnitt3#int_61h_-_erweiterte_bios_funktionen|3.3.1]]):\\
* 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.
* Ein geschieht ein Timeout wenn binnen 500ms keine Antwort erfolgt.
* Das Senden eines Blocks überträgt automatisch auch dessen Länge. Der Empfänger meldet einen Fehler wenn sein Puffer zu klein ist.
* Bei etwaigen Fehlern warten sie 500ms (um der anderen Seite einen Timeout zu ermöglichen) und versuchen sie das Senden/Empangen dann erneut.
* Ein Fehler auf der einen Seite verursacht normalerweise auch einen Fehler auf der anderen, somit sollte die Block-Reihenfolge erhalten bleiben.
* Mit jedem Block wird auch eine Prüfsumme übertragen um eine einfache einfache Fehlerprüfung zur Verfügung zu stellen.
* Nach dem Ende einer Übertagung sollten die Ports wieder geschlossen werden.\\
Für die Herstellung eines Kabels für die intelligente parallele Übertragung ist die Pinbelegung wie folgt:\\
Pin Signal
2 Daten vom PC
3 Takt vom PC
12 Takt vom Portfolio
13 Daten vom Portfolio
18 Masse
===== 4.3 IBM PC KARTENLAUFWERK =====
Das IBM PC Kartenlaufwerk besteht aus einer 8-Bit Steckkarte für den Erweiterungsbus des IBM PC und einem kleinen Endgehäuse das einen Speicherkartenschacht enthält. Das Endgehäuse wird durch ein flexibles Kabel mit der Steckkarte verbunden. Eine Aktivitätsleuchtdiode zeigt an ob ein Zugriff auf die Speicherkarte stattfindet.\\
Die Erweiterungssteckkarte kann in einem IBMPC/XT oder PC/AT kompatiblen Rechner benutzt werden. Durch das Starten der entsprechenden Gerätetreibersoftware kann der PC auf eine Speicherkarte in gleicher Weise zugreifen wie auf eine normalle Diskette.\\
Die Karte verwendet einen Block von vier I/O-Adressen. Diese befinden sich an einer Startadresse die durch optionale Verbindungen auf der Erweiterungskarte angezeigt wird. Wenn diese abweichend von der ursprünglichen Einstellung verändert werden muss der Gerätetreiber über diese Veränderung in der CONFIG.SYS informiert werden.\\
===== 4.4 EPROM Programmier-Adapterkarten =====
Es sind PROM Prorgrammieradapter erhältlich die es ermöglichen PROM (OTP) -Speicherkarten mit Hilfe eines handelsüblichen PROM-Brenners zu programmieren. Die Adapter konvertieren die PROM-Karten auf die Auslegung von standard DIL PROMs. Verwenden sie Modell HPC-501 um 512KBit-Karten, und Modell HPC-502 um 1 MBit-Karten zu programmieren.\\
Für die Programmierung der PROM-Karten sollte der Brenner die Einstellungen für Fujitsu PROMS verwenden. Falls keine Voreinstellungen für Fujitsu PROMS zur Verfügung stehen können auch andere 12.5V PROM- Einstellungen verwendet werden. Die ideale Programmiereinstellung ist:\\
VPP 12.5V
64KB 27C512 verwenden (idealerweise Fujitsu CMOS)
128KB 27C1001 verwenden (idealerweise NEC CMOS)
Ist der ROM-Typ bestimmt so gehen sie folgendermaßen vor um die Kopie einer RAM-Karte zu erstellen:
i) Wählen sie eine PROM-Karte mit der selben Speichergröße wie die der RAM-Karte aus.\\
ii) Stecken sie den Adapter in die PROM-Fassung des Brenners. Achten sie auf die korrekte Position.\\
iii) Stecken sie die RAM-Karte in den Adapter und laden sie den Inhalt mit der entsprechenden Option in den Brenner.\\
iv) Stecken sie die PROM-Karte in den Adapter und programmieren sie wie mit jedem anderen PROM-Chip.\\
**Warnung**\\
1) VERSUCHEN SIE NICHT DIE RAM-KARTE ZU PROGRAMMIEREN.\\
2) Manche Brenner mögen es nicht, wenn die Spannungsversorgung ein- und ausgeschaltet wird, also entfernen sie die Karten bevor sie den Brenner ein- oder ausschalten.\\
\\