gnupic: Re: [PicForth] pre-announcing Forth for PIC18F chips


Previous by date: 16 Jan 2005 22:41:56 +0000 gputils license query, David McNab
Next by date: 16 Jan 2005 22:41:56 +0000 Re: gputils license query, Mark J. Dulcey
Previous in thread: 16 Jan 2005 22:41:56 +0000 Re: [PicForth] pre-announcing Forth for PIC18F chips, J.C. Wren
Next in thread: 16 Jan 2005 22:41:56 +0000 Re: [PicForth] pre-announcing Forth for PIC18F chips, Mark J. Dulcey

Subject: Re: [PicForth] pre-announcing Forth for PIC18F chips
From: David McNab ####@####.####
Date: 16 Jan 2005 22:41:56 +0000
Message-Id: <41EAEDAB.8010602@rebirthing.co.nz>

J.C. Wren wrote:
>    Are the von Neuman memory map limits fixed?  The PIC18F8621, for 
> example, has 3K of RAM, and 64K of FLASH.  I'd like to be able to use 
> all the RAM, and 61K of the FLASH.

Very good point indeed. Makes sense that a user of such a chip would 
want to org the bytecodes to address 0xC00 or later, and feel safe that 
'!', '@', 'c@', 'c!', '+!' etc will hit RAM for addresses < 0xC00, and 
ROM for addresses >= 0xC00. I'll add this immediately.

(btw - '!', 'c!' etc act as 'placebos' for addresses in ROM space, ie 
they consume the data and address args but do nothing. I've done this 
because it would be nightmarishly inefficient to:
   - read into RAM the 64-byte page within which the target address
     resides
   - write the data to the correct location within the cached page in
     RAM
   - erase the 64-byte page in ROM
   - reprogram the page in ROM with the cached data.
Also, it would accelerate program memory 'wear'.

If one wants ROM storage operators, one can easily add the required 
primitives.

>    The '8621 also has a 31 entry hardware stack, with stack underflow 
> and overflow detection.

Ditto across the 18F range, AFAIK. Makes me wonder why people still put 
up with PIC16F chips, when pin-compatible 18F chips are only pennies 
more expensive.

> If it's not too unreasonable, it might be nice 
> to be able to use that instead of a software stack.

For calls to and between 'code' and 'primitive' words, I'm already using 
the hardware return stack. I only use the software return stack for 
calls between colon-defined words. In other words, with:

  primitive fred ... <assembler statements> ... end-primitive
  code mary ... <assembler statements> ... end-code
  : jim ... fred ... mary ... ;
  : alice ... jim ... fred ... mary ... ;

the software return stack is only used when 'alice' calls 'jim'.

I see problems in using the hardware return stack for calls between 
colon-defined words:

1) The vm reads and 'executes' bytecodes. Users' high-level 
(colon-defined) forth words get compiled down to strings of bytecode, 
not native code.

FWICT, the 'PUSH' instruction cannot push arbitrary data, it can only 
push PC+2, which means we'd need some serious acrobatics to push 
bytecode return addresses (if it can be done at all).

2) I use the return stack for storage of JH locals.

I am hardwired in my choice to support locals. Sorry, purists! :P

For example:

  : foo { arg1 arg2 | local1 }
      ...
      { local2 | local3 }
      ...
  ;

If the calling prog 'bar' executes:

    $451a $3431 $1139 foo

then immediately after entry to foo, the stacks viewed byte-wise look like:

DATA: .. 1a 45 31 34 39 11
RETURN:               0 barReturnH barReturnL ...

Note that we're using little-endian. Also, the extra '0' on the return 
stack is a 'frame size'. And also, we're showing the return stack 
growing downward in memory.

After executing the first locals statement, the stacks look like:

DATA: .. 1a 45
RETURN:           6 0 0 31 34 39 11 barReturnH barReturnL ..

Where the '6' is the new frame size, the '0 0' is the initialised local 
'local1', the '31 34' is 'arg1' ripped from data stack, and '39 11' is 
arg2 ripped from the data stack.

Similarly, if before executing the second locals statement, the data 
stack has become:

DATA: .. 1a 45 67 69

ie, statements in foo have pushed the extra value $6967 onto the stack, 
then the second locals statement would change the stacks to:

DATA: .. 1a 45
RETURN:    a 0 0 67 69 0 0 31 34 39 11 barReturnH barReturnL ..

So as you can see, each word call has a return stack cost of 3 bytes 
plus total size of all locals temporarily created by that word.

If you can suggest a way to efficiently use the PIC18 hardware return 
stack with all this, then please share your thoughts.

Cheers
David

> For large programs, 
> it's obviously inadequate, but for a lot of projects it's more than enough.
> 
>    --jc
> 
> David McNab wrote:
> 
>> Hi gnupic and picforth people,
>>
>> This is a pre-announcement of a coming Forth compiler for the 
>> PIC18Fxxx chips. I've tentatively called it 'PIC18forth', but am open 
>> to suggestions for a better name.
>>
>> PIC18forth is radically different from the PIC16Fxxx-only PicForth 
>> compiler. Almost nothing in common, since I've written PIC18forth from 
>> scratch.
>>
>> Quick summary of features - love them and loathe them:
>>
>>  * signed/unsigned 16-bit data cells and operators
>>  * software return stack
>>  * data stack grows up (increasing addresses), while
>>    return stack grows down (decreasing addresses)
>>  * total allocated size of data+return stacks can
>>    be set to anything between 16 and 1024 bytes
>>  * compiler is written in Python, and is very approachable
>>    and extensible, even for people new to the code
>>  * integrated into gputils
>>  * forth sources get compiled to relocatable assembly (.asm)
>>    sources, ready for gpasm and gplink
>>  * the generated code embeds a 16-bit forth vm (token threaded
>>    execution model) which executes bytecodes
>>  * the generated code is self-contained, and once assembled
>>    and linked, can be downloaded/flashed as a standalone program
>>  * FSR0 is usually used for data stack ptr, FSR1 usually
>>    used as return stack ptr, FSR2 used as general purpose
>>    pointer
>>  * full support for locals (John Hopkins syntax, data
>>    gets transferred from data stack to a frame on return stack
>>  * vm design favours code density over execution speed
>>  * contents of 'code .. end-code' definitions are included
>>    verbatim in generated assembly source (with '\' comments
>>    changed to ';')
>>  * the defining-words 'primitive .. end-primitive' can be
>>    used in place of 'code .. end-code', to define a word
>>    in assembler which will be available as a single-byte
>>    vm instruction - easy to add/remove primitives at will
>>  * maps to von Neumann memory model, with addresses <8000H
>>    treated as RAM addresses, and addresses>=8000H treated
>>    as program ROM addresses
>>
>> If you're currently hacking with PIC18Fxxx chips, and are interested 
>> in trying out PIC18forth, please mail me and I'll put you on a list 
>> for pre-alpha-testers.
>>
> 
> 
> 

Previous by date: 16 Jan 2005 22:41:56 +0000 gputils license query, David McNab
Next by date: 16 Jan 2005 22:41:56 +0000 Re: gputils license query, Mark J. Dulcey
Previous in thread: 16 Jan 2005 22:41:56 +0000 Re: [PicForth] pre-announcing Forth for PIC18F chips, J.C. Wren
Next in thread: 16 Jan 2005 22:41:56 +0000 Re: [PicForth] pre-announcing Forth for PIC18F chips, Mark J. Dulcey


Powered by ezmlm-browse 0.20.