....wenn ich beim initialisieren der Variable =0 weg lasse dann Funktioniert es ohne Fehler.
wenn ich im Compiler Register Variables auf none stelle, dann funktioniert es auch.
Ist das zufall oder hat hier der Compiler meine Variable geschreddert?
....wenn ich beim initialisieren der Variable =0 weg lasse dann Funktioniert es ohne Fehler.
wenn ich im Compiler Register Variables auf none stelle, dann funktioniert es auch.
Ist das zufall oder hat hier der Compiler meine Variable geschreddert?
momentan schaut es so aus.
Texturen in den speicher laden
int XMStex(){
FILE *ifs;
char datei[10];
unsigned int Nr=1;//
do{
//9-8-10-10
//1-2-3-4 (4=11!)
itoa(Nr,datei,10);
strcat(datei,".tex");
ifs=fopen(datei,"rb");
if (! ifs) fclose(ifs);else{
unsigned char *MXSP = &MXsprite[0][0];
fread(MXSP,1,51300,ifs);//51300??
fclose(ifs);
unsigned long sa=51300*(Nr-1);
XMScopy(0 ,FP_OFF(MXsprite),FP_SEG(MXsprite),XMShandle,sa,sa>>16,51300);
}
Nr++;
}while(Nr<10);
//XMScopy(XMShandle,0,0,0 ,FP_OFF(MXsprite),FP_SEG(MXsprite),51300);
}
//<<<<<
Alles anzeigen
Diese Funktion gibt die kopier anweisung
unsigned char far *getsprite(unsigned int TNr) //TNr ist die Textur Nummer
{
unsigned long DCa=TNr;
DCa=DCa*1026;
if (XMShandle!=1) Xprint(28,10,14,"XMSHANDLE");//Speicherbedarf am Anfang anzeigen
if (XMShandle!=1) Xprint(28,30,12,TNr);//Speicherbedarf am Anfang anzeigen
XMShandle=1;//wird einfach korrigiert damit das Programm beim testen nicht abstürzt oder grösseren mist macht...
XMScopy(XMShandle,(DCa<<16)>>16,DCa>>16,0 ,FP_OFF(&MXsprite[55][0]),FP_SEG(&MXsprite[55][0]),1026);
return(&MXsprite[55][0]);
}
//<<<<<
Alles anzeigen
Das ist die aufgerufene Funktion. ...es funktioniert halt irgendwie fast immer bei gewissen Adressen schreibt es aber den XMShandle um...
//###########################################################################
int XMScopy(unsigned int XMSqh ,unsigned int XMSqo,unsigned int XMSqs,unsigned int XMSzh,unsigned int XMSzo,unsigned int XMSzs,unsigned long XMSb ){
unsigned int XMSbl=XMSb;
unsigned int XMSbh=XMSb>>16;
asm{
//L„nge gerade Zahl!!
mov ax,XMSbl ;//Byte low
mov word ptr 0[si] ,ax ;
mov ax,XMSbh; ;//Byte high
mov word ptr 2[si] ,ax ;
//QUELLE
mov ax,XMSqh ;//Quell Handle
mov word ptr 4[si],ax ;
mov ax ,XMSqo ;//Offset
mov word ptr 6[si],ax ;
mov ax ,XMSqs ;//Segment
mov word ptr 8[si],ax ;
//ZIEL
mov ax,XMSzh ;//Ziel Handle
mov word ptr 10[si],ax ;//Ziel 0 = unterer Speicherbereich
mov ax ,XMSzo ;//offset ...bei handle >0 dann die 16low bits
mov word ptr 12[si],ax ;
mov ax ,XMSzs ;//Segment ...bei handle >0 dann die 16high bits
mov word ptr 14[si],ax ;
mov ah,0Bh ;
call XMSvec ;//Funktions Aufruf XMS Treiber
mov XMStest,ax ;//Antwort Treiber (1=OK)
mov XMSfehler,bl ;//Fehlercode
}
return(XMStest);
}
//###########################################################################
Alles anzeigen
was komisch ist, ich schreibe immer in die selben Ziel adressen, aber manchmal schreibt er scheinbar wo anders rein.
Anscheinend tritt der Fehler ab Textur 139 bis 154 auf...danach 155 Funktioniert wieder...alles ziemlich merkwürdig. Ich verstehs nicht wirklich.
das hatte ich gestern schon versucht, irgendwie reserviert er immer alles egal was ich da eingebe.
Momentan ärgert mich auch der Code ein wenig, der umbau vom Map Editor funktioniert bisher reibungslos. Aber im Spiel wird der Inhalt der Variable XMShandle ab und an verändert obwohl es keinen befehlt gibt der das macht.
Das Problem tritt immer bei kopieren auf, wenn die Quelladresse gewisse Werte hat.
Wenn ich als Quelle den richtigen Handle wähle und als ersten Byte im Speicher 142614 >> müsste dann Offset 11542 / Segment 2 sein. Dann tritt der Fehler auf. Bei niedrigeren Adressen und teilweise bei höheren tritt der Fehler nicht auf.
Merkwürdig das der Fehler auftritt wenn ich die Quelladresse ändere, die Zieladresse bleibt immer gleich. Also dürfte ja eigentlich nichts überschrieben werden, weil ich ja nur wo anders lese.
der Reservierte XMS Speicher ist 1,5MB groß wovon lediglich 300kb belegt sind.
Merkwürdig ist, wenn ich die Variable XMShandle später initialisiere (ein Array von 909 Chars habe ich jetzt einfach davor zuteilen lassen) dann tritt der Fehler nicht auf.
Hierdurch ändert sich ja die Adresse der Variable... also scheint irgendwas die Adresse gezielt zu überschreiben.
Die Hilfe zeigt nur das hier an
getestet hatte ich es nur mitm Borland bisher.
Jo Borland ist halt Borland.
Die hatten immer eine brauchbare IDE und auch sonst läuft der compiler schön stabil.
Wenn man XMS / EMS nutzen will, muss man vorm start einfach reservieren... wüsste jetzt nicht das man den compiler mit hausmitteln daran hindern kann einfach alles beim start zu reservieren was frei ist.
Grössere Software Projekte für Dos denke ich sind eher selten.
Bei Amiga / C64 wird vermutlich mehr los sein.
Aber ich arbeite gerne mit den alten 16 bit compilern, Basic und die Borland compiler mag ich einfach.
Es muss ja nicht schnell fertig werden und auf so alten Kisten macht das optimieren meist irgendwo Spaß.
Bis auf das eine mal wo der compiler die Festplatte komplett zerlegt hatte war alles immer ok ...kann unter DOS passieren.
Deshalb wird der 386DX40 Rechner nur zum entwickeln und testen verwendet. Zum spielen gibts nen andern 386.
Selber 8 Karten zu bunkern und dann von gierig zu sprechen, wenn ich mir eine 2. passende mal von meinem ehrlich verdienten Geld kaufe.
Finde ich jetzt nicht so prickelnd...
Ich bin dann mal so frei.
Ich habe jetzt soweit alle wichtigen Routinen in diese Funktions Sammlung gesteckt.
Damit kann man alles wichtige machen.
Unten in der Main ist dann ein Beispielprogramm welches folgendes macht.
XMS Treiber prüfen
XMS Manager Adresse abfragen
XMS Handle reservieren
Die ersten 10 Byte des Char Array Text1 in den reservierten XMS Handle kopieren
Die 10 byte vom reservierten XMS Handle kopieren in das Char Array Text2
Den reservierten XMS handle wieder frei geben
ENDE!
Man kann das Programm so nicht von den meisten compilern starten, weil diese während der Ausführung meist selber den kompletten speicher reservieren!
...ich umgehe das Problem indem ich vor dem Ausführen XMS reserviere und dann vom compiler aus den Handler mit einem toll wieder frei gebe, dann kann man auch vom compiler aus den Code ausführen.
...testen und experimentieren auf eigene Gefahr.
//###########################################################################
//XMS FUNKTIONEN 07.04.2024 - Version 1.0
// * * * *
// * * * * *
//
//###########################################################################
#include <conio.h> //clrscrn | getch
#include <stdio.h> //printf
#include <dos.h> //FP_OFF FP_SEG
//verwendete globale Variable
//###########################################################################
unsigned char XMSok=0; //Fehler ja(128) / Nein(0)
unsigned char XMStreiber=0; //XMS treiber ???
char XMSvec[4]; //XMS-Treiber Verctor Adresse
unsigned int XMStest=0; //Antwort bei anfragen
unsigned char XMSfehler=0; //Ablage fr Fehler
unsigned int XMShandle=0; //XMS-Handle fr einen angeforderten Speicherblock
unsigned int XMSkb=0;//XMS-Frei
unsigned int XMSkbblock=0;//gr”sster verfgbarer XMS Block an einem Stck
//Funktionen
//###########################################################################
int XMSini();
int XMSinfo();
int XMSsethandle(unsigned int XMSkbres);
int XMSfreehandle(unsigned int XMSfh);
int XMScopy(unsigned int XMSqh ,unsigned int XMSqo,unsigned int XMSqs,unsigned int XMSzh,unsigned int XMSzo,unsigned int XMSzs,unsigned long XMSb);
int XMS(unsigned int XMSsetkb);
//###########################################################################
//###########################################################################
//XMS-Treiber suchen und Adresse abfragen
//Hinterlegt werte in:
// XMScheck =Treiber geladen=128!
// XMStreiber =Treiber Variante Info?
// XMSvec =XMS Treiber Vector Adresse
//###########################################################################
int XMSini(){
//>>>>>prfen ob XMS Treiber aktiv
asm{
mov ax,4300h;
int 2fh;
mov XMSok,al ;//Treiber OK=128
mov XMStreiber,ah ;//Treiber Variante Info
}
if (XMSok != 128) return(0);//wenn treiber fehler return(0)
//<<<<<
//XMS Treiber Adresse abfragen>>>>>
asm{
mov ax,4310h;
int 2fh;
mov word ptr XMSvec,bx;
mov word ptr XMSvec +2,es;
}
return(1);
}
//###########################################################################
//###########################################################################
//XMS-freien Speicher abfragen
//Hinterlegt werte in:
// XMSkb =verfgbarer Speicher in KB
// XMSkbblock =gr”sster verfgbarer Speicherblock in KB
//###########################################################################
int XMSinfo(){
asm{
mov ah ,8;
call XMSvec; //anfordern
mov XMSkb ,dx; //verfgbarer XMS in Kbytes
mov XMSkbblock ,ax; //gr”sster noch freier zusammenh„ngender XMS-Block
}
return(1);
}
//###########################################################################
//###########################################################################
//XMS Speicher-Handle-zuteilen
// speicher in KB reservieren
//Hinterlegt werte in:
// XMStest =1=OK / 0=Fehler
// XMShandle =vergebener XMS handler
// XMSfehler =Fehlercode
//###########################################################################
int XMSsethandle(unsigned int XMSkbres){
asm{
mov dx ,XMSkbres; //ben”tigte Gr”sse
mov ah ,9;
call XMSvec; //anfordern
mov XMStest ,ax; //1=OK / 0=Fehler
mov XMShandle ,dx; //zurckgegebener Handle fr den angefragten XMS-Speicher
mov XMSfehler ,bl; //Fehlermeldung 160=kein speicher frei!
}
return(XMStest);
}
//###########################################################################
//###########################################################################
//XMS Speicher-Handle-freigeben
// Handle Nummer die freigegeben werden soll
//###########################################################################
int XMSfreehandle(unsigned int XMSfh){
if (XMSfh>0){
asm{
mov dx ,XMSfh;//Handle welches frei gegeben werden soll
mov ah ,0Ah
call XMSvec;
}
return(1);
}
return(0);
}
//###########################################################################
//###########################################################################
//XMS/Speicher kopieren
//Quelle Handle
//Quelle offset
//Quelle segment
//Ziel Handle
//Ziel offset
//Ziel segment
//Byte gr”sse kopieren low
//Byte gr”sse kopieren high ((high*65536)+low)
//Hinterlegt werte in:
// XMStest =//OK=1 / 0=Fehler
// XMSfehler =//Fehlercode
//###########################################################################
int XMScopy(unsigned int XMSqh ,unsigned int XMSqo,unsigned int XMSqs,unsigned int XMSzh,unsigned int XMSzo,unsigned int XMSzs,unsigned long XMSb ){
unsigned int XMSbl=XMSb;
unsigned int XMSbh=XMSb>>16;
asm{
//L„nge gerade Zahl!!
mov ax,XMSbl ;//Byte low
mov [si] ,ax ;
mov ax,XMSbh; ;//Byte high
mov 2[si] ,ax ;
//QUELLE
mov ax,XMSqh ;//Quell Handle
mov word ptr 4[si],ax ;
mov ax ,XMSqo ;//Offset
mov word ptr 6[si],ax ;
mov ax ,XMSqs ;//Segment
mov word ptr 8[si],ax ;
//ZIEL
mov ax,XMSzh ;//Ziel Handle
mov word ptr 10[si],ax ;//Ziel 0 = unterer Speicherbereich
mov ax ,XMSzo ;//offset
mov word ptr 12[si],ax ;
mov ax ,XMSzs ;
mov word ptr 14[si],ax ;//Segment
mov ah,0Bh ;
call XMSvec ;//Funktions Aufruf XMS Treiber
mov XMStest,ax ;//Antwort Treiber (1=OK)
mov XMSfehler,bl ;//Fehlercode
}
return(XMStest);
}
//###########################################################################
//###########################################################################
//XMS ini / info / sethandle
//Speicher in KB der reserviert werden soll
//###########################################################################
int XMS(unsigned int XMSsetkb){
//XMS treiber prfen ob verfgbar und Adresse auslesen
XMSini();
//verfgbarer speicher abfragen
XMSinfo();
//wenn Freier Block gr”sse XMSsetkb verfgbar, reservieren
if (XMSkbblock>=XMSsetkb) XMSsethandle(XMSsetkb);
//Anzeige Infoblock
clrscr();
printf("XMS Manager 1.05(C) 2024 Markus Willems\n");
printf("-------------------------------------------------------------------------------\n");
printf("XMS Treiber Aktiv (128) ..:%i\n",XMSok);
printf("XMS (67) .................:%i\n",XMStreiber);
printf("XMS Treiber Adresse ......:%i\n",XMSvec);
printf("-------------------------------------------------------------------------------\n");
printf("Freier XMS speicher gesamt:%i\n",XMSkb);
printf("Freier XMS gr”sster Block :%i\n",XMSkbblock);
printf("-------------------------------------------------------------------------------\n");
printf("reservierter XMShandle ...:%i\n",XMShandle);
printf("\n\nWaitkey.....\n");
//warten auf Tastendruck
getch();
if (XMShandle>0) return(1); else return(0);
}
//###########################################################################
/*
void main(){
XMS(1024);
//###########################################################################
if (XMShandle > 0){
char text1[50]="A123456789B123456789C123456789D123456789E123456789";
char text2[50]="FEHLER";
//kopiert von Variable in XMS
XMScopy(0 ,FP_OFF(text1),FP_SEG(text1),XMShandle,0,0,10);
//kopiert von XMS nach Variable
XMScopy(XMShandle ,0,0,0,FP_OFF(text2),FP_SEG(text2),10);
printf("%s\n",text1);
printf("%s\n",text2);
}
printf("\n\nTASTE ZUM BENDEN DRšCKEN\n");
getch();
//Speicher + Handle wieder freigeben beim beenden
if (XMShandle>0) XMSfreehandle(XMShandle);
}
*/
Alles anzeigen
150 Euro. war halt eine Baugleiche. Für ein SLI Pärchen bezahlt man sonst gerne 500-800€.
Mir fehlt nur noch das KAbel zum verbinden das sollte ja nicht das Problem werden.
Habe gestern das Pentium 60 Board von Matze bekommen.
Heute kam noch die bestellte Diamnond Voodoo 2 Karte an, eine baugleiche hatte ich ja schon.
Dann kann ich mal SLI testen in einem System.
habe ich noch nicht gemacht... c++ ist halt ziemliches Neuland für mich.
...hatte gestern 6 Stunden an dem Code gebastelt und am ende dann festgestellt das der Compiler sich irgendwo was verstellt hatte und deshalb immer alles abstürzte.
Wenn du ein Beispiel hast immer gerne her damit.. sonst muss ich wieder suchen.
Der Compiler ärgert mich mal wieder wo er nur kann.
ich muss einer Funktion eine Variable übergeben damit die Funktion auf dessen Adresse zugreift.
Wenn ich das über Pointer versuche, wird die Adresse der Pointer übergeben.
Kann machen was ich will es Funktioniert nicht.
Ich bin jetzt so weit das ich den Adresswert als HEX oder dezimal übergebe, weil es anders komplett unmöglich erscheint.
Nur finde ich bei der Lösung keinen Wert die Adresse einer Variable in einer anderen Variable als unsigned long Wert zu übergeben.
mir fällt einfach keine Lösung ein und ich finde im Netzt absolut garnichts wie man an die Adresse als zahlen Wert kommen kann.
Ich werde jetzt wohl erstmal eine Funktionssammlung zusammen stellen, welche ich dann Programmübergreifend nutzen kann.
Danach muss ich dann schauen das ich den MAP Editor anpasse damit ich dann Texturen frei wählen kann nach lust und laune.
Und dan brauche ich noch Funktionen die den Speicher verwalten in dem Texturen innerhalb der unteren 640kb abgelegt werden die ständig genutzt werden.
Mir wird nicht langweilig...
ich habe heute einen ersten Teslauf auf dem 386 gemacht mit einem Testprogramm.
Das Testprogramm ist das Spiel ...wobei bei jedem Frame zusätzlich noch 2 Texturen 2048 Byte vom XMS in den unteren Speicher bereich kopiert werden. Ich hätte hier jetzt eigentlich mit frame einbrüchen gerechnet zumal das Programm normalerweise 36-37 FPS macht wenn kein NPC durchs Bild läuft und der Char steht... was soll ich sagen, wenn ich bei jedem Frame die 2 Texturen im XMS verschiebe verliere ich KEIN FPS!!!
Also können locker 36-37 Aufrufe an den XMS Manager gesendet werden zum kopieren von jeweils 2 Texturen = 74 Texturen innerhalb einer Sekunde ohne das das System merklich an geschwindigkeit verliert.
Testrechner war wie fast immer der 386DX40 mit 8MB Ram wovon 1MB mit XMS genutz werden!
Ich hätte hier schon erwartet das die geschwindigkeit irgendwo einbricht... dem ist nicht so!
...genau mein Programm schnappt einen Handle und reserviert einfach einen 4MB Block.
Dann starte ich Borland, das schnappt sich alles was zu bekommen ist.
Jetzt muss man nur noch mit dem 1. Programm was man startet den speicher Handle wieder frei geben und ich habe 4MB XMS wieder frei.
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.
...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.
bald kannst du ein Floppotron bauen aus 5 Zoll LAufwerken.
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
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?
MXsp=&MXspriteT1[0][0];
asm{
//L„nge gerade Zahl!!
mov ax,51300;
mov [si] ,ax ;
mov ax,0;
mov 2[si] ,ax ;
//QUELLE
mov ax,XMShandle;
mov word ptr 4[si],ax ;
mov word ptr 6[si],0;
mov word ptr 8[si],0;
//ZIEL
mov word ptr 10[si],0 ;
//Funktioniert
mov word ptr 12[si],offset MXspriteT1[0][0];
mov word ptr 14[si],seg MXspriteT1[0][0];
//Funktioniert nicht
// mov word ptr 12[si],offset MXsp;
// mov word ptr 14[si],seg MXsp;
//Funktion / Aufruf
mov ah,0Bh;
call XMSvec ;
mov XMStest,ax ;//1=OK
mov XMSfehler,bl ;//Fehlermeldung 160=kein speicher frei!
}
Alles anzeigen