Watcom DOS: wcl vs wcl386

Wer mit CMake ein Watcom für DOS Projekt aufsetzt, erhält ein DPMI 32-bit Programm, das not mit einem DOS-Extender gestartet werden kann.

Das ist grundsätzlich gut, weil man dann “ganz” normal im 32-bit Flatmemory Stil arbeiten kann. Aber die guten alten Realmode Hardwarezugriffe sind damit ein Problem.

Wie macht man also “richtige” 16-bit DOS Programme im Jahr 2022?

————————————————————`

Antwort: Es liegt am eingesetzten Compiler.

wcl386.exe erzeugt 32-bit Code und wcl.exe generiert alten DOS 16-bit Code.

Je nachdem, welche EXE man ausführt und welche Parameter mitübergeben werden, kommt ein anderer Binärtyp heraus:

  • wcl386 main.c
    erzeugt eine “Standard” WinNT-Console main.exe
  • wcl386 -bcl=dos4g main.c
    erzeugt eine DOS/4G 32-bit main.exe
  • wcl386 -bcl=dos main.c
    ist falsch und funktioniert nicht
  • wcl -bcl=dos main.c
    erzeugt eine DOS 16-bit Realmode main.exe
  • wcl -bcl=com main.c
    erzeugt eine minimalistische DOS 16-bit Realmode main.com

Wenn man CMake auf DOS-Plattform einschwört, legt es sich auf DOS/4G 32-bit fest und ruft daher auch genau die dafür notwendigen Kommandos auf.
Das konnte ich auch mit noch so viel CMake Variablen-Umdeutungen nicht verhindern.

Wie überzeugt man also CMake von DOS 16-bit?

Das Geheimnis findet man in der Datei DOS-OpenWatcom.cmake in den CMake Scripts. Dort steht nämlich:

 1if(DEFINED CMAKE_SYSTEM_PROCESSOR AND CMAKE_SYSTEM_PROCESSOR STREQUAL "I86")
 2  string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " system dos")
 3  string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system dos")
 4  string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system dos")
 5else()
 6  string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " system dos4g")
 7  string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system dos4g")
 8  string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system dos4g")
 9endif()

Das heißt also, wenn man die Variable CMAKE_SYSTEM_PROCESSOR auf I86 setzt, dann erzeugt CMake die wmake Buildfiles genau so, dass eine echte 16-bit DOS-EXE am Ende herauskommt.

Konkret bedeutet das, mein CMake Aufruf muss so aussehen:

1cmake -G "Watcom WMake" -DCMAKE_SYSTEM_NAME=DOS -DCMAKE_SYSTEM_PROCESSOR=I86 -DCMAKE_BUILD_TYPE=Release path\to\sources

Und schon kann auf einem Windows 10 im Jahr 2022 eine 1980er-Party steigen.

Fazit

Als nächstes musste ich mir ein paar klein-Apps mit dem GATE Framework schreiben, die auch in eine kleine 16-Bit EXE passen. Zusätzlich war ein expliziter Wechsel zum Large-Model notwendig, weil Code und Daten nicht mehr in ein 64 KByte Segment passten.

Das war mit

1set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mm")
2set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mm")

erledigt.

Jetzt brauche ich nur noch einen DeLorean mit einem Fluxkompensator, damit ich mir selbst Glück bringen kann.
… aber das ist eine andere Geschichte.

📧 📋 🐘 | 🔔
 

Meine Dokus über:
 
Weitere externe Links zu:
Alle extern verlinkten Webseiten stehen nicht in Zusammenhang mit opengate.at.
Für deren Inhalt wird keine Haftung übernommen.



Wenn sich eine triviale Erkenntnis mit Dummheit in der Interpretation paart, dann gibt es in der Regel Kollateralschäden in der Anwendung.
frei zitiert nach A. Van der Bellen
... also dann paaren wir mal eine komplexe Erkenntnis mit Klugheit in der Interpretation!