Change log for sam7 emforth
Note that the new items are at the bottom.
Added a vocabulary stack.
Moved words into their correct vocab - eg FORTH, assembler, compiler, runtime etc.
The kernel uses the vocabs - FORTH, RUNTIME, COMPILER and ASSEMBLER.
The words : ; CODE and END-CODE modify the vocab stack by adding or removing the compiler or assembler vocabs.
Now V1.08 and files are in the gallery.
V1.09 - The word "FORGET" was changed to handle the multiple vocabs. Previous versions (non-ARM) didn't use FORGET but had a word "REMEMBER" which saved and restored the state of all the vocabs. FORGET assumes the words have been compiled in order ie building from low memory to high. It will not work if the dictionary pointer has be modified by an advanced user to point to a different memory area.
The baud rate has been changed from 38.4 kbd to 115 kbd.
<BUILDS DOES> construct added.
Object and message pointers (ROP and RMP) defined as registers R8 and R9.
Words OP! OP@ MP! MP@ defined.
More object and message stack words defined - eg >M M> GMESSAGE etc.
Words for sending serial packets ported from HC16 forth and mostly converted from assembler to FORTH.
Global messages for comms defined.
205774 error 205750 int32 20572C real32 205708 eof
2056E4 write 2056C0 read 20569C append 205678 close
205654 open 205630 hit 205608 getnumbe 2055E4 key
2055BC getline 20559C cr 205578 type 205554 emit
Ported memory manager.
EMserver with file system support
Serial terminal and file client ported from HC16 forth.
File descriptor data structures changed to 32 bit.
Code modified so forth can work in either dumb terminal or serial client mode.
Text capture and text redirect to file tested and working.
Can now compile from PC files via emserver. Files can be nested - ie include files can be in source files or in other include files.
Ported enough serial client stuff from sitting on top of the kernel to being part of it. This is needed to allow a self rebuild via emserver.
The meta-compilation uses three source file.
arm.for is the kernel - once compiled the kernel is booted in high memory.
reloc.for mainly moves the kernel into low memory and patches a bunch of addresses then runs it.
extra.for contains the extras like memdump and assembler.
The files are chained automatically.
Typing SOURCE ARM.FOR does the complete build.
A build takes about 25 seconds as opposed to 10 minutes the old way (hyper-terminal)
There is a minor problem with file buffers getting left open on the server.
Emforth can still work in dumb terminal mode as well.
Binary and source for emforth V1.19 uploaded to the file gallery.
Note the binary has not been tested - the ram image works but the binary save hasn't been verified.
Also released my 1992 vintage emserver - note this needs real serial ports not USB adaptors.
There seems to be a bug in 1.19 and an error (like a word not being found) causes a reboot.
Above bug fixed by added a separate *COLD vector and well as *ABORT.
V1.19 zip replaces with V1.20 in the file gallery.
The binaries have been tested with sam-ba and work.
I tried unsuccessfully to run V1.20 on an olimex SAM7-EX256 evaluation kit.
The main problem was USART1 is not connected.
I now have forth (v1.23) pinging both com ports and selecting the correct port when it get a response.
Emforth now runs on the new board.
The SAM7-EX256 uses a SAM7X256 not SAM7S256 like the header PCB.
This has messed things up because not only is the external hardware different but the chip itself has the USART sharing pins with different I/O lines.
For now I've enabled all six possible lines but in future I'll probably use the processor ID on reset to selects the correct lines.
I also need to do some sort of conditional compilation to cope with the external hardware changes - for example the new board does not have a LED on PA8 - instead PA8 goes to a joystick switch.
I now use the CPU ID during boot to select the correct i/o pins for serial comms.
However there is a problem self writing to flash. Every second flash page I wrote was blank.
Adding a delay between writing pages fixed this. This should not be necessary as I am waiting for the "ready" bit after each page write.
Some simple words are now coded as inline assembler instead of calls to forth words.
The words are - INVERT NEGATE 2/ 2* 1- 1+ SWAPDROP C@ @
There are now compile time (immediate) versions of these words in the COMPILER vocabulary so
be careful NOT to have the vocabulary loaded when trying to use these words interpretively.
A crude way to conditionally compile for different hardware has been added.
For now the word is called "IFDO" and it is really NOT-IF-(
Basically if TOP is false it ignores the rest of the line.
Probably near the top of file main file define the PCB type.
0 CONSTANT GENERIC // define some constants to identify different PCBs
1 CONSTANT H256
2 CONSTANT EX256
EX256 CONSTANT PCBTYPE // set the PCB type to the PCB you want.
// some time later.
PCBTYPE H256 = IFDO INCLUDE H256.DEF
PCBTYPE EX256 = IFDO INCLUDE EX256.DEF
PCBTYPE GENERIC = IFDO INCLUDE GENERIC.DEF
So the file EX256.DEF get compiled.
The type GENERIC compiles a version without any LED pin enabled so there will be no conflict if you are moving to hardware with something else connected to that pin.
A major change. Prior to V1.30 the top two stack elements were kept in registers now only TOP is in a register. This was a non-trivial change which has taken days to debug. Around 40 words had to redefined and that was bug free but there were a lot of other dependencies which caused the meta-compiler to fail.
Almost all the changed words are shorter but a couple such as store (!) are longer. Overall I'm sure it will be a little quicker. The reason I made the change is several common words ( eg DUP and DROP ) can now be compiled inline without increasing the code size.
It should also be possible to compile many literal values inline in two words. This is the same size as needed now but will execute much faster.
A while back (V1.35),
Changed tick (ie ' ) to return the code address not the link field address (LFA) - this is more standard.
Added 'LFA which does what tick used to do - searches for a word and returns the LFA.
Also DUP and DROP are compiled inline.
24 Sept 07, (Ver 1.41)
Variables separated from kernel code as a step towards having a version which can run in flash.
The vocabulary words (FORTH etc) also need to be changed so they don't need to be in RAM.
Vocab words (FORTH etc) now have the rewritable pointers separated from the kernel.
The kernel could now be relocated to flash.
The workings of the <BUILDS DOES> construct changed to eliminate absolute links in the code it generates. Previously each instance of a word created by a <BUILDS DOES> type constructor contained and absolute link to the "does" part of the code. This has been replaced by a relative BRLNK instruction.
The down side is it takes one extra clock cycle to execute.
The reason for the change is that every absolute address has to be patched when moving the code to a different address - such as relocating it to FLASH.
The kernel can now run in FLASH or RAM (tested and working).
A major rewrite of the <BUILDS DOES> mechanism. DOES> is now an immediate (compiler) word.
The runtime code which pushes the data location onto the stack in now embedded into the constructor.
The constructed words are one word (4 bytes) shorter and should execute a little faster.
The "message" structure has been made simpler.
Formerly the structure contained a link to separate linked list so messages could be search for regardless of which vocab they were in - now I assume all messages are in the MESSAGES vocab.
The structure also had a link back to the name field for fast conversion from a message number to it's name.
Now I do a much slower search for it. The name is rarely needed expect for interactive queries and error handling where speed is not necessary. These changes plus the new <BUILDS DOES> mechanism saves 3 words (12 bytes) per message definition.
V1.58 online. v158notes
I've a added RLITERAL and [RLIT] , these are relative literals.
A normal literal stores the absolute value of the literal after the call to [LIT]
RLITERAL stores a relative value instead and calls [RLIT]
In ordinary use they give the same result except the absolute version is slightly faster.
The difference is when the code is moved to a different location as happens during the meta-compile (ie system rebuild) or when the system in moved into flash.
Formerly if a literal was used to reference a location in the kernel it would no longer do so is the kernel was moved. This resulted is many words needing to be patched.
For example the word VARIABLE had to be patched so new variables called the moved version of [VAR]
Using RLITERAL for these kinds of things eliminates a lot of work when building new systems.
Ultimately it may be possible to make the entire FORTH system relocatable.
This may make it possible to have one binary which boots on ARM based devices with different memory maps.
SAM7 is not the only game in town.
Added a code word " LINK@ ". This figures out whether a link is relative or absolute based on whether the LSBit is set and returns the appropriate value.
This assumes links always point to even address - as is normally the case.
Added a colon word " LINK! " - this is like " ! " except to converts the address to be saved to a relative link.
Modified " LFA>CA " to handle relative links.
Modified " ALIAS " to use relative links - now aliases don't need to be patched when the kernel is moved.
Tested emforth on a MT256. Added new .def file to support the led and lcd back light.
No LCD support yet.
MT-256 LCD support added.
Tested the PWM controller and read the push-buttons on the MT256
Also - wrote words to make it easy to define table driven finite state machines, table driven commands processor and tables of string pointers.
"FORGET" has been removed. There was a serious problem with it when the variables where separated from the code in order to build a flashable kernel.
The problem is that there is no way to know how much ram to release to free up any variables removed by "forget".
I've gone back to using "REMEMBER" instead.
For example the last definition in the system source is "REMEMBER EMPTY"
This saves the VOCLINK variable - all the vocab thread end links and VARPTR ( the free ram pointer).
Executing EMPTY restores all these values thereby removing any definitions added after empty was defined.
Words like EMPTY also reset memory manager free list (CONFIGURE) so they can't be used inside source files compiled using emserver. I might need to separate CONFIGURE again to avoid this problem.
Object extensions are more or less ported. Some features have never been implemented and will wait for a need to arise before they are. The data field order may be changed in future as the original order was optimised for the tranpsuter and the complexity has no advantage on the ARM.
IRQ vector set to E51FFF20 to allow AIC auto vectoring to work.
Minor bug in assembler which prevented S bit being set in LDM, etc. - fixed.
Added support for interrupts and PDC/DMA.