Das sind die kompletten XMS Funktionen...
XMShandle ist eine Globale Variable in der jedes mal ein Wert hinterlegt wird wenn ein XMS handle reserviert wird.
...Das Programm verselbständigte sich aber irgendwo und hat dort ab und an einfach den Handle 1 in andere Werte geändert.
Wenn man DOSBOX startet wird der erste Handle immer als 1 angelegt. zu testzwecken hatte ich deshalb einfach sturr gegen XMShandle !=1 geprüft um die Quelle des Fehlers zu finden.
Beim starten des Spiels kommt noch ohne Grafik ein Info Fenster
hier sieht man ob der XMS korrekt initialisiert wurde.
Wenn es zu fehlern kommt wird das Programm auch sofort beendet mit einer Rückmeldung.
Hier nochmal alle XMS Funktionen ...bis auf die Spiel spezifischen wo dann Texturen und Pixel abgefragt werden.
Variablen am Anfang sind Global da werden beim initialisieren Informationen über Fehler hinterlegt.
zusätzlich geben die Funktionen eine 1 zurück wenn alles korrekt funktioniert hat.
//###########################################################################
//XMS FUNKTIONEN 07.04.2024 - Version 1.0
// * * * *
// * * * * *
//
//###########################################################################
//include nur fr Main "Musterprogramm"
#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 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
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
Der Fehler welcher Auftrat war für mich nicht reproduzierbar, ich hatte Zeitweise alle Grafik Funktionen und alles drumherum was schon seit Monaten läuft deaktiviert und trotzdem wurde die Globale Variable XMShandle einfach von 1 auf was anderes geändert.
Ich habe jetzt Einstellungen im compiler geändert, seitdem scheint ruhe zu sein.
Jetzt werden alle Texturen korrekt kopiert und ich konnte auch die ziemlich vermurksten Test Funktionen durch die Funktionen aus dem MAP Editor ersetzen.
Ich hatte zwischendurch auch sturr die Adressen mitm Rechner ausgerechnet und als Zahl in der Funktion eingetragen, dann schredderter der mir trotzdem den Wert aus der XMShandle Variabel, das war schon sehr kurios.
Es läuft jetzt und alle Texturen werden korrekt angezeigt, also wurden die Adressen vorher auch eigentlich schon richtig hinterlegt.
Register Variables auf none gesetzt und der Code funktionierte wieder.
Merkwürdig ist nur das der Map Editor die selbe XMS Datei includiert und dabei lief alles mit den selben compiler einstellungen wobei das Spiel nicht läuft.
Mitlerweile läuft es ja zum Glück.
auf dem 386 habe ich noch ca. 13FPS wenn ich das Spiel zwinge bei jeder Textur anfrage diese aus dem XMS rüber zu kopieren.
Ich habe aber einen Textur Puffer für 62 Texturen erstellt, wo angefragte Texturen rein geladen werden vom XMS.
Bei einer Textur Anfrage wird geprüft ob eine Textur im Puffer ist oder nicht. Hierzu wird jeder Textur Nummer eine Speicherplatz Nummer hinterlegt 0 heisst nicht gepuffert.
Dann wird sie neu in den Puffer geladen bei einer Anfrage.
Der Puffer wechselt einfach beim laden immer einen Speicherplatz weiter.
Dadurch können zwar benötigte Texturen überschrieben werden, aber bei 62 Texturen kommt das dennoch selten genug vor so das eigentlich immer permanent die Sichtbaren Texturen sich im Puffer ansammeln und von dort aus verwendet werden.
Ich muss nur noch die Textur Speicherplätze von 8 bit auf 16bit ändern damit 65536 anstelle der bisherigen 256 (tatsächlich nur 200) Texturen verwendet werden können, der Rest ist schon im editor und im Spiel Funktioniert schon.
Somit kann man zu jeder Zeit jede Textur überall für verwenden.
Wenn ich jetzt noch den Char Speicher anpasse und den Chars noch 60 Plätze zum Puffern gebe dann habe ich im unteren Speicher auf einmal wieder ca. 348kb mehr zur verfügung. >420KB sind dann noch frei, das sollte dann für den Rest noch locker reichen.
Und ich kann mir 100 Charaktere basteln wenn ich lust und Laune habe sind 2,052MB im Speicher 2000 Texturen. Das sollte reichen.