Direkte I/O-Zugriffe mit Visual Basic

Obwohl fast jeder schon mal damit programmiert hat, setzen viele Entwickler nur ein kaltes Lächeln auf, wenn man Sie heute nach der Programmiersprache Basic befragt. Aber es gibt auch noch eingefleischte Programmierer, die mit Basic professionelle Programme erstellen und das in einer Zeit und mit einer Qualität, die der Arbeit mit anderen Programmiersprachen in nichts nachstehen.

Ein Grund dafür ist sicher in dem von einem “größeren” Softwarehersteller angebotenen Visual Basic zu suchen, das die Benutzung externer DLLs sowie die Übergabe von Funktions- und Datenadressen erlaubt. Damit ist auch die Grundlage für die Benutzung der Kithara-Toolkits geschaffen, so dass kein Basic-Programmierer mehr vor direkten, zeitkritischen Hardware-Zugriffen zurückschrecken muss.

Sound on / Sound off

Wir möchten Ihnen in diesem Artikel kurz zeigen, wie einfach der Zugriff auf I/O-Ports und Speicher auch unter Basic sein kann. Zur Demonstration wollen wir hier dem altehrwürdigen PC-Speaker ein paar einfache Töne entlocken – wohl gemerkt, alles unter Win32 mit Visual Basic!

Da zur Benutzung von Funktionen externer DLLs ähnlich wie in Delphi oder Java eine entsprechende Deklaration notwendig ist, werden diese in unseren Toolkits in einem fertigen Schnittstellenmodul einschließlich anschaulicher Beispiele mitgeliefert.

Fast alle Funktionen geben einen “Fehlercode” zurück, anhand dessen man den Erfolg oder die Art des Versagens der Funktion ermitteln kann. So ist eine zuverlässige Überwachung der Arbeit gewährleistet. Aus Gründen der Vereinfachung ersparen wir uns hier in der Regel eine Fehlerauswertung, was man normalerweise natürlich nicht machen sollte.

Doch nun konkret: Für den direkten Zugriff auf die I/O-Ports des PCs müssen diese zunächst freigeschaltet werden. Für die Sound-Ausgabe benötigen wir die I/O-Ports 42 und 43 Hex sowie 61 Hex. Dazu wird die jeweilige I/O-Basisadresse, die Anzahl zusammenhängender Ports und zuletzt die Größe der Ports angegeben (Byte, Word oder DWord).

error = KS_enableIoRange(&H42, 2, KSF_SIZE_8_BIT)
If error Then
...                           ' Fehlerbehandlung
End If
error = KS_enableIoRange(&H61, 1, KSF_SIZE_8_BIT)

Ab jetzt können die Zugriffe auf die I/O-Adressen erfolgen. Dazu benutzen wir die Frequenz in Hertz, mit der der PC-Speaker “erklingen” soll.

Dim frequency As Long,value As Long, temp As Long

frequency = 440  		           ' Kammerton a'
value = &H1234DD\ frequency        ' Teilfrequenz
temp = KS_inpb(&H61)               ' Port H61 lesen
If (temp And &H3) <> &H3 Then      ' schon eingeschaltet?
KS_outpb &H61, temp Or &H3         ' Nein? -> Einschalten!
KS_outpb &H43, &HB6                ' Status setzen
End If
KS_outpb &H42, value               ' Frequenz setzen (Low)
KS_outpb &H42, value \ 2 ^ 8       ' Frequenz setzen (High)

OK. Wie Sie den Lautsprecher wieder zum Schweigen bringen, verraten wir beim nächsten Mal...

Scherz beiseite. Da der PC-“Quieker” jetzt bereits nervt, wollen wir ihn schnell wieder ausschalten. Das geht einfacher:

KS_outpb &H61, KS_inpb(&H61) And &HFC 

Hier noch ein Hinweis: Die I/O-Ports, auf die wir in diesem Beispiel zugegriffen haben, gehören zum Teil zu solch wichtigen Einheiten wie dem PC-Timerschaltkreis. Eine fehlerhafte Umprogrammierung der PC-Hardware kann durchaus verheerende Folgen auf die Arbeit der Betriebssysteme nach sich ziehen! Man sollte also entweder genau wissen, was man tut oder zumindest auf einen gelegentlichen “Blue Screen” gefasst sein.

Physischer Speicher

Ein anderes Thema ist der direkte Zugriff auf den physischen Speicher des PCs. Da Visual Basic ein direktes Arbeiten mit Adresszeigern nicht unterstützt, können hierzu die speziellen Funktionen KS_readMem bzw. KS_writeMem verwendet werden. Als erstes ist jedoch der physische Speicherbereich in den Adressraum der Anwendung einzublenden.

Wenn sich im Rechner beispielsweise eine PC-Einsteckkarte befindet, deren Dual-Port-RAM an der Adresse D800:0000 einen 16 KByte langen Speicherbereich belegt, könnten Sie diesen mit folgender Funktion zugänglich machen.

Public pPhysMem As Long          ' Zeiger auf Speicher
KS_mapPhysMem(pPhysMem, 0, &HD8000, &H4000, KSF_MAP_ISA)

Mit dem ermittelten Zeiger pPhysMem kann man jetzt auf den eingeblendeten Speicher an der angegebenen Adresse zugreifen, um etwa von der Karte ermittelte externe Daten zu lesen. Die Routine dazu könnte wie folgt aussehen.

Public pMemBuf(&HFF) As Byte ' Puffer für Speicherdaten
Dim offset As Long, size As Long
error = KS_readMem(pMemBuf(0), pPhysMem + offset, size)

Am Ende des Programms sollte korrekterweise noch etwas aufgeräumt werden, so ist das Speichermapping wie folgt zu beenden.

error = KS_unmapPhysMem(pPhysMem)

Damit findet auch unser kleiner Programmierexkurs sein Ende.

Fazit

Wie unschwer zu erkennen ist, braucht man nur wenige Quelltextzeilen und einige Funktionen aus den Kithara-Toolkits, um beispielsweise auf die I/O-Ports oder den physischen Speicher des PCs direkt zugreifen zu können. So erleichtern diese Werkzeuge in der neuen Version auch unter Visual Basic das Programmieren, ohne Nachtschichten bei der Kernel-Programmierung einlegen zu müssen.

Zurück