tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Scripting DDB in Forth?



I've accidentally wrote a Forth for sh3 (long story).  I thought it
might be interesting to put it into the kernel so that it can be
hooked into DDB.

Stopped in pid 0.2 (system) at  netbsd:cpu_Debugger+0x2:        rts
db> mach forth
Starting forth
db> : kvar \ kernel variable
db>   >in @ parse-word ksym
db>   ?dup not abort" unknown symbol"
db>   swap >in ! create ,
db>   does> @ ;
 ok
db> kvar foo
unknown symbol
db> kvar scifcn_speed
 ok
db> scifcn_speed @ .
9600  ok
db> : reg create , does> @ trapframe + @ ;
 ok
db> 8 reg $pc ( offset to SPC in trap frame ) 
 ok
db> hex
 ok
db> $pc u.
8c006df2  ok
db> bye
Exiting forth
db> c

Of course the more interesting scenario would be to implement
something like gdb's "condition" and "commands", but I didn't get
around to it yet, as it would require changes to MI parts of DDB.

Is this something that might be of general interest?

To give a bit of background...  This forth is dumb, honest to god
indirect threaded code.  The core is written entirely in assembler.
There are only three environmental dependencies for now - printing one
char (EMIT), printing a buffer (TYPE) and reading an input line
(ACCEPT).  Escape to C is also used for things like 64-bit division
(rewriting __divmoddi4 in asm from scratch is boring and kinda
pointless).  The DDB example above had a two additional words for this
demo, KSYM - a wrapper for ksym_getval(9) and TRAPFRAME - that, as the
name suggests, returns the pointer to the current struct trapframe.

The core of the interpreter for sh3 is 16 instructions.  About 70 asm
words tally up to about 500 instructions.  Nearly all of them are
short trivial sequences, like adding two numbers, etc.  I'd say that
someone familiar with the target ISA can port == write the asm core in
an evening or two.  The rest of the system is in manually "compiled"
threaded code, e.g.

!!! LIT - auxiliary for LITERAL (CORE 6.1.1780)
ASMWORD("lit", lit)
        SPILL_TOS		! == mov.l   TOS, @-PSP
        jmp     @NEXT		! interpreter's NEXT, kept in gloabl register
         mov.l  @IP+, TOS


!!! EMIT - CORE 6.1.1320
!!!     ( x -- )
CWORD("emit", emit)
        .long   _C_LABEL(emit_impl)


!!! #> - CORE 6.1.0040
!!!     Make the pictured numeric output string available as a
!!!     character string.
!!!     ( xd -- c-addr u )
WORD("#>", hash_greater)
        .long   two_drop
        .long   hld, fetch, pad, over, minus
        EXIT_4TH

which is a straightforward translation of

    : #> 2drop hld @ pad over - ;


If there's interest I can push what I have to bitbucket (I use
mercurial for this) as a first step, so that it can be ported to a few
ISAs first.

-uwe


Home | Main Index | Thread Index | Old Index