|
English
/* HELLO.CPP - Ce programme est un module CpcAlive et il doit être compilé seulement avec le compilateur Borland Turbo C++ Version 3.0(1992) avec la commande: tcc -mt -lt HELLO.cpp qui produira un fichier de format compatible Dos avec une extension .COM Toutes le variables utilsées dans les lignes en langage assembleur doivent être "globales" - Chargement à partir de la ligne de commande Dos: ! HELLO.COM - Chargement à partir d'un fichier de commandes CpcAlive: HELLO.COM - Chargement à partir de l'interpréteur basic du Cpc: |INPUT,"HELLO.COM":CALL 0 ----------------------------------------------------------------------------- !! nécessite la version V1.19i ou plus de l'émulateur CpcAlive !! -----------------------------------------------------------------------------*/ #include <stdio.h> #include <string.h> #if defined(__TURBOC__) || defined(_MSC_VER) #include <conio.h> #else #define _MAX_PATH 250 #define stricmp(x,y) strcasecmp(x,y) #define strnicmp(x,y,z) strncasecmp(x,y,z) #endif #define STACK_INIPTR -2 // ***************************** // *** Fonction prototypes *** // ***************************** CallFunctions();//routine d'appel des fonctions C++ ModuleInit();//vecteur d'initialisations function01();//fonction 1 - appel depuis basic avec |HELLO,param1,param2,... void skip00();//sauts divers void skip02(); // ************************** // *** Global variables *** // ************************** //-------------------------------------------------------------------------------------- //!!!!Toutes les variables utilsées dans les lignes en langage assembleur doivent être "globales"!!!! int GsSeg=0;//Segment data de l'émulateur CpcAlive=flag appel depuis émulateur int BasicParams[32]; //32 paramètres maxi int nbrParam=0; //nombre de paramètres de la commande BASIC //-------------------------------------------------------------------------------------- typedef int (*PtrFunct)(); // défini "type" pointeur de fonction PtrFunct CppVecTb[20]; // table des vecteurs du module(128 vecteurs maxi) PtrFunct FunctionOfs;int ssBak=0;int spBak=0;//valeurs temporaires //autre ex:>>> typedef int (*PtrFunct)(int, int); #if !defined(NO_MNEMOS) char MnemosBASIC[] = {// Mnémoniques d'appels depuis le BASIC CPC 'I','N','I','T'|0x80, //CppVecTb[0]=fonction 0 - initialisations 'H','E','L','L','O'|0x80, //CppVecTb[0]=fonction 1 - appel depuis basic avec |HELLO,param1,param2,... //... '\0'}; //marque fin de table #endif //structure table d'implémentation du module struct X86TbStruct {//s=string,w=word,b=byte,*=valeurs générées par le système char mark[6]; // s000h marque("X86CPC") int X86TbVersion; // w006h version table PtrFunct *CppVecTb; // w008h adresse table vecteurs d'entrée int W0AH[3]; // w00Ah réservé char *MnemosBASIC; // w010h offset mnémoniques char B12H[4]; // 4 valeurs // b012h (*)reçoit le numéro de module X86 // b013h numéro module complément // b014h (*)reçoit le numéro de la rom Z80 associée // b015h indicateur pour connection banques Cpc ou modules compléments int W16H; // w016h réservé char S18H[6]; // 4 valeurs // b018h réservé // w019h (*)reçoit le handle ems associé au module // w01Bh (*)reçoit le numéro logique première page du module // b01Dh réservé int W1EH[5]; // utiliser le même modèle que les fonctions de la table CppVecTb pour programmer ces fonctions // w01Eh adresse appelée à l'arrêt de l'émulateur (0=pas d'appel) // w020h adresse appelée à la mise en veille de l'émulateur (0=pas d'appel) // w022h adresse appelée au retour de veille de l'émulateur (0=pas d'appel) // w024h adresse appelée au chargement du module (0=pas d'appel) // w026h réservé char S28H[3]; // 2 valeurs // b028h reçoit le nombre de pages allouées au module (*) // (toujours 4 pages pour les modules C++) // w029h réservé int W2BH; // w02Bh(*)SS segment pile émulateur int W2DH; // w02Dh(*)SP pointeur pile émulateur char S2FH[1]; // s02FH réservé PtrFunct W30H; // w030h offset routine d'appel des fonctions C++ PtrFunct W32H; // w032h (*)reçoit l'adresse de la fonction appelée char S34H[100]; // s034H réservé }; struct X86TbStruct X86Tb;//table d'implémentation du module struct X86TbStruct *X86TbSet(){ // init table d'implémentation du module strcpy(X86Tb.mark,"X86CPC"); // s000h marque("X86CPC") X86Tb.X86TbVersion=1; // w006h version table X86Tb.CppVecTb=&CppVecTb[0]; // w008h adresse table vecteurs d'entrée #if defined(NO_MNEMOS) X86Tb.MnemosBASIC=0; // w010h offset mnémoniques (0=pas de mnémoniques) X86Tb.W24H=&ModuleInit; // fonction appelée au chargement du module #else X86Tb.MnemosBASIC=&MnemosBASIC[0]; // w010h offset mnémoniques #endif X86Tb.B12H[0]=-1; // b012h (*)reçoit le numéro de module X86 X86Tb.B12H[1]=-1; // b013h numéro module complément X86Tb.B12H[2]=-1; // b014h (*)reçoit le numéro de la rom Z80 associée X86Tb.B12H[3]=-1; // b015h indicateur pour connection banques Cpc ou modules compléments X86Tb.W30H=&CallFunctions; // routine d'appel des fonctions C++ return &X86Tb;// transmet l'offset de la table d'implémentation du module à l'émulateur } CallFunctions(){//routine d'appel des fonctions C++ asm {mov bp,cs;cli;mov ss,bp;mov sp,STACK_INIPTR;sti;mov bp,sp;push ax} FunctionOfs=X86Tb.W32H;ssBak=X86Tb.W2BH;spBak=X86Tb.W2DH; asm {pop ax;call FunctionOfs;cli;mov ss,ssBak;mov sp,spBak;sti;retf} } ModuleInit(){//vecteur 0 d'initialisation appelé au boot Cpc #if !defined(NO_MNEMOS) printf(" HELLO 1.1\n"); // message INIT asm {stc}//marque ok pour vecteur INIT #endif } int BasicParamInput(){//charge paramètres de la commande BASIC //<AL=nombre de paramètres // SI pointe paramètres dans la ram cpc //>Les valeurs récoltées dans le tableau BasicParams seront des pointeurs vers les données de chaque // variables (chaines de caractères par exemple), sauf pour les valeurs entières qui pouront être traitées telles quelles. if (GsSeg==0){return 0;}//segment data de l'émulateur CpcAlive=flag appel depuis émulateur nbrParam=_AX & 0x1f; // 32 paramètres max if (nbrParam){ _CX=nbrParam*2; // taille transfert _AH=5; // lire bloc banque 0 Cpc (voir accès à la mémoire du Cpc via int 018h) asm{ mov di,offset BasicParams int 018h } } return nbrParam; } function01(){//function 1 - call from basic with |HELLO,param1,param2,... //--------------------------------- //Free C++ area int i; if (BasicParamInput()!=0){//charge paramètres de la commande BASIC printf("Nbre de parametres=%d\n",nbrParam); for (i = 0; i < nbrParam; i++){printf("0x%x=valeur ou pointeur parametre %d\n",BasicParams[i],i);} } printf("HELLO CPC"); //--------------------------------- } // transmet l'offset de la table d'implémentation du module à l'émulateur struct X86TbStruct *main() // fonction d'entrée du programme { CppVecTb[0]=&ModuleInit;// vecteurs du module CppVecTb[1]=&function01;// vecteurs du module GsSeg=0; //Data segment of the emulator CpcAlive //=flag appel depuis émulateur asm { cmp byte ptr cs:[01B1h],090h // appel depuis émulateur ?(.COM) jz short skip00 // oui sauter cmp byte ptr cs:[0B1h],090h // appel depuis émulateur ?(.EXE) jnz short skip02 // non sauter } skip00: asm { db 0Fh,0A8H //PUSH GS(Data segment of the emulator CpcAlive) pop GsSeg //!=0 -> appel depuis émulateur } return X86TbSet();// transmet l'offset de la table d'implémentation du module à l'émulateur skip02: //pour test à partir du DOS function01();//fonction 1 if (getch() == 0) getch(); return 0; }
|