diff --git a/Makefile b/Makefile index b1237b6..b02f9ca 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,7 @@ msp430: AR := msp430-elf-gcc-ar msp430: CXXFLAGS += -I. -I/usr/msp430-elf/usr/include msp430: CXXFLAGS += -Os -mmcu=msp430fr2476 -ffunction-sections -fdata-sections msp430: CXXFLAGS += -flto -fno-asynchronous-unwind-tables -fno-threadsafe-statics -fno-stack-protector +msp430: CXXFLAGS += -DALEE_MSP430_HOST msp430: LDFLAGS += -L msp430 -T msp430fr2476.ld -Wl,-gc-sections -Wl,--no-warn-rwx-segments msp430: msp430/alee-msp430 diff --git a/alee-standalone.cpp b/alee-standalone.cpp index 2ab9b71..9f5eae5 100644 --- a/alee-standalone.cpp +++ b/alee-standalone.cpp @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -#include "alee.hpp" +#include "libalee/alee.hpp" #include "splitmemdict.hpp" #include diff --git a/alee.cpp b/alee.cpp index 5aba851..cc9abde 100644 --- a/alee.cpp +++ b/alee.cpp @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -#include "alee.hpp" +#include "libalee/alee.hpp" #include "memdict.hpp" #include diff --git a/alee.hpp b/alee.hpp deleted file mode 100644 index 87991bb..0000000 --- a/alee.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "libalee/parser.hpp" -#include "libalee/state.hpp" - diff --git a/libalee/alee.hpp b/libalee/alee.hpp new file mode 100644 index 0000000..7b46845 --- /dev/null +++ b/libalee/alee.hpp @@ -0,0 +1,7 @@ +#include "config.hpp" +#include "corewords.hpp" +#include "ctype.hpp" +#include "dictionary.hpp" +#include "parser.hpp" +#include "state.hpp" +#include "types.hpp" diff --git a/libalee/config.hpp b/libalee/config.hpp new file mode 100644 index 0000000..20d0950 --- /dev/null +++ b/libalee/config.hpp @@ -0,0 +1,5 @@ +#ifndef ALEE_MSP430_HOST +#define LIBALEE_SECTION +#else +#define LIBALEE_SECTION __attribute__((section(".libalee"))) +#endif diff --git a/libalee/corewords.cpp b/libalee/corewords.cpp index e3ba6b3..b768163 100644 --- a/libalee/corewords.cpp +++ b/libalee/corewords.cpp @@ -16,11 +16,11 @@ * along with this program. If not, see . */ -#include "corewords.hpp" -#include "parser.hpp" +#include "alee.hpp" #include +LIBALEE_SECTION void find(State& state, Word word) { Cell tok = 0; @@ -37,6 +37,7 @@ void find(State& state, Word word) state.push(imm); } +LIBALEE_SECTION void CoreWords::run(Cell ins, State& state) { Cell cell; @@ -252,6 +253,7 @@ execute: ip += sizeof(Cell); } +LIBALEE_SECTION Cell CoreWords::findi(State& state, Word word) { return findi(word.begin(&state.dict), word.size()); diff --git a/libalee/corewords.hpp b/libalee/corewords.hpp index d5c35ea..f4ab851 100644 --- a/libalee/corewords.hpp +++ b/libalee/corewords.hpp @@ -19,9 +19,9 @@ #ifndef ALEEFORTH_COREWORDS_HPP #define ALEEFORTH_COREWORDS_HPP -#include "ctype.hpp" +#include "config.hpp" #include "types.hpp" -#include "state.hpp" +#include "dictionary.hpp" /** * To be implemented by the user, this function is called when the `sys` word @@ -61,6 +61,7 @@ public: private: template + LIBALEE_SECTION constexpr static Cell findi(Iter it, std::size_t size) { const char *ptr = CoreWords::wordsarr; diff --git a/libalee/ctype.hpp b/libalee/ctype.hpp index 499a90f..b0df174 100644 --- a/libalee/ctype.hpp +++ b/libalee/ctype.hpp @@ -43,6 +43,10 @@ constexpr inline bool isupper(uint8_t c) { return c >= 'A' && c <= 'Z'; } +constexpr inline bool islower(uint8_t c) { + return c >= 'a' && c <= 'z'; +} + constexpr inline bool isalpha(uint8_t c) { return isupper(c) || (c >= 'a' && c <= 'z'); } diff --git a/libalee/dictionary.cpp b/libalee/dictionary.cpp index a86531d..b98b312 100644 --- a/libalee/dictionary.cpp +++ b/libalee/dictionary.cpp @@ -16,8 +16,9 @@ * along with this program. If not, see . */ -#include "dictionary.hpp" +#include "alee.hpp" +LIBALEE_SECTION void Dictionary::initialize() { write(Base, 10); @@ -27,6 +28,7 @@ void Dictionary::initialize() write(Source, Input + sizeof(Cell)); } +LIBALEE_SECTION Addr Dictionary::allot(Cell amount) noexcept { Addr old = here(); @@ -41,22 +43,26 @@ Addr Dictionary::allot(Cell amount) noexcept return old; } +LIBALEE_SECTION void Dictionary::add(Cell value) noexcept { write(allot(sizeof(Cell)), value); } +LIBALEE_SECTION Addr Dictionary::aligned(Addr addr) { return (addr + (sizeof(Cell) - 1)) & ~(sizeof(Cell) - 1); } +LIBALEE_SECTION Addr Dictionary::alignhere() noexcept { here(aligned(here())); return here(); } +LIBALEE_SECTION void Dictionary::addDefinition(Word word) noexcept { Cell wsize = word.size(); @@ -75,6 +81,7 @@ void Dictionary::addDefinition(Word word) noexcept alignhere(); } +LIBALEE_SECTION Addr Dictionary::find(Word word) noexcept { Addr lt = latest(); @@ -106,6 +113,7 @@ Addr Dictionary::find(Word word) noexcept return 0; } +LIBALEE_SECTION Addr Dictionary::getexec(Addr addr) noexcept { const Addr l = read(addr); @@ -119,6 +127,7 @@ Addr Dictionary::getexec(Addr addr) noexcept return aligned(addr); } +LIBALEE_SECTION bool Dictionary::hasInput() const noexcept { const Addr src = read(Dictionary::Source); @@ -140,6 +149,7 @@ bool Dictionary::hasInput() const noexcept return false; } +LIBALEE_SECTION Word Dictionary::input() noexcept { const Addr src = read(Dictionary::Source); @@ -169,11 +179,13 @@ Word Dictionary::input() noexcept return Word(wstart, wend); } +LIBALEE_SECTION bool Dictionary::equal(Word word, const char *str, unsigned len) const noexcept { return word.size() == len && equal(word.begin(this), word.end(this), str); } +LIBALEE_SECTION bool Dictionary::equal(Word word, Word other) const noexcept { return word.size() == other.size() && equal(word.begin(this), word.end(this), other.begin(this)); diff --git a/libalee/dictionary.hpp b/libalee/dictionary.hpp index 96db2ea..27edf68 100644 --- a/libalee/dictionary.hpp +++ b/libalee/dictionary.hpp @@ -19,8 +19,9 @@ #ifndef ALEEFORTH_DICTIONARY_HPP #define ALEEFORTH_DICTIONARY_HPP -#include "ctype.hpp" +#include "config.hpp" #include "types.hpp" +#include "ctype.hpp" #include #include @@ -72,10 +73,14 @@ struct Dictionary */ void initialize(); + LIBALEE_SECTION Addr here() const noexcept { return read(Here); } + LIBALEE_SECTION void here(Addr l) noexcept { write(Here, l); } + LIBALEE_SECTION Addr latest() const noexcept { return read(Latest); } + LIBALEE_SECTION void latest(Addr l) noexcept { write(Latest, l); } // Aligns the given address. @@ -124,6 +129,7 @@ struct Dictionary // Used for case-insensitive comparison between two iterators. template + LIBALEE_SECTION constexpr static bool equal(Iter1 b1, Iter1 e1, Iter2 b2) { return std::equal(b1, e1, b2, eqchars); } @@ -132,6 +138,7 @@ struct Dictionary private: // Case-insensitive comparison. + LIBALEE_SECTION constexpr static bool eqchars(char c1, char c2) { if (isalpha(static_cast(c1))) c1 |= 32; @@ -140,7 +147,6 @@ private: return c1 == c2; } - }; #endif // ALEEFORTH_DICTIONARY_HPP diff --git a/libalee/parser.cpp b/libalee/parser.cpp index 19aa5f7..b3e8211 100644 --- a/libalee/parser.cpp +++ b/libalee/parser.cpp @@ -16,12 +16,11 @@ * along with this program. If not, see . */ -#include "corewords.hpp" -#include "ctype.hpp" -#include "parser.hpp" +#include "alee.hpp" Error (*Parser::customParse)(State&, Word) = nullptr; +LIBALEE_SECTION Error Parser::parse(State& state, const char *str) { auto addr = Dictionary::Input; @@ -40,6 +39,7 @@ Error Parser::parse(State& state, const char *str) return parseSource(state); } +LIBALEE_SECTION Error Parser::parseSource(State& state) { auto err = Error::none; @@ -50,6 +50,7 @@ Error Parser::parseSource(State& state) return err; } +LIBALEE_SECTION Error Parser::parseWord(State& state, Word word) { bool imm; @@ -81,6 +82,7 @@ Error Parser::parseWord(State& state, Word word) return Error::none; } +LIBALEE_SECTION Error Parser::parseNumber(State& state, Word word) { const auto base = state.dict.read(Dictionary::Base); @@ -113,6 +115,7 @@ Error Parser::parseNumber(State& state, Word word) return Error::none; } +LIBALEE_SECTION void Parser::processLiteral(State& state, Cell value) { if (state.compiling()) { diff --git a/libalee/parser.hpp b/libalee/parser.hpp index f868afb..6b50918 100644 --- a/libalee/parser.hpp +++ b/libalee/parser.hpp @@ -19,7 +19,9 @@ #ifndef ALEEFORTH_PARSER_HPP #define ALEEFORTH_PARSER_HPP +#include "config.hpp" #include "types.hpp" +#include "state.hpp" #include diff --git a/libalee/state.cpp b/libalee/state.cpp index df785e0..ed1562f 100644 --- a/libalee/state.cpp +++ b/libalee/state.cpp @@ -16,31 +16,35 @@ * along with this program. If not, see . */ -#include "corewords.hpp" -#include "state.hpp" +#include "alee.hpp" #include +LIBALEE_SECTION bool State::compiling() const { return dict.read(Dictionary::Compiling); } +LIBALEE_SECTION void State::compiling(bool yes) { dict.write(Dictionary::Compiling, yes); } +LIBALEE_SECTION State::Context State::save() { return context; } +LIBALEE_SECTION void State::load(const State::Context& ctx) { context = ctx; } +LIBALEE_SECTION Error State::execute(Addr addr) { auto stat = static_cast(setjmp(context.jmpbuf)); @@ -63,6 +67,7 @@ Error State::execute(Addr addr) return stat; } +LIBALEE_SECTION void State::reset() { while (size()) @@ -74,11 +79,13 @@ void State::reset() context.ip = 0; } +LIBALEE_SECTION std::size_t State::size() const noexcept { return dsp - dstack; } +LIBALEE_SECTION std::size_t State::rsize() const noexcept { return rsp - rstack; diff --git a/libalee/state.hpp b/libalee/state.hpp index e77a223..0ac9a7c 100644 --- a/libalee/state.hpp +++ b/libalee/state.hpp @@ -19,6 +19,7 @@ #ifndef ALEEFORTH_STATE_HPP #define ALEEFORTH_STATE_HPP +#include "config.hpp" #include "dictionary.hpp" #include "types.hpp" @@ -57,10 +58,12 @@ public: */ void reset(); + LIBALEE_SECTION Addr& ip() noexcept { return context.ip; } + LIBALEE_SECTION void input() noexcept { inputfunc(*this); } @@ -82,42 +85,50 @@ public: */ void load(const Context&); + LIBALEE_SECTION inline void push(Cell value) { verify(dsp < dstack + DataStackSize, Error::push); *dsp++ = value; } + LIBALEE_SECTION inline Cell pop() { verify(dsp > dstack, Error::pop); return *--dsp; } + LIBALEE_SECTION inline void pushr(Cell value) { verify(rsp < rstack + ReturnStackSize, Error::pushr); *rsp++ = value; } + LIBALEE_SECTION inline Cell popr() { verify(rsp > rstack, Error::popr); return *--rsp; } + LIBALEE_SECTION inline Cell& top() { verify(dsp > dstack, Error::top); return *(dsp - 1); } + LIBALEE_SECTION inline Cell& pick(std::size_t i) { verify(dsp - i > dstack, Error::pick); return *(dsp - i - 1); } // Advances the instruction pointer and returns that cell's contents. + LIBALEE_SECTION inline Cell beyondip() { context.ip += sizeof(Cell); return dict.read(context.ip); } + LIBALEE_SECTION inline void verify(bool condition, Error error) { if (!condition) std::longjmp(context.jmpbuf, static_cast(error)); diff --git a/libalee/types.cpp b/libalee/types.cpp index 83cf1f7..7ac67c7 100644 --- a/libalee/types.cpp +++ b/libalee/types.cpp @@ -16,30 +16,34 @@ * along with this program. If not, see . */ -#include "dictionary.hpp" -#include "types.hpp" +#include "alee.hpp" +LIBALEE_SECTION Addr Word::size() const noexcept { return wend - start; } +LIBALEE_SECTION Word::iterator Word::begin(const Dictionary *dict) { return iterator(start, dict); } +LIBALEE_SECTION Word::iterator Word::end(const Dictionary *dict) { return iterator(wend, dict); } +LIBALEE_SECTION Word::iterator& Word::iterator::operator++() { addr++; return *this; } +LIBALEE_SECTION Word::iterator Word::iterator::operator++(int) { const auto copy = *this; @@ -47,12 +51,15 @@ Word::iterator Word::iterator::operator++(int) return copy; } +LIBALEE_SECTION Word::iterator::value_type Word::iterator::operator*() { return dict->readbyte(addr); } +LIBALEE_SECTION bool Word::iterator::operator!=(const iterator& other) { return dict != other.dict || addr != other.addr; } + diff --git a/libalee/types.hpp b/libalee/types.hpp index 4d86c5d..028c490 100644 --- a/libalee/types.hpp +++ b/libalee/types.hpp @@ -61,6 +61,7 @@ public: constexpr explicit Word(Addr s = 0, Addr e = 0): start(s), wend(e) {} + LIBALEE_SECTION static constexpr Word fromLength(Addr s, Addr l) { return Word(s, s + l); } diff --git a/memdict.hpp b/memdict.hpp index c88bc7d..003b3a7 100644 --- a/memdict.hpp +++ b/memdict.hpp @@ -19,7 +19,7 @@ #ifndef ALEEFORTH_MEMDICT_HPP #define ALEEFORTH_MEMDICT_HPP -#include "alee.hpp" +#include "libalee/alee.hpp" #ifndef MEMDICTSIZE #define MEMDICTSIZE (65536) diff --git a/msp430/alee-msp430.cpp b/msp430/alee-msp430.cpp index 07ad80b..51f63f8 100644 --- a/msp430/alee-msp430.cpp +++ b/msp430/alee-msp430.cpp @@ -16,8 +16,7 @@ * along with this program. If not, see . */ -#include "alee.hpp" -#include "libalee/ctype.hpp" +#include "libalee/alee.hpp" #include "lzss.h" static const #include "msp430fr2476_all.h" @@ -41,7 +40,9 @@ static void initUART(); static void Software_Trim(); #define MCLK_FREQ_MHZ (16) -#define ALEE_RODICTSIZE (9400) +static void alee_main(); + +#define ALEE_RODICTSIZE (9088) __attribute__((section(".lodict"))) #include "core.fth.h" @@ -55,11 +56,23 @@ static auto& dict = *(new (__dict) DictType (alee_dat, 0x10000)); int main() { WDTCTL = WDTPW | WDTHOLD; + + extern char __libaleebegin; + extern char __libaleeend; + extern char __libaleedst; + std::copy(&__libaleebegin, &__libaleeend, &__libaleedst); + initGPIO(); initClock(); initUART(); SYSCFG0 = FRWPPW; + alee_main(); +} + +LIBALEE_SECTION +void alee_main() +{ (void)alee_dat_len; State state (dict, readchar); Parser::customParse = findword; @@ -105,6 +118,7 @@ int main() } } +LIBALEE_SECTION void readchar(State& state) { auto idx = state.dict.read(Dictionary::Input); @@ -117,18 +131,21 @@ void readchar(State& state) state.dict.writebyte(addr, c ? c : ' '); } +LIBALEE_SECTION void serput(int c) { while (!(UCA0IFG & UCTXIFG)); UCA0TXBUF = static_cast(c); } +LIBALEE_SECTION void serputs(const char *s) { while (*s) serput(*s++); } +LIBALEE_SECTION void printint(DoubleCell n, char *buf, int base) { static const char digit[] = "0123456789ABCDEF"; @@ -152,6 +169,7 @@ void printint(DoubleCell n, char *buf, int base) serput(' '); } +LIBALEE_SECTION void user_sys(State& state) { switch (state.pop()) { @@ -191,6 +209,11 @@ void user_sys(State& state) case 17: exitLpm |= true; break; + case 50: + Parser::customParse = nullptr; + extern char _etext; + state.push((Addr)&_etext); + break; default: break; } @@ -208,7 +231,7 @@ Error findword(State& state, Word word) uint8_t *ptr = lzword; for (auto it = word.begin(&state.dict); it != word.end(&state.dict); ++it) { *ptr = *it; - if (!isupper(*ptr)) + if (islower(*ptr)) *ptr -= 32; ++ptr; } diff --git a/msp430/msp430fr2476.ld b/msp430/msp430fr2476.ld index 574a76b..a65f652 100644 --- a/msp430/msp430fr2476.ld +++ b/msp430/msp430fr2476.ld @@ -44,7 +44,7 @@ MEMORY { BOOTCODE : ORIGIN = 0x1C00, LENGTH = 0x0400 /* END=0x1FFF, size 1024 */ ROMLIB : ORIGIN = 0xC0000, LENGTH = 0x4000 /* END=0xC3FFF, size 16384 */ BSL1 : ORIGIN = 0xFFC00, LENGTH = 0x0400 /* END=0xFFFFF, size 1024 */ - RAM : ORIGIN = 0x2000, LENGTH = 0x2000 /* END=0x3FFF, size 8192 */ + RAM (rwx) : ORIGIN = 0x2000, LENGTH = 0x2000 /* END=0x3FFF, size 8192 */ INFOMEM : ORIGIN = 0x1800, LENGTH = 0x0200 /* END=0x19FF, size 512 */ FRAM (rwx) : ORIGIN = 0x8000, LENGTH = 0x7F80 /* END=0xFF7F, size 32640 */ HIFRAM (rxw) : ORIGIN = 0x10000, LENGTH = 0x00007FFF @@ -218,6 +218,14 @@ SECTIONS PROVIDE (__dict = .); } > TINYRAM + .libalee : { + . = ALIGN(2); + PROVIDE (__libaleedst = .); + *(.libalee) + } > RAM AT> FRAM + PROVIDE(__libaleebegin = LOADADDR(.libalee)); + PROVIDE (__libaleeend = LOADADDR(.libalee) + SIZEOF(.libalee)); + .data : { . = ALIGN(2); @@ -295,11 +303,14 @@ SECTIONS KEEP (*(.init)) KEEP (*(.fini)) KEEP (*(.tm_clone_table)) + + . = ALIGN(2); + PROVIDE (_etext = .); } > FRAM .lodict : { - . = ALIGN(2); + . = ALIGN(1024); *(.lodict) } > FRAM diff --git a/splitmemdict.hpp b/splitmemdict.hpp index 730d103..1093fbc 100644 --- a/splitmemdict.hpp +++ b/splitmemdict.hpp @@ -19,7 +19,7 @@ #ifndef ALEEFORTH_SPLITMEMDICT_HPP #define ALEEFORTH_SPLITMEMDICT_HPP -#include "alee.hpp" +#include "libalee/alee.hpp" #include diff --git a/splitmemdictrw.hpp b/splitmemdictrw.hpp index dc02ab9..21fd142 100644 --- a/splitmemdictrw.hpp +++ b/splitmemdictrw.hpp @@ -19,7 +19,7 @@ #ifndef ALEEFORTH_SPLITMEMDICTRW_HPP #define ALEEFORTH_SPLITMEMDICTRW_HPP -#include "alee.hpp" +#include "libalee/alee.hpp" #include