• 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

Revision02e7802a777427cfeb46618c31fa011048021531 (tree)
Time2014-07-02 17:55:33
Authorhikarupsp <hikarupsp@user...>
Commiterhikarupsp

Log Message

LIMM命令を追加
テストコードはASCII文字列の表示
ch4_sintのバグを修正

Change Summary

Incremental Difference

--- a/chncpu/ch4.c
+++ b/chncpu/ch4.c
@@ -128,7 +128,7 @@ ch4_uint CH4Reader_ReadBodyAtIndexAsUINT(CH4Reader *reader, int index, int *retR
128128 value = tmp;
129129 //
130130 readIndex = 1;
131- reader->lastBits = 4;
131+ reader->lastBits = 3;
132132 }
133133 } else{
134134 if((tmp & 4) == 0){
@@ -139,7 +139,7 @@ ch4_uint CH4Reader_ReadBodyAtIndexAsUINT(CH4Reader *reader, int index, int *retR
139139 value |= tmp & 0xf;
140140 //
141141 readIndex = 2;
142- reader->lastBits = 8;
142+ reader->lastBits = 6;
143143 } else if((tmp & 2) == 0){
144144 // 12bit
145145 value = tmp & 1;
@@ -151,7 +151,7 @@ ch4_uint CH4Reader_ReadBodyAtIndexAsUINT(CH4Reader *reader, int index, int *retR
151151 value |= tmp & 0xf;
152152 //
153153 readIndex = 3;
154- reader->lastBits = 12;
154+ reader->lastBits = 9;
155155 } else if((tmp & 1) == 0){
156156 // 16bit
157157 tmp = CH4Reader_Internal_Read4bitAtIndex(reader, index + 1);
@@ -164,7 +164,7 @@ ch4_uint CH4Reader_ReadBodyAtIndexAsUINT(CH4Reader *reader, int index, int *retR
164164 value |= tmp & 0xf;
165165 //
166166 readIndex = 4;
167- reader->lastBits = 16;
167+ reader->lastBits = 12;
168168 } else{
169169 // padding
170170 puts("CH4_READ_ERROR_TRAP_PADDING \n");
--- a/chncpu/chncpu.c
+++ b/chncpu/chncpu.c
@@ -99,7 +99,8 @@ int decodeHexString(char *src0, char *src1, unsigned char *dst0, unsigned char *
9999 int wlen = 0;
100100 // 0: first 4-bit
101101 // 1: second 4-bit
102- // 2: in literal string
102+ // 2: in string literal (byte aligned)
103+ // 3: in string literal (not aligned)
103104 unsigned char d = 0;
104105 char c;
105106
@@ -107,36 +108,35 @@ int decodeHexString(char *src0, char *src1, unsigned char *dst0, unsigned char *
107108
108109 for(p = src0; p != src1; p++){
109110 c = *p;
110- if('0' <= c && c <= '9'){
111- c = c - '0';
112- } else if('A' <= c && c <= 'F'){
113- c = c - 'A' + 0x0A;
114- } else if('a' <= c && c <= 'f'){
115- c = c - 'a' + 0x0a;
116- } else if(c == '"'){
117- if(phase == 0){
118- phase = 2;
119- } else if(phase == 1){
120- puts("chncpu:Error > HexString padding error, abort.\n");
121- exit(EXIT_FAILURE);
122- } else if(phase == 2){
123- phase = 0;
124- }
125- continue;
126- } else if(phase == 2){
127- puts("decodeHexString: not implemented.\n");
128- exit(EXIT_FAILURE);
129- } else{
130- if(c == ' ' || c == '\t' || c == '\n'){
111+ if(c == '"'){
112+ if(phase == 0){
113+ phase = 2;
114+ } else if(phase == 1){
115+ phase = 3;
116+ } else if(phase == 2){
117+ phase = 0;
118+ } else if(phase == 3){
119+ phase = 1;
120+ }
121+ continue;
122+ } else if(phase == 0 || phase == 1){
123+ if('0' <= c && c <= '9'){
124+ c = c - '0';
125+ } else if('A' <= c && c <= 'F'){
126+ c = c - 'A' + 0x0A;
127+ } else if('a' <= c && c <= 'f'){
128+ c = c - 'a' + 0x0a;
129+ } else if(c == ' ' || c == '\t' || c == '\n'){
131130 continue;
132- }
133- puts("decodeHexString: unknown character :");
134- putchar(c);
135- putchar('\n');
136- exit(EXIT_FAILURE);
137- break;
131+ } else{
132+ puts("decodeHexString: unexpected character :");
133+ putchar(c);
134+ putchar('\n');
135+ exit(EXIT_FAILURE);
136+ break;
137+ }
138138 }
139- if(phase == 0){
139+ if(phase == 0){
140140 d = c & 0x0f;
141141 phase = 1;
142142 } else if(phase == 1){
@@ -150,6 +150,14 @@ int decodeHexString(char *src0, char *src1, unsigned char *dst0, unsigned char *
150150 *wp = c;
151151 wp++;
152152 wlen++;
153+ } else if(phase == 3){
154+ d <<= 4;
155+ d |= (c >> 4) & 0x0f;
156+ *wp = d;
157+ wp++;
158+ wlen++;
159+ //
160+ d = c & 0x0f;
153161 }
154162
155163 if(wp >= dst1){
@@ -192,6 +200,7 @@ CHNCPU_RuntimeEnvironment *CHNCPU_CreateRuntimeEnvironment(CHNCPU_OpTableSet *op
192200 for(i = 0; i < CHNCPU_NUMBER_OF_PREG; i++){
193201 env->pReg[i].type = 0;
194202 env->pReg[i].mindex = 0;
203+ env->pReg[i].pindex = 0;
195204 }
196205
197206 // ラベル管理初期化
@@ -228,8 +237,10 @@ int CHNCPU_LoadBinaryFromHexStringFilePath(CHNCPU_RuntimeEnvironment *env, const
228237 }
229238
230239 env->appbinsize = decodeHexString(tmpdata0, tmpdata0 + len, env->appbin0, env->appbin0 + CHNCPU_SIZE_APPBIN);
231- //printf("appbin = %d Bytes\n", env->appbinsize);
232- //CHNCPU_DumpAppBin(env);
240+#if DEBUG_PRINT_APPBIN_BEFORE_EXECUTION
241+ printf("appbin = %d Bytes\n", env->appbinsize);
242+ CHNCPU_DumpAppBin(env);
243+#endif
233244
234245 CH4Reader_Initialize(env->appbinReader, env->appbin0, env->appbinsize);
235246
@@ -330,6 +341,9 @@ int CHNCPU_PrepareBinaryForExecution(CHNCPU_RuntimeEnvironment *env)
330341 if(env->errFlags & CHNCPU_ERR_C_DUPLICATED_LB){
331342 puts("INVALID-C: Duplicated LabelID.");
332343 }
344+ if(env->errFlags & CHNCPU_ERR_C_UNAVAILABLE_PTYPE){
345+ puts("INVALID-C: Unavailable pointer type.");
346+ }
333347 }
334348 env->currentIndex = 0;
335349 env->currentLabel = 0;
@@ -383,6 +397,15 @@ int CHNCPU_Execute(CHNCPU_RuntimeEnvironment *env)
383397 if(env->errFlags & CHNCPU_ERR_X_LABEL_NOT_FOUND){
384398 puts("INVALID-X: Label not found.");
385399 }
400+ if(env->errFlags & CHNCPU_ERR_X_PTYPE_NOT_MATCHED){
401+ puts("INVALID-X: Pointer type not matched.");
402+ }
403+ if(env->errFlags & CHNCPU_ERR_X_BAD_ACCESS){
404+ puts("INVALID-X: Bad access.");
405+ }
406+ if(env->errFlags & CHNCPU_ERR_X_INVALID_PTYPE){
407+ puts("INVALID-X: Invalid pointer type.");
408+ }
386409 }
387410
388411 #if DEBUG_PRINT_IREG_AFTER_EXECUTION
@@ -417,7 +440,7 @@ void CHNCPU_DumpIReg(CHNCPU_RuntimeEnvironment *env)
417440
418441 for(i = 0; i < CHNCPU_NUMBER_OF_IREG; i++){
419442 if(env->iRegBits[i]){
420- printf("R%02X = %010d = 0x%08X(%2d) ", i, env->iReg[i], env->iReg[i], env->iRegBits[i]);
443+ printf("R%02X = %10d = 0x%08X(%2d) ", i, env->iReg[i], env->iReg[i], env->iRegBits[i]);
421444 putchar('\n');
422445 regs++;
423446 }
--- a/chncpu/chncpu.h
+++ b/chncpu/chncpu.h
@@ -15,8 +15,9 @@
1515 #include "ch4.h"
1616
1717 // DEBUG Flag
18-#define DEBUG_PRINT_IREG_AFTER_EXECUTION 1
19-#define DEBUG_PRINT_OP_BINDING 1
18+#define DEBUG_PRINT_APPBIN_BEFORE_EXECUTION 0
19+#define DEBUG_PRINT_IREG_AFTER_EXECUTION 0
20+#define DEBUG_PRINT_OP_BINDING 0
2021 #define DEBUG_PRINT_OP_EXECUTING 0
2122
2223 // VM flags
@@ -51,6 +52,9 @@
5152 #define CHNCPU_ERR_X_INTERNAL 0x01
5253 #define CHNCPU_ERR_X_TRUNCATED_VALUE 0x02
5354 #define CHNCPU_ERR_X_LABEL_NOT_FOUND 0x04
55+#define CHNCPU_ERR_X_PTYPE_NOT_MATCHED 0x08
56+#define CHNCPU_ERR_X_BAD_ACCESS 0x10
57+#define CHNCPU_ERR_X_INVALID_PTYPE 0x20
5458
5559 // (2F)Prefix
5660 #define CHNCPU_PREFIX_ALLOW_TRUNCATE 0x01
@@ -76,6 +80,9 @@
7680 // 0x40 UINT32
7781 // 0x41 SINT32
7882
83+// Opcode
84+#define CHNCPU_OP_DATA 0x2E
85+
7986 typedef struct _CHNCPU_OP_TAG CHNCPU_OpTag;
8087 typedef struct _CHNCPU_BIOS CHNCPU_BIOS;
8188 typedef struct _CHNCPU_OP_TABLE_SET CHNCPU_OpTableSet;
@@ -85,8 +92,6 @@ typedef struct _CHNCPU_POINTER_TAG CHNCPU_PointerTag;
8592 typedef struct _CHNCPU_RUN_TIME_ENVIRONMENT CHNCPU_RuntimeEnvironment;
8693 typedef struct _CHNCPU_VM_ARGS CHNCPU_VMArgs;
8794
88-
89-
9095 struct _CHNCPU_OP_TAG {
9196 int opCode;
9297 void *opCache;
@@ -107,8 +112,9 @@ struct _CHNCPU_OP_TABLE_SET {
107112
108113 struct _CHNCPU_LABEL_TAG {
109114 ch4_uint labelID;
110- ch4_uint opt; // 0:local(R3F Only) 1:public(can be saved to memory, pRegs)
115+ ch4_uint opt; // 0:local(R3F Only) 1:public(can be stored to memory, pRegs)
111116 int mindex;
117+ ch4_sint pType;
112118 CHNCPU_LabelTag *next;
113119 };
114120
@@ -119,6 +125,7 @@ struct _CHNCPU_LABEL_SET {
119125 struct _CHNCPU_POINTER_TAG {
120126 ch4_sint type; // CHNCPU_PType_xx
121127 int mindex;
128+ int pindex;
122129 };
123130
124131 struct _CHNCPU_RUN_TIME_ENVIRONMENT {
@@ -186,6 +193,11 @@ int CHNCPU_Op_CALLBIOS_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op)
186193 int CHNCPU_Op_CALLBIOS_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file);
187194 int CHNCPU_Op_CALLBIOS_PrintWikiDoc(int opCode, FILE *file);
188195 //
196+int CHNCPU_Op_LMEM_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, unsigned int prefix);
197+int CHNCPU_Op_LMEM_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op);
198+int CHNCPU_Op_LMEM_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file);
199+int CHNCPU_Op_LMEM_PrintWikiDoc(int opCode, FILE *file);
200+//
189201 int CHNCPU_Op_TernaryReg_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, unsigned int prefix);
190202 int CHNCPU_Op_TernaryRegBitwise_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op);
191203 int CHNCPU_Op_TernaryRegArithmetic_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op);
@@ -201,6 +213,7 @@ int CHNCPU_Op_DATA_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op,
201213 int CHNCPU_Op_DATA_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op);
202214 int CHNCPU_Op_DATA_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file);
203215 int CHNCPU_Op_DATA_PrintWikiDoc(int opCode, FILE *file);
216+int CHNCPU_Op_DATA_ReadAtIndex(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, int index);
204217 //
205218 int CHNCPU_Op_Prefix2F_PrintWikiDoc(int opCode, FILE *file);
206219
@@ -213,7 +226,7 @@ int CHNCPU_BIOS_Op_putcReg_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTa
213226
214227 // @label.c
215228 CHNCPU_LabelSet *CHNCPU_CreateLabelSet(void);
216-int CHNCPU_Label_Add(CHNCPU_LabelSet *lbSet, int mindex, int labelID, int opt);
229+int CHNCPU_Label_Add(CHNCPU_LabelSet *lbSet, int mindex, ch4_uint labelID, ch4_uint opt, ch4_sint pType);
217230 CHNCPU_LabelTag *CHNCPU_Label_GetTagFromLabelID(CHNCPU_LabelSet *lbSet, int labelID);
218231
219232 #endif
--- a/chncpu/label.c
+++ b/chncpu/label.c
@@ -26,9 +26,9 @@ CHNCPU_LabelSet *CHNCPU_CreateLabelSet(void)
2626 return lbSet;
2727 }
2828
29-int CHNCPU_Label_Add(CHNCPU_LabelSet *lbSet, int mindex, int labelID, int opt)
29+int CHNCPU_Label_Add(CHNCPU_LabelSet *lbSet, int mindex, ch4_uint labelID, ch4_uint opt, ch4_sint pType)
3030 {
31- // retv: false:succeeded true:failed
31+ // retv: 0:succeeded -1:alreadyExisted -2:mallocError
3232 CHNCPU_LabelTag *t = &lbSet->top;
3333 for(;;){
3434 if(t->labelID == labelID){
@@ -45,12 +45,13 @@ int CHNCPU_Label_Add(CHNCPU_LabelSet *lbSet, int mindex, int labelID, int opt)
4545 t->next = malloc(sizeof(CHNCPU_LabelTag));
4646 if(t->next){
4747 t = t->next;
48+ t->pType = pType;
4849 t->mindex = mindex;
4950 t->labelID = labelID;
5051 t->opt = opt;
5152 t->next = NULL;
5253 } else{
53- return -1;
54+ return -2;
5455 }
5556
5657 return 0;
--- a/chncpu/opcode.c
+++ b/chncpu/opcode.c
@@ -68,6 +68,12 @@ int CHNCPU_Op_Init(CHNCPU_OpTableSet *opSet)
6868 opSet->printFuncTable[0x05] = CHNCPU_Op_CALLBIOS_PrintCode;
6969 opSet->docFuncTable[0x05] = CHNCPU_Op_CALLBIOS_PrintWikiDoc;
7070
71+ // LMEM
72+ opSet->bindFuncTable[0x08] = CHNCPU_Op_LMEM_BindOperand;
73+ opSet->execFuncTable[0x08] = CHNCPU_Op_LMEM_Execute;
74+ opSet->printFuncTable[0x08] = CHNCPU_Op_LMEM_PrintCode;
75+ opSet->docFuncTable[0x08] = CHNCPU_Op_LMEM_PrintWikiDoc;
76+
7177 // TernaryRegBitwise
7278 for(i = 0x10; i <= 0x12; i++){
7379 opSet->bindFuncTable[i] = CHNCPU_Op_TernaryReg_BindOperand;
@@ -139,7 +145,7 @@ int CHNCPU_Op_LB_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, u
139145
140146 env->currentLabel = opCache->labelID;
141147
142- if(CHNCPU_Label_Add(env->labelSet, env->currentIndex, opCache->labelID, opCache->opt)){
148+ if(CHNCPU_Label_Add(env->labelSet, env->currentIndex, opCache->labelID, opCache->opt, CHNCPU_PType_Label)){
143149 env->errFlags |= CHNCPU_ERR_C_DUPLICATED_LB;
144150 }
145151
@@ -216,6 +222,11 @@ int CHNCPU_Op_LIMM_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op,
216222 env->errFlags |= CHNCPU_ERR_C_PREFIX;
217223 return -1;
218224 }
225+ CHNCPU_AdjustValueForBit(env, &opCache->imm, opCache->bit, CHNCPU_PREFIX_ALLOW_TRUNCATE);
226+ if(env->errFlags){
227+ return -1;
228+ }
229+
219230 return 0;
220231 }
221232 int CHNCPU_Op_LIMM_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op)
@@ -224,7 +235,7 @@ int CHNCPU_Op_LIMM_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op)
224235
225236 opCache = op->opCache;
226237
227- env->iReg[opCache->r] = opCache->imm & (0xFFFFFFFF >> (32 - opCache->bit));
238+ env->iReg[opCache->r] = opCache->imm;
228239 env->iRegBits[opCache->r] = opCache->bit;
229240
230241 return 0;
@@ -294,7 +305,7 @@ int CHNCPU_Op_PLIMM_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op)
294305 }
295306
296307 env->pReg[opCache->r].mindex = label->mindex;
297- env->pReg[opCache->r].type = CHNCPU_PType_Label;
308+ env->pReg[opCache->r].type = label->pType;
298309
299310 if(opCache->r == 0x3F){
300311 if(env->pReg[0x3F].type == CHNCPU_PType_Label){
@@ -460,6 +471,95 @@ int CHNCPU_Op_CALLBIOS_PrintWikiDoc(int opCode, FILE *file)
460471 }
461472
462473 //
474+// 08 LMEM
475+//
476+
477+typedef struct _CHNCPU_OP_CACHE_LMEM CHNCPU_OpCache_LMEM;
478+struct _CHNCPU_OP_CACHE_LMEM {
479+ ch4_uint p;
480+ ch4_sint pType;
481+ ch4_sint pDiff;
482+ ch4_uint r;
483+ ch4_uint bitDst;
484+};
485+int CHNCPU_Op_LMEM_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, unsigned int prefix)
486+{
487+ CHNCPU_OpCache_LMEM *opCache;
488+
489+ opCache = malloc(sizeof(CHNCPU_OpCache_LMEM));
490+ op->opCache = opCache;
491+
492+ opCache->p = CH4Reader_ReadNextAsUINT(env->appbinReader);
493+ opCache->pType = CH4Reader_ReadNextAsSINT(env->appbinReader);
494+ opCache->pDiff = CH4Reader_ReadNextAsSINT(env->appbinReader);
495+ opCache->r = CH4Reader_ReadNextAsUINT(env->appbinReader);
496+ opCache->bitDst = CH4Reader_ReadNextAsUINT(env->appbinReader);
497+
498+ if(opCache->r >= CHNCPU_NUMBER_OF_IREG ||
499+ opCache->p >= CHNCPU_NUMBER_OF_PREG){
500+ env->errFlags |= CHNCPU_ERR_C_REGNUM;
501+ return -1;
502+ }
503+ if(!CHNCPU_CHK_IsAvailableBits(env, opCache->bitDst)){
504+ return -1;
505+ }
506+ if(prefix != 0){
507+ env->errFlags |= CHNCPU_ERR_C_PREFIX;
508+ return -1;
509+ }
510+ return 0;
511+}
512+int CHNCPU_Op_LMEM_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op)
513+{
514+ CHNCPU_OpCache_LMEM *opCache;
515+ CHNCPU_PointerTag *p;
516+ int value;
517+
518+ opCache = op->opCache;
519+ p = &env->pReg[opCache->p];
520+
521+ if(p->type != opCache->pType){
522+ env->errFlags |= CHNCPU_ERR_X_PTYPE_NOT_MATCHED;
523+ return -1;
524+ }
525+
526+ value = CHNCPU_Op_DATA_ReadAtIndex(env, &env->mainmemory[p->mindex], p->pindex);
527+ if(env->errFlags){
528+ return -1;
529+ }
530+
531+ CHNCPU_AdjustValueForBit(env, &value, opCache->bitDst, CHNCPU_PREFIX_ALLOW_TRUNCATE);
532+ if(env->errFlags){
533+ return -1;
534+ }
535+ env->iReg[opCache->r] = value;
536+ env->iRegBits[opCache->r] = opCache->bitDst;
537+
538+ p->pindex += opCache->pDiff;
539+
540+ return 0;
541+}
542+int CHNCPU_Op_LMEM_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file)
543+{
544+ CHNCPU_OpCache_LMEM *opCache;
545+
546+ opCache = op->opCache;
547+ fprintf(file, "LMEM(p:0x%02X, pType:0x%X, pDiff:%d, r:%02X, bitDst:%d);\n", opCache->p, opCache->pType, opCache->pDiff, opCache->r, opCache->bitDst);
548+
549+ return 0;
550+}
551+int CHNCPU_Op_LMEM_PrintWikiDoc(int opCode, FILE *file)
552+{
553+ fprintf(file, ", %s, %02X, %X, %s, %s, %s, %s, %s, %s, %s, %s, %s\n",
554+ "LMEM",
555+ 0x08, 0x08 + 0x80,
556+ "p", "(sint)pType", "(sint)pDiff", "r", "bitDst", "", "",
557+ "", "");
558+
559+ return 0;
560+}
561+
562+//
463563 // Ternary Register Operation
464564 //
465565
@@ -869,7 +969,7 @@ int CHNCPU_Op_DATA_BindOperand(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op,
869969 }
870970 }
871971
872- if(CHNCPU_Label_Add(env->labelSet, env->currentIndex, opCache->labelID, opCache->labelOpt)){
972+ if(CHNCPU_Label_Add(env->labelSet, env->currentIndex, opCache->labelID, opCache->labelOpt, opCache->dataType)){
873973 env->errFlags |= CHNCPU_ERR_C_DUPLICATED_LB;
874974 }
875975
@@ -884,10 +984,9 @@ int CHNCPU_Op_DATA_Execute(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op)
884984 // 何もしない
885985 return 0;
886986 }
887-
888987 int CHNCPU_Op_DATA_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, FILE *file)
889988 {
890- int i;
989+ int i = 0;
891990 CHNCPU_OpCache_DATA *opCache;
892991 opCache = op->opCache;
893992
@@ -912,7 +1011,6 @@ int CHNCPU_Op_DATA_PrintCode(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, F
9121011
9131012 return 0;
9141013 }
915-
9161014 int CHNCPU_Op_DATA_PrintWikiDoc(int opCode, FILE *file)
9171015 {
9181016 fprintf(file, ", %s, %02X, %X, %s, %s, %s, %s, %s, %s, %s, %s, %s\n",
@@ -923,6 +1021,26 @@ int CHNCPU_Op_DATA_PrintWikiDoc(int opCode, FILE *file)
9231021
9241022 return 0;
9251023 }
1024+int CHNCPU_Op_DATA_ReadAtIndex(CHNCPU_RuntimeEnvironment *env, CHNCPU_OpTag *op, int index)
1025+{
1026+ int retv;
1027+ CHNCPU_OpCache_DATA *opCache;
1028+
1029+ opCache = op->opCache;
1030+ if(op->opCode != 0x2E || index < 0 || index >= opCache->dataCount){
1031+ env->errFlags |= CHNCPU_ERR_X_BAD_ACCESS;
1032+ return 0;
1033+ }
1034+
1035+ if(opCache->dataType == CHNCPU_PType_UINT8){
1036+ retv = ((unsigned char *)opCache->rawData)[index];
1037+ } else{
1038+ env->errFlags |= CHNCPU_ERR_X_INVALID_PTYPE;
1039+ return 0;
1040+ }
1041+
1042+ return retv;
1043+}
9261044
9271045 //
9281046 // Prefix2F
--- a/chncpu/test.hex
+++ b/chncpu/test.hex
@@ -1,10 +1,12 @@
1-2 a0 0 90
2-AE 4 0 90 4 12 34 56 78
1+AE 4 0 90 6 "Hello!"
2+2 0 0 90
33 2 1 1 90
4-2 C7E 2 90
4+2 86 2 90
5+3 4 0
56 1 1 0
6-5 0 0
7+88 0 90 1 bf 90
8+5 0 bf
79 94 0 1 0 90
8-a4 0 2 90 bf 90
10+a2 0 2 90 bf 90
911 4 bf
1012 3 1 bf