Inhaltsverzeichnis

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 10×4 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 3.3.1):

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.