UART 16550

Gast
Hallo, ja und zwar möchte ich das ganze Vorgehen für die ISR bzw COM 
Interrupt Handler beschreiben.
1
void __cdecl CommIntHandler(ETSINTREGS *pRegs);
2

3
void COM(void)
4
{
5
...
6
UartIntVecNum = EtsPicGetIRQIntNumber(UartIRQNum); 
7
// UartIntVecNum = 0x0C
8
SaveFlags = EtsSetInterruptFlag(ETS_DISABLEINTS);
9
EtsSaveInterruptHandler(UartIntVecNum, &CommDesc);
10
EtsSetInterruptHandler( UartIntVecNum, CommIntHandler); // set handler
11
...
12
}

//
// Saved register block passed to interrupt handlers registered
// with EtsSetInterruptHandler() and EtsSetExceptionHandler().
// These fields contain the register contents at the time of the
// interrupt.  The interrupt service routine can modify the
// values in the passed structure in order to change the user
// registers on return from the interrupt.
//
// Note:  The FS and GS registers are neither saved nor restored
// by the interrupt handler framework.  If a user interrupt handler
// wants to use either of these registers, it must preserve them itself!
//
typedef struct tagETSINTREGS
{
  DWORD   Ebp;                    // [00]
  DWORD   Eax;                    // [04]
  DWORD   Ebx;                    // [08]
  DWORD   Ecx;                    // [12]
  DWORD   Edx;                    // [16]
  DWORD   Esi;                    // [20]
  DWORD   Edi;                    // [24]
  DWORD   Gs;                     // [28]
  DWORD   Ds;                     // [32]
  DWORD   Es;                     // [36]
  DWORD   IntNum;                 // [40]
  DWORD   Ecode;                  // [44]
                           (Zero if int w/o error code)
  DWORD   Eip;                    // [48]
  DWORD   Cs;                     // [52]
  DWORD   Eflags;                 // [56]
} ETSINTREGS, *PETSINTREGS;

//---------------------------------------------------------------------- 
-------
// EtsSetInterruptHandler - Install a C function as an interrupt handler
//
//      This API installs a C function as an interrupt handler
//      for the specified interrupt.  The handler is entered as a normal
//      C function (__cdecl calling sequence) with interrupts disabled
//      and receives a pointer to the saved register set on the stack
//      as its argument.  The saved register set includes all general
//      purpose registers, DS, ES, and EFLAGS.  The FS and GS registers
//      are neither saved nor restored; if the handler alters them, it
//      must restore them itself before returning.  The handler
//      is expected to process the interrupt and may modify the
//      saved register set on the stack if wishes to
//      alter the context of the interrupted code.  When the handler 
function
//      returns, the saved registers are popped off the stack and
//      control returns to the interrupted code.
//
//      The return value from the function is TRUE if successful or 
FALSE
//      if an error occurs.
//
//---------------------------------------------------------------------- 
-------
BOOL    __cdecl EtsSetInterruptHandler(unsigned IntNumber,
               PETSINTHANDLER pHandler);

Ich verstehe da das genau Vorgehen nicht.
Was geschieht bei diesem Funktionsaufruf genau:
>>EtsSetInterruptHandler( UartIntVecNum, CommIntHandler);
Ist der CommIntHandler ein Zeiger auf einen bestimmten STACK?
Gast
Das ist ein Board mit einem ELAN-SC400 Prozessor von AMD.
Ich tue mich sehr schwer mit dem Beschreiben der UART und dem COM 
Interrupt Handler.
Persönliche Seite
Was auch immer das da sein soll, das hat nach wie vor nichts mit der 
UART zu tun.

Warum im Interrupthandler der Interruptcontroller befummelt wird, 
entzieht sich meinem Verständnis; die übliche Vorgehensweise in einem 
PC-Interrupthandler (unter DOS, also praktisch ohne Betriebssystem) 
sieht so aus:

[int]

Schnittstellenstatus aus UART auslesen
(Warum hat die UART den Interrupt ausgelöst?)

Je nach Schnittstellenstatus zu erledigende Dinge tun
(Zeichen abholen und speichern oder Zeichen aus Sendepuffer lesen und an 
UART übertragen oder ...)

Interruptcontroller die Beendigung der Interruptroutine mitteilen

[reti]


Es ist nicht erforderlich, in der Interruptroutine irgendwelche 
Interruptvektoren zu bestimmen, denn das geschieht schon implizit durch 
Aufruf der richtigen Interruptroutine.
Persönliche Seite
Dann darf das aber nicht mit dem Namen der Interruptroutine beschriftet 
sein.

Im übrigen wird auf PC-Hardware (unter DOS, also ohne Betriebssystem) 
ein Interrupthandler dadurch installiert, daß seine Startadresse in die 
Interrupttabelle im Arbeitsspeicher eingetragen wird. Danach muss nur 
noch dem Interruptcontroller mitgeteilt werden, daß es den 
Interrupthandler gibt (setzen/löschen des erforderlichen Bits) und 
fertig.


Hier mal etwas Pascal-Quelltext:

Interrupthandler
1
procedure v24_irq;
2
{ interruptroutine. Wird fr jedes auf 8250 ankommendes Zeichen aufgerufen }
3
interrupt;
4
  var
5
    zeichen : byte;
6
    inhalt : integer;
7
  begin
8
    inline($FA);              { Interrupts sperren }
9
    zeichen := port[uart];    { angekommenes Zeichen lesen }
10
    buffer[ein] := zeichen;   { Zeichen in FIFO eintragen }
11
    inc(ein);                 { Schreibzeiger erh”hen }
12
    inc(counter);             { Fllstand erh”hen }
13
    if (fifo_len - ein = 0)   { FIFO-Wraparound }
14
      then ein := 0;
15
    if (counter > fifo_len - fifo_dlost)
16
      then begin
17
        dec(counter);
18
        dec(ein);             { FIFO-šberlauf ! (weitere Zeichen ignorieren) }
19
      end;
20
    if (counter > fifo_len - fifo_off)
21
      then v24_off;           { Handshake : Schnittstelle abschalten }
22
    if (ein >= aus)
23
      then inhalt := ein - aus
24
      else inhalt := fifo_len - (aus - ein);
25
    counter := inhalt;
26
    inline($FB);              { Interrupts wieder zulassen }
27
    port[$20] := EOI;         { weitere Interrupts zulassen (8259) }
28
  end;
Die letzte Anweisung ist hier interessant.


Und hier wird der Interruptvektor gesetzt:
1
    { Interruptvektor retten & setzen }
2
    case com_intr[nr] of
3
      3 :
4
        begin
5
          setintvec(11,@v24_irq);
6
        end;
7
      4 :
8
        begin
9
          setintvec(12,@v24_irq);
10
        end;
11
      end;

Hier wird dem Interruptcontroller das Vorhandensein des Handlers 
mitgeteilt
1
          case com_intr[com_nr] of
2
            3 : port[interrupt_controller] := port_21 and $f7;
3
            4 : port[interrupt_controller] := port_21 and $ef;
4
          end;
5
          port[uart + 1] := 1;    { IRQ bei Datenempfang }
(sowie bei der UART der Empfangsinterrupt freigeschaltet


Die eigentliche Initialisierung der UART geschieht hier:
1
    { Baudratenteiler berechnen }
2
    baudteil := 115200 div baudrate;
3

4
    { Schnittstelle initialisieren }
5
    port[uart + 5] := 60;     { Line Status Register }
6
    port[uart + 1] := $00;    { Interrupt Enable Register }
7
    port[uart + 2] := $04;    { Interrupt Ident. Register }
8
    port[uart + 4] := $0B;    { Modem Control Register }
9
    port[uart + 3] := $80;    { Baudratenteiler ansprechen }
10
    port[uart] := lo(baudteil);
11
    port[uart + 1] := hi(baudteil);
12
    port[uart + 3] := $07;    { Line Control Register }

und ist natürlich vor dem Setzen und Initialisieren des 
Interrupthandlers durchzuführen.


Auch wenn das Turbo-Pascal-Code ist, lässt sich das recht leicht auch in 
C ausdrücken.


Was Du da gepostet hast, hat mit irgendeinem Betriebssystem oder 
irgendeiner betriebssystemartigen Umgebung zu tun.
Gast
Danke für die Hilfe!!!
Ich habe es jetzt mal so in Sätzen zusammengefasst:

Das Senden und Empfangen von der seriellen Schnittstelle funktioniert 
hier Interruptgesteuert. Dazu wurde ein Interrupt Handler eingerichtet, 
in diesem wird das Interrupt Identifikations Register ausgelesen. Über 
das Interrupt Identifikations Register, erfährt der Interrupt 
Controller, wegen welchem Ereignis der Interrupt ausgelöst wurde. Der 
Interrupt Handler wird dadurch installiert, dass seine Startadresse in 
die Interrupttabelle im Arbeitsspeicher eingetragen wird. Danach wird 
noch dem Interrupt Controller mitgeteilt, dass der Interrupt Handler 
existiert.

Sobald der UART ein Datum empfängt bzw. ein Datum an die UART übergibt, 
wird ein Interrupt ausgelöst, dieser veranlasst, dass der Interrupt 
Handler gestartet wird.

(Auf dem Board läuft ein 32Bit Echtzeitbetriebssystem, dort kann man auf 
die Win API zugreifen)
Persönliche Seite
> Über das Interrupt Identifikations Register, erfährt der Interrupt
> Controller, wegen welchem Ereignis der Interrupt ausgelöst wurde.

Nein. Der Interrupt-Controller hat damit nichts zu tun, durch das 
Auslesen des IIR erfährt der Interrupt-Handler (also Deine Software), 
welches Ereignis den Interrupt ausgelöst hat.

Wann der/die UART Interrupts auslöst, wird durch die Initialisierung 
festgelegt, dort lassen sich Interrupts bei Datenempfang, leerem 
Senderegister, Änderungen der Handshakeleitungen etc. konfigurieren.

Da Du aber ein Betriebssystem verwendest, werden etliche Details anders 
gehandhabt werden; das Betriebssystem selbst verwaltet die Behandlung 
des Interruptcontrollers und auch das Einrichten eines Interrupthandlers 
durch entsprechende Funktionsaufrufe.

Daher sind die in den von mir geposteten Pascal-Sourcen getätigten Dinge 
nur mit äußerster Vorsicht zu genießen.

Ist das 32-Bit-Echtzeitsystem zufälligerweise OnTime RTOS-32?
Gast
>Ich habe es jetzt mal so in Sätzen zusammengefasst:
Schön aber was soll das?

>Das Senden und Empfangen von der seriellen Schnittstelle funktioniert
>hier Interruptgesteuert...
Brauchst du das für einen Vortrag oder willst du irgendwas 
programmieren?
Wie das mit den Interrupts funktioniert wissen zumindest die die dir 
helfen könnten. Es ist nur unklar was du eigentlich willst.

>Sobald der UART ein Datum empfängt bzw. ein Datum an die UART übergibt,
>wird ein Interrupt ausgelöst, dieser veranlasst, dass der Interrupt
>Handler gestartet wird.
nicht ganz der 16c550 kann auch erst bei einem bestimmten Füllstand 
Interrupts auslösen. Also wenn mehrere Daten vorhanden sind.

>(Auf dem Board läuft ein 32Bit Echtzeitbetriebssystem, dort kann man auf
>die Win API zugreifen)
Die erste richtige Info, wie heißt das Betriebssystem und was willst du 
eigentlich machen?
Gast
Als Betriebssoftware wird die ETS -  TNT Embedded ToolSuite von PharLap 
eingesetzt. Diese ist ein 32 bit Real-Time Operating System (RTOS), das 
sich durch Unterstützung eines Teils der WIN32 API leicht in Windows 
Systeme integrieren lässt.

Ich möchte eigentlich den ganzen Vorgang von der seriellen Kommunikation 
(UART) dokumentieren. Mein Programm benutzt ein Interrupt Handler für 
die serielle Schnittstelle.

1. Beschreibung UART
2. Initialiserung UART
3. Aktivierung Interrupt für COM
4. Erstellung eines Interrupt Handlers für COM
5. Funktionsweise des Interrupt Handlers
Gast
Ich hab nochmals meinen Text einwenig verändert:

Das Senden und Empfangen von der seriellen Schnittstelle funktioniert 
hier Interruptgesteuert. Dazu wurde ein Interrupt Handler eingerichtet, 
in diesem wird das Interrupt Identifikations Register ausgelesen. Über 
das Auslesen des Interrupt Identifikations Registers, erfährt der 
Interrupt Handler, welches Ereignis den Interrupt ausgelöst hat. Der 
Interrupt Handler wird dadurch installiert, indem seine Startadresse in 
die Interrupttabelle im Arbeitsspeicher eingetragen wird. Danach wird 
dem Interrupt Controller mitgeteilt, dass der Interrupt Handler 
existiert.

Sobald der UART ein Datum empfängt bzw. ein Datum an die UART übergibt, 
wird ein Interrupt ausgelöst, dieser veranlasst, dass der Interrupt 
Handler gestartet wird.

(Dies soll eigentlich einfach gehalten werden)
Persönliche Seite
> Fakt ist, das ist ein  ein 32 bit Real-Time Operating System (RTOS).
> Dieses Programmiere ich mit Visual Studio 6.0 (C++).

Du wirst unglaubwürdig, da Du zwei unterschiedliche Produkte aufgeführt 
hast. Würdest Du tatsächlich mit einem davon arbeiten, wüsstest Du, wie 
es heißt.

Trotzreaktionen sind hier wenig hilfreich.

> > Ich programmiere unter Linux.
>
> > Ich programmiere unter Windows.
>
> Was denn nun?
>
> > Fakt ist, das ist ein 32-Bit Betriebssystem.

Erkennst Du Deine "Argumentation" wieder?

Sei's drum.


> Sobald der UART ein Datum empfängt bzw. ein Datum an die UART übergibt,

Den Sendeinterrupt (TXEMPT) solltest Du besser anders beschreiben.

Sobald der UART ein in sein Senderegister geschriebenes Zeichen (trenne 
Dich vom unglücklichen "Datum"!) versendet hat, wird der "transmit 
register empty"-Interrupt ausgelöst, um zu signalisieren, daß ein neues 
Zeichen versendet werden kann.
Gast
Warum unglaubwürdig? Ich programmiere unter Windows. Linux habe ich hier 
nie verwendet. Mir geht es um das alg. Handling mit dem ganzen geraffel.
Persönliche Seite
Ich habe bereits dargelegt, daß es einen ganz erheblichen Unterschied 
macht, worunter/wofür man einen Interrupthandler schreibt - es ist was 
anderes, ob man einen Interrupthandler für RTOS-32 (das ist ein Produkt! 
Keine generische Bezeichnung) oder für Pharlap TNT ETS schreibt.

Der Windows-/Linux-Vergleich ist eine Metapher für Deine Reaktion auf 
die Frage, wofür Du da was zu schreiben glaubst.

Das Handling des ganzen Geraffels ist eben unterschiedlich und 
deswegen kommt es darauf an, die Rahmenbedingungen zu kennen und auch zu 
nennen.

Dir aber scheint es wohl nur um einen Aufsatz oder dergleichen zu gehen 
...
Gast
Ich habs jetzt so geschrieben:

Sobald der UART ein in seinem Senderegister geschriebenes Zeichen 
versendet hat, wird „transmit holding register empty“- Interrupt 
ausgelöst, um zu signalisieren, dass ein neues Zeichen versendet werden 
kann. Im umgekehrten Fall, wenn ein Zeichen im Empfangsregister 
vorliegt, dann wird „receive data is available“- Interrupt ausgelöst, 
damit wird signalisiert dass ein neues Zeichen empfangen werden kann.
Gast
Ich habe eher das Gefühl, du machst einen Teil einer Belegarbeit an der 
Uni,
die anderen haben es programmiert und da du Probleme dabei hattest, hast 
du dir den Dokumentationsteil rausgesucht.
Wenns wirklich so sein sollte: Schlechte Wahl, das setzt nämlich erst 
recht voraus, daß du alles verstehst.
Deine Bezeichnungen lassen erkennen, daß du in Hardwarenaher 
Programmierung nicht firm bist.

>Ich habs jetzt so geschrieben:
>...
ist etwas besser, aber deutlicher wird es mit einem Statediagram und 
Text

>dann wird „receive data is available“- Interrupt ausgelöst,
>damit wird signalisiert dass ein neues Zeichen empfangen werden kann.
das ist Müll, wenn du ein Zeichen bekommst solltest du es abholen
Gast
Ich hoffe das stimmt was ich hier geschrieben habe:

Das Senden und Empfangen von der seriellen Schnittstelle funktioniert 
hier Interruptgesteuert. Dazu wurde ein Interrupt Handler eingerichtet, 
in diesem wird das Interrupt Status Register ausgelesen. Über das 
Auslesen des Interrupt Status Registers, erfährt der Interrupt Handler, 
welches Ereignis den Interrupt ausgelöst hat.

Der Interrupt Handler wird dadurch installiert, indem seine Startadresse 
in die Interrupttabelle im Arbeitsspeicher eingetragen wird. Danach wird 
dem Interrupt Controller mitgeteilt, dass der Interrupt Handler 
existiert.

Sobald der UART ein in seinem Senderegister geschriebenes Zeichen 
versendet hat, wird „transmit holding register empty“- Interrupt 
ausgelöst, um zu signalisieren, dass ein neues Zeichen versendet werden 
kann. Im umgekehrten Fall, wenn ein Zeichen im Empfangsregister 
vorliegt, wird „receive data is available“- Interrupt ausgelöst, damit 
kann nun das Zeichen vom Empfangsregister abgeholt werden.
Gast
> Danach wird dem Interrupt Controller mitgeteilt, dass der Interrupt
> Handler existiert.

Ich weiß ja nicht was da für ein Interruptcontroller drauf ist aber 
normalerweise wird der betreffende Interrupt nur freigeschaltet.
Gast
Es ist ein 8259 Controller. Der kann doch 15 Geräte verwllten oder?

void __cdecl CommIntHandler(ETSINTREGS *pRegs);

void COM(void)
{
 ...
 UartIntVecNum = EtsPicGetIRQIntNumber(UartIRQNum);
 // --> UartIntVecNum = 0x0C
 ....
 EtsSetInterruptHandler( UartIntVecNum, CommIntHandler); // set handler
 ...
}

Ich hab da noch immer Probleme damit. Ich beschreibe es mal mit meinen 
eigenen Worten.
1. UartIntVecNum = EtsPicGetIRQIntNumber(UartIRQNum);
--> Nr. von der Vectortabelle auslesen, ist hier 0x0C
  (Warum Vectortabelle?)
2.EtsSetInterruptHandler( UartIntVecNum, CommIntHandler); // set handler
--> Interrupt Handler einrichten: 0x0C und Adresse vom Interrupt Handler 
der Funktion übergeben. Dann passiert irgendwas im Stack.

Weiss nicht so ganz obn dies hier stimmt.
Gast
Ich verstehe das genau Zusammenspiel UART, Interrupt Controller, 
Interrupt Handler noch nicht ganz.
Kann mir einer erklären wie es im Prinzip funktioniert?
Gast
Ein 8259 kann 8 Interrupts verwalten - man kann ihn aber auch 
kaskadieren und bekommt dann Weitere.

Wie ein Interrupt abläuft:

Byte wurde empfangen -> UART akiviert die IRQ-Leitung -> IRQController 
prüft, ob aktiviert -> IRQController aktiviert die INT-Leitung zum 
Prozessor -> wenn Interrupts dort freigeschaltet sind: Prozessor macht 
seinen aktuellen Befehl noch fertig, schreibt die aktuelle CS:IP Adresse 
auf den Stack und setzt die INTA-Leitung zum IRQController -> 
IRQController überträgt den Vector (Vectortabelle ist ein Array mit den 
Anfangsaddressen der Interrupthandler-Funktionen, Vector der Index eines 
Eintrages in dieser Tabelle) -> CPU springt die zum Vector passende 
Interrupthandler-Funktion an -> Interrupthandler fragt die Hardware ab 
-> UART deaktiviert seine IRQ-Leitung -> Interrupthandler macht ein IRET 
(oder wars RETI?) -> CPU macht da weiter wo sie unterbrochen wurde.
Gast
Guten Abend, ich habe doch noch Probleme mit dem Interrupt Handler.
Und zwar es wird doch zuerst die Vectornummer von der Schnittstelle COM1 
(0x3F8) ausgelesen. Dies ist hier 0x0C. Dann wirdn doch der eigentliche 
Interrupt Handler installiert bzw. eingerichtet. Die Funktion 
EtsSetInterrupt Handler erhält zwei Parameter. 1. Parameter = 
Vectornummer 0x0C, 2. Parameter  die Adresse vom Interrupt Handler. Ist 
das jetzt richtig so?
Ich möchte nur diesen Vorgang beschreiben. Mir ist nun nicht ganz klar 
ob meine Aussage so stimmt.
1
void __cdecl CommIntHandler(ETSINTREGS *pRegs);
2

3
void COM(void)
4
{
5
...
6
UartIntVecNum = EtsPicGetIRQIntNumber(UartIRQNum); 
7
...
8
EtsSetInterruptHandler( UartIntVecNum, CommIntHandler); // set handler
9
...
10
}
Gast
2F8 und 3F8 sind IO adressen, wo das UART montiert ist. Was soll das 
Ganze ? Weder unter Linux, noch unter Windows schreibt jemand einen 
Interrupthandler.  Dort ist die Thematik eine ganz andere. Wie 
manoevriert man in den Tiefen des verbockten Windows, ohne das alles 
abschmiert. Sogar kundige Spzialisten verbraten da schnell mal 2 Monate. 
Vergiss es.
Intel hat einen schoenen Interruptcontroller gemacht, der kann 
Prioritaeten zuweisen und rotieren. Trotzdem wollte Microsoft was 
anderes und hat oben eine Software draufgesetzt die alles vermurkst.
Als Einsteigelektuere sei das iAPX86 Manual von Intel empfohlen, Dort 
wird auch der 8259 beschrieben, und ein paar Interrupthandler sind da 
auch drin. Als naechstes waere das 386 Manual mit dem Protected mode 
empfohlen. Dort wurden die Interrupts virtualisiert und muessen durch 
trap gates. Seither hat sich interruptmaessig nicht mehr sehr viel fuer 
den Benutzer geaendert.
Gast
Das ist ein Webserverboard von PharLap. Es nutzt ETS ein 32 bit Echtzeit 
Betriebssystem und kann ein Teil der WIN32 API-Funktionen. Der Prozessor 
ist ein AMD-ELAN Prozessor mit 66 MHZ. Programmieren tue ich das ganze 
unter Visual Studio 6.0 mit C++.
Gast
Ich habe die Beschreibungen zu dem entsprechenden Funktionen gefunden.
Ich hab da Probleme das ganze hier zu verstehen.

//
// Return the interrupt vector number which corresponds to the
// specified hardware IRQ.  Assumes PC/AT mapping of 08h for IRQs 0-7
// and 70h for IRQs 8-15.  Source is provided in 
PHAREMB/EMBCUST/PCPIC.ASM.
//
// hardwareIRQNum is the desired IRQ number
//
// Returns the interrupt vector number which corresponds to the
// specified IRQ, or -1 if the specified IRQ is out of range.
//
int     __cdecl EtsPicGetIRQIntNumber(int hardwareIRQNum);


//---------------------------------------------------------------------- 
-------
// EtsSetInterruptHandler - Install a C function as an interrupt handler
//
//      This API installs a C function as an interrupt handler
//      for the specified interrupt.  The handler is entered as a normal
//      C function (__cdecl calling sequence) with interrupts disabled
//      and receives a pointer to the saved register set on the stack
//      as its argument.  The saved register set includes all general
//      purpose registers, DS, ES, and EFLAGS.  The FS and GS registers
//      are neither saved nor restored; if the handler alters them, it
//      must restore them itself before returning.  The handler
//      is expected to process the interrupt and may modify the
//      saved register set on the stack if wishes to
//      alter the context of the interrupted code.  When the handler 
// function
//      returns, the saved registers are popped off the stack and
//      control returns to the interrupted code.
//
//      The return value from the function is TRUE if successful or 
FALSE
//      if an error occurs.
//
//---------------------------------------------------------------------- 
-------
BOOL    __cdecl EtsSetInterruptHandler(unsigned IntNumber,
               PETSINTHANDLER pHandler);

//
// Saved register block passed to interrupt handlers registered
// with EtsSetInterruptHandler() and EtsSetExceptionHandler().
// These fields contain the register contents at the time of the
// interrupt.  The interrupt service routine can modify the
// values in the passed structure in order to change the user
// registers on return from the interrupt.
//
// Note:  The FS and GS registers are neither saved nor restored
// by the interrupt handler framework.  If a user interrupt handler
// wants to use either of these registers, it must preserve them itself!
//
typedef struct tagETSINTREGS
{
  DWORD   Ebp;                    // [00]
  DWORD   Eax;                    // [04]
  DWORD   Ebx;                    // [08]
  DWORD   Ecx;                    // [12]
  DWORD   Edx;                    // [16]
  DWORD   Esi;                    // [20]
  DWORD   Edi;                    // [24]
  DWORD   Gs;                     // [28]
  DWORD   Ds;                     // [32]
  DWORD   Es;                     // [36]
  DWORD   IntNum;                 // [40]
  DWORD   Ecode;                  // [44]   (Zero if int w/o error code)
  DWORD   Eip;                    // [48]
  DWORD   Cs;                     // [52]
  DWORD   Eflags;                 // [56]
} ETSINTREGS, *PETSINTREGS;

void __cdecl CommIntHandler(ETSINTREGS *pRegs);

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 19 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.