[OpenBIOS] [PATCH] ppc: add Adler-32 checksum capability with copyright hack

Mark Cave-Ayland mark.cave-ayland at ilande.co.uk
Wed May 27 00:37:12 CEST 2015


On 26/05/15 17:48, Cormac O'Brien wrote:

Hi Cormac,

> This patch implements Adler-32 checksum support for compatibility with Mac
> OS 9. Since OS 9 is the only client known to use the Adler-32 function, we
> bind the copyright message needed by OS 9 when the function is called.
> 
> Signed-off-by: Cormac O'Brien <i.am.cormac.obrien at gmail.com>
> 
> ---
>  arch/ppc/qemu/init.c  | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  arch/ppc/qemu/qemu.fs | 13 ++++++++++++
>  2 files changed, 68 insertions(+)
> 
> diff --git a/arch/ppc/qemu/init.c b/arch/ppc/qemu/init.c
> index 4fe8b72..84a3615 100644
> --- a/arch/ppc/qemu/init.c
> +++ b/arch/ppc/qemu/init.c
> @@ -680,6 +680,58 @@ static void ffilll(void)
>      }   
>  }
>  
> +/*
> + * adler32        ( adler buf len -- checksum )
> + *
> + * Adapted from Mark Adler's original implementation (zlib license)
> + */
> +
> +#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
> +#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
> +#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
> +#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
> +#define DO16(buf)   DO8(buf,0); DO8(buf,8);
> +
> +static void adler32(void)
> +{
> +    uint32_t len = (uint32_t)POP();
> +    char *buf = (char *)POP();
> +    uint32_t adler = (uint32_t)POP();
> +
> +    if (buf == NULL) {
> +        RET(-1);
> +    }
> +
> +    uint32_t base = 65521;
> +    uint32_t nmax = 5552;
> +
> +    uint32_t s1 = adler & 0xffff;
> +    uint32_t s2 = (adler >> 16) & 0xffff;
> +
> +    uint32_t k;
> +    while (len > 0) {
> +        k = (len < nmax ? len : nmax);
> +        len -= k;
> +
> +        while (k >= 16) {
> +            DO16(buf);
> +            buf += 16;
> +            k -= 16;
> +        }
> +        if (k != 0) {
> +            do {
> +                s1 += *buf++;
> +                s2 += s1;
> +            } while (--k);
> +        }
> +
> +        s1 %= base;
> +        s2 %= base;
> +    }
> +
> +    RET(s2 << 16 | s1);
> +}
> +
>  void
>  arch_of_init(void)
>  {
> @@ -945,6 +997,9 @@ arch_of_init(void)
>  
>      /* Implementation of filll word (required by BootX) */
>      bind_func("filll", ffilll);
> +
> +    /* Adler-32 required by Mac OS 9 */
> +    bind_func("(adler32)", adler32);
>      
>      bind_func("platform-boot", boot);
>      bind_func("(go)", go);
> diff --git a/arch/ppc/qemu/qemu.fs b/arch/ppc/qemu/qemu.fs
> index 458af1b..d2c6a4c 100644
> --- a/arch/ppc/qemu/qemu.fs
> +++ b/arch/ppc/qemu/qemu.fs
> @@ -93,3 +93,16 @@ variable keyboard-phandle 0 keyboard-phandle !
>  :noname
>    set-defaults
>  ; PREPOST-initializer
> +
> +\ -------------------------------------------------------------------------
> +\ Apple copyright hack
> +\ -------------------------------------------------------------------------
> +

I think this comment is a bit misleading since the adler32 word isn't
anything to do with the copyright hack. It's still a valid word, it just
so happens that it's a good injection point for a dummy copyright
property. Maybe just explain in the comment below that OS 9 does a fixed
string comparison on boot which is why we need to do this?

> +: adler32 ( adler buf len -- checksum )
> +  \ The only OS that calls this is Mac OS 9, so we take this opportunity to
> +  \ patch in the required copyright string.
> +  " /" find-device

The use of find-device here is likely to cause problems as it's
effectively changing the current device package which means when control
is returned to the boot script, it won't be in the device it thinks it is.

> +  " Copyright 1983-2001 Apple Computer, Inc. THIS MESSAGE FOR COMPATIBILITY PURPOSES ONLY. COPYRIGHT IS HELD BY THE OPENBIOS PROJECT AND ITS CONTRIBUTORS."
> +  encode-string " copyright" property

In OpenBIOS you should be able to use something like find-package and
set-property to set the property directly without having to change to a
different package.

And thinking about this more, with an enhanced comment above then
stopping the message just after "THIS MESSAGE IS FOR COMPATIBILITY
PURPOSES ONLY." should suffice as the context seems fairly clear.

> +  " (adler32)" evaluate

The normal convention is Forth is to search the dictionary for a word
(xt) and then execute it directly rather than directly execing strings
in the Forth interpreter.

At compile time you'd go for something like "['] myfunction execute" but
since (adler32) is only bound at runtime then you'll need to use $find
or similar to find it - there should be several existing examples around
in the source for you to study.


ATB,

Mark.




More information about the OpenBIOS mailing list