So, es ist vollbracht. Ich muss mal schauen, wann ich zum Aufnehmen komme, aber das Proof-Of-Concept Programm funktioniert.
So, es ist vollbracht. Ich muss mal schauen, wann ich zum Aufnehmen komme, aber das Proof-Of-Concept Programm funktioniert.
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.
//prfen ob XMS-Treiber installiert
if (ch=='1'){
asm{
mov ax,4300h;
int 2fh;
//al=80h (128) = Treiber OK
mov XMScheck,al;
}
}
//XMS Handler Adresse erfragen
if (ch=='2'){
asm{
//xmsvec dd ?
mov ax,4310h;
int 2fh;
//
mov word ptr XMSvec,bx;
mov word ptr XMSvec +2,es;
}
}
//XMS Allocate Memory "Handle reservieren"
if (ch=='3'){
unsigned int kbytes=10;//KB anfragen
asm{
mov dx ,kbytes; //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!
}
}
//XMS freien speicher abfragen
if (ch=='4'){
asm{
mov ah ,8;
call XMSvec; //anfordern
mov XMSfree ,dx; //verfgbarer XMS in Kbytes
mov XMSbblock ,ax; //gr”sster noch freier zusammenh„ngender XMS-Block
}
}
//XMS Handle frei geben
if (ch=='5'){
asm{
mov dx ,XMShandle;//Handle welches frei gegeben werden soll
mov ah ,0Ah
call XMSvec;
}
}
Alles anzeigen
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream.h>
#include <stdio.h>
#include <dos.h>
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
void print(int XPx , int XPy,int XPc,long XPt)
{
gotoxy(XPx, XPy);
textcolor(XPc);
char MXct[33];
ltoa(XPt,MXct,10);
cprintf(MXct);
}
void print(int XPx , int XPy,int XPc,char XPt[80])
{
gotoxy(XPx, XPy);
textcolor(XPc);
cprintf(XPt);
}
char C_text[40];//Text (39 Zeichen!!!!)
unsigned char C_typ;//Text (39 Zeichen!!!!)
unsigned char C_ziel;//Text (39 Zeichen!!!!)
unsigned char C_id;//Text (39 Zeichen!!!!)
char Dia_text[64][16][40];//Text (39 Zeichen!!!!)
unsigned char Dia_typ[64][16];//Text (39 Zeichen!!!!)
unsigned char Dia_ziel[64][16];//Text (39 Zeichen!!!!)
unsigned char Dia_id[64][16];//Text (39 Zeichen!!!!)
unsigned char Bl=0;
unsigned char Ze=0;
unsigned char tabX;
unsigned char tabY=0;//Zeile darstellung
unsigned char ch=0;
unsigned char CuX=0;
unsigned char CuY=0;
void DATAreset(){
Ze=0;
Bl=0;
do{
do{
Dia_typ [Bl][Ze]=0;
Dia_ziel[Bl][Ze]=0;
Dia_id [Bl][Ze]=0;
strcpy (Dia_text[Bl][Ze],"");
Ze++;
} while(Ze<16);
Ze=0;
Bl++;
} while(Bl<64);
Bl=0;
Ze=0;
}
//############################ MXprintc(x,y,Color,"Char-Array") #############################
int input(int MXx , int MXy,int MXcolor,char MXc[41],char MXmax){
unsigned char Zeichen;
unsigned char oZeichen;
unsigned char ch;
char MXc2[2]=" ";
MXc2[1]=0;
Zeichen=0;
oZeichen=0;
ch=0;
char MXpage=0;
print(MXx,MXy,MXcolor,MXc);
gotoxy(MXx+Zeichen,MXy);
do
{
//tasteneingabe >>>>>
if (kbhit() )
{
ch=getche();
// Return > beenden
if (ch==13) return(13);
// Escape > beenden
if (ch==27) return(27);
// Zeichen Eingabe ASCII 32-175
if (ch>=32 && ch<=175 && Zeichen<MXmax)
{
//Zeichen aufschieben>>>>>
unsigned char MXinput=MXmax-1;
do{
MXc[MXinput]=MXc[MXinput-1];
MXinput=MXinput-1; //=MXmax-1;
}while (MXinput>Zeichen);
//<<<<<
MXc[Zeichen]=ch;
Zeichen++;
}
// <-
if (ch ==8 && Zeichen>0)
{
Zeichen=Zeichen-1;
//Zeichen < nachrcken>>>>>
unsigned char MXinput=Zeichen;
do{
MXc[MXinput]=MXc[MXinput+1];
MXinput=MXinput+1; //=MXmax-1;
}while (MXinput<MXmax);
MXc[MXmax]=0;
//<<<<<
}
//Sonderzeichen folgt>>>>>
if (ch ==0)
{
//Folgezeichen
ch=getche();
//Entf |<<
if (ch ==83 && Zeichen<MXmax)
{
//Zeichen < nachrcken>>>>>
unsigned char MXinput=Zeichen;
do{
MXc[MXinput]=MXc[MXinput+1];
MXinput=MXinput+1; //=MXmax-1;
}while (MXinput<MXmax);
MXc[MXmax]=0;
//<<<<<
}
//Cursor <
if (ch =='K' && Zeichen>0)
{
Zeichen=Zeichen-1;
}
//Cursoe >
if (ch =='M' && Zeichen<MXmax)
{
if (MXc[Zeichen]>0) Zeichen=Zeichen+1;
}
//springen Pos1
if (ch ==71)
{
Zeichen=0;
}
//springen Ende text
if (ch ==79)
{
do{
Zeichen++; //=MXmax-1;
}while (MXc[Zeichen]>0 && Zeichen<MXmax);
}
}
//<<<<<
print(MXx,MXy,MXcolor," ");
print(MXx,MXy,MXcolor,MXc);
gotoxy(MXx+Zeichen,MXy);
if (Zeichen<MXmax+1)
{
//MXline((MXx<<2)+((Zeichen)<<3),MXy+8+MXpage+200,(MXx<<2)+((Zeichen)<<3)+6,MXy+8+MXpage+200,MXcolor);
}
if (oZeichen !=Zeichen && oZeichen < MXmax+1)
{
//MXline((MXx<<2)+((oZeichen)<<3),MXy+8+MXpage+200,(MXx<<2)+((oZeichen)<<3)+6,MXy+8+MXpage+200,MXcolor2);
}
oZeichen=Zeichen;
}
} while(ch != '13');
}
//<<<<<
unsigned char XMScheck=0; //XMS verfgbar (80h = OK)
char XMSvec[4]; //Adresse XMS-Handler
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 XMSfree=0;//XMS-Frei
unsigned int XMSbblock=0;//gr”sster verfgbarer XMS Block an einem Stck
//######################################################################################
int main(void)
{
Anfang:
clrscr();
CLSAnfang:
//prfen ob Treiber geladen
print(1,2,8,"1=XMS Prfen");
print(20,2,8,XMScheck);
//Handler erfragt
print(1,3,8,"2=XMS Handler");
print(20,3,8,XMSvec);
//Anfrage
print(1,4,8,"3=XMS Anfrage");
print(20,4,8,XMStest);
print(30,4,8,XMSfehler);
print(40,4,8,XMShandle);
//verfgbarer speicher
print(1,5,8,"4=XMS verfgbar");
print(20,5,8,XMSfree);
print(30,5,8,XMSbblock);
//verfgbarer speicher
print(1,5,8,"5=XMS Handle freigeben");
ch=getch();
if (ch==0) ch=getch()+128;
//prfen ob XMS-Treiber installiert
if (ch=='1'){
asm{
mov ax,4300h;
int 2fh;
//al=80h (128) = Treiber OK
mov XMScheck,al;
}
}
//XMS Handler Adresse erfragen
if (ch=='2'){
asm{
//xmsvec dd ?
mov ax,4310h;
int 2fh;
//
mov word ptr XMSvec,bx;
mov word ptr XMSvec +2,es;
}
}
//XMS Allocate Memory "Handle reservieren"
if (ch=='3'){
unsigned int kbytes=10;//KB anfragen
asm{
mov dx ,kbytes; //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!
}
}
//XMS freien speicher abfragen
if (ch=='4'){
asm{
mov ah ,8;
call XMSvec; //anfordern
mov XMSfree ,dx; //verfgbarer XMS in Kbytes
mov XMSbblock ,ax; //gr”sster noch freier zusammenh„ngender XMS-Block
}
}
//XMS Handle frei geben
if (ch=='5'){
asm{
mov dx ,XMShandle;//Handle welches frei gegeben werden soll
mov ah ,0Ah
call XMSvec;
}
}
//if (ch=='n'){
//gotoxy(1, 20);
//cin>>Dia_text[Bl][Ze];
//}
if (ch!=27) goto Anfang;
clrscr();
print(25,10,12,"Programm Beenden (ESC) (ENTER)?");
if (input(1,14,1,"",0)!=13) goto Anfang;
clrscr();
print(1,1,7,"Cu");
return 0;
}
Alles anzeigen
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...
Ich erinnere in Sachen XMS auch mal an meinen früheren Beitrag hier: Turbo Pascal 4.0/5.0 und XMS Nutzung - Testprogramm läuft, aber...
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.
... so habe angefangen ein Beispiel für XMS zu schreiben ...CodeAlles anzeigen//prfen ob XMS-Treiber installiert if (ch=='1'){ asm{ mov ax,4300h; int 2fh; //al=80h (128) = Treiber OK mov XMScheck,al; } } //XMS Handler Adresse erfragen if (ch=='2'){ asm{ //xmsvec dd ? mov ax,4310h; int 2fh; // mov word ptr XMSvec,bx; mov word ptr XMSvec +2,es; } } //XMS Allocate Memory "Handle reservieren" if (ch=='3'){ unsigned int kbytes=10;//KB anfragen asm{ mov dx ,kbytes; //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! } } ...
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.
es macht noch nicht so ganz was es soll, die Rückmeldungen sind komisch. Bin aber jetzt auch zu verpennt um das fertig zu machen.
So das XMS test Programm läuft dann soweit erstmal.
es prüft ob ein XMS treiber vorhanden ist
//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
//XMS Handler Adresse erfragen
asm{
mov ax,4310h;
int 2fh;
//
mov word ptr XMSvec,bx;
mov word ptr XMSvec +2,es;
}
//INFO Adresse >>
print(1,3,8,"XMS Adresse :");
print(40,3,7,XMSvec);
Alles anzeigen
danach wird keine interupt mehr verwendet.
jetzt wird abgefragt wieviel speicher verfügbar ist und wie gross der grösste Block ist.
//XMS freien speicher abfragen
asm{
mov ah ,8;
call XMSvec; //anfordern
mov XMSfree ,dx; //verfgbarer XMS in Kbytes
mov XMSbblock ,ax; //gr”sster noch freier zusammenh„ngender XMS-Block
}
//INFO Freier Speicher/Bl”cke
print(1,5,8,"XMS freier speicher");
print(21,5,7,XMSfree);
print(30,5,8,"XMS gr”sster Block");
print(49,5,7,XMSbblock);
Alles anzeigen
Ein Block von 1000kb wird reserviert und dem Block wird ein Handler zugewiesen.
//XMS Allocate Memory
unsigned int kbytes=1000;//KB anfragen
asm{
mov dx ,kbytes; //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!
}
//INFO Block reservieren
print(1,7,8,"XMS reservieren");
print(1,7,8,"XMS 1=OK/0=Fehler");
print(19,7,7,XMStest);
print(30,7,8,"XMS Fehlercode");
print(45,7,7,XMSfehler);
print(60,7,8,"XMS Handle");
print(71,7,7,XMShandle);
//
fehler(XMSfehler);
print(1,8,14,Fehler);
Alles anzeigen
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.
//kopieren XMS > X
if (ch=='7'){
unsigned int XMSl_L=8;
unsigned int XMSl_H=0;
asm{
//L„nge gerade Zahl!!
mov ax,XMSl_L;
mov [si] ,ax ;
mov ax,XMSl_H;
mov 2[si] ,ax ;
//QUELLE
mov ax,XMShandle;
mov word ptr 4[si],ax ;
mov word ptr 6[si],offset 0 ;
mov word ptr 8[si],seg 0 ;
//ZIEL
mov word ptr 10[si],0 ;
mov word ptr 12[si],offset &test2;
mov word ptr 14[si],seg &test2 ;
//Funktion / Aufruf
mov ah,0Bh;
call XMSvec ;
mov XMStest,ax ;//1=OK
mov XMSfehler,bl ;//Fehlermeldung 160=kein speicher frei!
}
fehler(XMSfehler);
print(1,12,14,"X > XMS");
print(9,12,12,XMSfehler);
print(30,12,14,"AX1=OK");
print(39,12,14,XMStest);
print(1,13,14,Fehler);
}
//kopieren X > XMS
if (ch=='6'){
unsigned int XMSl_L=8;
unsigned int XMSl_H=0;
asm{
//L„nge gerade Zahl!!
mov ax,XMSl_L ;
mov [si] ,ax ;
mov ax,XMSl_H ;
mov 2[si] ,ax ;
//QUELLE
mov word ptr 4[si],0 ;
mov word ptr 6[si],offset &test1;
mov word ptr 8[si],seg &test1 ;
//ZIEL
mov ax,XMShandle
mov word ptr 10[si],ax ;
mov word ptr 12[si],offset 0 ;
mov word ptr 14[si],seg 0 ;
//Funktion / Aufruf
mov ah,0Bh;
call XMSvec ;
mov XMStest,ax ;//1=OK
mov XMSfehler,bl ;//Fehlermeldung 160=kein speicher frei!
}
fehler(XMSfehler);
print(1,12,14,"X > XMS");
print(9,12,12,XMSfehler);
print(30,12,14,"AX1=OK");
print(39,12,14,XMStest);
print(1,13,14,Fehler);
}
Alles anzeigen
beim beenden wird der Block wieder frei gegeben.
//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.
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream.h>
#include <stdio.h>
#include <dos.h>
//-------------------------------------------------------------------------
char Fehler[36];
//Fehler Meldung Text zuweisen!
void fehler(unsigned char EC)
{
strcpy(Fehler,"");
if (EC==0x80) strcat(Fehler,"unbekannte Funktion ");
if (EC==0x81) strcat(Fehler,"VDISK gefunden ");
if (EC==0x82) strcat(Fehler,"Gate A20 Fehlfunktion ");
if (EC==0x8E) strcat(Fehler,"unbestimmter Fehler des Treibers ");
if (EC==0x8F) strcat(Fehler,"Schwerer Fehler, Programm beenden!!");
if (EC==0x90) strcat(Fehler,"kein HMA verfügbar ");
if (EC==0x91) strcat(Fehler,"HMA belegt ");
if (EC==0x92) strcat(Fehler,"DX < /HMAMIN= @ DEVICE=HIMEM.SYS");
if (EC==0x93) strcat(Fehler,"HMA nicht vergeben ");
if (EC==0x94) strcat(Fehler,"A20 noch freigegeben ");
if (EC==0xA0) strcat(Fehler,"XMS vollständig vergeben ");
if (EC==0xA1) strcat(Fehler,"alle XMS Handles vergeben ");
if (EC==0xA2) strcat(Fehler,"ungültige Handle ");
if (EC==0xA3) strcat(Fehler,"ungültige Handle bei Quelladresse ");
if (EC==0xA4) strcat(Fehler,"ungültige Quelladresse (Offset) ");
if (EC==0xA5) strcat(Fehler,"ungültige Handle bei Zieladresse ");
if (EC==0xA6) strcat(Fehler,"ungültige Zieladresse (Offset) ");
if (EC==0xA7) strcat(Fehler,"ungültige Länge ");
if (EC==0xA8) strcat(Fehler,"Kopierbereiche überlappen ");
if (EC==0xA9) strcat(Fehler,"Parity-Fehler ");
if (EC==0xAA) strcat(Fehler,"Block nicht gesperrt ");
if (EC==0xAB) strcat(Fehler,"Block gesperrt ");
if (EC==0xAC) strcat(Fehler,"zuviele Blocksperen ");
if (EC==0xAD) strcat(Fehler,"Blocksperre fehlgeschlagen ");
if (EC==0xB0) strcat(Fehler,"nur noch kleinere UMBs verfügbar ");
if (EC==0xB1) strcat(Fehler,"kein UMB verfügbar ");
if (EC==0xB2) strcat(Fehler,"ungültiges UMB Segment ");
}
//Print Funktion fr schreibfaule!
//-------------------------------------------------------------------------
void print(int XPx , int XPy,int XPc,long XPt)
{
gotoxy(XPx, XPy);
textcolor(XPc);
char MXct[33];
ltoa(XPt,MXct,10);
cprintf(MXct);
}
void print(int XPx , int XPy,int XPc,char XPt[80])
{
gotoxy(XPx, XPy);
textcolor(XPc);
cprintf(XPt);
}
//######################################################################################
unsigned char XMScheck=0; //XMS verfgbar (80h = OK)
char XMSvec[4]; //Adresse XMS-Handler
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 XMSfree=0;//XMS-Frei
unsigned int XMSbblock=0;//gr”sster verfgbarer XMS Block an einem Stck
char test1[8]="erste111";
char test2[8]="zweite22";
unsigned char ch=0;
//######################################################################################
int main(void)
{
clrscr();
//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);
//XMS Handler Adresse erfragen
asm{
mov ax,4310h;
int 2fh;
//
mov word ptr XMSvec,bx;
mov word ptr XMSvec +2,es;
}
//INFO Adresse >>
print(1,3,8,"XMS Adresse :");
print(40,3,7,XMSvec);
//XMS freien speicher abfragen
asm{
mov ah ,8;
call XMSvec; //anfordern
mov XMSfree ,dx; //verfgbarer XMS in Kbytes
mov XMSbblock ,ax; //gr”sster noch freier zusammenh„ngender XMS-Block
}
//INFO Freier Speicher/Bl”cke
print(1,5,8,"XMS freier speicher");
print(21,5,7,XMSfree);
print(30,5,8,"XMS gr”sster Block");
print(49,5,7,XMSbblock);
//XMS Allocate Memory
unsigned int kbytes=1000;//KB anfragen
asm{
mov dx ,kbytes; //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!
}
//INFO Block reservieren
print(1,7,8,"XMS reservieren");
print(1,7,8,"XMS 1=OK/0=Fehler");
print(19,7,7,XMStest);
print(30,7,8,"XMS Fehlercode");
print(45,7,7,XMSfehler);
print(60,7,8,"XMS Handle");
print(71,7,7,XMShandle);
//
fehler(XMSfehler);
print(1,8,14,Fehler);
Anfang:
print(1,1,8,"XMS-TEST-004");
print(20,1,8,test1);
print(30,1,8,test2);
ch=getch();
if (ch==0) ch=getch()+128;
//kopieren XMS > X
if (ch=='7'){
unsigned int XMSl_L=8;
unsigned int XMSl_H=0;
asm{
//L„nge gerade Zahl!!
mov ax,XMSl_L;
mov [si] ,ax ;
mov ax,XMSl_H;
mov 2[si] ,ax ;
//QUELLE
mov ax,XMShandle;
mov word ptr 4[si],ax ;
mov word ptr 6[si],offset 0 ;
mov word ptr 8[si],seg 0 ;
//ZIEL
mov word ptr 10[si],0 ;
mov word ptr 12[si],offset &test2;
mov word ptr 14[si],seg &test2 ;
//Funktion / Aufruf
mov ah,0Bh;
call XMSvec ;
mov XMStest,ax ;//1=OK
mov XMSfehler,bl ;//Fehlermeldung 160=kein speicher frei!
}
fehler(XMSfehler);
print(1,12,14,"X > XMS");
print(9,12,12,XMSfehler);
print(30,12,14,"AX1=OK");
print(39,12,14,XMStest);
print(1,13,14,Fehler);
}
//kopieren X > XMS
if (ch=='6'){
unsigned int XMSl_L=8;
unsigned int XMSl_H=0;
asm{
//L„nge gerade Zahl!!
mov ax,XMSl_L ;
mov [si] ,ax ;
mov ax,XMSl_H ;
mov 2[si] ,ax ;
//QUELLE
mov word ptr 4[si],0 ;
mov word ptr 6[si],offset &test1;
mov word ptr 8[si],seg &test1 ;
//ZIEL
mov ax,XMShandle
mov word ptr 10[si],ax ;
mov word ptr 12[si],offset 0 ;
mov word ptr 14[si],seg 0 ;
//Funktion / Aufruf
mov ah,0Bh;
call XMSvec ;
mov XMStest,ax ;//1=OK
mov XMSfehler,bl ;//Fehlermeldung 160=kein speicher frei!
}
fehler(XMSfehler);
print(1,12,14,"X > XMS");
print(9,12,12,XMSfehler);
print(30,12,14,"AX1=OK");
print(39,12,14,XMStest);
print(1,13,14,Fehler);
}
if (ch!=27) goto Anfang;
//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);
if (XMShandle>0) XMShandle--;
}
clrscr();
print(1,1,7,"Beendet");
return 0;
}
Alles anzeigen
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
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
aber ich muss da eine Variable hin bekommen anstelle eines festen wertes, da dieser sich ändert.
Warum addierst du die Variable nicht einfach auf ax?
Die Zeilen sähen dann so aus oder?
das Funktioniert so nicht.
...hier nochmal das ganze
if (ch=='7'){
unsigned int nr=20;
unsigned int XMSl_L=10;
unsigned int XMSl_H=0;
asm{
//L„nge gerade Zahl!!
mov ax,XMSl_L;
mov [si] ,ax ;
mov ax,XMSl_H;
mov 2[si] ,ax ;
//QUELLE
mov ax,XMShandle;
mov word ptr 4[si],ax ;
xor ax,ax;
add ax,nr;
mov word ptr 6[si],offset ax;
// mov ax,nr;
// add word ptr 6[si],ax;
xor ax,ax;
mov word ptr 8[si],seg ax ;
//ZIEL
mov word ptr 10[si],0 ;
mov word ptr 12[si],offset &test2;
mov word ptr 14[si],seg &test2 ;
//Funktion / Aufruf
mov ah,0Bh;
call XMSvec ;
mov XMStest,ax ;//1=OK
mov XMSfehler,bl ;//Fehlermeldung 160=kein speicher frei!
}
fehler(XMSfehler);
print(1,12,14,"X > XMS");
print(9,12,12,XMSfehler);
print(30,12,14,"AX1=OK");
print(39,12,14,XMStest);
print(1,13,14,Fehler);
}
Alles anzeigen
Kannst du verkürzen zu
mov ax, nr
...offset musste ich entfernen dann scheint es zu funktionieren.
mov word ptr 6[si],offset ax;
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
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
mov word ptr 12[si], offset deinpointer
mov word ptr 14[si], seg deinpointer
push es
push di
les di, dword ptr 12[si]
mov ax,es:[di]
mov word ptr 12[si], ax
mov ax,es:[di+2]
mov word ptr 14[si], ax
pop di
pop es
Alles anzeigen
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.
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.
Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!