Here is my "BETA" version of an interpreter.
No documentation yet sorry.
.
Fibonacci 6000 times is completed in 68460 microseconds unoptimized.
EDIT: It is currently running on a UNO.
Please do not distribute this without my permission.
Here is the code.
// ==================================================================
// BC256 --Byte Code 256-- INSTRUCTIONS (1.0) "BETA"
// ==================================================================
#define PAUSE_CODE
#define PIN_CTRL
#define ANLG_CTRL // Adds an extra micros? unknown reason
#define EXTRA_MATH
enum {
STOP = 0,
MOVr = 1, // => reg=reg
MOVb = 2, // => reg=byte
PRINT = 3, // => Serial.println(reg)
ADDr = 4, // => reg+=reg
ADDb = 5, // => reg+=byte
SUBr = 6, // => reg-reg
SUBb = 7, // => reg-=byte
MULr = 8, // => reg*=reg
MULb = 9, // => reg*=byte
DIVr = 10, // => reg/=reg
DIVb = 11, // => reg/=byte
MODr = 12, // => reg%=reg
MODb = 13, // => reg%=byte
SWAP = 14, // => reg<->reg
BEGr = 15, // => loop reg
BEGb = 16, // => loop byte
LOOP = 17, // => loop end
PUSH = 18, // => mem=reg
POP = 19, // => reg=mem
PSHALL = 20, // mem=all regs
POPALL = 21, // alls regs=mem
JMPe = 22, // jump to address if =
JMPl = 23, // jump to address if <
JMPg = 24, // jump to address if >
JMPle = 25, // jump to address if <=
JMPge = 26, // jump to address if >=
JMPne = 27, // jump to address if !=
INCR = 28, // reg++
DECR = 29, // reg--
#ifdef PAUSE_CODE
HALTr = 30, // pause reg milliseconds
HALTb = 31, // pause byte milliseconds
HLTMr = 32, // pause reg microseconds
HLTMb = 33, // pause byte microseconds
#endif
#ifdef PIN_CTRL
DDRBr = 34, // DDRB = reg
DDRBb = 35, // DDRB = byte
DDRCr = 36, // DDRC = reg
DDRCb = 37, // DDRC = byte
DDRDr = 38, // DDRD = reg
DDRDb = 39, // DDRD = byte
PORTBr = 40, // PORTB = reg
PORTBb = 41, // PORTB = byte
PORTCr = 42, // PORTC = reg
PORTCb = 43, // PORTC = byte
PORTDr = 44, // PORTD = reg
PORTDb = 45, // PORTD = byte
BPIN = 46, // reg = PINB
CPIN = 47, // reg = PINC
DPIN = 48, // reg = PIND
#ifdef ANLG_CTRL
ANLGOr = 49, // Analog out reg
ANLGOb = 50, // Analog out byte
ANLGIN = 51, // reg = analog in
#endif
#endif
#ifdef EXTRA_MATH
RSHFTr = 52, // reg>>=reg
RSHFTb = 53, // reg>>=byte
LSHFTr = 54, // reg<<=reg
LSHFTb = 55, // reg<<=byte
ANDr = 56, // reg&=reg
ANDb = 57, // reg&=byte
ORr = 58, // reg|=reg
ORb = 59, // reg|=byte
XORr = 60, // reg^=reg
XORb = 61, // reg^=byte
NOTr = 62, // reg=~reg
#endif
};
const byte program[] PROGMEM = {
MOVb, 0, 1, // A=1
MOVb, 1, 1, // B=1
MOVb, 5, 24, // ??=24 ==:9
PUSH, 4, // mem=?
PUSH, 5, // mem=??
MOVb, 5, 250, // ??=250 == :16
ADDr, 0, 1, // A=A+1
SWAP, 0, 1, // B=A & A=B
INCR, 4, // ?++
JMPl, 0, 16, // ?<?? jump to byte 16
POP, 5, // ?=mem
POP, 4, // ??=mem
INCR, 4, // ?++
JMPl, 0, 9, // ?<?? jump to byte 9
STOP, // Program end
};
byte pRAM[1536];
byte regs[11]; // A = [0], B = [1], C = [2], D = [3], ? = [4], ?? = [5], sp = [6], lpt = [7], lpa = [8], lpa = [9], lpc = [10]
int progaddr = 0;
byte a = 0, b = 0, c = 0, instr = 0;
unsigned long time;
void setup() {
randomSeed(analogRead(6));
Serial.begin(9600);
for (int load = 0; load < sizeof(program); load++) {
pRAM[load] = pgm_read_byte_near(program+load);
}
time = micros();
BC256();
Serial.println(micros()-time);
}
void loop() {
}
// ==================================================================
// BC256 --Byte Code 256-- INTEPRETER (1.0) "BETA"
// ==================================================================
void BC256() {
#define nxtc() pRAM[progaddr++]
static void* labels[]= {&&instr_0,&&instr_1,&&instr_2,&&instr_3,&&instr_4,&&instr_5,&&instr_6,&&instr_7,&&instr_8,&&instr_9,&&instr_10,&&instr_11,&&instr_12,&&instr_13,&&instr_14,&&instr_15,&&instr_16,&&instr_17,&&instr_18,&&instr_19,&&instr_20,&&instr_21,&&instr_22,&&instr_23,&&instr_24,&&instr_25,&&instr_26,&&instr_27,&&instr_28,&&instr_29,
#ifdef PAUSE_CODE
&&instr_30,&&instr_31,&&instr_32,&&instr_33,
#endif
#ifdef PIN_CTRL
&&instr_34,&&instr_35,&&instr_36,&&instr_37,&&instr_38,&&instr_39,&&instr_40,&&instr_41,&&instr_42,&&instr_43,&&instr_44,&&instr_45,&&instr_46,&&instr_47,&&instr_48,
#ifdef ANLG_CTRL
&&instr_49,&&instr_50,&&instr_51,
#endif
#endif
#ifdef EXTRA_MATH
&&instr_52,&&instr_53,&&instr_54,&&instr_55,&&instr_56,&&instr_57,&&instr_58,&&instr_59,&&instr_60,&&instr_61,&&instr_62
#endif
};
#define doinstr() {goto *(labels[instr]);}
run_prog:
instr = nxtc();
doinstr();
instr_0: // => End program
return;
goto run_prog;
instr_1: // => Mov reg <- reg
a = nxtc();
b = nxtc();
regs[a] = regs[b];
goto run_prog;
instr_2: // => Mov reg <- byte
a = nxtc();
b = nxtc();
regs[a] = b;
goto run_prog;
instr_3:
a = nxtc();
Serial.println(regs[a]);
goto run_prog;
instr_4: // => Add reg += reg
a = nxtc();
b = nxtc();
regs[a] += regs[b];
goto run_prog;
instr_5: // => Add reg += byte
a = nxtc();
b = nxtc();
regs[a] += b;
goto run_prog;
instr_6: // => Sub reg += reg
a = nxtc();
b = nxtc();
regs[a] -= regs[b];
goto run_prog;
instr_7: // => Sub reg += byte
a = nxtc();
b = nxtc();
regs[a] -= b;
goto run_prog;
instr_8: // => Mul reg *= reg
a = nxtc();
b = nxtc();
regs[a] *= regs[b];
goto run_prog;
instr_9: // => Mul reg *= byte
a = nxtc();
b = nxtc();
regs[a] *= b;
goto run_prog;
instr_10: // => Div reg /= reg
a = nxtc();
b = nxtc();
regs[a] /= regs[b];
goto run_prog;
instr_11: // => Div reg /= byte
a = nxtc();
b = nxtc();
regs[a] /= b;
goto run_prog;
instr_12: // => Mod reg %= reg
a = nxtc();
b = nxtc();
regs[a] %= regs[b];
goto run_prog;
instr_13: // => Mod reg %= byte
a = nxtc();
b = nxtc();
regs[a] %= b;
goto run_prog;
instr_14: // => Swap reg <-> reg
a = nxtc();
b = nxtc();
c = regs[a];
regs[a] = regs[b];
regs[b] = c;
goto run_prog;
instr_15: // => Loop reg
a = nxtc();
regs[7] = regs[a];
regs[8] = progaddr;
regs[9] = 0;
goto run_prog;
instr_16: // => Loop byte
a = nxtc();
regs[7] = a;
regs[8] = progaddr >> 8;
regs[9] = progaddr & 0xFF;
regs[10] = 0;
goto run_prog;
instr_17: // => Loop end
regs[10]++;
if (regs[10] < regs[7]) {progaddr = word(regs[8], regs[9]);}
goto run_prog;
instr_18: // => Push reg
a = nxtc();
b = 1535 - regs[6];
pRAM[b] = regs[a];
regs[6]++;
regs[a] = 0;
goto run_prog;
instr_19: // => Pop reg
regs[6]--;
a = nxtc();
b = 1535 - regs[6];
regs[a] = pRAM[b];
goto run_prog;
instr_20: // => Push all
a = 1535 - regs[6];
for (byte pshlp = 0; pshlp < 11; pshlp++) {if (pshlp != 6) {pRAM[a-pshlp] = regs[pshlp]; regs[pshlp] = 0;}}
regs[6] += 11;
goto run_prog;
instr_21: // => Pop all
a = 1536 - regs[6];
for (byte poplp = 0; poplp < 11; poplp++) {if (poplp != 4) {regs[10-poplp] = pRAM[a+poplp];}}
regs[6] -= 11;
goto run_prog;
instr_22: // => Jmp equal
a = nxtc();
b = nxtc();
if (regs[4] == regs[5]) {progaddr = word(a, b);}
goto run_prog;
instr_23: // => Jmp less then
a = nxtc();
b = nxtc();
if (regs[4] < regs[5]) {progaddr = word(a, b);}
goto run_prog;
instr_24: // => Jmp greater then
a = nxtc();
b = nxtc();
if (regs[4] > regs[5]) {progaddr = word(a, b);}
goto run_prog;
instr_25: // => Jmp less or equal then
a = nxtc();
b = nxtc();
if (regs[4] <= regs[5]) {progaddr = word(a, b);}
goto run_prog;
instr_26: // => Jmp greater or equal then
a = nxtc();
b = nxtc();
if (regs[4] >= regs[5]) {progaddr = word(a, b);}
goto run_prog;
instr_27: // => Jmp not equal
a = nxtc();
b = nxtc();
if (regs[4] != regs[5]) {progaddr = word(a, b);}
goto run_prog;
instr_28: // => Increase reg by one
a = nxtc();
regs[a]++;
goto run_prog;
instr_29: // => Decrease reg by one
a = nxtc();
regs[a]--;
goto run_prog;
#ifdef PAUSE_CODE
instr_30: // => Delay millis reg
a = nxtc();
delay(regs[a]);
goto run_prog;
instr_31: // => Delay millis byte
a = nxtc();
delay(a);
goto run_prog;
instr_32: // => Delay micros reg
a = nxtc();
delayMicroseconds(regs[a]);
goto run_prog;
instr_33: // => Delay micros byte
a = nxtc();
delayMicroseconds(a);
goto run_prog;
#endif
#ifdef PIN_CTRL
instr_34: // => DDRB reg
a = nxtc();
DDRB = regs[a];
goto run_prog;
instr_35: // => DDRB byte
a = nxtc();
DDRB = a;
goto run_prog;
instr_36: // => DDRC reg
a = nxtc();
DDRC = regs[a];
goto run_prog;
instr_37: // => DDRC byte
a = nxtc();
DDRC = a;
goto run_prog;
instr_38: // => DDRD reg
a = nxtc();
DDRD = regs[a];
goto run_prog;
instr_39: // => DDRD byte
a = nxtc();
DDRD = a;
goto run_prog;
instr_40: // => PORTB reg
a = nxtc();
PORTB = regs[a];
goto run_prog;
instr_41: // => PORTB byte
a = nxtc();
PORTB = a;
goto run_prog;
instr_42: // => PORTC reg
a = nxtc();
PORTC = regs[a];
goto run_prog;
instr_43: // => PORTC byte
a = nxtc();
PORTC = a;
goto run_prog;
instr_44: // => PORTD reg
a = nxtc();
PORTD = regs[a];
goto run_prog;
instr_45: // => PORTD byte
a = nxtc();
PORTD = a;
goto run_prog;
instr_46: // => PINB reg
a = nxtc();
regs[a] = PINB;
goto run_prog;
instr_47: // => PINC reg
a = nxtc();
regs[a] = PINC;
goto run_prog;
instr_48: // => PIND reg
a = nxtc();
regs[a] = PIND;
goto run_prog;
#ifdef ANLG_CTRL
instr_49: // => Analog out reg
a = nxtc();
analogWrite(regs[0], regs[a]);
goto run_prog;
instr_50: // => Analog out byte
a = nxtc();
analogWrite(regs[0], a);
goto run_prog;
instr_51: // => Analog in reg
a = nxtc();
regs[a] = analogRead(regs[0]);
goto run_prog;
#endif
#endif
#ifdef EXTRA_MATH
instr_52: // => Right shift reg reg
a = nxtc();
b = nxtc();
regs[a] >>= regs[b];
goto run_prog;
instr_53: // => Right shift reg byte
a = nxtc();
b = nxtc();
regs[a] >>= b;
goto run_prog;
instr_54: // => Left shift reg reg
a = nxtc();
b = nxtc();
regs[a] <<= regs[b];
goto run_prog;
instr_55: // => Left shift reg byte
a = nxtc();
b = nxtc();
regs[a] <<= b;
goto run_prog;
instr_56: // => And reg &= reg
a = nxtc();
b = nxtc();
regs[a] &= regs[b];
goto run_prog;
instr_57: // => And reg &= byte
a = nxtc();
b = nxtc();
regs[a] &= b;
goto run_prog;
instr_58: // => Or reg |= reg
a = nxtc();
b = nxtc();
regs[a] |= regs[b];
goto run_prog;
instr_59: // => Or reg |= byte
a = nxtc();
b = nxtc();
regs[a] |= b;
goto run_prog;
instr_60: // => Xor reg ^= reg
a = nxtc();
b = nxtc();
regs[a] ^= regs[b];
goto run_prog;
instr_61: // => Xor reg ^= byte
a = nxtc();
b = nxtc();
regs[a] ^= b;
goto run_prog;
instr_62: // => Not reg ~= byte
a = nxtc();
regs[a] = ~regs[a];
goto run_prog;
#endif
}