Am 08.04.19 um 22:45 schrieb Klaus Brandl:
> Hi,
> 
> i think i found two bugs in the z80 port:
> 
> buggy.c:
> __sfr __banked __at 0xf500 SPI_PORT_IN;
> 
> struct {
>       unsigned char SDHC : 1;
>       unsigned char FAT32 : 1;
> } SDFlags;
> 
> int main () {
>       SDFlags.SDHC = (SPI_PORT_IN & 0x40) ? 1 : 0;
>       return(SDFlags.SDHC);
> }
> 
> compiles to:
>                              53 ;buggy.c:9: SDFlags.SDHC = (SPI_PORT_IN
> & 0x40) ? 1 : 0;
>    0000 3E F5         [ 7]   54       ld      a,#>(_SPI_PORT_IN)
>    0002 DB 00         [11]   55       in      a,(#<(_SPI_PORT_IN))
> 
> SPI_PORT_IN should be:
>                                       ld      bc,#SPI_PORT_IN
>                                       in      a,(c)

The generated code here looks correct to me. From the Zilog Z80 user
manual, description of in a,(n): "The operand n is placed on the bottom
half (A0 through A7) of the address bus to select the I/O device at one
of 256 possible ports. The contents of the Accumulator also appear on
the top half (A8 through A15) of the address bus at this time."

> 
>    0004 E6 40         [ 7]   56       and     a, #0x40
>    0006 21r00r00      [10]   57       ld      hl,#_SDFlags
>    0009 E6 01         [ 7]   58       and     a,#0x01
> 
> What is this? It makes "a" broken.
> 
>    000B 4F            [ 4]   59       ld      c,a
>    000C 7E            [ 7]   60       ld      a,(hl)
>    000D E6 FE         [ 7]   61       and     a,#0xFE
>    000F B1            [ 4]   62       or      a,c
>    0010 77            [ 7]   63       ld      (hl),a
> 
> I think, it should be:
>                                       ld      hl,#_SDFlags
>                                       ld      c,a
>                                       ld      a,(hl)
>                                       bit     6,c
>                                       jr      z,zero
>                                       or      a,#0x01
>                                       jr      save
> zero:                                 and     a,#0xFE
> save:                                 ld      (hl),a
> 
> (or so...)
> 

I cannot reproduce this issue. Using SDCC 3.8.7 #11188 I get:

   0000 3E F5         [ 7]   53         ld      a, #>(_SPI_PORT_IN)
   0002 DB 00         [11]   54         in      a, (#<(_SPI_PORT_IN))
   0004 CB 77         [ 8]   55         bit     6, a
   0006 28 05         [12]   56         jr      Z,00103$
   0008 01 01 00      [10]   57         ld      bc, #0x0001
   000B 18 03         [12]   58         jr      00104$
   000D                      59 00103$:
   000D 01 00 00      [10]   60         ld      bc, #0x0000
   0010                      61 00104$:
   0010 79            [ 4]   62         ld      a, c
   0011 21r00r00      [10]   63         ld      hl, #_SDFlags
   0014 E6 01         [ 7]   64         and     a, #0x01
   0016 4F            [ 4]   65         ld      c, a
   0017 7E            [ 7]   66         ld      a, (hl)
   0018 E6 FE         [ 7]   67         and     a, #0xfe
   001A B1            [ 4]   68         or      a, c
   001B 77            [ 7]   69         ld      (hl), a
   001C 3Ar00r00      [13]   71         ld      a,(#_SDFlags + 0)
   001F E6 01         [ 7]   72         and     a, #0x01
   0021 6F            [ 4]   73         ld      l, a
   0022 26 00         [ 7]   74         ld      h, #0x00
   0024 C9            [10]   76         ret

Which looks correct, though not particularly efficient.

Philipp

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Sdcc-user mailing list
Sdcc-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sdcc-user

Reply via email to