From f9575e0186256f6db1671af755b58bb2a7b541c7 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 14 Aug 2018 21:46:23 -0700 Subject: [PATCH] Check in Hardware::Virtual's x86 core in its new home --- x86/boards.txt | 7 + x86/cores/virtual/Arduino.c | 27 ++ x86/cores/virtual/Arduino.h | 355 ++++++++++++++ x86/cores/virtual/HardwareSerial.cpp | 61 +++ x86/cores/virtual/HardwareSerial.h | 54 +++ x86/cores/virtual/Print.cpp | 238 ++++++++++ x86/cores/virtual/Print.h | 102 ++++ x86/cores/virtual/Printable.h | 39 ++ x86/cores/virtual/Stream.cpp | 8 + x86/cores/virtual/Stream.h | 150 ++++++ x86/cores/virtual/WCharacter.h | 152 ++++++ x86/cores/virtual/WMath.cpp | 58 +++ x86/cores/virtual/WString.cpp | 675 +++++++++++++++++++++++++++ x86/cores/virtual/WString.h | 284 +++++++++++ x86/cores/virtual/binary.h | 534 +++++++++++++++++++++ x86/cores/virtual/main.cpp | 54 +++ x86/cores/virtual/stdlib_ext.c | 72 +++ x86/cores/virtual/stdlib_ext.h | 18 + x86/cores/virtual/virtual_io.cpp | 159 +++++++ x86/cores/virtual/virtual_io.h | 16 + x86/libraries | 1 + x86/platform.txt | 118 +++++ x86/variants/virtual/.keep | 3 + 23 files changed, 3185 insertions(+) create mode 100644 x86/boards.txt create mode 100644 x86/cores/virtual/Arduino.c create mode 100644 x86/cores/virtual/Arduino.h create mode 100644 x86/cores/virtual/HardwareSerial.cpp create mode 100644 x86/cores/virtual/HardwareSerial.h create mode 100644 x86/cores/virtual/Print.cpp create mode 100644 x86/cores/virtual/Print.h create mode 100644 x86/cores/virtual/Printable.h create mode 100644 x86/cores/virtual/Stream.cpp create mode 100644 x86/cores/virtual/Stream.h create mode 100644 x86/cores/virtual/WCharacter.h create mode 100644 x86/cores/virtual/WMath.cpp create mode 100644 x86/cores/virtual/WString.cpp create mode 100644 x86/cores/virtual/WString.h create mode 100644 x86/cores/virtual/binary.h create mode 100644 x86/cores/virtual/main.cpp create mode 100644 x86/cores/virtual/stdlib_ext.c create mode 100644 x86/cores/virtual/stdlib_ext.h create mode 100644 x86/cores/virtual/virtual_io.cpp create mode 100644 x86/cores/virtual/virtual_io.h create mode 120000 x86/libraries create mode 100644 x86/platform.txt create mode 100644 x86/variants/virtual/.keep diff --git a/x86/boards.txt b/x86/boards.txt new file mode 100644 index 0000000..363b41f --- /dev/null +++ b/x86/boards.txt @@ -0,0 +1,7 @@ +virtual.name="Kaleidoscope Virtual Keyboard" +virtual.build.usb_product="Kaleidoscope Virtual Keyboard" +virtual.build.usb_manufacturer="Kaleidoscope" +virtual.build.board=VIRTUAL +virtual.build.core=virtual +virtual.build.variant=virtual +virtual.build.extra_flags=-DKALEIDOSCOPE_HARDWARE_H="Kaleidoscope-Hardware-Virtual.h" diff --git a/x86/cores/virtual/Arduino.c b/x86/cores/virtual/Arduino.c new file mode 100644 index 0000000..f4d55d5 --- /dev/null +++ b/x86/cores/virtual/Arduino.c @@ -0,0 +1,27 @@ +#include "Arduino.h" + +// TODO: better time emulation +// this is pretty hacky, but hopefully helps most code behave sanely +// note: 'weak' attribute allows users to override with their own implementation of millis() +__attribute__((weak)) +unsigned long millis(void) { + static unsigned long time = 0; + return time++; +} +unsigned long micros(void) { + return millis()*1000; +} + + +// yes, these are pretty stupid with the current millis() and micros() +// but hopefully they stays fine if/when we get a better millis() and micros() + +void delay(unsigned long ms) { + unsigned long end = millis() + ms; + while(millis() < end); +} + +void delayMicroseconds(unsigned int us) { + unsigned long end = micros() + us; + while(micros() < end); +} diff --git a/x86/cores/virtual/Arduino.h b/x86/cores/virtual/Arduino.h new file mode 100644 index 0000000..41f688b --- /dev/null +++ b/x86/cores/virtual/Arduino.h @@ -0,0 +1,355 @@ +/* + Arduino.h - Main include file for the Arduino SDK + Copyright (c) 2005-2013 Arduino Team. All right reserved. + + Modified into main include file for the Kaleidoscope Virtual Keyboard + Copyright (c) 2017 Craig Disselkoen. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Arduino_h +#define Arduino_h + +#include +#include +#include +#include +#include + +#include "binary.h" +#include "stdlib_ext.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void yield(void); + +#define HIGH 0x1 +#define LOW 0x0 + +#define INPUT 0x0 +#define OUTPUT 0x1 +#define INPUT_PULLUP 0x2 + +#define PI 3.1415926535897932384626433832795 +#define HALF_PI 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 +#define DEG_TO_RAD 0.017453292519943295769236907684886 +#define RAD_TO_DEG 57.295779513082320876798154814105 +#define EULER 2.718281828459045235360287471352 + +#define SERIAL 0x0 +#define DISPLAY 0x1 + +#define LSBFIRST 0 +#define MSBFIRST 1 + +#define CHANGE 1 +#define FALLING 2 +#define RISING 3 + +#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) +#define DEFAULT 0 +#define EXTERNAL 1 +#define INTERNAL1V1 2 +#define INTERNAL INTERNAL1V1 +#elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) +#define DEFAULT 0 +#define EXTERNAL 4 +#define INTERNAL1V1 8 +#define INTERNAL INTERNAL1V1 +#define INTERNAL2V56 9 +#define INTERNAL2V56_EXTCAP 13 +#else +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) +#define INTERNAL1V1 2 +#define INTERNAL2V56 3 +#else +#define INTERNAL 3 +#endif +#define DEFAULT 1 +#define EXTERNAL 0 +#endif + +// undefine stdlib's abs if encountered +#ifdef abs +#undef abs +#endif + +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)>(b)?(a):(b)) +#define abs(x) ((x)>0?(x):-(x)) +#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) +#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) +#define radians(deg) ((deg)*DEG_TO_RAD) +#define degrees(rad) ((rad)*RAD_TO_DEG) +#define sq(x) ((x)*(x)) + +#define interrupts() sei() +#define noInterrupts() cli() + +#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) +#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) +#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) + +#define lowByte(w) ((uint8_t) ((w) & 0xff)) +#define highByte(w) ((uint8_t) ((w) >> 8)) + +#define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#define bitSet(value, bit) ((value) |= (1UL << (bit))) +#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) + +// avr-libc defines _NOP() since 1.6.2 +#ifndef _NOP +#define _NOP() do { __asm__ volatile ("nop"); } while (0) +#endif + +typedef unsigned int word; + +#define bit(b) (1UL << (b)) + +typedef bool boolean; +typedef uint8_t byte; + +void init(void); +void initVariant(void); + +void pinMode(uint8_t, uint8_t); +void digitalWrite(uint8_t, uint8_t); +int digitalRead(uint8_t); +int analogRead(uint8_t); +void analogReference(uint8_t mode); +void analogWrite(uint8_t, int); + +unsigned long millis(void); +unsigned long micros(void); +void delay(unsigned long); +void delayMicroseconds(unsigned int us); +unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout); +unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout); + +void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); +uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder); + +void attachInterrupt(uint8_t, void (*)(void), int mode); +void detachInterrupt(uint8_t); + +void setup(void); +void loop(void); + +// Get the bit location within the hardware port of the given virtual pin. +// This comes from the pins_*.c file for the active board configuration. + +#define analogInPinToBit(P) (P) + +// Ignore "PROGMEM" on virtual hardware +#define PROGMEM + +// On the ATmega1280, the addresses of some of the port registers are +// greater than 255, so we can't store them in uint8_t's. +extern const uint16_t PROGMEM port_to_mode_PGM[]; +extern const uint16_t PROGMEM port_to_input_PGM[]; +extern const uint16_t PROGMEM port_to_output_PGM[]; + +extern const uint8_t PROGMEM digital_pin_to_port_PGM[]; +// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[]; +extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[]; +extern const uint8_t PROGMEM digital_pin_to_timer_PGM[]; + +// Get the bit location within the hardware port of the given virtual pin. +// This comes from the pins_*.c file for the active board configuration. +// +// These perform slightly better as macros compared to inline functions +// +#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) ) +#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) ) +#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) ) +#define analogInPinToBit(P) (P) +#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) ) +#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) ) +#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) ) + +#define NOT_A_PIN 0 +#define NOT_A_PORT 0 + +#define NOT_AN_INTERRUPT -1 + +#ifdef ARDUINO_MAIN +#define PA 1 +#define PB 2 +#define PC 3 +#define PD 4 +#define PE 5 +#define PF 6 +#define PG 7 +#define PH 8 +#define PJ 10 +#define PK 11 +#define PL 12 +#endif + +#define NOT_ON_TIMER 0 +#define TIMER0A 1 +#define TIMER0B 2 +#define TIMER1A 3 +#define TIMER1B 4 +#define TIMER1C 5 +#define TIMER2 6 +#define TIMER2A 7 +#define TIMER2B 8 + +#define TIMER3A 9 +#define TIMER3B 10 +#define TIMER3C 11 +#define TIMER4A 12 +#define TIMER4B 13 +#define TIMER4C 14 +#define TIMER4D 15 +#define TIMER5A 16 +#define TIMER5B 17 +#define TIMER5C 18 + +#ifdef __cplusplus +} // extern "C" +#endif + +#ifdef __cplusplus +#include "WCharacter.h" +#include "WString.h" +#include "HardwareSerial.h" + +uint16_t makeWord(uint16_t w); +uint16_t makeWord(byte h, byte l); + +#define word(...) makeWord(__VA_ARGS__) + +unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); +unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); + +void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0); +void noTone(uint8_t _pin); + +// WMath prototypes +long random(long); +long random(long, long); +void randomSeed(unsigned long); +long map(long, long, long, long, long); + +#endif // __cplusplus + +// We don't use avr/pgmspace.h, so the remainder of this file is a heavily abbreviated version +// of avr/pgmspace.h with the same or alternate definitions +// TODO: avr/pgmspace.h always includes avr/io.h, so do the same for avr/io.h +#include +#include +#ifndef __ATTR_CONST__ +#define __ATTR_CONST__ __attribute__((__const__)) +#endif +#ifndef __ATTR_PROGMEM__ +#define __ATTR_PROGMEM__ __attribute__((__progmem__)) +#endif +#ifndef __ATTR_PURE__ +#define __ATTR_PURE__ __attribute__((__pure__)) +#endif +// We just discard the PROGMEM qualifier +#define PROGMEM + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef PGM_P +#define PGM_P const char* +#endif +#ifndef PGM_VOID_P +#define PGM_VOID_P const void* +#endif + +// We don't do anything special with PSTR +#define PSTR(s) ((const char*)(s)) + +// Not sure if these are acceptable substitute definitions in our context or not +#define pgm_read_byte_near(addr) (*(const byte*)(addr)) +#define pgm_read_word_near(addr) (*(const word*)(addr)) +#define pgm_read_dword_near(addr) (*(const dword*)(addr)) +#define pgm_read_float_near(addr) (*(const float*)(addr)) +#define pgm_read_ptr_near(addr) (*(const void**)(addr)) +#define pgm_read_byte_far(addr) pgm_read_byte_near(addr) +#define pgm_read_word_far(addr) pgm_read_word_near(addr) +#define pgm_read_dword_far(addr) pgm_read_dword_near(addr) +#define pgm_read_float_far(addr) pgm_read_float_near(addr) +#define pgm_read_ptr_far(addr) pgm_read_ptr_near(addr) +#define pgm_read_byte(addr) pgm_read_byte_near(addr) +#define pgm_read_word(addr) pgm_read_word_near(addr) +#define pgm_read_dword(addr) pgm_read_dword_near(addr) +#define pgm_read_float(addr) pgm_read_float_near(addr) +#define pgm_read_ptr(addr) pgm_read_ptr_near(addr) +#define pgm_get_far_address(var) (&(var)) + +// _P or _PF string functions just call their standard library equivalents +#include +#define memchr_P memchr +#define memcmp_P memcmp +#define memccpy_P memccpy +#define memcpy_P memcpy +#define memmem_P memmem +#define memrchr_P memrchr +#define strcat_P strcat +#define strchr_P strchr +#define strchrnul_P strchrnul +#define strcmp_P strcmp +#define strcpy_P strcpy +#define strcasecmp_P strcasecmp +#define strcasestr_P strcasestr +#define strcspn_P strcspn +#define strlcat_P strlcat +#define strlcpy_P strlcpy +#define strnlen_P strnlen +#define strncmp_P strncmp +#define strncasecmp_P strncasecmp +#define strncat_P strncat +#define strncpy_P strncpy +#define strpbrk_P strpbrk +#define strrchr_P strrchr +#define strsep_P strsep +#define strspn_P strspn +#define strstr_P strstr +#define strtok_P strtok +#define strtok_rP strtok_r +#define strlen_PF strlen +#define strnlen_PF strnlen +#define memcpy_PF memcpy +#define strcpy_PF strcpy +#define strncpy_PF strncpy +#define strcat_PF strcat +#define strlcat_PF strlcat +#define strncat_PF strncat +#define strcmp_PF strcmp +#define strncmp_PF strncmp +#define strcasecmp_PF strcasecmp +#define strncasecmp_PF strncasecmp +#define strstr_PF strstr +#define strlcpy_PF strlcpy +#define memcmp_PF memcmp +#define strlen_P strlen + +#ifdef __cplusplus +} +#endif + +#endif // Arduino_h diff --git a/x86/cores/virtual/HardwareSerial.cpp b/x86/cores/virtual/HardwareSerial.cpp new file mode 100644 index 0000000..049c9b6 --- /dev/null +++ b/x86/cores/virtual/HardwareSerial.cpp @@ -0,0 +1,61 @@ +#include "HardwareSerial.h" +#include "Arduino.h" + +// see comments in the real HardwareSerial.cpp +void serialEvent() __attribute__((weak)); +void serialEvent1() __attribute__((weak)); +void serialEvent2() __attribute__((weak)); +void serialEvent3() __attribute__((weak)); +bool Serial0_available() __attribute__((weak)); +bool Serial1_available() __attribute__((weak)); +bool Serial2_available() __attribute__((weak)); +bool Serial3_available() __attribute__((weak)); + +void serialEventRun(void) { + if (Serial0_available && serialEvent && Serial0_available()) serialEvent(); + if (Serial1_available && serialEvent && Serial1_available()) serialEvent1(); + if (Serial2_available && serialEvent && Serial2_available()) serialEvent2(); + if (Serial3_available && serialEvent && Serial3_available()) serialEvent3(); +} + +unsigned HardwareSerial::serialNumber = 0; + +HardwareSerial::HardwareSerial() {} + +void HardwareSerial::begin(unsigned long baud, byte config) { + char filename[64]; + snprintf(filename, 64, "results/serial_%u.txt", serialNumber++); + out = fopen(filename, "w"); +} + +void HardwareSerial::end() { + if (out) fclose(out); +} + +int HardwareSerial::availableForWrite(void) { + return out ? 1000 : 0; +} +size_t HardwareSerial::write(uint8_t c) { + if (out) fputc(c, out); + return 1; +} +void HardwareSerial::flush(void) { + if (out) fflush(out); +} + +// TODO make input serial connections better. +// For now they're just essentially not allowed +int HardwareSerial::peek(void) { + return -1; +} +int HardwareSerial::read(void) { + return -1; +} +int HardwareSerial::available(void) { + return 0; +} + +HardwareSerial Serial; +HardwareSerial Serial1; +HardwareSerial Serial2; +HardwareSerial Serial3; diff --git a/x86/cores/virtual/HardwareSerial.h b/x86/cores/virtual/HardwareSerial.h new file mode 100644 index 0000000..f4ec02f --- /dev/null +++ b/x86/cores/virtual/HardwareSerial.h @@ -0,0 +1,54 @@ +#pragma once + +#include "Stream.h" +#include + +class HardwareSerial : public Stream { + public: + HardwareSerial(); + void begin(unsigned long baud) { + begin(baud, 0x06); + } + void begin(unsigned long, uint8_t); + void end(); + virtual int available(); + virtual int peek(); + virtual int read(); + virtual int availableForWrite(); + virtual void flush(); + virtual size_t write(uint8_t); + // we keep these four write()s the same as the default Arduino core + inline size_t write(unsigned long n) { + return write((uint8_t)n); + } + inline size_t write(long n) { + return write((uint8_t)n); + } + inline size_t write(unsigned int n) { + return write((uint8_t)n); + } + inline size_t write(int n) { + return write((uint8_t)n); + } + using Print::write; // write(str) and write(buf, size) + operator bool() { + return true; + } + private: + static unsigned serialNumber; + FILE* out; +}; +// The default Arduino core only provides each of these HardwareSerial objects if +// various things are #defined. We always provide them for virtual hardware. +extern HardwareSerial Serial; +#define HAVE_HWSERIAL0 +extern HardwareSerial Serial1; +#define HAVE_HWSERIAL1 +extern HardwareSerial Serial2; +#define HAVE_HWSERIAL2 +extern HardwareSerial Serial3; +#define HAVE_HWSERIAL3 +// end HardwareSerial + +extern void serialEventRun(void) __attribute__((weak)); + diff --git a/x86/cores/virtual/Print.cpp b/x86/cores/virtual/Print.cpp new file mode 100644 index 0000000..6a0136c --- /dev/null +++ b/x86/cores/virtual/Print.cpp @@ -0,0 +1,238 @@ +/* + Print.cpp - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 23 November 2006 by David A. Mellis + Modified 03 August 2015 by Chuck Todd + */ + +#include +#include +#include +#include +#include "Arduino.h" + +#include "Print.h" + +// Public Methods ////////////////////////////////////////////////////////////// + +/* default implementation: may be overridden */ +size_t Print::write(const uint8_t *buffer, size_t size) { + size_t n = 0; + while (size--) { + if (write(*buffer++)) n++; + else break; + } + return n; +} + +size_t Print::print(const __FlashStringHelper *ifsh) { + PGM_P p = reinterpret_cast(ifsh); + size_t n = 0; + while (1) { + unsigned char c = pgm_read_byte(p++); + if (c == 0) break; + if (write(c)) n++; + else break; + } + return n; +} + +size_t Print::print(const String &s) { + return write(s.c_str(), s.length()); +} + +size_t Print::print(const char str[]) { + return write(str); +} + +size_t Print::print(char c) { + return write(c); +} + +size_t Print::print(unsigned char b, int base) { + return print((unsigned long) b, base); +} + +size_t Print::print(int n, int base) { + return print((long) n, base); +} + +size_t Print::print(unsigned int n, int base) { + return print((unsigned long) n, base); +} + +size_t Print::print(long n, int base) { + if (base == 0) { + return write(n); + } else if (base == 10) { + if (n < 0) { + int t = print('-'); + n = -n; + return printNumber(n, 10) + t; + } + return printNumber(n, 10); + } else { + return printNumber(n, base); + } +} + +size_t Print::print(unsigned long n, int base) { + if (base == 0) return write(n); + else return printNumber(n, base); +} + +size_t Print::print(double n, int digits) { + return printFloat(n, digits); +} + +size_t Print::println(const __FlashStringHelper *ifsh) { + size_t n = print(ifsh); + n += println(); + return n; +} + +size_t Print::print(const Printable& x) { + return x.printTo(*this); +} + +size_t Print::println(void) { + return write("\r\n"); +} + +size_t Print::println(const String &s) { + size_t n = print(s); + n += println(); + return n; +} + +size_t Print::println(const char c[]) { + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(char c) { + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(unsigned char b, int base) { + size_t n = print(b, base); + n += println(); + return n; +} + +size_t Print::println(int num, int base) { + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned int num, int base) { + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(long num, int base) { + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned long num, int base) { + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(double num, int digits) { + size_t n = print(num, digits); + n += println(); + return n; +} + +size_t Print::println(const Printable& x) { + size_t n = print(x); + n += println(); + return n; +} + +// Private Methods ///////////////////////////////////////////////////////////// + +size_t Print::printNumber(unsigned long n, uint8_t base) { + char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. + char *str = &buf[sizeof(buf) - 1]; + + *str = '\0'; + + // prevent crash if called with base == 1 + if (base < 2) base = 10; + + do { + char c = n % base; + n /= base; + + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } while (n); + + return write(str); +} + +size_t Print::printFloat(double number, uint8_t digits) { + size_t n = 0; + + if (isnan(number)) return print("nan"); + if (isinf(number)) return print("inf"); + if (number > 4294967040.0) return print("ovf"); // constant determined empirically + if (number < -4294967040.0) return print("ovf"); // constant determined empirically + + // Handle negative numbers + if (number < 0.0) { + n += print('-'); + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for (uint8_t i = 0; i < digits; ++i) + rounding /= 10.0; + + number += rounding; + + // Extract the integer part of the number and print it + unsigned long int_part = (unsigned long)number; + double remainder = number - (double)int_part; + n += print(int_part); + + // Print the decimal point, but only if there are digits beyond + if (digits > 0) { + n += print('.'); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) { + remainder *= 10.0; + unsigned int toPrint = (unsigned int)(remainder); + n += print(toPrint); + remainder -= toPrint; + } + + return n; +} diff --git a/x86/cores/virtual/Print.h b/x86/cores/virtual/Print.h new file mode 100644 index 0000000..0b92172 --- /dev/null +++ b/x86/cores/virtual/Print.h @@ -0,0 +1,102 @@ +/* + Print.h - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Print_h +#define Print_h + +#include +#include // for size_t + +#include "WString.h" +#include "Printable.h" + +#define DEC 10 +#define HEX 16 +#define OCT 8 +#ifdef BIN // Prevent warnings if BIN is previously defined in "iotnx4.h" or similar +#undef BIN +#endif +#define BIN 2 + +class Print { + private: + int write_error; + size_t printNumber(unsigned long, uint8_t); + size_t printFloat(double, uint8_t); + protected: + void setWriteError(int err = 1) { + write_error = err; + } + public: + Print() : write_error(0) {} + + int getWriteError() { + return write_error; + } + void clearWriteError() { + setWriteError(0); + } + + virtual size_t write(uint8_t) = 0; + size_t write(const char *str) { + if (str == NULL) return 0; + return write((const uint8_t *)str, strlen(str)); + } + virtual size_t write(const uint8_t *buffer, size_t size); + size_t write(const char *buffer, size_t size) { + return write((const uint8_t *)buffer, size); + } + + // default to zero, meaning "a single write may block" + // should be overriden by subclasses with buffering + virtual int availableForWrite() { + return 0; + } + + size_t print(const __FlashStringHelper *); + size_t print(const String &); + size_t print(const char[]); + size_t print(char); + size_t print(unsigned char, int = DEC); + size_t print(int, int = DEC); + size_t print(unsigned int, int = DEC); + size_t print(long, int = DEC); + size_t print(unsigned long, int = DEC); + size_t print(double, int = 2); + size_t print(const Printable&); + + size_t println(const __FlashStringHelper *); + size_t println(const String &s); + size_t println(const char[]); + size_t println(char); + size_t println(unsigned char, int = DEC); + size_t println(int, int = DEC); + size_t println(unsigned int, int = DEC); + size_t println(long, int = DEC); + size_t println(unsigned long, int = DEC); + size_t println(double, int = 2); + size_t println(const Printable&); + size_t println(void); + + virtual void flush() { + /* Empty implementation for backward compatibility */ + } +}; + +#endif diff --git a/x86/cores/virtual/Printable.h b/x86/cores/virtual/Printable.h new file mode 100644 index 0000000..d0ea74f --- /dev/null +++ b/x86/cores/virtual/Printable.h @@ -0,0 +1,39 @@ +/* + Printable.h - Interface class that allows printing of complex types + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Printable_h +#define Printable_h + +#include + +class Print; + +/** The Printable class provides a way for new classes to allow themselves to be printed. + By deriving from Printable and implementing the printTo method, it will then be possible + for users to print out instances of this class by passing them into the usual + Print::print and Print::println methods. +*/ + +class Printable { + public: + virtual size_t printTo(Print& p) const = 0; +}; + +#endif + diff --git a/x86/cores/virtual/Stream.cpp b/x86/cores/virtual/Stream.cpp new file mode 100644 index 0000000..662d8cf --- /dev/null +++ b/x86/cores/virtual/Stream.cpp @@ -0,0 +1,8 @@ +// The following are dummy implementations that saturate linkage + +#include "Stream.h" + +long +Stream::parseInt(LookaheadMode lookahead, char ignore) { + return 0; +} diff --git a/x86/cores/virtual/Stream.h b/x86/cores/virtual/Stream.h new file mode 100644 index 0000000..ac153e5 --- /dev/null +++ b/x86/cores/virtual/Stream.h @@ -0,0 +1,150 @@ +/* + Stream.h - base class for character-based streams. + Copyright (c) 2010 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + parsing functions based on TextFinder library by Michael Margolis +*/ + +#ifndef Stream_h +#define Stream_h + +#include +#include "Print.h" + +// compatability macros for testing +/* +#define getInt() parseInt() +#define getInt(ignore) parseInt(ignore) +#define getFloat() parseFloat() +#define getFloat(ignore) parseFloat(ignore) +#define getString( pre_string, post_string, buffer, length) +readBytesBetween( pre_string, terminator, buffer, length) +*/ + +// This enumeration provides the lookahead options for parseInt(), parseFloat() +// The rules set out here are used until either the first valid character is found +// or a time out occurs due to lack of input. +enum LookaheadMode { + SKIP_ALL, // All invalid characters are ignored. + SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid. + SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped. +}; + +#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field + +class Stream : public Print { + protected: + unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read + unsigned long _startMillis; // used for timeout measurement + int timedRead(); // private method to read stream with timeout + int timedPeek(); // private method to peek stream with timeout + int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout + + public: + virtual int available() = 0; + virtual int read() = 0; + virtual int peek() = 0; + + Stream() { + _timeout = 1000; + } + +// parsing methods + + void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second + unsigned long getTimeout(void) { + return _timeout; + } + + bool find(char *target); // reads data from the stream until the target string is found + bool find(uint8_t *target) { + return find((char *)target); + } + // returns true if target string is found, false if timed out (see setTimeout) + + bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found + bool find(uint8_t *target, size_t length) { + return find((char *)target, length); + } + // returns true if target string is found, false if timed out + + bool find(char target) { + return find(&target, 1); + } + + bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found + bool findUntil(uint8_t *target, char *terminator) { + return findUntil((char *)target, terminator); + } + + bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found + bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) { + return findUntil((char *)target, targetLen, terminate, termLen); + } + + long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // returns the first valid (long) integer value from the current position. + // lookahead determines how parseInt looks ahead in the stream. + // See LookaheadMode enumeration at the top of the file. + // Lookahead is terminated by the first character that is not a valid part of an integer. + // Once parsing commences, 'ignore' will be skipped in the stream. + + float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // float version of parseInt + + size_t readBytes(char *buffer, size_t length); // read chars from stream into buffer + size_t readBytes(uint8_t *buffer, size_t length) { + return readBytes((char *)buffer, length); + } + // terminates if length characters have been read or timeout (see setTimeout) + // returns the number of characters placed in the buffer (0 means no valid data found) + + size_t readBytesUntil(char terminator, char *buffer, size_t length); // as readBytes with terminator character + size_t readBytesUntil(char terminator, uint8_t *buffer, size_t length) { + return readBytesUntil(terminator, (char *)buffer, length); + } + // terminates if length characters have been read, timeout, or if the terminator character detected + // returns the number of characters placed in the buffer (0 means no valid data found) + + // Arduino String functions to be added here + String readString(); + String readStringUntil(char terminator); + + protected: + long parseInt(char ignore) { + return parseInt(SKIP_ALL, ignore); + } + float parseFloat(char ignore) { + return parseFloat(SKIP_ALL, ignore); + } + // These overload exists for compatibility with any class that has derived + // Stream and used parseFloat/Int with a custom ignore character. To keep + // the public API simple, these overload remains protected. + + struct MultiTarget { + const char *str; // string you're searching for + size_t len; // length of string you're searching for + size_t index; // index used by the search routine. + }; + + // This allows you to search for an arbitrary number of strings. + // Returns index of the target that is found first or -1 if timeout occurs. + int findMulti(struct MultiTarget *targets, int tCount); +}; + +#undef NO_IGNORE_CHAR +#endif diff --git a/x86/cores/virtual/WCharacter.h b/x86/cores/virtual/WCharacter.h new file mode 100644 index 0000000..b371c80 --- /dev/null +++ b/x86/cores/virtual/WCharacter.h @@ -0,0 +1,152 @@ +/* + WCharacter.h - Character utility functions for Wiring & Arduino + Copyright (c) 2010 Hernando Barragan. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef Character_h +#define Character_h + +#include + +// WCharacter.h prototypes +inline boolean isAlphaNumeric(int c) __attribute__((always_inline)); +inline boolean isAlpha(int c) __attribute__((always_inline)); +inline boolean isAscii(int c) __attribute__((always_inline)); +inline boolean isWhitespace(int c) __attribute__((always_inline)); +inline boolean isControl(int c) __attribute__((always_inline)); +inline boolean isDigit(int c) __attribute__((always_inline)); +inline boolean isGraph(int c) __attribute__((always_inline)); +inline boolean isLowerCase(int c) __attribute__((always_inline)); +inline boolean isPrintable(int c) __attribute__((always_inline)); +inline boolean isPunct(int c) __attribute__((always_inline)); +inline boolean isSpace(int c) __attribute__((always_inline)); +inline boolean isUpperCase(int c) __attribute__((always_inline)); +inline boolean isHexadecimalDigit(int c) __attribute__((always_inline)); +inline int toAscii(int c) __attribute__((always_inline)); +inline int toLowerCase(int c) __attribute__((always_inline)); +inline int toUpperCase(int c)__attribute__((always_inline)); + + +// Checks for an alphanumeric character. +// It is equivalent to (isalpha(c) || isdigit(c)). +inline boolean isAlphaNumeric(int c) { + return (isalnum(c) == 0 ? false : true); +} + + +// Checks for an alphabetic character. +// It is equivalent to (isupper(c) || islower(c)). +inline boolean isAlpha(int c) { + return (isalpha(c) == 0 ? false : true); +} + + +// Checks whether c is a 7-bit unsigned char value +// that fits into the ASCII character set. +inline boolean isAscii(int c) { + return (isascii(c) == 0 ? false : true); +} + + +// Checks for a blank character, that is, a space or a tab. +inline boolean isWhitespace(int c) { + return (isblank(c) == 0 ? false : true); +} + + +// Checks for a control character. +inline boolean isControl(int c) { + return (iscntrl(c) == 0 ? false : true); +} + + +// Checks for a digit (0 through 9). +inline boolean isDigit(int c) { + return (isdigit(c) == 0 ? false : true); +} + + +// Checks for any printable character except space. +inline boolean isGraph(int c) { + return (isgraph(c) == 0 ? false : true); +} + + +// Checks for a lower-case character. +inline boolean isLowerCase(int c) { + return (islower(c) == 0 ? false : true); +} + + +// Checks for any printable character including space. +inline boolean isPrintable(int c) { + return (isprint(c) == 0 ? false : true); +} + + +// Checks for any printable character which is not a space +// or an alphanumeric character. +inline boolean isPunct(int c) { + return (ispunct(c) == 0 ? false : true); +} + + +// Checks for white-space characters. For the avr-libc library, +// these are: space, formfeed ('\f'), newline ('\n'), carriage +// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). +inline boolean isSpace(int c) { + return (isspace(c) == 0 ? false : true); +} + + +// Checks for an uppercase letter. +inline boolean isUpperCase(int c) { + return (isupper(c) == 0 ? false : true); +} + + +// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7 +// 8 9 a b c d e f A B C D E F. +inline boolean isHexadecimalDigit(int c) { + return (isxdigit(c) == 0 ? false : true); +} + + +// Converts c to a 7-bit unsigned char value that fits into the +// ASCII character set, by clearing the high-order bits. +inline int toAscii(int c) { + return toascii(c); +} + + +// Warning: +// Many people will be unhappy if you use this function. +// This function will convert accented letters into random +// characters. + +// Converts the letter c to lower case, if possible. +inline int toLowerCase(int c) { + return tolower(c); +} + + +// Converts the letter c to upper case, if possible. +inline int toUpperCase(int c) { + return toupper(c); +} + +#endif \ No newline at end of file diff --git a/x86/cores/virtual/WMath.cpp b/x86/cores/virtual/WMath.cpp new file mode 100644 index 0000000..96d7f99 --- /dev/null +++ b/x86/cores/virtual/WMath.cpp @@ -0,0 +1,58 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Wiring project - http://wiring.org.co + Copyright (c) 2004-06 Hernando Barragan + Modified 13 August 2006, David A. Mellis for Arduino - http://www.arduino.cc/ + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +extern "C" { +#include "stdlib.h" +} + +void randomSeed(unsigned long seed) { + if (seed != 0) { + srandom(seed); + } +} + +long random(long howbig) { + if (howbig == 0) { + return 0; + } + return random() % howbig; +} + +long random(long howsmall, long howbig) { + if (howsmall >= howbig) { + return howsmall; + } + long diff = howbig - howsmall; + return random(diff) + howsmall; +} + +long map(long x, long in_min, long in_max, long out_min, long out_max) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +unsigned int makeWord(unsigned int w) { + return w; +} +unsigned int makeWord(unsigned char h, unsigned char l) { + return (h << 8) | l; +} diff --git a/x86/cores/virtual/WString.cpp b/x86/cores/virtual/WString.cpp new file mode 100644 index 0000000..6202d7f --- /dev/null +++ b/x86/cores/virtual/WString.cpp @@ -0,0 +1,675 @@ +/* + WString.cpp - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All rights reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "WString.h" +#include "Arduino.h" + +/*********************************************/ +/* Constructors */ +/*********************************************/ + +String::String(const char *cstr) { + init(); + if (cstr) copy(cstr, strlen(cstr)); +} + +String::String(const String &value) { + init(); + *this = value; +} + +String::String(const __FlashStringHelper *pstr) { + init(); + *this = pstr; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +String::String(String &&rval) { + init(); + move(rval); +} +String::String(StringSumHelper &&rval) { + init(); + move(rval); +} +#endif + +String::String(char c) { + init(); + char buf[2]; + buf[0] = c; + buf[1] = 0; + *this = buf; +} + +String::String(unsigned char value, unsigned char base) { + init(); + char buf[1 + 8 * sizeof(unsigned char)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(int value, unsigned char base) { + init(); + char buf[2 + 8 * sizeof(int)]; + itoa(value, buf, base); + *this = buf; +} + +String::String(unsigned int value, unsigned char base) { + init(); + char buf[1 + 8 * sizeof(unsigned int)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(long value, unsigned char base) { + init(); + char buf[2 + 8 * sizeof(long)]; + ltoa(value, buf, base); + *this = buf; +} + +String::String(unsigned long value, unsigned char base) { + init(); + char buf[1 + 8 * sizeof(unsigned long)]; + ultoa(value, buf, base); + *this = buf; +} + +String::String(float value, unsigned char decimalPlaces) { + init(); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::String(double value, unsigned char decimalPlaces) { + init(); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::~String() { + free(buffer); +} + +/*********************************************/ +/* Memory Management */ +/*********************************************/ + +inline void String::init(void) { + buffer = NULL; + capacity = 0; + len = 0; +} + +void String::invalidate(void) { + if (buffer) free(buffer); + buffer = NULL; + capacity = len = 0; +} + +unsigned char String::reserve(unsigned int size) { + if (buffer && capacity >= size) return 1; + if (changeBuffer(size)) { + if (len == 0) buffer[0] = 0; + return 1; + } + return 0; +} + +unsigned char String::changeBuffer(unsigned int maxStrLen) { + char *newbuffer = (char *)realloc(buffer, maxStrLen + 1); + if (newbuffer) { + buffer = newbuffer; + capacity = maxStrLen; + return 1; + } + return 0; +} + +/*********************************************/ +/* Copy and Move */ +/*********************************************/ + +String & String::copy(const char *cstr, unsigned int length) { + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy(buffer, cstr); + return *this; +} + +String & String::copy(const __FlashStringHelper *pstr, unsigned int length) { + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy_P(buffer, (PGM_P)pstr); + return *this; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +void String::move(String &rhs) { + if (buffer) { + if (rhs && capacity >= rhs.len) { + strcpy(buffer, rhs.buffer); + len = rhs.len; + rhs.len = 0; + return; + } else { + free(buffer); + } + } + buffer = rhs.buffer; + capacity = rhs.capacity; + len = rhs.len; + rhs.buffer = NULL; + rhs.capacity = 0; + rhs.len = 0; +} +#endif + +String & String::operator = (const String &rhs) { + if (this == &rhs) return *this; + + if (rhs.buffer) copy(rhs.buffer, rhs.len); + else invalidate(); + + return *this; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +String & String::operator = (String &&rval) { + if (this != &rval) move(rval); + return *this; +} + +String & String::operator = (StringSumHelper &&rval) { + if (this != &rval) move(rval); + return *this; +} +#endif + +String & String::operator = (const char *cstr) { + if (cstr) copy(cstr, strlen(cstr)); + else invalidate(); + + return *this; +} + +String & String::operator = (const __FlashStringHelper *pstr) { + if (pstr) copy(pstr, strlen_P((PGM_P)pstr)); + else invalidate(); + + return *this; +} + +/*********************************************/ +/* concat */ +/*********************************************/ + +unsigned char String::concat(const String &s) { + return concat(s.buffer, s.len); +} + +unsigned char String::concat(const char *cstr, unsigned int length) { + unsigned int newlen = len + length; + if (!cstr) return 0; + if (length == 0) return 1; + if (!reserve(newlen)) return 0; + strcpy(buffer + len, cstr); + len = newlen; + return 1; +} + +unsigned char String::concat(const char *cstr) { + if (!cstr) return 0; + return concat(cstr, strlen(cstr)); +} + +unsigned char String::concat(char c) { + char buf[2]; + buf[0] = c; + buf[1] = 0; + return concat(buf, 1); +} + +unsigned char String::concat(unsigned char num) { + char buf[1 + 3 * sizeof(unsigned char)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(int num) { + char buf[2 + 3 * sizeof(int)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned int num) { + char buf[1 + 3 * sizeof(unsigned int)]; + utoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(long num) { + char buf[2 + 3 * sizeof(long)]; + ltoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned long num) { + char buf[1 + 3 * sizeof(unsigned long)]; + ultoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(float num) { + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +unsigned char String::concat(double num) { + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +unsigned char String::concat(const __FlashStringHelper * str) { + if (!str) return 0; + int length = strlen_P((const char *) str); + if (length == 0) return 1; + unsigned int newlen = len + length; + if (!reserve(newlen)) return 0; + strcpy_P(buffer + len, (const char *) str); + len = newlen; + return 1; +} + +/*********************************************/ +/* Concatenate */ +/*********************************************/ + +StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) { + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) { + StringSumHelper &a = const_cast(lhs); + if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, char c) { + StringSumHelper &a = const_cast(lhs); + if (!a.concat(c)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) { + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, int num) { + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) { + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, long num) { + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) { + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, float num) { + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, double num) { + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) { + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs)) a.invalidate(); + return a; +} + +/*********************************************/ +/* Comparison */ +/*********************************************/ + +int String::compareTo(const String &s) const { + if (!buffer || !s.buffer) { + if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; + if (buffer && len > 0) return *(unsigned char *)buffer; + return 0; + } + return strcmp(buffer, s.buffer); +} + +unsigned char String::equals(const String &s2) const { + return (len == s2.len && compareTo(s2) == 0); +} + +unsigned char String::equals(const char *cstr) const { + if (len == 0) return (cstr == NULL || *cstr == 0); + if (cstr == NULL) return buffer[0] == 0; + return strcmp(buffer, cstr) == 0; +} + +unsigned char String::operator<(const String &rhs) const { + return compareTo(rhs) < 0; +} + +unsigned char String::operator>(const String &rhs) const { + return compareTo(rhs) > 0; +} + +unsigned char String::operator<=(const String &rhs) const { + return compareTo(rhs) <= 0; +} + +unsigned char String::operator>=(const String &rhs) const { + return compareTo(rhs) >= 0; +} + +unsigned char String::equalsIgnoreCase(const String &s2) const { + if (this == &s2) return 1; + if (len != s2.len) return 0; + if (len == 0) return 1; + const char *p1 = buffer; + const char *p2 = s2.buffer; + while (*p1) { + if (tolower(*p1++) != tolower(*p2++)) return 0; + } + return 1; +} + +unsigned char String::startsWith(const String &s2) const { + if (len < s2.len) return 0; + return startsWith(s2, 0); +} + +unsigned char String::startsWith(const String &s2, unsigned int offset) const { + if (offset > len - s2.len || !buffer || !s2.buffer) return 0; + return strncmp(&buffer[offset], s2.buffer, s2.len) == 0; +} + +unsigned char String::endsWith(const String &s2) const { + if (len < s2.len || !buffer || !s2.buffer) return 0; + return strcmp(&buffer[len - s2.len], s2.buffer) == 0; +} + +/*********************************************/ +/* Character Access */ +/*********************************************/ + +char String::charAt(unsigned int loc) const { + return operator[](loc); +} + +void String::setCharAt(unsigned int loc, char c) { + if (loc < len) buffer[loc] = c; +} + +char & String::operator[](unsigned int index) { + static char dummy_writable_char; + if (index >= len || !buffer) { + dummy_writable_char = 0; + return dummy_writable_char; + } + return buffer[index]; +} + +char String::operator[](unsigned int index) const { + if (index >= len || !buffer) return 0; + return buffer[index]; +} + +void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const { + if (!bufsize || !buf) return; + if (index >= len) { + buf[0] = 0; + return; + } + unsigned int n = bufsize - 1; + if (n > len - index) n = len - index; + strncpy((char *)buf, buffer + index, n); + buf[n] = 0; +} + +/*********************************************/ +/* Search */ +/*********************************************/ + +int String::indexOf(char c) const { + return indexOf(c, 0); +} + +int String::indexOf(char ch, unsigned int fromIndex) const { + if (fromIndex >= len) return -1; + const char* temp = strchr(buffer + fromIndex, ch); + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::indexOf(const String &s2) const { + return indexOf(s2, 0); +} + +int String::indexOf(const String &s2, unsigned int fromIndex) const { + if (fromIndex >= len) return -1; + const char *found = strstr(buffer + fromIndex, s2.buffer); + if (found == NULL) return -1; + return found - buffer; +} + +int String::lastIndexOf(char theChar) const { + return lastIndexOf(theChar, len - 1); +} + +int String::lastIndexOf(char ch, unsigned int fromIndex) const { + if (fromIndex >= len) return -1; + char tempchar = buffer[fromIndex + 1]; + buffer[fromIndex + 1] = '\0'; + char* temp = strrchr(buffer, ch); + buffer[fromIndex + 1] = tempchar; + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::lastIndexOf(const String &s2) const { + return lastIndexOf(s2, len - s2.len); +} + +int String::lastIndexOf(const String &s2, unsigned int fromIndex) const { + if (s2.len == 0 || len == 0 || s2.len > len) return -1; + if (fromIndex >= len) fromIndex = len - 1; + int found = -1; + for (char *p = buffer; p <= buffer + fromIndex; p++) { + p = strstr(p, s2.buffer); + if (!p) break; + if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; + } + return found; +} + +String String::substring(unsigned int left, unsigned int right) const { + if (left > right) { + unsigned int temp = right; + right = left; + left = temp; + } + String out; + if (left >= len) return out; + if (right > len) right = len; + char temp = buffer[right]; // save the replaced character + buffer[right] = '\0'; + out = buffer + left; // pointer arithmetic + buffer[right] = temp; //restore character + return out; +} + +/*********************************************/ +/* Modification */ +/*********************************************/ + +void String::replace(char find, char replace) { + if (!buffer) return; + for (char *p = buffer; *p; p++) { + if (*p == find) *p = replace; + } +} + +void String::replace(const String& find, const String& replace) { + if (len == 0 || find.len == 0) return; + int diff = replace.len - find.len; + char *readFrom = buffer; + char *foundAt; + if (diff == 0) { + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + memcpy(foundAt, replace.buffer, replace.len); + readFrom = foundAt + replace.len; + } + } else if (diff < 0) { + char *writeTo = buffer; + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + unsigned int n = foundAt - readFrom; + memcpy(writeTo, readFrom, n); + writeTo += n; + memcpy(writeTo, replace.buffer, replace.len); + writeTo += replace.len; + readFrom = foundAt + find.len; + len += diff; + } + strcpy(writeTo, readFrom); + } else { + unsigned int size = len; // compute size needed for result + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + readFrom = foundAt + find.len; + size += diff; + } + if (size == len) return; + if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! + int index = len - 1; + while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { + readFrom = buffer + index + find.len; + memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); + len += diff; + buffer[len] = 0; + memcpy(buffer + index, replace.buffer, replace.len); + index--; + } + } +} + +void String::remove(unsigned int index) { + // Pass the biggest integer as the count. The remove method + // below will take care of truncating it at the end of the + // string. + remove(index, (unsigned int) - 1); +} + +void String::remove(unsigned int index, unsigned int count) { + if (index >= len) { + return; + } + if (count <= 0) { + return; + } + if (count > len - index) { + count = len - index; + } + char *writeTo = buffer + index; + len = len - count; + strncpy(writeTo, buffer + index + count, len - index); + buffer[len] = 0; +} + +void String::toLowerCase(void) { + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = tolower(*p); + } +} + +void String::toUpperCase(void) { + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = toupper(*p); + } +} + +void String::trim(void) { + if (!buffer || len == 0) return; + char *begin = buffer; + while (isspace(*begin)) begin++; + char *end = buffer + len - 1; + while (isspace(*end) && end >= begin) end--; + len = end + 1 - begin; + if (begin > buffer) memcpy(buffer, begin, len); + buffer[len] = 0; +} + +/*********************************************/ +/* Parsing / Conversion */ +/*********************************************/ + +long String::toInt(void) const { + if (buffer) return atol(buffer); + return 0; +} + +float String::toFloat(void) const { + return float(toDouble()); +} + +double String::toDouble(void) const { + if (buffer) return atof(buffer); + return 0; +} diff --git a/x86/cores/virtual/WString.h b/x86/cores/virtual/WString.h new file mode 100644 index 0000000..b8aa776 --- /dev/null +++ b/x86/cores/virtual/WString.h @@ -0,0 +1,284 @@ +/* + WString.h - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All right reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef String_class_h +#define String_class_h +#ifdef __cplusplus + +#include +#include +#include + +// When compiling programs with this class, the following gcc parameters +// dramatically increase performance and memory (RAM) efficiency, typically +// with little or no increase in code size. +// -felide-constructors +// -std=c++0x + +class __FlashStringHelper; +#define F(string_literal) (reinterpret_cast(PSTR(string_literal))) + +// An inherited class for holding the result of a concatenation. These +// result objects are assumed to be writable by subsequent concatenations. +class StringSumHelper; + +// The string class +class String { + // use a function pointer to allow for "if (s)" without the + // complications of an operator bool(). for more information, see: + // http://www.artima.com/cppsource/safebool.html + typedef void (String::*StringIfHelperType)() const; + void StringIfHelper() const {} + + public: + // constructors + // creates a copy of the initial value. + // if the initial value is null or invalid, or if memory allocation + // fails, the string will be marked as invalid (i.e. "if (s)" will + // be false). + String(const char *cstr = ""); + String(const String &str); + String(const __FlashStringHelper *str); +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String(String &&rval); + String(StringSumHelper &&rval); +#endif + explicit String(char c); + explicit String(unsigned char, unsigned char base = 10); + explicit String(int, unsigned char base = 10); + explicit String(unsigned int, unsigned char base = 10); + explicit String(long, unsigned char base = 10); + explicit String(unsigned long, unsigned char base = 10); + explicit String(float, unsigned char decimalPlaces = 2); + explicit String(double, unsigned char decimalPlaces = 2); + ~String(void); + + // memory management + // return true on success, false on failure (in which case, the string + // is left unchanged). reserve(0), if successful, will validate an + // invalid string (i.e., "if (s)" will be true afterwards) + unsigned char reserve(unsigned int size); + inline unsigned int length(void) const { + return len; + } + + // creates a copy of the assigned value. if the value is null or + // invalid, or if the memory allocation fails, the string will be + // marked as invalid ("if (s)" will be false). + String & operator = (const String &rhs); + String & operator = (const char *cstr); + String & operator = (const __FlashStringHelper *str); +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String & operator = (String &&rval); + String & operator = (StringSumHelper &&rval); +#endif + + // concatenate (works w/ built-in types) + + // returns true on success, false on failure (in which case, the string + // is left unchanged). if the argument is null or invalid, the + // concatenation is considered unsucessful. + unsigned char concat(const String &str); + unsigned char concat(const char *cstr); + unsigned char concat(char c); + unsigned char concat(unsigned char c); + unsigned char concat(int num); + unsigned char concat(unsigned int num); + unsigned char concat(long num); + unsigned char concat(unsigned long num); + unsigned char concat(float num); + unsigned char concat(double num); + unsigned char concat(const __FlashStringHelper * str); + + // if there's not enough memory for the concatenated value, the string + // will be left unchanged (but this isn't signalled in any way) + String & operator += (const String &rhs) { + concat(rhs); + return (*this); + } + String & operator += (const char *cstr) { + concat(cstr); + return (*this); + } + String & operator += (char c) { + concat(c); + return (*this); + } + String & operator += (unsigned char num) { + concat(num); + return (*this); + } + String & operator += (int num) { + concat(num); + return (*this); + } + String & operator += (unsigned int num) { + concat(num); + return (*this); + } + String & operator += (long num) { + concat(num); + return (*this); + } + String & operator += (unsigned long num) { + concat(num); + return (*this); + } + String & operator += (float num) { + concat(num); + return (*this); + } + String & operator += (double num) { + concat(num); + return (*this); + } + String & operator += (const __FlashStringHelper *str) { + concat(str); + return (*this); + } + + friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); + friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); + + // comparison (only works w/ Strings and "strings") + operator StringIfHelperType() const { + return buffer ? &String::StringIfHelper : 0; + } + int compareTo(const String &s) const; + unsigned char equals(const String &s) const; + unsigned char equals(const char *cstr) const; + unsigned char operator == (const String &rhs) const { + return equals(rhs); + } + unsigned char operator == (const char *cstr) const { + return equals(cstr); + } + unsigned char operator != (const String &rhs) const { + return !equals(rhs); + } + unsigned char operator != (const char *cstr) const { + return !equals(cstr); + } + unsigned char operator < (const String &rhs) const; + unsigned char operator > (const String &rhs) const; + unsigned char operator <= (const String &rhs) const; + unsigned char operator >= (const String &rhs) const; + unsigned char equalsIgnoreCase(const String &s) const; + unsigned char startsWith(const String &prefix) const; + unsigned char startsWith(const String &prefix, unsigned int offset) const; + unsigned char endsWith(const String &suffix) const; + + // character acccess + char charAt(unsigned int index) const; + void setCharAt(unsigned int index, char c); + char operator [](unsigned int index) const; + char& operator [](unsigned int index); + void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index = 0) const; + void toCharArray(char *buf, unsigned int bufsize, unsigned int index = 0) const { + getBytes((unsigned char *)buf, bufsize, index); + } + const char* c_str() const { + return buffer; + } + char* begin() { + return buffer; + } + char* end() { + return buffer + length(); + } + const char* begin() const { + return c_str(); + } + const char* end() const { + return c_str() + length(); + } + + // search + int indexOf(char ch) const; + int indexOf(char ch, unsigned int fromIndex) const; + int indexOf(const String &str) const; + int indexOf(const String &str, unsigned int fromIndex) const; + int lastIndexOf(char ch) const; + int lastIndexOf(char ch, unsigned int fromIndex) const; + int lastIndexOf(const String &str) const; + int lastIndexOf(const String &str, unsigned int fromIndex) const; + String substring(unsigned int beginIndex) const { + return substring(beginIndex, len); + }; + String substring(unsigned int beginIndex, unsigned int endIndex) const; + + // modification + void replace(char find, char replace); + void replace(const String& find, const String& replace); + void remove(unsigned int index); + void remove(unsigned int index, unsigned int count); + void toLowerCase(void); + void toUpperCase(void); + void trim(void); + + // parsing/conversion + long toInt(void) const; + float toFloat(void) const; + double toDouble(void) const; + + protected: + char *buffer; // the actual char array + unsigned int capacity; // the array length minus one (for the '\0') + unsigned int len; // the String length (not counting the '\0') + protected: + void init(void); + void invalidate(void); + unsigned char changeBuffer(unsigned int maxStrLen); + unsigned char concat(const char *cstr, unsigned int length); + + // copy and move + String & copy(const char *cstr, unsigned int length); + String & copy(const __FlashStringHelper *pstr, unsigned int length); +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + void move(String &rhs); +#endif +}; + +class StringSumHelper : public String { + public: + StringSumHelper(const String &s) : String(s) {} + StringSumHelper(const char *p) : String(p) {} + StringSumHelper(char c) : String(c) {} + StringSumHelper(unsigned char num) : String(num) {} + StringSumHelper(int num) : String(num) {} + StringSumHelper(unsigned int num) : String(num) {} + StringSumHelper(long num) : String(num) {} + StringSumHelper(unsigned long num) : String(num) {} + StringSumHelper(float num) : String(num) {} + StringSumHelper(double num) : String(num) {} +}; + +#endif // __cplusplus +#endif // String_class_h diff --git a/x86/cores/virtual/binary.h b/x86/cores/virtual/binary.h new file mode 100644 index 0000000..aec4c73 --- /dev/null +++ b/x86/cores/virtual/binary.h @@ -0,0 +1,534 @@ +/* + binary.h - Definitions for binary constants + Copyright (c) 2006 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Binary_h +#define Binary_h + +#define B0 0 +#define B00 0 +#define B000 0 +#define B0000 0 +#define B00000 0 +#define B000000 0 +#define B0000000 0 +#define B00000000 0 +#define B1 1 +#define B01 1 +#define B001 1 +#define B0001 1 +#define B00001 1 +#define B000001 1 +#define B0000001 1 +#define B00000001 1 +#define B10 2 +#define B010 2 +#define B0010 2 +#define B00010 2 +#define B000010 2 +#define B0000010 2 +#define B00000010 2 +#define B11 3 +#define B011 3 +#define B0011 3 +#define B00011 3 +#define B000011 3 +#define B0000011 3 +#define B00000011 3 +#define B100 4 +#define B0100 4 +#define B00100 4 +#define B000100 4 +#define B0000100 4 +#define B00000100 4 +#define B101 5 +#define B0101 5 +#define B00101 5 +#define B000101 5 +#define B0000101 5 +#define B00000101 5 +#define B110 6 +#define B0110 6 +#define B00110 6 +#define B000110 6 +#define B0000110 6 +#define B00000110 6 +#define B111 7 +#define B0111 7 +#define B00111 7 +#define B000111 7 +#define B0000111 7 +#define B00000111 7 +#define B1000 8 +#define B01000 8 +#define B001000 8 +#define B0001000 8 +#define B00001000 8 +#define B1001 9 +#define B01001 9 +#define B001001 9 +#define B0001001 9 +#define B00001001 9 +#define B1010 10 +#define B01010 10 +#define B001010 10 +#define B0001010 10 +#define B00001010 10 +#define B1011 11 +#define B01011 11 +#define B001011 11 +#define B0001011 11 +#define B00001011 11 +#define B1100 12 +#define B01100 12 +#define B001100 12 +#define B0001100 12 +#define B00001100 12 +#define B1101 13 +#define B01101 13 +#define B001101 13 +#define B0001101 13 +#define B00001101 13 +#define B1110 14 +#define B01110 14 +#define B001110 14 +#define B0001110 14 +#define B00001110 14 +#define B1111 15 +#define B01111 15 +#define B001111 15 +#define B0001111 15 +#define B00001111 15 +#define B10000 16 +#define B010000 16 +#define B0010000 16 +#define B00010000 16 +#define B10001 17 +#define B010001 17 +#define B0010001 17 +#define B00010001 17 +#define B10010 18 +#define B010010 18 +#define B0010010 18 +#define B00010010 18 +#define B10011 19 +#define B010011 19 +#define B0010011 19 +#define B00010011 19 +#define B10100 20 +#define B010100 20 +#define B0010100 20 +#define B00010100 20 +#define B10101 21 +#define B010101 21 +#define B0010101 21 +#define B00010101 21 +#define B10110 22 +#define B010110 22 +#define B0010110 22 +#define B00010110 22 +#define B10111 23 +#define B010111 23 +#define B0010111 23 +#define B00010111 23 +#define B11000 24 +#define B011000 24 +#define B0011000 24 +#define B00011000 24 +#define B11001 25 +#define B011001 25 +#define B0011001 25 +#define B00011001 25 +#define B11010 26 +#define B011010 26 +#define B0011010 26 +#define B00011010 26 +#define B11011 27 +#define B011011 27 +#define B0011011 27 +#define B00011011 27 +#define B11100 28 +#define B011100 28 +#define B0011100 28 +#define B00011100 28 +#define B11101 29 +#define B011101 29 +#define B0011101 29 +#define B00011101 29 +#define B11110 30 +#define B011110 30 +#define B0011110 30 +#define B00011110 30 +#define B11111 31 +#define B011111 31 +#define B0011111 31 +#define B00011111 31 +#define B100000 32 +#define B0100000 32 +#define B00100000 32 +#define B100001 33 +#define B0100001 33 +#define B00100001 33 +#define B100010 34 +#define B0100010 34 +#define B00100010 34 +#define B100011 35 +#define B0100011 35 +#define B00100011 35 +#define B100100 36 +#define B0100100 36 +#define B00100100 36 +#define B100101 37 +#define B0100101 37 +#define B00100101 37 +#define B100110 38 +#define B0100110 38 +#define B00100110 38 +#define B100111 39 +#define B0100111 39 +#define B00100111 39 +#define B101000 40 +#define B0101000 40 +#define B00101000 40 +#define B101001 41 +#define B0101001 41 +#define B00101001 41 +#define B101010 42 +#define B0101010 42 +#define B00101010 42 +#define B101011 43 +#define B0101011 43 +#define B00101011 43 +#define B101100 44 +#define B0101100 44 +#define B00101100 44 +#define B101101 45 +#define B0101101 45 +#define B00101101 45 +#define B101110 46 +#define B0101110 46 +#define B00101110 46 +#define B101111 47 +#define B0101111 47 +#define B00101111 47 +#define B110000 48 +#define B0110000 48 +#define B00110000 48 +#define B110001 49 +#define B0110001 49 +#define B00110001 49 +#define B110010 50 +#define B0110010 50 +#define B00110010 50 +#define B110011 51 +#define B0110011 51 +#define B00110011 51 +#define B110100 52 +#define B0110100 52 +#define B00110100 52 +#define B110101 53 +#define B0110101 53 +#define B00110101 53 +#define B110110 54 +#define B0110110 54 +#define B00110110 54 +#define B110111 55 +#define B0110111 55 +#define B00110111 55 +#define B111000 56 +#define B0111000 56 +#define B00111000 56 +#define B111001 57 +#define B0111001 57 +#define B00111001 57 +#define B111010 58 +#define B0111010 58 +#define B00111010 58 +#define B111011 59 +#define B0111011 59 +#define B00111011 59 +#define B111100 60 +#define B0111100 60 +#define B00111100 60 +#define B111101 61 +#define B0111101 61 +#define B00111101 61 +#define B111110 62 +#define B0111110 62 +#define B00111110 62 +#define B111111 63 +#define B0111111 63 +#define B00111111 63 +#define B1000000 64 +#define B01000000 64 +#define B1000001 65 +#define B01000001 65 +#define B1000010 66 +#define B01000010 66 +#define B1000011 67 +#define B01000011 67 +#define B1000100 68 +#define B01000100 68 +#define B1000101 69 +#define B01000101 69 +#define B1000110 70 +#define B01000110 70 +#define B1000111 71 +#define B01000111 71 +#define B1001000 72 +#define B01001000 72 +#define B1001001 73 +#define B01001001 73 +#define B1001010 74 +#define B01001010 74 +#define B1001011 75 +#define B01001011 75 +#define B1001100 76 +#define B01001100 76 +#define B1001101 77 +#define B01001101 77 +#define B1001110 78 +#define B01001110 78 +#define B1001111 79 +#define B01001111 79 +#define B1010000 80 +#define B01010000 80 +#define B1010001 81 +#define B01010001 81 +#define B1010010 82 +#define B01010010 82 +#define B1010011 83 +#define B01010011 83 +#define B1010100 84 +#define B01010100 84 +#define B1010101 85 +#define B01010101 85 +#define B1010110 86 +#define B01010110 86 +#define B1010111 87 +#define B01010111 87 +#define B1011000 88 +#define B01011000 88 +#define B1011001 89 +#define B01011001 89 +#define B1011010 90 +#define B01011010 90 +#define B1011011 91 +#define B01011011 91 +#define B1011100 92 +#define B01011100 92 +#define B1011101 93 +#define B01011101 93 +#define B1011110 94 +#define B01011110 94 +#define B1011111 95 +#define B01011111 95 +#define B1100000 96 +#define B01100000 96 +#define B1100001 97 +#define B01100001 97 +#define B1100010 98 +#define B01100010 98 +#define B1100011 99 +#define B01100011 99 +#define B1100100 100 +#define B01100100 100 +#define B1100101 101 +#define B01100101 101 +#define B1100110 102 +#define B01100110 102 +#define B1100111 103 +#define B01100111 103 +#define B1101000 104 +#define B01101000 104 +#define B1101001 105 +#define B01101001 105 +#define B1101010 106 +#define B01101010 106 +#define B1101011 107 +#define B01101011 107 +#define B1101100 108 +#define B01101100 108 +#define B1101101 109 +#define B01101101 109 +#define B1101110 110 +#define B01101110 110 +#define B1101111 111 +#define B01101111 111 +#define B1110000 112 +#define B01110000 112 +#define B1110001 113 +#define B01110001 113 +#define B1110010 114 +#define B01110010 114 +#define B1110011 115 +#define B01110011 115 +#define B1110100 116 +#define B01110100 116 +#define B1110101 117 +#define B01110101 117 +#define B1110110 118 +#define B01110110 118 +#define B1110111 119 +#define B01110111 119 +#define B1111000 120 +#define B01111000 120 +#define B1111001 121 +#define B01111001 121 +#define B1111010 122 +#define B01111010 122 +#define B1111011 123 +#define B01111011 123 +#define B1111100 124 +#define B01111100 124 +#define B1111101 125 +#define B01111101 125 +#define B1111110 126 +#define B01111110 126 +#define B1111111 127 +#define B01111111 127 +#define B10000000 128 +#define B10000001 129 +#define B10000010 130 +#define B10000011 131 +#define B10000100 132 +#define B10000101 133 +#define B10000110 134 +#define B10000111 135 +#define B10001000 136 +#define B10001001 137 +#define B10001010 138 +#define B10001011 139 +#define B10001100 140 +#define B10001101 141 +#define B10001110 142 +#define B10001111 143 +#define B10010000 144 +#define B10010001 145 +#define B10010010 146 +#define B10010011 147 +#define B10010100 148 +#define B10010101 149 +#define B10010110 150 +#define B10010111 151 +#define B10011000 152 +#define B10011001 153 +#define B10011010 154 +#define B10011011 155 +#define B10011100 156 +#define B10011101 157 +#define B10011110 158 +#define B10011111 159 +#define B10100000 160 +#define B10100001 161 +#define B10100010 162 +#define B10100011 163 +#define B10100100 164 +#define B10100101 165 +#define B10100110 166 +#define B10100111 167 +#define B10101000 168 +#define B10101001 169 +#define B10101010 170 +#define B10101011 171 +#define B10101100 172 +#define B10101101 173 +#define B10101110 174 +#define B10101111 175 +#define B10110000 176 +#define B10110001 177 +#define B10110010 178 +#define B10110011 179 +#define B10110100 180 +#define B10110101 181 +#define B10110110 182 +#define B10110111 183 +#define B10111000 184 +#define B10111001 185 +#define B10111010 186 +#define B10111011 187 +#define B10111100 188 +#define B10111101 189 +#define B10111110 190 +#define B10111111 191 +#define B11000000 192 +#define B11000001 193 +#define B11000010 194 +#define B11000011 195 +#define B11000100 196 +#define B11000101 197 +#define B11000110 198 +#define B11000111 199 +#define B11001000 200 +#define B11001001 201 +#define B11001010 202 +#define B11001011 203 +#define B11001100 204 +#define B11001101 205 +#define B11001110 206 +#define B11001111 207 +#define B11010000 208 +#define B11010001 209 +#define B11010010 210 +#define B11010011 211 +#define B11010100 212 +#define B11010101 213 +#define B11010110 214 +#define B11010111 215 +#define B11011000 216 +#define B11011001 217 +#define B11011010 218 +#define B11011011 219 +#define B11011100 220 +#define B11011101 221 +#define B11011110 222 +#define B11011111 223 +#define B11100000 224 +#define B11100001 225 +#define B11100010 226 +#define B11100011 227 +#define B11100100 228 +#define B11100101 229 +#define B11100110 230 +#define B11100111 231 +#define B11101000 232 +#define B11101001 233 +#define B11101010 234 +#define B11101011 235 +#define B11101100 236 +#define B11101101 237 +#define B11101110 238 +#define B11101111 239 +#define B11110000 240 +#define B11110001 241 +#define B11110010 242 +#define B11110011 243 +#define B11110100 244 +#define B11110101 245 +#define B11110110 246 +#define B11110111 247 +#define B11111000 248 +#define B11111001 249 +#define B11111010 250 +#define B11111011 251 +#define B11111100 252 +#define B11111101 253 +#define B11111110 254 +#define B11111111 255 + +#endif diff --git a/x86/cores/virtual/main.cpp b/x86/cores/virtual/main.cpp new file mode 100644 index 0000000..2c23272 --- /dev/null +++ b/x86/cores/virtual/main.cpp @@ -0,0 +1,54 @@ +/* + main.cpp - Main loop for Arduino sketches + Copyright (c) 2005-2013 Arduino Team. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include "virtual_io.h" +#include + +// Weak empty variant initialization function. +// May be redefined by variant files. +void initVariant() __attribute__((weak)); +void initVariant() { } + +void setupUSB() __attribute__((weak)); +void setupUSB() { } + +void init(void) { + // Arduino core does some device-related setup here. + // We don't need to do anything. +} + +int main(int argc, char* argv[]) { + if (!initVirtualInput(argc, argv)) return 1; + + init(); + initVariant(); + + setup(); + + while (true) { + std::cout << "Starting cycle " << currentCycle() << std::endl; + loop(); + if (serialEventRun) serialEventRun(); + nextCycle(); + } + + return 0; +} + diff --git a/x86/cores/virtual/stdlib_ext.c b/x86/cores/virtual/stdlib_ext.c new file mode 100644 index 0000000..43841f9 --- /dev/null +++ b/x86/cores/virtual/stdlib_ext.c @@ -0,0 +1,72 @@ +#include "stdlib_ext.h" +#include + +// This implementation is adapted from en.wikibooks.org/wiki/C_Programming/stdlib.h/itoa +#define SIGNED_INT_TO_A \ + int i, sign; \ + if ((sign = val) < 0) val = -val; \ + i = 0; \ + do { \ + s[i++] = val % radix + '0'; \ + } while ((val /= 10) > 0); \ + if (sign < 0) \ + s[i++] = '-'; \ + s[i] = '\0'; \ + reverse(s); /* reverse s in place */ \ + return s; + +#define UNSIGNED_INT_TO_A \ + unsigned i = 0; \ + do { \ + s[i++] = val % radix + '0'; \ + } while ((val /= 10) > 0); \ + s[i] = '\0'; \ + reverse(s); \ + return s; + +void reverse(char* s); // reverse s in place + +char* itoa(int val, char* s, int radix) { + SIGNED_INT_TO_A +} + +char* ltoa(long val, char* s, int radix) { + SIGNED_INT_TO_A +} + +char* utoa(unsigned int val, char* s, int radix) { + UNSIGNED_INT_TO_A +} + +char* ultoa(unsigned long val, char* s, int radix) { + UNSIGNED_INT_TO_A +} + +void reverse(char* s) { + // from the same wikibooks link as itoa() + int i, j; + char c; + for (i = 0, j = strlen(s)-1; i +#include +#include +#include +#include // exit() +#include // mkdir() +#include // mkdir() +#include + +static bool interactive; +static std::istream* input = NULL; +static std::ostream* usbstream = NULL; +static std::ostream* ledstream = NULL; +static unsigned cycle = 0; + +bool isInteractive(void) { + return interactive; +} + +unsigned currentCycle(void) { + return cycle; +} +void nextCycle(void) { + cycle++; +} + +void logUSBEvent(std::string descrip, void* data, int length) { + if (usbstream) { + *usbstream << "Cycle " << std::dec << currentCycle() << ": " << descrip << ": 0x" << std::hex; + unsigned char* report = (unsigned char*) data; + for (int i = 0; i < length; i++) *usbstream << std::setfill('0') << std::setw(2) << (unsigned int)(report[i]); // pad with 0's to total of 2 characters + *usbstream << std::endl; + } +} + +void logUSBEvent_keyboard(std::string descrip) { + if (usbstream) { + *usbstream << "Cycle " << std::dec << currentCycle() << ": " << descrip << std::endl; + } +} + +void logLEDStates(std::string descrip) { + if (ledstream) { + *ledstream << "Cycle " << std::dec << currentCycle() << ": " << descrip << std::endl; + } +} + +bool initVirtualInput(int argc, char* argv[]) { + if (argc < 2 || strcmp(argv[1], "?") == 0) { + printHelp(); + return false; + } else if (argc > 2) { + std::cerr << "Error: more arguments than expected (got " << (argc - 1) << ")" << std::endl; + return false; + } + + if (strcmp(argv[1], "-i") == 0) { + interactive = true; + input = &std::cin; + } else { + interactive = false; + input = new std::ifstream(argv[1]); + if (!input || !(*input)) { + std::cerr << "Error opening input file \"" << argv[1] << "\"" << std::endl; + return false; + } + } + + if (mkdir("results", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) && errno != EEXIST) { + std::cerr << "Error creating directory 'results', errno " << errno << std::endl; + return false; + } + usbstream = new std::ofstream("results/USB.txt"); + ledstream = new std::ofstream("results/LED.txt"); + + return true; +} + +std::string getLineOfInput(bool anythingHeld) { + if (interactive) { + std::cout << "Enter a command for this scan cycle, or ? or 'help' for help." << std::endl; + if (anythingHeld) std::cout << "+> "; + else std::cout << "> "; + } + std::string line; + std::getline(*input, line); + if (!interactive && !(*input)) exit(0); // reached EOF or other file error + return line; +} + +void printHelp(void) { + std::cout << "\nUsage:\n" << std::endl; + std::cout << "(Running with no arguments or with the argument '?' will print this help message and quit.)\n" << std::endl; + std::cout << "This program expects a single argument, which is either:" << std::endl; + std::cout << " 1. An input file/script, with format given below, or" << std::endl; + std::cout << " 2. \"-i\", to run interactively, where you can interactively enter commands and see results." << std::endl; + std::cout << "\nIn either case, for each scan cycle you will specify zero or more input 'commands', that is," << std::endl; + std::cout << " actions to take on the keys of the virtual keyboard. Each line of the input file, or each" << std::endl; + std::cout << " prompt (in interactive mode), represents one scan cycle; a blank line or empty prompt means" << std::endl; + std::cout << " to do nothing to the inputs this scan cycle (held keys will still remain held, though)." << std::endl; + std::cout << "\nOutput, in terms of HID reports (packets sent to the host computer, for real hardware), is" << std::endl; + std::cout << " printed to stdout as it happens, in summarized/human-readable form. Raw HID output and" << std::endl; + std::cout << " serial output (through the 'Serial' object) are collected and redirected to various files" << std::endl; + std::cout << " in a subdirectory \"results\" of the current directory." << std::endl; + std::cout << "\nSerial input is currently unsupported - sketches requesting it will still build, but will" << std::endl; + std::cout << " find nothing is ever transmitted to them on the serial port." << std::endl; + std::cout << "\n--- Commands ---" << std::endl; + std::cout << "\n1. BASICS\n" << std::endl; + std::cout << "In any given scan cycle, you can 'tap' a virtual key simply by entering its name." << std::endl; + std::cout << "To 'tap' multiple keys in one cycle, enter each of their names separated by a space." << std::endl; + std::cout << "Keys can be identified either by their (row,col) coordinate, or by their \"physical\" names." << std::endl; + std::cout << "Keys' coordinate names are simply of the form (row,col). E.g. (0,1) or (2,10) or (1,0)." << std::endl; + std::cout << " (Don't put any extra whitespace inside the coordinate name.)" << std::endl; + std::cout << "A key's \"physical\" name is the (unshifted) text printed on the key on the standard QWERTY" << std::endl; + std::cout << " Model 01. The key always has the same name regardless of what the keymap in the current" << std::endl; + std::cout << " Kaleidoscope sketch may or may not be doing. As an exception to the printed-name rule, we" << std::endl; + std::cout << " distinguish physical keys with the same text (ctrl, shift, and fn) with 'l' or 'r' indicating the hand." << std::endl; + std::cout << "Here is a list of all the valid key \"physical\" names:" << std::endl; + std::cout << " prog 1 2 3 4 5 led any 6 7 8 9 0 num ` q w e r t y u i o p = pgup a s d f g tab enter h j k l ; '" << std::endl; + std::cout << " pgdn z x c v b esc fly n m , . / - lctrl bksp cmd lshift lfn rshift alt space rctrl rfn" << std::endl; + std::cout << "The comment character '#' instructs the program to ignore the rest of the line (either in the" << std::endl; + std::cout << " script, or in interactive mode)." << std::endl; + std::cout << "\nExample script:" << std::endl; + std::cout << " t # first scan cycle: tap the physical T key" << std::endl; + std::cout << " esc # next scan cycle: tap the physcial esc key" << std::endl; + std::cout << " # take no action for a scan cycle" << std::endl; + std::cout << " (2,1) # tap the key in row 2, column 1" << std::endl; + std::cout << " lshift e # tap the lshift and e keys simultaneously" << std::endl; + std::cout << " s (1,3) (3,8) # tap the s key, the key at (1,3), and the key at (3,8) simultaneously" << std::endl; + std::cout << " p q lfn fly # tap the p, q, lfn, and fly keys simultaneously" << std::endl; + std::cout << "\n2. ADVANCED\n" << std::endl; + std::cout << "In addition to key names and the comment command '#', there are various other commands available." << std::endl; + std::cout << "Key names are always in all lowercase (defined as symbols that appear in the unshifted positions" << std::endl; + std::cout << " on the standard QWERTY Model 01); uppercase/shifted symbols denote commands." << std::endl; + std::cout << "Commands can be inserted anywhere in the input line, and affect the handling of keys following." << std::endl; + std::cout << "The default command, which we used above, is 'tap' (where the key is 'down' for just this cycle)." << std::endl; + std::cout << "'tap' can also be explicitly specified by 'T', as in \"T b\" to 'tap' the physical B key." << std::endl; + std::cout << "You can hold virtual keys down using the 'D' (down) command. The key will remain held until you" << std::endl; + std::cout << " say otherwise. In interactive mode, while keys are held, the prompt changes from '>' to '+>'." << std::endl; + std::cout << "You can release a previously held virtual key using the 'U' command." << std::endl; + std::cout << "Commands affect all following keys within the line unless overridden. So, \"D lshift u\" holds" << std::endl; + std::cout << " both lshift and u. To hold lshift and tap u, either enter \"D lshift T u\", or \"u D lshift\"." << std::endl; + std::cout << "An exception to the above rule is the command 'C', which releases all currently held keys." << std::endl; + std::cout << "One final command, 'Q', will quit the program. In non-interactive mode (i.e. with an input" << std::endl; + std::cout << " script), the end of the script also implicitly indicates the end of the program." << std::endl; + std::cout << "\nAdvanced script example:" << std::endl; + std::cout << " h # tap the physical H key" << std::endl; + std::cout << " D lshift # hold the physical lshift key down" << std::endl; + std::cout << " c (0,3) # tap both c and the key at (0,3) (with lshift held)" << std::endl; + std::cout << " D alt # hold alt (in addition to lshift)" << std::endl; + std::cout << " U lshift T e # Release lshift, and tap e in the same cycle" << std::endl; + std::cout << " # Do nothing for a scan cycle (but keep alt held)" << std::endl; + std::cout << " C # Release all held keys (in this case, just alt)" << std::endl; + std::cout << " enter D (1,12) # Tap the physical enter key, and hold the key at (1,12)" << std::endl; + std::cout << " fly # Tap the fly key (with (1,12) held)" << std::endl; + std::cout << " Q # Quit the program" << std::endl; + std::cout << std::endl; +} diff --git a/x86/cores/virtual/virtual_io.h b/x86/cores/virtual/virtual_io.h new file mode 100644 index 0000000..c7b1c77 --- /dev/null +++ b/x86/cores/virtual/virtual_io.h @@ -0,0 +1,16 @@ +#include +#include + +// Returns TRUE if successful, FALSE if not +bool initVirtualInput(int argc, char* argv[]); + +std::string getLineOfInput(bool anythingHeld); +bool isInteractive(void); +void printHelp(void); + +unsigned currentCycle(void); // current cycle number, first cycle is 0 +void nextCycle(void); // should only be used by cores/virtual/main.cpp, to increment currentCycle() + +void logUSBEvent(std::string descrip, void* data, int length); +void logUSBEvent_keyboard(std::string descrip); // assumes 'descrip' uniquely describes the raw data too +void logLEDStates(std::string descrip); // assumes 'descrip' uniquely describes the LED states diff --git a/x86/libraries b/x86/libraries new file mode 120000 index 0000000..5ba468a --- /dev/null +++ b/x86/libraries @@ -0,0 +1 @@ +../avr/libraries/ \ No newline at end of file diff --git a/x86/platform.txt b/x86/platform.txt new file mode 100644 index 0000000..69b40c1 --- /dev/null +++ b/x86/platform.txt @@ -0,0 +1,118 @@ + +# For more info: +# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification + +name=Keyboardio Keyboards +version=1.6.11 + +# This file is for "virtual" hardware which means we compile the sketch for +# x86, and with an entirely different core. + +compiler.warning_flags=-w +compiler.warning_flags.none=-w +compiler.warning_flags.default= +compiler.warning_flags.more=-Wall +compiler.warning_flags.all=-Wall -Wextra + +compiler.path= +compiler.c.cmd=gcc +compiler.c.flags=-c -g -Os {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -MMD +compiler.c.elf.flags={compiler.warning_flags} -Os -Wl,--gc-sections +compiler.c.elf.cmd=g++ +compiler.S.flags=-c -g -x assembler-with-cpp +compiler.cpp.cmd=g++ +compiler.cpp.flags=-c -g -Os {compiler.warning_flags} -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD +compiler.ar.cmd=ar +compiler.ar.flags=rcs +compiler.objcopy.cmd=objcopy +compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 +compiler.elf2hex.flags=-O ihex -R .eeprom +compiler.elf2hex.cmd=objcopy +compiler.ldflags= +compiler.size.cmd=echo >/dev/null + +# This can be overridden in boards.txt +build.extra_flags= + +# These can be overridden in platform.local.txt +compiler.c.extra_flags=-Wno-unused-parameter -Wno-unused-variable -Wno-type-limits +compiler.c.elf.extra_flags= +compiler.S.extra_flags= +compiler.cpp.extra_flags=-Woverloaded-virtual -Wno-unused-parameter -Wno-unused-variable -Wno-type-limits +compiler.ar.extra_flags= +compiler.objcopy.eep.extra_flags= +compiler.elf2hex.extra_flags= + +# AVR compile patterns +# -------------------- + +## Compile c files +recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {build.usb_flags} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" + +## Compile c++ files +recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {build.usb_flags} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" + +## Compile S files +recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.S.flags} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {build.usb_flags} {compiler.S.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" + +## Create archives +# archive_file_path is needed for backwards compatibility with IDE 1.6.5 or older, IDE 1.6.6 or newer overrides this value +archive_file_path={build.path}/{archive_file} +recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}" + +## Combine gc-sections, archives, and objects +recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm + +## Create output files (.eep and .hex) +recipe.objcopy.eep.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.objcopy.eep.flags} {compiler.objcopy.eep.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.eep" +recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex" + +## Save hex +recipe.output.tmp_file={build.project_name}.hex +recipe.output.save_file={build.project_name}.{build.variant}.hex + +## Compute size +recipe.size.pattern=echo "[size not computed for virtual build]" +recipe.size.regex=^.* +recipe.size.regex.data=^.* +recipe.size.regex.eeprom=^.* + +## Preprocessor +preproc.includes.flags=-w -x c++ -M -MG -MP +recipe.preproc.includes="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.includes.flags} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {build.usb_flags} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" + +preproc.macros.flags=-w -x c++ -E -CC +recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.macros.flags} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {build.usb_flags} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{preprocessed_file_path}" + +# AVR Uploader/Programmers tools +# ------------------------------ + +tools.avrdude.path={runtime.tools.avrdude.path} +tools.avrdude.cmd.path={path}/bin/avrdude +tools.avrdude.config.path={path}/etc/avrdude.conf + +tools.avrdude.upload.params.verbose=-v +tools.avrdude.upload.params.quiet=-q -q +tools.avrdude.upload.params.noverify=-V +tools.avrdude.upload.pattern= + +tools.avrdude.program.params.verbose=-v +tools.avrdude.program.params.quiet=-q -q +tools.avrdude.program.params.noverify=-V +tools.avrdude.program.pattern= + +tools.avrdude.erase.params.verbose=-v +tools.avrdude.erase.params.quiet=-q -q +tools.avrdude.erase.pattern= + +tools.avrdude.bootloader.params.verbose=-v +tools.avrdude.bootloader.params.quiet=-q -q +tools.avrdude.bootloader.pattern= + +tools.avrdude_remote.upload.pattern= + +# USB Default Flags +# Default blank usb manufacturer will be filled in at compile time +# - from numeric vendor ID, set to Unknown otherwise +build.usb_manufacturer="Unknown" +build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' diff --git a/x86/variants/virtual/.keep b/x86/variants/virtual/.keep new file mode 100644 index 0000000..2e53e50 --- /dev/null +++ b/x86/variants/virtual/.keep @@ -0,0 +1,3 @@ +This file exists purely so that we can check in the support/x86/variants/virtual + directory to the Git repo. (Git doesn't allow to check in empty folders.) +We need this directory in order to satisfy the Arduino build system.