-
Notifications
You must be signed in to change notification settings - Fork 4
http://mecrisp.sourceforge.net/ Mecrisp-Ice is an enhanced version of Swapforth and the J1a stack processor by James Bowman, featuring three MSP430 style IO ports, a tick counter, constant folding, inlining and tail-call optimisations
License
zuloloxi/mecrisp-ice
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
------------------------------------------------------------------------------- Mecrisp-Ice - A conveniently enhanced fork of Swapforth by James Bowman It makes your Lattice Icestick FPGA development board to behave just like a microcontroller. The original Swapforth and J1a processor implementation can be found here: http://www.excamera.com/sphinx/article-j1a-swapforth.html I would not have been possible without the first open-source FPGA toolchain: http://www.clifford.at/icestorm/ Many, many thanks to James Bowman and the whole Icestorm team ! http://mecrisp.sourceforge.net/ [email protected] ------------------------------------------------------------------------------- HIC SUNT DRACONES - HIC SUNT DRACONES - HIC SUNT DRACONES This is the first experimental release, so beware: Monsters may be inside ! ------------------------------------------------------------------------------- Shortly after Clifford Wolff, Mathias Lasser and Cotton Seed managed to build the first working completely open-source FPGA toolchain for the iCE40-HX1K, James Bowman started porting his elegant J1 processor design. I have been involved in testing and enhanced the resulting monumental work with stronger optimisations and a handfull of features for convenience. ------------------------------------------------------------------------------- What you need: * A Lattice Icestick with an iCE40-HX1K FPGA http://www.latticesemi.com/icestick * Or a Nandland Go with iCE40-HX1K FPGA https://www.nandland.com/goboard/introduction.html * Or a Lattice HX8K breakout board with an iCE40-HX8K FPGA * The Iceprog tool to flash the included binary http://www.clifford.at/icestorm/ * A terminal, picocom is fine. ------------------------------------------------------------------------------- Which board for you ? If you just wish to play with a stack processor, if you have small ideas, if you desire to have IrDA communication, if you wish a cheap, cool looking board, if you are fine without tinkering with additional logic --> HX1K Icestick is your choice. If you wish to experiment with VGA video, if you like 7-segment displays, if you need buttons on your board --> HX1K Nandland Go should be the right for you. If you have large ideas in Forth, if you need a lot of IO pins, if you wish to wire in additional peripherals, opcodes or whatever you imagine, if you love to have single cycle multiplier and barrel shifters --> HX8K breakout board will give you a nice time. ------------------------------------------------------------------------------- Basic usage, same for HX1K and HX8K: Flash the binary: iceprog -b j1a.bin Open a terminal: picocom -b 115200 /dev/ttyUSB$n --imap lfcrlf,crcrlf --omap delbs,crlf --send-cmd "ascii-xfr -s -l 30 -n" Toggle DTR line to Reset by pressing Crtl+A Ctrl+T Crtl+A Ctrl+T You should get a welcome message. If you hard crash it, iceprog -t or a power cycle should recover. ------------------------------------------------------------------------------- Some notes for Forth users new to this target and its peripheral possibilities: The Icestick has 8 kb of initialised RAM which is mapped from address $0000 to $1FFF and a SPI flash to store the FPGA bitstream and additional user generated memory images. Data and return stack are 16 elements deep. James implemented them as part of the CPU itself, so they are not accessible through memory. Pinout and board layout: /-------------------------------------- / Header 1: 76543210-+ / ________ ++ / | | R -- [USB] FT | FPGA | R G R 73 Ir [USB] DI | | R 62 DA \ |________| 51 \ 40 \ Header 2: 01234567-+ \-------------------------------------- Numbers are bit numbers + is 3.3 V - is GND G Green LED R Red LEDs There is a separate IO address space, with those registers available: Addr Bit READ WRITE 0001 0 PMOD in 0002 1 PMOD out PMOD out 0004 2 PMOD dir PMOD dir 0008 3 misc.out misc.out 0010 4 header 1 in 0020 5 header 1 out header 1 out 0040 6 header 1 dir header 1 dir 0080 7 eint 0100 8 header 2 in 0200 9 header 2 out header 2 out 0400 10 header 2 dir header 2 dir 0800 11 dint 1000 12 UART RX UART TX 2000 13 misc.in 4000 14 ticks clear ticks 8000 15 Contents of misc.out and misc.in: Bitmask Bit misc.out misc.in 0001 0 SPI CS UART Ready to Transmit 0002 1 SPI MOSI UART Character received 0004 2 SPI SCK SPI MISO 0008 3 IrDA-TXD IrDA-RXD 0010 4 IrDA-Sleep RTS 0020 5 CTS Random 0040 6 Green LED 0080 7 Red LED 0100 8 Red LED 0200 9 Red LED 0400 10 Red LED If you are already familiar with MSP430 chips, you will know this IO port style: * The IN register gives the current electrical state * The contents of the OUT registers determine what level the outputs should be * The DIR register let you switch a pin to be an output by writing an one into You can set two registers at once if you OR together their addresses. 255 $440 io! should set all header pins as outputs. Inputs can ORed together the same way and give an ORed result. You can detect short-circuited pins - for example if a pin is set to output and low, but shortened to Vcc, then the OUT register will read back low, as set by you, but the IN register will read high for that pin. Misc.out and misc.in are a mixed back of wires and flags available. No fear to destroy the IrDA transceiver with too long pulses as it turns off the IR LED itself when IrDA-TXD is high for more than 50 us. The UART data register is for both incoming and outgoing data, a read from it will clear the "Character received" flag and you should only write to it when "Ready to Transmit" is set. Ticks contains a 16 bit cycle counter that counts up with 48 MHz and you can set it to any value you wish by writing to it. Memory location $1FFE is an interrupt vector for the ticks counter overflow. You can place an opcode there, perhaps ALU Exit ($608C) or a JMP to a handler. Interrupts can be enabled with eint and disabled with dint. ------------------------------------------------------------------------------- Notes on HX8K: -------------- This feels very similiar to Mecrisp-Ice on HX1K, just with a few differences: + Double amount of memory: 16 kb instead of 8 kb + Double stack depth: 32 elements each instead of 16 + Barrel shifter for single cycle lshift rshift arshift + Single cycle multiplication + Fast opcodes for 1+ and 1- + rdepth + 8 LEDs instead of 5 + Lots of gates free for experiments - 36 MHz only - No IrDA - Variable @ needs 2 instructions and 5 cycles instead of 1 instruction and 2 cycles The peripheral map is the same, but the IN, OUT and DIR registers are up to 16 bits wide, with the following connections: $0001 Port A IN $0010 Port B IN $0100 Port C IN $0002 Port A OUT $0020 Port B OUT $0200 Port C OUT $0004 Port A DIR $0040 Port B DIR $0400 Port C DIR Red LEDs 76543210 1.2V 3.3V oo oo oo 1.2V B13 oo oo oo A12 B12 oo ________ oo oo GND GND oo | | oo oo A11 B11 oo | FPGA | oo oo A10 B10 oo | | oo oo A9 B9 oo |________| oo oo GND GND oo oo oo A8 B8 oo oo oo A7 B7 oo oo oo A6 B6 oo Jumper config: oo oo GND GND oo oo oo A5 B5 oo | || oo oo A4 B4 oo oo oo A3 B3 oo Green oo oo GND GND oo LED oo oo A2 B2 oo FT oo oo A1 B1 oo DI oo oo A0 B0 oo oo oo GND GND oo [USB] oo oo [USB] Port C is currently unconnected, you can wire the bits as you wish in the constraints PCF file. Ticks contains a 16 bit cycle counter that counts up with 36 MHz and you can set it to any value you wish by writing to it. Memory location $3FFE is an interrupt vector for the ticks counter overflow. You can place an opcode there, perhaps ALU Exit ($608C) or a JMP to a handler. Interrupts can be enabled with eint and disabled with dint. ------------------------------------------------------------------------------- Notes on Nandland Go: --------------------- S4 is Reset button, as DTR line is not connected on this board. Addr Bit READ WRITE 0001 0 PMOD in 0002 1 PMOD out PMOD out 0004 2 PMOD dir PMOD dir 0008 3 misc.out misc.out 0010 4 VGA Colours 0020 5 VGA HSYNC 0040 6 VGA VSYNC 0080 7 Segments Segments 0100 8 0200 9 0400 10 0800 11 1000 12 UART RX UART TX 2000 13 misc.in 4000 14 ticks clear ticks 8000 15 Contents of misc.out and misc.in: Bitmask Bit misc.out misc.in 0001 0 SPI CS UART Ready to Transmit 0002 1 SPI MOSI UART Character received 0004 2 SPI SCK SPI MISO 0008 3 Green LED 1 Random 0010 4 Green LED 2 S1 0020 5 Green LED 3 S2 0040 6 Green LED 4 S3 Note that you can OR together the VGA lines. VSYNC HSYNC Blue 2 Blue 1 Blue 0 Green 2 Green 1 Green 0 Red 2 Red 1 Red 0 $10: 256 128 64 32 16 8 4 2 1 $20: 512 $40: 1024 So by writing IO Register $60, you can set HSYNC and VSYNC independently from the colour register bits. If you prefer to have all VGA signals in one register, use IO port $70. Ticks contains a 16 bit cycle counter that counts up with 25 MHz and you can set it to any value you wish by writing to it. Memory location $1FFE is an interrupt vector for the ticks counter overflow. You can place an opcode there, perhaps ALU Exit ($608C) or a JMP to a handler. Interrupts can be enabled with eint and disabled with dint. ------------------------------------------------------------------------------- Special features included in Mecrisp-Ice: ----------------------------------------- You can save the complete current memory contents into the SPI flash sectors 1 to 63. Sector 0 contains the FPGA bitstream, sector 1 will be loaded automatically on startup if you save a memory image into this. sector# load sector# save sector# erase There is a variable "init" which is executed after loading an image. So if you wish to create a turnkey application, prepare everything in RAM and type: ' fireworks init ! 1 save Replace fireworks with whatever you wish to be executed on startup. Nothing is executed if init contains a zero, which is the default. If you are not sure if it will work properly, save to any other sector and load manually. The init mechanism works the same on all sectors. On HX8K: Sectors 0, 1 and 2 contain the bitstream. Sector 3 will be loaded automatically if available. The Nandland Go has a smaller SPI Flash with four sectors only: 0: Bitstream 1: Autoload 2: Free 3: Free ----------------------------------------- For your convenience, some introspection features are preloaded for default. Things to try: 0 8192 dump insight see + They will be removed by typing "new" so that you have more space available. ----------------------------------------- Inline optimisations and constant folding are included ! ------------------------------------------------------------------------------- Main differences to Mecrisp and Mecrisp-Stellaris: Unlike Mecrisp and Mecrisp-Stellaris, this is running completely in RAM memory. So there is no need for special memory handling ! You can use CREATE with DOES> and if you need a buffer, just CREATE ... ALLOT it. By the way: If you save a memory image, the last contents of the variables are saved during the process and reloaded with the image. Variables are initialised, but there is no logic to reinitialise them on Reset to the values assigned at compilation. ------------------------------------------------------------------------------- If you wish to build the whole package yourself: * Gforth * Freepascal * Yosys for synthesis * Arachne-PNR for place and route * Icestorm tools for bitstream generation ... and their dependencies. In a nutshell, you need to type: compile iceprog -b j1a.bin That's all. ;------------------------------------------------------------------------------ Here comes a word list, -- Glossary -- with short descriptions of all currently included words: View it with fixed-width font ! ;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------ ; Terminal-IO ;------------------------------------------------------------------------------ emit? ( -- Flag ) Ready to send a character ? key? ( -- Flag ) Checks if a key is waiting key ( -- Char ) Waits for and fetches the pressed key emit ( Char -- ) Emits a character. ;------------------------------------------------------------------------------ ; Stack Jugglers ;------------------------------------------------------------------------------ Single-Jugglers: depth ( -- +n ) Gives number of single-cell stack items. rdepth ( -- +n ) HX8K only: Number of items on return stack. nip ( x1 x2 -- x2 ) drop ( x -- ) rot ( x1 x2 x3 -- x2 x3 x1 ) -rot ( x1 x2 x3 -- x3 x1 x2 ) swap ( x1 x2 -- x2 x1 ) tuck ( x1 x2 -- x2 x1 x2 ) over ( x1 x2 -- x1 x2 x1 ) ?dup ( x -- 0 | x x ) dup ( x -- x x ) >r ( x -- ) (R: -- x ) r> ( -- x ) (R: x -- ) r@ ( -- x ) (R: x -- x ) rdrop ( -- ) (R: x -- ) Double-Jugglers: They perform the same for double numbers. 2drop ( x1 x2 -- ) 2swap ( x1 x2 x3 x4 -- x3 x4 x1 x2 ) 2over ( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 ) 2dup ( x1 x2 -- x1 x2 x1 x2 ) ;------------------------------------------------------------------------------ ; Logic ;------------------------------------------------------------------------------ arshift ( x1 u -- x2 ) Arithmetric right-shift of u bit-places rshift ( x1 u -- x2 ) Logical right-shift of u bit-places lshift ( x1 u -- x2 ) Logical left-shift of u bit-places invert ( x1 -- x2 ) Invert all bits not ( x1 -- x2 ) Invert all bits = Bitwise not xor ( x1 x2 -- x3 ) Bitwise Exclusive-OR or ( x1 x2 -- x3 ) Bitwise OR and ( x1 x2 -- x3 ) Bitwise AND false ( -- 0 ) False-Flag true ( -- -1 ) True-Flag ;------------------------------------------------------------------------------ ; Arithmetic for single numbers ;------------------------------------------------------------------------------ /mod ( n1 n2 -- n3 n4 ) n1 / n2 = n4 rem n3 mod ( n1 n2 -- n3 ) n1 / n2 = remainder n3 / ( n1 n2 -- n3 ) n1 / n2 = n3 * ( u1|n1 u2|n2 -- u3|n3 ) 16*16 = 16 Multiplication min ( n1 n2 -- n1|n2 ) Keeps smaller of top two items max ( n1 n2 -- n1|n2 ) Keeps greater of top two items umin ( u1 u2 -- u1|u2 ) Keeps unsigned smaller umax ( u1 u2 -- u1|u2 ) Keeps unsigned greater 1- ( u1|n1 -- u2|n2 ) Subtracts one, optimized 1+ ( u1|n1 -- u2|n2 ) Adds one, optimized 2* ( n1 -- n2 ) Arithmetric left-shift 2/ ( n1 -- n2 ) Arithmetric right-shift abs ( n -- u ) Absolute value negate ( n1 -- n2 ) Negate sgn ( u1 n1 -- n2 ) Give u1 the sign of n2 - ( u1|n1 u2|n2 -- u3|n3 ) Subtraction + ( u1|n1 u2|n2 -- u3|n3 ) Addition ;------------------------------------------------------------------------------ ; Arithmetic involving double numbers ;------------------------------------------------------------------------------ um* ( u1 u2 -- ud ) 16*16 = 32 Multiplication um/mod ( ud u1 -- u2 u3 ) ud / u1 = u3 remainder u2 m+ ( d1 n -- d2 ) Addition of a double with a single m* ( n1 n2 -- d ) n1 * n2 = d fm/mod ( d n1 -- n2 n3 ) d / n1 = n3 remainder r2 floored sm/rem ( d n1 -- n2 n3 ) d / n1 = n3 remainder r2 symmetric */ ( n1 n2 n3 -- n4 ) n1 * n2 / n3 = n4 */mod ( n1 n2 n3 -- n4 n5 ) n1 * n2 / n3 = n5 remainder n4 d2* ( d1 -- d2 ) Arithmetric left-shift dabs ( d -- ud ) Absolute value dnegate ( d1 -- d2 ) Negate d- ( ud1|d1 ud2|d2 -- ud3|d3 ) Subtraction d+ ( ud1|d1 ud2|d2 -- ud3|d3 ) Addition s>d ( n -- d ) Makes a signed single number double length ;------------------------------------------------------------------------------ ; Comparisions ;------------------------------------------------------------------------------ u<= ( u1 u2 -- flag ) Unsigned comparisions u>= ( u1 u2 -- flag ) u> ( u1 u2 -- flag ) u< ( u1 u2 -- flag ) <= ( n1 n2 -- flag ) Signed comparisions >= ( n1 n2 -- flag ) > ( n1 n2 -- flag ) < ( n1 n2 -- flag ) 0> ( n -- flag ) Positive ? 0< ( n -- flag ) Negative ? 0<> ( x -- flag ) 0= ( x -- flag ) <> ( x1 x2 -- flag ) = ( x1 x2 -- flag ) d0= ( d -- flag ) within ( x1 x2 x3 -- ? ) Check if x1 is within x2 and x3. ;------------------------------------------------------------------------------ ; Tools for number input ;------------------------------------------------------------------------------ number ( c-addr len -- 0 ) -- n 1 ) -- n-low n-high 2 ) Tries to convert a string to a number. ;------------------------------------------------------------------------------ ; Number base ;------------------------------------------------------------------------------ binary ( -- ) Sets base to 2 decimal ( -- ) Sets base to 10 hex ( -- ) Sets base to 16 base ( -- a-addr ) Base variable address ;------------------------------------------------------------------------------ ; Memory access ;------------------------------------------------------------------------------ cmove ( c-addr1 c-addr2 u -- ) Moves backward cmove> ( c-addr1 c-addr2 u -- ) Moves forward move ( c-addr1 c-addr2 u -- ) Moves u Bytes in Memory fill ( c-addr u c ) Fill u Bytes of Memory with value c constant name ( u|n -- ) Makes a single constant. variable name ( u|n -- ) Makes an initialized single variable 2@ ( a-addr -- ud|d ) Fetches double number from memory 2! ( ud|d a-addr -- ) Stores double number in memory @ ( a-addr -- u|n ) Fetches single number from memory ! ( u|n a-addr -- ) Stores single number in memory +! ( u|n a-addr -- ) Add to memory location c@ ( c-addr -- char ) Fetches byte from memory c! ( char c-addr ) Stores byte in memory IO memory area: io@ ( c-addr -- x ) Fetches from IO register io! ( x c-addr -- ) Stores into IO register xor! ( mask c-addr -- ) Toggle bits bic! ( mask c-addr -- ) Clear BIts bis! ( mask c-addr -- ) Set BIts ;------------------------------------------------------------------------------ ; Strings and beautiful output ;------------------------------------------------------------------------------ String routines: type ( c-addr length -- ) Prints a string. rtype ( c-addr length u -- ) Prints a string in a field u characters wide. s" Hello" Compiles a string and ( -- c-addr length ) gives back its address and length when executed. ." Hello" Compiles a string and ( -- ) prints it when executed. ( Comment ) Ignore Comment \ Comment Comment to end of line cr ( -- ) Emits line feed bl ( -- 32 ) ASCII code for Space space ( -- ) Emits space spaces ( n -- ) Emits n spaces if n is positive accept ( c-addr maxlength -- length ) Read input into a string. Counted string routines: count ( cstr-addr -- c-addr length ) Convert counted string into addr-length string Pictured numerical output: [char] * Compiles code of following char ( -- char ) when executed char * ( -- char ) gives code of following char hold ( char -- ) Adds character to pictured number output buffer from the front. sign ( n -- ) Add a minus sign to pictured number output buffer, if n is negative #S ( ud1|d1 -- 0 0 ) Add all remaining digits from the double length number to output buffer # ( ud1|d1 -- ud2|d2 ) Add one digit from the double length number to output buffer #> ( ud|d -- c-addr len ) Drops double-length number and finishes pictured numeric output ready for type <# ( -- ) Prepare pictured number output buffer u. ( u -- ) Print unsigned single number . ( n -- ) Print single number ud. ( ud -- ) Print unsigned double number d. ( d -- ) Print double number u.r ( u width -- ) Print unsigned right aligned .r ( n width -- ) Print signed right aligned d.r ( d width -- ) Print double signed right aligned buf0 ( -- a-addr ) Start of number output buffer buf ( -- a-addr ) End of number output buffer hld ( -- a-addr ) Variable with current position Deep insights: words ( -- ) Prints list of defined words. .x2 ( c -- ) Prints 8 bit unsigned in hex base .x ( u -- ) Prints 16 bit unsigned in hex base This is independent of number subsystem. ;------------------------------------------------------------------------------ ; User input and its interpretation ;------------------------------------------------------------------------------ tib ( -- c-addr ) Input buffer pad ( -- c-addr ) Location to hold temporary data refill ( -- ? ) Refill input buffer, return true if successful source! ( c-addr len -- ) Change source source ( -- c-addr len ) Current source >in ( -- addr ) Variable with current offset into source /string ( c-addr1 u1 n -- c-addr2 u2 ) Cut n leading characters parse-name ( -- c-addr len ) Get next token from input buffer parse ( char -- c-addr len ) Cuts anything delimited by char out of input buffer evaluate ( any addr len -- any ) Interpret given string quit ( many -- ) (R: many -- ) Resets Stacks abort ( many -- ) (R: many -- ) Print ? and quit ;------------------------------------------------------------------------------ ; Dictionary expansion ;------------------------------------------------------------------------------ align ( -- ) Aligns dictionary pointer aligned ( c-addr -- a-addr ) Advances to next aligned address cell+ ( x -- x+2 ) Add size of one cell cells ( n -- 2*n ) Calculate size of n cells allot ( n -- ) Tries to advance Dictionary Pointer by n bytes here ( -- a-addr|c-addr ) Gives current position in Dictionary , ( u|n -- ) Appends a single number to dictionary c, ( char -- ) Appends a byte to dictionary unused ( -- u ) How many free space is still available ? cornerstone name Create a permanent dictionary wayback point new Core wayback point. ;------------------------------------------------------------------------------ ; Dictionary expansion (more internal) ;------------------------------------------------------------------------------ s, ( c-addr len -- ) Inserts a string with a maximum of 255 characters without runtime sliteral ( c-addr len -- ) Insert a string with runtime literal ( u|n -- ) Compiles a literal compile, ( a-addr -- ) Compiles a call to a subroutine forth ( -- a-addr ) Variable with entry point for dictionary ahead ( -- a-addr ) Prepare a forward jump ;------------------------------------------------------------------------------ ; Flags and inventory ;------------------------------------------------------------------------------ immediate ( -- ) Makes current definition immediate. foldable ( n -- ) Current word becomes foldable with n constants sfind ( c-addr len -- c-addr len 0 | a-addr flags ) Searches for a string in Dictionary. ;------------------------------------------------------------------------------ ; Compiler essentials ;------------------------------------------------------------------------------ execute ( a-addr -- ) Calls subroutine recurse ( -- ) Lets the current definition call itself ' name ( -- a-addr ) Tries to find name in dictionary gives back executable address ['] name ( -- a-addr) Tick that compiles the executable address of found word as literal postpone name ( -- ) Helps compiling immediate words. does> ( -- ) executes: ( -- a-addr ) Gives address to where you have stored data. create name ( -- ) Create a definition with default action >body ( a-addr -- a-addr ) Address of data field after create state ( -- a-addr ) Address of state variable ] ( -- ) Switch to compile state [ ( -- ) Switch to execute state ; ( -- ) Finishes new definition : name ( -- ) Opens new definition :noname ( -- a-addr ) Opens new definition without name ;------------------------------------------------------------------------------ ; Control structures ;------------------------------------------------------------------------------ Decisions: flag if ... then flag if ... else ... then then ( -- ) This is the common else ( -- ) flag if ... [else ...] then if ( flag -- ) structure. Case: n case m1 of ... endof m2 .. ... ..... all others endcase case ( n -- n ) Begins case structure of ( m -- ) Compares m with n, choose this if n=m endof ( -- ) End of one possibility endcase ( n -- ) Ends case structure, discards n Indefinite Loops: begin ... again begin ... flag until begin ... flag while ... repeat repeat ( -- ) Finish of a middle-flag-checking loop. while ( flag -- ) Check a flag in the middle of a loop until ( flag -- ) begin ... flag until loops as long flag is true again ( -- ) begin ... again is an endless loop begin ( -- ) Definite Loops: limit index do ... [one or more leave(s)] ... loop ?do ... [one or more leave(s)] ... loop do ... [one or more leave(s)] ... n +loop ?do ... [one or more leave(s)] ... n +loop j ( -- u|n ) Gives second loop index i ( -- u|n ) Gives innermost loop index unloop (R: old-limit old-index -- ) Drops innermost loop structure, pops back old loop structures to loop registers exit ( -- ) Returns from current definition. leave ( -- ) (R: old-limit old-index -- ) Leaves current innermost loop promptly +loop ( u|n -- ) (R: unchanged | old-limit old-index -- ) Adds number to current loop index register and checks whether to continue or not loop ( -- ) (R: unchanged | old-limit old-index -- ) Increments current loop index register by one and checks whether to continue or not. ?do ( Limit Index -- ) (R: unchanged | -- old-limit old-index ) Begins a loop if limit and index are not equal do ( Limit Index -- ) (R: -- old-limit old-index ) Begins a loop bounds ( addr len -- limit index ) Calculate values to loop over a string ;------------------------------------------------------------------------------ ; SPI and low-level flash memory access ;------------------------------------------------------------------------------ spix ( c1 -- c2 ) Exchange one byte on SPI >spi ( c -- ) Send one byte to SPI spi> ( -- c ) Receive one byte from SPI idle ( -- ) Set SPI flash to idle state spiwe ( -- ) Write enable on SPI flash waitspi ( -- ) Wait for write or erase to finish ;------------------------------------------------------------------------------ ; Memory images ;------------------------------------------------------------------------------ Sectors from 1 to 63. Sector 1 is automatically loaded after Reset. load ( sector# -- ) Loads an image save ( sector# -- ) Saves an image erase ( sector# -- ) Erase an image init ( -- a-addr ) Variable containing either zero or the address of a turnkey definition which is executed automatically ;------------------------------------------------------------------------------ ; Misc hardware ;------------------------------------------------------------------------------ leds ( x -- ) Display bitpattern on LEDs ms ( u -- ) Wait u milliseconds ticks ( -- u ) Read current ticks now ( -- ) Clear tick counter delay ( u -- ) Wait until u ticks are reached randombit ( -- 0 | 1 ) Gives a random bit random ( -- x ) Gives a random number eint? ( -- ? ) Are interrupts enabled ? eint ( -- ) Enable ticks counter overflow interrupt dint ( -- ) Disable interrupt ;------------------------------------------------------------------------------ ; Insight tools that are gone after NEW ;------------------------------------------------------------------------------ .s ( many -- many ) Prints stack contents dump ( addr len -- ) Dump memory contents insight ( -- ) Complete printout of dictionary structure name. ( a-addr -- ) If this is the code-start of a definition, try to print its name. memstamp ( a-addr -- ) Show memory location nicely disasm-$ ( -- a-addr ) Variable for current disasm position disasm-cont ( -- a-addr ) Variable: Continue up to this position disasm-step ( -- ) Disassemble one more instruction seec ( -- ) Continue to see at disasm-$ see name ( -- ) See the definition Matthias Koch, Summer 2015
About
http://mecrisp.sourceforge.net/ Mecrisp-Ice is an enhanced version of Swapforth and the J1a stack processor by James Bowman, featuring three MSP430 style IO ports, a tick counter, constant folding, inlining and tail-call optimisations
Resources
License
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published