Xassembler vocabulary for Atmega

published: 27 March 2021 / updated 27 March 2021

Lire cette page en français

 

To generate a code that can be used on an ARDUINO card, you must first compile and assemble primitives in the TARGET area. To do this, it is necessary to have, under gForth, a specific assembler.

Assembler for Atmega

gForth has a number of vocabularies, including a ASSEMBLE vocabulary.

To see the list of all gForth vocabularies, you have to run VOCS:

vocs
libcc-types assembler esc-sequences new-locals-wl locals-types 
locals environment-wordlist Root Forth  ok

The available vocabularies are displayed after vocs. We sees the vocabulary assembler.

Selecting a vocabulary

To see the content of a vocabulary, all you have to do is type the name of this vocabulary, followed by words:

assembler words 
makeflag YET BUT ?DO REPEAT AGAIN UNTIL WHILE DO BEGIN ELSE AHEAD 
THEN IF >offset ~cond PREFETCHT2 PREFETCHT1 PREFETCHT0 PREFETCHNTA 
SFENCE PSWABD PFPNACC PFNACC PF2IW PI2FW PSHUFW PSADBW PMULHUW 
PMOVMSKB PMINUB PMINSW PMAXUB PMAXSW PINSRW PEXTRW PAVGW PAVGB 
....[CUT]...
[BP+DI] [BP+SI] [BX+DI] [BX+SI] wadr wadr: bregs breg Regs finish0F 
0F, finishb finish opcode, rbytes, bytes, .qa .q .da .d .wa .w .b 
sclear pre- .arel .64bit .rex .64now .64size .onow .osize .anow 
.asize seg byte? Adisp? Aimm? imm# imm disp# disp SIB# SIB ModR/M# 
ModR/M +rel c! allot here , >exec nonrelocate nrc (+rel >codes 
case? user' [A] [F]  ok

The problem is that the content of this assembler vocabulary is not suitable at all for the generation of code intended for the Atmega processor fitted to the cards ARDUINO.

As it is out of the question to delete this assembler vocabulary and replace it with our Atmega compatible assembler vocabulary, we are going to define a Xassembler vocabulary.

Creation of the Xassembler vocabulary

To create this new vocabulary, we will use the word vocabulary:

vocabulary Xassembler 

In order to check if this new vocabulary has been integrated, let's run vocs:

vocs
Xassembler libcc-types assembler esc-sequences new-locals-wl locals-types 
locals environment-wordlist Root Forth  ok

We check the search order of the words by typing order:

order
Forth Forth Root     Forth  ok

Now we need to tell gForth that all the new definitions must be integrated into this vocabulary by executing definitions:

Xassembler definitions 

We check the word search order again with order:

order
Xassembler Forth Root     Xassembler  ok

The search order is read from left to right. Any new word will be defined in Xassembler. If by chance we create in this vocabulary Xassembler a word already defined in the FORTH vocabulary, this word will be created in this vocabulary without altering its namesake in the FORTH vocabulary.

In the article titled Infixed to postfixed notation converter we create a vocabulary algebra, in which we define homonyms for * / + -, etc ... In the context of this algebra vocabulary, for example the word + will work differently from the word + defined in the FORTH vocabulary.

Structuring of source files

Here is how the source files can be organized:

----------/ <meta>
          |     meta.txt
          |     meta_AVR328.txt
          |     kernel.txt
          |---------------------/ <avr>
                                /     Xassembler.txt
                                /     m328def.txt
                                /     core.txt
                                /
                                / <pic>
                                /     Xassembler.txt         
                                /     core.txt

We first have a meta directory in which we will find:

Example of the contents of the meta_avr328.txt file compiled by gForth:

include meta.txt
include avr/m328def.txt
include avr/Xassembler.txt
include avr/core.txt
include kernel.txt     

Words like , c, are redefined in meta.txt to allow code generation in TARGET:

If you want to generate a FORTH kernel for another processor, you just have to write a meta_PIC.txt file for example, containing:

include meta.txt
include pic/Xassembler.txt
include pic/core.txt
include kernel.txt     

The content of the pic/Xassembler.txt file will be very different from that of the file avr/Xassembler.txt.

Contents of the Xassembler.txt file for Atmega

No question of rewriting an assembler. Might as well take back the one that already exists in FlashForth: FlashForth assembler for Atmega chips

In order to make the contents of this file compatible with gForth, we modify very slightly its content by putting at the beginning of the file:

\ define Xassembler  
vocabulary Xassembler 
Xassembler definitions 
 
: i, 
    , ; 
: flash 
    ; 
: ram 
    ; 
 
\ OFLASH  constant pfl 
\ RAMPZV  constant zfl     \ value [0..3]     

The rest of the source code is not modified, except for if, which has been provisionally neutralized pending an update.

The final idea is to replace this assembly code:

PLUS_L:
.db     NFA|INLINE4|1, "+"
 
PLUS:
        ld      t0, Y+        
        ld      t1, Y+
        add     tosl, t0
        adc     tosh, t1
        ret

by this in our primitives:

code + 
   y+ t0 ld, 
   y+ t1 ld, 
   t0 tosl add, 
   t1 tosh adc, 
   ret, 
end-code 

We will therefore need to define the words code and end-code in the meta vocabulary. This is what we will see in another article..