Ajattelin kysyä että kuinka olisi mahdollista käyttää prosessorin MMX-käskyjä DOS-pohjaisesta Watcom C++ kääntäjästä käsin?
Olisi hienoa jos 32 bittisen MOVSD käskyn voisi korvata esim. 64 bittisellä MMX vastineella.
Alla nykyisin käyttämäni kaksoispuskuroitu piirtokoodi.
unsigned char ScBu[640*480]; #pragma aux screen1=\ "mov edi,0a0000h",\ "lea esi,ScBu[0]",\ "mov ecx,16384",\ "rep movsd",\ modify[esi edi ecx]; #pragma aux screen2=\ "mov edi,0a0000h",\ "lea esi,ScBu[65536]",\ "mov ecx,16384",\ "rep movsd",\ modify[esi edi ecx]; #pragma aux screen3=\ "mov edi,0a0000h",\ "lea esi,ScBu[131072]",\ "mov ecx,16384",\ "rep movsd",\ modify[esi edi ecx]; #pragma aux screen4=\ "mov edi,0a0000h",\ "lea esi,ScBu[196608]",\ "mov ecx,16384",\ "rep movsd",\ modify[esi edi ecx]; #pragma aux screen5=\ "mov edi,0a0000h",\ "lea esi,ScBu[262144]",\ "mov ecx,11264",\ "rep movsd",\ modify[esi edi ecx]; void UpdateSvgaScreen(void) { screen1(); screen2(); screen3(); screen4(); screen5(); }
Onhan sekin nykykoneilla TOSI nopeaa mutta haluan repiä DOS:sista kaiken irti!
Eli piirtokoodi pitäisi ensin varmaankin kirjoittaa taulukkoon käsky ja parametri kerrallaan vastaavina heksalukuina ja sitten siirtää koodi muistiin.
Piirtofunktiota pitäisi myös C++:an puolelta pystyä kutsumaan...
Ehkä se kävisi näin.
#pragma aux Kutsu=\ "mov eax,0x????????" "call eax" modify[eax]
Eli pitäisi tietää MMX-käskyjen hexaarvot.
Osaako kukaan auttaa?
Voit kyllä assembloida koodisi ulkoisella assemblerilla, liittää sen binaarina ohjelmaasi ja kutsua sitä. Call ei kuitenkaan toimi noin, vaan sille annetaan kutsuttavan koodin (funktion) osoite. Pitää myös muistaa, että DOSissa osoitteet ja segmentit ovat 16-bittisiä, eli normaali call ei välttämättä riitä, jos koodi ei ole samassa segmentissä.
Helpoiten ja parhaaseen tulokseen pääset luultavasti sillä, että hoidat assemblyn oikealla assemblerilla, teet funktioista oikeita, irrallisia stand-alone-funktioita ja linkität ne C++-ohjelmaan jälkeen päin. Watcomin kääntäjää en tunne, mutta esimerkiksi Linuxissa NASMin ja GCC:n kanssa homma toimisi suunnilleen näin:
// koodi.cpp extern "C" { // Jotta funktion nimi pysyy samana int funktio(const char *parametri); } int main() { return funktio("Moi!"); }
; koodi.asm [BITS 16] global funktio funktio: mov eax, [esp+4] ret
nasm -f elf -o koodi.asm.o koodi.asm g++ -c -o koodi.cpp.o koodi.cpp g++ koodi.cpp.o koodi.asm.o -o ohjelma
Perehdy siis johonkin assembleriin ja tutustu tarkemmin C++-kääntäjäsi tukemiin objektiformaatteihin ja funktionnimeämiskäytäntöihin.
Mutta watcom c++ toimii suojatussa tilassa eli siinä ei käsittääkseni ole segmenttejä.
Ja edelleenkään en tiedä MMX-käskyjen hexakoodeja.
Mutta kiitos tuostakin!:)
Edelleenkin saat ne MMX-käskyjen koodit käyttämällä jotakin oikeaa assembleria, joka tukee niitä, ja katsomalla, millaisen tiedoston se tuottaa. Esimerkiksi mainitsemani NASM käy oikein hyvin. Suosittelen myös muuta kuvaamaani menetelmää yhtä lailla suojatussa tilassa. Viestini ainoa reaalitilaan viittaava kohta oli juuri tuo segmenttiasia, suojatussa tilassa tätä ei tietenkään tarvitse huomioida, vaan funktion osoitteen voi suoraan laittaa eax-rekisteriin.
Aihe on jo aika vanha, joten et voi enää vastata siihen.