|
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 -----------------------------------------------------------------------------*/ #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 *** // ***************************** function00();//vecteur d'initialisations function01();//fonction 1 - appel depuis basic avec |HELLO,param1,param2,... void skip00();//sauts divers void skip02(); void skip04(); // ************************** // *** 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 x=0;int y=0; int nbrParam=0; //nombre de paramètres de la commande BASIC int BasicParams[32]; //32 paramètres maxi //-------------------------------------------------------------------------------------- typedef int (*PtrFunct)(); // défini "type" pointeur de fonction PtrFunct CppVecTb[20]; // table des vecteurs du module(128 vecteurs maxi) //autre ex:>>> typedef int (*PtrFunct)(int, int);PtrFunct pf; 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 //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 (*)1ere adresse Cpc accessible(pour les modules C++ l'accès // à la mémoire Z80 n'est possible qu'à travers l'interruption INT 018H) 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]; // (V1.19c) 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 (*) // ou nombre de pages à allouer (si<>0 au chargement) // ou nombre de pages connectées (*) // ou nombre de pages à connecter (si<>0) // (l'émulateur réserve 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[20]; // s02FH 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 X86Tb.MnemosBASIC=&MnemosBASIC[0]; // w010h offset mnémoniques 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.S28H[0]=4; // nombre de pages à connecter(toujours 4 pour les modules C++) return &X86Tb;// transmet l'offset de la table d'implémentation du module à l'émulateur } void BackToZ80(){//Return to Z80 //(x&y=global integers) asm{push ax};x=X86Tb.W2BH;y=X86Tb.W2DH;asm {pop ax;cli;mov ss,x;mov sp,y;sti;retf} } function00(){//vecteur 0 d'initialisation appelé au boot Cpc asm {//Init fonction pour appel depuis CPC mov bp,cs;cli;mov ss,bp;mov sp,STACK_INIPTR;sti;mov bp,sp } printf(" HELLO 1.0\n"); // message INIT asm {stc}//marque ok pour vecteur INIT BackToZ80();//Return to Z80 } 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 asm{ and ax,01Fh // 32 paramètres max mov nbrParam,ax // nombre de paramètres mov cl,al xor ch,ch add cx,cx // taille transfert jz short skip04 // sauter si pas de paramètre mov di,offset BasicParams mov ah,5 // read bloc banque 0 Cpc int 018h } skip04: return nbrParam; } //cette fonction peut être appelée depuis main() pour tests function01(){//function 1 - call from basic with |HELLO,param1,param2,... if (GsSeg!=0){ //Data segment of the emulator CpcAlive //=flag appel depuis émulateur asm{//Init fonction pour appel depuis CPC mov bp,cs;cli;mov ss,bp;mov sp,STACK_INIPTR;sti;mov bp,sp } } //--------------------------------- //Free C++ area if (BasicParamInput()!=0){//charge paramètres de la commande BASIC printf("Nbre de parametres=%d\n",nbrParam); } printf("HELLO CPC"); //--------------------------------- if (GsSeg==0x0){return 0;} //retour main() si appel depuis main() BackToZ80(); //sinon retour Z80 } // transmet l'offset de la table d'implémentation du module à l'émulateur struct X86TbStruct *main() // fonction d'entrée du programme { CppVecTb[0]=&function00;// 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; }
|