zeroflag / punyforth

Forth inspired programming language for the ESP8266

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

request for Memory map of Punyforth

enriquepinedo opened this issue · comments

Dear Attila,

Sory if this is explained elsewhere I did not found it

I am very confused without a memory map of Punyforth, I need to understand
what is happening with my reboot problems I am experimenting with
different programs. It is also almost impossible to advance with Forth
without having a memory map of the full system, I feel like shooting
with a machinegun blindfolded ! It is tough.

I am copying below an example of a memory Map of MicroPhyton for ESP8266
please if you can edit it and correct it for Punyforth to help
everybody visualize better how is Flash and Ram used in Punyforth, and
were is our free space going after loading dependencies.
The example of the internal of Micropython on ESP8266
helped me understand a bit further how the Rtos and Wifi will
consume memory etc...

I have many questions left : 1) is Uber.forth at $51000
copyed from flash to RAM before execution ? because it does not make
sense if we have 1 MB Flash , that 96 K or 64 K ram of ESP get so fast
gone ! In my application 1 LCD with i2cbus and 1 wifi Repl , it consumes
all my memory, I have left only 2K ! After that I can almost not add
anything more without falling into constant reboots.
2) how can this 1MB or 4MB of internal flash been better used ? Is it now
a wasted space ?
3) I suppose there is no way to add an external SD card, this would not
help in any sense. What else can be done ?

Mphyton Memory MAP :


----------------------- 0X4030_0000

MEMORY MAPPED FLASH ROM (1M)

----------------------- 0X4020_0000 ]
]
FLASH MEMORY MAPPING CACHE #1 ] 6
16 K INSTARAM ] 4
-------------------------0X4010_C000 ]
] K
FLASH MEMORY MAPPING CACHE #0 ]
16 K INSTARAM ]
]
------------------------ 0X4011_0000 ]

FAST CODE INSTARAM (32K)

------------------------ 0X4010_0000

------------------------ 0X4001_0000

 BOOT ROM  (64)

------------------------ 0X4000_0000 ]
] 9
]
SYSTEM DATA RAM (16K) ] 6
]
------------------------ 0X4001_0000 ]
] K
]
USER DATA RAM (80 K) ]
]
------------------------ 0X3FFE_8000 ]


Kind regards
Enrique

I continue exploring punyforth and I have tests and results
( all numbers below in decimal.)

core.forth alone gives freemem of 16.776 bytes free
on an empty system here points to 1073.653.560 ( i can not find any correlation
with physical memory in this large number )

tcp-repl with all it dependencies and
a bit of code for an i2c LCD gives me 2.200 bytes freemem
for programming
anything else I try to include after that Punyforth will hang. I can only add
very elementary forth operands. after a "screen" or a "block" of txt (1024 k
text code)_ it will hang.

I have been looking at flash.forth dependencies, it has only 1 needs "core.forth"

Questions : is this editor working ? It seems it saves to Flash memory, like I previously asked
if there is a way to "SAVE" a system interactively and incrementally...

I will try to understand more..... apparently having Rtos and open-boot in the system
those calls are causing the lack of program memory, ( even when ESP8266 has such a
large ram in terms of a forth system).

Kind regards
Enrique

I have many questions left : 1) is Uber.forth at $51000 copyed from flash to RAM before execution

No, the text is not copied into the RAM. Punyforth compiles indirect thread code from the text and fills up the dictionary.

I have left only 2K

This sounds realistic. The freemem word shows the available forth dictionary space, not the free system memory. There is an osfreemem word for getting the free memory from RTOS. Punyforth allocates about 24k dictionary space which means that your program and its dependencies consume about 22k.

When I was experimenting with larger dictionary spaces in the past, the system became unstable because not enough memory was left for RTOS. It usually crashed inside the lwip (tcp stack) code when it tried to allocate netcon buffers. So I decided to allocate only 24 forth heap, and leave the rest to RTOS.

You can experiment with larger memory settings by changing this line and recompile Punyforth

https://github.com/zeroflag/punyforth/blob/master/generic/data.S#L32

If you don't use the wifi and the tcp stack then it'll probably Ok.

But an easier way to fix this is to remove unused words from the uber.forth.

Questions : is this editor working ? It seems it saves to Flash memory, like I previously asked
if there is a way to "SAVE" a system interactively and incrementally...

There is an experimental editor in flash.forth but you need to use the --block-format parameter of modules.py when generating uber.forth.

Ok excellent !
Line 32 ......... .space 25152

In your opinion if I place .space to 50000 will it work ? 30000, 35000 ? which are the limits ?

Can we expect in future a memory map of punyforth within the ESP8266 ? I would like to help
in anything related to documentation to your proyect if you whish.
I am preparing for my own use a Spreadsheet with all the words of punyforth, like a glossary, the
old systems used to have , with stack notation and if possible or needed for more complex words
an example below so anybody can learn faster. As soon I have it ready I will pass this to you.
Thanks again for your time !

In your opinion if I place .space to 50000 will it work ? 30000, 35000 ? which are the limits ?

As far as I remember 30k should work but it will become unstable if you use the WiFi a lot.

Can we expect in future a memory map of punyforth within the ESP8266 ?

Punyforth is not a bare metal Forth (at least currently) but it runs as an RTOS task. This task is created by calling xTaskCreate, which allocates some memory dynamically. But I don't know how the memory allocation is handled internally.

I am preparing for my own use a Spreadsheet with all the words of punyforth, like a glossary

That's great. I'm sure this will be useful for others too.

Thanks Attila !
I will try this and let you know.

FYI I made some optimalization in variable: and constant: that reduces their memory consumption. This should buy you some additional memory.

Excelent ! THank you very much !

Hello Attila,
If you want to reduce the code size you can consider moving to a version with TOS in register. The a2 register is the best candidate for TOS because it is the first parameter when calling OS function. A lot of these calls when moved to this new version will end with
DPOP a2
NEXT
sequence which can be replace by a:
B PopNext
and
somewhere
PopNext:
DPOP a2
NEXT
And for a lot of primitives you will save the final DPUSH.

Hi Gerard,

I was thinking about TOS to register optimization earlier (mainly because of speed) but decided not to do it because some of the caveats. There are words like sp@ and sp! which would be difficult to use if TOS was in a register. Also one can write a code that treats the stack as an array which would likely break with TOS optimization. Task switching and exception handling would likely be more complicated as well.
And I'm not worried about the size of the compiled primitives as much because they're not stored in the same (~24K) dictionary space like the user defined words.

Attila

Hello Attila,
sp@ sp! will become:

defprimitive "sp@",3,spat,REGULAR
DPUSH a2
mov a2, a15
NEXT

defprimitive "sp!",3,spstore,REGULAR
mov a15, a2
DPOP a2
NEXT

Gérard

Right. I just don't think the extra complexity would worth the effort. But if you think so feel free to send a PR with the changes required. I'm not against it, I know other Forths do this but mainly because of speed (which is not the main concern) and not memory usage.

Hello Attila,
I have done this work some months ago but at that time was unable to assemble the source (some weird things in ubuntu under w10) and know I am unable to merge in Github...
I may be give a try again by bypassing github.
BTW do you know good documentation about the ESP8266 I got the Xtensa Instruction Set Architecture but i miss some documentation about how 8266 is implementing over LX106
Gérard

@GerardSontag no I don't know any unfortunately. But there are some projects in github like the esp port of microphython or forthright which can be used as an example. The API of FreeRTOS is well documented (http://www.freertos.org/a00106.html).

It seems that the flash rom is so big enough to add more compiled code into it. So if someone can design the metacompiler to append the code to it that would be great, right? I'll try, and you.

Hi, everybody,
I've developed the esp8266 assembler as well as dis-assembler under win32forth 4.2.671 in order to develop cross-compiler for the chip. For now it is almost completed with some difficult problem of dealing with create dose>. The variable header containing in flashrom causes the variable address to be in the same area. I can deal it well with some tricks to put in the ram area. But when it comes to put together with does> I was surrendered. Can anyone do the help?
I can compile the program in ram as well as in flashrom area so as we can expand the program to the maximum under my cross-compiler. Or if we don't use the cross-compiler we still can copy the code from ram area to the flashrom area with the same address except the higher 4 digits changed by executing the word 3FFE>4026. Of course, you can change whatever address you like by modifying 4026 to 4027, 4028, 4029, 402A, ....402F. That can expand limited spaces for now, achieving about 240K. That's not too bad. But still you have to solve the problem of variable and does>.
: 3FFE>4026 ( -- ) 3FFE88C0 ( lfa'.of.interpret? ) 402688C0 10000 88C0 - cmove'
402688C0 10000 88C0 - BOUNDS
DO i 32@' FFFF0000 AND 3FFE0000 = if i 32@' ffff and 40260000 or i 32!' then 4
+LOOP 40219854 ( LFA'.OF.immediate ) 402688C0 ( lfa'.of.interpret? ) 2dup 32!' lfa'->lfa* !
\ ` 4026DAEC var-lastword !
;

Hi holinepu,

Could you elaborate the problem with create does>? I'm trying to recall how it works.

create: always creates a new word with an enterdoes codeword/entrypoint instead of entercol (which is the usual entrypoint for colon definitions).

The enterdoes expects a behaviour pointer (which is an execution token of an other word) after the codeword and some arbitrary data after this. It'll push the location of the data part onto the stack and invoke the behaviour word. The default behaviour word is nop, but does> overwrites it with a user supplied word.

: create: createheader enterdoes , ['] nop cell + , ; \ default behaviour is nop, does> overwrites this

Here you can see that it creates a dictionary header and inserts the enterdoes codeword as an entry point. After that it inserts the xt of nop. The data part is not initialized.

: does> r> lastword link>body ! ;

does> replaces the behaviour part with the user supplied word (from the return stack).

So a constant for example can be defined:

: constant: cerate: , does> @ ;

But punyforth uses distinct codewords for variable/constants to save some space.

Dear Attila,
Thanks for the reply.
I've been trying to compile the program in the rom area. It is succefull to do now.
But still we have to solve the problem of variables residing in rom/ram area.
The nop instruction is just to provide a ( random ) address in RAM where is a safe place.
Why not just give it a fixed RAM address ( 3FFFF800, for example )?
I'd like to put create: and does> in flash rom ( or ram ), that way there is no need nop accompaning to the twos.

variable: can be defined in rom area too, so long as it can provide a number which is a ram address.

: variable.base.address hex: 3FFFF800 ; \ 3FFFF800 can be changed according to need.
: ram.address.replacing.nop variable.base.address
: variable.counter variable.base.address 4 ; \ 0 variable.counter ! <-- how to intialize it?
: variable.area variable.base.address 8 + ;
: variable.area.wide hex: 400 ; \ 400 can be changed according to need.
: var(ram) ( -- )

 createheader  hex:  40239B2C ,         variable.area     variable.counter  @   +  ['],  ,
 4  variable.counter  +!  hex: 402182C8 ( exit )  ,   ;

: create:(ram) var(ram) -4 variable.counter +! ;
: allot(ram) ( -- n ) align variable.counter +! ;

var(ram) v1
var(ram) v2
var(ram) v3

see v1 see v2 see v3

\ ******************************************************************************************
( 3FFE9098 3FFE9088 )
\ 3FFE909C 07 63 72 65 61 74 65 2F
: create/
\ ------------------------------------------------------------------------------------------
( 3FFE90A4 40239B2C ) ( docolon )
( 3FFE90A8 40218E0C ) createheader
( 3FFE90AC 40219660 ) enterdoes
( 3FFE90B0 40218AB4 ) ,
( 3FFE90B4 4021824C ) ( dolit ) 3FFE9090
( 3FFE90BC 40218A9C ) cell
( 3FFE90C0 40218174 ) +
( 3FFE90C4 40218AB4 ) ,
( 3FFE90C8 402182C8 ) exit

see create:
\ ******************************************************************************************
( 40279098 40279088 )
\ 4027909C 07 63 72 65 61 74 65 3A
: create:
\ ------------------------------------------------------------------------------------------
( 402790A4 40239B2C ) ( docolon )
( 402790A8 40218E0C ) createheader
( 402790AC 40219660 ) enterdoes
( 402790B0 40218AB4 ) ,
( 402790B4 4021824C ) ( dolit ) 3FFFF800
( 402790BC 40218A9C ) cell
( 402790C0 40218174 ) +
( 402790C4 40218AB4 ) ,
( 402790C8 402182C8 ) exit

\ ******************************************************************************************

The decompiler program compiled by punyForth in RAM can be relocated in any address of flash rom now.
So, the application program can be compiled in RAM and then transfered to flash ROM for further use.
\ lastword FFFF and 40260000 or 3FFE88C0 ! 4026DDCC 3FFE88C0 ! \ only interpret? remains left in RAM for linking purpose 3FFE88C0 var-lastword ! \ lastword change to interpret? where is in RAM
` 3FFE88E8 var-dp ! \ here can be changed to allow more RAM spaces for further use
see see see words7
: t1 8 . ;
: t2 88 . ;
see t8

@holinepu is the source code of this project available on github?

The program compiled by punyforth in RAM area can now be moved to any flash rom area by executing
40280000 3FFE88C0>402xxxxx under esp8266 punyforth development system. After flashing it into the chip we can execute words7 to see the org of each word. Likewise we can execute words6 to decompile the whole words.
visit --> https://groups.yahoo.com/neo/groups/armForth/files/esp8266%20punyForth/
words7

( lfa= ) 40218114 ( 00000000 ) ( cfa= 4021811C = 40239800 ) org t:+ dup
( lfa= ) 40218120 ( 40218114 ) ( cfa= 4021812C = 40239810 ) org t:+ drop
( lfa= ) 40218130 ( 40218120 ) ( cfa= 4021813C = 4023981C ) org t:+ swap
( lfa= ) 40218140 ( 40218130 ) ( cfa= 40218148 = 40239830 ) org t:+ rot
( lfa= ) 4021814C ( 40218140 ) ( cfa= 40218158 = 40239848 ) org t:+ 2swap
( lfa= ) 4021815C ( 4021814C ) ( cfa= 40218168 = 40239864 ) org t:+ 2over
( lfa= ) 4021816C ( 4021815C ) ( cfa= 40218174 = 4023987C ) org t:+ +
( lfa= ) 40218178 ( 4021816C ) ( cfa= 40218180 = 40239890 ) org t:+ -
( lfa= ) 40218184 ( 40218178 ) ( cfa= 4021818C = 402398A4 ) org t:+ *
( lfa= ) 40218190 ( 40218184 ) ( cfa= 4021819C = 402398BC ) org t:+ /mod
( lfa= ) 402181A0 ( 40218190 ) ( cfa= 402181A8 = 402398F8 ) org t:+ or
( lfa= ) 402181AC ( 402181A0 ) ( cfa= 402181B4 = 4023990C ) org t:+ and
( lfa= ) 402181B8 ( 402181AC ) ( cfa= 402181C0 = 40239920 ) org t:+ xor
( lfa= ) 402181C4 ( 402181B8 ) ( cfa= 402181D0 = 40239934 ) org t:+ invert
( lfa= ) 402181D4 ( 402181C4 ) ( cfa= 402181E0 = 40239948 ) org t:+ lshift
( lfa= ) 402181E4 ( 402181D4 ) ( cfa= 402181F0 = 40239960 ) org t:+ rshift
( lfa= ) 402181F4 ( 402181E4 ) ( cfa= 40218200 = 40239994 ) org t:+ _emit
( lfa= ) 40218204 ( 402181F4 ) ( cfa= 40218210 = 402399C4 ) org t:+ abort
( lfa= ) 40218214 ( 40218204 ) ( cfa= 4021821C = 402399F0 ) org t:+ @
( lfa= ) 40218220 ( 40218214 ) ( cfa= 40218228 = 40239A00 ) org t:+ c@
( lfa= ) 4021822C ( 40218220 ) ( cfa= 40218234 = 40239A10 ) org t:+ !
( lfa= ) 40218238 ( 4021822C ) ( cfa= 40218240 = 40239A24 ) org t:+ c!
( lfa= ) 40218244 ( 40218238 ) ( cfa= 4021824C = 40239A38 ) org t:+ [']
( lfa= ) 40218250 ( 40218244 ) ( cfa= 40218258 = 40239A4C ) org t:+ <
( lfa= ) 4021825C ( 40218250 ) ( cfa= 40218268 = 40239A64 ) org t:+ branch
( lfa= ) 4021826C ( 4021825C ) ( cfa= 40218278 = 40239A74 ) org t:+ branch0
( lfa= ) 4021827C ( 4021826C ) ( cfa= 40218284 = 40239A88 ) org t:+ >r
( lfa= ) 40218288 ( 4021827C ) ( cfa= 40218290 = 40239A9C ) org t:+ r>
( lfa= ) 40218294 ( 40218288 ) ( cfa= 4021829C = 40239AB0 ) org t:+ i
( lfa= ) 402182A0 ( 40218294 ) ( cfa= 402182A8 = 40239AC0 ) org t:+ j
( lfa= ) 402182AC ( 402182A0 ) ( cfa= 402182B8 = 40239AD0 ) org t:+ execute
( lfa= ) 402182BC ( 402182AC ) ( cfa= 402182C8 = 40239ADC ) org t:+ exit
( lfa= ) 402182CC ( 402182BC ) ( cfa= 402182D4 = 40239AEC ) org t:+ sp@
( lfa= ) 402182D8 ( 402182CC ) ( cfa= 402182E0 = 40239AFC ) org t:+ sp!
( lfa= ) 402182E4 ( 402182D8 ) ( cfa= 402182EC = 40239B0C ) org t:+ rp@
( lfa= ) 402182F0 ( 402182E4 ) ( cfa= 402182F8 = 40239B1C ) org t:+ rp!
( lfa= ) 402182FC ( 402182F0 ) ( cfa= 4021830C = 40239B2C ) org t:+ readchar
( lfa= ) 40218360 ( 402182FC ) ( cfa= 4021836C = 40239B2C ) org t:+ xpause
( lfa= ) 4021837C ( 40218360 ) ( cfa= 40218390 = 40239B58 ) org t:+ readchar-wait
( lfa= ) 40218394 ( 4021837C ) ( cfa= 402183A8 = 40239B88 ) org t:+ readchar-nowait
( lfa= ) 402183AC ( 40218394 ) ( cfa= 402183B8 = 40239BB8 ) org t:+ over
( lfa= ) 402183BC ( 402183AC ) ( cfa= 402183C8 = 40239BC8 ) org t:+ -rot
( lfa= ) 402183CC ( 402183BC ) ( cfa= 402183D8 = 40239BE0 ) org t:+ 2dup
( lfa= ) 402183DC ( 402183CC ) ( cfa= 402183E8 = 40239BF8 ) org t:+ 2drop
( lfa= ) 402183EC ( 402183DC ) ( cfa= 402183F8 = 40239C04 ) org t:+ 4drop
( lfa= ) 402183FC ( 402183EC ) ( cfa= 40218408 = 40239C10 ) org t:+ cells
( lfa= ) 4021840C ( 402183FC ) ( cfa= 40218414 = 40239C28 ) org t:+ >
( lfa= ) 40218418 ( 4021840C ) ( cfa= 40218420 = 40239C40 ) org t:+ =
( lfa= ) 40218424 ( 40218418 ) ( cfa= 4021842C = 40239C58 ) org t:+ <>
( lfa= ) 40218430 ( 40218424 ) ( cfa= 40218438 = 40239C70 ) org t:+ <=
( lfa= ) 4021843C ( 40218430 ) ( cfa= 40218444 = 40239C88 ) org t:+ >=
( lfa= ) 40218448 ( 4021843C ) ( cfa= 40218450 = 40239CA0 ) org t:+ 1+
( lfa= ) 40218454 ( 40218448 ) ( cfa= 4021845C = 40239CB0 ) org t:+ 1-
( lfa= ) 40218460 ( 40218454 ) ( cfa= 40218468 = 40239CC0 ) org t:+ 0=
( lfa= ) 4021846C ( 40218460 ) ( cfa= 40218474 = 40239CD4 ) org t:+ 0<>
( lfa= ) 40218478 ( 4021846C ) ( cfa= 40218480 = 40239CE8 ) org t:+ 0<
( lfa= ) 40218484 ( 40218478 ) ( cfa= 4021848C = 40239CFC ) org t:+ 0>
( lfa= ) 40218490 ( 40218484 ) ( cfa= 40218498 = 40239D14 ) org t:+ ms@
( lfa= ) 4021849C ( 40218490 ) ( cfa= 402184A8 = 40239D44 ) org t:+ _type
( lfa= ) 402184AC ( 4021849C ) ( cfa= 402184C0 = 40239D74 ) org t:+ uart-set-bps
( lfa= ) 402184C4 ( 402184AC ) ( cfa= 402184D4 = 40239DA8 ) org t:+ gpio-mode
( lfa= ) 402184D8 ( 402184C4 ) ( cfa= 402184F0 = 40239DDC ) org t:+ gpio-set-interrupt
( lfa= ) 402184F4 ( 402184D8 ) ( cfa= 40218504 = 40239E10 ) org t:+ gpio-write
( lfa= ) 40218508 ( 402184F4 ) ( cfa= 40218518 = 40239E44 ) org t:+ gpio-read
( lfa= ) 4021851C ( 40218508 ) ( cfa= 4021852C = 40239E78 ) org t:+ adc-read
( lfa= ) 40218530 ( 4021851C ) ( cfa= 40218540 = 40239EA8 ) org t:+ pwm-init
( lfa= ) 40218544 ( 40218530 ) ( cfa= 40218554 = 40239EDC ) org t:+ pwm-freq
( lfa= ) 40218558 ( 40218544 ) ( cfa= 40218568 = 40239F0C ) org t:+ pwm-duty
( lfa= ) 4021856C ( 40218558 ) ( cfa= 4021857C = 40239F3C ) org t:+ pwm-start
( lfa= ) 40218580 ( 4021856C ) ( cfa= 40218590 = 40239F68 ) org t:+ pwm-stop
( lfa= ) 40218594 ( 40218580 ) ( cfa= 4021859C = 40239F94 ) org t:+ ms
( lfa= ) 402185A0 ( 40218594 ) ( cfa= 402185BC = 40239FC4 ) org t:+ netcon-set-recvtimeout
( lfa= ) 402185C0 ( 402185A0 ) ( cfa= 402185DC = 40239FF8 ) org t:+ netcon-read-timeout@
( lfa= ) 402185E0 ( 402185C0 ) ( cfa= 402185FC = 4023A02C ) org t:+ netcon-read-timeout!
( lfa= ) 40218600 ( 402185E0 ) ( cfa= 40218610 = 4023A060 ) org t:+ netcon-new
( lfa= ) 40218614 ( 40218600 ) ( cfa= 40218628 = 4023A094 ) org t:+ netcon-connect
( lfa= ) 4021862C ( 40218614 ) ( cfa= 4021863C = 4023A0D0 ) org t:+ netcon-bind
( lfa= ) 40218640 ( 4021862C ) ( cfa= 40218654 = 4023A10C ) org t:+ netcon-listen
( lfa= ) 40218658 ( 40218640 ) ( cfa= 40218668 = 4023A140 ) org t:+ netcon-send
( lfa= ) 4021866C ( 40218658 ) ( cfa= 40218680 = 4023A17C ) org t:+ netcon-write
( lfa= ) 40218684 ( 4021866C ) ( cfa= 40218698 = 4023A1B8 ) org t:+ netcon-recvinto
( lfa= ) 4021869C ( 40218684 ) ( cfa= 402186AC = 4023A1F8 ) org t:+ netbuf-del
( lfa= ) 402186B0 ( 4021869C ) ( cfa= 402186C0 = 4023A228 ) org t:+ netbuf-next
( lfa= ) 402186C4 ( 402186B0 ) ( cfa= 402186D4 = 4023A25C ) org t:+ netbuf-data
( lfa= ) 402186D8 ( 402186C4 ) ( cfa= 402186E8 = 4023A294 ) org t:+ netcon-recv
( lfa= ) 402186EC ( 402186D8 ) ( cfa= 40218700 = 4023A2CC ) org t:+ netcon-accept
( lfa= ) 40218704 ( 402186EC ) ( cfa= 40218718 = 4023A304 ) org t:+ netcon-close
( lfa= ) 4021871C ( 40218704 ) ( cfa= 40218730 = 4023A334 ) org t:+ netcon-delete
( lfa= ) 40218734 ( 4021871C ) ( cfa= 40218744 = 4023A364 ) org t:+ task-yield
( lfa= ) 40218748 ( 40218734 ) ( cfa= 40218760 = 4023A390 ) org t:+ os-enter-critical
( lfa= ) 40218764 ( 40218748 ) ( cfa= 4021877C = 4023A3BC ) org t:+ os-exit-critical
( lfa= ) 40218780 ( 40218764 ) ( cfa= 40218790 = 4023A3E8 ) org t:+ wait-event
( lfa= ) 40218794 ( 40218780 ) ( cfa= 402187A0 = 4023A420 ) org t:+ random
( lfa= ) 402187A4 ( 40218794 ) ( cfa= 402187B4 = 4023A450 ) org t:+ erase-flash
( lfa= ) 402187B8 ( 402187A4 ) ( cfa= 402187C8 = 4023A484 ) org t:+ read-flash
( lfa= ) 402187CC ( 402187B8 ) ( cfa= 402187DC = 4023A4C0 ) org t:+ write-flash
( lfa= ) 402187E0 ( 402187CC ) ( cfa= 402187F0 = 4023A4FC ) org t:+ spi-init
( lfa= ) 402187F4 ( 402187E0 ) ( cfa= 40218804 = 4023A544 ) org t:+ spi-send8
( lfa= ) 40218808 ( 402187F4 ) ( cfa= 40218818 = 4023A57C ) org t:+ spi-send
( lfa= ) 4021881C ( 40218808 ) ( cfa= 40218830 = 4023A5C0 ) org t:+ wifi-set-mode
( lfa= ) 40218834 ( 4021881C ) ( cfa= 40218850 = 4023A5F4 ) org t:+ wifi-set-station-config
( lfa= ) 40218854 ( 40218834 ) ( cfa= 40218870 = 4023A62C ) org t:+ wifi-set-softap-config
( lfa= ) 40218874 ( 40218854 ) ( cfa= 40218884 = 4023A674 ) org t:+ wifi-set-ip
( lfa= ) 40218888 ( 40218874 ) ( cfa= 40218898 = 4023A6A4 ) org t:+ wifi-ip-str
( lfa= ) 4021889C ( 40218888 ) ( cfa= 402188B8 = 4023A6DC ) org t:+ wifi-station-connect
( lfa= ) 402188BC ( 4021889C ) ( cfa= 402188D8 = 4023A70C ) org t:+ wifi-station-disconnect
( lfa= ) 402188DC ( 402188BC ) ( cfa= 402188EC = 4023A73C ) org t:+ dhcpd-start
( lfa= ) 402188F0 ( 402188DC ) ( cfa= 40218900 = 4023A770 ) org t:+ dhcpd-stop
( lfa= ) 40218904 ( 402188F0 ) ( cfa= 40218914 = 4023A79C ) org t:+ push-enter
( lfa= ) 40218918 ( 40218904 ) ( cfa= 40218928 = 4023A7C8 ) org t:+ osfreemem
( lfa= ) 4021892C ( 40218918 ) ( cfa= 40218934 = 4023A7F8 ) org t:+ us@
( lfa= ) 40218938 ( 4021892C ) ( cfa= 40218940 = 4023A828 ) org t:+ us
( lfa= ) 40218944 ( 40218938 ) ( cfa= 40218954 = 4023A858 ) org t:+ deep-sleep
( lfa= ) 40218958 ( 40218944 ) ( cfa= 40218968 = 4023A888 ) org t:+ pulse-in
( lfa= ) 4021896C ( 40218958 ) ( cfa= 40218974 = 4023A8C4 ) org t:+ r@
( lfa= ) 40218978 ( 4021896C ) ( cfa= 40218988 = 4023A8D4 ) org t:+ i2c-start
( lfa= ) 4021898C ( 40218978 ) ( cfa= 4021899C = 4023A900 ) org t:+ i2c-stop
( lfa= ) 402189A0 ( 4021898C ) ( cfa= 402189B0 = 4023A92C ) org t:+ i2c-init
( lfa= ) 402189B4 ( 402189A0 ) ( cfa= 402189C4 = 4023A960 ) org t:+ i2c-read
( lfa= ) 402189C8 ( 402189B4 ) ( cfa= 402189D8 = 4023A994 ) org t:+ i2c-write
( lfa= ) 402189DC ( 402189C8 ) ( cfa= 402189F0 = 4023A9C8 ) org t:+ i2c-read-slave
( lfa= ) 402189F4 ( 402189DC ) ( cfa= 40218A08 = 4023AA08 ) org t:+ i2c-write-slave
( lfa= ) 40218A0C ( 402189F4 ) ( cfa= 40218A14 = 40239B2C ) org t:+ nip
( lfa= ) 40218A24 ( 40218A0C ) ( cfa= 40218A30 = 40239B2C ) org t:+ tuck
( lfa= ) 40218A40 ( 40218A24 ) ( cfa= 40218A48 = 40239B2C ) org t:+ s0
( lfa= ) 40218A5C ( 40218A40 ) ( cfa= 40218A64 = 40239B2C ) org t:+ r0
( lfa= ) 40218A74 ( 40218A5C ) ( cfa= 40218A7C = 40239B2C ) org t:+ 1=
( lfa= ) 40218A90 ( 40218A74 ) ( cfa= 40218A9C = 40239B2C ) org t:+ cell
( lfa= ) 40218AAC ( 40218A90 ) ( cfa= 40218AB4 = 40239B2C ) org t:+ ,
( lfa= ) 40218AD8 ( 40218AAC ) ( cfa= 40218AE0 = 40239B2C ) org t:+ c,
( lfa= ) 40218B00 ( 40218AD8 ) ( cfa= 40218B08 = 40239B2C ) org t:+ >in
( lfa= ) 40218B18 ( 40218B00 ) ( cfa= 40218B24 = 40239B2C ) org t:+ #tib
( lfa= ) 40218B34 ( 40218B18 ) ( cfa= 40218B3C = 40239B2C ) org t:+ tib
( lfa= ) 40218B4C ( 40218B34 ) ( cfa= 40218B58 = 40239B2C ) org t:+ state
( lfa= ) 40218B68 ( 40218B4C ) ( cfa= 40218B74 = 40239B2C ) org t:+ literal
( lfa= ) 40218B8C ( 40218B68 ) ( cfa= 40218B98 = 40239B2C ) org t:+ compare
( lfa= ) 40218C50 ( 40218B8C ) ( cfa= 40218C5C = 40239B2C ) org t:+ find
( lfa= ) 40218CEC ( 40218C50 ) ( cfa= 40218CF8 = 40239B2C ) org t:+ align
( lfa= ) 40218D1C ( 40218CEC ) ( cfa= 40218D28 = 40239B2C ) org t:+ here
( lfa= ) 40218D38 ( 40218D1C ) ( cfa= 40218D40 = 40239B2C ) org t:+ dp
( lfa= ) 40218D50 ( 40218D38 ) ( cfa= 40218D5C = 40239B2C ) org t:+ var-dp
( lfa= ) 40218D6C ( 40218D50 ) ( cfa= 40218D7C = 40239B2C ) org t:+ heap-start
( lfa= ) 40218D8C ( 40218D6C ) ( cfa= 40218D9C = 40239B2C ) org t:+ heap-end
( lfa= ) 40218DAC ( 40218D8C ) ( cfa= 40218DB8 = 40239B2C ) org t:+ align!
( lfa= ) 40218DD0 ( 40218DAC ) ( cfa= 40218DDC = 40239B2C ) org t:+ allot
( lfa= ) 40218DF8 ( 40218DD0 ) ( cfa= 40218E0C = 40239B2C ) org t:+ createheader
( lfa= ) 40218EA0 ( 40218DF8 ) ( cfa= 40218EAC = 40239B2C ) org t:+ >number
( lfa= ) 40218FD8 ( 40218EA0 ) ( cfa= 40218FE4 = 40239B2C ) org t:+ word
( lfa= ) 40219138 ( 40218FD8 ) ( cfa= 40219140 = 40239B2C ) org t:+ :
( lfa= ) 4021915C ( 40219138 ) ( cfa= 40219168 = 40239B2C ) org t:+ eundef
( lfa= ) 402191B0 ( 4021915C ) ( cfa= 402191B8 = 40239B2C ) org t:+ ]
( lfa= ) 40219310 ( 402191B0 ) ( cfa= 4021931C = 40239B2C ) org t:+ eundefi
( lfa= ) 4021932C ( 40219310 ) ( cfa= 40219338 = 40239B2C ) org t:+ eundefc
( lfa= ) 40219348 ( 4021932C ) ( cfa= 40219354 = 40239B2C ) org t:+ xemit
( lfa= ) 40219364 ( 40219348 ) ( cfa= 40219370 = 40239B2C ) org t:+ emit
( lfa= ) 4021939C ( 40219364 ) ( cfa= 402193A8 = 40239B2C ) org t:+ xtype
( lfa= ) 402193B8 ( 4021939C ) ( cfa= 402193C4 = 40239B2C ) org t:+ type
( lfa= ) 402193F0 ( 402193B8 ) ( cfa= 40219404 = 40239B2C ) org t:+ type-counted
( lfa= ) 40219440 ( 402193F0 ) ( cfa= 4021944C = 40239B2C ) org t:+ chr>in
( lfa= ) 402194B4 ( 40219440 ) ( cfa= 402194C0 = 40239B2C ) org t:+ in>char
( lfa= ) 402194E8 ( 402194B4 ) ( cfa= 402194F4 = 40239B2C ) org t:+ prompt
( lfa= ) 40219504 ( 402194E8 ) ( cfa= 40219514 = 40239B2C ) org t:+ show_prompt
( lfa= ) 4021953C ( 40219504 ) ( cfa= 40219544 = 40239B2C ) org t:+ key
( lfa= ) 402195C4 ( 4021953C ) ( cfa= 402195D8 = 40239B2C ) org t:+ compile-time
( lfa= ) 4021960C ( 402195C4 ) ( cfa= 40219620 = 40239B2C ) org t:+ var-lastword
( lfa= ) 40219630 ( 4021960C ) ( cfa= 40219640 = 40239B2C ) org t:+ lastword
( lfa= ) 40219650 ( 40219630 ) ( cfa= 40219660 = 40239B2C ) org t:+ enterdoes
( lfa= ) 40219670 ( 40219650 ) ( cfa= 40219680 = 40239B2C ) org t:+ entercol
( lfa= ) 40219690 ( 40219670 ) ( cfa= 402196A0 = 40239B2C ) org t:+ link>flb
( lfa= ) 402196B0 ( 40219690 ) ( cfa= 402196C0 = 40239B2C ) org t:+ link>len
( lfa= ) 402196DC ( 402196B0 ) ( cfa= 402196EC = 40239B2C ) org t:+ link>flags
( lfa= ) 40219708 ( 402196DC ) ( cfa= 40219718 = 40239B2C ) org t:+ link>name
( lfa= ) 4021972C ( 40219708 ) ( cfa= 40219738 = 40239B2C ) org t:+ link>xt
( lfa= ) 40219758 ( 4021972C ) ( cfa= 40219768 = 40239B2C ) org t:+ link>body
( lfa= ) 4021977C ( 40219758 ) ( cfa= 40219788 = 40239B2C ) org t:+ hidden?
( lfa= ) 402197AC ( 4021977C ) ( cfa= 402197B8 = 40239B2C ) org t:+ hide
( lfa= ) 402197E4 ( 402197AC ) ( cfa= 402197F0 = 40239B2C ) org t:+ reveal
( lfa= ) 40219820 ( 402197E4 ) ( cfa= 40219830 = 40239B2C ) org t:+ immediate?
( lfa= ) 40219854 ( 40219820 ) ( cfa= 40219864 = 40239B2C ) org t:+ immediate
( lfa= ) 40280000 ( 40219854 ) ( cfa= 40280010 = 40239B2C ) org t:+ interpret?
( lfa= ) 40280024 ( 40280000 ) ( cfa= 40280034 = 40239B2C ) org t:+ backref,
( lfa= ) 40280048 ( 40280024 ) ( cfa= 40280054 = 40239B2C ) org t:+ begin
( lfa= ) 40280064 ( 40280048 ) ( cfa= 40280070 = 40239B2C ) org t:+ again
( lfa= ) 4028008C ( 40280064 ) ( cfa= 40280098 = 40239B2C ) org t:+ until
( lfa= ) 402800B4 ( 4028008C ) ( cfa= 402800C4 = 40239B2C ) org t:+ line-break?
( lfa= ) 402800F0 ( 402800B4 ) ( cfa= 402800F8 = 40239B2C ) org t:+ (
( lfa= ) 40280118 ( 402800F0 ) ( cfa= 40280120 = 40239B2C ) org t:+
( lfa= ) 40280138 ( 40280118 ) ( cfa= 40280140 = 40239B2C ) org t:+ dip
( lfa= ) 40280158 ( 40280138 ) ( cfa= 40280164 = 40239B2C ) org t:+ keep
( lfa= ) 4028017C ( 40280158 ) ( cfa= 40280184 = 40239B2C ) org t:+ bi
( lfa= ) 4028019C ( 4028017C ) ( cfa= 402801A4 = 40239B2C ) org t:+ bi*
( lfa= ) 402801BC ( 4028019C ) ( cfa= 402801C4 = 40239B2C ) org t:+ bi@
( lfa= ) 402801D4 ( 402801BC ) ( cfa= 402801E0 = 40239B2C ) org t:+ 3dup
( lfa= ) 402801F4 ( 402801D4 ) ( cfa= 40280200 = 40239B2C ) org t:+ 3drop
( lfa= ) 40280210 ( 402801F4 ) ( cfa= 40280218 = 40239B2C ) org t:+ cr
( lfa= ) 40280238 ( 40280210 ) ( cfa= 40280244 = 40239B2C ) org t:+ space
( lfa= ) 40280258 ( 40280238 ) ( cfa= 40280260 = 40239B2C ) org t:+ %
( lfa= ) 40280270 ( 40280258 ) ( cfa= 40280278 = 40239B2C ) org t:+ /
( lfa= ) 40280288 ( 40280270 ) ( cfa= 40280290 = 40239B2C ) org t:+ +!
( lfa= ) 402802AC ( 40280288 ) ( cfa= 402802B4 = 40239B2C ) org t:+ -!
( lfa= ) 402802D4 ( 402802AC ) ( cfa= 402802DC = 40239B2C ) org t:+ c+!
( lfa= ) 402802F8 ( 402802D4 ) ( cfa= 40280310 = 40239B2C ) org t:+ prepare-forward-ref
( lfa= ) 40280328 ( 402802F8 ) ( cfa= 40280340 = 40239B2C ) org t:+ resolve-forward-ref
( lfa= ) 4028035C ( 40280328 ) ( cfa= 40280364 = 40239B2C ) org t:+ if
( lfa= ) 40280380 ( 4028035C ) ( cfa= 4028038C = 40239B2C ) org t:+ else
( lfa= ) 402803B0 ( 40280380 ) ( cfa= 402803BC = 40239B2C ) org t:+ then
( lfa= ) 402803CC ( 402803B0 ) ( cfa= 402803D8 = 40239B2C ) org t:+ ?dup
( lfa= ) 402803F0 ( 402803CC ) ( cfa= 402803F8 = 40239B2C ) org t:+ .
( lfa= ) 40280454 ( 402803F0 ) ( cfa= 4028045C = 40239B2C ) org t:+ ?
( lfa= ) 4028046C ( 40280454 ) ( cfa= 40280478 = 40239B2C ) org t:+ unloop
( lfa= ) 40280494 ( 4028046C ) ( cfa= 4028049C = 40239B2C ) org t:+ do
( lfa= ) 402804D0 ( 40280494 ) ( cfa= 402804DC = 40239B2C ) org t:+ bounds
( lfa= ) 402804F0 ( 402804D0 ) ( cfa= 402804FC = 40239B2C ) org t:+ loop
( lfa= ) 40280590 ( 402804F0 ) ( cfa= 4028059C = 40239B2C ) org t:+ end?
( lfa= ) 402805E4 ( 40280590 ) ( cfa= 402805F0 = 40239B2C ) org t:+ +loop
( lfa= ) 40280648 ( 402805E4 ) ( cfa= 40280654 = 40239B2C ) org t:+ while
( lfa= ) 40280670 ( 40280648 ) ( cfa= 4028067C = 40239B2C ) org t:+ repeat
( lfa= ) 402806A0 ( 40280670 ) ( cfa= 402806AC = 40239B2C ) org t:+ case
( lfa= ) 402806C0 ( 402806A0 ) ( cfa= 402806C8 = 40239B2C ) org t:+ of
( lfa= ) 40280708 ( 402806C0 ) ( cfa= 40280714 = 40239B2C ) org t:+ endof
( lfa= ) 40280748 ( 40280708 ) ( cfa= 40280754 = 40239B2C ) org t:+ endcase
( lfa= ) 402807A8 ( 40280748 ) ( cfa= 402807B8 = 40239B2C ) org t:+ override
( lfa= ) 402807C8 ( 402807A8 ) ( cfa= 402807D4 = 40239B2C ) org t:+ create*
( lfa= ) 402807F0 ( 402807C8 ) ( cfa= 402807F8 = 40239B2C ) org t:+ nop
( lfa= ) 40280800 ( 402807F0 ) ( cfa= 4028080C = 40239B2C ) org t:+ create:
( lfa= ) 40280834 ( 40280800 ) ( cfa= 40280840 = 40239B2C ) org t:+ does>
( lfa= ) 40280858 ( 40280834 ) ( cfa= 40280868 = 40239B2C ) org t:+ constant:
( lfa= ) 40280880 ( 40280858 ) ( cfa= 40280894 = 40239B2C ) org t:+ init-variable:
( lfa= ) 402808A4 ( 40280880 ) ( cfa= 402808B4 = 40239B2C ) org t:+ variable:
( lfa= ) 402808C8 ( 402808A4 ) ( cfa= 402808D4 = 40239B2C ) org t:+ TRUE
( lfa= ) 402808E4 ( 402808C8 ) ( cfa= 402808F0 = 40239B2C ) org t:+ FALSE
( lfa= ) 40280900 ( 402808E4 ) ( cfa= 40280910 = 40239B2C ) org t:+ exception:
( lfa= ) 4028092C ( 40280900 ) ( cfa= 4028093C = 40239B3C ) org t:+ EUNDERFLOW
( lfa= ) 40280948 ( 4028092C ) ( cfa= 40280958 = 40239B3C ) org t:+ EOVERFLOW
( lfa= ) 40280964 ( 40280948 ) ( cfa= 40280970 = 40239B3C ) org t:+ EASSERT
( lfa= ) 4028097C ( 40280964 ) ( cfa= 4028098C = 40239B3C ) org t:+ ENOTFOUND
( lfa= ) 40280998 ( 4028097C ) ( cfa= 402809A8 = 40239B3C ) org t:+ ECONVERT
( lfa= ) 402809B4 ( 40280998 ) ( cfa= 402809C0 = 40239B3C ) org t:+ EESCAPE
( lfa= ) 402809CC ( 402809B4 ) ( cfa= 402809D8 = 40239B2C ) org t:+ defer:
( lfa= ) 402809F8 ( 402809CC ) ( cfa= 40280A04 = 40239B2C ) org t:+ defer!
( lfa= ) 40280A24 ( 402809F8 ) ( cfa= 40280A34 = 40239B3C ) org t:+ unhandled
( lfa= ) 40280A40 ( 40280A24 ) ( cfa= 40280A4C = 40239B3C ) org t:+ handler
( lfa= ) 40280A58 ( 40280A40 ) ( cfa= 40280A68 = 40239B3C ) org t:+ var-handler
( lfa= ) 40280A74 ( 40280A58 ) ( cfa= 40280A88 = 40239B2C ) org t:+ single-handler
( lfa= ) 40280A94 ( 40280A74 ) ( cfa= 40280AA0 = 40239B2C ) org t:+ catch
( lfa= ) 40280AE8 ( 40280A94 ) ( cfa= 40280AF4 = 40239B2C ) org t:+ throw
( lfa= ) 40280B5C ( 40280AE8 ) ( cfa= 40280B64 = 40239B2C ) org t:+ '
( lfa= ) 40280B94 ( 40280B5C ) ( cfa= 40280BA4 = 40239B2C ) org t:+ postpone:
( lfa= ) 40280BB4 ( 40280B94 ) ( cfa= 40280BC0 = 40239B2C ) org t:+ ['],
( lfa= ) 40280BD4 ( 40280BB4 ) ( cfa= 40280BDC = 40239B2C ) org t:+ {
( lfa= ) 40280C1C ( 40280BD4 ) ( cfa= 40280C24 = 40239B2C ) org t:+ }
( lfa= ) 40280C40 ( 40280C1C ) ( cfa= 40280C48 = 40239B2C ) org t:+ is:
( lfa= ) 40280C84 ( 40280C40 ) ( cfa= 40280C90

hi,
It seems like that no one cares about the cross-compiler that can be better to do the job. Ok! we'll change to the possibility to use punyForth itself to compile the source code and then transfer it to the console via rs232. That way we can obtain the hex file by executing , for example , 40280000 >flash. Now we can convert it to 40280000.bin file to be written to flash rom by flasher.exe. Wouldn't that be great to finish the job! Blees you by the name of Forth holi

40260000 (3).zip

hi, I've completed the function of transfering the code compiled in ram area to the flash Rom area. It is quite easy to use it to extend the program now. I've already send you the pf.rar file, see if you could try it out, please tell me if you succeed. Best regard holi