 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Ahnungslos

Anmeldungsdatum: 29.10.2007 Beiträge: 13 Wohnort: oben, bei Mutti
|
Verfasst am: 29.10.2007, 16:43 Titel: 16550 FIFO einschalten |
|
|
Hallo,
ich bastele an einer kleinen Steuerungssache.
Meine Hardware ist ein Motherboard das über RS232 Daten austauschen soll. Meine Software ist FREEDOS & FREEBASIC.
Leider verliere ich bei der RS232 Kommunikation ab und ein paar Bytes .
Ich benutze den Software-interrupt 14h, Funktion 0,1,2,3 um die RS232 Schnittstelle zu initialisieren, Zeichen zu senden, zu empfangen und den Status zu lesen. Da FRREBASIC anscheined keine INTERRUPTS so wie QBASIC kennt, muss ich die Interrupts mit einem kleinen Inline-Assembler-Programm aufrufen.
Unter Windows und QBASIC besteht das Problem nicht. Dort ist anscheinend der 16-Byte-FIFO des 16550 eingeschaltet so das während des Timerinterrupts (18.2 mal pro Sekunde) die Daten der RS232 Übertragung nicht verloren gehen. Außerdem benutzt QBASIC anscheinend auch die Hardware-Interrupts der COM-Ports...
Ich brauche jetzt mal etwas Hilfe in Form eines kleinen Basic-Programms, das den 16550-FIFO einschaltet.
Bitte laßt mich jetzt nicht hängen... _________________ In einem Club, der Leute wie mich aufnimmt, da möchte ich nicht Mitglied sein! |
|
Nach oben |
|
 |
PMedia
Anmeldungsdatum: 14.08.2006 Beiträge: 2847
|
Verfasst am: 30.10.2007, 00:29 Titel: |
|
|
mhm gut, da du FreeDOS nutzt ist das vlt. recht nutzlos, aber unter Windows erzielte OpenCOM immer gute Ergebnisse dazu
(vgl http://www.freebasic-portal.de/index.php?s=fbporticula&mode=show&id=178 )
Interrupts in FB sollten egtl auch nicht möglich sein, weiß ja nicht, irgendeiner bekommt das bestimmt hin (IRC-Leser wissen wieder mal mehr )
Praktisch ist man natürlich dran, wenn man den Quelltext der jeweiligen BIOS-Interupts hat... jaja, so eine Robotron-Systemdokumentation ist praktisch
Wenn du magst, such ich dir das raus, das sollte heute auf den IBM-PCs auch laufen, die sind ja ... merkwürdigerweise ... relativ Baugleich mit dieser Serie von Robotron-PCs...  |
|
Nach oben |
|
 |
Ahnungslos

Anmeldungsdatum: 29.10.2007 Beiträge: 13 Wohnort: oben, bei Mutti
|
Verfasst am: 30.10.2007, 13:03 Titel: OPEN COM Befehl |
|
|
Danke für die nette Antwort, aber leider leider, ich zitiere:
FreeBASIC-Befehlsreferenz OPEN COM
OPEN COM
Syntax: OPEN COM "COMn:Optionen, erweiterte_Optionen" [FOR Dateimodus] AS [#]Dateinummer
Typ: Anweisung
Kategorie: Hardware
Diese Version von OPEN steht derzeit nur in der Win32-Version von freeBASIC v0.15b
und deren Nachfolgern zur Verfügung!
Was ich jetzt brauche ist ein kleines FREEBASIC Programm-Fragment, das den 16550 mit INP und OUT Befehlen direkt so programmiert, das der seinen FIFO verwendet. _________________ In einem Club, der Leute wie mich aufnimmt, da möchte ich nicht Mitglied sein! |
|
Nach oben |
|
 |
PMedia
Anmeldungsdatum: 14.08.2006 Beiträge: 2847
|
Verfasst am: 30.10.2007, 18:14 Titel: |
|
|
ja, ich kenne die Referenz, ich war an der Umsetzung beteiligt...
Ich such grad noch |
|
Nach oben |
|
 |
HorstD
Anmeldungsdatum: 01.11.2007 Beiträge: 110
|
Verfasst am: 01.11.2007, 02:52 Titel: |
|
|
Code: |
'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
'³ ³
'³ PowerBASIC-Routinen zur Kommunikation mit den seriellen Schnittstellen. ³
'³ Copyright (c) 1994 by PowerBASIC, Inc. All Rights Reserved. ³
'³ Letzte nderung: 30. August 1995 ³
'³ ³
'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
'³ ³
'³ Enthaltene Routinen: ³
'³ ³
'³ Carrier - gibt den Status des Carrier-Anschlusses zurck ³
'³ CtsStatus - gibt den Status von CTS zurck ³
'³ DsrStatus - gibt den Status von DSR zurck ³
'³ DtrStatus - gibt den Status von DTR zurck ³
'³ GetComAddress - gibt die I/O-Adresse des angegeb. COM-Ports zurck ³
'³ SetComAddress - setzt die Adresse des angegebenen COM-Ports ³
'³ SetDtr - setzt den DTR Status ³
'³ SetFifoTrigger - setzt den FIFO Trigger ³
'³ ³
'³ LptReady - wird Wahr (-1) wenn der Drucker bereit ist ³
'³ LptStatus - gibt das Statusbyte einer par. Schnittstelle zurck ³
'³ GetLptAddress - gibt die Adresse einer par. Schnittst. zurck (BIOS) ³
'³ SetLptAddress - setzt die Adresse einer par. Schnittstelle (BIOS) ³
'³ SwapLpt1and2 - tauscht die Adressen von LPT1 und LPT2 (BIOS) ³
'³ ³
'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
$CPU 8086 'kompatibel mit allen 80x86-Systemen
$LIB ALL OFF 'PowerBASIC-Biblotheken abschalten,
'da es als UNIT kompiliert wird
$ERROR ALL OFF 'Fehlerbehandlung abschalten
$OPTIMIZE SIZE 'auf mglichst kleinen Code optimieren
$COMPILE UNIT 'als UNIT (.PBU) kompilieren
DEFINT A-Z 'alle Variablen als Integer definieren
'verhindert das Einbinden der
'mathematischen Bibliotheken (macht
'erzeugten Code kleiner)
'===========================================================================
' DtrStatus - gibt den Status der DTR-Leitung der angegebenen COM-Schnitt-
' stelle zurck
'
' port = COM-Schnittstelle (1-4)
'
FUNCTION DtrStatus(BYVAL port AS INTEGER) PUBLIC AS INTEGER
! push DS ; DS-Register sichern
! mov BX, port ; Schnittstellen-Nummer in BX ablegen
! shl BX, 1 ; Schnittst.-Nr. mit 2 multiplzieren
! add BX, &H3FE ; 3FEh dazuaddieren -> Adresse im
' BIOS-Datenbereich wo die Port-
' Adressen abgelegt sind
! xor DX, DX ; DX-Register lschen (=0)
! mov DS, DX ; DS-Register mit DX laden (DS=0)
! mov DX, DS: [BX] ; Port-Adresse von COMx in DX laden
! add DX, 4 ; Port-Adr. des Steuerregisters
' liegt um 4 Adressen hher als
' die Basisadresse
! in AL, DX ; Statusbyte in AX-Register laden
! and AX, 1 ; der DTR-Status ist im ersten Bit
! neg AX ; Wert negieren 0=low / -1=high
! mov FUNCTION, AX ; Ergebnis bergeben
! pop DS ; DS-Register wieder auf alten Wert
' setzen
END FUNCTION
'===========================================================================
' SetDtr - setzt den DTR-Status fr den angegbenen COM-Port
' Wenn man den Status auf Null setzt, legen einige Modemtypen auf.
' Soll mit einem Modem kommuniziert werden, muá DTR eingeschaltet
' werden.
'
' port = COM-Schnittstelle (1-4)
' state = zu setzender Status
'
SUB SetDtr(BYVAL Port AS INTEGER, BYVAL State AS INTEGER) PUBLIC
! push DS ; DS-Register sichern
! mov BX, port ; Schnittstellen-Nummer in BX ablegen
! shl BX, 1 ; Schnittst.-Nr. mit 2 multiplzieren
! add BX, &H3FE ; 3FEh dazuaddieren -> Adresse im
' BIOS-Datenbereich wo die Port-
' Adressen abgelegt sind
! xor DX, DX ; DX-Register lschen (=0)
! mov DS, DX ; DS-Register mit DX laden (DS=0)
! mov DX, DS: [BX] ; Port-Adresse von COMx in DX laden
! add DX, 4 ; Port-Adr. des Steuerregisters
' liegt um 4 Adressen hher als
' die Basisadresse
! mov AX, State ; gewnschten DTR-Status in AX
! or AX, AX ; soll DTR gesetzt werden ?
! in AL, DX ; DTR-Status lesen (verndert Flags
' nicht)
! jnz RaiseDTR ; springe, wenn es gesetzt wird
! and AL, &H0FE ; aha, es soll gelscht werden
SetState:
! out DX, AL ; neuen Status setzen
ExitSetDTR:
! pop DS ; DS-Register wieder auf alten Wert
' setzen
EXIT SUB
RaiseDTR:
! or AL, 1 ; DTR-Bit setzen
! jmp Short SetState ; Sprung zum OUT-Befehl
END SUB
'===========================================================================
' CtsStatus - gibt den Status der CTS-Leitung zurck
'
' port = COM-Schnittstelle (1-4)
'
FUNCTION CtsStatus(BYVAL port AS INTEGER) PUBLIC AS INTEGER
! push DS ; DS-Register sichern
! mov BX, port ; Schnittstellen-Nummer in BX ablegen
! shl BX, 1 ; Schnittst.-Nr. mit 2 multiplzieren
! add BX, &H3FE ; 3FEh dazuaddieren -> Adresse im
' BIOS-Datenbereich
! xor DX, DX ; DX-Register lschen (=0)
! mov DS, DX ; DS-Register mit DX laden (DS=0)
! mov DX, DS: [BX] ; Port-Adresse von COMx in DX laden
! add DX, 6 ; Port-Adr. des Statusregisters
' liegt um 4 Adressen hher als
' die Basisadresse
! in AL, DX ; Statusbyte in AX-Register laden
! mov CL, 4 ; der CTS-Status steht in Bit 5
! shr AX, CL ; Bit 5 in Positon 1 schieben
! and AX, 1 ; alle anderen Bits auf 0 setzen
! neg AX ; Wert negieren 0=low / -1=high
! mov FUNCTION, AX ; CTS-Status bergeben
! pop DS ; DS-Register wieder auf alten Wert
' setzen
END FUNCTION
'===========================================================================
' DsrStatus - gibt den Status der DSR-Leitung zurck
'
' port = COM-Schnittstelle (1-4)
'
FUNCTION DsrStatus(BYVAL port AS INTEGER) PUBLIC AS INTEGER
! push DS ; DS-Register sichern
! mov BX, port ; Schnittstellen-Nummer in BX ablegen
! shl BX, 1 ; Schnittst.-Nr. mit 2 multiplzieren
! add BX, &H3FE ; 3FEh dazuaddieren -> Adresse im
' BIOS-Datenbereich
! xor DX, DX ; DX-Register lschen (=0)
! mov DS, DX ; DS-Register mit DX laden (DS=0)
! mov DX, DS: [BX] ; Port-Adresse von COMx in DX laden
! add DX, 6 ; Port-Adr. des Statusregisters
' liegt um 6 Adressen hher als
' die Basisadresse
! in AL, DX ; Statusbyte in AX-Register laden
! mov CL, 5 ; der DSR-Status steht in Bit 6
! shr AX, CL ; Bit 6 in Positon 1 schieben
! and AX, 1 ; alle anderen Bits auf 0 setzen
! neg AX ; Wert negieren 0=low / -1=high
! mov FUNCTION, AX ; DSR-Status bergeben
! pop DS ; DS-Register wieder auf alten Wert
' setzen
END FUNCTION
'===========================================================================
' Carrier - gibt den Status der CD-Leitung zurck
'
' port = COM-Schnittstelle (1-4)
'
FUNCTION Carrier(BYVAL port AS INTEGER) PUBLIC AS INTEGER
! push DS ; DS-Register sichern
! mov BX, port ; Schnittstellen-Nummer in BX ablegen
! shl BX, 1 ; Schnittst.-Nr. mit 2 multiplzieren
! add BX, &H3FE ; 3FEh dazuaddieren -> Adresse im
' BIOS-Datenbereich
! xor DX, DX ; DX-Register lschen (=0)
! mov DS, DX ; DS-Register mit DX laden (DS=0)
! mov DX, DS: [BX] ; Port-Adresse von COMx in DX laden
! add DX, 6 ; Port-Adr. des Statusregisters
' liegt um 6 Adressen hher als
' die Basisadresse
! in AL, DX ; Statusbyte in AX-Register laden
! mov CL, 7 ; der CD-Status steht in Bit 8
! shr AX, CL ; Bit 8 in Positon 1 schieben
! and AX, 1 ; alle anderen Bits auf 0 setzen
! neg AX ; Wert negieren 0=low / -1=high
! mov FUNCTION, AX ; CD-Status bergeben
! pop DS ; DS-Register wieder auf alten Wert
' setzen
END FUNCTION
'===========================================================================
' GetComAddress - gibt die Basis-I/O-Addresse der angegebenen COM-Schnitt-
' stelle zurck
'
' port = COM-Schnittstelle (1-4)
'
FUNCTION GetComAddress(BYVAL port AS INTEGER) PUBLIC AS INTEGER
! push DS ; DS-Register sichern
! mov BX, port ; Schnittstellen-Nummer in BX ablegen
! shl BX, 1 ; Schnittst.-Nr. mit 2 multiplzieren
! add BX, &H3FE ; 3FEh dazuaddieren -> Adresse im
' BIOS-Datenbereich
! xor DX, DX ; DX-Register lschen (=0)
! mov DS, DX ; DS-Register mit DX laden (DS=0)
! mov DX, DS: [BX] ; Port-Adresse von COMx in DX laden
! mov FUNCTION, AX ; Adresse bergeben
! pop DS ; DS-Register wieder auf alten Wert
' setzen
ComAddress = address
END FUNCTION
'===========================================================================
' SetComAddress - setzt die Basis-I/O-Adresse der angegebenen COM-Schnitt-
' stelle auf den Wert der in adress angegeben wird.
' !! Achtung: Dies verndert nicht die Einstellung auf der
' Schnittstellenkarte !!
'
' port = COM-Schnittstelle (1-4)
' address = neue Address fr port
'
SUB SetComAddress(BYVAL port AS INTEGER, BYVAL address AS INTEGER) PUBLIC
! push DS ; DS-Register sichern
! mov BX, port ; Schnittstellen-Nummer in BX ablegen
! shl BX, 1 ; Schnittst.-Nr. mit 2 multiplzieren
! add BX, &H3FE ; 3FEh dazuaddieren -> Adresse im
' BIOS-Datenbereich
! xor DX, DX ; DX-Register lschen (=0)
! mov DS, DX ; DS-Register mit DX laden (DS=0)
! mov AX, address ; AX mit neuer Adresse laden
! mov DS:[BX], AX ; nue Adresse in BIOS-Tabelle ablegen
! pop DS ; DS-Register wieder auf alten Wert
' setzen
END SUB
'===========================================================================
' SetFifoTrigger - Setzt den FIFO-Trigger des 16550 UART. PowerBASIC benutzt
' 4 byte als Standard nach dem ffnen des COM-Ports.
' Andere Werte knnen auf sehr langsamen Rechneren
' notwendig werden, oder bei exzessiven Plattenzugriffen.
'
' port = COM-Schnittstelle (1-4)
' level = Trigger : 0, 1, 4, 8 oder 14 bytes bis Interrupt erzeugt wird.
'
SUB SetFifoTrigger(BYVAL port AS INTEGER, BYVAL level AS INTEGER) PUBLIC
SELECT CASE level
CASE 1 : level = &H1F ' 1 byte
CASE 4 : level = &H4F ' 4 bytes
CASE 8 : level = &H8F ' 8 bytes
CASE 14 : level = &HCF ' 14 bytes
CASE ELSE : level = &H00 ' kein FIFO-Puffer benutzen
END SELECT
! push DS ; DS-Register sichern
! mov BX, port ; Schnittstellen-Nummer in BX ablegen
! shl BX, 1 ; Schnittst.-Nr. mit 2 multiplzieren
! add BX, &H3FE ; 3FEh dazuaddieren -> Adresse im
' BIOS-Datenbereich
! xor DX, DX ; DX-Register lschen (=0)
! mov DS, DX ; DS-Register mit DX laden (DS=0)
! mov DX, DS: [BX] ; Port-Adresse von COMx in DX laden
! add DX, 2 ; Adresse des Interrupt-ID-Registers
! mov AL, level ; Triggerwert in AL laden
! out DX, AL ; ins Interrupt-ID-Reg. schreiben
! pop DS ; DS-Register wieder auf alten Wert
' setzen
END SUB
'===========================================================================
' LptReady - gibt den Druckerstatus zurck
'
' port = LPT-Schnittstelle (1-3)
'
FUNCTION LptReady(BYVAL port AS INTEGER) PUBLIC AS INTEGER
DIM status AS INTEGER
status = LptStatus(port)
FUNCTION = BIT( status, 7 ) = 1
END FUNCTION
'===========================================================================
' LptStatus - gibt den Status einer LPT-Schnittstelle zurck
'
' BIT(Status, 0) = Timeout (Zeitberlauf)
' BIT(Status, 3) = Ein-/Ausgabefehler (LPT-pin 15)
' BIT(Status, 4) = Drucker ist kommunikationsbreit (LPT-pin 13)
' BIT(Status, 5) = kein Papier mehr im Drucker (LPT-pin 12)
' BIT(Status, 6) = Drucker Online (LPT-pin 10)
' BIT(Status, 7) = Drucker beschftigt (busy) (LPT-pin 11)
'
' port = LPT-Schnittstelle (1-3)
'
FUNCTION LptStatus(BYVAL port AS INTEGER) PUBLIC AS INTEGER
! push DS ; DS-Register sichern
! xor AX, AX ; AX = 0
! mov DX, Port ; Portnummer in DX
! dec DX ; 0-basiert
! mov AH, 2 ; BIOS: Druckerstatus
! int &H17 ; BIOS aufrufen
! mov AL, AH ; Status in AL kopieren
! xor AH, AH ; AH lschen
! mov FUNCTION, AX ; Status zurckliefern
! pop DS ; DS-Register wieder auf alten Wert
' setzen
END FUNCTION
'===========================================================================
' GetLptAddress - gibt die I/O-Adresse eines LPT-Ports zurck
'
' port = LPT-Schnittstelle (1-3)
'
FUNCTION GetLptAddress(BYVAL port AS INTEGER) PUBLIC AS INTEGER
! push DS
! mov BX, port ; Portnummer in BX
! shl BX, 1 ; mit 2 multiplizieren
! add BX, &H406 ; 406h dazuaddieren
! xor DX, DX ; Segment BIOS-Daten (0000h)
! mov DS, DX ; lade DS mit Segment
! mov AX, DS: [BX] ; hole Portadresse
! mov FUNCTION, AX ; Adresse zurckgeben
! pop DS
END FUNCTION
'===========================================================================
' SetLptAddress - setzt die I/O-Adresse eines LPT-Ports in den BIOS-Daten
'
' port = LPT-Schnittstelle (1-3)
' address = neue Portadresse
'
SUB SetLptAddress(BYVAL port AS INTEGER, BYVAL address AS INTEGER) PUBLIC
! push DS
! mov BX, port ; Portnummer in BX
! shl BX, 1 ; mit 2 multiplizieren
! add BX, &H406 ; 406h dazuaddieren
! xor DX, DX ; Segment BIOS-Daten (0000h)
! mov DS, DX ; lade DS mit Segment
! mov AX, address ; neue Adresse in AX laden
! mov DS:[BX], AX ; Adresse in BIOS-Daten schreiben
! pop DS
END SUB
'===========================================================================
' SwapLpt1and2 - Tauscht die Adressen von LPT1 und LPT2. Damit kann man mit
' LPRINT auch auf die LPT2 drucken.
'
' ** ACHTUNG ** Vergessen Sie nicht, diesen Tausch vor dem Beenden Ihres
' Programms wieder rckgngig zu machen. Sonst arbeiten
' andere Programme eventuell nicht mehr richtig. Ein weiterer
' Aufruf von SwapLpt1and2() macht dies wieder rckgngig.
'
SUB SwapLpt1and2() PUBLIC
DIM Lpt1 AS INTEGER
DIM Lpt2 AS INTEGER
Lpt1 = GetLptAddress( 1 )
Lpt2 = GetLptAddress( 2 )
SWAP Lpt1, Lpt2
SetLptAddress 1, Lpt1
SetLptAddress 2, Lpt2
END SUB
|
Editiert durch Moderator: Code-Tags zur besseren Übersicht hinzugefügt. (A.K.) |
|
Nach oben |
|
 |
PMedia
Anmeldungsdatum: 14.08.2006 Beiträge: 2847
|
Verfasst am: 01.11.2007, 15:16 Titel: |
|
|
OMG
Moderatoren, das ganze erstmal "lesbar" machen
(Oder HorstD macht das selbst, bei seinem letzten Beitrag Bearbeiten anklicken, und vor dem Quelltext [ code ] (ohne Leerzeichen) und nach dem Quelltext [/code ] (erneut ohne Leerzeichen) anfügen)
Wie man schon oben sieht, es wird PowerBasic vorausgesetzt, alles was ich sage kann somit vollständig falsch sein, da ich kein PowerBasicler bin
... und soweit ich das seh, sind das nur erweiterte Funktionen, PowerBASIC sollte auch die Schnittstelle mit Open Com öffnen...
mhm, ich habe nur ein Interupthandbuch gefunden, int14h:00h macht das was du tun willst, aber die Frage bleibt, wie man Interrupts mit FB aufruft...
wenn, dann nur über Inline Asm, aber ich lass das mal jetzt ungetestet im Raum stehen:
Code: |
ASM
mov AH, &h00 'Funktion 0 von Interupt 14
mov AL, &b11100011 '9600 BAUD, keine Parität, 1 Stoppbit, 8 Datenbits
mov DX, &h00 'COM1
int &h14 'Den Interrupt ausführen
'fraglich ob FBC den Befehl unter (Free)DOS unterstützt
END ASM
|
Hier der Auszug der Beschreibung für Interrupt 14.0:
Code: |
7.22. EIN- UND AUSGABE UEBER EINEN
SERIELLEN ANSCHLUSS INT14
----------------------------------------------------------------
7.22.1. INITSIALISIERUNG SERIELLER ANSCHLUSS INT14:00h
----------------------------------------------------------------
Funktion:
Durch diese Funktion kann ein Kabel (COM-Port) des Adapters
fuer serielle Kommunikation initialisiert werden. Es werden die
Uebertragungsrate, Paritaet, Wortlaenge und die Anzahl der
Stopp-Bits festgelegt.
Aufruf:
------------------------------------------------------------
| Register | Inhalt/Bedeutung |
|----------+-----------------------------------------------|
| AH | 00h |
| AL | Parameter Initialisierung |
| DX | Kanalnummer |
------------------------------------------------------------
Der Initialisierungsparameter hat folgenden Inhalt:
Bit Bit
7 6 5 4 3 2 1 0
| | | | | | | |
| | | | | | +-----+-- Bits/Zeichen
| | | | | | 10 - 7 Bits
| | | | | | 11 - 8 Bits
| | | | | |
| | | | | +-- Anzahl Stopp-Bits
| | | | | 0 - 1 Stopp-Bit
| | | | | 1 - 2 Stopp-Bits
| | | | |
| | | +-----+-- Paritaet
| | | 00 - ohne
| | | 01 - ungerade
| | | 10 - ohne
| | | 11 - gerade
| | |
+-----+-----+-- Geschwindigkeit
000 - 110 Baud 100 - 1200 Baud
001 - 150 Baud 101 - 2400 Baud
010 - 300 Baud 110 - 4800 Baud
011 - 600 Baud 111 - 9600 Baud
Mittels der Kanalnummer kann der Kanal eingestellt werden, ueber
welchen die Dateinein- und -ausgabe erfolgen soll
Es gilt:
Kanalnummer:
00h = COM1: Ein- und Ausgabe ueber den Adapter fuer
serielle Kommunikation - Kanal A (V.24)
01h = COM2: Ein- und Ausgabe ueber den Adapter fuer
serielle Kommunikation - Kanal B (IFSS)
Rueckkehr:
------------------------------------------------------------
| Reg./Flag | Inhalt/Bedeutung |
|-----------+----------------------------------------------|
| AH | Leitungsstatus |
| AL | Modemstatus |
------------------------------------------------------------
(Erlaeuterungen zum Status siehe Kapitel 7.22.4)
|
(Quelle: robotron Programmtechnische Beschreibung - Anleitung für den Systemprogrammierer Arbeitsplatzcomputer A 7150 Betriebssystem DCP 1700 - C 3013-0000-0 M 3030)
Soweit ich weiß handelt es sich bei besagten Modell um einen Klon des IBM-PCs, drum sollten diese Angaben stimmen.
Btw, interessant ist, dass in der Kopfzeile dieser beiden Seiten, die ich auszugsweise präsentiert habe, "*** BOIS-Interrupts ***" steht
//edit zum zigsten Mal, diesmal mit Contentänderung:
Ich hab grad über die Forensuche einen alten Beitrag gefunden, wo ich dieses Buch schonmal erwähnt habe... es kann hier als PDF heruntergeladen werden - wozu hab ich das egtl jetzt abgetippt??? |
|
Nach oben |
|
 |
Ahnungslos

Anmeldungsdatum: 29.10.2007 Beiträge: 13 Wohnort: oben, bei Mutti
|
Verfasst am: 01.11.2007, 18:02 Titel: 16550 FIFO einschalten |
|
|
Hallo,
erst mal ein fettes Dankeschön für eure Antworten.
Ich habe jetzt folgendes:
Code: |
'**************************************************************
' Routine um 16550 FIFO einzuschalten 01.11.2007
' !!! Noch nicht getestet mit int14h !!!
'**************************************************************
Adr = &H3FE + Port * 2 'Port 1..4
DEF SEG = 0
Adr = 256 * PEEK(Adr + 1) + PEEK(Adr) '=> 3F8 2F8 3E8 2E8
OUT Adr + 2, &HCF
' Adr + 2 => Adresse des Interrupt-ID-Registers
' &HCF => 14 Byte FIFO
'**************************************************************
|
Meine int14h Routinen sehen so aus:
Code: |
'****************************************************************************
FUNCTION Serial_Init(kom as UByte)
Dim Status as UByte
kom_ = kom
ASM
MOV AH,&H0 'Funktion 0
MOV AL,&HE3
MOV DL,[kom_]
MOV DH,0
DEC DX
INT &H14
MOV [Status],AH
MOV DX,&H3F8
MOV AL,[kom_]
CMP AL,1
JE com1_sel
MOV DX,&H2F8
com1_sel:
ADD DX,3
IN AL,DX
OR AL,&H80
out DX,AL 'out darf nicht in Groábuchstaben geschrieben sein!
'OUT Basisadr+3,128 OR INP(Basisadr+3)
'Steuerregister schaltet um auf Baudratenregister
'an Basisadresse + 0 und Basisadresse + 1
SUB DX,3
MOV AL,1
out DX,AL 'OUT Basisadr+0,1
'Baudratenregister jetzt auf 1 = 115200 Baud
ADD DX,3
IN AL,DX
AND AL,&H7F
out DX,AL 'OUT Basisadr+3,127 AND INP(Basisadr+3)
'Steuerregister schaltet um auf
'Daten und Interrupt-Maskenregister
'an Basisadresse + 0 und Basisadresse + 1
end ASM
Return Status
END FUNCTION
'****************************************************************************
|
Code: |
'****************************************************************************
FUNCTION Serial_Send(kom as UByte,Zeichen as UByte)
Dim Status as UByte
kom_ = kom
Zeichen_ = Zeichen
ASM
MOV AH,&H1 'Funktion 1
MOV AL,[Zeichen_]
MOV DL,[kom_]
MOV DH,0
DEC DX
INT &H14
MOV [Status],AH
end ASM
Return Status
END FUNCTION
'****************************************************************************
|
Code: |
'****************************************************************************
FUNCTION Serial_Receive(kom as UByte)
Dim Zeichen as UByte
kom_ = kom
ASM
MOV AH,&H2 'Funktion 2
MOV DL,[kom_]
MOV DH,0
DEC DX
INT &H14
MOV [Zeichen],AL
end ASM
Return Zeichen
END FUNCTION
'****************************************************************************
|
Code: |
'****************************************************************************
FUNCTION Serial_Receive_Status(kom as UByte)
Dim Status as UByte
kom_ = kom
ASM
MOV AH,&H3 'Funktion 3
MOV DL,[kom_]
MOV DH,0
DEC DX
INT &H14
AND AH,&H01 'Nur ob Zeichen empfangen!
MOV [Status],AH
end ASM
Return Status
END FUNCTION
'****************************************************************************
|
Wie gesagt, die int14h Routinen arbeiten (ab und zu ein bis 8 Byte verloren). Jetzt muss ich nur die 16550 FIFO-Routine testen... _________________ In einem Club, der Leute wie mich aufnimmt, da möchte ich nicht Mitglied sein! |
|
Nach oben |
|
 |
ytwinky

Anmeldungsdatum: 28.05.2005 Beiträge: 2624 Wohnort: Machteburch
|
Verfasst am: 01.11.2007, 18:29 Titel: |
|
|
Du solltest bei deinen 'Versuchen' diese Seite berücksichtigen:
http://www.freebasic.net/wiki/wikka.php?wakka=KeyPgAsm
btw: wenn du diese Seite nicht verstehst, solltest du imho die Finger davon lassen..
und noch btwer: Nein, ich übersetze das nicht.. _________________
v1ctor hat Folgendes geschrieben: | Yeah, i like INPUT$(n) as much as PRINT USING.. | ..also ungefähr so, wie ich GOTO.. |
|
Nach oben |
|
 |
Ahnungslos

Anmeldungsdatum: 29.10.2007 Beiträge: 13 Wohnort: oben, bei Mutti
|
Verfasst am: 01.11.2007, 19:12 Titel: Antwort von ytwinky |
|
|
Sorry,
aber bei dieser Antwort weiss ich nicht so recht was gemeint ist.
By The Way:
Der Link führt auf eine Seite die sich mit Freebasic & Assembler beschäftigt.
In My Humble Opinion:
Die Fragestellung dieses Threads ist aber 16550-FIFO einschalten.
Alles andere wurde schon gesagt (geschrieben)  _________________ In einem Club, der Leute wie mich aufnimmt, da möchte ich nicht Mitglied sein! |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 01.11.2007, 19:31 Titel: |
|
|
ytwinky will vermutlich darauf hinaus, dass die zusammengestellten Code-Stücke so gut wie nur ASM verwenden, und er ist sich vielleicht nicht ganz sicher, ob du weißt, was du da tust.  _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
HorstD
Anmeldungsdatum: 01.11.2007 Beiträge: 110
|
Verfasst am: 01.11.2007, 20:29 Titel: |
|
|
Hallo PMedia,
selbstverständich muss bei PowerBASIC die Schnittstelle erst mit open com geöffnet werden.
Die Frage war ja wie der FIFO eingeschaltet wird. Da Ahnungslos ja offentsichlich Assemblerkenntnisse hat, dürfte es für ihn kein Problem sein den PowerBASIC-Code anzupassen.
Übrigens das Ausrufezeichen (!)ist bei PB ein Ersatz für ASM.
Code: |
'===========================================================================
' SetFifoTrigger - Setzt den FIFO-Trigger des 16550 UART. PowerBASIC benutzt
' 4 byte als Standard nach dem ffnen des COM-Ports.
' Andere Werte knnen auf sehr langsamen Rechneren
' notwendig werden, oder bei exzessiven Plattenzugriffen.
'
' port = COM-Schnittstelle (1-4)
' level = Trigger : 0, 1, 4, 8 oder 14 bytes bis Interrupt erzeugt wird.
'
SUB SetFifoTrigger(BYVAL port AS INTEGER, BYVAL level AS INTEGER) PUBLIC
SELECT CASE level
CASE 1 : level = &H1F ' 1 byte
CASE 4 : level = &H4F ' 4 bytes
CASE 8 : level = &H8F ' 8 bytes
CASE 14 : level = &HCF ' 14 bytes
CASE ELSE : level = &H00 ' kein FIFO-Puffer benutzen
END SELECT
! push DS ; DS-Register sichern
! mov BX, port ; Schnittstellen-Nummer in BX ablegen
! shl BX, 1 ; Schnittst.-Nr. mit 2 multiplzieren
! add BX, &H3FE ; 3FEh dazuaddieren -> Adresse im
' BIOS-Datenbereich
! xor DX, DX ; DX-Register lschen (=0)
! mov DS, DX ; DS-Register mit DX laden (DS=0)
! mov DX, DS: [BX] ; Port-Adresse von COMx in DX laden
! add DX, 2 ; Adresse des Interrupt-ID-Registers
! mov AL, level ; Triggerwert in AL laden
! out DX, AL ; ins Interrupt-ID-Reg. schreiben
! pop DS ; DS-Register wieder auf alten Wert
' setzen
END SUB
|
Gruß Horstd |
|
Nach oben |
|
 |
Ahnungslos

Anmeldungsdatum: 29.10.2007 Beiträge: 13 Wohnort: oben, bei Mutti
|
Verfasst am: 01.11.2007, 20:54 Titel: Assembler |
|
|
Ich wollte nochmal feststellen, das ich die Routinen, die mit int14h die COM-Schnittstelle ansprechen, in Assembler geschrieben habe, weil ich keine andere Möglichkeit gesehen habe in Freebasic den int14h zu machen. Bäh was für ein Schlagensatz, hoffentlich noch zu verstehen.
Aber wenn jemand eine andere Möglichkeit sieht, die COM-Schnittstelle unter Freebasic und unter FREEDOS anzusprechen, immer heraus damit.
Melde mich jetzt ins Wochenende ab...  _________________ In einem Club, der Leute wie mich aufnimmt, da möchte ich nicht Mitglied sein! |
|
Nach oben |
|
 |
ytwinky

Anmeldungsdatum: 28.05.2005 Beiträge: 2624 Wohnort: Machteburch
|
Verfasst am: 01.11.2007, 21:22 Titel: |
|
|
Es ist gut möglich, daß du weißt, was du tust, wenn du Assembler-Code verwendest..
..aber ich wollte egtl. darauf hinaus, daß FreeBASIC evtl. da nicht mitmacht^^
Auf der o.a. FB-Wiki Seite ist am Ende ein Block mit 'disallowed instructions'.
Das wären auf deutsch 'nicht erlaubte Befehle'..
Darunter ist auch der Hlt-Befehl, der, wie volta schon erwähnte, nicht so ohne Weiteres zu benutzen ist..
..etwas weiter darunter steht auch Int
..da es hier aber nicht um Zahlen-Umwandlung geht, kann also nur der Interrupt-Aufruf gemeint sein und du schreibst ja selber, daß es nicht ganz funktioniert, deshalb denke daran, daß Asm sich mglw nicht 1:1 in FreeBASIC benutzen läßt..
Schönes Wochenende^^ _________________
v1ctor hat Folgendes geschrieben: | Yeah, i like INPUT$(n) as much as PRINT USING.. | ..also ungefähr so, wie ich GOTO.. |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 03.11.2007, 16:00 Titel: |
|
|
Ahnungslos hat Folgendes geschrieben: | Meine Software ist FREEDOS & FREEBASIC | Nun ja, 'DEF SEG = 0' funktioniert natürlich nicht bei 32Bit PM.
Der Int 14 sollte aber gehen, obwohl es bei DPMI Probleme mit dem Rückgabewert im AX - Register geben soll (ich habe selbst noch keine Erfahrung damit gesammelt).
Warum die FB-Entwickler unter DOS die Com-Portsteuerung ausgelassen haben muß schon einen triftigen Grund haben. Irgendwie vermute ich unverträglichkeiten von DPMI <-> Interuptverarbeitung. _________________ Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater. |
|
Nach oben |
|
 |
Ahnungslos

Anmeldungsdatum: 29.10.2007 Beiträge: 13 Wohnort: oben, bei Mutti
|
Verfasst am: 07.11.2007, 19:31 Titel: 16550 FIFO eingeschaltet |
|
|
Hallo alle zusammen,
ich habe jetzt diese kleine FREEBASIC-Programm geschrieben,
das ohne int14h auskommt. Der FIFO des 16550 ist eingeschaltet und puffert 16 Byte. Das Programm läuft unter FREEDOS.
Code: |
?
?"Dies ist ein FREEBASIC-Programm,"
?"das die RS232-Schnittstelle mit 115200 Baud bedient."
?"Die Register des 16550 werden direkt verwendet."
?"Programm mit Taste Escape beenden"
DIM A AS STRING
Basisadr = &H3F8 'COM1 => 3F8 COM2 => 2F8
OUT Basisadr + 3, 128 OR INP(Basisadr + 3) 'DLAB = 1
OUT Basisadr + 0, 1 'switch to 115200
OUT Basisadr + 3, 127 AND INP(Basisadr + 3) 'DLAB = 0
OUT Basisadr + 2, &HC1 'FIFO Control Register => 16 Byte
WHILE A$ <> CHR$(27) 'Escape = CHR$(27)
A$ = INKEY$
IF (A$ <> "") and (A$ <> CHR$(27)) THEN OUT Basisadr, ASC(A$)
IF INP(Basisadr + 5) AND 1 THEN PRINT CHR$(INP(Basisadr));
WEND
|
Eine Merkwürdigkeit ist drin, wenn ich eine "1" ins FIFO-Control_Register schreibe, lese ich eine &HC1 zurück. Mir nicht ganz klar
Ansonsten ist für mich dieser Thread gelöst  _________________ In einem Club, der Leute wie mich aufnimmt, da möchte ich nicht Mitglied sein! |
|
Nach oben |
|
 |
ytwinky

Anmeldungsdatum: 28.05.2005 Beiträge: 2624 Wohnort: Machteburch
|
Verfasst am: 07.11.2007, 19:46 Titel: Re: 16550 FIFO eingeschaltet |
|
|
Hi,
Ahnungslos hat Folgendes geschrieben: | Code: | OUT Basisadr + 2, &HC1 'FIFO Control Register => 16 Byte |
| Du schreibst hier 'C1' und sagst, daß es das FIFO Control Register wär,
und beim Auslesen erhältst du ein 'C1'..
..kann es sein, daß da ein Zusammenhang besteht? _________________
v1ctor hat Folgendes geschrieben: | Yeah, i like INPUT$(n) as much as PRINT USING.. | ..also ungefähr so, wie ich GOTO.. |
|
Nach oben |
|
 |
Ahnungslos

Anmeldungsdatum: 29.10.2007 Beiträge: 13 Wohnort: oben, bei Mutti
|
Verfasst am: 07.11.2007, 19:55 Titel: FIFO Control Register |
|
|
Habe mich da etwas unklar ausgedrückt, ich will das da im FIFO Control Register &HC1 drin steht. Ich habe aber festgestellt, das ich das auch erreichen kann, wenn ich nur eine "1" ins FIFO Control Register schreibe.  _________________ In einem Club, der Leute wie mich aufnimmt, da möchte ich nicht Mitglied sein! |
|
Nach oben |
|
 |
HorstD
Anmeldungsdatum: 01.11.2007 Beiträge: 110
|
Verfasst am: 08.11.2007, 19:50 Titel: |
|
|
Das FIFO-Steuer-Register belegt die gleiche Adresse wie das Interrupt-ID-Register. Während das
Interrupt-ID-Register aber nur ausgelesen werden kann, lässt sich das bei den 8250-Nachfolgern
vorhandene FIFO-Register nur beschreiben.
Aufbau des FIFO-Steuer-Registers beim 16550 und seinen Nachfolgern (Offset 02 h):
Bit 0 = 1: FIFO-Puffer an
Bit 1 = 1: Empfangspuffer löschen
Bit 2 = 1: Sendepuffer löschen
Bit 3-5 = immer 0
Bit 6,7 Anzahl der Zeichen, nach deren Empfang der UART einen Interrupt auslösen soll
00 = nach jedem Zeichen
01 = nach 4 Zeichen
10 = nach 8 Zeichen
11 = nach 14 Zeichen
mfg
horstd |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|