diff --git a/Makefile b/Makefile index d33a1b0..d6c6eff 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,8 @@ CXXFILES := $(wildcard libalee/*.cpp) OBJFILES := $(subst .cpp,.o,$(CXXFILES)) LIBFILE := libalee/libalee.a +STANDALONE := forth/core.fth + all: alee msp430: CXX := msp430-elf-g++ @@ -16,6 +18,9 @@ msp430: CXXFLAGS += -DMEMDICTSIZE=128 -flto -fno-asynchronous-unwind-tables -fno msp430: LDFLAGS += -L/usr/msp430-elf/usr/include -Tmsp430/msp430g2553.ld -Wl,-gc-sections msp430: clean-lib msp430/alee-msp430 +msp430-prep: STANDALONE += forth/msp430.fth +msp430-prep: core.fth.h + small: CXXFLAGS += -Os -fno-asynchronous-unwind-tables -fno-threadsafe-statics -fno-stack-protector small: alee @@ -42,8 +47,8 @@ core.fth.h: alee.dat xxd -i $< > $@ sed -i "s/unsigned /static const &/" $@ -alee.dat: alee forth/core.fth - echo "3 sys" | ./alee forth/core.fth +alee.dat: alee $(STANDALONE) + echo "3 sys" | ./alee $(STANDALONE) clean: clean-lib rm -f alee alee-standalone msp430/alee-msp430 diff --git a/README.md b/README.md index 148d51d..434136e 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,16 @@ # Alee Forth -Alee is a concise Forth implementation written in modern C++ that aims for portability, minimal program size, and execution efficiency. +Alee Forth is a concise Forth implementation written in modern C++ that aims for portability, minimal program size, and execution efficiency. ## Cross-platform compatibility -Alee relies on the C++17 standard. Alee *does not* rely on operating-system-specific functions, making portability easy. +Alee Forth relies on the C++20 standard. It *does not* rely on any operating system. As a result, portability extends down to microcontroller targets with < 1 kB of memory. See the `msp430` folder for an example of such a port. -The goal of portability extends down to microcontroller targets with kilobytes of memory. See the `msp430` target for an example of a port. - -System-specific functionality is obtained through a `sys` Forth word. This word calls a user-supplied C++ function that implements the necessary (or any additional) functionality. +System-specific functionality is obtained through a `sys` Forth word. This word calls a user-supplied C++ function that implements whatever functionality is needed. ## Forth compatibility -Alee implements a large majority of the "core" and "core extension" [word sets](https://forth-standard.org/standard/core). Implementation is tracked in `compat.txt`, with missing words listed below. Fundamental words are built into Alee (written in C++); the rest of the implementation is in `core.fth` and `core-ext.fth`. - -Running Alee without `core.fth` or `core-ext.fth` passed as arguments will leave you with a minimal word set. The `standalone` target will package the `core.fth` dictionary into the program. +Alee implements a large majority of the "core" and "core extension" [word-sets](https://forth-standard.org/standard/core). Implementation is tracked in `compat.txt` with missing words listed below. Fundamental words are hard-coded into Alee while the rest of the implementation is found in `forth/core.fth` and `forth/core-ext.fth`. Running Alee without these implementation files will leave you with a very minimal word-set. These files may be compiled into the Alee binary by building the `standalone` target. **Missing** core features: * Pictured numeric output conversion (e.g. `<# #>`) @@ -24,18 +20,18 @@ Running Alee without `core.fth` or `core-ext.fth` passed as arguments will leave .R HOLDS PAD PARSE PARSE-NAME REFILL RESTORE-INPUT S\" SAVE-INPUT SOURCE-ID U.R U> UNUSED WITHIN [COMPILE] ``` -Alee aims for compliance with common Forth standards like Forth 2012 and ANS Forth. Compliance is tested using a [Forth 2012 test suite](https://github.com/gerryjackson/forth2012-test-suite). Supported test files are in the `test` directory, with tests for unimplemented words commented out. +Alee aims for compliance with common Forth standards like Forth 2012 and ANS Forth. Compliance is tested using a [Forth 2012 test suite](https://github.com/gerryjackson/forth2012-test-suite). Supported test files are in the `test` directory with tests for unimplemented words commented out. ## Building -Alee requires `make` and a C++17-compatible compiler. Simply running `make` will produce the `libalee.a` library and a REPL binary named `alee`. Note that this binary has no built-in libraries; these can be passed in by calling `./alee core.fth core-ext.fth`. +Alee requires `make` and a compiler that supports C++20. Simply running `make` will produce the `libalee.a` library and a REPL binary named `alee`. You will likely want to pass in the core implementation files by calling `./alee forth/core.fth forth/core-ext.fth`. -There are other build targets: +Other available build targets: * `small`: Optimize for minimal binary size. * `fast`: Optimize for maximum performance on the host system. * `standalone`: Builds the core dictionary (`core.fth`) into the binary. -* `msp430`: Builds a binary for the [MSP430G2553](https://www.ti.com/product/MSP430G2553) microcontroller. The `standalone` target must be built first for the core dictionary. +* `msp430-prep` and `msp430`: Builds a binary for the [MSP430G2553](https://www.ti.com/product/MSP430G2553) microcontroller. See the `msp430` folder for more information. -If building for a new platform, see `Makefile`, `types.hpp`, and `state.hpp` for available configuration options. +If building for a new platform, review these files: `Makefile`, `libalee/types.hpp`, and `libalee/state.hpp`. diff --git a/forth/msp430.fth b/forth/msp430.fth new file mode 100644 index 0000000..1497e04 --- /dev/null +++ b/forth/msp430.fth @@ -0,0 +1,110 @@ +: r! 3 sys ; +: r@ 4 sys ; + +: rset dup r@ rot | swap r! ; +: rclr dup r@ rot invert & swap r! ; +: rtgl dup r@ rot ^ swap r! ; + +16 base ! + +: ie1 0000 ; +: ifg1 0002 ; +: ie2 0001 ; +: ifg2 0003 ; +: adc10dtc0 0048 ; +: adc10dtc1 0049 ; +: adc10ae0 004a ; +: adc10ctl0 01b0 ; +: adc10ctl1 01b2 ; +: adc10mem 01b4 ; +: adc10sa 01bc ; +: dcoctl 0056 ; +: bcsctl1 0057 ; +: bcsctl2 0058 ; +: bcsctl3 0053 ; +: cactl1 0059 ; +: cactl2 005a ; +: capd 005b ; +: fctl1 0128 ; +: fctl2 012a ; +: fctl3 012c ; +: p1in 0020 ; +: p1out 0021 ; +: p1dir 0022 ; +: p1ifg 0023 ; +: p1ies 0024 ; +: p1ie 0025 ; +: p1sel 0026 ; +: p1sel2 0041 ; +: p1ren 0027 ; +: p2in 0028 ; +: p2out 0029 ; +: p2dir 002a ; +: p2ifg 002b ; +: p2ies 002c ; +: p2ie 002d ; +: p2sel 002e ; +: p2sel2 0042 ; +: p2ren 002f ; +: p3in 0018 ; +: p3out 0019 ; +: p3dir 001a ; +: p3sel 001b ; +: p3sel2 0043 ; +: p3ren 0010 ; +: ta0iv 012e ; +: ta0ctl 0160 ; +: ta0cctl0 0162 ; +: ta0cctl1 0164 ; +: ta0cctl2 0166 ; +: ta0r 0170 ; +: ta0ccr0 0172 ; +: ta0ccr1 0174 ; +: ta0ccr2 0176 ; +: ta1iv 011e ; +: ta1ctl 0180 ; +: ta1cctl0 0182 ; +: ta1cctl1 0184 ; +: ta1cctl2 0186 ; +: ta1r 0190 ; +: ta1ccr0 0192 ; +: ta1ccr1 0194 ; +: ta1ccr2 0196 ; +: uca0ctl0 0060 ; +: uca0ctl1 0061 ; +: uca0br0 0062 ; +: uca0br1 0063 ; +: uca0mctl 0064 ; +: uca0stat 0065 ; +: uca0rxbuf 0066 ; +: uca0txbuf 0067 ; +: uca0abctl 005d ; +: uca0irtctl 005e ; +: uca0irrctl 005f ; +: ucb0ctl0 0068 ; +: ucb0ctl1 0069 ; +: ucb0br0 006a ; +: ucb0br1 006b ; +: ucb0i2cie 006c ; +: ucb0stat 006d ; +: ucb0rxbuf 006e ; +: ucb0txbuf 006f ; +: ucb0i2coa 0118 ; +: ucb0i2csa 011a ; +: wdtctl 0120 ; +: caldco_16mhz 10f8 ; +: calbc1_16mhz 10f9 ; +: caldco_12mhz 10fa ; +: calbc1_12mhz 10fb ; +: caldco_8mhz 10fc ; +: calbc1_8mhz 10fd ; +: caldco_1mhz 10fe ; +: calbc1_1mhz 10ff ; +: tlv_checksum 10c0 ; +: tlv_dco_30_tag 10f6 ; +: tlv_dco_30_len 10f7 ; +: tlv_adc10_1_tag 10da ; +: tlv_adc10_1_len 10db ; + +decimal + diff --git a/msp430/README.md b/msp430/README.md new file mode 100644 index 0000000..34d2ddb --- /dev/null +++ b/msp430/README.md @@ -0,0 +1,20 @@ +# msp430 implementation + +This is the MSP430 port of Alee Forth. It produces a binary that enters a REPL made available on the UART peripheral at 115200 baud. The specific target is MSP430G2553. + +## Building + +1. `make clean` (just in case) +2. `make msp430-prep`: Builds `alee` for the host computer and uses it to create an `alee.dat` blob containing bytecode for `forth/core.fth` and `forth/msp430.fth`. +3. `make msp430`: Produces `alee-msp430`, a standalone binary for the MSP430 with built-in core and msp430 word-sets. + +The final binary is < 11 kB and provides 150 bytes for user dictionary in RAM (assuming 512 bytes of total RAM). + +## msp430.fth + +The msp430 word-set makes programming for the MSP430 easier: + +* All register names are defined (P1OUT, ADC10MEM, etc.). +* `r!` and `r@` to write and read device memory (i.e. registers). +* `rset`, `rclr`, `rtgl` work like `r!` but set, clear, or toggle the given value/mask instead. + diff --git a/msp430/alee-msp430.cpp b/msp430/alee-msp430.cpp index 3d660a7..6328419 100644 --- a/msp430/alee-msp430.cpp +++ b/msp430/alee-msp430.cpp @@ -36,15 +36,15 @@ int main() { WDTCTL = WDTPW | WDTHOLD; DCOCTL = 0; - BCSCTL1 = CALBC1_1MHZ; - DCOCTL = CALDCO_1MHZ; + BCSCTL1 = CALBC1_16MHZ; + DCOCTL = CALDCO_16MHZ; P1SEL |= BIT1 | BIT2; P1SEL2 |= BIT1 | BIT2; UCA0CTL1 = UCSWRST; UCA0CTL1 |= UCSSEL_2; - UCA0BR0 = 104; + UCA0BR0 = 139; UCA0BR1 = 0; UCA0MCTL = UCBRS0; UCA0CTL1 &= (uint8_t)~UCSWRST;