Cpc
basic key words
|
Français
/* HELLO.CPP - This program is a CpcAlive Module and it must be compiled only with the Borland Turbo C++ Version 3.0(1992) with the command: tcc -mt -lt HELLO.cpp wich produce a DosBox executable file with a .COM extension All variables used with the inline assembler must be "global" Loading from the Dos command line: ! HELLO.COM Loading from a CpcAlive command file: HELLO.COM Loading from the Cpc BASIC interpreter: |INPUT, "HELLO.COM":CALL 0 -------------------------------------------------------------------------------------- !!requires version V1.19i or more of the CpcAlive emulator!! --------------------------------------------------------------------------------------*/ #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 // ***************************** // *** Function prototypes *** // ***************************** CallFunctions();//C++ functions call routine ModuleInit(); //initialisations function01(); //function 1 - call from basic with |HELLO,param1,param2,... void skip00(); //some jumps void skip02(); // ************************** // *** Global variables *** // ************************** //-------------------------------------------------------------------------------------- //!!! All variables used with inline assembler must be "global" !!! int GsSeg=0; //Data segment of the emulator CpcAlive=flag "called from emulator" int BasicParams[32]; //32 parameters max int nbrParam; //number of parameters of the BASIC command //-------------------------------------------------------------------------------------- typedef int (*PtrFunct)(); // define "type" of function pointer PtrFunct CppVecTb[20]; // module vectors table(128 vectors max) PtrFunct FunctionOfs;int ssBak=0;int spBak=0;//temporary values //other ex:>>> typedef int (*PtrFunct)(int, int); #if !defined(NO_MNEMOS) char MnemosBASIC[] = { // Mnemonics call's from CPC BASIC 'I','N','I','T'|0x80, //CppVecTb[0]=function 0 - initialisations 'H','E','L','L','O'|0x80, //CppVecTb[1]=function 1 - call from basic with |HELLO,param1,param2,... //.... '\0'}; //mark end of table #endif //struct of implementation table of the module struct X86TbStruct { //s=string,w=word,b=byte,*=value generated by the system char mark[6]; // s000h mark("X86CPC") int X86TbVersion; // w006h version table PtrFunct *CppVecTb; // w008h entry vectors table int W0AH[3]; // w00Ah reserved char *MnemosBASIC; // w010h offset mnemonics table for calls with Basic char B12H[4]; // 4 values // b012h (*)receipt the X86 module area number // b013h module complement number or bank Cpc block number // b014h (*)reçeipt the Z80 rom number associated // b015h indicator for Cpc banks or modules complements connection int W16H; // w016h reserved char S18H[6]; // 4 values // b018h reserved // w019h (*)receipt the ems handle associated to the module // w01Bh (*)receipt the logical number of the first 16K page of the module // b01Dh reserved int W1EH[5]; // use the same model as functions in the CppVecTb table to program these functions // w01Eh address called when the emulator exit (0=no call) // w020h address called when the emulator is put in "sleep mode" (0=no call) // w022h address called when the emulator return from "sleep mode" (0=no call) // w024h address called when the module is load (0=no call) // w026h reserved char S28H[3]; // 2 values // b028h receipt the number of 16K pages allocated to the module (*) // (always 4 for the C++ modules) // w029h reserved int W2BH; // w02Bh (*)SS emulator stack segment int W2DH; // w02Dh (*)SP emulator stack pointer char S2FH[1]; // s02FH reserved PtrFunct W30H; // w030h C++ functions call offset routine PtrFunct W32H; // w032h (*)receives the address of the called function char S34H[100]; // s034H reserved }; struct X86TbStruct X86Tb;//implementation table of the module struct X86TbStruct *X86TbSet(){ // init implementation table of the module strcpy(X86Tb.mark,"X86CPC"); // s000h mark("X86CPC") X86Tb.X86TbVersion=1; // w006h version table X86Tb.CppVecTb=&CppVecTb[0]; // w008h entry vectors table #if defined(NO_MNEMOS) X86Tb.MnemosBASIC=0; // w010h offset mnemonics (0=no mnemonics) X86Tb.W24H=&ModuleInit; // function called when the module is load (0=no call) #else X86Tb.MnemosBASIC=&MnemosBASIC[0];// w010h offset mnemonics #endif X86Tb.B12H[0]=-1; // b012h (*)receipt the X86 module area number X86Tb.B12H[1]=-1; // b013h module complement number or bank Cpc block number X86Tb.B12H[2]=-1; // b014h (*)reçeipt the Z80 rom number associated X86Tb.B12H[3]=-1; // b015h indicator for Cpc banks or modules complements connection X86Tb.W30H=&CallFunctions; // w030h C++ functions call routine return &X86Tb;//passes the offset of the module implementation table to the emulator } CallFunctions(){//C++ functions call routine 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(){//initialisation vector called with the CPC boot #if !defined(NO_MNEMOS) printf(" HELLO 1.1\n"); // INIT message asm {stc}//= ok for INIT vector #endif } int BasicParamInput(){//load parameters of the BASIC command //<AL=number of parameters // SI=parameters pointer in Cpc Ram //>Values collected in the BasicParams array will be pointers to the data for each // variables (e.g., strings), except for integer values that can be processed as is. if (GsSeg==0){return 0;}//Data segment of the emulator CpcAlive=flag "call from emulator" nbrParam=_AX & 0x1f; // 32 parameters max if (nbrParam){ _CX=nbrParam*2; // size block _AH=5; // read block bank 0 Cpc - see Cpc memory access from C++ environment asm{ mov di,offset BasicParams int 018h } } return nbrParam; } function01(){//function 1 - call from basic with |HELLO,param1,param2,... int i; //--------------------------------- //Free C++ area if (BasicParamInput()!=0){//load parameters of the BASIC command printf("Numbers of parameters=%d\n",nbrParam); for (i = 0; i < nbrParam; i++){printf("0x%x=value or pointer of parameter %d\n",BasicParams[i],i);} } printf("HELLO CPC"); //--------------------------------- } //passes the offset of the module implementation table to the emulator struct X86TbStruct *main() // ---------- MAIN ------------ { CppVecTb[0]=&ModuleInit;// vectors of module CppVecTb[1]=&function01; //... GsSeg=0; //Data segment of the emulator CpcAlive //=flag "called from emulator" asm { cmp byte ptr cs:[01B1h],090h // called from emulator ?(.COM) jz short skip00 // jump if yes cmp byte ptr cs:[0B1h],090h // called from emulator ?(.EXE) jnz short skip02 // jump if not } skip00: asm { db 0Fh,0A8H //PUSH GS(Data segment of the emulator CpcAlive) pop GsSeg //!=0 -> called from emulator } return X86TbSet();//passes the offset of the module implementation table to the emulator skip02: //for test from DOS function01();//function 1 if (getch() == 0) getch(); return 0; } |