Re: 8051 assembler in Common Lisp



Greg Menke <gregm-xyzpdq@xxxxxxxxxxxx> writes:

> Peter Seibel <peter@xxxxxxxxxxxxxxx> writes:

>> To provide some food for thought, here's a sketch of part of an
>> assembler that works somewhat like I think yours ought to. Basically I
>> define a macro DEFTEXT which can be used to define an association
>> between a name and a snippet of machine code. The idea (which I'm sort
>> of guessing at from the code you've shown us) is that such as snippet
>> is then combined with other snippets into a final assembly. This
>> sketch doesn't include the ability to include arbitrary Common Lisp
>> code within a DEFTEXT body but only because I'm not sure how you're
>> envisioning that being used. At anyrate, note how there's no interning
>> or uninterning of symbols and no calls to EVAL. After a DEFTEXT form
>> is evaluated you can use the function GETTEXT to get at the machine
>> code. For instance you can EVAL the following form (or load a file
>> containing the form or whatever):
>>
>> (deftext foo
>> (nop)
>> (goto label2)
>> (nop)
>> label1 (nop)
>> (push 128)
>> (push 255)
>> (goto label1)
>> label2 (nop))
>>
>> then:
>>
>> ASM51> (gettext 'foo)
>> #(0 1 11 0 0 2 128 2 255 1 4 0)
>>
>> Hope this gives you some ideas.
>
> Below is the level of syntax I want to support. Your gettext example
> cannot work because all symbols referenced by the assembly within it
> must be defined before binary code can be produced. The gettext above
> has to emit intermediate code that captures the symbols, which is
> finally executed once all symbols have addresses.

So if you look at my other post where I included the implementation of
DEFTEXT and GETTEXT, you'll see that DEFTEXT works in several
passes. It may be that you want to store the result of one of earlier
passes, before symbols have been resolved. Then you can stitch
together a bunch of bits of code defined with different DEFTEXT's and
DEFBSS's and so forth and then do the final resolution of symbols to
addresses.

Anyway, if you can annotate this test code a brief comment about what
each form does, that'd help me understand what's goin on.

>
> (defproject testproj
> (:text-base #x100
> :data-base nil
> :text-align 16
> :data-align 8))
>
> (defmacro xyzpdq (parm)
> `(add acc ,parm))
>
> (defparameter +RESERVE-DATA-LEN+ 100)
>
>
> (defdata tst-data2 (:org #x20)
> (dw 'tst-code))
>
> (defbss tst-bss ()
> (reserve +RESERVE-DATA-LEN+))
>
> (defdata tst-data ()
> (dw 0 1 2 3 'tst-code 'tst-bss)
> (db 4 5 6 7 '(lobyte tst-data2))
> (db \"hello, world\")
> supercat2
> (filldata +RESERVE-DATA-LEN+)
> (filldata 10 #\\x)
> (filldata 2 '(let ((x 1) (y 2) (z 3))
> (list x y z))) )
>
> (deftext tst-code ()
> (nop)
> (xyzpdq 10)
> (nop)
> supercat
> (addc a 1)
> (anl acc 15)
> (inc dptr)
> (cjne acc 3 'tst-data)
> (clr a)
> ;;(ajmp 'supercat2)
> (acall 'supercat)
> (acall 'tst-data)
> (acall '(+ tst-code 2)))

Finally, on a terminology note, you talk about "symbols" in a fairly
confusing way. If I've understood correctly, a form like a DEFTEXT
form creates something (exactly what isn't quite clear to me yet:
intermediate code or machine code or something) and then gives it a
name. The name is a symbol but the data is not the symbol. In other
words it's analogous to the way DEFUN creates something (a function)
and associates it with a name. For example given:

(defun hello () (print "hello"))

we don't say the symbol HELLO *is* a function; we say it names the
function.

Similarly in your system, it would probably be better to talk about
"the address of the text segment named FOO" than "the address of the
symbol FOO".

-Peter

--
Peter Seibel * peter@xxxxxxxxxxxxxxx
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp * http://www.gigamonkeys.com/book/
.