Vectored I/O with '?KEY and 'EMIT
The basic I/O words ?KEY and EMIT are now vectored, and they can be redefined. This happens automatically in the background task, but this feature can also be used for the console (foreground).
Here is an example for a custom EMIT word:
stm8eForth v2.2
: funEMIT ( c -- ) DUP 64 72 WITHIN -32 * + TX! ; ( change A..G to lowercase ) ok
' funEMIT 'EMIT ! ok
words
funeMIT ReSeT RaM NVM adc adc! OUT! LOcK ULOcK 2c 2c! bSR WORdS
.S dUMP VaRIabLe dOeS> cReaTe IMMedIaTe : caLL, ] ; ." abORT"
afT RePeaT WHILe eLSe THeN If agaIN UNTIL begIN +LOOP LOOP dO
NeXT fOR LITeRaL c, , aLLOT ' [ \ ( .( ? . U. TYPe U.R .R cR
SPaceS SPace NUf? KeY decIMaL HeX eRaSe fILL cMOVe HeRe 2` 2! +!
PIcK 0= abS NegaTe NOT 2/ 1- 1+ 2* 2- 2+ */ */MOd M* * UM* / MOd
/MOd M/MOd UM/MOd WITHIN MIN MaX < U< = dNegaTe 2dUP ROT ?dUP
fILe HaNd bg TIM -1 1 0 bL OUT 'KeY 'eMIT baSe UM+ - 0< OR aNd
XOR + OVeR SWaP dUP >R R` 2dROP dROP I R> c! c@ eXecUTe LeaVe
TX! eMIT ?RX ?KeY hi 'bOOT cOLd ok
The vectors 'EMIT and 'KEY can be set to normal Forth words, and words akin to ?RX and TX! can take the role of device drivers for character I/O. That's almost an operating-system like feature!
Significant binary size reduction
Most core words now make sure that Y=TOS, which means that assembly and STC code can be mixed more easily. Due to a lack of registers in the STM8 architecture there is no true Y=TOS (i.e. no stack manipulation for ( n -- n ) words.
I did a rewrite of many routines in assembly, and I used a new coding method for ( n -- n ) primitives (check for DOXCODE).
All in all the binary size improved quite a but:
- CORE binary size is below 4 KiB (bare-bones for interactive testing, no NVM, background, and reduced vocabulary)
- MINDEV binary size is below 5 KiB (full featured, but not all the basic words of interpreter and compiler linked)
- the size of a binary with a fully linked vocabulary is below 5.5 KiB
As usual, source, new binaries, and additional information are available on the GitHub release page.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
Hi Samuel, vectoring type for implementing buffered I/O makes sense, and reading a buffer would create some sort of "piped I/O". That, together with lightweight threats, would create an even more UNIX-esque programmer experience.
As my current hardware target has very limited memory resources, block I/O isn't on my agenda (yet). However, if I come to block-I/O I'll look into options for lightweight abstraction, too.
Are you sure? yes | no
?RX and !TX definitely provide for device abstraction. I also vector EMIT and ?KEY, but also TYPE and I think I have a word to read a buffer-worth of data as well (I forget now, and too lazy to look it up). For the Kestrel-3, I do have ambitions of evolving the eForth environment into a viable operating system, even going so far as to support multiple address spaces and, almost certainly, virtual machines too.
I'm also going to be revisiting the block I/O facility as well; it'll be a rewrite from what I currently have, implementing more of figFORTH features. Support for multiple storage devices (right now it only supports a single SD card), the variable OFFSET will allow for selecting the "current device", and I'm thinking of introducing a new variable, LIMIT, to ensure a program doesn't accidentally read or write beyond the boundary supported by that device.
Are you sure? yes | no