Mehr Arbeitsspeicher in DOS nutzen?



  • Hallo,

    ich schreibe ein Programm unter DOS mit Turbo C++ 3.0. Ich finde es allerdings schade, dass DOS scheinbar nicht mehr als 640 KiB Arbeitsspeicher hergibt. Ich habe in Google allerlei Dinge gelesen über DOS Extender und XMS, allerdings verstehe ich nicht, wie ich jetzt konkret vorgehen muss, um die 640 KiB Grenze zu überschreiten?

    mfg
    Developer30



  • Warum tust du dir das an? Wen zum Geier interessiert das noch?



  • Wozu gibt's denn ein Unterforum "DOS und Win32-Konsole"? Dann kann ich doch auch dem entsprechend eine Frage, die 1. mit C++ und 2. mit Dos zutun hat, stellen - oder nicht? Vielleicht ist hier ja wer, der (vielleicht sogar noch aus eigener Erfahrung von früher) mir hierzu was nützliches sagen kann.



  • Es gab schon eine Frage hier, ob man das "DOS" nicht streichen sollte 😉

    Natürlich kannst du die Frage stellen. Und ich gebs auch zu, ich kenne keine Antwort drauf. Aber ich finde es sehr verwunderlich, dass du dich mit sowas beschäftigst. Ich habe auch mal etwas für DOS programmiert, aber das ist schon sehr lange her, und schon damals hat DOS keine Sau interessiert. Aber es hatte einen gewissen Charme und war zu Windows 95 Zeiten halt noch nicht ganz tot. Aber ich hab das mehr zum Spass gemacht und habe mich in solche Probleme wie "zu wenig Arbeitsspeicher" nie reingedacht. Das Problem existiert seit über 30 Jahren nicht mehr. Ich seh wirklich überhaupt gar keinen Sinn, sich da jetzt noch reinzudenken. Es gibt viel wichtigere und interessantere Sachen, in die du dich reindenken könntest.



  • Such mal nach EMS und XMS. Das waren damals die beiden Wege, an mehr Speicher zu kommen. Aber keine Ahnung, ob man dazu noch großartig Doku findet.



  • (vielleicht sogar noch aus eigener Erfahrung von früher)

    Ja, aber daran kann ich mich nur schwammig erinnern. Sowas wie highmem.sys und emm386.exe ...



  • knivil schrieb:

    Ja, aber daran kann ich mich nur schwammig erinnern.

    Ja, ich auch.

    Aber manche älteren Borland C++ (möglicherweise aber nicht die billigeren Turbos), konnten mit den DOS-Speichererweiterungen umgehen, das waren irgendwelche Einstellungen bei den Projektoptionen. Sollte auch in der zugehörigen Doku drin stehen.

    Insbesondere mit BC++ 4 und 5 gab es auch 32-Bit DOS-Programme, die konnten mehrere MB Arbeitsspeicher verwenden. Die entsprechende DOS-Extender Software war da dabei.



  • nn schrieb:

    knivil schrieb:

    Ja, aber daran kann ich mich nur schwammig erinnern.

    Ja, ich auch.

    Aber manche älteren Borland C++ (möglicherweise aber nicht die billigeren Turbos), konnten mit den DOS-Speichererweiterungen umgehen, das waren irgendwelche Einstellungen bei den Projektoptionen. Sollte auch in der zugehörigen Doku drin stehen.

    Insbesondere mit BC++ 4 und 5 gab es auch 32-Bit DOS-Programme, die konnten mehrere MB Arbeitsspeicher verwenden. Die entsprechende DOS-Extender Software war da dabei.

    BC++ 4 und höher lösen das 16 Bit Problem wohl nicht. Leider hatte Borland das
    Problem damals nur für Turbo-Pascal elegant gelöst. das gipfelte sogar darin,
    das Borland ensthaft vorgeschlagen hatte einen Turbo-Pascal Loader für Turbo-C
    zu verwenden - Nicht sehr praktikabel, aber möglich.

    OK. Das Know-How zu dem Thema findet sich "natürlich" im PC-Intern im Kapitel
    "Erweiterungsspeicher".

    @Mechanics: Die unselige Entscheidung von IBM den Speicher in "real-mode" auf
    maximal 640 kB festzulegen kommt zwar aus 1980 hat uns leider noch bis in die 90er begleitet.

    Also wenn man von DOS spricht ist Realmode mit gemeint und das begrenzt den
    Speicher auf 1MByte. 1985 kam man auf die Idee den Speicher über 640kByte
    als EMS-Speicher (Expandet Memory oder LIM-Standard) über ein verschiebbares
    Speicherfenster verfügbar zu machen.

    Zunächst muss man feststellen, ob EMS-Speicher sammt EMS-Treiber (EMM)
    installiert sind. Es wird also ein Treiber mit dem Namen EMMXXXX0 und
    Handler für den Interrupt 67h gesucht.
    Return-Wert ist TRUE, wenn EMS-Speicher installiert ist, sonst FALSE.

    BOOL ems_inst()
     {
      static char emm_name[] = { 'E', 'M', 'M', 'X', 'X', 'X', 'X', '0' };
      union REGS regs;       
      struct SREGS sregs;    
    
      regs.x.ax = 0x3567;               /* Fkt: Interruptvektor 0x67 holen */
      intdosx(&regs, &regs, &sregs);    /* den DOS-Interrupt 0x21 aufrufen */
      return !memcmp( MK_FP(sregs.es, 10), emm_name, sizeof emm_name );
     }
    

    *Der Code ist für den damals üblichen Borland-C geeignet.

    Die Funktionen des EMM sind bei Erfolg dann über den Interrupt 67h nutzbar.

    Als erstes wird die Gesamtanzahl der EMS-Pages ermittelt

    BYTE emm_ec;             /* EMM-Fehler-Code */
    int ems_num_page()
     {
      union REGS regs;    
    
      regs.h.ah = 0x42;                 /* Fkt: Anzahl der Pages ermitteln */
      int86(0x67, &regs, &regs);        /* EMM aufrufen */
      if ((int) (emm_ec = regs.h.ah))   
       return(-1);                      /* Fehler aufgetreten */
      else                              
       return( regs.x.dx );             /* Gesamtanzahl der Pages zurueck */
     }
    

    Dann kann man die Segmentadresse des EMS-Page-Frames ermitteln

    WORD ems_frame_seg()
     {
      union REGS regs;   
    
      regs.h.ah = 0x41;                 /* Fkt: Segmentadr. Page-Frame holen */
      int86(0x67, &regs, &regs);        /* EMM aufrufen */
      if ((int) (emm_ec = regs.h.ah))  
       return(EMS_ERR);                 /* Fehler aufgetreten */
      else                                
       return( regs.x.bx );             /* Segmentadresse zurueck */
     }
    

    Mit Funktion 0x43 kann man dann Pages allokieren und mit Fkt 0x44 kann man
    eine logische Seite auf eine physikalische Page mappen.
    Der Pointer auf die physikalische Seite berechnet dann sich wie folgt:

    #define PAGE_ADR(x) ((void *) MK_FP(ems_frame_seg() + ((x) << 10), 0))
    

    Daneben gab es noch Extendet Memory mit dem man den Speicher wie heute üblich
    "am Stück" ansprechen kann. Das funktioniert allerdings nur im Protected Mode.



  • Mechanics schrieb:

    Ich habe auch mal etwas für DOS programmiert, aber das ist schon sehr lange her, und schon damals hat DOS keine Sau interessiert. Aber es hatte einen gewissen Charme und war zu Windows 95 Zeiten halt noch nicht ganz tot.

    Auch später war DOS nicht so ganz tot. Ich habe in meiner Ausbildung (bis 2004) hauptsächlich DOS programmiert (CA-Clipper). Wir haben damit noch unser Geld verdient. Zu der Zeit schon eine absolute Ausnahme, zugegeben. 🙂



  • Überlege mal, ob Du nicht besser den Open-Watcom-Compiler dafür nimmst.
    Der bringt den DOS4GW-Extender mit, und dann kannst Du auf 32-Bit-Mode hoch und bis auf 16 MB linear durch programmieren. Entsprechende Beispiele sollten verfügbar sein. Der RealMode hat noch weitere Einschränkungen, die Du erst später merkst, z.B. Arraygrenzen von 64kb, enger Stack etc. Sowas nervt gewaltig.



  • Bitsy schrieb:

    ..., und dann kannst Du auf 32-Bit-Mode hoch und bis auf 16 MB
    linear durch programmieren. Entsprechende Beispiele sollten verfügbar sein.
    Der RealMode hat noch weitere Einschränkungen, die Du erst später merkst, z.B.
    Arraygrenzen von 64kb, enger Stack etc. Sowas nervt gewaltig.

    Da ist vermutlich einiges durcheinander geraten ...

    Es ist wohl richtig, das man Adressen bis zu 16 MB im 16-Bit Protected Mode und
    bis zu 4GB im 32-Bit Protected Mode verwenden könnte.

    http://de.wikipedia.org/wiki/Protected_Mode

    Im „16-Bit Protected Mode“ können maximal 16 MB physischer Hauptspeicher
    über 2 Tabellen mit jeweils 8192 Segmenten zu je maximal 64 KB angesprochen
    werden.

    Also hilft dieser 16-Bit Modus nicht wirklich.

    Allerdings verkomplizieren sich einige Dinge wie z.b. der Zugriff auf Hardware
    möglicherweise auch. Inwieweit BIOS-Aufrufe im Protected Mode nutzbar sind
    ist z.B. ein Aspekt.

    Wenn man Protected Mode unter DOS nutzen möchte ist der Watcom sicher ein
    interessanter Compiler.



  • Danke für die Tipps. Ich werde das Codebeispiel von merano gleich mal ausprobieren und auch mal ein Blick auf den Open-Watcom-Compiler werfen.



  • Da ist vermutlich einiges durcheinander geraten ..

    Das war ja auch ein Durcheinander damals!
    http://en.wikipedia.org/wiki/DOS/4G
    Limit zwar nicht 16 MB, aber 64 - ich wußte, da war was! 😉

    Ich weiß nicht, inwieweit sie die Umgebung weiterentwickelt haben.
    Jedenfalls war das damals noch ein richtiger Grabenkampf mit Makefiles und Batches. Angenehm war der Compiler nicht gerade. Aber er hatte eben die nötige Power. Ich mußte ihn im Wesentlichen nur in einem Projekt einsetzen - und das auch nur wegen einer dämlichen Grafikkarte. Da gab's doch damals dieses eine dickere Treiberpaket (univesa etc.) - mit dem kam der Watcom zurecht, TC nicht so...

    @Developer:
    Du könntest Dir auch noch ein DJGPP-Paket packen.
    http://www.delorie.com/djgpp/zip-picker.html
    Die RHIDE-Shell wurde nach der TC-Shell konzipiert, kaum Umgewöhnung also.
    Aber hier hättest Du auch direkt 32-bit-Code und merkst von den Speichergrenzen gar nichts mehr. Da gibt es dann auch noch die eine oder andere taugliche Lib um ordentlich an Grafik und Sound zu kommen. Also - wenn, dann dieser Compiler!

    Übrigens habe ich neulich mal versucht, den alten Krempel unter der DosBox in Win7 zu Laufen zu bringen. Das geht im Prinzip schon, nur hat die RHIDE saublöde Farben. Jemand eine Idee, wie ich in der DOSBox die Grundfarben ändere? Gute alte Ansi.sys? Nee, oder?


Anmelden zum Antworten