No need for a new level.
Eric, I also have a spare board here from the prototype run.
I believe this board doesnāt have the caps swapped out for the RTC to work properly but other than that everything is online. Drop me an email if youāre interested
seems kickstarter is not usable with a german bank account
is that right ??
Iām not sure about the back account but they do accept PayPal these days.
[Correction] They accept Amazon Payments
Remember that link I have up right now is only a preview. The project will not be live until approved by the admins over there.
@ Skewworks:
Your project is extremely interesting, but there is one claim that I find somewhat difficult to believe: that the VCPU runs as if it were a 117 MHz āArduinoā.
Given that the VCPU is implemented in NETMF (by which I assume you mean managed code), which is already interpreted, and therefore much slower than native code, and the chip is only 168 MHz to begin with, and generally CPU emulation is done at a fraction of the host CPUās speed, it is my opinion that this statement will need some justification.
But I am a sourpuss like that.
Youāre forgetting RLPLite.
Graphics is also done almost exclusively in RLP.
That said 30% overhead is a rough estimate. Itās not stated on the KickStarter and I would need to run a battery of tests to give an exact overhead amount.
So, when you say NETMF, you mean native code?
Still, 70% of native speed is, frankly, incredible, even if the CPU wasnāt doing much else.
Iām willing to believe Iām wrongā¦
Iāll do my best to create some tests over the next coming weeks. Honestly though, Iām extremely overburdened at the moment.
The way I arrived at the estimate is assuming a default overhead for RLP calls and how many operations I would need to do on the RLP side to perform an average operation from the instruction set.
If you look at the code for Pyxis Oneās VCPU you should have a pretty good idea of the costs as this is based on it.
To give you a better idea, this is an extracted portion of the P1VCPU
void Pyxis::runPXE(char* filename)
{
int x1,y1,x2,y2,x3,y3;
long lTemp,l;
int iTemp,i;
long lRet; // Call/Return
long registers[31]; // Registers
unsigned long int acc = 0; // Accumulator
unsigned long int fileSize; // Actual Size of File
unsigned long int pxefileSize; // Actual Size of File called by PXE
unsigned char *buffer; // uSD Read Buffer
unsigned char *sdString; // uSD Read Buffer
unsigned char res; // Result
bool bRes;
char* string;
uint8_t vRAM[2048]; // Virtual RAM for Programs
registers[0] = 0;
registers[1] = 2048;
registers[2] = 2048;
// Open the file
res = SD.openFileRead(filename, 3, &fileSize);
if (res != 0) return;
// Seek to Start
SD.seek(3,0);
buffer = (unsigned char*)malloc(31);
while(1)
{
// Check Accumulator
if (acc >= fileSize)
{
return;
}
// Read the command
while(1)
{
res = SD.read(3,buffer,4);
if (res == 0) break;
if (res != 0xD0)
{
SD.closeFile(3);
return;
}
}
/*
// Uncomment for debugging
Serial.println("");
Serial.print("(");
Serial.print(acc);
Serial.print(")");
Serial.print("COMMAND: 0x");
Serial.print(buffer[0],HEX);
Serial.print(" 0x");
Serial.print(buffer[1],HEX);
Serial.print(" 0x");
Serial.print(buffer[2],HEX);
Serial.print(" 0x");
Serial.println(buffer[3],HEX);
*/
switch(buffer[0])
{
case 0x00: // exit
SD.closeFile(3);
return;
break;
case 0x01: // xyo
x1 = registers[buffer[1]]; // 0 - 255 Range
y1 = registers[buffer[2]]; // 0 - 255 Range
break;
case 0x03: // xyd
x2 = registers[buffer[1]]; // 0 - 255 Range
y2 = registers[buffer[2]]; // 0 - 255 Range
break;
case 0x05: // dly
delay(registers[buffer[1]]); // Register
break;
case 0x06: // xyt
x3 = registers[buffer[1]]; // 0 - 255 Range
y3 = registers[buffer[2]]; // 0 - 255 Range
break;
case 0x08: // bcol
LCD.backcolor(registers[buffer[1]],registers[buffer[2]],registers[buffer[3]]);
break;
case 0x09: // fcol
LCD.forecolor(registers[buffer[1]],registers[buffer[2]],registers[buffer[3]]);
break;
case 0x0A: // mov
registers[buffer[1]] = registers[buffer[2]];
break;
case 0x0B: // sbyt
vRAM[registers[buffer[1]]] = BYTELOW(registers[buffer[2]]);
break;
case 0x0C: // swrd
vRAM[registers[buffer[1]]] = BYTEHIGH(registers[buffer[2]]);
vRAM[registers[buffer[1]]+1] = BYTELOW (registers[buffer[2]]);
break;
case 0x0D: // slng
vRAM[registers[buffer[1]]] = WORDHIGH_BYTEHIGH(registers[buffer[2]]);
vRAM[registers[buffer[1]]+1] = WORDHIGH_BYTELOW (registers[buffer[2]]);
vRAM[registers[buffer[1]]+2] = WORDLOW_BYTEHIGH (registers[buffer[2]]);
vRAM[registers[buffer[1]]+3] = WORDLOW_BYTELOW (registers[buffer[2]]);
break;
case 0x0E: // lbyt
registers[buffer[1]] = vRAM[registers[buffer[2]]];
break;
case 0x0F: // lwrd
WORDHIGH_BYTEHIGH(registers[buffer[1]]) = 0;
WORDHIGH_BYTELOW (registers[buffer[1]]) = 0;
WORDLOW_BYTEHIGH (registers[buffer[1]]) = vRAM[registers[buffer[2]]];
WORDLOW_BYTELOW (registers[buffer[1]]) = vRAM[registers[buffer[2]]+1];
break;
case 0x10: // llng
WORDHIGH_BYTEHIGH(registers[buffer[1]]) = vRAM[registers[buffer[2]]];
WORDHIGH_BYTELOW (registers[buffer[1]]) = vRAM[registers[buffer[2]]+1];
WORDLOW_BYTEHIGH (registers[buffer[1]]) = vRAM[registers[buffer[2]]+2];
WORDLOW_BYTELOW (registers[buffer[1]]) = vRAM[registers[buffer[2]]+3];
break;
case 0x11: // inc
registers[buffer[1]]++;
break;
case 0x12: // dec
registers[buffer[1]]--;
break;
case 0x13: // add
registers[buffer[1]] = registers[buffer[2]] + registers[buffer[3]];
break;
case 0x14: // addi
registers[buffer[1]] = registers[buffer[2]] + buffer[3];
break;
case 0x15: // sub
registers[buffer[1]] = registers[buffer[2]] - registers[buffer[3]];
break;
case 0x16: // subi
registers[buffer[1]] = registers[buffer[2]] - buffer[3];
break;
case 0x17: // mul
registers[buffer[1]] = registers[buffer[2]] * registers[buffer[3]];
break;
case 0x18: // muli
registers[buffer[1]] = registers[buffer[2]] * buffer[3];
break;
case 0x19: // div
registers[buffer[1]] = registers[buffer[2]] / registers[buffer[3]];
break;
case 0x1A: // divi
registers[buffer[1]] = registers[buffer[2]] / buffer[3];
break;
case 0x1B: // bor
registers[buffer[1]] = (registers[buffer[1]] == 1) ? 0 : 1;
break;
case 0x1E: // call
// Store ACC
lRet = acc + 4;
// Set New ACC
WORDHIGH_BYTEHIGH(lTemp) = 0;
WORDHIGH_BYTELOW (lTemp) = 0;
WORDLOW_BYTEHIGH (lTemp) = buffer[1];
WORDLOW_BYTELOW (lTemp) = buffer[2];
lTemp = lTemp * 4; // 4 Bytes per line, jump given in lines
if (buffer[3] == 0)
{
acc = acc + lTemp;
}
else
{
acc = acc - lTemp;
}
// First go to beginning of file
if (SD.seek(3,0) != 0) return;
// Now seek to where we need to be
if (SD.seek(3,acc) != 0) return;
// We'll be adding 4 after this so subtract 4 to stay ahead
acc = acc - 4;
break;
case 0x1F: // beq
if (registers[buffer[1]] == registers[buffer[2]])
{
// BRANCH
if (buffer[3] == 0)
{
acc = (registers[1] * 4);
}
else
{
acc = (registers[1] * 4) - 8;
}
// First go to beginning of file
if (SD.seek(3,0) != 0) return;
// Now seek to where we need to be
if (SD.seek(3,acc) != 0) return;
// We'll be adding 4 after this so subtract 4 to stay ahead
acc = acc - 4;
}
break;
case 0x20: // bneq
if (registers[buffer[1]] != registers[buffer[2]])
{
// BRANCH
if (buffer[3] == 0)
{
acc = (registers[1] * 4);
}
else
{
acc = (registers[1] * 4) - 8;
}
// First go to beginning of file
if (SD.seek(3,0) != 0) return;
// Now seek to where we need to be
if (SD.seek(3,acc) != 0) return;
// We'll be adding 4 after this so subtract 4 to stay ahead
acc = acc - 4;
}
break;
case 0x21: // blt
if (registers[buffer[1]] < registers[buffer[2]])
{
// BRANCH
if (buffer[3] == 0)
{
acc = (registers[1] * 4);
}
else
{
acc = (registers[1] * 4) - 8;
}
// First go to beginning of file
if (SD.seek(3,0) != 0) return;
// Now seek to where we need to be
if (SD.seek(3,acc) != 0) return;
// We'll be adding 4 after this so subtract 4 to stay ahead
acc = acc - 4;
}
break;
case 0x22: // blte
if (registers[buffer[1]] <= registers[buffer[2]])
{
// BRANCH
if (buffer[3] == 0)
{
acc = (registers[1] * 4);
}
else
{
acc = (registers[1] * 4) - 8;
}
// First go to beginning of file
if (SD.seek(3,0) != 0) return;
// Now seek to where we need to be
if (SD.seek(3,acc) != 0) return;
// We'll be adding 4 after this so subtract 4 to stay ahead
acc = acc - 4;
}
break;
case 0x23: // bgt
if (registers[buffer[1]] > registers[buffer[2]])
{
// BRANCH
if (buffer[3] == 0)
{
acc = (registers[1] * 4);
}
else
{
acc = (registers[1] * 4) - 8;
}
// First go to beginning of file
if (SD.seek(3,0) != 0) return;
// Now seek to where we need to be
if (SD.seek(3,acc) != 0) return;
// We'll be adding 4 after this so subtract 4 to stay ahead
acc = acc - 4;
}
break;
case 0x24: // bgte
if (registers[buffer[1]] >= registers[buffer[2]])
{
// BRANCH
if (buffer[3] == 0)
{
acc = (registers[1] * 4);
}
else
{
acc = (registers[1] * 4) - 8;
}
// First go to beginning of file
if (SD.seek(3,0) != 0) return;
// Now seek to where we need to be
if (SD.seek(3,acc) != 0) return;
// We'll be adding 4 after this so subtract 4 to stay ahead
acc = acc - 4;
}
break;
case 0x25: // jump
// Set New ACC
WORDHIGH_BYTEHIGH(lTemp) = 0;
WORDHIGH_BYTELOW (lTemp) = 0;
WORDLOW_BYTEHIGH (lTemp) = buffer[1];
WORDLOW_BYTELOW (lTemp) = buffer[2];
lTemp = lTemp * 4;
if (buffer[3] == 0)
{
acc = acc + lTemp;
}
else
{
acc = acc - lTemp;
}
// First go to beginning of file
if (SD.seek(3,0) != 0) return;
// Now seek to where we need to be
if (SD.seek(3,acc) != 0) return;
// We'll be adding 4 after this so subtract 4 to stay ahead
acc = acc - 4;
break;
case 0x26: // return
// First go to beginning of file
if (SD.seek(3,0) != 0) return;
// Now seek to where we need to be
if (SD.seek(3,lRet) != 0) return;
// We'll be adding 4 after this so subtract 4 to stay ahead
acc = lRet - 4;
break;
case 0x27: // LCD extension function
switch(buffer[1])
{
case 0x0A: // cls
LCD.cls();
break;
case 0x0B: // scrm (landscape)
LCD.landscapeMode();
break;
case 0x0C: // scrm (portrait)
LCD.portraitMode();
break;
case 0x0D: // smoothing mode
LCD.smoothingMode(registers[buffer[1]]);
break;
case 0x20: // dln
LCD.drawLine(x1,y1,x2,y2);
break;
case 0x21: // drct
LCD.drawRect(x1,y1,x2,y2);
break;
case 0x22: // delp
LCD.drawEllipse(x1,y1,x2,y2);
break;
case 0x25: // dtri
LCD.drawTriangle(x1,y1,x2,y2,x3,y3);
break;
case 0x26: // frct
LCD.fillRect(x1,y1,x2,y2);
break;
case 0x27: // felp
LCD.fillEllipse(x1,y1,x2,y2);
break;
case 0x2A: // ftri
LCD.fillTriangle(x1,y1,x2,y2,x3,y3);
break;
case 0x53: // dwin
string = stringFromAddress(registers[buffer[2]],acc+4);
LCD.drawWindow(string,x1,y1,x2,y2,232,232,232);
free(string);
LCD.backcolor(232,232,232);
break;
case 0x60: // sfnt
LCD.setFont(registers[buffer[1]]);
break;
case 0x61: // dvar
lTemp = registers[1];
switch(buffer[3])
{
case 0: // Byte OR Value
if (buffer[2] == 0)
{
// This is a value
LCD.drawString(lTemp,x1,y1);
}
else
{
LCD.setPosition(x1,y1);
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) LCD.drawString(", "); // It's an array, separate value
LCD.drawString((int)vRAM[lTemp]);
lTemp++;
}
}
break;
case 1: // Boolean
LCD.setPosition(x1,y1);
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) LCD.drawString(", "); // It's an array, separate value
LCD.drawString((vRAM[lTemp] == 0) ? (char*)"false" : (char*)"true");
lTemp++;
}
break;
case 2: // Character
LCD.setPosition(x1,y1);
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (vRAM[lTemp] == 0) break;
LCD.drawChar(vRAM[lTemp]);
lTemp++;
}
break;
case 3: // Int
LCD.setPosition(x1,y1);
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) LCD.drawString(", "); // It's an array, separate value
BYTEHIGH(iTemp) = vRAM[lTemp];
BYTELOW (iTemp) = vRAM[lTemp + 1];
LCD.drawString((int)iTemp);
lTemp+=2;
}
break;
case 4: // Long
LCD.setPosition(x1,y1);
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) LCD.drawString(", "); // It's an array, separate value
WORDHIGH_BYTEHIGH(l) = vRAM[lTemp];
WORDHIGH_BYTELOW (l) = vRAM[lTemp+1];
WORDLOW_BYTEHIGH (l) = vRAM[lTemp+2];
WORDLOW_BYTELOW (l) = vRAM[lTemp+3];
LCD.drawString((long)l);
lTemp+=4;
}
break;
}
break;
case 0x62: // dstr
string = stringFromAddress(registers[buffer[2]],acc+4);
LCD.drawString(string,x1,y1);
free(string);
break;
default:
break;
}
break;
case 0x28: // pmode
pinMode(registers[buffer[1]],buffer[2]);
break;
case 0x29: // dwrt
digitalWrite(registers[buffer[1]],registers[buffer[2]]);
break;
case 0x2A: // dread
lTemp = registers[buffer[2]]; // Get the Variable Address
switch(buffer[3]) // Store the Value by Type Size
{
case 1: // Boolean,Byte,Character
vRAM[lTemp] = digitalRead(registers[buffer[1]]);
break;
case 2: // Integer
vRAM[lTemp] = 0;
vRAM[lTemp+1] = digitalRead(registers[buffer[1]]);
break;
case 4: // Long
vRAM[lTemp] = 0;
vRAM[lTemp+1] = 0;
vRAM[lTemp+2] = 0;
vRAM[lTemp+3] = digitalRead(registers[buffer[1]]);
break;
}
case 0x2B: // awrt
analogWrite(registers[buffer[1]],registers[buffer[2]]);
break;
case 0x2C: // aread
lTemp = registers[buffer[2]]; // Get the Variable Address
iTemp = analogRead(registers[buffer[1]]);
switch(buffer[3]) // Store the Value by Type Size
{
case 1: // Boolean,Byte,Character
vRAM[lTemp] = BYTELOW (iTemp);
break;
case 2: // Integer
vRAM[lTemp] = BYTEHIGH(iTemp);
vRAM[lTemp+1] = BYTELOW (iTemp);
break;
case 4: // Long
vRAM[lTemp] = 0;
vRAM[lTemp+1] = 0;
vRAM[lTemp+2] = BYTEHIGH(iTemp);
vRAM[lTemp+3] = BYTELOW (iTemp);
break;
}
case 0x2D: // SD Write
// buffer[1] = variable address
// buffer[2] = size to write
// buffer[3] = result variable address
lTemp = registers[buffer[2]];
sdString = (unsigned char*)malloc(lTemp);
for (i = 0; i < lTemp; i++)
{
sdString[i] = (unsigned char)vRAM[registers[buffer[1]] + i];
}
iTemp = (int)SD.write(2,sdString,lTemp);
free(sdString);
vRAM[registers[buffer[3]]] = BYTEHIGH(iTemp);
vRAM[registers[buffer[3]]+1] = BYTELOW (iTemp);
break;
case 0x2E: // SD Commands
switch(buffer[1])
{
case 0x00: // sdcf
SD.seek(2,0);
SD.closeFile(2);
break;
case 0x02: // sdgn
sdString = (unsigned char*)malloc(12);
iTemp = (int)SD.getCurrentName(sdString);
lTemp = registers[buffer[2]];
for (i = 0; i < 13; i++)
{
vRAM[lTemp] = (char)sdString[i];
lTemp++;
}
free(sdString);
vRAM[registers[buffer[3]]] = BYTEHIGH(iTemp);
vRAM[registers[buffer[3]]+1] = BYTELOW (iTemp);
break;
case 0x03: // sdof
string = (char*)malloc(13);
for (i = 0; i < 13; i++)
{
string[i] = vRAM[registers[buffer[2]] + i];
}
iTemp = (int)SD.openFileWrite(string, 2, &pxefileSize);
vRAM[registers[buffer[3]]] = BYTEHIGH(iTemp);
vRAM[registers[buffer[3]]+1] = BYTELOW (iTemp);
free(string);
break;
case 0x07: // sdsk
WORDHIGH_BYTEHIGH(lTemp) = 0;
WORDHIGH_BYTELOW (lTemp) = 0;
WORDLOW_BYTEHIGH (lTemp) = vRAM[registers[buffer[2]]];
WORDLOW_BYTELOW (lTemp) = vRAM[registers[buffer[2]]];
iTemp = (int)SD.seek(2,lTemp);
vRAM[registers[buffer[3]]] = BYTEHIGH(iTemp);
vRAM[registers[buffer[3]]+1] = BYTELOW (iTemp);
free(string);
break;
case 0x09: // sdrm
string = (char*)malloc(13);
for (i = 0; i < 13; i++)
{
string[i] = vRAM[registers[buffer[2]] + i];
}
iTemp = (int)SD.deleteEntry(string);
vRAM[registers[buffer[3]]] = BYTEHIGH(iTemp);
vRAM[registers[buffer[3]]+1] = BYTELOW (iTemp);
free(string);
break;
case 0x0A: // sdmk
string = (char*)malloc(13);
for (i = 0; i < 13; i++)
{
string[i] = vRAM[registers[buffer[2]] + i];
}
iTemp = (int)SD.createDirectory(string);
vRAM[registers[buffer[3]]] = BYTEHIGH(iTemp);
vRAM[registers[buffer[3]]+1] = BYTELOW (iTemp);
free(string);
break;
case 0x0C: // sddr
l = registers[buffer[2]];
iTemp = (int)SD.dir(0);
for (i = 1; i < l; i++)
{
iTemp = (int)SD.dir(1);
}
vRAM[registers[buffer[3]]] = BYTEHIGH(iTemp);
vRAM[registers[buffer[3]]+1] = BYTELOW (iTemp);
break;
}
break;
case 0x2F: // SD Read
// buffer[1] = variable address
// buffer[2] = size to write
// buffer[3] = result variable address
lTemp = registers[buffer[2]];
sdString = (unsigned char*)malloc(lTemp);
iTemp = (int)SD.write(2,sdString,lTemp);
for (i = 0; i < lTemp; i++)
{
vRAM[registers[buffer[1]]] = (char)sdString[i];
}
free(sdString);
vRAM[registers[buffer[3]]] = BYTEHIGH(iTemp);
vRAM[registers[buffer[3]]+1] = BYTELOW (iTemp);
break;
case 0x30: // la
BYTEHIGH(iTemp) = buffer[2]; // Address Byte 1
BYTELOW (iTemp) = buffer[3]; // Address Byte 2 (Max Range 0 - 65535)
if (buffer[1] > 0) registers[buffer[1]] = iTemp;
break;
case 0x31: // li
iTemp = 0;
BYTEHIGH(iTemp) = buffer[2];
BYTELOW (iTemp) = buffer[3];
if (buffer[1] > 0) registers[buffer[1]] = iTemp;
break;
case 0x32: // lwu
break;
case 0x33: // lwui
WORDHIGH_BYTEHIGH(registers[buffer[1]]) = buffer[2];
WORDHIGH_BYTELOW (registers[buffer[1]]) = buffer[3];
break;
case 0x34: // lwl
break;
case 0x35: // lwli
WORDLOW_BYTEHIGH(registers[buffer[1]]) = buffer[2];
WORDLOW_BYTELOW (registers[buffer[1]]) = buffer[3];
break;
case 0x36: // lar
// buffer[1] = Variable Address Register
// buffer[2] = Variable Length Register
// buffer[3] = Disk Address
string = stringFromAddress(registers[buffer[3]],acc+4,registers[buffer[2]]);
for (i = 0; i < registers[buffer[2]]; i++)
{
vRAM[registers[buffer[1]] + i] = string[i];
}
free(string);
break;
case 0x40: // s0pl
WORDHIGH_BYTEHIGH(l) = 0;
WORDHIGH_BYTELOW (l) = buffer[1];
WORDLOW_BYTEHIGH (l) = buffer[2];
WORDLOW_BYTELOW (l) = buffer[3];
string = stringFromAddress(l,acc+4);
Serial.print(string);
free(string);
break;
case 0x41: // s0p
lTemp = registers[buffer[1]]; // Address for Variable
if (buffer[2] == 0 && buffer[3] == 0)
{
// We're printing a register's value
Serial.print(lTemp);
}
else
{
switch(buffer[3]) // Variable Type
{
case 0: // Byte
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) Serial.print(", "); // It's an array, separate value
Serial.print((int)vRAM[lTemp]);
lTemp++;
}
break;
case 1: // Boolean
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) Serial.print(", "); // It's an array, separate value
Serial.print((vRAM[lTemp] == 0) ? "false" : "true");
lTemp++;
}
break;
case 2: // Character
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
Serial.print((char)vRAM[lTemp]);
lTemp++;
}
break;
case 3: // Int
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) Serial.print(", "); // It's an array, separate value
BYTEHIGH(iTemp) = vRAM[lTemp];
BYTELOW (iTemp) = vRAM[lTemp + 1];
Serial.print((int)iTemp);
lTemp+=2;
}
break;
case 4: // Long
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) Serial.print(", "); // It's an array, separate value
WORDHIGH_BYTEHIGH(l) = vRAM[lTemp];
WORDHIGH_BYTELOW (l) = vRAM[lTemp+1];
WORDLOW_BYTEHIGH (l) = vRAM[lTemp+2];
WORDLOW_BYTELOW (l) = vRAM[lTemp+3];
Serial.print((long)l);
lTemp+=4;
}
break;
}
}
break;
case 0x42: // s0pln
Serial.println("");
break;
case 0x43: // s1pl
WORDHIGH_BYTEHIGH(l) = 0;
WORDHIGH_BYTELOW (l) = buffer[1];
WORDLOW_BYTEHIGH (l) = buffer[2];
WORDLOW_BYTELOW (l) = buffer[3];
string = stringFromAddress(l,acc+4);
Serial1.print(string);
free(string);
break;
case 0x44: // s1p
lTemp = registers[buffer[1]]; // Address for Variable
if (buffer[2] == 0 && buffer[3] == 0)
{
// We're printing a register's value
Serial1.print(lTemp);
}
else
{
switch(buffer[3]) // Variable Type
{
case 0: // Byte
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) Serial1.print(", "); // It's an array, separate value
Serial1.print((int)vRAM[lTemp]);
lTemp++;
}
break;
case 1: // Boolean
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) Serial1.print(", "); // It's an array, separate value
Serial1.print((vRAM[lTemp] == 0) ? "false" : "true");
lTemp++;
}
break;
case 2: // Character
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
Serial1.print((char)vRAM[lTemp]);
lTemp++;
}
break;
case 3: // Int
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) Serial1.print(", "); // It's an array, separate value
BYTEHIGH(iTemp) = vRAM[lTemp];
BYTELOW (iTemp) = vRAM[lTemp + 1];
Serial1.print((int)iTemp);
lTemp+=2;
}
break;
case 4: // Long
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) Serial1.print(", "); // It's an array, separate value
WORDHIGH_BYTEHIGH(l) = vRAM[lTemp];
WORDHIGH_BYTELOW (l) = vRAM[lTemp+1];
WORDLOW_BYTEHIGH (l) = vRAM[lTemp+2];
WORDLOW_BYTELOW (l) = vRAM[lTemp+3];
Serial1.print((long)l);
lTemp+=4;
}
break;
}
}
break;
case 0x45: // s1pln
Serial1.println("");
break;
case 0x46: // s2pl
WORDHIGH_BYTEHIGH(l) = 0;
WORDHIGH_BYTELOW (l) = buffer[1];
WORDLOW_BYTEHIGH (l) = buffer[2];
WORDLOW_BYTELOW (l) = buffer[3];
string = stringFromAddress(l,acc+4);
Serial2.print(string);
free(string);
break;
case 0x47: // s2p
lTemp = registers[buffer[1]]; // Address for Variable
if (buffer[2] == 0 && buffer[3] == 0)
{
// We're printing a register's value
Serial2.print(lTemp);
}
else
{
switch(buffer[3]) // Variable Type
{
case 0: // Byte
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) Serial2.print(", "); // It's an array, separate value
Serial2.print((int)vRAM[lTemp]);
lTemp++;
}
break;
case 1: // Boolean
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) Serial2.print(", "); // It's an array, separate value
Serial2.print((vRAM[lTemp] == 0) ? "false" : "true");
lTemp++;
}
break;
case 2: // Character
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
Serial2.print((char)vRAM[lTemp]);
lTemp++;
}
break;
case 3: // Int
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) Serial2.print(", "); // It's an array, separate value
BYTEHIGH(iTemp) = vRAM[lTemp];
BYTELOW (iTemp) = vRAM[lTemp + 1];
Serial2.print((int)iTemp);
lTemp+=2;
}
break;
case 4: // Long
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) Serial2.print(", "); // It's an array, separate value
WORDHIGH_BYTEHIGH(l) = vRAM[lTemp];
WORDHIGH_BYTELOW (l) = vRAM[lTemp+1];
WORDLOW_BYTEHIGH (l) = vRAM[lTemp+2];
WORDLOW_BYTELOW (l) = vRAM[lTemp+3];
Serial2.print((long)l);
lTemp+=4;
}
break;
}
}
break;
case 0x48: // s2pln
Serial2.println("");
break;
case 0x49: // s3pl
WORDHIGH_BYTEHIGH(l) = 0;
WORDHIGH_BYTELOW (l) = buffer[1];
WORDLOW_BYTEHIGH (l) = buffer[2];
WORDLOW_BYTELOW (l) = buffer[3];
string = stringFromAddress(l,acc+4);
Serial3.print(string);
free(string);
break;
case 0x4A: // s3p
lTemp = registers[buffer[1]]; // Address for Variable
if (buffer[2] == 0 && buffer[3] == 0)
{
// We're printing a register's value
Serial3.print(lTemp);
}
else
{
switch(buffer[3]) // Variable Type
{
case 0: // Byte
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) Serial3.print(", "); // It's an array, separate value
Serial3.print((int)vRAM[lTemp]);
lTemp++;
}
break;
case 1: // Boolean
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) Serial3.print(", "); // It's an array, separate value
Serial3.print((vRAM[lTemp] == 0) ? "false" : "true");
lTemp++;
}
break;
case 2: // Character
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
Serial3.print((char)vRAM[lTemp]);
lTemp++;
}
break;
case 3: // Int
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) Serial3.print(", "); // It's an array, separate value
BYTEHIGH(iTemp) = vRAM[lTemp];
BYTELOW (iTemp) = vRAM[lTemp + 1];
Serial3.print((int)iTemp);
lTemp+=2;
}
break;
case 4: // Long
for (i = 0; i < buffer[2]; i++) // buffer[2] = size of array
{
if (i != 0) Serial3.print(", "); // It's an array, separate value
WORDHIGH_BYTEHIGH(l) = vRAM[lTemp];
WORDHIGH_BYTELOW (l) = vRAM[lTemp+1];
WORDLOW_BYTEHIGH (l) = vRAM[lTemp+2];
WORDLOW_BYTELOW (l) = vRAM[lTemp+3];
Serial3.print((long)l);
lTemp+=4;
}
break;
}
}
break;
case 0x4B: // s3pln
Serial3.println("");
break;
case 0x4C: // rdbp
iTemp = Pad.readButtons();
vRAM[registers[buffer[1]]] = BYTEHIGH(iTemp);
vRAM[registers[buffer[1]]+1] = BYTELOW(iTemp);
break;
case 0x4D: // upen
LCD.updatePen(&bRes,&x2,&x3);
vRAM[registers[buffer[1]]] = (bRes == false) ? 0 : 1;
vRAM[registers[buffer[2]]] = BYTEHIGH(x2);
vRAM[registers[buffer[2]]+1] = BYTELOW(x2);
vRAM[registers[buffer[3]]] = BYTEHIGH(x3);
vRAM[registers[buffer[3]]+1] = BYTELOW(x3);
break;
default:
Serial.print("Unknown Command: 0x");
Serial.println(buffer[0],HEX);
break;
}
acc = acc + 4;
}
SD.closeFile(3);
}
The title line on the KickStarter page says āArMF Imbue : An All-In-On For Everyoneā. I am guessing that it is suppose to be āArMF Imbue : An All-In-One For Everyoneā. One instead of on.
@ tstewart - good catch! I canāt update anything until admins are done but Iāll change it as soon as its unlocked.
Iām with godefroi in that you need to be prepared on day one to explain the details of Arduino running on this since more people will probably come from that camp than any other. There needs to be something in the project description that tells just how Arduino is operating. I think the tendency will be to assume that itās running natively and youāll have a lot of angry customers if they donāt figure out until it arrives that itās actually interpreted. I know you say a little about there being a PC app that does some magic but for an Arduino person thatās never run NETMF and doesnāt knows that itās interpreted code, theyāre just going to assume Arduino runs as theyāre used to it running.
Txt me as soon as itās up. I want to be your first supporter
txt us all ! We all want to be close to Ianās pledge !
Thanks guys will do! Iāll be sure to mention regular Arduino based off the Due could be ported over as well.
Thereās really not a good shot of the back of the board anywhere. Thereās a few quick glimpses in the video but it would be nice to have a good static pic in the Kickstarter somewhere. Will there be an ICSP port?
How much of this will be open sourced? I donāt see an OSHW logo anywhere. If the target market is education (universities) then I would think this would be important.
Itās open source. You donāt have to out a logo on it for it to be. But perhaps Iāll put it on the final board. KS mentions its open source but Iāll try to make it more clear. Iāll also add a pick of the back.
I see the project is live on Kickstarter now!
http://www.kickstarter.com/projects/skewworks/armf-imbue-an-all-in-one-for-everyone?ref=recently_launched
That literally JUST happened; you are beating me to the punch Bob!
Is your āArduinoā compiler/virtual CPU open source?
I had plans to make it so. However the KickStarter seems to be dead in the water so Iām not sure what the future holds for it.