diff --git a/include/conio.h b/include/conio.h index f1749b3..32968e8 100644 --- a/include/conio.h +++ b/include/conio.h @@ -23,6 +23,25 @@ void dispmode40col(void); void dispmode80col(void); #endif +#define PETSCII_CURSOR_LEFT 0x9d +#define PETSCII_CURSOR_RIGHT 0x1d +#define PETSCII_CURSOR_UP 0x91 +#define PETSCII_CURSOR_DOWN 0x11 +#define PETSCII_HOME 0x13 +#define PETSCII_CLEAR 0x94 +#define PETSCII_DEL 0x14 +#define PETSCII_INSERT 0x94 + +#define PETSCII_F1 0x85 +#define PETSCII_F2 0x89 +#define PETSCII_F3 0x86 +#define PETSCII_F4 0x8a +#define PETSCII_F5 0x87 +#define PETSCII_F6 0x8b +#define PETSCII_F7 0x88 +#define PETSCII_F8 0x8c + + int kbhit(void); int getche(void); diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index b5ebba4..a550d4b 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -11350,7 +11350,8 @@ bool InterCodeBasicBlock::MergeCommonPathInstructions(void) nins->mSrc[0].mTemp = tins->mDst.mTemp; nins->mSrc[0].mType = tins->mDst.mType; assert(nins->mSrc[0].mTemp >= 0); - mInstructions.Insert(tindex, nins); + mFalseJump->mInstructions.Insert(0, nins); + fi++; } } mTrueJump->mInstructions.Remove(ti); @@ -13422,7 +13423,7 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams) { int offset = 0; if (ins->mSrc[0].mTemp < 0) - offset = ins->mSrc[0].mIntConst; + offset = int(ins->mSrc[0].mIntConst); if (ins->mSrc[0].mTemp >= 0 && ins->mSrc[1].mTemp >= 0) ins->mExpensive = true; @@ -18521,7 +18522,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "main"); + CheckFunc = !strcmp(mIdent->mString, "restore_expression"); CheckCase = false; mEntryBlock = mBlocks[0]; diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index d5ef5aa..9ec94dd 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -2440,8 +2440,6 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* vl = ToValue(proc, exp, block, inlineMapper, vl); vr = ToValue(proc, exp, block, inlineMapper, vr); - vr = Dereference(proc, exp, block, inlineMapper, vr); - InterInstruction * ins = new InterInstruction(MapLocation(exp, inlineMapper), IC_BINARY_OPERATOR); if (vl.mType->mType == DT_TYPE_POINTER || vl.mType->mType == DT_TYPE_ARRAY) @@ -2456,9 +2454,26 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ptype->mBase = vl.mType->mBase; ptype->mSize = 2; ptype->mStride = vl.mType->mStride; + vl.mReference = 0; vl.mType = ptype; } + if (vr.mType->mType == DT_TYPE_POINTER) + vr = Dereference(proc, exp, block, inlineMapper, vr); + else if (vr.mType->mType == DT_TYPE_ARRAY) + { + vr = Dereference(proc, exp, block, inlineMapper, vr, 1); + + Declaration* ptype = new Declaration(exp->mLocation, DT_TYPE_POINTER); + ptype->mBase = vr.mType->mBase; + ptype->mSize = 2; + ptype->mStride = vr.mType->mStride; + vr.mReference = 0; + vr.mType = ptype; + } + else + vr = Dereference(proc, exp, block, inlineMapper, vr); + if (vr.mType->IsIntegerType()) { InterInstruction * cins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT); @@ -2502,7 +2517,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType); block->Append(ins); } - else if (vr.mType->IsSame(vl.mType)) + else if (vr.mType->mType == DT_TYPE_POINTER && vr.mType->mBase->IsConstSame(vl.mType->mBase)) { if (exp->mToken == TK_SUB) { @@ -2626,6 +2641,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* else { vl = Dereference(proc, exp, block, inlineMapper, vl); + vr = Dereference(proc, exp, block, inlineMapper, vr); if (!vl.mType->IsNumericType()) mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Left hand operand type is not numeric"); diff --git a/oscar64/MachineTypes.h b/oscar64/MachineTypes.h index 77ea5d0..f0f320a 100644 --- a/oscar64/MachineTypes.h +++ b/oscar64/MachineTypes.h @@ -97,6 +97,25 @@ extern uint8 BC_REG_LOCALS; extern uint8 BC_REG_TMP; extern uint8 BC_REG_TMP_SAVED; +inline int ustrlen(const uint8* s) +{ + int i = 0; + while (s[i]) + i++; + return i; +} + +inline void ustrcpy(uint8* dp, const uint8* sp) +{ + int i = 0; + while (sp[i]) + { + dp[i] = sp[i]; + i++; + } + dp[i] = 0; +} + inline int64 int64max(int64 a, int64 b) { return a > b ? a : b; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index fe13409..8fc22b5 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -7303,6 +7303,14 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc, mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1)); sreg = BC_REG_ACCU; } + else if (size * sstride > 256) + { + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1)); + sreg = BC_REG_ACCU; + } else { sreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; @@ -7371,6 +7379,14 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc, mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1)); dreg = BC_REG_ADDR; } + else if (size * dstride > 256) + { + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1)); + dreg = BC_REG_ADDR; + } else { dreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; @@ -7378,12 +7394,27 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc, if (size <= msize) { + int si = 0; + int di = 0; for (int i = 0; i < size; i++) { - mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, i * sstride)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, si)); mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_INDIRECT_Y, sreg)); - mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, i* dstride)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, di)); mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_INDIRECT_Y, dreg)); + + si += sstride; + di += dstride; + if (si >= 256) + { + mIns.Push(NativeCodeInstruction(ins, ASMIT_INC, ASMIM_ZERO_PAGE, sreg + 1)); + si &= 0xff; + } + if (di >= 256) + { + mIns.Push(NativeCodeInstruction(ins, ASMIT_INC, ASMIM_ZERO_PAGE, dreg + 1)); + di &= 0xff; + } } return this; @@ -18847,6 +18878,27 @@ bool NativeCodeBasicBlock::SameTail(const NativeCodeInstruction& ins) const return false; } +bool NativeCodeBasicBlock::HasTailSTAX16(int& addr, int& index) const +{ + int sz = mIns.Size(); + if (sz >= 4) + { + sz -= 4; + if (mIns[sz + 0].mType == ASMIT_LDA && + mIns[sz + 1].mType == ASMIT_STA && mIns[sz + 1].mMode == ASMIM_ZERO_PAGE && + mIns[sz + 2].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDX, mIns[sz + 2].mMode) && + mIns[sz + 3].mType == ASMIT_STA && mIns[sz + 3].mMode == ASMIM_ZERO_PAGE && mIns[sz + 3].mAddress == mIns[sz + 1].mAddress + 1 && + !mIns[sz + 1].SameEffectiveAddress(mIns[sz + 2])) + { + addr = mIns[sz + 1].mAddress; + index = sz; + return true; + } + } + + return false; +} + bool NativeCodeBasicBlock::HasTailSTA(int& addr, int& index) const { int i = mIns.Size(); @@ -20277,6 +20329,42 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool while (eb->mIns.Size() > 0) { + int addr, index, taddr, tindex; + if (!mEntryRequiredRegs[CPU_REG_X] && eb->HasTailSTAX16(addr, index)) + { + i = 1; + while (i < mEntryBlocks.Size() && mEntryBlocks[i]->HasTailSTAX16(taddr, tindex) && taddr == addr) + i++; + if (i == mEntryBlocks.Size()) + { + mEntryRequiredRegs += CPU_REG_A; + mEntryRequiredRegs += CPU_REG_X; + + mIns.Insert(0, eb->mIns[index + 3]); + mIns.Insert(0, eb->mIns[index + 1]); + + mIns[0].mType = ASMIT_STX; + mIns[0].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_X | LIVE_CPU_REG_Y; + mIns[1].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_X | LIVE_CPU_REG_Y; + for (int i = 0; i < mEntryBlocks.Size(); i++) + { + NativeCodeBasicBlock* b = mEntryBlocks[i]; + b->HasTailSTAX16(taddr, tindex); + + b->mExitRequiredRegs += CPU_REG_A; + b->mExitRequiredRegs += CPU_REG_X; + + b->mIns[tindex + 0].mType = ASMIT_LDX; + for (int j = tindex; j < b->mIns.Size(); j++) + b->mIns[j].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_X; + + b->mIns.Remove(tindex + 3); + b->mIns.Remove(tindex + 1); + } + changed = true; + } + } + NativeCodeInstruction& ins(eb->mIns[eb->mIns.Size() - 1]); i = 1; while (i < mEntryBlocks.Size() && mEntryBlocks[i]->SameTail(ins)) @@ -20309,7 +20397,6 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool } else { - int addr, index, taddr, tindex; if (eb->HasTailSTA(addr, index)) { i = 1; @@ -20325,6 +20412,8 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool { NativeCodeBasicBlock* b = mEntryBlocks[i]; b->HasTailSTA(taddr, tindex); + b->mExitRequiredRegs += CPU_REG_A; + for (int j = tindex + 1; j < b->mIns.Size(); j++) b->mIns[j].mLive |= LIVE_CPU_REG_A; b->mIns.Remove(tindex); @@ -20348,6 +20437,7 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool { NativeCodeBasicBlock* b = mEntryBlocks[i]; b->HasTailSTX(taddr, tindex); + b->mExitRequiredRegs += CPU_REG_X; for (int j = tindex + 1; j < b->mIns.Size(); j++) b->mIns[j].mLive |= LIVE_CPU_REG_X; b->mIns.Remove(tindex); @@ -20371,6 +20461,7 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool { NativeCodeBasicBlock* b = mEntryBlocks[i]; b->HasTailSTY(taddr, tindex); + b->mExitRequiredRegs += CPU_REG_Y; for (int j = tindex + 1; j < b->mIns.Size(); j++) b->mIns[j].mLive |= LIVE_CPU_REG_Y; b->mIns.Remove(tindex); diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 1f94dfa..548e8a9 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -514,6 +514,7 @@ public: bool HasTailSTA(int& addr, int& index) const; bool HasTailSTX(int& addr, int& index) const; bool HasTailSTY(int& addr, int& index) const; + bool HasTailSTAX16(int& addr, int& index0) const; bool CanJoinEntryLoadStoreZP(int saddr, int daddr); bool DoJoinEntryLoadStoreZP(int saddr, int daddr); diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 020e582..d4facf3 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -1476,7 +1476,7 @@ Declaration * Parser::CopyConstantInitializer(int offset, Declaration* dtype, Ex uint8* Parser::ParseStringLiteral(int msize) { - int size = strlen(mScanner->mTokenString); + int size = ustrlen(mScanner->mTokenString); if (size + 1 > msize) msize = size + 1; uint8* d = new uint8[msize]; @@ -1484,7 +1484,7 @@ uint8* Parser::ParseStringLiteral(int msize) int i = 0; while (i < size) { - d[i] = mCharMap[(uint8)mScanner->mTokenString[i]]; + d[i] = mCharMap[mScanner->mTokenString[i]]; i++; } @@ -1499,7 +1499,7 @@ uint8* Parser::ParseStringLiteral(int msize) // automatic string concatenation while (mScanner->mToken == TK_STRING) { - int s = strlen(mScanner->mTokenString); + int s = ustrlen(mScanner->mTokenString); if (size + s + 1 > msize) msize = size + s + 1; @@ -1509,7 +1509,7 @@ uint8* Parser::ParseStringLiteral(int msize) int i = 0; while (i < s) { - nd[i + size] = mCharMap[(uint8)mScanner->mTokenString[i]]; + nd[i + size] = mCharMap[mScanner->mTokenString[i]]; i++; } size += s; @@ -5309,7 +5309,7 @@ Expression* Parser::ParseSimpleExpression(bool lhs) case TK_STRING: { dec = new Declaration(mScanner->mLocation, DT_CONST_DATA); - int size = strlen(mScanner->mTokenString); + int size = ustrlen(mScanner->mTokenString); dec->mSize = size + 1; dec->mVarIndex = -1; dec->mSection = mCodeSection; @@ -5337,7 +5337,7 @@ Expression* Parser::ParseSimpleExpression(bool lhs) // automatic string concatenation while (mScanner->mToken == TK_STRING) { - int s = strlen(mScanner->mTokenString); + int s = ustrlen(mScanner->mTokenString); uint8* d = new uint8[size + s + 1]; memcpy(d, dec->mData, size); int i = 0; @@ -10922,7 +10922,7 @@ void Parser::ParsePragma(void) ConsumeToken(TK_OPEN_PARENTHESIS); if (mScanner->mToken == TK_STRING) { - mCompilationUnits->AddUnit(mScanner->mLocation, mScanner->mTokenString, mScanner->mLocation.mFileName); + mCompilationUnits->AddUnit(mScanner->mLocation, (const char *)mScanner->mTokenString, mScanner->mLocation.mFileName); mScanner->NextToken(); } ConsumeToken(TK_CLOSE_PARENTHESIS); diff --git a/oscar64/Parser.h b/oscar64/Parser.h index ade1d6c..6bd5230 100644 --- a/oscar64/Parser.h +++ b/oscar64/Parser.h @@ -31,7 +31,7 @@ protected: bool ConsumeTokenIf(Token token); bool ConsumeIdentIf(const char* ident); - char mCharMap[256]; + uint8 mCharMap[256]; int mUnrollLoop; bool mUnrollLoopPage; bool mInlineCall; diff --git a/oscar64/Scanner.cpp b/oscar64/Scanner.cpp index ca60f20..59ada76 100644 --- a/oscar64/Scanner.cpp +++ b/oscar64/Scanner.cpp @@ -320,9 +320,9 @@ TokenSequence::TokenSequence(Scanner* scanner) { if (mToken == TK_STRING) { - int ssize = strlen(scanner->mTokenString); - char * str = new char[ssize + 1]; - strcpy_s(str, ssize + 1, scanner->mTokenString); + int ssize = ustrlen(scanner->mTokenString); + uint8 * str = new uint8[ssize + 1]; + ustrcpy(str, scanner->mTokenString); mTokenString = str; } } @@ -480,7 +480,7 @@ void Scanner::NextToken(void) mTokenNumber = mReplay->mTokenNumber; mTokenInteger = mReplay->mTokenInteger; if (mReplay->mTokenString) - strcpy_s(mTokenString, mReplay->mTokenString); + ustrcpy(mTokenString, mReplay->mTokenString); mReplay = mReplay->mNext; } @@ -583,8 +583,8 @@ void Scanner::NextPreToken(void) NextRawToken(); if (mToken == TK_STRING) { - if (!mPreprocessor->OpenSource("Including", mTokenString, true)) - mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Could not open source file", mTokenString); + if (!mPreprocessor->OpenSource("Including", (const char *)mTokenString, true)) + mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Could not open source file", (const char*)mTokenString); else if (mOnceDict->Lookup(Ident::Unique(mPreprocessor->mSource->mFileName))) mPreprocessor->CloseSource(); } @@ -592,8 +592,8 @@ void Scanner::NextPreToken(void) { mOffset--; StringToken('>', 'a'); - if (!mPreprocessor->OpenSource("Including", mTokenString, false)) - mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Could not open source file", mTokenString); + if (!mPreprocessor->OpenSource("Including", (const char*)mTokenString, false)) + mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Could not open source file", (const char*)mTokenString); else if (mOnceDict->Lookup(Ident::Unique(mPreprocessor->mSource->mFileName))) mPreprocessor->CloseSource(); } @@ -606,7 +606,7 @@ void Scanner::NextPreToken(void) int64 v = PrepParseConditional(); if (mLocation.mLine == l && mToken == TK_STRING) { - strcpy_s(mPreprocessor->mSource->mLocationFileName, mTokenString); + strcpy_s(mPreprocessor->mSource->mLocationFileName, (const char*)mTokenString); NextRawToken(); } mPreprocessor->mLocation.mLine = int(v) + mLocation.mLine - l; @@ -896,15 +896,15 @@ void Scanner::NextPreToken(void) if (mToken == TK_STRING) { - if (!mPreprocessor->EmbedData("Embedding", mTokenString, true, skip, limit, mode, decoder)) - mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Could not open source file", mTokenString); + if (!mPreprocessor->EmbedData("Embedding", (const char*)mTokenString, true, skip, limit, mode, decoder)) + mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Could not open source file", (const char*)mTokenString); } else if (mToken == TK_LESS_THAN) { mOffset--; StringToken('>', 'a'); - if (!mPreprocessor->EmbedData("Embedding", mTokenString, false, skip, limit, mode, decoder)) - mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Could not open source file", mTokenString); + if (!mPreprocessor->EmbedData("Embedding", (const char*)mTokenString, false, skip, limit, mode, decoder)) + mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Could not open source file", (const char*)mTokenString); } } else if (mToken == TK_IDENT) @@ -1785,14 +1785,14 @@ void Scanner::Error(const char* error) { mErrors->Error(mLocation, EERR_SYNTAX, error); } -static char p2smap[] = { 0x00, 0x20, 0x00, 0x40, 0x00, 0x60, 0x40, 0x60 }; +static uint8 p2smap[] = { 0x00, 0x20, 0x00, 0x40, 0x00, 0x60, 0x40, 0x60 }; -static inline char p2s(char ch) +static inline uint8 p2s(uint8 ch) { return (ch & 0x1f) | p2smap[ch >> 5]; } -static inline char transchar(char mode, char ch) +static inline uint8 transchar(char mode, uint8 ch) { switch (mode) { @@ -1800,8 +1800,10 @@ static inline char transchar(char mode, char ch) case 'a': return ch; case 'p': - if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') + if (ch >= 'a' && ch <= 'z') return ch ^ 0x20; + else if (ch >= 'A' && ch <= 'Z') + return ch ^ 0x80; else return ch; break; @@ -1938,7 +1940,7 @@ void Scanner::CharToken(char mode) int n = 0; - char ch = mLine[mOffset++]; + uint8 ch = mLine[mOffset++]; if (ch == '\\' && mLine[mOffset]) { @@ -1996,6 +1998,7 @@ void Scanner::CharToken(char mode) mTokenChar = transchar(mode, ch); mTokenInteger = mTokenChar; + assert(mTokenInteger >= 0); if (mLine[mOffset] && mLine[mOffset] == '\'') { diff --git a/oscar64/Scanner.h b/oscar64/Scanner.h index 1f41adc..ccf7149 100644 --- a/oscar64/Scanner.h +++ b/oscar64/Scanner.h @@ -219,7 +219,7 @@ struct TokenSequence Token mToken; const Ident * mTokenIdent; - const char * mTokenString; + const uint8 * mTokenString; double mTokenNumber; int64 mTokenInteger; @@ -256,7 +256,7 @@ public: bool mStartOfLine; const Ident * mTokenIdent; - char mTokenString[1024], mTokenChar; + uint8 mTokenString[1024], mTokenChar; uint8 * mTokenEmbed; int mTokenEmbedSize;