diff --git a/.gitignore b/.gitignore index 5321bb1..821dbbe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +*.swp +*.swo */.DS_Store examples/bitlashdemo/applet examples/*/applet diff --git a/README-UNIX.md b/README-UNIX.md index aa21b5b..4db9711 100644 --- a/README-UNIX.md +++ b/README-UNIX.md @@ -8,6 +8,11 @@ Here are some notes on experimental Unix support for Bitlash. - the basic functions work - on OS X, numvar is 64 bits, so everything is 64 bits wide - Makefile in src/ will build the binary as src/bin/bitlash + - Requires the ArduinoUnix library, which can be cloned from + https://github.com/matthijskooijman/ArduinoUnix. The makefile + normally looks for a directory called "ArduinoUnix" next to + the bitlash directory, but this can be changed by setting + ARDUINO_UNIX_PATH when calling make. - there are some precompiled binaries in src/bin/ - eeprom is simulated diff --git a/bitlash.cpp b/bitlash.cpp index a529a3f..92de9d1 100644 --- a/bitlash.cpp +++ b/bitlash.cpp @@ -34,27 +34,16 @@ ***/ -#if defined(ARDUINO) && ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif - -#ifdef UNIX_BUILD -#include "src/bitlash-unix.c" -//#else -//#include "src/bitlash-arduino.c" -#endif - -#include "src/bitlash-cmdline.c" -#include "src/bitlash-eeprom.c" -#include "src/bitlash-error.c" -#include "src/bitlash-functions.c" -#include "src/bitlash-builtins.c" -#include "src/bitlash-interpreter.c" -#include "src/bitlash-instream.c" -#include "src/bitlash-parser.c" -#include "src/bitlash-serial.c" -#include "src/bitlash-taskmgr.c" -#include "src/bitlash-api.c" -#include "src/eeprom.c" + +#include "src/bitlash-cmdline.cpp" +#include "src/bitlash-eeprom.cpp" +#include "src/bitlash-error.cpp" +#include "src/bitlash-functions.cpp" +#include "src/bitlash-builtins.cpp" +#include "src/bitlash-interpreter.cpp" +#include "src/bitlash-instream.cpp" +#include "src/bitlash-parser.cpp" +#include "src/bitlash-serial.cpp" +#include "src/bitlash-taskmgr.cpp" +#include "src/bitlash-api.cpp" +#include "src/eeprom.cpp" diff --git a/bitlash.h b/bitlash.h index 1405b44..0623a4f 100644 --- a/bitlash.h +++ b/bitlash.h @@ -33,78 +33,10 @@ OTHER DEALINGS IN THE SOFTWARE. ***/ -#if defined(ARDUINO) && ARDUINO >= 100 - #include "Arduino.h" - #define prog_char char PROGMEM - #define prog_uchar unsigned char PROGMEM -#else - #include "WProgram.h" -#endif +#include "src/bitlash-public.h" // Un-comment the line below to expose all the internals // of the Bitlash core to your sketch. // -//#include "src/bitlash.h" - -/////////////////////// -// Start Bitlash, and give it cycles to do stuff -// -void initBitlash(unsigned long baud); // start up and set baud rate -void runBitlash(void); // call this in loop(), frequently - -// Bitlash variables are of type "numvar" -// -typedef long int numvar; // bitlash returns things of type numvar -typedef unsigned long int unumvar; // sometimes unsigned interpretation is best (like millis) - - -/////////////////////// -// Pass a command to Bitlash for interpretation -// -numvar doCommand(char *); // execute a command from your sketch -void doCharacter(char); // pass an input character to the line editor - -/////////////////////// -// Access to Numeric Variables -// -// NOTE: access to variables a..z is via an index 0..25, not the variable names. Got it? -// -numvar getVar(unsigned char); // return value of bitlash variable. id is [0..25] for [a..z] -void assignVar(unsigned char, numvar); // assign value to variable. id is [0..25] for [a..z] -numvar incVar(unsigned char); // increment variable. id is [0..25] for [a..z] - - -/////////////////////// -// Access to the Bitlash symbol table -// -// Lookup id and return TRUE if it exists -// -byte findscript(char *); // returns TRUE if a script exists with this ID -int getValue(char *key); // return location of macro value in EEPROM or -1 - -/////////////////////// -// Add a user function to Bitlash -// -typedef numvar (*bitlash_function)(void); -void addBitlashFunction(const char *, bitlash_function); -numvar getarg(numvar); -numvar isstringarg(numvar); -numvar getstringarg(numvar which); - -/////////////////////// -// Serial Output Capture -// -typedef void (*serialOutputFunc)(byte); -byte serialIsOverridden(void); -void setOutputHandler(serialOutputFunc); -void setOutput(byte pin); -void resetOutputHandler(void); -numvar func_printf_handler(byte, byte); - -/////////////////////// -// File functions -// -numvar sdcat(void); -numvar sdwrite(char *filename, char *contents, byte append); -numvar func_fprintf(void); +//#include "src/bitlash-private.h" diff --git a/examples/bitlash_rf/bitlash_rf.h b/examples/bitlash_rf/bitlash_rf.h index d63de64..ae9e77e 100644 --- a/examples/bitlash_rf/bitlash_rf.h +++ b/examples/bitlash_rf/bitlash_rf.h @@ -57,10 +57,6 @@ //#define RADIO_VIRTUALWIRE //#include "VirtualWire.h" -// Arduino detector -// -#define ARDUINO_BUILD 1 - #include #include #include "pkt.h" diff --git a/src/Makefile b/src/Makefile index a9f182a..508abee 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,16 @@ -all: - gcc -pthread *.c -o bin/bitlash +ARDUINO_UNIX_PATH ?= ../../ArduinoUnix + +include $(ARDUINO_UNIX_PATH)/Makefile.mk + +CFLAGS := -DUNIX_BUILD -pthread -I$(ARDUINO_UNIX_INCLUDE_PATH) +LDFLAGS := -lstdc++ -pthread +SOURCES := $(wildcard *.cpp) $(ARDUINO_UNIX_SOURCES) +BINARY := bin/bitlash +PREFIX := /usr/local +BINPATH := $(PREFIX)/bin + +all: + gcc $(LDFLAGS) $(CFLAGS) $(SOURCES) -o $(BINARY) install: - sudo cp bin/bitlash /usr/local/bin/ + sudo cp $(BINARY) $(BINPATH) diff --git a/src/bin/bitlash b/src/bin/bitlash index 12c529c..6c71cd5 100755 Binary files a/src/bin/bitlash and b/src/bin/bitlash differ diff --git a/src/bitlash-api.c b/src/bitlash-api.cpp similarity index 83% rename from src/bitlash-api.c rename to src/bitlash-api.cpp index da829e0..096a059 100644 --- a/src/bitlash-api.c +++ b/src/bitlash-api.cpp @@ -33,7 +33,7 @@ OTHER DEALINGS IN THE SOFTWARE. ***/ -#include "bitlash.h" +#include "bitlash-private.h" // Exception handling state @@ -45,19 +45,12 @@ jmp_buf env; // // doCommand: main entry point to execute a bitlash command // -numvar doCommand(char *cmd) { +numvar doCommand(const char *cmd) { return execscript(SCRIPT_RAM, (numvar) cmd, 0); } -void initBitlash(unsigned long baud) { - -#if defined(TINY_BUILD) - beginSerial(9600); -#else - beginSerial(baud); -#endif - +static void initBitlashInternal() { #if defined(ARM_BUILD) eeinit(); #endif @@ -76,3 +69,17 @@ void initBitlash(unsigned long baud) { initlbuf(); } +#ifndef DEFAULT_CONSOLE_ONLY +void initBitlash(Stream& stream) { + blout = bloutdefault = blconsole = &stream; + initBitlashInternal(); +} +#endif + +void initBitlash(unsigned long baud) { + #if defined(TINY_BUILD) + baud = 9600; + #endif + DEFAULT_CONSOLE.begin(baud); + initBitlashInternal(); +} diff --git a/src/bitlash-builtins.c b/src/bitlash-builtins.cpp similarity index 98% rename from src/bitlash-builtins.c rename to src/bitlash-builtins.cpp index 5c9c911..c88a8c6 100644 --- a/src/bitlash-builtins.c +++ b/src/bitlash-builtins.cpp @@ -33,7 +33,7 @@ OTHER DEALINGS IN THE SOFTWARE. ***/ -#include "bitlash.h" +#include "bitlash-private.h" /********** @@ -87,7 +87,7 @@ const prog_char builtin_table[] PROGMEM = { -byte findbuiltin(char *name) { +byte findbuiltin(const char *name) { const prog_char *wordlist = builtin_table; while (pgm_read_byte(wordlist)) { diff --git a/src/bitlash-cmdline.c b/src/bitlash-cmdline.cpp similarity index 96% rename from src/bitlash-cmdline.c rename to src/bitlash-cmdline.cpp index 45ac712..de9cfef 100644 --- a/src/bitlash-cmdline.c +++ b/src/bitlash-cmdline.cpp @@ -33,7 +33,7 @@ OTHER DEALINGS IN THE SOFTWARE. ***/ -#include "bitlash.h" +#include "bitlash-private.h" // Serial command line buffer @@ -106,7 +106,7 @@ void initlbuf(void) { prompt(); // flush any pending serial input - while (serialAvailable()) serialRead(); + while (blconsole->read() >= 0) /* nothing */; } @@ -125,7 +125,7 @@ byte putlbuf(char c) { void pointToError(void) { if (fetchtype == SCRIPT_RAM) { - int i = (char *) fetchptr - lbuf; + int i = (const char *) fetchptr - lbuf; if ((i < 0) || (i >= LBUFLEN)) return; speol(); while (i-- >= 0) spb('-'); @@ -197,7 +197,7 @@ void doCharacter(char c) { void runBitlash(void) { // Pipe the serial input into the command handler - if (serialAvailable()) doCharacter(serialRead()); + if (blconsole->available()) doCharacter(blconsole->read()); // Background macro handler: feed it one call each time through runBackgroundTasks(); diff --git a/src/bitlash-config.h b/src/bitlash-config.h new file mode 100644 index 0000000..57b5286 --- /dev/null +++ b/src/bitlash-config.h @@ -0,0 +1,334 @@ +/*** + bitlash-config.h - Build options + + Bitlash is a tiny language interpreter that provides a serial port shell environment + for bit banging and hardware hacking. + + See the file README for documentation. + + Bitlash lives at: http://bitlash.net + The author can be reached at: bill@bitlash.net + + Copyright (C) 2008-2012 Bill Roy + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. +***/ + +#ifndef _BITLASH_CONFIG_H +#define _BITLASH_CONFIG_H + +// Uncomment this to set Arduino version if < 18: +//#define ARDUINO 15 + +//////////////////////////////////////////////////// +// GLOBAL BUILD OPTIONS +//////////////////////////////////////////////////// +// +// Enable LONG_ALIASES to make the parser recognize analogRead(x) as well as ar(x), and so on +// cost: ~200 bytes flash +//#define LONG_ALIASES 1 + +// +// Enable PARSER_TRACE to make ^T toggle a parser trace debug print stream +// cost: ~400 bytes flash +//#define PARSER_TRACE 1 + +// Define this to disable the initBitlash(Stream*) function and have the +// console I/O fixed to DEFAULT_CONSOLE (saves program memory) +//#define DEFAULT_CONSOLE_ONLY + +// Enable SD card script-in-file support +//#define SDFILE + + +#if !defined(ARDUINO) && !defined(UNIX_BUILD) +#error "Building is only supported through Arduino and src/Makefile. If you have an Arduino version older than 018 which does not define the ARDUINO variable, manually set your Arduino version in src/bitlash-config.h" +#endif + +#if defined(ARDUINO) && ARDUINO < 100 + #include "WProgram.h" +#else + #include "Arduino.h" + #define prog_char char PROGMEM + #define prog_uchar char PROGMEM +#endif + +/////////////////////////////////////////////////////// +// +// Find build type +#if !defined(UNIX_BUILD) +#if defined(__SAM3X8E__) +#define ARM_BUILD 1 +#elif (defined(__MK20DX128__) || defined(__MK20DX256__)) && defined (CORE_TEENSY) + // Teensy 3 + #define ARM_BUILD 2 +#elif defined(PART_LM4F120H5QR) //support Energia.nu - Stellaris Launchpad / Tiva C Series +#define ARM_BUILD 4 //support Energia.nu - Stellaris Launchpad / Tiva C Series +#else +#define AVR_BUILD 1 +#endif +#endif // !defined(UNIX_BUILD) + +/////////////////////////////////////////////////////// +// +// UNIX BUILD +// +// See README-UNIX.md for info about how to compile +// +#ifdef UNIX_BUILD +#define MINIMUM_FREE_RAM 200 +#define NUMPINS 32 +#undef SOFTWARE_SERIAL_TX +#define E2END 2047 + +#define DEFAULT_CONSOLE StdioStream +// No corresponding pin +#undef DEFAULT_OUTPIN + +#endif // defined unix_build + +//////////////////////////////////////////////////// +// +// ARDUINO BUILD +// (This includes third-party boards like sanguino) +// +//////////////////////////////////////////////////// +// +#if defined(ARDUINO) // this detects the Arduino build environment + +#ifdef SERIAL_PORT_MONITOR +#define DEFAULT_CONSOLE SERIAL_PORT_MONITOR +#else +// Support 1.0.5 and below and 1.5.4 and below, that don't have +// SERIAL_PORT_MONITOR defined +#define DEFAULT_CONSOLE Serial +#endif + +// Assume DEFAULT_CONSOLE lives at pin 0 (Arduino headers don't have +// any way of finding out). Might be undef'd or redefined below. +#define DEFAULT_OUTPIN 0 + +// Enable Software Serial tx support for Arduino +// this enables "setbaud(4, 4800); print #4:..." +// at a cost of about 400 bytes (for tx only) +// +#define SOFTWARE_SERIAL_TX 1 + +#define MINIMUM_FREE_RAM 50 + +// Arduino < 019 does not have the Stream class, so don't support +// passing a different Stream object to initBitlash +#if ARDUINO < 19 +#define DEFAULT_CONSOLE_ONLY +#endif + +#endif // defined(ARDUINO) + + +/////////////////////////////////////////////////////// +// +// SANGUINO BUILD +// +/////////////////////////////////////////////////////// +// +// SANGUINO is auto-enabled to build for the Sanguino '644 +// if the '644 define is present +// +#if defined(__AVR_ATmega644P__) +#define SANGUINO + +// Sanguino has 24 digital and 8 analog io pins +#define NUMPINS (24+8) + +// Sanguino primary serial tx output is on pin 9 (rx on 8) +// Sanguino alternate hardware serial port tx output is on pin 11 (rx on 10) +#define SANGUINO_DEFAULT_SERIAL 9 +#define SANGUINO_ALTERNATE_SERIAL 11 +#undef DEFAULT_OUTPIN +#define DEFAULT_OUTPIN SANGUINO_DEFAULT_SERIAL +#define ALTERNATE_OUTPIN SANGUINO_ALTERNATE_SERIAL + +#endif // defined (644) + + +/////////////////////////////////////////////////////// +// +// MEGA BUILD +// +// Note: These are speculative and untested. Feedback welcome. +// +/////////////////////////////////////////////////////// +// +// MEGA is auto-enabled to build for the Arduino Mega or Mega2560 +// if the '1280/'2560 define is present +// +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#define MEGA 1 + +// MEGA has 54 digital and 16 analog pins +#define NUMPINS (54+16) + +// Mega primary serial tx output is on pin 1 (rx on 0) +// Mega alternate hardware serial port tx output is on pin 18 (rx on 19) +// TODO: Support for hardware serial uart2 and uart3 +// +#define MEGA_DEFAULT_SERIAL 1 +#define MEGA_ALTERNATE_SERIAL 18 +#undef DEFAULT_OUTPIN +#define DEFAULT_OUTPIN MEGA_DEFAULT_SERIAL +#define ALTERNATE_OUTPIN MEGA_ALTERNATE_SERIAL + +#endif // defined (1280) + + +/////////////////////////////////////////////////////// +// +// Atmega64 BUILD +#if defined(__AVR_ATmega64__) +#define NUMPINS (53) +#endif + + +/////////////////////////////////////////////////////// +// +// TINY BUILD OPTIONS +// +#if defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny84__) +#define TINY_BUILD 1 +#undef MINIMUM_FREE_RAM +#define MINIMUM_FREE_RAM 20 +#define NUMPINS 6 +#undef SOFTWARE_SERIAL_TX +#endif // TINY_BUILD + + +/////////////////////////////////////////////////////// +// +// AVROPENDOUS and TEENSY BUILD +// +#if defined(__AVR_AT90USB162__) + +//#define AVROPENDOUS_BUILD +#if defined(AVROPENDOUS_BUILD) +#define MINIMUM_FREE_RAM 20 +#define NUMPINS 24 +#undef SOFTWARE_SERIAL_TX +// Serial is virtual (USB), so no corresponding pin +#undef DEFAULT_OUTPIN +#endif // defined AVRO + +#define TEENSY +#ifdef TEENSY +// No TEENSY options yet +#endif // defined TEENSY + +#endif // defined '162 + + +/////////////////////////////////////////////////////// +// +// AVROPENDOUS 32U4 and TEENSY2 BUILD +// +#if defined(__AVR_ATmega32U4__) + +//#define AVROPENDOUS_BUILD +#if defined(AVROPENDOUS_BUILD) +#define MINIMUM_FREE_RAM 50 +#define NUMPINS 40 +#undef SOFTWARE_SERIAL_TX +// Serial is virtual (USB), so no corresponding pin +#undef DEFAULT_OUTPIN +#endif // AVRO + +#define TEENSY2 +#if defined(TEENSY2) +// No TEENSY2 options yet +#endif // TEENSY2 + +#endif // defined '32U4 + + +//////////////////// +// +// ARM BUILD +#if defined(ARM_BUILD) + #define prog_char char +#define prog_uchar byte +#define PROGMEM +#define pgm_read_byte(b) (*(char *)(b)) +#define pgm_read_word(b) (*(int *)(b)) +#define strncpy_P strncpy +#define strcmp_P strcmp +#define strlen_P strlen +#if ARM_BUILD==1 + #define E2END 4096 +#else + // Teensy 3 + #define E2END 2048 +#endif + +#endif + +///////////////////////////////////////////// +// External EEPROM (I2C) +// +// Uncomment to enable EEPROM via I2C +// Supports a Microchip 24xx32A EEPROM module attached to the I2C bus +// http://ww1.microchip.com/downloads/en/DeviceDoc/21713J.pdf +// Specifically, the DigiX has such a module onboard +// https://digistump.com/wiki/digix/tutorials/eeprom +//#define EEPROM_MICROCHIP_24XX32A + +#define EEPROM_ADDRESS 0x50 // default EEPROM address for DigiX boards + +//////////////////////// +// +// EEPROM database begin/end offset +// +// Use the predefined constant from the avr-gcc support file +// +#if defined(EEPROM_MICROCHIP_24XX32A) + #define ENDDB 4095 + #define ENDEEPROM 4095 +#else + #define ENDDB E2END + #define ENDEEPROM E2END +#endif + + +// Enable USER_FUNCTIONS to include the add_bitlash_function() extension mechanism +// This costs about 256 bytes +// +#if !defined(TINY_BUILD) +#define USER_FUNCTIONS +#endif + +// String value buffer size +#ifdef AVR_BUILD + #define STRVALSIZE 120 +#else + #define STRVALSIZE 512 +#endif +#define STRVALLEN (STRVALSIZE-1) +#define LBUFLEN STRVALSIZE + +#endif // _BITLASH_CONFIG_H diff --git a/src/bitlash-eeprom.c b/src/bitlash-eeprom.cpp similarity index 94% rename from src/bitlash-eeprom.c rename to src/bitlash-eeprom.cpp index 0283f41..a140fff 100644 --- a/src/bitlash-eeprom.c +++ b/src/bitlash-eeprom.cpp @@ -33,7 +33,7 @@ OTHER DEALINGS IN THE SOFTWARE. ***/ -#include "bitlash.h" +#include "bitlash-private.h" /*** @@ -73,7 +73,7 @@ int findend(int addr) { // return true if string in EEPROM at addr matches string at str -char eestrmatch(int addr, char *str) { +char eestrmatch(int addr, const char *str) { while (*str) if (eeread(addr++) != *str++) return 0; if (eeread(addr) == 0) return 1; // ended at the same place? return 0; @@ -81,7 +81,7 @@ char eestrmatch(int addr, char *str) { // find an entry in the db; return offset of id or FAIL -int findKey(char *id) { +int findKey(const char *id) { int start = STARTDB; while (start < ENDDB-4) { // find the next entry @@ -100,7 +100,7 @@ int start = STARTDB; // Look up an entry by key. Returns -1 on fail else addr of value. -int getValue(char *key) { +int getValue(const char *key) { int kaddr = findKey(key); return (kaddr < 0) ? kaddr : findend(kaddr); } @@ -134,7 +134,7 @@ int starthole = STARTDB, endhole; // // Save string at str to EEPROM at addr -void saveString(int addr, char *str) { +void saveString(int addr, const char *str) { while (*str) eewrite(addr++, *str++); eewrite(addr, 0); } @@ -150,7 +150,7 @@ int erasestr(int addr) { } // erase entry by id -void eraseentry(char *id) { +void eraseentry(const char *id) { int entry = findKey(id); if (entry >= 0) erasestr(erasestr(entry)); } @@ -180,10 +180,10 @@ char id[IDLEN+1]; // buffer for id // fetchptr is on the character after '{' // // BUG: This is broken for file scripts - char *startmark = (char *) fetchptr; // mark first char of macro text + const char *startmark = (const char *) fetchptr; // mark first char of macro text void skipstatement(void); skipstatement(); // gobble it up without executing it - char *endmark = (char *) fetchptr; // and note the char past '}' + const char *endmark = (const char *) fetchptr; // and note the char past '}' // endmark is past the closing '}' - back up and find it do { diff --git a/src/bitlash-error.c b/src/bitlash-error.cpp similarity index 98% rename from src/bitlash-error.c rename to src/bitlash-error.cpp index e77e4ad..7e81f3e 100644 --- a/src/bitlash-error.c +++ b/src/bitlash-error.cpp @@ -33,7 +33,7 @@ OTHER DEALINGS IN THE SOFTWARE. ***/ -#include "bitlash.h" +#include "bitlash-private.h" void fatal2(char msg1, char msg2) { diff --git a/src/bitlash-functions.c b/src/bitlash-functions.cpp similarity index 96% rename from src/bitlash-functions.c rename to src/bitlash-functions.cpp index 6c2074f..c6acd64 100644 --- a/src/bitlash-functions.c +++ b/src/bitlash-functions.cpp @@ -31,7 +31,7 @@ OTHER DEALINGS IN THE SOFTWARE. ***/ -#include "bitlash.h" +#include "bitlash-private.h" // syntactic sugar for func_handlers() #if 0 // 15022 bytes @@ -176,7 +176,7 @@ numvar func_pulsein(void) { reqargs(3); return pulseIn(arg1, arg2, arg3); } numvar func_snooze(void) { reqargs(1); snooze(arg1); return 0; } numvar func_delay(void) { reqargs(1); delay(arg1); return 0; } -#if !defined(TINY_BUILD) +#if defined(SOFTWARE_SERIAL_TX) numvar func_setBaud(void) { reqargs(2); setBaud(arg1, arg2); return 0; } #endif @@ -189,17 +189,17 @@ numvar func_bitread(void) { reqargs(2); return (arg1 & ((numvar)1 << arg2)) != 0 numvar func_bitwrite(void) { reqargs(3); return arg3 ? func_bitset() : func_bitclear(); } numvar func_getkey(void) { - if (getarg(0) > 0) sp((char *) getarg(1)); - while (!serialAvailable()) {;} // blocking! - return (numvar) serialRead(); + if (getarg(0) > 0) sp((const char *) getarg(1)); + while (!blconsole->available()) {;} // blocking! + return (numvar) blconsole->read(); } numvar func_getnum(void) { numvar num = 0; - if (getarg(0) > 0) sp((char *) getarg(1)); + if (getarg(0) > 0) sp((const char *) getarg(1)); for (;;) { - while (!serialAvailable()) {;} // blocking! - int k = serialRead(); + while (!blconsole->available()) {;} // blocking! + int k = blconsole->read(); if ((k == '\r') || (k == '\n')) { speol(); return num; @@ -274,7 +274,9 @@ const prog_char functiondict[] PROGMEM = { "abs\0" "ar\0" "aw\0" +#if defined(SOFTWARE_SERIAL_TX) "baud\0" +#endif "bc\0" "beep\0" "br\0" @@ -351,7 +353,9 @@ const bitlash_function function_table[] PROGMEM = { func_abs, func_ar, func_aw, +#if defined(SOFTWARE_SERIAL_TX) func_setBaud, +#endif func_bitclear, func_beep, func_bitread, @@ -383,13 +387,6 @@ const bitlash_function function_table[] PROGMEM = { }; #endif -// Enable USER_FUNCTIONS to include the add_bitlash_function() extension mechanism -// This costs about 256 bytes -// -#if !defined(TINY_BUILD) -#define USER_FUNCTIONS -#endif - #ifdef USER_FUNCTIONS #define MAX_USER_FUNCTIONS 20 // increase this if needed, but keep free() > 200 ish #define USER_FUNCTION_FLAG 0x80 @@ -441,7 +438,7 @@ void addBitlashFunction(const char *name, bitlash_function func_ptr) { // find_user_function: find id in the user function table. // return true if found, with the user function token in symval (with USER_FUNCTION_FLAG set) // -char find_user_function(char *id) { +char find_user_function(const char *id) { symval = 0; while (symval < bf_install_count) { if (!strcmp(id, user_functions[symval].name)) { diff --git a/src/bitlash-instream.c b/src/bitlash-instream.cpp similarity index 88% rename from src/bitlash-instream.c rename to src/bitlash-instream.cpp index dad38f0..d57ffe7 100644 --- a/src/bitlash-instream.c +++ b/src/bitlash-instream.cpp @@ -33,21 +33,21 @@ OTHER DEALINGS IN THE SOFTWARE. ***/ -#include "bitlash.h" +#include "bitlash-private.h" -#if defined(SDFILE) +#if defined(SDFILE) || defined(UNIX_BUILD) #define O_READ 0x01 // from SdFile.h // Trampolines for the SD library -byte scriptfileexists(char *scriptname); -byte scriptopen(char *scriptname, numvar position, byte flags); +byte scriptfileexists(const char *scriptname); +byte scriptopen(const char *scriptname, numvar position, byte flags); numvar scriptgetpos(void); byte scriptread(void); -byte scriptwrite(char *filename, char *contents, byte append); +byte scriptwrite(const char *filename, const char *contents, byte append); void scriptwritebyte(byte b); -#elif !defined(UNIX_BUILD) -byte scriptfileexists(char *scriptname) { return 0; } +#else +byte scriptfileexists(const char *scriptname) { return 0; } #endif // masks for stashing the pointer type in the high nibble @@ -60,7 +60,7 @@ byte scriptfileexists(char *scriptname) { return 0; } #endif // forward declaration -void initparsepoint(byte scripttype, numvar scriptaddress, char *scriptname); +void initparsepoint(byte scripttype, numvar scriptaddress, const char *scriptname); ///////// @@ -72,7 +72,7 @@ void initparsepoint(byte scripttype, numvar scriptaddress, char *scriptname); // and in runBackgroundTasks to kick off the background run. // // -numvar execscript(byte scripttype, numvar scriptaddress, char *scriptname) { +numvar execscript(byte scripttype, numvar scriptaddress, const char *scriptname) { // save parse context parsepoint fetchmark; @@ -137,8 +137,8 @@ numvar execscript(byte scripttype, numvar scriptaddress, char *scriptname) { // how to access the calling and called function names // //#define callername ((char *) ((numvar *) arg[2]) [1]) -#define callername (arg[2] ? (char* ) (((numvar *) arg[2]) [1]) : NULL ) -#define calleename ((char *) arg[1]) +#define callername (arg[2] ? (const char* ) (((numvar *) arg[2]) [1]) : NULL ) +#define calleename ((const char *) arg[1]) ///////// @@ -195,7 +195,7 @@ void markparsepoint(parsepoint *p) { } -void initparsepoint(byte scripttype, numvar scriptaddress, char *scriptname) { +void initparsepoint(byte scripttype, numvar scriptaddress, const char *scriptname) { #ifdef PARSER_TRACE if (trace) { @@ -234,12 +234,12 @@ void initparsepoint(byte scripttype, numvar scriptaddress, char *scriptname) { #ifdef UNIX_BUILD -char *topname = ".top."; +const char *topname = ".top."; void returntoparsepoint(parsepoint *p, byte returntoparent) { // restore parse type and location; for script files, pass name from string pool byte ftype = p->fetchtype; - char *scriptname = calleename; + const char *scriptname = calleename; if (returntoparent) { if ((ftype == SCRIPT_NONE) || (ftype == SCRIPT_RAM)) scriptname = topname; @@ -297,7 +297,7 @@ void fetchc(void) { // void primec(void) { switch (fetchtype) { - case SCRIPT_RAM: inchar = *(char *) fetchptr; break; + case SCRIPT_RAM: inchar = *(const char *) fetchptr; break; case SCRIPT_PROGMEM: inchar = pgm_read_byte(fetchptr); break; case SCRIPT_EEPROM: inchar = eeread((int) fetchptr); break; @@ -327,7 +327,7 @@ void primec(void) { void traceback(void) { numvar *a = arg; while (a) { - sp((char *) (a[1])); speol(); + sp((const char *) (a[1])); speol(); a = (numvar *) (a[2]); } } @@ -340,10 +340,10 @@ numvar *a = arg; // "cat": copy file to serial out // numvar sdcat(void) { - if (!scriptfileexists((char *) getarg(1))) return 0; + if (!scriptfileexists((const char *) getarg(1))) return 0; parsepoint fetchmark; markparsepoint(&fetchmark); - initparsepoint(SCRIPT_FILE, 0L, (char *) getarg(1)); + initparsepoint(SCRIPT_FILE, 0L, (const char *) getarg(1)); while (inchar) { if (inchar == '\n') spb('\r'); spb(inchar); @@ -358,7 +358,7 @@ numvar sdcat(void) { // // sdwrite: write or append a line to a file // -numvar sdwrite(char *filename, char *contents, byte append) { +numvar sdwrite(const char *filename, const char *contents, byte append) { #if !defined(UNIX_BUILD) parsepoint fetchmark; markparsepoint(&fetchmark); @@ -373,6 +373,8 @@ numvar sdwrite(char *filename, char *contents, byte append) { return 1; } +// fprintf needs SERIAL_OVERRIDE to work +#ifdef SERIAL_OVERRIDE ////////// // // func_fprintf(): implementation of fprintf() function @@ -382,7 +384,7 @@ numvar func_fprintf(void) { parsepoint fetchmark; markparsepoint(&fetchmark); - scriptwrite((char *) getarg(1), "", 1); // open the file for append (but append nothing) + scriptwrite((const char *) getarg(1), "", 1); // open the file for append (but append nothing) //serialOutputFunc saved_handler = serial_override_handler; // save previous output handler void scriptwritebyte(byte); @@ -397,5 +399,6 @@ numvar func_fprintf(void) { #endif returntoparsepoint(&fetchmark, 1); } +#endif #endif // SDFILE diff --git a/src/bitlash-interpreter.c b/src/bitlash-interpreter.cpp similarity index 99% rename from src/bitlash-interpreter.c rename to src/bitlash-interpreter.cpp index 49abcbe..74be4af 100644 --- a/src/bitlash-interpreter.c +++ b/src/bitlash-interpreter.cpp @@ -33,7 +33,7 @@ OTHER DEALINGS IN THE SOFTWARE. ***/ -#include "bitlash.h" +#include "bitlash-private.h" // Turn HEX_UPLOAD on to enable the hex file EEPROM uploader diff --git a/src/bitlash-parser.c b/src/bitlash-parser.cpp similarity index 98% rename from src/bitlash-parser.c rename to src/bitlash-parser.cpp index 30d20a5..928f2de 100644 --- a/src/bitlash-parser.c +++ b/src/bitlash-parser.cpp @@ -33,7 +33,7 @@ OTHER DEALINGS IN THE SOFTWARE. ***/ -#include "bitlash.h" +#include "bitlash-private.h" #if defined(AVR_BUILD) #include "avr/eeprom.h" @@ -44,7 +44,7 @@ byte fetchtype; // current script type numvar fetchptr; // pointer to current char in script numvar symval; // value of current numeric expression -#if !USE_GPIORS +#if !defined(USE_GPIORS) byte sym; // current input symbol byte inchar; // Current parser character #endif @@ -222,7 +222,7 @@ void spush(char c) { } // push a string into the string pool -void strpush(char *ptr) { +void strpush(const char *ptr) { while (*ptr) spush(*ptr++); spush(0); } @@ -383,7 +383,7 @@ const prog_uchar reservedwordtypes[] PROGMEM = { s_arg, s_boot, s_else, s_functi #endif // find id in PROGMEM wordlist. result in symval, return true if found. -byte findindex(char *id, const prog_char *wordlist, byte sorted) { +byte findindex(const char *id, const prog_char *wordlist, byte sorted) { symval = 0; while (pgm_read_byte(wordlist)) { int result = strcmp_P(id, wordlist); @@ -436,7 +436,7 @@ const prog_uchar pinvalues[] PROGMEM = { 0, 1, 13, (PV_ANALOG | 1), (PV_VAR | 25) }; -byte findpinname(char *alias) { +byte findpinname(const char *alias) { if (!findindex(alias, (const prog_char *) pinnames, 0)) return 0; // sets symval byte pin = pgm_read_byte(pinvalues + symval); //sym = (pin & PV_ANALOG) ? s_apin : s_dpin; @@ -612,7 +612,9 @@ void parseid(void) { else if (findpinname(idbuf)) {;} // sym and symval are set in findpinname #endif +#ifdef USER_FUNCTIONS else if (find_user_function(idbuf)) sym = s_nfunct; +#endif else findscript(idbuf); } @@ -622,7 +624,7 @@ void parseid(void) { // // findscript: look up a script, with side effects // -byte findscript(char *idbuf) { +byte findscript(const char *idbuf) { // script function in eeprom? if ((symval=findKey(idbuf)) >= 0) sym = s_script_eeprom; diff --git a/src/bitlash-private.h b/src/bitlash-private.h new file mode 100644 index 0000000..094f3c6 --- /dev/null +++ b/src/bitlash-private.h @@ -0,0 +1,434 @@ +/*** + bitlash-private.h - Private API + + Bitlash is a tiny language interpreter that provides a serial port shell environment + for bit banging and hardware hacking. + + See the file README for documentation. + + Bitlash lives at: http://bitlash.net + The author can be reached at: bill@bitlash.net + + Copyright (C) 2008-2013 Bill Roy + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + +***/ +#ifndef _BITLASH_PRIVATE_H +#define _BITLASH_PRIVATE_H + +// bitlash-public.h declares public functions and types +// bitlash-private.h declares private (internal) functions and types +// bitlash-config.h contains (sometimes tweakable) build parameters +#include "bitlash-public.h" + +#if defined(AVR_BUILD) +#include "avr/pgmspace.h" +#endif + +#include +#include +#include + +///////////////////////////////////////////// +// bitlash-builtins.c +// +void displayBanner(void); +byte findbuiltin(const char *name); + +///////////////////////////////////////////// +// bitlash-cmdline.c +// +void initlbuf(void); +void pointToError(void); +void cmd_help(void); + +extern char *lbufptr; +extern char lbuf[LBUFLEN]; + +///////////////////////////////////////////// +// bitlash-eeprom.c +// +int findKey(const char *key); // return location of macro keyname in EEPROM or -1 + +int findoccupied(int); +int findend(int); +void eeputs(int); + +#define EMPTY ((uint8_t)255) +#define STARTDB 0 +#define FAIL ((int)-1) + +///////////////////////////////////////////// +// bitlash-error.c +// +extern jmp_buf env; +#define X_EXIT 1 +void fatal2(char, char); +void overflow(byte); +void underflow(byte); +void expected(byte); +void expectedchar(byte); +void unexpected(byte); +void missing(byte); +void oops(int); // fatal exit + + +///////////////////////////////////////////// +// bitlash-functions.c +// +void show_user_functions(void); +char find_user_function(const char *id); + +void dofunctioncall(byte); +numvar func_free(void); +void make_beep(unumvar, unumvar, unumvar); + +extern const prog_char functiondict[] PROGMEM; +extern const prog_char aliasdict[] PROGMEM; + +void stir(byte); + +///////////////////////////////////////////// +// bitlash-program.c +// +extern char startup[]; + + +///////////////////////////////////////////// +// bitlash-serial.c +// +void printIntegerInBase(unumvar, uint8_t, numvar, byte); +void printInteger(numvar,numvar, byte); +void printHex(unumvar); +void printBinary(unumvar); +void spb(char c); +void sp(const char *); +void speol(void); + +numvar func_printf(void); +numvar func_printf_handler(byte,byte); +void cmd_print(void); + +#ifdef SOFTWARE_SERIAL_TX +numvar setBaud(numvar, unumvar); +void resetOutput(void); +#endif + +#ifdef ARDUINO +void chkbreak(void); +void cmd_print(void); +#endif + +// The Stream where input is read from and print writes to when there is +// not output handler set. +#ifndef DEFAULT_CONSOLE_ONLY +extern Stream *blconsole; +#else +// Console is fixed to DEFAULT_CONSOLE, so make blconsole a unchangeable +// pointer to DEFAULT_CONSOLE. By also copying the type of +// DEFAULT_CONSOLE, the compiler can optimize away all vtable operations +// for minimal code overhead +__typeof__(DEFAULT_CONSOLE) * const blconsole = &DEFAULT_CONSOLE; +#endif + +// The Print object where the print command normally goes (e.g. when not +// redirected with print #10: "foo") +#ifdef SERIAL_OVERRIDE +extern Print *bloutdefault; +#else +// SERIAL_OVERRIDE is disabled, so print redirection should always just +// reset blout to blconsole. Using this define, we essentially make both +// identifiers refer to the same variable. +#define bloutdefault blconsole +#endif + +// The Print object where the print command goes right now +#ifdef SOFTWARE_SERIAL_TX +extern Print *blout; +#else +// SOFTWARE_SERIAL_TX is disabled, so printing should always just go to +// bloutdefault. Using this define, we essentiallyl make both +// identifiers refer to the same variable. +#define blout bloutdefault +#endif + +// Note that if SOFTWARE_SERIAL_TX and SERIAL_OVERRIDE are disabled, +// then blconsole, bloutdefault and blout are all effectively the same +// variable. + +///////////////////////////////////////////// +// bitlash-taskmgr.c +// +void initTaskList(void); +void runBackgroundTasks(void); +void stopTask(byte); +void startTask(int, numvar); +void snooze(unumvar); +void showTaskList(void); +unsigned long millisUntilNextTask(void); +extern byte background; +extern byte curtask; +extern byte suspendBackground; + + +///////////////////////////////////////////// +// eeprom.c +// +void eewrite(int, byte); +byte eeread(int); +void eraseentry(const char *id); +void cmd_function(void); +void cmd_ls(void); +void cmd_peep(void); + +#if defined(AVR_BUILD) +// they must live off piste due to aggressive compiler inlining. +void eewrite(int, byte) __attribute__((noinline)); +byte eeread(int) __attribute__((noinline)); +#endif + +#if defined(ARM_BUILD) +extern char virtual_eeprom[]; +void eeinit(void); +#endif + + +///////////////////////////////////////////// +// bitlash-interpreter.c +// +numvar getstatementlist(void); +void domacrocall(int); + + +///////////////////////////////////////////// +// bitlash-parser.c +// +void vinit(void); // init the value stack +void vpush(numvar); // push a numvar on the stack +numvar vpop(void); // pop a numvar +extern byte vsptr; +#define vsempty() vsptr==0 +extern numvar *arg; // argument frame pointer + +// parse context types +#define SCRIPT_NONE 0 +#define SCRIPT_RAM 1 +#define SCRIPT_PROGMEM 2 +#define SCRIPT_EEPROM 3 +#define SCRIPT_FILE 4 + +byte scriptfileexists(const char *); +numvar execscript(byte, numvar, const char *); +void callscriptfunction(byte, numvar); + +typedef struct { + numvar fetchptr; + byte fetchtype; +} parsepoint; + +void markparsepoint(parsepoint *); +void returntoparsepoint(parsepoint *, byte); +void primec(void); +void fetchc(void); +void getsym(void); +void traceback(void); + +const prog_char *getmsg(byte); +void parsestring(void (*)(char)); +void msgp(byte); +void msgpl(byte); +numvar getnum(void); +void calleeprommacro(int); +void getexpression(void); +byte hexval(char); +byte is_end(void); +numvar isstring(void); +void releaseargblock(void); +void parsearglist(void); +extern const prog_char reservedwords[]; + + + +// Interpreter globals +extern byte fetchtype; // current script type +extern numvar fetchptr; // pointer to current char in input buffer +extern numvar symval; // value of current numeric expression + +#if defined(AVR_BUILD) && defined(GPIOR0) && defined(GPIOR1) +#define USE_GPIORS +#define sym GPIOR0 +#define inchar GPIOR1 +#else +extern byte sym; // current input symbol +extern byte inchar; // Current parser character +#endif + +#ifdef PARSER_TRACE +extern byte trace; +void tb(void); +#endif + + +// Expression result +extern byte exptype; // type of expression: s_nval [or s_sval] +extern numvar expval; // value of numeric expr or length of string + +// Temporary buffer for ids +#define IDLEN 12 +extern char idbuf[IDLEN+1]; + +///////////////////////////////////////////// +// bitlash-instream.c +// + +#if defined(SDFILE) || defined(UNIX_BUILD) +numvar sdwrite(const char *filename, const char *contents, byte append); +#endif + +///////////////////////////////////////////// +// bitlash-unix-file.c +// +#if defined(UNIX_BUILD) +numvar exec(void); +numvar sdls(void); +numvar sdexists(void); +numvar sdrm(void); +numvar sdcreate(void); +numvar sdappend(void); +numvar sdcd(void); +numvar sdmd(void); +numvar func_pwd(void); +#endif + +// Strings live in PROGMEM to save ram +// +#define M_expected 0 +#define M_unexpected 1 +#define M_missing 2 +#define M_string 3 +#define M_underflow 4 +#define M_overflow 5 +#define M_ctrlc 6 +#define M_ctrlb 7 +#define M_ctrlu 8 +#define M_exp 9 +#define M_op 10 +#define M_pfmts 11 +#define M_eof 12 +#define M_var 13 +#define M_number 14 +#define M_rparen 15 +#define M_saved 16 +#define M_eeprom 17 +#define M_defmacro 18 +#define M_prompt 19 +#define M_char 20 +#define M_stack 21 +#define M_startup 22 +#define M_id 23 +#define M_promptid 24 +#define M_functions 25 +#define M_oops 26 +#define M_arg 27 +#define M_function 28 + + +// Names for symbols +// +// Each symbol in the grammar is parsed to a unique symval enumerated here +// +// One character symbols take their ascii value as their symval +// Complex symbols have the high bit set so start at 128 (0x80) +// +#define s_eof 0 +#define s_undef (0 | 0x80) +#define s_nval (1 | 0x80) +#define s_sval (2 | 0x80) +#define s_nvar (3 | 0x80) +#define s_le (4 | 0x80) +#define s_ge (5 | 0x80) +#define s_logicaland (6 | 0x80) +#define s_logicalor (7 | 0x80) +#define s_logicaleq (8 | 0x80) +#define s_logicalne (9 | 0x80) +#define s_shiftleft (10 | 0x80) +#define s_shiftright (11 | 0x80) +#define s_incr (12 | 0x80) +#define s_decr (13 | 0x80) +#define s_nfunct (14 | 0x80) +#define s_if (15 | 0x80) +#define s_while (16 | 0x80) +#define s_apin (17 | 0x80) +#define s_dpin (18 | 0x80) +#define s_define (19 | 0x80) +#define s_function (20 | 0x80) +#define s_rm (21 | 0x80) +#define s_run (22 | 0x80) +#define s_ps (23 | 0x80) +#define s_stop (24 | 0x80) +#define s_boot (25 | 0x80) +#define s_peep (26 | 0x80) +#define s_help (27 | 0x80) +#define s_ls (28 | 0x80) +#define s_print (29 | 0x80) +#define s_switch (30 | 0x80) +#define s_return (31 | 0x80) +#define s_returning (32 | 0x80) +#define s_arg (33 | 0x80) +#define s_else (34 | 0x80) +#define s_script_eeprom (35 | 0x80) +#define s_script_progmem (36 | 0x80) +#define s_script_file (37 | 0x80) +#define s_comment (38 | 0x80) + + +// Names for literal symbols: these one-character symbols +// are represented by their 7-bit ascii char code +#define s_semi ';' +#define s_add '+' +#define s_sub '-' +#define s_mul '*' +#define s_div '/' +#define s_mod '%' +#define s_lparen '(' +#define s_rparen ')' +#define s_dot '.' +#define s_lt '<' +#define s_gt '>' +#define s_equals '=' +#define s_bitand '&' +#define s_bitor '|' +#define s_comma ',' +#define s_bitnot '~' +#define s_logicalnot '!' +#define s_xor '^' +#define s_colon ':' +#define s_pound '#' +#define s_quote '"' +#define s_dollars '$' +#define s_lcurly '{' +#define s_rcurly '}' + + +#endif // defined _BITLASH_H + diff --git a/src/bitlash-public.h b/src/bitlash-public.h new file mode 100644 index 0000000..b71d1af --- /dev/null +++ b/src/bitlash-public.h @@ -0,0 +1,127 @@ +/*** + bitlash-public.h - public API + + Bitlash is a tiny language interpreter that provides a serial port shell environment + for bit banging and hardware hacking. + + See the file README for documentation. + + Bitlash lives at: http://bitlash.net + The author can be reached at: bill@bitlash.net + + Copyright (C) 2008-2012 Bill Roy + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + +***/ +#ifndef _BITLASH_PUBLIC_H +#define _BITLASH_PUBLIC_H + +// bitlash-public.h declares public functions and types +// bitlash-private.h declares private (internal) functions and types +// bitlash-config.h contains (sometimes tweakable) build parameters +#include "bitlash-config.h" + +/////////////////////// +// Bitlash variables are of type "numvar" +// +// numvar is 32 bits, except for tiny builds where it is 16 bits +#if !defined(TINY_BUILD) +typedef long int numvar; +typedef unsigned long int unumvar; +#else +typedef int numvar; +typedef unsigned int unumvar; +#endif // !defined(TINY_BUILD) + +/////////////////////// +// Start Bitlash, and give it cycles to do stuff +// +void initBitlash(unsigned long baud); // start up and set baud rate +#ifndef DEFAULT_CONSOLE_ONLY +void initBitlash(Stream& stream); +#endif +void runBitlash(void); // call this in loop(), frequently + + +/////////////////////// +// Pass a command to Bitlash for interpretation +// +numvar doCommand(const char *); // execute a command from your sketch +void doCharacter(char); // pass an input character to the line editor + +/////////////////////// +// Access to Numeric Variables +// +// NOTE: access to variables a..z is via an index 0..25, not the variable names. Got it? +// +numvar getVar(unsigned char); // return value of bitlash variable. id is [0..25] for [a..z] +void assignVar(unsigned char, numvar); // assign value to variable. id is [0..25] for [a..z] +numvar incVar(unsigned char); // increment variable. id is [0..25] for [a..z] + + +/////////////////////// +// Access to the Bitlash symbol table +// +// Lookup id and return TRUE if it exists +// +byte findscript(const char *); // returns TRUE if a script exists with this ID +int getValue(const char *key); // return location of macro value in EEPROM or -1 + +/////////////////////// +// Add a user function to Bitlash +// +typedef numvar (*bitlash_function)(void); +void addBitlashFunction(const char *, bitlash_function); +numvar getarg(numvar); +numvar isstringarg(numvar); +numvar getstringarg(numvar which); + +/////////////////////// +// Serial Output Capture +// +#define SERIAL_OVERRIDE +#ifdef SERIAL_OVERRIDE +typedef void (*serialOutputFunc)(byte); +byte serialIsOverridden(void); +void setOutputHandler(serialOutputFunc); +void setOutputHandler(Print& newHandler); +void resetOutputHandler(void); +#endif +numvar func_printf_handler(byte, byte); + +#ifdef SOFTWARE_SERIAL_TX +void setOutput(byte pin); +#endif + +/////////////////////// +// File functions +// +#if defined(UNIX_BUILD) +numvar sdcat(void); +#endif +#if defined(SDFILE) || defined(UNIX_BUILD) +numvar sdwrite(const char *filename, const char *contents, byte append); +#endif +numvar func_fprintf(void); + +#endif // _BITLASH_PUBLIC_H diff --git a/src/bitlash-serial.c b/src/bitlash-serial.cpp similarity index 61% rename from src/bitlash-serial.c rename to src/bitlash-serial.cpp index e003335..dbd7e8b 100644 --- a/src/bitlash-serial.c +++ b/src/bitlash-serial.cpp @@ -33,17 +33,19 @@ OTHER DEALINGS IN THE SOFTWARE. ***/ -#include "bitlash.h" +#include "bitlash-private.h" +#ifndef DEFAULT_CONSOLE_ONLY +Stream *blconsole = &DEFAULT_CONSOLE; +#endif -// Character io primitives -//#define spb serialWrite +#ifdef SERIAL_OVERRIDE +Print *bloutdefault = blconsole; +#endif -// The default default outpin is, of course, zero -#ifndef DEFAULT_OUTPIN -#define DEFAULT_OUTPIN 0 +#ifdef SOFTWARE_SERIAL_TX +Print *blout = blconsole; #endif -byte outpin = DEFAULT_OUTPIN; // output pin #ifdef SOFTWARE_SERIAL_TX @@ -52,10 +54,46 @@ byte outpin = DEFAULT_OUTPIN; // output pin #ifndef NUMPINS #define NUMPINS 32 // default to Arduino Diecimila/168..328 #endif -int bittime[NUMPINS]; // bit times (1000000/baud) per pin, 0 = uninitialized // set output back to 'stdout' ;) -void resetOutput(void) { outpin = DEFAULT_OUTPIN; } +void resetOutput(void) { blout = bloutdefault; } + +// TX-only minimal software serial implementation +class SoftwareSerialTX : public Print { +public: + uint8_t pin; + static uint16_t bittime[NUMPINS]; // bit times (1000000/baud) per pin, 0 = uninitialized + + // bit whack a byte out the port designated by 'outpin' +#if defined(ARDUINO) && ARDUINO < 100 + virtual void write(uint8_t c) { +#else + virtual size_t write(uint8_t c) { +#endif + const uint16_t bt = bittime[this->pin]; + char bits = 8; // 8 data bits + digitalWrite(this->pin, LOW); + delayMicroseconds(bt); + while (bits--) { + //if ((c & 1) == 0) digitalWrite(outpin, LOW); + //else digitalWrite(outpin, HIGH); + digitalWrite(this->pin, c & 1); + delayMicroseconds(bt); + c >>= 1; + } + digitalWrite(this->pin, HIGH); + delayMicroseconds(bt<<1); +#if !(defined(ARDUINO) && ARDUINO < 100) + return 1; +#endif + } + + +}; + +uint16_t SoftwareSerialTX::bittime[]; + +static SoftwareSerialTX sstx; void chkpin(char pin) { // TODO: fix this warning re: comparison @@ -65,12 +103,12 @@ void chkpin(char pin) { numvar setBaud(numvar pin, unumvar baud) { chkpin(pin); -//#ifndef SOFTWARE_SERIAL_TX +#ifdef DEFAULT_OUTPIN if (pin == DEFAULT_OUTPIN) { - beginSerial(baud); + DEFAULT_CONSOLE.begin(baud); return 0; } -//#endif +#endif #ifdef ALTERNATE_OUTPIN else if (pin == ALTERNATE_OUTPIN) { @@ -79,45 +117,36 @@ numvar setBaud(numvar pin, unumvar baud) { } #endif - bittime[pin] = (1000000/baud) - clockCyclesToMicroseconds(50); + sstx.bittime[pin] = (1000000/baud) - clockCyclesToMicroseconds(50); pinMode(pin, OUTPUT); // make it an output digitalWrite(pin, HIGH); // set idle - delayMicroseconds(bittime[pin]); // let it quiesce - return bittime[pin]; + delayMicroseconds(sstx.bittime[pin]); // let it quiesce + return sstx.bittime[pin]; } void setOutput(byte pin) { chkpin(pin); - outpin = pin; -#ifdef HARDWARE_SERIAL_TX - // skip soft baud check for the hardware uart - if (outpin != DEFAULT_OUTPIN) +#ifdef DEFAULT_OUTPIN + if (pin == DEFAULT_OUTPIN) { + blout = &DEFAULT_CONSOLE; + return; + } #endif + #ifdef ALTERNATE_OUTPIN - if (outpin != ALTERNATE_OUTPIN) + if (pin == ALTERNATE_OUTPIN) { + blout = &Serial1; + return; + } #endif // set the softserial baud if it's not already set - if (!bittime[outpin]) setBaud(pin, DEFAULT_SECONDARY_BAUD); + if (!sstx.bittime[pin]) setBaud(pin, DEFAULT_SECONDARY_BAUD); + sstx.pin = pin; + blout = &sstx; } -// bit whack a byte out the port designated by 'outpin' -void whackabyte(unsigned char c) { - int bt = bittime[outpin]; - char bits = 8; // 8 data bits - digitalWrite(outpin, LOW); - delayMicroseconds(bt); - while (bits--) { - //if ((c & 1) == 0) digitalWrite(outpin, LOW); - //else digitalWrite(outpin, HIGH); - digitalWrite(outpin, c & 1); - delayMicroseconds(bt); - c >>= 1; - } - digitalWrite(outpin, HIGH); - delayMicroseconds(bt<<1); -} #endif // SOFTWARE_SERIAL_TX @@ -129,16 +158,40 @@ void whackabyte(unsigned char c) { // serialOutputFunc serial_override_handler; +class PrintToFunction : public Print { +public: + serialOutputFunc func; + +#if defined(ARDUINO) && ARDUINO < 100 + virtual void write(uint8_t c) +#else + virtual size_t write(uint8_t c) +#endif + { + func (c); +#if !(defined(ARDUINO) && ARDUINO < 100) + return 1; +#endif + } +}; + +static PrintToFunction outputHandlerPrint; + byte serialIsOverridden(void) { - return serial_override_handler != 0; + return bloutdefault != blconsole; } void setOutputHandler(serialOutputFunc newHandler) { - serial_override_handler = newHandler; + outputHandlerPrint.func = newHandler; + blout = bloutdefault = &outputHandlerPrint; +} + +void setOutputHandler(Print& print) { + blout = bloutdefault = &print; } void resetOutputHandler(void) { - serial_override_handler = 0; + blout = bloutdefault = blconsole; } #endif @@ -150,138 +203,13 @@ void resetOutputHandler(void) { // // this is a pinchpoint on output. all output funnels through spb. // -#if defined(HARDWARE_SERIAL_TX) || defined(SOFTWARE_SERIAL_TX) void spb(char c) { -#ifdef HARDWARE_SERIAL_TX - if (outpin == DEFAULT_OUTPIN) { - -#ifdef SERIAL_OVERRIDE - if (serial_override_handler) (*serial_override_handler)(c); - else -#endif - serialWrite(c); - return; - } -#endif -#ifdef ALTERNATE_OUTPIN - if (outpin == ALTERNATE_OUTPIN) { Serial1.print(c); return; } -#endif -#ifdef SOFTWARE_SERIAL_TX - whackabyte(c); -#endif + blout->write((uint8_t)c); } + void sp(const char *str) { while (*str) spb(*str++); } void speol(void) { spb(13); spb(10); } -#else -// handle no-serial case -#endif - - -/* - bitlash software serial rx implementation adapted from: - SoftwareSerial.cpp - Software serial library - Copyright (c) 2006 David A. Mellis. All right reserved. - hacked by ladyada -*/ -#ifdef SOFTWARE_SERIAL_RX - -#define MAX_SOFT_RX_BUFF 32 -volatile uint8_t soft_rx_buffer_head; -uint8_t soft_rx_buffer_tail; -char soft_rx_buffer[MAX_SOFT_RX_BUFF]; - -// Pin-change interrupt handlers -// -// NOTE: Currently, software rx is supported only on pins d0..d7. -// -//SIGNAL(SIG_PIN_CHANGE0) {} - -#ifdef ARDUINO_BUILD -#define RXPINCHANGEREG PCMSK2 -SIGNAL(SIG_PIN_CHANGE2) { -#else -#define RXPINCHANGEREG PCMSK0 -SIGNAL(PCINT0_vect) { -#endif - if ((RXPIN < 8) && !digitalRead(RXPIN)) { - char c = 0; - int bitdelay = bittime[RXPIN]; - // would be nice to know latency to here - delayMicroseconds(bitdelay >> 1); // wait half a bit to get centered - for (uint8_t i=0; i<8; i++) { - delayMicroseconds(bitdelay); - if (digitalRead(RXPIN)) c |= _BV(i); - } - delayMicroseconds(bitdelay); // fingers in ears for one stop bit - - uint8_t newhead = soft_rx_buffer_head + 1; - if (newhead >= MAX_SOFT_RX_BUFF) newhead = 0; - if (newhead != soft_rx_buffer_tail) { - soft_rx_buffer[soft_rx_buffer_head] = c; - soft_rx_buffer_head = newhead; - } - } -} - -int softSerialRead(void) { - uint8_t c; - if (soft_rx_buffer_tail == soft_rx_buffer_head) return -1; - c = soft_rx_buffer[soft_rx_buffer_tail]; - cli(); // clean increment means less excrement - if (++soft_rx_buffer_tail >= MAX_SOFT_RX_BUFF) soft_rx_buffer_tail = 0; - sei(); - return c; -} -int softSerialAvailable(void) { - cli(); - uint8_t avail = (soft_rx_buffer_tail != soft_rx_buffer_head); - sei(); - return avail; -} - -void beginSoftSerial(unsigned long baud) { - -#ifdef BAUD_OVERRIDE - baud = BAUD_OVERRIDE; -#endif - // set up the output pin and copy its bit rate - bittime[RXPIN] = setBaud(DEFAULT_OUTPIN, baud); - pinMode(RXPIN, INPUT); // make it an input - digitalWrite(RXPIN, HIGH); // and engage the pullup - delayMicroseconds(bittime[RXPIN]); // gratuitous stop bits - - // Enable the pin-change interrupt for RXPIN - if (RXPIN < 8) { // a PIND pin, PCINT16-23 - RXPINCHANGEREG |= _BV(RXPIN); - PCICR |= _BV(2); - } -#if 0 - // for pins above 7: enable these, set up a signal handler above, - // and off you go. - else if (RXPIN <= 13) { // a PINB pin, PCINT0-5 - PCMSK0 |= _BV(RXPIN-8); - PCICR |= _BV(0); - } - else if (RXPIN < 23) { // a PINC pin, PCINT8-14 - PCMSK1 |= _BV(RXPIN-14); - PCICR != _BV(1) - } -#endif - else unexpected(M_number); - // todo: handle a0..7; pin out of range; extend for Sanguino, Mega, ... -} - -// aliases for the rest of the interpreter -#define serialAvailable softSerialAvailable -#define serialRead softSerialRead -#define beginSerial beginSoftSerial - -#endif // SOFTWARE_SERIAL_RX - - -#if (defined(ARDUINO_BUILD) && (ARDUINO_VERSION >= 12)) || defined(AVROPENDOUS_BUILD) || defined(UNIX_BUILD) -// From Arduino 0011/wiring_serial.c -// These apparently were removed from wiring_serial.c in 0012 void printIntegerInBase(unumvar n, uint8_t base, numvar width, byte pad) { char buf[8 * sizeof(numvar)]; // stack for the digits @@ -319,9 +247,6 @@ void printInteger(numvar n, numvar width, byte pad) { } void printHex(unumvar n) { printIntegerInBase(n, 16, 0, '0'); } void printBinary(unumvar n) { printIntegerInBase(n, 2, 0, '0'); } -#endif - - #if defined(UNIX_BUILD) @@ -338,11 +263,17 @@ void chkbreak(void) { // check serial input stream for ^C break void chkbreak(void) { - if (serialAvailable()) { // allow ^C to break out - if (serialRead() == 3) { // BUG: this gobblesnarfs input characters! - need serialPeek() - msgpl(M_ctrlc); - longjmp(env, X_EXIT); - } + // allow ^C to break out +#if defined(ARDUINO) && ARDUINO < 100 + // Arduino before 1.0 didn't have peek(), so just read a + // byte (this discards a byte when it wasn't ^C, though... + if (blconsole->read() == 3) { +#else + if (blconsole->peek() == 3) { + blconsole->read(); +#endif + msgpl(M_ctrlc); + longjmp(env, X_EXIT); } if (func_free() < MINIMUM_FREE_RAM) overflow(M_stack); } @@ -386,7 +317,7 @@ void cmd_print(void) { else if (symval == 'b'-'a') printBinary((unumvar) expval); // :b print binary #endif else if (symval == 'y'-'a') spb(expval); // :y print byte - else if (symval == 's'-'a') sp((char *)expval); // :s print string + else if (symval == 's'-'a') sp((const char *)expval); // :s print string } else if (sym > ' ') while (expval-- > 0) spb(sym); // any litsym else expected(M_pfmts); @@ -422,7 +353,7 @@ numvar func_printf_handler(byte formatarg, byte optionalargs) { // todo: get rid of s_pound if (getarg(0) < formatarg) { speol(); return 0; } - char *fptr = (char *) getarg(formatarg); // format string pointer + const char *fptr = (const char *) getarg(formatarg); // format string pointer while (*fptr) { if (*fptr == '%') { @@ -447,7 +378,7 @@ numvar func_printf_handler(byte formatarg, byte optionalargs) { case 'b': printIntegerInBase(getarg(optionalargs), 2, width, pad); break; // binary case 's': { // string - char *sptr = (char *) getarg(optionalargs); + const char *sptr = (const char *) getarg(optionalargs); // BUG: width is the max not the prepad width -= strlen(sptr); while (width-- > 0) spb(' '); // pre-pad with blanks diff --git a/src/bitlash-taskmgr.c b/src/bitlash-taskmgr.cpp similarity index 99% rename from src/bitlash-taskmgr.c rename to src/bitlash-taskmgr.cpp index 6fef279..1e529c5 100644 --- a/src/bitlash-taskmgr.c +++ b/src/bitlash-taskmgr.cpp @@ -33,7 +33,7 @@ OTHER DEALINGS IN THE SOFTWARE. ***/ -#include "bitlash.h" +#include "bitlash-private.h" // Background task manager diff --git a/src/bitlash-unix-file.c b/src/bitlash-unix-file.cpp similarity index 88% rename from src/bitlash-unix-file.c rename to src/bitlash-unix-file.cpp index 035fd5d..f882685 100644 --- a/src/bitlash-unix-file.c +++ b/src/bitlash-unix-file.cpp @@ -76,7 +76,12 @@ ... uploads memdump as "md" ***/ -#include "bitlash.h" +#include "bitlash-private.h" +#include +#include +#include +#include +#include #if defined(UNIX_BUILD) @@ -90,7 +95,7 @@ char cachedname[FNAMELEN]; byte cachedflags; // return true iff script exists -byte scriptfileexists(char *scriptname) { +byte scriptfileexists(const char *scriptname) { FILE *file; if ((file = fopen(scriptname, "r")) == NULL) return 0; fclose(file); @@ -106,7 +111,7 @@ byte scriptclose(void) { } // open and set parse location on input file -byte scriptopen(char *scriptname, numvar position, byte flags) { +byte scriptopen(const char *scriptname, numvar position, byte flags) { // open the input file if there is no file open, // or the open file does not match what we want @@ -140,14 +145,14 @@ byte scriptread(void) { return input; } -byte scriptwrite(char *filename, char *contents, byte append) { +byte scriptwrite(const char *filename, const char *contents, byte append) { /// if (scriptfile_is_open) { /// if (!scriptfile.close()) return 0; /// } FILE *outfile; - char *flags; + const char *flags; if (append) flags = "a"; else flags = "w"; @@ -179,28 +184,28 @@ numvar sdls(void) { return 0; } numvar sdexists(void) { - return scriptfileexists((char *) getarg(1)); + return scriptfileexists((const char *) getarg(1)); } numvar sdrm(void) { - return unlink((char *) getarg(1)); + return unlink((const char *) getarg(1)); } numvar sdcreate(void) { - return sdwrite((char *) getarg(1), (char *) getarg(2), 0); + return sdwrite((const char *) getarg(1), (const char *) getarg(2), 0); } numvar sdappend(void) { - return sdwrite((char *) getarg(1), (char *) getarg(2), 1); + return sdwrite((const char *) getarg(1), (const char *) getarg(2), 1); } numvar sdcd(void) { // close any cached open file handle if (scriptfile_is_open) scriptclose(); - return chdir((char *) getarg(1)); + return chdir((const char *) getarg(1)); } numvar sdmd(void) { - return mkdir((char *) getarg(1)); + return mkdir((const char *) getarg(1), 0777); } numvar exec(void) { - return doCommand((char *) getarg(1)); + return doCommand((const char *) getarg(1)); } numvar func_pwd(void) { @@ -234,4 +239,4 @@ void setup(void) { #endif -#endif // defined(UNIX_BUILD) \ No newline at end of file +#endif // defined(UNIX_BUILD) diff --git a/src/bitlash-unix.c b/src/bitlash-unix.cpp similarity index 55% rename from src/bitlash-unix.c rename to src/bitlash-unix.cpp index 4262e39..d4728eb 100644 --- a/src/bitlash-unix.c +++ b/src/bitlash-unix.cpp @@ -26,14 +26,17 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "bitlash.h" +#include "bitlash-private.h" +#include +#include +#include +#include /* Build: - cd bitlash/src - mac: gcc *.c -o bitlash - linux: gcc -pthread *.c -o bitlash + cd bitlash/src + make Issues @@ -65,159 +68,6 @@ boot segfaults ;) char bitlash_directory[PATH_LEN]; #define DEFAULT_BITLASH_PATH "/.bitlash/" - -#if _POSIX_TIMERS // not on the Mac, unfortunately -struct timespec startup_time, current_time, elapsed_time; - -// from http://www.guyrutenberg.com/2007/09/22/profiling-code-using-clock_gettime/ -struct timespec time_diff(struct timespec start, struct timespec end) { - struct timespec temp; - if ((end.tv_nsec-start.tv_nsec)<0) { - temp.tv_sec = end.tv_sec-start.tv_sec-1; - temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; - } else { - temp.tv_sec = end.tv_sec-start.tv_sec; - temp.tv_nsec = end.tv_nsec-start.tv_nsec; - } - return temp; -} - -void init_millis(void) { - clock_gettime(CLOCK_REALTIME, &startup_time); -} - -unsigned long millis(void) { - clock_gettime(CLOCK_REALTIME, ¤t_time); - elapsed_time = time_diff(startup_time, current_time); - return (elapsed_time.tv_sec * 1000UL) + (elapsed_time.tv_nsec / 1000000UL); -} -#else -#include - -unsigned long startup_millis, current_millis, elapsed_millis; -struct timeval startup_time, current_time; - -// after http://laclefyoshi.blogspot.com/2011/05/getting-nanoseconds-in-c-on-freebsd.html -void init_millis(void) { - gettimeofday(&startup_time, NULL); - startup_millis = (startup_time.tv_sec * 1000) + (startup_time.tv_usec /1000); -} - -unsigned long millis(void) { - gettimeofday(¤t_time, NULL); - current_millis = (current_time.tv_sec * 1000) + (current_time.tv_usec / 1000); - elapsed_millis = current_millis - startup_millis; - return elapsed_millis; -} - -#endif - - -#if 0 -// after http://stackoverflow.com/questions/4025891/create-a-function-to-check-for-key-press-in-unix-using-ncurses -//#include - -int init_keyboard(void) { - initscr(); - cbreak(); - noecho(); - nodelay(stdscr, TRUE); - scrollok(stdscr, TRUE); -} - -int serialAvailable(void) { - int ch = getch(); - - if (ch != ERR) { - ungetch(ch); - return 1; - } - else return 0; -} - -int serialRead(void) { return getch(); } -#endif - -#if 0 -//#include "conio.h" -int lookahead_key = -1; - -int serialAvailable(void) { - if (lookahead_key != -1) return 1; - lookahead_key = mygetch(); - if (lookahead_key == -1) return 0; - //printf("getch: %d ", lookahead_key); - return 1; -} - -int serialRead(void) { - if (lookahead_key != -1) { - int retval = lookahead_key; - lookahead_key = -1; - //printf("key: %d", retval); - return retval; - } - return mygetch(); -} -#endif - -#if 1 -int serialAvailable(void) { - return 0; -} - -int serialRead(void) { - return '$'; -} - -#endif - -void spb (char c) { - if (serial_override_handler) (*serial_override_handler)(c); - else { - putchar(c); - //printf("%c", c); - fflush(stdout); - } -} -void sp(const char *str) { while (*str) spb(*str++); } -void speol(void) { spb(13); spb(10); } - -numvar setBaud(numvar pin, unumvar baud) { return 0; } - -// stubs for the hardware IO functions -// -unsigned long pins; -void pinMode(byte pin, byte mode) { ; } -int digitalRead(byte pin) { return ((pins & (1< 0) fname = (char *) getarg(1); + const char *fname = "eeprom"; + if (getarg(0) > 0) fname = (const char *) getarg(1); savefd = fopen(fname, "w"); if (!savefd) return 0; setOutputHandler(&fputbyte); @@ -243,6 +94,7 @@ numvar func_save(void) { fclose(savefd); return 1; }; +#endif @@ -272,7 +124,7 @@ void *BackgroundMacroThread(void *threadid) { numvar func_system(void) { - return system((char *) getarg(1)); + return system((const char *) getarg(1)); } numvar func_exit(void) { @@ -310,10 +162,11 @@ int main () { init_fake_eeprom(); addBitlashFunction("system", (bitlash_function) &func_system); addBitlashFunction("exit", (bitlash_function) &func_exit); + #ifdef SERIAL_OVERRIDE addBitlashFunction("save", (bitlash_function) &func_save); + #endif // from bitlash-unix-file.c - extern bitlash_function exec, sdls, sdexists, sdrm, sdcreate, sdappend, sdcat, sdcd, sdmd, func_pwd; addBitlashFunction("exec", (bitlash_function) &exec); addBitlashFunction("dir", (bitlash_function) &sdls); addBitlashFunction("exists", (bitlash_function) &sdexists); @@ -324,10 +177,12 @@ int main () { addBitlashFunction("cd", (bitlash_function) &sdcd); addBitlashFunction("md", (bitlash_function) &sdmd); addBitlashFunction("pwd", (bitlash_function) &func_pwd); + #ifdef SERIAL_OVERRIDE addBitlashFunction("fprintf", (bitlash_function) &func_fprintf); + #endif - init_millis(); + init(); initBitlash(0); //signal(SIGINT, inthandler); @@ -338,7 +193,7 @@ int main () { // run the main stdin command loop for (;;) { - char * ret = fgets(lbuf, STRVALLEN, stdin); + const char * ret = fgets(lbuf, STRVALLEN, stdin); if (ret == NULL) break; doCommand(lbuf); initlbuf(); diff --git a/src/bitlash.h b/src/bitlash.h deleted file mode 100644 index 3616d23..0000000 --- a/src/bitlash.h +++ /dev/null @@ -1,860 +0,0 @@ -/*** - bitlash.h - - Bitlash is a tiny language interpreter that provides a serial port shell environment - for bit banging and hardware hacking. - - See the file README for documentation. - - Bitlash lives at: http://bitlash.net - The author can be reached at: bill@bitlash.net - - Copyright (C) 2008-2013 Bill Roy - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - -***/ -#ifndef _BITLASH_H -#define _BITLASH_H - -#if defined(__x86_64__) || defined(__i386__) -#define UNIX_BUILD 1 -#elif defined(__SAM3X8E__) -#define ARM_BUILD 1 -#elif (defined(__MK20DX128__) || defined(__MK20DX256__)) && defined (CORE_TEENSY) - // Teensy 3 - #define ARM_BUILD 2 -#elif defined(PART_LM4F120H5QR) //support Energia.nu - Stellaris Launchpad / Tiva C Series -#define ARM_BUILD 4 //support Energia.nu - Stellaris Launchpad / Tiva C Series -#else -#define AVR_BUILD 1 -#endif - - -#if defined(AVR_BUILD) -#include "avr/io.h" -#include "avr/pgmspace.h" -#include "avr/interrupt.h" -#endif - -#if defined(AVR_BUILD) || defined(ARM_BUILD) -#include "string.h" -#include "ctype.h" -#include "setjmp.h" -#endif - -// Unix includes -#if defined(UNIX_BUILD) -#include -#include -#include -#include -#include "ctype.h" -#include "setjmp.h" -#include -#include -#include -//#include -#endif - -#ifndef byte -#define byte uint8_t -#endif - - -//////////////////////////////////////////////////// -// GLOBAL BUILD OPTIONS -//////////////////////////////////////////////////// -// -// Enable LONG_ALIASES to make the parser recognize analogRead(x) as well as ar(x), and so on -// cost: ~200 bytes flash -//#define LONG_ALIASES 1 - -// -// Enable PARSER_TRACE to make ^T toggle a parser trace debug print stream -// cost: ~400 bytes flash -//#define PARSER_TRACE 1 - - - -//////////////////////////////////////////////////// -// -// ARDUINO BUILD OPTIONS -// -//////////////////////////////////////////////////// -// -#if defined(HIGH) || defined(ARDUINO) // this detects the Arduino build environment - -#define ARDUINO_BUILD 1 - -//#define ARDUINO_VERSION 14 // working -//#define ARDUINO_VERSION 15 // working -#define ARDUINO_VERSION 16 // working, released - -// the serial support, she is changing all the time -#if ARDUINO_VERSION >= 15 -#define beginSerial Serial.begin -#define serialAvailable Serial.available -#define serialRead Serial.read - -#if defined(ARDUINO) && ARDUINO >= 100 - #define serialWrite Serial.write -#else - #define serialWrite Serial.print -#endif - -#endif - -// Arduino version: 11 - enable by hand if needed; see bitlash-serial.h -//#define ARDUINO_VERSION 11 - - -#if defined(ARDUINO) && ARDUINO >= 100 - #include "Arduino.h" - #define prog_char char PROGMEM - #define prog_uchar char PROGMEM -#else - #include "WProgram.h" - #include "WConstants.h" -#endif - - -// Enable Software Serial tx support for Arduino -// this enables "setbaud(4, 4800); print #4:..." -// at a cost of about 400 bytes (for tx only) -// -#define SOFTWARE_SERIAL_TX 1 -#define HARDWARE_SERIAL_TX 1 - -#define MINIMUM_FREE_RAM 50 - -#else -#define HIGH 1 -#define LOW 0 -#endif // HIGH: arduino build - - -/////////////////////////////////////////////////////// -// -// ARDUINO ETHERNET BUILD OPTIONS -// -/////////////////////////////////////////////////////// -// -// Enable WIZ_ETHERNET true to build for telnet access to the official Arduino -// WIZ-5100 Ethernet shield -//#define WIZ_ETHERNET 1 -// -// Enable AF_ETHERNET to build for telnet access to the Adafruit Ethernet shield -// configured per the pinout below -// -//#define AF_ETHERNET 1 -// - -/////////////////////////////////////////////////////// -// WIZNET ETHERNET CONFIGURATION -// -#ifdef WIZ_ETHERNET - -// -// You'll need these two lines in your sketch, as of Arduino-0022: -// -// #include -// #include -// - -byte mac[] = { 'b','i','t','l','s','h' }; -byte ip[] = { 192, 168, 1, 27 }; -byte gateway[] = { 192, 168, 1, 1 }; -byte subnet[] = {255,255,255,0}; -#define PORT 8080 -Server server = Server(PORT); - -#define beginSerial beginEthernet -#define serialAvailable server.available -#define serialRead server.available().read -#define serialWrite server.write -void beginEthernet(unsigned long baud) { - Ethernet.begin(mac, ip, gateway, subnet); - server.begin(); -} -#endif // WIZ_ETHERNET - - -/////////////////////////////////////////////////////// -// ADAFRUIT XPORT ETHERNET CONFIGURATION -// -#ifdef AF_ETHERNET -#define NET_TX 2 -#define NET_RX 3 -#define SOFTWARE_SERIAL_RX 1 -#define RXPIN NET_RX -#undef HARDWARE_SERIAL_TX // sorry, no room for pin 0/1 hard uart -#define DEFAULT_OUTPIN NET_TX -#define BAUD_OVERRIDE 9600 -#endif // AF_ETHERNET - - - -/////////////////////////////////////////////////////// -// -// SANGUINO BUILD -// -/////////////////////////////////////////////////////// -// -// SANGUINO is auto-enabled to build for the Sanguino '644 -// if the '644 define is present -// -#if defined(__AVR_ATmega644P__) -#define SANGUINO - -//void beginSerial(unsigned long baud) { Serial.begin(baud); } -//char serialAvailable(void) { return Serial.available(); } -//char serialRead(void) { return Serial.read(); } -//void serialWrite(char c) { return Serial.print(c); } - -#ifndef beginSerial -#define beginSerial Serial.begin -#define serialAvailable Serial.available -#define serialRead Serial.read -#define serialWrite Serial.print -#endif - -// Sanguino has 24 digital and 8 analog io pins -#define NUMPINS (24+8) - -// Sanguino primary serial tx output is on pin 9 (rx on 8) -// Sanguino alternate hardware serial port tx output is on pin 11 (rx on 10) -#define SANGUINO_DEFAULT_SERIAL 9 -#define SANGUINO_ALTERNATE_SERIAL 11 -#define DEFAULT_OUTPIN SANGUINO_DEFAULT_SERIAL -#define ALTERNATE_OUTPIN SANGUINO_ALTERNATE_SERIAL - -#endif // defined (644) - - -/////////////////////////////////////////////////////// -// -// MEGA BUILD -// -// Note: These are speculative and untested. Feedback welcome. -// -/////////////////////////////////////////////////////// -// -// MEGA is auto-enabled to build for the Arduino Mega or Mega2560 -// if the '1280/'2560 define is present -// -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -#define MEGA 1 -#endif - -#if defined(MEGA) -#define beginSerial Serial.begin -#define serialAvailable Serial.available -#define serialRead Serial.read -#define serialWrite Serial.print - -// MEGA has 54 digital and 16 analog pins -#define NUMPINS (54+16) - -// Mega primary serial tx output is on pin 1 (rx on 0) -// Mega alternate hardware serial port tx output is on pin 18 (rx on 19) -// TODO: Support for hardware serial uart2 and uart3 -// -#define MEGA_DEFAULT_SERIAL 1 -#define MEGA_ALTERNATE_SERIAL 18 -#define DEFAULT_OUTPIN MEGA_DEFAULT_SERIAL -#define ALTERNATE_OUTPIN MEGA_ALTERNATE_SERIAL - -#endif // defined (1280) - -#if defined(__AVR_ATmega64__) - -#define beginSerial Serial1.begin -#define serialAvailable Serial1.available -#define serialRead Serial1.read -#define serialWrite Serial1.print - -#define NUMPINS (53) -#endif - - - -/////////////////////////////////////////////////////// -// -// TINY BUILD OPTIONS -// -#if defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny84__) -#define TINY_BUILD 1 -#undef MINIMUM_FREE_RAM -#define MINIMUM_FREE_RAM 20 -#define NUMPINS 6 -//#undef HARDWARE_SERIAL_TX -#undef SOFTWARE_SERIAL_TX -//#define SOFTWARE_SERIAL_TX 1 - -//#include "usbdrv.h" - -#endif // TINY_BUILD - - - -/////////////////////////////////////////////////////// -// -// AVROPENDOUS and TEENSY BUILD OPTIONS -// -#if defined(__AVR_AT90USB162__) - -//#define AVROPENDOUS_BUILD -#if defined(AVROPENDOUS_BUILD) -#define MINIMUM_FREE_RAM 20 -#define NUMPINS 24 -#undef HARDWARE_SERIAL_TX -#undef SOFTWARE_SERIAL_TX -void beginSerial(unsigned long baud) { ; } -#define serialAvailable usbAvailable -#define serialRead usbRead -#define serialWrite usbWrite -#include -#endif // defined AVRO - -#define TEENSY -#ifdef TEENSY -#endif // defined TEENSY - -#endif // defined '162 - - -/////////////////////////////////////////////////////// -// -// ATMega32U4 BUILD OPTIONS -// -#if defined(__AVR_ATmega32U4__) - -//#define AVROPENDOUS_BUILD -#if defined(AVROPENDOUS_BUILD) -#define MINIMUM_FREE_RAM 50 -#define NUMPINS 40 -#undef HARDWARE_SERIAL_TX -#undef SOFTWARE_SERIAL_TX -void beginSerial(unsigned long baud) { ; } -#define serialAvailable usbAvailable -#define serialRead usbRead -#define serialWrite usbWrite -#include -#endif // AVRO - -#define TEENSY2 -#if defined(TEENSY2) -#endif // TEENSY2 - -#endif // defined '32U4 - - -/////////////////////////////////////////////////////// -// -// SD CARD SUPPORT: Enable the SDFILE define for SD card script-in-file support -// -//#define SDFILE - - -/////////////////////////////////////////////////////// -// -// Unix build options -// (not working) -// -// > gcc bitlash.cpp -D UNIX_BUILD -// -#ifdef UNIX_BUILD -#define MINIMUM_FREE_RAM 200 -#define NUMPINS 32 -#undef HARDWARE_SERIAL_TX -#undef SOFTWARE_SERIAL_TX -#define beginSerial(x) - -#define E2END 2047 - -#define uint8_t unsigned char -#define uint32_t unsigned long int -#define prog_char char -#define prog_uchar unsigned char -#define strncpy_P strncpy -#define strcmp_P strcmp -#define strlen_P strlen - -#define PROGMEM -#define OUTPUT 1 - -#define pgm_read_byte(addr) (*(char*) (addr)) -#define pgm_read_word(addr) (*(int *) (addr)) - -unsigned long millis(void); - -#endif // defined unix_build - - -//////////////////// -// -// ARM BUILD -#if defined(ARM_BUILD) - #define prog_char char -#define prog_uchar byte -#define PROGMEM -#define pgm_read_byte(b) (*(char *)(b)) -#define pgm_read_word(b) (*(int *)(b)) -#define strncpy_P strncpy -#define strcmp_P strcmp -#define strlen_P strlen -#if ARM_BUILD==1 - #define E2END 4096 -#else - // Teensy 3 - #define E2END 2048 -#endif - -#endif - - -// numvar is 32 bits on Arduino and 16 bits elsewhere -#if (defined(ARDUINO_BUILD) || defined(UNIX_BUILD)) && !defined(TINY_BUILD) -typedef long int numvar; -typedef unsigned long int unumvar; -#else -typedef int numvar; -typedef unsigned int unumvar; -#endif // arduino_build - - -#ifdef AVROPENDOUS_BUILD -// USB integration -uint8_t usbAvailable(void); -int usbRead(void); -void usbWrite(uint8_t); -void usbMouseOn(void); -void usbMouseOff(void); -void connectBitlash(void); -#endif // avropendous - - -// Function prototypes - - -///////////////////////////////////////////// -// bitlash-api.c -// -void initBitlash(unsigned long baud); // start up and set baud rate -void runBitlash(void); // call this in loop(), frequently -numvar doCommand(char *); // execute a command from your sketch -void doCharacter(char); // pass an input character to the line editor - -//void flash(unsigned int, int); - - -///////////////////////////////////////////// -// bitlash-arduino.c -// -//#ifndef ARDUINO_BUILD -#if 0 -void digitalWrite(uint8_t, uint8_t); -int digitalRead(uint8_t); -int analogRead(uint8_t); -void pinMode(uint8_t, uint8_t); -unsigned long millis(void); -void delay(unsigned long); -void delayMicroseconds(unsigned int); -#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) -#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) -#define INPUT 0 -#define OUTPUT 1 -#endif - - -///////////////////////////////////////////// -// bitlash-cmdline.c -// -#ifdef TINY_BUILD -byte putlbuf(char); -void initlbuf(void); -#endif - -// String value buffer size -#ifdef AVR_BUILD - #define STRVALSIZE 120 -#else - #define STRVALSIZE 512 -#endif -#define STRVALLEN (STRVALSIZE-1) -#define LBUFLEN STRVALSIZE - -extern char *lbufptr; -extern char lbuf[LBUFLEN]; - - -///////////////////////////////////////////// -// bitlash-eeprom.c -// -int findKey(char *key); // return location of macro keyname in EEPROM or -1 -int getValue(char *key); // return location of macro value in EEPROM or -1 - -int findoccupied(int); -int findend(int); -void eeputs(int); - -#define EMPTY ((uint8_t)255) -#define STARTDB 0 -#define FAIL ((int)-1) - -///////////////////////////////////////////// -// External EEPROM (I2C) -// -//#define EEPROM_MICROCHIP_24XX32A // Uncomment to enable EEPROM via I2C - // Supports a Microchip 24xx32A EEPROM module attached to the I2C bus - // http://ww1.microchip.com/downloads/en/DeviceDoc/21713J.pdf - // Specifically, the DigiX has such a module onboard - // https://digistump.com/wiki/digix/tutorials/eeprom - -#define EEPROM_ADDRESS 0x50 // default EEPROM address for DigiX boards - -//////////////////////// -// -// EEPROM database begin/end offset -// -// Use the predefined constant from the avr-gcc support file -// -#if defined(EEPROM_MICROCHIP_24XX32A) - #define ENDDB 4095 - #define ENDEEPROM 4095 -#else - #define ENDDB E2END - #define ENDEEPROM E2END -#endif - -///////////////////////////////////////////// -// bitlash-error.c -// -extern jmp_buf env; -#define X_EXIT 1 -void fatal2(char, char); -void overflow(byte); -void underflow(byte); -void expected(byte); -void expectedchar(byte); -void unexpected(byte); -void missing(byte); -//void oops(int); // fatal exit - - -///////////////////////////////////////////// -// bitlash-functions.c -// -typedef numvar (*bitlash_function)(void); -void show_user_functions(void); - -void dofunctioncall(byte); -numvar func_free(void); -void make_beep(unumvar, unumvar, unumvar); - -extern const prog_char functiondict[] PROGMEM; -extern const prog_char aliasdict[] PROGMEM; - -void stir(byte); - -///////////////////////////////////////////// -// bitlash-program.c -// -extern char startup[]; - - -///////////////////////////////////////////// -// bitlash-serial.c -// -void printIntegerInBase(unumvar, uint8_t, numvar, byte); -void printInteger(numvar,numvar, byte); -void printHex(unumvar); -void printBinary(unumvar); -void spb(char c); -void sp(const char *); -void speol(void); - -numvar func_printf(void); -numvar func_printf_handler(byte,byte); - -#ifdef SOFTWARE_SERIAL_TX -numvar setBaud(numvar, unumvar); -void resetOutput(void); -#endif - -// serial override handling -#define SERIAL_OVERRIDE -#ifdef SERIAL_OVERRIDE -typedef void (*serialOutputFunc)(byte); -byte serialIsOverridden(void); -void setOutputHandler(serialOutputFunc); -void resetOutputHandler(void); -extern serialOutputFunc serial_override_handler; -#endif - -#ifdef ARDUINO_BUILD -void chkbreak(void); -void cmd_print(void); -#endif -numvar func_printf_handler(byte, byte); - - -///////////////////////////////////////////// -// bitlash-taskmgr.c -// -void initTaskList(void); -void runBackgroundTasks(void); -void stopTask(byte); -void startTask(int, numvar); -void snooze(unumvar); -void showTaskList(void); -extern byte background; -extern byte curtask; -extern byte suspendBackground; - - -///////////////////////////////////////////// -// eeprom.c -// they must live off piste due to aggressive compiler inlining. -// -#if defined(AVR_BUILD) -void eewrite(int, byte) __attribute__((noinline)); -byte eeread(int) __attribute__((noinline)); - -#elif defined(ARM_BUILD) -void eewrite(int, byte); -byte eeread(int); -extern char virtual_eeprom[]; -void eeinit(void); -#endif - - -///////////////////////////////////////////// -// bitlash-interpreter.c -// -numvar getstatementlist(void); -void domacrocall(int); - - -///////////////////////////////////////////// -// bitlash-parser.c -// -void vinit(void); // init the value stack -void vpush(numvar); // push a numvar on the stack -numvar vpop(void); // pop a numvar -extern byte vsptr; -#define vsempty() vsptr==0 -extern numvar *arg; // argument frame pointer -numvar getVar(uint8_t id); // return value of bitlash variable. id is [0..25] for [a..z] -void assignVar(uint8_t id, numvar value); // assign value to variable. id is [0..25] for [a..z] -numvar incVar(uint8_t id); // increment variable. id is [0..25] for [a..z] - -// parse context types -#define SCRIPT_NONE 0 -#define SCRIPT_RAM 1 -#define SCRIPT_PROGMEM 2 -#define SCRIPT_EEPROM 3 -#define SCRIPT_FILE 4 - -byte findscript(char *); -byte scriptfileexists(char *); -numvar execscript(byte, numvar, char *); -void callscriptfunction(byte, numvar); - -typedef struct { - numvar fetchptr; - byte fetchtype; -} parsepoint; - -void markparsepoint(parsepoint *); -void returntoparsepoint(parsepoint *, byte); -void primec(void); -void fetchc(void); -void getsym(void); -void traceback(void); - -numvar func_fprintf(void); - -const prog_char *getmsg(byte); -void parsestring(void (*)(char)); -void msgp(byte); -void msgpl(byte); -numvar getnum(void); -void calleeprommacro(int); -void getexpression(void); -byte hexval(char); -byte is_end(void); -numvar getarg(numvar); -numvar isstring(void); -numvar getstringarg(numvar); -void releaseargblock(void); -void parsearglist(void); -extern const prog_char reservedwords[]; - - - -// Interpreter globals -extern byte fetchtype; // current script type -extern numvar fetchptr; // pointer to current char in input buffer -extern numvar symval; // value of current numeric expression - -#define USE_GPIORS defined(AVR_BUILD) - -#ifndef GPIOR0 || GPIOR1 - #undef USE_GPIORS -#endif -#if (defined USE_GPIORS) -#define sym GPIOR0 -#define inchar GPIOR1 -#else -extern byte sym; // current input symbol -extern byte inchar; // Current parser character -#endif - -#ifdef PARSER_TRACE -extern byte trace; -void tb(void); -#endif - - -// Expression result -extern byte exptype; // type of expression: s_nval [or s_sval] -extern numvar expval; // value of numeric expr or length of string - -// Temporary buffer for ids -#define IDLEN 12 -extern char idbuf[IDLEN+1]; - - -// Strings live in PROGMEM to save ram -// -#define M_expected 0 -#define M_unexpected 1 -#define M_missing 2 -#define M_string 3 -#define M_underflow 4 -#define M_overflow 5 -#define M_ctrlc 6 -#define M_ctrlb 7 -#define M_ctrlu 8 -#define M_exp 9 -#define M_op 10 -#define M_pfmts 11 -#define M_eof 12 -#define M_var 13 -#define M_number 14 -#define M_rparen 15 -#define M_saved 16 -#define M_eeprom 17 -#define M_defmacro 18 -#define M_prompt 19 -#define M_char 20 -#define M_stack 21 -#define M_startup 22 -#define M_id 23 -#define M_promptid 24 -#define M_functions 25 -#define M_oops 26 -#define M_arg 27 -#define M_function 28 - - -// Names for symbols -// -// Each symbol in the grammar is parsed to a unique symval enumerated here -// -// One character symbols take their ascii value as their symval -// Complex symbols have the high bit set so start at 128 (0x80) -// -#define s_eof 0 -#define s_undef (0 | 0x80) -#define s_nval (1 | 0x80) -#define s_sval (2 | 0x80) -#define s_nvar (3 | 0x80) -#define s_le (4 | 0x80) -#define s_ge (5 | 0x80) -#define s_logicaland (6 | 0x80) -#define s_logicalor (7 | 0x80) -#define s_logicaleq (8 | 0x80) -#define s_logicalne (9 | 0x80) -#define s_shiftleft (10 | 0x80) -#define s_shiftright (11 | 0x80) -#define s_incr (12 | 0x80) -#define s_decr (13 | 0x80) -#define s_nfunct (14 | 0x80) -#define s_if (15 | 0x80) -#define s_while (16 | 0x80) -#define s_apin (17 | 0x80) -#define s_dpin (18 | 0x80) -#define s_define (19 | 0x80) -#define s_function (20 | 0x80) -#define s_rm (21 | 0x80) -#define s_run (22 | 0x80) -#define s_ps (23 | 0x80) -#define s_stop (24 | 0x80) -#define s_boot (25 | 0x80) -#define s_peep (26 | 0x80) -#define s_help (27 | 0x80) -#define s_ls (28 | 0x80) -#define s_print (29 | 0x80) -#define s_switch (30 | 0x80) -#define s_return (31 | 0x80) -#define s_returning (32 | 0x80) -#define s_arg (33 | 0x80) -#define s_else (34 | 0x80) -#define s_script_eeprom (35 | 0x80) -#define s_script_progmem (36 | 0x80) -#define s_script_file (37 | 0x80) -#define s_comment (38 | 0x80) - - -// Names for literal symbols: these one-character symbols -// are represented by their 7-bit ascii char code -#define s_semi ';' -#define s_add '+' -#define s_sub '-' -#define s_mul '*' -#define s_div '/' -#define s_mod '%' -#define s_lparen '(' -#define s_rparen ')' -#define s_dot '.' -#define s_lt '<' -#define s_gt '>' -#define s_equals '=' -#define s_bitand '&' -#define s_bitor '|' -#define s_comma ',' -#define s_bitnot '~' -#define s_logicalnot '!' -#define s_xor '^' -#define s_colon ':' -#define s_pound '#' -#define s_quote '"' -#define s_dollars '$' -#define s_lcurly '{' -#define s_rcurly '}' - - -#endif // defined _BITLASH_H - diff --git a/src/conio.h b/src/conio.h deleted file mode 100644 index 6b2e2ea..0000000 --- a/src/conio.h +++ /dev/null @@ -1,30 +0,0 @@ -// from http://www.daniweb.com/software-development/c/threads/410155/gcc-equivalent-for-getch -#include -#include -#include -/* reads from keypress, doesn't echo */ -int getch(void) -{ - struct termios oldattr, newattr; - int ch; - tcgetattr( STDIN_FILENO, &oldattr ); - newattr = oldattr; - newattr.c_lflag &= ~( ICANON | ECHO ); - tcsetattr( STDIN_FILENO, TCSANOW, &newattr ); - ch = getchar(); - tcsetattr( STDIN_FILENO, TCSANOW, &oldattr ); - return ch; -} -/* reads from keypress, echoes */ -int getche(void) -{ - struct termios oldattr, newattr; - int ch; - tcgetattr( STDIN_FILENO, &oldattr ); - newattr = oldattr; - newattr.c_lflag &= ~( ICANON ); - tcsetattr( STDIN_FILENO, TCSANOW, &newattr ); - ch = getchar(); - tcsetattr( STDIN_FILENO, TCSANOW, &oldattr ); - return ch; -} \ No newline at end of file diff --git a/src/eeprom.c b/src/eeprom.cpp similarity index 99% rename from src/eeprom.c rename to src/eeprom.cpp index 4b43fa4..77071f0 100644 --- a/src/eeprom.c +++ b/src/eeprom.cpp @@ -27,7 +27,7 @@ OTHER DEALINGS IN THE SOFTWARE. ***/ -#include "bitlash.h" +#include "bitlash-private.h" #if defined(EEPROM_MICROCHIP_24XX32A) diff --git a/src/mygetch.c b/src/mygetch.c deleted file mode 100644 index 7e7b25e..0000000 --- a/src/mygetch.c +++ /dev/null @@ -1,59 +0,0 @@ -// fromm http://pastebin.com/r6BRYDxV -#include -#include -#include -#include "ctype.h" -#include "setjmp.h" -#include -#include -#include - -int mygetch() { - char ch; - int error; - static struct termios Otty, Ntty; - - fflush(stdout); - tcgetattr(0, &Otty); - Ntty = Otty; - - Ntty.c_iflag = 0; /* input mode */ - Ntty.c_oflag = 0; /* output mode */ - Ntty.c_lflag &= ~ICANON; /* line settings */ - -#if 1 - /* disable echoing the char as it is typed */ - Ntty.c_lflag &= ~ECHO; /* disable echo */ -#else - /* enable echoing the char as it is typed */ - Ntty.c_lflag |= ECHO; /* enable echo */ -#endif - -// Ntty.c_cc[VMIN] = CMIN; /* minimum chars to wait for */ -// Ntty.c_cc[VTIME] = CTIME; /* minimum wait time */ - Ntty.c_cc[VMIN] = 0; /* minimum chars to wait for */ - Ntty.c_cc[VTIME] = 0; /* minimum wait time */ - -//printf("MYGETCH: %d %d", CMIN, CTIME); // 1 0 -//fflush(stdout); - -#if 0 - /* - * use this to flush the input buffer before blocking for new input - */ - #define FLAG TCSAFLUSH -#else - /* - * use this to return a char from the current input buffer, or block if - * no input is waiting. - */ - #define FLAG TCSANOW -#endif - - if ((error = tcsetattr(0, FLAG, &Ntty)) == 0) { - error = read(0, &ch, 1); /* get char from stdin */ - error += tcsetattr(0, FLAG, &Otty); /* restore old settings */ - } - - return (error == 1 ? (int) ch : -1 ); -}