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/ m-atthias@users.sf.net
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
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:
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.
This feels very similiar to Mecrisp-Ice on HX1K, just with a few differences:
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.
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.
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:
... 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