1 /*********************************************************************************
\r
3 * --------------------------------------------------------------------------------
\r
5 * This file is part of MiMic
\r
6 * Copyright (C)2011 Ryo Iizuka
\r
8 * MiMic is free software: you can redistribute it and/or modify
\r
9 * it under the terms of the GNU Lesser General Public License as published
\r
10 * by the Free Software Foundation, either version 3 of the License, or
\r
11 * (at your option) any later version.
\r
13 * This program is distributed in the hope that it will be useful,
\r
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
16 * GNU General Public License for more details.
\r
18 * You should have received a copy of the GNU Lesser General Public License
\r
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
\r
21 * For further information please contact.
\r
23 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
\r
25 *********************************************************************************/
\r
28 #include "NyLPC_cMiMicVM_protected.h"
\r
30 static NyLPC_TUInt8 process_instruction(NyLPC_TcMiMicVM_t* i_inst,const union NyLPC_TcMiMicVM_TInstruction* ist);
\r
34 void NyLPC_cMiMicVM_initialize(NyLPC_TcMiMicVM_t* i_inst,struct NyLPC_TcMiMicVM_TEvent* i_handler)
\r
36 NyLPC_Assert(i_inst!=NULL);
\r
37 NyLPC_Assert(i_handler!=NULL);
\r
38 NyLPC_Assert(i_handler->get_stream!=NULL);
\r
39 NyLPC_Assert(i_handler->put_stream!=NULL);
\r
40 NyLPC_Assert(i_handler->sleep!=NULL);
\r
41 i_inst->_event_handler=i_handler;
\r
47 * 固定長命令+固定長データを実行します。
\r
48 * 関数の終了条件は、1.EXIT命令に到達する。2.インストラクションの終端に到達する。3.エラーが発生する。です。
\r
51 NyLPC_TBool NyLPC_cMiMicVM_run(NyLPC_TcMiMicVM_t* i_inst,const NyLPC_TUInt32* i_instruction,const NyLPC_TUInt16 i_size_of_instruction)
\r
53 //データ部をgetstreamと連動させること。
\r
55 NyLPC_TUInt8 proc_in_byte;
\r
57 if(i_size_of_instruction>0){
\r
58 proc_in_byte=process_instruction(i_inst,(const union NyLPC_TcMiMicVM_TInstruction*)(i_instruction+pc));
\r
60 //プログラムの終端に到達するか、0バイト処理の場合にブレーク。
\r
61 while(proc_in_byte>0 && pc<i_size_of_instruction){
\r
62 proc_in_byte=process_instruction(i_inst,(const union NyLPC_TcMiMicVM_TInstruction*)(i_instruction+pc));
\r
66 return i_inst->ret_code==0?NyLPC_TBool_TRUE:NyLPC_TBool_FALSE;
\r
73 * インストラクションを1個処理し、処理したバイト数を返す。
\r
74 * インストラクションの境界値はチェックされないので、コンパイル時にチェックしておくこと。
\r
76 * 処理したインストラクションのワード数(UInt32単位)。
\r
77 * 終了した場合は0を返す。0を返したときは、ret_codeメンバをチェックして、理由を調べること。
\r
79 static NyLPC_TUInt8 process_instruction(NyLPC_TcMiMicVM_t* i_inst,const union NyLPC_TcMiMicVM_TInstruction* ist)
\r
81 switch(ist->op.opc){
\r
82 case NyLPC_TcMiMicVM_OP_TYPE_AND:
\r
83 switch(ist->op.oprtype){
\r
84 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
\r
85 i_inst->wm[ist->wmwm_32.wm1]&=i_inst->wm[ist->wmwm_32.wm2];
\r
87 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
\r
88 i_inst->wm[ist->wmh32_64.wm]&=ist->wmh32_64.h32;
\r
91 NyLPC_OnErrorGoto(ERROR);
\r
94 case NyLPC_TcMiMicVM_OP_TYPE_OR:
\r
95 switch(ist->op.oprtype){
\r
96 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
\r
97 i_inst->wm[ist->wmwm_32.wm1]|=i_inst->wm[ist->wmwm_32.wm2];
\r
99 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
\r
100 i_inst->wm[ist->wmh32_64.wm]|=ist->wmh32_64.h32;
\r
103 NyLPC_OnErrorGoto(ERROR);
\r
106 case NyLPC_TcMiMicVM_OP_TYPE_XOR:
\r
107 switch(ist->op.oprtype){
\r
108 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
\r
109 i_inst->wm[ist->wmwm_32.wm1]^=i_inst->wm[ist->wmwm_32.wm2];
\r
111 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
\r
112 i_inst->wm[ist->wmh32_64.wm]^=ist->wmh32_64.h32;
\r
115 NyLPC_OnErrorGoto(ERROR);
\r
118 case NyLPC_TcMiMicVM_OP_TYPE_NOT:
\r
119 switch(ist->op.oprtype){
\r
120 case NyLPC_TcMiMicVM_OPR_TYPE_WM:
\r
121 i_inst->wm[ist->wm_32.wm]=~i_inst->wm[ist->wm_32.wm];
\r
124 NyLPC_OnErrorGoto(ERROR);
\r
127 case NyLPC_TcMiMicVM_OP_TYPE_SHL:
\r
128 switch(ist->op.oprtype){
\r
129 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H08:
\r
130 i_inst->wm[ist->wmh08_32.wm]=i_inst->wm[ist->wmh08_32.wm]<<ist->wmh08_32.h8;
\r
133 NyLPC_OnErrorGoto(ERROR);
\r
136 case NyLPC_TcMiMicVM_OP_TYPE_SHR:
\r
137 switch(ist->op.oprtype){
\r
138 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H08:
\r
139 i_inst->wm[ist->wmh08_32.wm]=i_inst->wm[ist->wmh08_32.wm]>>ist->wmh08_32.h8;
\r
142 NyLPC_OnErrorGoto(ERROR);
\r
145 case NyLPC_TcMiMicVM_OP_TYPE_ADD:
\r
146 switch(ist->op.oprtype){
\r
147 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
\r
148 i_inst->wm[ist->wmwm_32.wm1]+=i_inst->wm[ist->wmwm_32.wm2];
\r
150 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
\r
151 i_inst->wm[ist->wmh32_64.wm]+=ist->wmh32_64.h32;
\r
154 NyLPC_OnErrorGoto(ERROR);
\r
157 case NyLPC_TcMiMicVM_OP_TYPE_SUB:
\r
158 switch(ist->op.oprtype){
\r
159 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
\r
160 i_inst->wm[ist->wmwm_32.wm1]-=i_inst->wm[ist->wmwm_32.wm2];
\r
162 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
\r
163 i_inst->wm[ist->wmh32_64.wm]-=ist->wmh32_64.h32;
\r
166 NyLPC_OnErrorGoto(ERROR);
\r
169 case NyLPC_TcMiMicVM_OP_TYPE_MUL:
\r
170 switch(ist->op.oprtype){
\r
171 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
\r
172 i_inst->wm[ist->wmwm_32.wm1]*=i_inst->wm[ist->wmwm_32.wm2];
\r
174 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
\r
175 i_inst->wm[ist->wmh32_64.wm]*=ist->wmh32_64.h32;
\r
178 NyLPC_OnErrorGoto(ERROR);
\r
181 case NyLPC_TcMiMicVM_OP_TYPE_MGET:
\r
182 switch(ist->op.oprtype){
\r
183 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
\r
184 i_inst->wm[ist->wmh32_64.wm]=*((NyLPC_TUInt32*)(ist->wmh32_64.h32));
\r
187 NyLPC_OnErrorGoto(ERROR);
\r
190 case NyLPC_TcMiMicVM_OP_TYPE_MPUT:
\r
191 switch(ist->op.oprtype){
\r
192 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
\r
193 *((NyLPC_TUInt32*)(ist->wmh32_64.h32))=i_inst->wm[ist->wmh32_64.wm];
\r
196 NyLPC_OnErrorGoto(ERROR);
\r
199 case NyLPC_TcMiMicVM_OP_TYPE_SGET:
\r
200 switch(ist->op.oprtype){
\r
201 case NyLPC_TcMiMicVM_OPR_TYPE_WM:
\r
202 if(!i_inst->_event_handler->get_stream(i_inst->_event_handler,&(i_inst->wm[ist->wm_32.wm]))){
\r
203 NyLPC_OnErrorGoto(ERROR);
\r
207 NyLPC_OnErrorGoto(ERROR);
\r
210 case NyLPC_TcMiMicVM_OP_TYPE_SPUT:
\r
211 switch(ist->op.oprtype){
\r
212 case NyLPC_TcMiMicVM_OPR_TYPE_WM:
\r
213 if(!i_inst->_event_handler->put_stream(i_inst->_event_handler,i_inst->wm[ist->wm_32.wm])){
\r
214 NyLPC_OnErrorGoto(ERROR);
\r
217 case NyLPC_TcMiMicVM_OPR_TYPE_H32:
\r
218 if(!i_inst->_event_handler->put_stream(i_inst->_event_handler,ist->h32_64.h32)){
\r
219 NyLPC_OnErrorGoto(ERROR);
\r
223 NyLPC_OnErrorGoto(ERROR);
\r
226 case NyLPC_TcMiMicVM_OP_TYPE_LD:
\r
227 switch(ist->op.oprtype){
\r
228 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
\r
229 i_inst->wm[ist->wmwm_32.wm1]=i_inst->wm[ist->wmwm_32.wm2];
\r
231 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
\r
232 i_inst->wm[ist->wmh32_64.wm]=ist->wmh32_64.h32;
\r
235 NyLPC_OnErrorGoto(ERROR);
\r
238 case NyLPC_TcMiMicVM_OP_TYPE_NOP:
\r
239 switch(ist->op.oprtype){
\r
240 case NyLPC_TcMiMicVM_OPR_TYPE_NONE:
\r
242 case NyLPC_TcMiMicVM_OPR_TYPE_H08:
\r
243 i_inst->_event_handler->sleep(i_inst->_event_handler,ist->h8_32.h8);
\r
246 NyLPC_OnErrorGoto(ERROR);
\r
249 case NyLPC_TcMiMicVM_OP_TYPE_EXIT:
\r
250 i_inst->ret_code=0;
\r
253 NyLPC_OnErrorGoto(ERROR);
\r
256 switch(ist->op.oprtype){
\r
257 case NyLPC_TcMiMicVM_OPR_TYPE_NONE:
\r
258 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
\r
259 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H08:
\r
260 case NyLPC_TcMiMicVM_OPR_TYPE_WM:
\r
261 case NyLPC_TcMiMicVM_OPR_TYPE_H08:
\r
262 case NyLPC_TcMiMicVM_OPR_TYPE_H16:
\r
264 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H16:
\r
265 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
\r
266 case NyLPC_TcMiMicVM_OPR_TYPE_H32:
\r
270 i_inst->ret_code=1;
\r
277 #include "NyLPC_cMiMicTxtCompiler.h"
\r
280 struct NyLPC_TcMiMicVM_TEvent eh;
\r
282 NyLPC_TcMiMicVM_t vm;
\r
283 struct NyLPC_TCharArrayPtr bc;
\r
284 NyLPC_TcMiMicTxtCompiler_t inst;
\r
285 struct NyLPC_TUInt32ArrayPtr bin;
\r
289 NyLPC_TUInt16 l,bl;
\r
290 NyLPC_TUInt32 obuf[1024];
\r
291 NyLPC_cMiMicBcCompiler_initialize(&inst);
\r
292 sprintf(BC,"AA0102AB0100000001AE0203AF0200000003AI0304AJ0300000004AM07BA0505BE0607CA0304CB0300000005CE0304CF0300000005CI0304CJ0300000005ZA.E",&ap,&ap);
\r
301 switch(NyLPC_cMiMicBcCompiler_compileFragment(&inst,&bc,&bin,&bl,&l))
\r
303 case NyLPC_TcMiMicTxtCompiler_RET_OK:
\r
305 NyLPC_TCharArrayPtr_seek(&bc,l);
\r
308 case NyLPC_TcMiMicTxtCompiler_RET_OK_END:
\r
310 NyLPC_cMiMicVM_initialize(&vm,&eh);
\r
311 if(!NyLPC_cMiMicVM_run(&vm,obuf,ist_len)){
\r
316 case NyLPC_TcMiMicTxtCompiler_RET_CONTINUE:
\r
318 NyLPC_TCharArrayPtr_seek(&bc,l);
\r
320 case NyLPC_TcMiMicTxtCompiler_RET_NG:
\r