• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisión7e5a6010f234caa8d9ba8aa2af10e4cfc4ae224b (tree)
Tiempo2014-06-06 23:09:56
Autorhikarupsp <hikarupsp@user...>
Commiterhikarupsp

Log Message

LIMMが動くようになった

Cambiar Resumen

Diferencia incremental

--- a/chncpu/chncpu.c
+++ b/chncpu/chncpu.c
@@ -18,6 +18,7 @@ int main(int argc, const char * argv[])
1818 }
1919 env = CHNCPU_CreateRuntimeEnvironment();
2020 CHNCPU_LoadBinaryFromHexStringFilePath(env, argv[1]);
21+ CHNCPU_Execute(env);
2122 return 0;
2223 }
2324
@@ -119,6 +120,20 @@ CHNCPU_RuntimeEnvironment *CHNCPU_CreateRuntimeEnvironment(void)
119120
120121 env->appbinReader = malloc(sizeof(CH4Reader));
121122
123+ // bindOpFuncTable
124+ for(i = 0; i <= CHNCPU_OPECODE_MAX; i++){
125+ env->bindOpFuncTable[i] = NULL;
126+ }
127+ env->bindOpFuncTable[0x02] = CHNCPU_Op_LIMM_BindOperand;
128+
129+ // execOpFuncTable
130+ for(i = 0; i <= CHNCPU_OPECODE_MAX; i++){
131+ env->execOpFuncTable[i] = NULL;
132+ }
133+ env->execOpFuncTable[0x02] = CHNCPU_Op_LIMM_Execute;
134+
135+ env->errFlags = 0;
136+
122137 return env;
123138 }
124139
@@ -159,6 +174,7 @@ int CHNCPU_PrepareBinaryForExecution(CHNCPU_RuntimeEnvironment *env)
159174 int index, page;
160175 CHNCPU_OpTag *op;
161176 int breakFlag = 0;
177+ int retv;
162178
163179 // env->appbinReaderから読み込んで、実行可能な状態にする。
164180 // これはコンパイラ版におけるコンパイルに相当する。
@@ -169,7 +185,7 @@ int CHNCPU_PrepareBinaryForExecution(CHNCPU_RuntimeEnvironment *env)
169185 for(index = 0; index < CHNCPU_NUMBER_OF_OP_TAG; index++){
170186 opcode = CH4Reader_ReadNextAsUINT(env->appbinReader);
171187 if(CH4Reader_IsEndOfBinary(env->appbinReader)){
172- puts("< End of binary > \n");
188+ puts("< End of binary >");
173189 breakFlag = 1;
174190 break;
175191 }
@@ -180,32 +196,106 @@ int CHNCPU_PrepareBinaryForExecution(CHNCPU_RuntimeEnvironment *env)
180196 switch(opcode){
181197 case 0x00:
182198 // NOP
183- puts("NOP();");
184- break;
185- case 0x02:
186- // LIMM
187- CHNCPU_Op_LIMM_BindOperand(env, op);
199+ puts("NOP();\n");
200+ index--;
188201 break;
189202 default:
190- // Undefined
191- op->opCode = CHNCPU_OPCODE_INVALID;
192- puts("Undefined Opcode. \n");
193- breakFlag = 1;
203+ // ごく一部の特殊な命令以外は、命令テーブルを参照する
204+ if(opcode <= CHNCPU_OPECODE_MAX && env->bindOpFuncTable[opcode]){
205+ retv = env->bindOpFuncTable[opcode](env, op);
206+ if(retv){
207+ opcode = CHNCPU_OPCODE_INVALID;
208+ }
209+ } else{
210+ opcode = CHNCPU_OPCODE_INVALID;
211+ }
212+ if(opcode == CHNCPU_OPCODE_INVALID){
213+ op->opCode = CHNCPU_OPCODE_INVALID;
214+ env->errFlags |= CHNCPU_ERR_C_OPCODE;
215+ breakFlag = 1;
216+ }
194217 break;
195218 }
196219 if(breakFlag == 1){
197220 break;
198221 }
199- putchar('\n');
200222 }
201223 if(breakFlag){
202224 break;
203225 }
204226 }
227+ if(env->errFlags){
228+ putchar('\n');
229+ if(env->errFlags & CHNCPU_ERR_C_REGNUM){
230+ puts("INVALID-C: Invalid register number.");
231+ }
232+ if(env->errFlags & CHNCPU_ERR_C_BITS){
233+ puts("INVALID-C: Not supported bit width.");
234+ }
235+ if(env->errFlags & CHNCPU_ERR_C_OPCODE){
236+ puts("INVALID-C: Unknown opCode.");
237+ }
238+ }
205239
206240 return 0;
207241 }
208242
243+int CHNCPU_Execute(CHNCPU_RuntimeEnvironment *env)
244+{
245+ int breakFlag = 0;
246+ int count = 0;
247+ int retv;
248+ CHNCPU_OpTag *op;
249+
250+ puts("< Beginning of execution >");
251+ for(; env->currentPage < CHNCPU_NUMBER_OF_MEMORY_PAGE; env->currentPage++){
252+ op = &env->mainmemory[env->currentPage].data[0];
253+ if(op->opCode == CHNCPU_OPCODE_INVALID){
254+ // 空白のメモリページ:バイナリの末端
255+ puts(">>> Control reached end of binary.");
256+ breakFlag = 1;
257+ break;
258+ }
259+ for(; env->currentIndex < CHNCPU_NUMBER_OF_OP_TAG; env->currentIndex++){
260+ op = &env->mainmemory[env->currentPage].data[env->currentIndex];
261+ if(op->opCode == CHNCPU_OPCODE_INVALID){
262+ // このページはここでおしまい
263+ break;
264+ }
265+ if(op->opCode <= CHNCPU_OPECODE_MAX && env->bindOpFuncTable[op->opCode]){
266+ retv = env->execOpFuncTable[op->opCode](env, op);
267+ } else{
268+ // すでにチェックしたはずなのに不明な命令が来た
269+ env->errFlags |= CHNCPU_ERR_X_INTERNAL;
270+ breakFlag = 1;
271+ break;
272+ }
273+ if(retv){
274+ breakFlag = 1;
275+ break;
276+ }
277+
278+ }
279+ if(breakFlag){
280+ break;
281+ }
282+ count++;
283+ env->currentIndex = 0;
284+ }
285+ if(env->errFlags){
286+ putchar('\n');
287+ if(env->errFlags & CHNCPU_ERR_X_INTERNAL){
288+ puts("INVALID-X: Internal error.");
289+ }
290+ }
291+
292+ CHNCPU_DumpIReg(env);
293+
294+ puts("< End of execution >");
295+
296+ return count;
297+}
298+
209299 void CHNCPU_DumpAppBin(CHNCPU_RuntimeEnvironment *env)
210300 {
211301 int i;
@@ -221,4 +311,24 @@ void CHNCPU_DumpAppBin(CHNCPU_RuntimeEnvironment *env)
221311 }
222312 }
223313
314+void CHNCPU_DumpIReg(CHNCPU_RuntimeEnvironment *env)
315+{
316+ int i, regs = 0;
317+
318+ puts(">>> Integer registers");
319+
320+ for(i = 0; i < CHNCPU_NUMBER_OF_IREG; i++){
321+ if(env->iRegBits[i]){
322+ printf("R%02X:0x%08X(%2d) ", i, env->iReg[i], env->iRegBits[i]);
323+ if((regs & 0xF) == 0xF){
324+ putchar('\n');
325+ }
326+ regs++;
327+ }
328+ }
329+ if(((regs - 1) & 0xF) != 0xF){
330+ putchar('\n');
331+ }
332+}
333+
224334
--- a/chncpu/chncpu.h
+++ b/chncpu/chncpu.h
@@ -15,6 +15,7 @@
1515
1616 #define SIZE_TMPDATA (1024 * 1024 * 1)
1717
18+#define CHNCPU_OPECODE_MAX 0xFF
1819 #define CHNCPU_BITS_MAX 32
1920 #define CHNCPU_BITS_DEFAULT 32
2021 #define CHNCPU_NUMBER_OF_IREG 64
@@ -25,6 +26,9 @@
2526
2627 #define CHNCPU_ERR_C_REGNUM 1
2728 #define CHNCPU_ERR_C_BITS 2
29+#define CHNCPU_ERR_C_OPCODE 4
30+
31+#define CHNCPU_ERR_X_INTERNAL 1
2832
2933 typedef struct CHNCPU_OP_TAG CHNCPU_OpTag;
3034 struct CHNCPU_OP_TAG {
@@ -40,12 +44,16 @@ struct CHNCPU_MEMORY_PAGE {
4044
4145 typedef struct CHNCPU_RUN_TIME_ENVIRONMENT CHNCPU_RuntimeEnvironment;
4246 struct CHNCPU_RUN_TIME_ENVIRONMENT {
47+ int (*bindOpFuncTable[CHNCPU_OPECODE_MAX])(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op);
48+ int (*execOpFuncTable[CHNCPU_OPECODE_MAX])(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op);
4349 int iReg[CHNCPU_NUMBER_OF_IREG];
4450 int iRegBits[CHNCPU_NUMBER_OF_IREG];
4551 CHNCPU_MemoryPage mainmemory[CHNCPU_NUMBER_OF_MEMORY_PAGE];
4652 unsigned char *appbin0;
4753 int appbinsize;
4854 CH4Reader *appbinReader;
55+ unsigned int errFlags;
56+ int currentPage, currentIndex;
4957 };
5058
5159 typedef struct CHNCPU_OP_CACHE_LIMM CHNCPU_OpCache_LIMM;
@@ -60,9 +68,12 @@ int decodeHexString(char *src0, char *src1, unsigned char *dst0, unsigned char *
6068 CHNCPU_RuntimeEnvironment *CHNCPU_CreateRuntimeEnvironment(void);
6169 int CHNCPU_LoadBinaryFromHexStringFilePath(CHNCPU_RuntimeEnvironment *env, const char *path);
6270 int CHNCPU_PrepareBinaryForExecution(CHNCPU_RuntimeEnvironment *env);
71+int CHNCPU_Execute(CHNCPU_RuntimeEnvironment *env);
6372 void CHNCPU_DumpAppBin(CHNCPU_RuntimeEnvironment *env);
73+void CHNCPU_DumpIReg(CHNCPU_RuntimeEnvironment *env);
6474
6575 // @opcode.c
6676 int CHNCPU_Op_LIMM_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op);
77+int CHNCPU_Op_LIMM_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op);
6778
6879 #endif
--- a/chncpu/opcode.c
+++ b/chncpu/opcode.c
@@ -19,16 +19,35 @@ int CHNCPU_Op_LIMM_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op)
1919 opCache->r = CH4Reader_ReadNextAsUINT(env->appbinReader);
2020 opCache->bit = CH4Reader_ReadNextAsUINT(env->appbinReader);
2121
22- printf("LIMM(imm:0x%X r:%d bit:%d);", opCache->imm, opCache->r, opCache->bit);
22+ printf("LIMM(imm:0x%X r:%d bit:%d);\n", opCache->imm, opCache->r, opCache->bit);
2323
2424 if(opCache->r >= CHNCPU_NUMBER_OF_IREG){
25- puts("INVALID-C: register number.");
26- return CHNCPU_ERR_C_REGNUM;
25+ env->errFlags |= CHNCPU_ERR_C_REGNUM;
26+ return -1;
2727 }
2828 if(opCache->bit > CHNCPU_BITS_MAX){
29- puts("INVALID-C: bits.");
30- return CHNCPU_ERR_C_BITS;
29+ env->errFlags |= CHNCPU_ERR_C_BITS;
30+ return -1;
3131 }
3232 return 0;
3333 }
3434
35+int CHNCPU_Op_LIMM_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op)
36+{
37+ CHNCPU_OpCache_LIMM *opCache;
38+
39+ opCache = op->opCache;
40+
41+ printf("LIMM(imm:0x%X r:%d bit:%d);\n", opCache->imm, opCache->r, opCache->bit);
42+
43+ env->iReg[opCache->r] = opCache->imm;
44+ if(opCache->bit){
45+ env->iRegBits[opCache->r] = opCache->bit;
46+ } else{
47+ env->iRegBits[opCache->r] = CHNCPU_BITS_DEFAULT;
48+ }
49+
50+ return 0;
51+}
52+
53+
--- a/chncpu/test.hex
+++ b/chncpu/test.hex
@@ -1 +1 @@
1-2 E123 0 0
\ No newline at end of file
1+2 E123 0 0 2 E365 1 0
\ No newline at end of file