Am Montag, den 08.04.2019, 23:36 +0200 schrieb Philipp Klaus Krause:
> 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_I
> > N))
> >
> > 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."
thanks, i didn't found the right manual yet, and have not seen this
syntax anywhere.
>
> >
> > 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.
you are right, it is only broken in 3.5.0, maybe i have forgotten one
step. But anyhow, the following is more efficient:
SDFlags.SDHC = 0;
if (SPI_PORT_IN & 0x40)
SDFlags.SDHC = 1;
Sorry for the noise!
Klaus
_______________________________________________
Sdcc-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sdcc-user