Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

16550 FIFO einschalten

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Computer-Forum
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Ahnungslos



Anmeldungsdatum: 29.10.2007
Beiträge: 13
Wohnort: oben, bei Mutti

BeitragVerfasst am: 29.10.2007, 16:43    Titel: 16550 FIFO einschalten Antworten mit Zitat

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 mit dem Kopf durch die Mauer wollen .

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
Benutzer-Profile anzeigen Private Nachricht senden
PMedia



Anmeldungsdatum: 14.08.2006
Beiträge: 2847

BeitragVerfasst am: 30.10.2007, 00:29    Titel: Antworten mit Zitat

mhm gut, da du FreeDOS nutzt ist das vlt. recht nutzlos, aber unter Windows erzielte OpenCOM immer gute Ergebnisse dazu grinsen
(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 zwinkern (IRC-Leser wissen wieder mal mehr grinsen )
Praktisch ist man natürlich dran, wenn man den Quelltext der jeweiligen BIOS-Interupts hat... jaja, so eine Robotron-Systemdokumentation ist praktisch lächeln
Wenn du magst, such ich dir das raus, das sollte heute auf den IBM-PCs auch laufen, die sind ja ... merkwürdigerweise grinsen ... relativ Baugleich mit dieser Serie von Robotron-PCs... grinsen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Ahnungslos



Anmeldungsdatum: 29.10.2007
Beiträge: 13
Wohnort: oben, bei Mutti

BeitragVerfasst am: 30.10.2007, 13:03    Titel: OPEN COM Befehl Antworten mit Zitat

Danke für die nette Antwort, aber leider leider, weinen 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
Benutzer-Profile anzeigen Private Nachricht senden
PMedia



Anmeldungsdatum: 14.08.2006
Beiträge: 2847

BeitragVerfasst am: 30.10.2007, 18:14    Titel: Antworten mit Zitat

ja, ich kenne die Referenz, ich war an der Umsetzung beteiligt...
Ich such grad noch
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
HorstD



Anmeldungsdatum: 01.11.2007
Beiträge: 110

BeitragVerfasst am: 01.11.2007, 02:52    Titel: Antworten mit Zitat

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 zurck       ³
'³   CtsStatus      -  gibt den Status von CTS zurck                       ³
'³   DsrStatus      -  gibt den Status von DSR zurck                       ³
'³   DtrStatus      -  gibt den Status von DTR zurck                       ³
'³   GetComAddress  -  gibt die I/O-Adresse des angegeb. COM-Ports zurck   ³
'³   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 zurck  ³
'³   GetLptAddress  -  gibt die Adresse einer par. Schnittst. zurck (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 m”glichst 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 zurck
'
' 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 l”schen (=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 h”her 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 fr 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 l”schen (=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 h”her als
                                        ' die Basisadresse

    !   mov     AX, State               ; gewnschten DTR-Status in AX
    !   or      AX, AX                  ; soll DTR gesetzt werden ?
    !   in      AL, DX                  ; DTR-Status lesen (ver„ndert Flags
                                        '                   nicht)
    !   jnz     RaiseDTR                ; springe, wenn es gesetzt wird
    !   and     AL, &H0FE               ; aha, es soll gel”scht 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 zurck
'
' 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 l”schen (=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 h”her 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 zurck
'
' 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 l”schen (=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 h”her 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 zurck
'
' 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 l”schen (=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 h”her 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 zurck
'
' 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 l”schen (=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 ver„ndert nicht die Einstellung auf der
'                    Schnittstellenkarte !!
'
' port    = COM-Schnittstelle (1-4)
' address = neue Address fr 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 l”schen (=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 k”nnen 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 l”schen (=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 zurck
'
' 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 zurck
'
'   BIT(Status, 0) = Timeout (Zeitberlauf)
'   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 besch„ftigt (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 l”schen

    !   mov     FUNCTION, AX            ; Status zurckliefern

    !   pop     DS                      ; DS-Register wieder auf alten Wert
                                        ' setzen
END FUNCTION


'===========================================================================
' GetLptAddress - gibt die I/O-Adresse eines LPT-Ports zurck
'
' 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 zurckgeben

    !   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 rckg„ngig zu machen. Sonst arbeiten
'                andere Programme eventuell nicht mehr richtig. Ein weiterer
'                Aufruf von SwapLpt1and2() macht dies wieder rckg„ngig.
'
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
Benutzer-Profile anzeigen Private Nachricht senden
PMedia



Anmeldungsdatum: 14.08.2006
Beiträge: 2847

BeitragVerfasst am: 01.11.2007, 15:16    Titel: Antworten mit Zitat

OMG
Moderatoren, das ganze erstmal "lesbar" machen zwinkern
(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 lachen
... 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 grinsen

//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
Benutzer-Profile anzeigen Private Nachricht senden
Ahnungslos



Anmeldungsdatum: 29.10.2007
Beiträge: 13
Wohnort: oben, bei Mutti

BeitragVerfasst am: 01.11.2007, 18:02    Titel: 16550 FIFO einschalten Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
ytwinky



Anmeldungsdatum: 28.05.2005
Beiträge: 2624
Wohnort: Machteburch

BeitragVerfasst am: 01.11.2007, 18:29    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Ahnungslos



Anmeldungsdatum: 29.10.2007
Beiträge: 13
Wohnort: oben, bei Mutti

BeitragVerfasst am: 01.11.2007, 19:12    Titel: Antwort von ytwinky Antworten mit Zitat

Sorry,
aber bei dieser Antwort durchgeknallt weiss ich nicht so recht was gemeint ist. Kopf schütteln

By The Way: grinsen
Der Link führt auf eine Seite die sich mit Freebasic & Assembler beschäftigt.

In My Humble Opinion: zwinkern
Die Fragestellung dieses Threads ist aber 16550-FIFO einschalten.

Alles andere wurde schon gesagt (geschrieben) lächeln
_________________
In einem Club, der Leute wie mich aufnimmt, da möchte ich nicht Mitglied sein!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4704
Wohnort: ~/

BeitragVerfasst am: 01.11.2007, 19:31    Titel: Antworten mit Zitat

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. zwinkern
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
HorstD



Anmeldungsdatum: 01.11.2007
Beiträge: 110

BeitragVerfasst am: 01.11.2007, 20:29    Titel: Antworten mit Zitat

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 k”nnen 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 l”schen (=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
Benutzer-Profile anzeigen Private Nachricht senden
Ahnungslos



Anmeldungsdatum: 29.10.2007
Beiträge: 13
Wohnort: oben, bei Mutti

BeitragVerfasst am: 01.11.2007, 20:54    Titel: Assembler Antworten mit Zitat

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 geschockt 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... cool
_________________
In einem Club, der Leute wie mich aufnimmt, da möchte ich nicht Mitglied sein!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ytwinky



Anmeldungsdatum: 28.05.2005
Beiträge: 2624
Wohnort: Machteburch

BeitragVerfasst am: 01.11.2007, 21:22    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 03.11.2007, 16:00    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Ahnungslos



Anmeldungsdatum: 29.10.2007
Beiträge: 13
Wohnort: oben, bei Mutti

BeitragVerfasst am: 07.11.2007, 19:31    Titel: 16550 FIFO eingeschaltet Antworten mit Zitat

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 verwundert
Ansonsten ist für mich dieser Thread gelöst lächeln
_________________
In einem Club, der Leute wie mich aufnimmt, da möchte ich nicht Mitglied sein!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ytwinky



Anmeldungsdatum: 28.05.2005
Beiträge: 2624
Wohnort: Machteburch

BeitragVerfasst am: 07.11.2007, 19:46    Titel: Re: 16550 FIFO eingeschaltet Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Ahnungslos



Anmeldungsdatum: 29.10.2007
Beiträge: 13
Wohnort: oben, bei Mutti

BeitragVerfasst am: 07.11.2007, 19:55    Titel: FIFO Control Register Antworten mit Zitat

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. verwundert
_________________
In einem Club, der Leute wie mich aufnimmt, da möchte ich nicht Mitglied sein!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
HorstD



Anmeldungsdatum: 01.11.2007
Beiträge: 110

BeitragVerfasst am: 08.11.2007, 19:50    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Computer-Forum Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
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.

 Impressum :: Datenschutz