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 --------------------------------------------------------------------------------------*/ #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 *** // ***************************** function00();//initialisations function01();//function 1 - call from basic with |HELLO,param1,param2,... void skip00();//some jumps void skip02(); void skip04(); // ************************** // *** 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 x=0;int y=0; int nbrParam=0; //number of parameters of the BASIC command int BasicParams[32]; //32 parameters max //----------------------------------------------------------- typedef int (*PtrFunct)(); // define "type" of function pointer PtrFunct CppVecTb[20]; // module vectors table(128 vectors max) //other ex:>>> typedef int (*PtrFunct)(int, int);PtrFunct pf; 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 //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 (*)=0 - reçeipt the first Cpc accessible address // 0=no address accessible - see Cpc memory access from C++ environment 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]; //(V1.19c)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 (*) // or number of pages to be allocated (if <>0 when the module is loaded) // or number of connected pages (*) // or number of pages to connect // (the emulator reserved 4 pages for the C++ modules) // w029h reserved int W2BH; // w02Bh (*)SS emulator stack segment int W2DH; // w02Dh (*)SP emulator stack pointer char S2FH[20]; // s02FH 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 X86Tb.MnemosBASIC=&MnemosBASIC[0];// w010h offset mnemonics 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.S28H[0]=4; // number of pages to connect(always 4 for the C++ modules) return &X86Tb;//passes the offset of the module implementation table to the emulator } 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(){//initialisation vector called with the CPC boot asm {//Init function for calls from Cpc mov bp,cs;cli;mov ss,bp;mov sp,STACK_INIPTR;sti;mov bp,sp } printf(" HELLO 1.0\n"); // INIT message asm {stc}//= ok for INIT vector BackToZ80();//Return to Z80 } 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" asm{ and ax,01Fh // 32 parameters max mov nbrParam,ax // numbers of parameters mov cl,al xor ch,ch add cx,cx // size block jz short skip04 // jump if no parameters mov di,offset BasicParams mov ah,5 // read block bank 0 Cpc int 018h } skip04: return nbrParam; } //this function can be called from main() for tests function01(){//function 1 - call from basic with |HELLO,param1,param2,... if (GsSeg!=0){ //Data segment of the emulator CpcAlive //=flag call from emulator asm{//Init function for call from CPC mov bp,cs;cli;mov ss,bp;mov sp,STACK_INIPTR;sti;mov bp,sp } } //--------------------------------- //Free C++ area if (BasicParamInput()!=0){//load parameters of the BASIC command printf("Numbers of parameters=%d\n",nbrParam); } printf("HELLO CPC"); //--------------------------------- if (GsSeg==0x0){return 0;} //back to main() if called from main() BackToZ80(); //else return to Z80 } //passes the offset of the module implementation table to the emulator struct X86TbStruct *main() // ---------- MAIN ------------ { CppVecTb[0]=&function00;// 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; } |