Anybody ever use Aztec C for APPLEII?

From: Sean 'Captain Napalm' Conner <spc_at_conman.org>
Date: Wed Apr 28 03:40:32 2004

It was thus said that the Great Ethan Dicks once stated:
>
> On Tue, Apr 27, 2004 at 06:33:35PM -0400, Sean 'Captain Napalm' Conner wrote:
>
> > The 6809 is geared more towards C (and higher level languages in general)
> > than the 6502.
>
> I'm not as familiar with the 6809 as I am with the 6502... what differences
> in architecture make it better? Larger stack frame? More (and larger)
> registers?

  Yes to the above. The 6809 has the following:

        A - 8bit accumulator
        B - 8bit accumulator
        DP - 8bit Direct Page [1]
        CC - 8bit condition code

        D - 16bit accumulator (reg A MSB, reg B LSB)
        X - 16bit index
        Y - 16bit index
        S - 16bit stack [2] / index
        U - 16bit stack [3] / index
        PC - 16bit program counter

        [1] The 6809 uses this as the MSB for 8-bit
                direct addressing modes---it defaults to
                $00 on startup.

        [2] Hardware stack pointer, for use with BSR,
                JSR, and interrupts. Can also be used as
                an index register.

        [3] software stack pointer, meant to be used
                to pass parameters, but can also be used
                as an index register

  It also supports more addressing modes than the 6502 like position
independant (indexed off PC) and indirect addressing (in C, this would be
dereferencing a pointer). It also has a fairly orthogonal instruction set
which also helps in compiler writing (in my opinion). Of all the 8bit CPUs,
this happens to be my favorite.

> > (Z80) may produce mediocre code.
>
> Is that inherent to the CPU architecture, or just a coincidence of how
> much effort people have (or have not) put into C compilers for 8-bit
> machines?

  Probably a bit of both. I know the instruction set of the 8080/Z80 is not
as orthogonal as the 6800/6809, with quite a few specialized instructions,
and only a single accumulator. To use the 8086 as an example (since it's
derived from the 8080), it takes quite a bit of compiler smarts to turn:

        int i;
        char *s = src;
        char *d = dest;

        for (i = 0 ; i < SIZE ; i++)
                *d++ = *s++;

into:

        mov cx,SIZE
        mov si,[bp + src]
        mov di,[bp + dest]
        rep movsb

        ; a smart compiler might realize that s,d and i aren't
        ; used after this point, and discard the follow
        ; instructions ... (and this applies to each of the examples
        ; below as well)

        mov [bp + src],si
        mov [bp + dest],di
        mov word ptr [bp + i],SIZE

  A horribly written C compiler might produce (and I have seen this):


        mov ax,[bp + src]
        mov [bp + s],ax
        mov ax,[bp + dest]
        mov [bp + d],ax

        mov word ptr [bp+i],0

loop: mov ax,[bp + i]
        cmp ax,SIZE
        je loop_exit
        mov bx,[bp + s]
        mov al,[bx]
        inc bx
        mov [bp + s],bx
        mov bx,[bp + d]
        mov [bx],al
        inc bx
        mov [bp + d],bx
        mov ax,[bp + i]
        inc ax
        mov [bp + i],ax
        jmps loop
loop_exit:

  while a slightly better one would see that s and d are used as memory
pointers, and that i is used as a counter so it too could be used in a
register:

        xor dx,dx
        mov si,[bp + src]
        mov di,[bp + dest]

loop: mov al,[si]
        inc si
        mov [di],al
        inc di
        inc dx,
        cmp dx,SIZE
        jl loop

        mov [bp + s],si
        mov [bp + d],di
        mov [bp + i],dx

  You get the idea. You, looking at the C code, can guess immediately that
you should probably use REP MOVSB, but a compiler can't guess that outright,
at least, not without a lot of smarts.

  On the 6809 though, will look more like the above sequence (assuming a
half-way decent compiler) and that's about as good as you can get, since the
6809 doesn't have specialized instructions:

        clra
        clrb
        std i,u
        ldx src,u
        ldy dest,u

loop: lda ,x+
        sty ,y+
        ldd i,u
        addd #1
        std i,u
        cmpd #SIZE
        bne loop

        stx src,u
        sty dest,u

  Although, if SIZE doesn't exceed 255, the compiler could produce:

        clrb
        ldx src,u
        ldy dest,u

loop: lda ,x+
        sta ,y+
        incb
        cmpb #SIZE
        bne loop

        ldb #SIZE
        clr i_high,u
        stb i_low,u
        stx src,u
        sty dest,u

  Of course, you should replace:

        for (i = 0 ; i < SIZE ; i++)
                *d++ = *s++;

  with

        memcpy(dest,src,SIZE);

  which a C compiler is free to replace with:

        mov cx,SIZE
        mov si,[bp + src]
        mov di,[bp + dest]
        rep movsb

  or (on a 6809):

        ldb #SIZE ; assuming SIZE < 256
        ldx src,u
        ldy dest,u
loop: lda ,x+
        sta ,y+
        decb
        bne loop

  Even a poorly written compiler can be written with *that* amount of smarts
(basically, inlining anything defined in <string.h>). But I'm digressing.

  -spc (Okay, should probably go to bed now ... )
Received on Wed Apr 28 2004 - 03:40:32 BST

This archive was generated by hypermail 2.3.0 : Fri Oct 10 2014 - 23:36:31 BST