Mode X und EGA Parrallax

  • So, es ist vollbracht. Ich muss mal schauen, wann ich zum Aufnehmen komme, aber das Proof-Of-Concept Programm funktioniert.


    root42 auf YouTube


    80486DX@33 MHz, 16 MiB RAM, Tseng ET4000 1 MiB, GUSar Lite & TNDY & SnarkBarker, PC MIDI Card + SC55 + MT-32, XT CF Lite, OSSC 1.6

  • von root kommt ja bald was zum Thema EMS, ich habe jetzt angefangen das Thema XMS ab zu arbeiten.


    über einen Adress Call wird hier gearbeitet um im Speicher zu "basteln". Ich denke es sollte also schneller wie mit Interrupt arbeiten.

    Muss ich aber noch alles auf dem 3er testen.



    so habe angefangen ein Beispiel für XMS zu schreiben.

    in der >Main< werden schon alle Funktionen zum arbeiten mit XMS behandelt.


    Interessant hierbei, Borland C++ 3.1 reserviert sich den kompletten Speicher!!!!! Man muss also zur Ausführung den Compiler beenden und dann das Programm öffnen, ansonsten wird halt immer gemeckert das kein Speicher verfügbar ist.


    Ist alles noch was Chaotisch da es nur ein Test ist.





  • Interessant hierbei, Borland C++ 3.1 reserviert sich den kompletten Speicher!!!!! Man muss also zur Ausführung den Compiler beenden und dann das Programm öffnen, ansonsten wird halt immer gemeckert das kein Speicher verfügbar ist.

    Hier könnte es Sinn machen unter Windows zu entwickeln und zwei DOS Fenster zu öffnen...

    root42 auf YouTube


    80486DX@33 MHz, 16 MiB RAM, Tseng ET4000 1 MiB, GUSar Lite & TNDY & SnarkBarker, PC MIDI Card + SC55 + MT-32, XT CF Lite, OSSC 1.6

  • Hier diese Seite geht ganz gut auf das wesentliche ein. Ich denke das für die meisten Programme relevante wird erklärt.


    Bisher kann ich Speicher an einen Handler binden/reservieren, diesen wieder freigeben und schauen wieviel Speicher frei ist und wie grosß der größte Speicherblock an einem Stück ist.


    @root ...denke auch 2x Dosbox ist am einfachsten auf dem neuen. Beim 386 werde ich einfach Borland beenden, wobei ich dort seltener den Compiler anwerfe.

    Oder ich muss tricksen, Speicher reservieren, Compiler starten und welchen frei geben. Die Kiste hat 16MB Simms, eventuell funktioniert das auch.

  • @root ...denke auch 2x Dosbox ist am einfachsten auf dem neuen. Beim 386 werde ich einfach Borland beenden, wobei ich dort seltener den Compiler anwerfe.

    Oder ich muss tricksen, Speicher reservieren, Compiler starten und welchen frei geben. Die Kiste hat 16MB Simms, eventuell funktioniert das auch.

    Vorsicht! DosBox ist sehr picky was neue/veränderte Dateien angeht! Ich meinte wirklich ein Windows 3.1 oder 95 und dann DOS Fenster darin. Das sollte eigentlich auch sehr gut gehen. Das kannst du dann natürlich wiederum in DOSBox laufen lassen. Wenn zum Beispiel Dateien neu erstellt werden, während DOSBox schon läuft, dann sind die nicht sichtbar.

    root42 auf YouTube


    80486DX@33 MHz, 16 MiB RAM, Tseng ET4000 1 MiB, GUSar Lite & TNDY & SnarkBarker, PC MIDI Card + SC55 + MT-32, XT CF Lite, OSSC 1.6

  • ... so habe angefangen ein Beispiel für XMS zu schreiben ...

    Fängt gut an als XMS-Buchhaltungs-Beispiel :) Die wichtigste XMS Funktion für Nicht-Protected-Mode-Programme ist aber am Ende die XMS Kopierfunktion, um Speicherbereiche von oder nach XMS zu kopieren, hast du die auch schon getestet? :)


    Vielleicht kann man der Borland IDE sagen, dass sie einen Teil vom XMS freilassen soll für das zu entwickelnde Programm, oder dass sie maximal X Platz reservieren darf? Du kannst beim XMS Treiber ggf. auch mehr Handles anlegen mit geeigneten Optionen beim Treiberstart, falls nur deine Handles verbraucht sein sollten aber noch XMS Platz frei wäre. Schreibe ggf. eine Testfunktion in dein Programm, mit der die aktuell belegten Handles und ihre Details angezeigt werden.

  • So das XMS test Programm läuft dann soweit erstmal.


    es prüft ob ein XMS treiber vorhanden ist

    Code
    //prfen ob XMS-Treiber installiert
    asm{
        mov ax,4300h;
        int 2fh;
        //al=80h (128) = Treiber OK
        mov XMScheck,al;
    }
    //INFO >>
    print(1,2,8,"XMS treober aktiv (128 / 0x80 = OK) :");
    print(40,2,7,XMScheck);

    danach wird die Adresse vom XMS Handler erfragt


    danach wird keine interupt mehr verwendet.


    jetzt wird abgefragt wieviel speicher verfügbar ist und wie gross der grösste Block ist.


    Ein Block von 1000kb wird reserviert und dem Block wird ein Handler zugewiesen.



    danach kommt man in eine Schleife welche 2 funktionen hat.

    1. Inhalt der Variable test1 in den reservierten XMS Block kopieren

    2. Inhalt aus XMS Block kopieren nach Variable test2


    Im Programm wird der Inhalt von Variable test1 / test2 oben nebeneinander angezeigt.




    beim beenden wird der Block wieder frei gegeben.


    Code
    //XMS Handle frei geben
    if (XMShandle>0){
        asm{
            mov dx        ,XMShandle;//Handle welches frei gegeben werden soll
            mov ah        ,0Ah
            call XMSvec;
        }
    //INFO Block freigeben
    print(1,9,4,"XMS Handle frei gegeben");
    print(25,9,12,XMSbblock);


    ...man kann blöcke kopieren obwohl keiner reserviert wurde... das kann etwas unschön enden, weil hier dann in Handle 0 geschrieben, das sind die ersten 1MB...

    also darf funktion 7 nur verwendet werden wenn zuvor alles ohne Fehler durch lief.








    hier nochmal das ganze.

  • ich muss zum kopieren des XMS eine Offset Adresse angeben.

    Ich habe einen grundwertt von 0 und möchte dann über eine Variable sagen es soll ab dem X. byte kopiert werden.

    eine Variable kann ich scheinbar nicht hinter offset angeben ...dann nimmt er die Adresse von der Variable selber.


    ich habe das jetzt getrickst indem ich folgendes mache

    Code
    unsigned int nr = 10;
    
    asm{
    xor ax,ax;
    mov word ptr 6[si],offdset ax;
    
    mov ax,nr;
    add word ptr 6[si],ax;
    }




    was auch funktionierte war

    Code
    asm{
    mov word ptr 6[si],offdset 10;
    }


    aber ich muss da eine Variable hin bekommen anstelle eines festen wertes, da dieser sich ändert.

  • Die Zeilen sähen dann so aus oder?

    das Funktioniert so nicht.

    Code
        xor ax,ax;
        add ax,nr;
        mov word ptr  6[si],offset ax;


    ...hier nochmal das ganze

  • Ich brauche nochmal eure Hilfe.... bin mit Assembler noch nicht so fit und mir qualmt der Kopf vom ganzen Code umbauen.



    was ich machen möchte ...MXsp ist ein Pointer

    Code
    MXsp=&MXspriteT1[0][0];


    wenn ich den Code wie folgt schreibe wird scheinbar die Adresse des Pointers übergeben und nicht die Adresse der Variable worauf der Pointer zeigt.


    Wie kann ich die Adresse einer Variable über einen Pointer im Assembler Code übergeben?

    Code
    //    mov word ptr 12[si],offset MXsp;
    //    mov word ptr  14[si],seg MXsp;







  • Also da du unabsichtlich, aber erfolgreich die Adresse des Pointers statt seinen Wert übergeben hast, könntest du dem Pointer folgen und das Ergebnis wieder auf ds:[si+12] als Pointer abspeichern :)


    Evtl. hilft es auch einfach, mit & und [0] etc. zu spielen, also deinpointer[0] oder &deinpointer[0] oder &deinpointer oder so ähnlich zu verwenden, keine Ahnung wie sich bei Inline-Assembler C und Assembler Syntax mischen? Oder evtl. lässt man offset und seg weg? Sowas ist fürchte ich immer sehr Dialekt-abhängig.


    Siehe vielleicht auch https://stackoverflow.com/ques…rd-ptr-and-string#3488452

  • ...ich habe das Problem umgangen indem ich es nicht in Assembler sondern schon davor im Code angepasst hatte.

    Ich werde da noch einiges umstricken müssen.


    Immerhin konnte ich erste änderungen durchführen. Beim laden Wird geprüft ob XMS verfügbar ist.

    Dann werden 1,5MB reserviert in einem Handle!


    danach werden alle Texturen aus 20 Dateien in den Handle geschoben.


    Beim laden der Textur werden dann die alt bekannten Textur datenbanken vom XMS in die 4 Arrays geschoben.


    Das ganze funktioniert schonmal ganz gut.

    ...Kevin läuft auch wieder fröhlich durchs Bild. Dabei fällt mir auf Kevin frisst 15FPS beim 386... der ist ganz schön hungrig!



    ....jetzt muss ich BC nur noch dazu bewegen mir nicht den ganzen XMS zu klauen vor dem Start! das wäre ziemlich praktisch!


    Habe ein kleines tool welches XMS reserviert mit handler 1 bei Dosbox, anschliessend starte ich Borlande C++.

    Dann starte ich ein tool welches handle 1 frei gibt im compiler und anschliessend habe ich 4 MB frei ...geht so auf jeden fall schonmal!



    Edit ... die XMS Handler beim 386 sind auch komisch, der erste ist 2701, der Treiber sollte nur 32 Handle zur verfügung stellen wie kommt der da auf 2701?

    Bei Dosbox fängt der erste brav mit 1 an.

    Einmal editiert, zuletzt von Markus ()

  • Die Handlenummern sind je nach Treiber absichtlich nicht einfach 1, 2, 3. Letztendlich sind die Handles einfach wie zufällige 16-bit Werte zu behandeln. Du kannst bei verschiedenen Treibern auch gleich beim Laden mehr Handles für den Pool bereitlegen lassen, vielleicht reicht es dann auch ohne Tools und Tricks für Borland und das Spiel gleichzeitig? :)

  • Mein Problem ist das Borland beim starten einfach den kompletten speicher reserviert. Es sind 0KB über.


    Im grunde braucht man ja nur einen Handler für sein Programm.

    XMS Handler können ja extrem gross sein, da gibts keine 64kb Grenze.

  • Gut zu wissen, dass nicht die Anzahl der Handles das Problem ist. Dein Tool könnte also eine beliebige Menge XMS reservieren bevor die IDE startet und dann während die Borland IDE läuft wieder freigeben.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!