From 23d5f003b063daf60c2f1837bae653a637091944 Mon Sep 17 00:00:00 2001 From: afanofosc Date: Thu, 9 Feb 2012 06:12:26 +0000 Subject: version 1.32 added variable-based jumps and calls/exittos added toupper and tolower arrops added text drawing to any Y value git-svn-id: https://mindboards.svn.sourceforge.net/svnroot/mindboards/lms_nbcnxc/branches/version_131@45 c9361245-7fe8-9947-84e8-057757c4e366 --- AT91SAM7S256/Source/c_cmd.c | 123 ++++++++++++++++++++++++++++++---- AT91SAM7S256/Source/c_cmd_bytecodes.h | 24 ++++--- AT91SAM7S256/Source/c_cmd_drawing.inc | 53 ++++++++++++--- AT91SAM7S256/Source/c_loader.iom | 2 +- AT91SAM7S256/Source/d_hispeed.r | 2 +- AT91SAM7S256/Source/d_loader.h | 2 +- 6 files changed, 171 insertions(+), 35 deletions(-) diff --git a/AT91SAM7S256/Source/c_cmd.c b/AT91SAM7S256/Source/c_cmd.c index fca498f..2909201 100644 --- a/AT91SAM7S256/Source/c_cmd.c +++ b/AT91SAM7S256/Source/c_cmd.c @@ -2115,11 +2115,11 @@ NXT_STATUS cCmdActivateProgram(UBYTE * pFileName) if((!isString2 || !isString3) || t1 == TC_ARRAY) // allow strings to go scalar, don't let through element compares of bytes or Bools isScalarBinop= FALSE; } - else if(opCode == OP_BRCMP) + else if(opCode == OP_BRCMP || opCode == OP_BRCMPABSVAR) isScalarBinop= FALSE; } } - else if(InstrSize == 6 && isT2Agg && (opCode == OP_NOT || opCode == OP_BRTST)) + else if(InstrSize == 6 && isT2Agg && (opCode == OP_NOT || opCode == OP_BRTST || opCode == OP_BRTSTABSVAR)) isScalarUnop2= FALSE; } pInstr += InstrSize/2; @@ -4740,6 +4740,7 @@ afterCompaction: NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode) { + CLUMP_REC* pClumpRec = &(VarsCmd.pAllClumps[VarsCmd.RunQ.Head]); NXT_STATUS Status = NO_ERR; UBYTE opCode; DATA_ARG Arg1; @@ -4759,6 +4760,14 @@ NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode) } break; + case OP_JMPABSVAR: + { + CODE_INDEX pc = (CODE_INDEX)(pClumpRec->PC-pClumpRec->CodeStart); + gPCDelta = (SWORD)Arg1-(SWORD)pc; + Status = NO_ERR; + } + break; + case OP_ACQUIRE: { NXT_ASSERT(cCmdIsDSElementIDSane(Arg1)); @@ -4795,9 +4804,18 @@ NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode) break; case OP_FINCLUMPIMMED: + case OP_FINCLUMPVAR: { CLUMP_ID Clump= VarsCmd.RunQ.Head; // DeQ changes Head, use local val cCmdDeQClump(&(VarsCmd.RunQ), Clump); //Dequeue finalized clump + if (opCode == OP_FINCLUMPVAR) + { + // indirect clump reference + if (cCmdDSType(Arg1) <= TC_LAST_INT_SCALAR) + Arg1 = cCmdGetScalarValFromDataArg(Arg1, 0); + else + return (ERR_INSTR); + } cCmdSchedDependent(Clump, (CLUMP_ID)Arg1); // Use immediate form Status = CLUMP_DONE; @@ -4837,15 +4855,32 @@ NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode) break; case OP_STOPCLUMPIMMED: + case OP_STOPCLUMPVAR: { + if (opCode == OP_STOPCLUMPVAR) + { + // indirect clump reference + if (cCmdDSType(Arg1) <= TC_LAST_INT_SCALAR) + Arg1 = cCmdGetScalarValFromDataArg(Arg1, 0); + else + return (ERR_INSTR); + } // Release any mutexes that the clump we are stopping owns - CLUMP_ID Clump = (CLUMP_ID)Arg1; - cCmdStopClump(Clump); + cCmdStopClump((CLUMP_ID)Arg1); } break; case OP_STARTCLUMPIMMED: + case OP_STARTCLUMPVAR: { + if (opCode == OP_STARTCLUMPVAR) + { + // indirect clump reference + if (cCmdDSType(Arg1) <= TC_LAST_INT_SCALAR) + Arg1 = cCmdGetScalarValFromDataArg(Arg1, 0); + else + return (ERR_INSTR); + } CLUMP_ID Clump = (CLUMP_ID)Arg1; // only enqueue the clump if it is not already on one of the queues // otherwise this is a no-op @@ -4874,6 +4909,7 @@ NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode) ULONG scalarNots= 0, scalarBrtst= 0, scalarUn2Other= 0, scalarUn2Dispatch= 0, polyUn2Dispatch= 0; NXT_STATUS cCmdInterpScalarUnop2(CODE_WORD * const pCode) { + CLUMP_REC* pClumpRec = &(VarsCmd.pAllClumps[VarsCmd.RunQ.Head]); NXT_STATUS Status; UBYTE opCode; @@ -4897,7 +4933,7 @@ NXT_STATUS cCmdInterpScalarUnop2(CODE_WORD * const pCode) Status = NO_ERR; scalarNots ++; } - else if(opCode == OP_BRTST) + else if(opCode == OP_BRTST || opCode == OP_BRTSTABSVAR) { ULONG Branch, compare= COMP_CODE(pCode); ULONG TypeCode; @@ -4930,8 +4966,12 @@ NXT_STATUS cCmdInterpScalarUnop2(CODE_WORD * const pCode) || (compare == OPCC1_GTEQ && SVal1 >= 0)); } } - if (Branch) - gPCDelta = (SWORD)Arg1; + if (Branch) { + if (opCode == OP_BRTST) + gPCDelta = (SWORD)Arg1; + else + gPCDelta = (UWORD)Arg1 - (pClumpRec->PC-pClumpRec->CodeStart); + } else gPCDelta= 3; Status = NO_ERR; @@ -4946,6 +4986,7 @@ NXT_STATUS cCmdInterpScalarUnop2(CODE_WORD * const pCode) NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode) { + CLUMP_REC* pClumpRec = &(VarsCmd.pAllClumps[VarsCmd.RunQ.Head]); NXT_STATUS Status = NO_ERR; UBYTE opCode; DATA_ARG Arg1; @@ -5003,6 +5044,7 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode) break; case OP_BRTST: + case OP_BRTSTABSVAR: { //!!!BDUGGAN BRTST w/ Float? ULONG Branch, compare= COMP_CODE(pCode); @@ -5025,7 +5067,10 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode) if (Branch) { - gPCDelta = (SWORD)Arg1; + if (opCode == OP_BRTST) + gPCDelta = (SWORD)Arg1; + else + gPCDelta = (UWORD)Arg1 - (pClumpRec->PC-pClumpRec->CodeStart); Status = NO_ERR; } } @@ -5054,7 +5099,15 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode) break; case OP_SUBCALL: + case OP_SUBCALLVAR: { + if (opCode == OP_SUBCALLVAR) + { + if (cCmdDSType(Arg1) <= TC_LAST_INT_SCALAR) + Arg1 = cCmdGetScalarValFromDataArg(Arg1, 0); + else + return (ERR_INSTR); + } NXT_ASSERT(cCmdIsClumpIDSane((CLUMP_ID)Arg1)); NXT_ASSERT(!cCmdIsClumpOnQ(&(VarsCmd.RunQ), (CLUMP_ID)Arg1)); @@ -5606,6 +5659,7 @@ NXT_STATUS cCmdIOGetSet(ULONG opCode, DATA_ARG Arg1, DATA_ARG Arg2, DATA_ARG Arg ULONG scalarCmp= 0, scalarFloatCmp= 0, recursiveCmp= 0, PolyScalarCmp= 0, polyPolyCmp= 0, scalarOther= 0, scalarBinopDispatch= 0, polyBinopDispatch= 0; NXT_STATUS cCmdInterpScalarBinop(CODE_WORD * const pCode) { + CLUMP_REC* pClumpRec = &(VarsCmd.pAllClumps[VarsCmd.RunQ.Head]); NXT_STATUS Status; UBYTE opCode; UBYTE CmpBool; @@ -5649,7 +5703,7 @@ NXT_STATUS cCmdInterpScalarBinop(CODE_WORD * const pCode) scalarFloatCmp++; } } - else if(opCode == OP_BRCMP) { // t2 and t3 guaranteed scalar + else if(opCode == OP_BRCMP || opCode == OP_BRCMPABSVAR) { // t2 and t3 guaranteed scalar TYPE_CODE TypeCode2, TypeCode3; ULONG ArgVal2, ArgVal3; @@ -5662,10 +5716,14 @@ NXT_STATUS cCmdInterpScalarBinop(CODE_WORD * const pCode) ArgVal3= cCmdGetScalarValFromDataArg(Arg3, 0); CmpBool= cCmdCompare(COMP_CODE(pCode), ArgVal2, ArgVal3, TypeCode2, TypeCode3); - if (CmpBool) - gPCDelta = (SWORD)Arg1; - else - gPCDelta= 4; + if (CmpBool) { + if (opCode == OP_BRCMP) + gPCDelta = (SWORD)Arg1; + else + gPCDelta = (UWORD)Arg1-(pClumpRec->PC-pClumpRec->CodeStart); + } + else + gPCDelta = 4; Status= NO_ERR; } else if(opCode >= OP_SETIN && opCode <= OP_GETOUT) { @@ -5685,6 +5743,7 @@ NXT_STATUS cCmdInterpScalarBinop(CODE_WORD * const pCode) NXT_STATUS cCmdInterpBinop(CODE_WORD * const pCode) { + CLUMP_REC* pClumpRec = &(VarsCmd.pAllClumps[VarsCmd.RunQ.Head]); NXT_STATUS Status = NO_ERR; UBYTE opCode; DATA_ARG Arg1, Arg2, Arg3; @@ -5742,6 +5801,7 @@ NXT_STATUS cCmdInterpBinop(CODE_WORD * const pCode) break; case OP_BRCMP: + case OP_BRCMPABSVAR: { TYPE_CODE TypeCode2= cCmdDSType(Arg2), TypeCode3= cCmdDSType(Arg3); if(TypeCode2 <= TC_LAST_INT_SCALAR && TypeCode3 <= TC_LAST_INT_SCALAR) { @@ -5755,6 +5815,8 @@ NXT_STATUS cCmdInterpBinop(CODE_WORD * const pCode) if (CmpBool) gPCDelta = (SWORD)Arg1; + else + gPCDelta = (UWORD)Arg1 - (pClumpRec->PC-pClumpRec->CodeStart); } break; @@ -7324,11 +7386,17 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode) // array operation if (Arg1 == OPARR_SORT) { - // source must be an array of non-aggregate type + // destination must be an array of non-aggregate type NXT_ASSERT(cCmdDSType(Arg2) == TC_ARRAY); TypeCode2 = cCmdDSType(INC_ID(Arg2)); NXT_ASSERT(!IS_AGGREGATE_TYPE(TypeCode2)); } + else if (Arg1 == OPARR_TOUPPER || Arg1 == OPARR_TOLOWER) { + // destination must be an array of ubyte type + NXT_ASSERT(cCmdDSType(Arg2) == TC_ARRAY); + TypeCode2 = cCmdDSType(INC_ID(Arg2)); + NXT_ASSERT(TypeCode2 == TC_UBYTE); + } else { // destination must be a non-aggregate type NXT_ASSERT(!IS_AGGREGATE_TYPE(cCmdDSType(Arg2))); @@ -7556,6 +7624,33 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode) else if (TypeCode2 == TC_FLOAT) shell_sort_flt(pArg2, MinCount); } + else if (Arg1 == OPARR_TOUPPER || Arg1 == OPARR_TOLOWER) + { + NXT_ASSERT((cCmdDSType(Arg3) == TC_ARRAY) && (cCmdDSType(INC_ID(Arg3)) == TC_UBYTE)); + //Allocate Dst array + Status = cCmdDSArrayAlloc(Arg2, 0, MinCount); + if (IS_ERR(Status)) + return Status; + + UBYTE *pDst = cCmdResolveDataArg(Arg2, 0, NULL); + UBYTE *pSrc = cCmdResolveDataArg(Arg3, 0, NULL); + + //Move src to dst + for (i = 0; i < ArrayCount3; i++) + { + UBYTE ch = *pSrc; + if ((i >= ArgVal4) && (i <= ArgVal4+MinCount)) + { + if ((Arg1 == OPARR_TOUPPER) && (ch >= 'a') && (ch <= 'z')) + ch -= 0x20; + else if ((Arg1 == OPARR_TOLOWER) && (ch >= 'A') && (ch <= 'Z')) + ch += 0x20; + } + *pDst = ch; + pDst++; + pSrc++; + } + } else { //Fatal error: Unrecognized instruction diff --git a/AT91SAM7S256/Source/c_cmd_bytecodes.h b/AT91SAM7S256/Source/c_cmd_bytecodes.h index 5c24472..418d814 100644 --- a/AT91SAM7S256/Source/c_cmd_bytecodes.h +++ b/AT91SAM7S256/Source/c_cmd_bytecodes.h @@ -137,17 +137,25 @@ // misc other JCH additions #define OP_ADDROF 0x89 // dest, src, rel -// additional string opcodes +#define OP_FINCLUMPVAR 0x90 // clumpID +#define OP_SUBCALLVAR 0x91 // subroutine, callerID +#define OP_STOPCLUMPVAR 0x92 // clumpID +#define OP_STARTCLUMPVAR 0x93 // clumpID +#define OP_JMPABSVAR 0x94 // pcvar +#define OP_BRCMPABSVAR 0x95 // pcvar, src1, src2 +#define OP_BRTSTABSVAR 0x96 // pcvar, src // array operation definitions -#define OPARR_SUM 0x00 -#define OPARR_MEAN 0x01 -#define OPARR_SUMSQR 0x02 -#define OPARR_STD 0x03 -#define OPARR_MIN 0x04 -#define OPARR_MAX 0x05 -#define OPARR_SORT 0x06 +#define OPARR_SUM 0x00 +#define OPARR_MEAN 0x01 +#define OPARR_SUMSQR 0x02 +#define OPARR_STD 0x03 +#define OPARR_MIN 0x04 +#define OPARR_MAX 0x05 +#define OPARR_SORT 0x06 +#define OPARR_TOUPPER 0x07 +#define OPARR_TOLOWER 0x08 // condition code definitions #define OPCC1_LT 0x00 diff --git a/AT91SAM7S256/Source/c_cmd_drawing.inc b/AT91SAM7S256/Source/c_cmd_drawing.inc index 5592180..22daeee 100644 --- a/AT91SAM7S256/Source/c_cmd_drawing.inc +++ b/AT91SAM7S256/Source/c_cmd_drawing.inc @@ -1629,13 +1629,18 @@ void cCmdClearScreenIfNeeded(ULONG DrawOptions) void cCmdDrawString(UBYTE *pString, ULONG X, ULONG Y, UBYTE InvertMode, UBYTE LogicalMode, UBYTE FillMode) //JJR { UBYTE *pSource; - UBYTE *pDestination; + UBYTE *pDestination1; + UBYTE *pDestination2; UBYTE a; FONT *pFont; ULONG FontWidth; ULONG Items; ULONG Item; - ULONG Line; + SLONG Line; + UBYTE offset; + UWORD a2; + UWORD mask; + UWORD font; //Get current font information pFont = pMapDisplay->pFont; @@ -1643,14 +1648,30 @@ void cCmdDrawString(UBYTE *pString, ULONG X, ULONG Y, UBYTE InvertMode, UBYTE Lo //Invert Y coordinate to match display buffer Y = TRANSLATE_Y(Y); - Line = (Y & 0xF8) / 8; + Line = (Y & 0xF8) / 8; // truncates down to nearest multiple of 8 + offset = (Y-7) % 8; // how many bits is the content shifted? + if (offset) + Line--; + + mask = ~(0x00ff << offset); //If text line is out of bounds, do nothing. if (Line >= TEXTLINES) return; //Calculate pointer to first byte of drawing destination - pDestination = &(DISP_BUFFER_P[Line * DISPLAY_WIDTH + X]); + if (Line >= TEXTLINE_1) + pDestination1 = &(DISP_BUFFER_P[Line * DISPLAY_WIDTH + X]); + else + pDestination1 = NULL; + if (offset && (Line < TEXTLINE_8)) + pDestination2 = &(DISP_BUFFER_P[(Line+1) * DISPLAY_WIDTH + X]); + else + pDestination2 = NULL; + + // bail out early if neither destination is valid + if (pDestination1 == NULL && pDestination2 == NULL) + return; while (*pString) { @@ -1669,7 +1690,6 @@ void cCmdDrawString(UBYTE *pString, ULONG X, ULONG Y, UBYTE InvertMode, UBYTE Lo while (FontWidth--) { //JJR -// *pDestination = *pSource; //Fetch a byte from the source bitmap: //If fill mode is on, pretend the source bitmap is solid: @@ -1680,26 +1700,39 @@ void cCmdDrawString(UBYTE *pString, ULONG X, ULONG Y, UBYTE InvertMode, UBYTE Lo //Implement bitmap invert mode: if (InvertMode==DRAW_BITMAP_INVERT) a = ~a; + + // grab data from 1 or 2 lines + a2 = (pDestination2 ? ((UWORD)(*pDestination2) << 8) : 0x0000) | + (pDestination1 ? (UWORD)(*pDestination1) : 0x0000); + + font = (UWORD) a << offset; //Implement bitmap logical mode when writing on screen: switch (LogicalMode) { case DRAW_LOGICAL_OR: - *pDestination |= a; + a2 |= font; break; case DRAW_LOGICAL_AND: - *pDestination &= a; + a2 &= font | mask; break; case DRAW_LOGICAL_XOR: - *pDestination ^= a; + a2 ^= font; break; case DRAW_LOGICAL_COPY: default: - *pDestination = a; + a2 = (a2 & mask) | font; break; } //JJR - pDestination++; + if (pDestination1) { + *pDestination1 = (UBYTE)(a2 & 0xFF); + pDestination1++; + } + if (pDestination2) { + *pDestination2 = ((UBYTE)(a2>>8) & 0xFF); + pDestination2++; + } pSource++; } } diff --git a/AT91SAM7S256/Source/c_loader.iom b/AT91SAM7S256/Source/c_loader.iom index afc6523..73e78ef 100644 --- a/AT91SAM7S256/Source/c_loader.iom +++ b/AT91SAM7S256/Source/c_loader.iom @@ -21,7 +21,7 @@ //For example, version 1.5 would be 0x0105 //If these switch to little-endian, be sure to update //definition and usages of VM_OLDEST_COMPATIBLE_VERSION, too! -#define FIRMWAREVERSION 0x011F //1.31 +#define FIRMWAREVERSION 0x0120 //1.32 #define PROTOCOLVERSION 0x017C //1.124 enum diff --git a/AT91SAM7S256/Source/d_hispeed.r b/AT91SAM7S256/Source/d_hispeed.r index 3c4c58a..817e79a 100644 --- a/AT91SAM7S256/Source/d_hispeed.r +++ b/AT91SAM7S256/Source/d_hispeed.r @@ -65,7 +65,7 @@ static UBYTE InBufOutCnt; *AT91C_PIOA_ASR = HIGHSPEED_TX_PIN | HIGHSPEED_RTS_PIN | HIGHSPEED_RX_PIN;; /* Enable Per. A on PA5, PA6 & PA7 */\ *AT91C_US0_CR = AT91C_US_RSTSTA; /* Resets pins on UART0 */\ *AT91C_US0_CR = AT91C_US_STTTO; /* Start timeout functionality after 1 byte */\ - *AT91C_US0_RTOR = 2400+((15-(_spd))*4200); /* Approxitely 20 mS,x times bit time with 115200 bit pr s */\ + *AT91C_US0_RTOR = 2400; /* Approxitely 20 mS,x times bit time with 115200 bit pr s */\ *AT91C_US0_IDR = AT91C_US_TIMEOUT; /* Disable interrupt on timeout */\ *AT91C_AIC_IDCR = UART0_INQ; /* Disable UART0 interrupt */\ *AT91C_AIC_ICCR = UART0_INQ; /* Clear interrupt register */\ diff --git a/AT91SAM7S256/Source/d_loader.h b/AT91SAM7S256/Source/d_loader.h index 0914231..4aaf140 100644 --- a/AT91SAM7S256/Source/d_loader.h +++ b/AT91SAM7S256/Source/d_loader.h @@ -19,7 +19,7 @@ #define STARTOFFILETABLE (0x140000L - (FILETABLE_SIZE*4)) #define FILEPTRTABLE ((const ULONG*)(0x140000L - (FILETABLE_SIZE*4))) #ifndef STRIPPED -#define STARTOFUSERFLASH (0x126000L)//(0x124600L) 1.31 == (0x122100L) +#define STARTOFUSERFLASH (0x126400L)//(0x124600L) 1.31 == (0x122100L) #else #define STARTOFUSERFLASH (0x122C00L)//(0x124600L) 1.31 == (0x122100L) #endif -- cgit v1.2.3