home .. forth .. misc mail list archive ..

Re: Unidentified subject!


Dave Lowry:
>  I need some help from the P21 assembly language gurus!  I'm working
>  on a C compiler for P21.  To save myself some work, I'd like to use
>  some words from P21Forth as a runtime library.  That is, I'd like
>  to "call" words from outside the normal Forth inner interpreter.
>  What I have so far is appended below.  This looks kind of clumsy.
>  Is there a better way?  Thanks!

>  VARIABLE IPSAVE
>  VARIABLE IPNEW
>  HERE 6 + IPNEW !

>  ' TX!

>  ASSEMBLER

>  CODE CALL-TX!
>    / some code...
>    A PUSH IPSAVE # NOP
>    A! POP !A IPNEW #
>    A! # PUSH ;'
>    IPSAVE # NOP A! @A
>    A! NOP NOP NOP
>    / some more code...
>    NEXT
>    END-CODE

Er... what are you trying to hold constant, and what can vary?

Near as I can see your code fragment copies A over to IPSAVE, then
copies IPNEW to A, calls some random location.  Upon returning it
restores A from IPSAVE.

Questions:

(1) what is IPNEW for?  Why don't you do anything with it after
returning?

(2) do you really mean for this code to be non reentrant?

(3) I'm curious, is this constant code or a template?

(4) What are your "register conventions" for the C compiler?

(5) Do you care to investigate free internal stack space in the
routines you're calling?

(6) Don't you think that A! and + should automatically insert nops
where needed?

......................................................................

Presuming the easy answers to these questions, I'd probably generate
code like:
   varref ipsave
   varref ipnew
   varref calladdr
...
   ipsave # a<->tos !a #ipnew a! #calladdr push ;' #ipsave a! @a a!

Using idealized machine language (no interleaving of instruction
bits), I might get something like this:
                   01010 11001 11100 11110	\ n a@ push nop
                   ipsaveaddress
                   11101 11000 01111 01010	\ a! pop a@! n
ipnewaddress       ipnewvalue
                   11101 01010 11100 00001	\ a! n push ;'
                   calladdr
                   01010 11110 11101 01011	\ n nop a! a@@
ipsaveaddress      ipsavevalue
                   11101 ...                    \ a! ...

Of course, changing that first line to
                   11001 11100 01010 11110	\ a push n nop
would reduce data stack depth, but that's something a peephole
optimizer should be able to do automatically.

And, I suspect that calladdr is the address of TX.

I don't think you can get better than this without changing the
parameters of the problem.  The only significant moral here is that
you can get one read reference of a variable free without trashing A
(presuming you're willing to leave the code in variable space).  Note
that the normal variable space code for a variable is something like:
n ;

By the way: no, I don't have a compiler, yet, which would properly
deal with the above.  I'm still feeling my way along here.  Perhaps it
would be better to manage A as the implicit TOS and have the code
fragment read:
   varref ipsave
   varref ipnew
   varref calladdr
...
   ipsave # ! #ipnew #calladdr execute #ipsave @

Of course, I'd intend for this to generate the same machine code as
above.

----------------------------------------------------------------------

My own personal big mystery is what are the high 12 bits that result
from the following words after retrieving data from 8 bit wide rom or
sram?

n
@
@+

The obvious answers are:

(*) some bit pattern which is treated as an undocumented instruction
indicating "process this instruction word in boot mode" to the cpu.

(*) the number AAA00 (pattern 0 for the high bits).

(*) the address lines for the relevant byte of data

(*) the number 00000 (would have been nice, but the boot code doesn't
assume this and I think I saw a reference in the doc that this wasn't
the case).

(*) something else?

Anybody know for sure?

-- 
Raul D. Miller