July 28, 2025

Sun 3 bootrom souce - the Sun assembler

As you might expect, the bootrom source includes a fair number of assembly language source files. These were written in the Sun assembler syntax, which has significant differences from what the Gnu assembler expects. Here are some examples.
First some Sun "dialect":
    movl    #0x77770000,d7      | 7777 pattern for "in diag.s"
    movw    #0x2700, sr     	| put cpu on level 7

    subl    a7,a7
    movc    a7, vbr         	| reset the vector base register

    moveq   #FC_MMU,d0
    movc    d0,sfc
    movc    d0,dfc
And next (as an experiment) I hand edit the above into gas dialect:
    movl    #0x77770000,%d7      | 7777 pattern for "in diag.s"
    movw    #0x2700, %sr         | put cpu on level 7
    movew   #0x2700, %sr         | put cpu on level 7

    subl    %a7,%a7
    movc    %a7, %vbr             | reset the vector base register

    moveq   #FC_MMU,%d0
    movq    #FC_MMU,%d0
    movc    %d0,%sfc
    movc    %d0,%dfc
    movec   %d0,%dfc
To my utter amazement, the gnu assembler accepts either the abbreviated sun mnemonics or the longer mnemonics. I.e. either movc or movec is just fine. This saves me a lot of work. It is necessary to put a parenthesis in front of each register name. This is intended to differentiate between (for example) a register named dfc and a variable named dfc.

Obviously the sun programmers were not concerned about this. The gnu assembler offers a switch "--register-prefix-optional" to allow the percent sign to be omitted. Using this switch would appear to allow the sun sources to be assembled without some kind of translation. I was fully expecting to have to code up some translator to map mnemonics and add the parentheses to register names.
Not having to do this is pleasant news.

The Gnu assembler

There is a nice 238 page PDF document entitled "Using as" for the Gnu assembler.
  • Gnu assembler manual (238 pages, PDF)
  • Section 8.17 (beginning on page 135) gives "M680x0 Dependent Features" and is highly relevant for the current project.

    The C preprocessor

    The Makefile from sun ran the preprocessor for each file explicitly using a sequence of commands like the following:
    romvec.o: ../sun3/romvec.s
        cp ../sun3/romvec.s romvec.c
        ${CC} -E -DASM ${CFLAGS} romvec.c >romvec.i
        ${AS} ${LFLAG} romvec.i -o romvec.o
        rm -f romvec.c romvec.i
    

    These days this could be done more simply by renaming the file to romvec.S and then feeding it to gcc. Maybe something like this:

    romvec.o: ../sun3/romvec.s
        cp ../sun3/romvec.s romvec.S
        ${CC} -c romvec.S
        rm -f romvec.S
    

    Rather than this, I would just rename all the assembler files from *.s to *.S. I don't know why the capital "S" allows this behavior, but it does while the lowercase does not. Most likely this is explained and documented somewhere. Making this change would remove a lot of "fluff" from the Makefile.

    There is even a way to avoid the rename, use gcc with this option:

    -x assembler-with-cpp
    
    With this switch it ought to be possible to do this:
    romvec.o: ../sun3/romvec.s
        ${CC} -x assembler-with-cpp -c ../sun3/romvec.s
    

    Note that the preprocessor is essential to perform conditional compilation of things that depend on SIRIUS and CARERRA, not just to interpolate values set by #define statements, though that is also vital.

    After some experimentation, the actual line I am now using in my makefile is:

    m68k-linux-gnu-gcc -DASM -march=68020 -mcpu=68020 -x assembler-with-cpp -Wa,--register-prefix-optional -Wno-endif-labels -c ../sun3/trap.s
    

    local symbol (label) names

    The sun code uses local labels like this:
        lea IDPROMOFF,a1    | select id prom
        jra 2$      		| Enter loop at bottom as usual for dbra
    1$: movsb   a1@+,d2     | get a byte
        movb    d2,a0@+     | save it
    2$: dbra    d1,1$       | and loop
    
    The Gnu assembler uses a different scheme, without the dollar sign:
        lea IDPROMOFF,a1    | select id prom
        jra 2f      		| Enter loop at bottom as usual for dbra
    1:  movsb   a1@+,d2     | get a byte
        movb    d2,a0@+     | save it
    2:  dbra    d1,1b       | and loop
    
    Here the letters "f" and "b" indicate forward and backward. The Gnu scheme allows there to be several labels with the same number, for what that might be worth, thus making such labels "more local".

    Some kind of translator could be written to handle this, but I will just modify such code by hand.


    Feedback? Questions? Drop me a line!

    Tom's Computer Info / tom@mmto.org