This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088

Dependents:   MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NyLPC_cMiMicVM.c Source File

NyLPC_cMiMicVM.c

00001 /*********************************************************************************
00002  * PROJECT: MiMic
00003  * --------------------------------------------------------------------------------
00004  *
00005  * This file is part of MiMic
00006  * Copyright (C)2011 Ryo Iizuka
00007  *
00008  * MiMic is free software: you can redistribute it and/or modify
00009  * it under the terms of the GNU Lesser General Public License as published
00010  * by the Free Software Foundation, either version 3 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public License
00019  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00020  *
00021  * For further information please contact.
00022  *  http://nyatla.jp/
00023  *  <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
00024  *
00025  *********************************************************************************/
00026 #include <ctype.h>
00027 #include <stdlib.h>
00028 #include "NyLPC_cMiMicVM_protected.h"
00029 
00030 static NyLPC_TUInt8 process_instruction(NyLPC_TcMiMicVM_t* i_inst,const union NyLPC_TcMiMicVM_TInstruction* ist,NyLPC_TUInt32* o_code);
00031 
00032 
00033 
00034 void NyLPC_cMiMicVM_initialize(NyLPC_TcMiMicVM_t* i_inst,struct NyLPC_TcMiMicVM_TEvent* i_handler)
00035 {
00036     NyLPC_Assert(i_inst!=NULL);
00037     NyLPC_Assert(i_handler!=NULL);
00038     NyLPC_Assert(i_handler->get_stream!=NULL);
00039     NyLPC_Assert(i_handler->put_stream!=NULL);
00040     NyLPC_Assert(i_handler->sleep!=NULL);
00041     i_inst->_event_handler=i_handler;
00042     return;
00043 }
00044 
00045 
00046 /**
00047  * 固定長命令+固定長データを実行します。
00048  * 関数の終了条件は、1.EXIT命令に到達する。2.インストラクションの終端に到達する。3.エラーが発生する。
00049  * 
00050  */
00051 NyLPC_TUInt32 NyLPC_cMiMicVM_run(NyLPC_TcMiMicVM_t* i_inst,const NyLPC_TUInt32* i_instruction,const NyLPC_TUInt16 i_size_of_instruction)
00052 {
00053     //データ部をgetstreamと連動させること。
00054     NyLPC_TUInt32 retcode=NyLPC_cMiMicVM_RESULT_OK;
00055     NyLPC_TUInt16 pc=0;
00056     NyLPC_TUInt8 proc_in_byte;
00057     if(i_size_of_instruction>0){
00058         proc_in_byte=process_instruction(i_inst,(const union NyLPC_TcMiMicVM_TInstruction*)(i_instruction+pc),&retcode);
00059         pc+=proc_in_byte;
00060         //プログラムの終端に到達するか、0バイト処理の場合にブレーク。
00061         while(proc_in_byte>0 && pc<i_size_of_instruction){
00062             proc_in_byte=process_instruction(i_inst,(const union NyLPC_TcMiMicVM_TInstruction*)(i_instruction+pc),&retcode);
00063             pc+=proc_in_byte;
00064         }
00065     }
00066     return retcode;
00067 }
00068 /**
00069  * 出力ストリームへ32ビット値を書き出す。
00070  */
00071 NyLPC_TBool NyLPC_cMiMicVM_sput(NyLPC_TcMiMicVM_t* i_inst,NyLPC_TUInt32 i_val)
00072 {
00073     if(!i_inst->_event_handler->put_stream(i_inst->_event_handler,i_val)){
00074         return NyLPC_TBool_FALSE;
00075     }
00076     return NyLPC_TBool_TRUE;
00077 }
00078 /**
00079  * 入力ストリームから32ビット値を読み出す。
00080  */
00081 NyLPC_TBool NyLPC_cMiMicVM_sget(NyLPC_TcMiMicVM_t* i_inst,NyLPC_TUInt32* o_val)
00082 {
00083     if(!i_inst->_event_handler->get_stream(i_inst->_event_handler,o_val)){
00084         return NyLPC_TBool_FALSE;
00085     }
00086     return NyLPC_TBool_TRUE;
00087 }
00088 
00089 
00090 
00091 /**
00092  * インストラクションを1個処理し、処理したバイト数を返す。
00093  * インストラクションの境界値はチェックされないので、コンパイル時にチェックしておくこと。
00094  * @return
00095  * 処理したインストラクションのワード数(UInt32単位)。
00096  * 終了した場合は0を返す。0を返したときは、ret_codeにMiMicVMの終了コードを返す。
00097  */
00098 static NyLPC_TUInt8 process_instruction(NyLPC_TcMiMicVM_t* i_inst,const union NyLPC_TcMiMicVM_TInstruction* ist,NyLPC_TUInt32* o_code)
00099 {
00100     NyLPC_TUInt32 tret;
00101     switch(ist->op.opc){
00102     case NyLPC_TcMiMicVM_OP_TYPE_AND:
00103         switch(ist->op.oprtype){
00104         case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
00105             i_inst->wm[ist->wmwm_32.wm1]&=i_inst->wm[ist->wmwm_32.wm2];
00106             break;
00107         case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
00108             i_inst->wm[ist->wmh32_64.wm]&=ist->wmh32_64.h32;
00109             break;
00110         default:
00111             NyLPC_OnErrorGoto(ERROR);
00112         }
00113         break;
00114     case NyLPC_TcMiMicVM_OP_TYPE_OR:
00115         switch(ist->op.oprtype){
00116         case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
00117             i_inst->wm[ist->wmwm_32.wm1]|=i_inst->wm[ist->wmwm_32.wm2];
00118             break;
00119         case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
00120             i_inst->wm[ist->wmh32_64.wm]|=ist->wmh32_64.h32;
00121             break;
00122         default:
00123             NyLPC_OnErrorGoto(ERROR);
00124         }
00125         break;
00126     case NyLPC_TcMiMicVM_OP_TYPE_XOR:
00127         switch(ist->op.oprtype){
00128         case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
00129             i_inst->wm[ist->wmwm_32.wm1]^=i_inst->wm[ist->wmwm_32.wm2];
00130             break;
00131         case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
00132             i_inst->wm[ist->wmh32_64.wm]^=ist->wmh32_64.h32;
00133             break;
00134         default:
00135             NyLPC_OnErrorGoto(ERROR);
00136         }
00137         break;
00138     case NyLPC_TcMiMicVM_OP_TYPE_NOT:
00139         switch(ist->op.oprtype){
00140         case NyLPC_TcMiMicVM_OPR_TYPE_WM:
00141             i_inst->wm[ist->wm_32.wm]=~i_inst->wm[ist->wm_32.wm];
00142             break;
00143         default:
00144             NyLPC_OnErrorGoto(ERROR);
00145         }
00146         break;
00147     case NyLPC_TcMiMicVM_OP_TYPE_SHL:
00148         switch(ist->op.oprtype){
00149         case NyLPC_TcMiMicVM_OPR_TYPE_WM_H08:
00150             i_inst->wm[ist->wmh08_32.wm]=i_inst->wm[ist->wmh08_32.wm]<<ist->wmh08_32.h8;
00151             break;
00152         case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
00153             i_inst->wm[ist->wmwm_32.wm1]=i_inst->wm[ist->wmwm_32.wm1]<<i_inst->wm[ist->wmwm_32.wm2];
00154             break;
00155         default:
00156             NyLPC_OnErrorGoto(ERROR);
00157         }
00158         break;
00159     case NyLPC_TcMiMicVM_OP_TYPE_SHR:
00160         switch(ist->op.oprtype){
00161         case NyLPC_TcMiMicVM_OPR_TYPE_WM_H08:
00162             i_inst->wm[ist->wmh08_32.wm]=i_inst->wm[ist->wmh08_32.wm]>>ist->wmh08_32.h8;
00163             break;
00164         case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
00165             i_inst->wm[ist->wmwm_32.wm1]=i_inst->wm[ist->wmwm_32.wm1]>>i_inst->wm[ist->wmwm_32.wm2];
00166             break;
00167         default:
00168             NyLPC_OnErrorGoto(ERROR);
00169         }
00170         break;
00171     case NyLPC_TcMiMicVM_OP_TYPE_ADD:
00172         switch(ist->op.oprtype){
00173         case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
00174             i_inst->wm[ist->wmwm_32.wm1]+=i_inst->wm[ist->wmwm_32.wm2];
00175             break;
00176         case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
00177             i_inst->wm[ist->wmh32_64.wm]+=ist->wmh32_64.h32;
00178             break;
00179         default:
00180             NyLPC_OnErrorGoto(ERROR);
00181         }
00182         break;
00183     case NyLPC_TcMiMicVM_OP_TYPE_SUB:
00184         switch(ist->op.oprtype){
00185         case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
00186             i_inst->wm[ist->wmwm_32.wm1]-=i_inst->wm[ist->wmwm_32.wm2];
00187             break;
00188         case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
00189             i_inst->wm[ist->wmh32_64.wm]-=ist->wmh32_64.h32;
00190             break;
00191         default:
00192             NyLPC_OnErrorGoto(ERROR);
00193         }
00194         break;
00195     case NyLPC_TcMiMicVM_OP_TYPE_MUL:
00196         switch(ist->op.oprtype){
00197         case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
00198             i_inst->wm[ist->wmwm_32.wm1]*=i_inst->wm[ist->wmwm_32.wm2];
00199             break;
00200         case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
00201             i_inst->wm[ist->wmh32_64.wm]*=ist->wmh32_64.h32;
00202             break;
00203         default:
00204             NyLPC_OnErrorGoto(ERROR);
00205         }
00206         break;
00207     case NyLPC_TcMiMicVM_OP_TYPE_MGET:
00208         switch(ist->op.oprtype){
00209         case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
00210             i_inst->wm[ist->wmh32_64.wm]=*((NyLPC_TUInt32*)(ist->wmh32_64.h32));
00211             break;
00212         case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
00213             i_inst->wm[ist->wmwm_32.wm1]=*((NyLPC_TUInt32*)(i_inst->wm[ist->wmwm_32.wm2]));
00214             break;
00215         default:
00216             NyLPC_OnErrorGoto(ERROR);
00217         }
00218         break;
00219     case NyLPC_TcMiMicVM_OP_TYPE_MPUT:
00220         switch(ist->op.oprtype){
00221         case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
00222             *((NyLPC_TUInt32*)(ist->wmh32_64.h32))=i_inst->wm[ist->wmh32_64.wm];
00223             break;
00224         case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
00225             *((NyLPC_TUInt32*)(i_inst->wm[ist->wmwm_32.wm2]))=i_inst->wm[ist->wmwm_32.wm1];
00226             break;
00227         default:
00228             NyLPC_OnErrorGoto(ERROR);
00229         }
00230         break;
00231     case NyLPC_TcMiMicVM_OP_TYPE_SGET:
00232         switch(ist->op.oprtype){
00233         case NyLPC_TcMiMicVM_OPR_TYPE_WM:
00234             if(!i_inst->_event_handler->get_stream(i_inst->_event_handler,&(i_inst->wm[ist->wm_32.wm]))){
00235                 NyLPC_OnErrorGoto(ERROR);
00236             }
00237             break;
00238         default:
00239             NyLPC_OnErrorGoto(ERROR);
00240         }
00241         break;
00242     case NyLPC_TcMiMicVM_OP_TYPE_SPUT:
00243         switch(ist->op.oprtype){
00244         case NyLPC_TcMiMicVM_OPR_TYPE_WM:
00245             if(!i_inst->_event_handler->put_stream(i_inst->_event_handler,i_inst->wm[ist->wm_32.wm])){
00246                 NyLPC_OnErrorGoto(ERROR);
00247             }
00248             break;
00249         case NyLPC_TcMiMicVM_OPR_TYPE_H32:
00250             if(!i_inst->_event_handler->put_stream(i_inst->_event_handler,ist->h32_64.h32)){
00251                 NyLPC_OnErrorGoto(ERROR);
00252             }
00253             break;
00254         default:
00255             NyLPC_OnErrorGoto(ERROR);
00256         }
00257         break;
00258     case NyLPC_TcMiMicVM_OP_TYPE_LD:
00259         switch(ist->op.oprtype){
00260         case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
00261             i_inst->wm[ist->wmwm_32.wm1]=i_inst->wm[ist->wmwm_32.wm2];
00262             break;
00263         case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
00264             i_inst->wm[ist->wmh32_64.wm]=ist->wmh32_64.h32;
00265             break;
00266         default:
00267             NyLPC_OnErrorGoto(ERROR);
00268         }
00269         break;
00270     case NyLPC_TcMiMicVM_OP_TYPE_NOP:
00271         switch(ist->op.oprtype){
00272         case NyLPC_TcMiMicVM_OPR_TYPE_NONE:
00273             break;
00274         case NyLPC_TcMiMicVM_OPR_TYPE_H08:
00275             i_inst->_event_handler->sleep(i_inst->_event_handler,ist->h8_32.h8);
00276             break;
00277         default:
00278             NyLPC_OnErrorGoto(ERROR);
00279         }
00280         break;
00281     //native call
00282     case NyLPC_TcMiMicVM_OP_TYPE_CALL:
00283         switch(ist->op.oprtype){
00284         case NyLPC_TcMiMicVM_OPR_TYPE_WM:
00285             tret=i_inst->_event_handler->native_call(i_inst->_event_handler,i_inst->wm[ist->wm_32.wm],i_inst);
00286             if(!NyLPC_cMiMicVM_RESULT_isOK(tret)){
00287                 *o_code=tret;
00288                 NyLPC_OnErrorGoto(ERROR_INHERIT);//エラー継承
00289             }
00290             break;
00291         case NyLPC_TcMiMicVM_OPR_TYPE_H32:
00292             tret=i_inst->_event_handler->native_call(i_inst->_event_handler,ist->h32_64.h32,i_inst);
00293             if(!NyLPC_cMiMicVM_RESULT_isOK(tret)){
00294                 *o_code=tret;
00295                 NyLPC_OnErrorGoto(ERROR_INHERIT);//エラー継承
00296             }
00297             break;
00298         default:
00299             NyLPC_OnErrorGoto(ERROR);
00300         }
00301         break;
00302     case NyLPC_TcMiMicVM_OP_TYPE_EXIT:
00303         *o_code=NyLPC_cMiMicVM_RESULT_OK;//OKに上書き
00304         return 0;
00305     default:
00306         NyLPC_OnErrorGoto(ERROR);
00307     }
00308     //実行したコードのワード長を返す。
00309     switch(ist->op.oprtype){
00310     case NyLPC_TcMiMicVM_OPR_TYPE_NONE:
00311     case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
00312     case NyLPC_TcMiMicVM_OPR_TYPE_WM_H08:
00313     case NyLPC_TcMiMicVM_OPR_TYPE_WM:
00314     case NyLPC_TcMiMicVM_OPR_TYPE_H08:
00315     case NyLPC_TcMiMicVM_OPR_TYPE_H16:
00316         *o_code=NyLPC_cMiMicVM_RESULT_OK;//OKに上書き
00317         return 1;
00318     case NyLPC_TcMiMicVM_OPR_TYPE_WM_H16:
00319     case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
00320     case NyLPC_TcMiMicVM_OPR_TYPE_H32:
00321         *o_code=NyLPC_cMiMicVM_RESULT_OK;//OKに上書き
00322         return 2;
00323     }
00324 ERROR:
00325     *o_code=NyLPC_cMiMicVM_RESULT_RUNTIME_NG;//ランタイムNG
00326 ERROR_INHERIT:
00327     return 0;
00328 }
00329 
00330 #define TEST
00331 #ifndef TEST
00332 
00333 #include "NyLPC_cMiMicTxtCompiler.h"
00334 void main(void)
00335 {
00336     struct NyLPC_TcMiMicVM_TEvent eh;
00337     NyLPC_TUInt32 ap;
00338     NyLPC_TcMiMicVM_t vm;
00339     struct NyLPC_TCharArrayPtr bc;
00340     NyLPC_TcMiMicTxtCompiler_t inst;
00341     struct NyLPC_TUInt32ArrayPtr bin;
00342     char BC[1024];
00343     int ist_len;
00344 
00345     NyLPC_TUInt16 l,bl;
00346     NyLPC_TUInt32 obuf[1024];
00347     NyLPC_cMiMicBcCompiler_initialize(&inst);
00348     sprintf(BC,"AA0102AB0100000001AE0203AF0200000003AI0304AJ0300000004AM07BA0505BE0607CA0304CB0300000005CE0304CF0300000005CI0304CJ0300000005ZA.E",&ap,&ap);
00349     bc.ptr=(char* )BC;
00350     bc.len=strlen(BC);
00351     bin.ptr=obuf;
00352     bin.len=100;
00353     ist_len=0;
00354 
00355     for(;;){
00356 
00357         switch(NyLPC_cMiMicBcCompiler_compileFragment(&inst,&bc,&bin,&bl,&l))
00358         {
00359         case NyLPC_TcMiMicTxtCompiler_RET_OK:
00360             //命令確定。
00361             NyLPC_TCharArrayPtr_seek(&bc,l);
00362             ist_len+=bl;
00363             break;
00364         case NyLPC_TcMiMicTxtCompiler_RET_OK_END:
00365             //命令終端
00366             NyLPC_cMiMicVM_initialize(&vm,&eh);
00367             if(!NyLPC_cMiMicVM_run(&vm,obuf,ist_len)){
00368                 printf("エンダァ");
00369             }
00370             printf("OK");
00371             break;
00372         case NyLPC_TcMiMicTxtCompiler_RET_CONTINUE:
00373             //蓄積中。
00374             NyLPC_TCharArrayPtr_seek(&bc,l);
00375             break;
00376         case NyLPC_TcMiMicTxtCompiler_RET_NG:
00377             printf("エラー");
00378             return;
00379         default:
00380             break;
00381         }
00382     }
00383 }
00384 #endif