diff --git a/alee.cpp b/alee.cpp index a154017..5aba851 100644 --- a/alee.cpp +++ b/alee.cpp @@ -25,7 +25,6 @@ #include #ifdef ALEE_MSP430 -#include #include "lzss.h" static const #include "msp430fr2476_all.h" @@ -190,7 +189,7 @@ Error findword(State& state, Word word) if (c != LZSS_MAGIC_SEPARATOR) { *lzptr++ = (char)c; } else { - if (lzwlen == lzptr - lzbuf - 2 && strncmp(lzword, lzbuf, lzptr - lzbuf - 2) == 0) { + if (lzwlen == lzptr - lzbuf - 2 && std::equal(lzbuf, lzptr - 2, lzword)) { lzwlen = (*(lzptr - 2) << 8) | *(lzptr - 1); return 1; } else { diff --git a/libalee/corewords.hpp b/libalee/corewords.hpp index 25f6a6e..d5c35ea 100644 --- a/libalee/corewords.hpp +++ b/libalee/corewords.hpp @@ -19,11 +19,10 @@ #ifndef ALEEFORTH_COREWORDS_HPP #define ALEEFORTH_COREWORDS_HPP +#include "ctype.hpp" #include "types.hpp" #include "state.hpp" -#include - /** * To be implemented by the user, this function is called when the `sys` word * is executed. @@ -42,7 +41,7 @@ public: */ static Cell findi(State&, Word); consteval static Cell findi(const char *word) { - return findi(word, std::strlen(word)); + return findi(word, strlen(word)); } /** @@ -67,7 +66,7 @@ private: const char *ptr = CoreWords::wordsarr; for (Cell wordsi = 0; wordsi < WordCount; ++wordsi) { - std::size_t wordsize = std::strlen(ptr); + std::size_t wordsize = strlen(ptr); if (wordsize == size && Dictionary::equal(ptr, ptr + wordsize, it)) return wordsi; diff --git a/libalee/ctype.hpp b/libalee/ctype.hpp index 878c747..499a90f 100644 --- a/libalee/ctype.hpp +++ b/libalee/ctype.hpp @@ -25,6 +25,12 @@ #include +constexpr inline unsigned strlen(const char * const s) { + unsigned i = 0; + while (s[i]) i++; + return i; +} + constexpr inline bool isspace(uint8_t c) { return c == ' ' || c == '\t' || c == '\r' || c == '\n'; } diff --git a/libalee/dictionary.cpp b/libalee/dictionary.cpp index 6c359bd..a86531d 100644 --- a/libalee/dictionary.cpp +++ b/libalee/dictionary.cpp @@ -18,8 +18,6 @@ #include "dictionary.hpp" -#include - void Dictionary::initialize() { write(Base, 10); diff --git a/libalee/parser.cpp b/libalee/parser.cpp index 3236ae2..19aa5f7 100644 --- a/libalee/parser.cpp +++ b/libalee/parser.cpp @@ -20,16 +20,13 @@ #include "ctype.hpp" #include "parser.hpp" -#include -#include - Error (*Parser::customParse)(State&, Word) = nullptr; Error Parser::parse(State& state, const char *str) { auto addr = Dictionary::Input; - const auto len = static_cast(std::strlen(str)); + const auto len = static_cast(strlen(str)); state.dict.write(addr, 0); state.dict.write(Dictionary::SourceLen, len); @@ -95,7 +92,7 @@ Error Parser::parseNumber(State& state, Word word) ++it; const auto end = word.end(&state.dict); - for (char c; it != end; ++it) { + for (uint8_t c; it != end; ++it) { c = *it; if (isdigit(c)) { diff --git a/libalee/state.cpp b/libalee/state.cpp index 6e12999..df785e0 100644 --- a/libalee/state.cpp +++ b/libalee/state.cpp @@ -19,7 +19,6 @@ #include "corewords.hpp" #include "state.hpp" -#include #include bool State::compiling() const diff --git a/msp430/alee-msp430.cpp b/msp430/alee-msp430.cpp index c270612..07ad80b 100644 --- a/msp430/alee-msp430.cpp +++ b/msp430/alee-msp430.cpp @@ -22,7 +22,6 @@ static const #include "msp430fr2476_all.h" -#include #include #include "splitmemdictrw.hpp" @@ -40,9 +39,9 @@ static void initGPIO(); static void initClock(); static void initUART(); static void Software_Trim(); -#define MCLK_FREQ_MHZ (8) // MCLK = 8MHz +#define MCLK_FREQ_MHZ (16) -#define ALEE_RODICTSIZE (9200) +#define ALEE_RODICTSIZE (9400) __attribute__((section(".lodict"))) #include "core.fth.h" @@ -50,10 +49,8 @@ static bool exitLpm; static Addr isr_list[24] = {}; using DictType = SplitMemDictRW; - -alignas(DictType) -static unsigned char dictbuf[sizeof(DictType)]; -static auto dict = reinterpret_cast(dictbuf); +extern char __dict[sizeof(DictType)]; +static auto& dict = *(new (__dict) DictType (alee_dat, 0x10000)); int main() { @@ -64,9 +61,7 @@ int main() SYSCFG0 = FRWPPW; (void)alee_dat_len; - dict->lodict = alee_dat; - dict->hidict = 0x10000; - State state (*dict, readchar); + State state (dict, readchar); Parser::customParse = findword; serputs("alee forth\n\r"); @@ -203,17 +198,17 @@ void user_sys(State& state) #define LZSS_MAGIC_SEPARATOR (0xFB) -static char lzword[32]; +static uint8_t lzword[32]; static int lzwlen; -static char lzbuf[32]; -static char *lzptr; +static uint8_t lzbuf[32]; +static uint8_t *lzptr; Error findword(State& state, Word word) { - char *ptr = lzword; + uint8_t *ptr = lzword; for (auto it = word.begin(&state.dict); it != word.end(&state.dict); ++it) { *ptr = *it; - if (islower(*ptr)) + if (!isupper(*ptr)) *ptr -= 32; ++ptr; } @@ -224,9 +219,9 @@ Error findword(State& state, Word word) auto ret = decode([](int c) { if (c != LZSS_MAGIC_SEPARATOR) { - *lzptr++ = (char)c; + *lzptr++ = (uint8_t)c; } else { - if (lzwlen == lzptr - lzbuf - 2 && strncmp(lzword, lzbuf, lzptr - lzbuf - 2) == 0) { + if (lzwlen == lzptr - lzbuf - 2 && std::equal(lzbuf, lzptr - 2, lzword)) { lzwlen = (*(lzptr - 2) << 8) | *(lzptr - 1); return 1; } else { @@ -271,35 +266,47 @@ void initGPIO() void initClock() { - __bis_SR_register(SCG0); // disable FLL - CSCTL3 |= SELREF__REFOCLK; // Set REFO as FLL reference source - CSCTL1 = DCOFTRIMEN_1 | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_3;// DCOFTRIM=3, DCO Range = 8MHz - CSCTL2 = FLLD_0 + 243; // DCODIV = 8MHz + static_assert(MCLK_FREQ_MHZ == 16); + + // Configure one FRAM waitstate as required by the device datasheet for MCLK + // operation beyond 8MHz _before_ configuring the clock system. + FRCTL0 = FRCTLPW | NWAITS_1; + + P2SEL0 |= BIT0 | BIT1; // P2.0~P2.1: crystal pins + do + { + CSCTL7 &= ~(XT1OFFG | DCOFFG); // Clear XT1 and DCO fault flag + SFRIFG1 &= ~OFIFG; + } while (SFRIFG1 & OFIFG); // Test oscillator fault flag + + __bis_SR_register(SCG0); // disable FLL + CSCTL3 |= SELREF__XT1CLK; // Set XT1 as FLL reference source + CSCTL1 = DCOFTRIMEN_1 | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_5;// DCOFTRIM=5, DCO Range = 16MHz + CSCTL2 = FLLD_0 + 487; // DCOCLKDIV = 16MHz __delay_cycles(3); - __bic_SR_register(SCG0); // enable FLL - Software_Trim(); // Software Trim to get the best DCOFTRIM value + __bic_SR_register(SCG0); // enable FLL + Software_Trim(); // Software Trim to get the best DCOFTRIM value + + CSCTL4 = SELMS__DCOCLKDIV | SELA__XT1CLK; // set XT1 (~32768Hz) as ACLK source, ACLK = 32768Hz + // default DCOCLKDIV as MCLK and SMCLK source - CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK; // set default REFO(~32768Hz) as ACLK source, ACLK = 32768Hz - // default DCODIV as MCLK and SMCLK source } void initUART() { // Configure UART pins - P5SEL0 |= BIT1 | BIT2; // set 2-UART pin as second function - SYSCFG3|=USCIA0RMP; //Set the remapping source - // Configure UART + P5SEL0 |= BIT1 | BIT2; + SYSCFG3 |= USCIA0RMP; // Set the remapping source + UCA0CTLW0 |= UCSWRST; - UCA0CTLW0 |= UCSSEL__SMCLK; + UCA0CTLW0 |= UCSSEL__SMCLK; // 16 MHz // Baud Rate calculation - // 8000000/(16*9600) = 52.083 - // Fractional portion = 0.083 - // User's Guide Table 17-4: UCBRSx = 0x49 - // UCBRFx = int ( (52.083-52)*16) = 1 - UCA0BR0 = 52; // 8000000/16/9600 - UCA0BR1 = 0x00; - UCA0MCTLW = 0x4900 | UCOS16 | UCBRF_1; + // N = 16MHz / 115200 = 138.888 + // OS16 = 1, UCBRx = INT(N/16) = 8(.6806) + // UCBRFx = INT( ((N/16) - UCBRx) * 16) = 10(.8896) + UCA0BRW = 8; + UCA0MCTLW = 0xD600 | 0x00A0 | UCOS16; UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI } @@ -378,7 +385,7 @@ bool alee_isr_handle(unsigned index) const Addr isr = isr_list[index]; if (isr != 0) { - State isrstate (*dict, readchar); + State isrstate (dict, readchar); exitLpm = false; isrstate.execute(isr); return exitLpm; @@ -418,3 +425,6 @@ DEFINE_ISR(TIMER1_A0_VECTOR, 21) DEFINE_ISR(TIMER0_A1_VECTOR, 22) DEFINE_ISR(TIMER0_A0_VECTOR, 23) +// Override newlib's free to save hundreds of bytes +extern "C" void free(void *) {} + diff --git a/msp430/msp430fr2476.ld b/msp430/msp430fr2476.ld index 08b0299..574a76b 100644 --- a/msp430/msp430fr2476.ld +++ b/msp430/msp430fr2476.ld @@ -214,7 +214,9 @@ SECTIONS KEEP (*(.dtors)) } > FRAM - .tinyram : {} > TINYRAM + .tinyram : { + PROVIDE (__dict = .); + } > TINYRAM .data : { diff --git a/splitmemdictrw.hpp b/splitmemdictrw.hpp index 7fcb5cd..dc02ab9 100644 --- a/splitmemdictrw.hpp +++ b/splitmemdictrw.hpp @@ -40,7 +40,6 @@ public: return *this; } - virtual Cell read(Addr addr) const noexcept final { if (addr < LON) return *reinterpret_cast(lodict + addr); @@ -72,6 +71,9 @@ public: virtual unsigned long int capacity() const noexcept final { return LON + HIN; } + +private: + virtual ~SplitMemDictRW() override {}; }; #endif // ALEEFORTH_SPLITMEMDICTRW_HPP