floppy: Ensure that RDATA pin is deasserted when drive is not selected.

Specifically, the gpio_configure_pin() in rdata_start() sets the pin
default state to O_TRUE (0) if the drive is selected when the read
stream starts. This causes the pin to be erroneously asserted in
_IRQ_SELA_changed when the drive is deselected.

One effect of this happened to be that drive A is drowned out on a
CPC 6128 if F-F was connected as drive B. The CPC 6128 selects drive B
most of the time (since SELB is generated simply as !SELA) and hence
made this bug extremely likely to trigger.

Thanks to ikonsgr on EAB (and Ebay!) for the bug report. His
Spectrum/Amstrad drive cables will now work properly with FlashFloppy!
This commit is contained in:
Keir Fraser 2017-09-25 21:26:53 +01:00
parent e82e584f39
commit bb7f7f0128
2 changed files with 4 additions and 4 deletions

View file

@ -11,7 +11,7 @@
#define GPI_bus GPI_floating #define GPI_bus GPI_floating
#define GPO_bus GPO_pushpull(_2MHz,O_FALSE) #define GPO_bus GPO_pushpull(_2MHz,O_FALSE)
#define AFO_bus AFO_pushpull(_2MHz) #define AFO_bus (AFO_pushpull(_2MHz) | (O_FALSE<<4))
#define m(bitnr) (1u<<(bitnr)) #define m(bitnr) (1u<<(bitnr))

View file

@ -116,17 +116,17 @@ static void _IRQ_SELA_changed(uint32_t _gpio_out_active)
/* Set pin_rdata as timer output (AFO_bus). */ /* Set pin_rdata as timer output (AFO_bus). */
if (dma_rd && (dma_rd->state == DMA_active)) if (dma_rd && (dma_rd->state == DMA_active))
gpio_data->crl = (gpio_data->crl & ~(0xfu<<(pin_rdata<<2))) gpio_data->crl = (gpio_data->crl & ~(0xfu<<(pin_rdata<<2)))
| (AFO_bus<<(pin_rdata<<2)); | ((AFO_bus&0xfu)<<(pin_rdata<<2));
/* Let main code know it can drive the bus until further notice. */ /* Let main code know it can drive the bus until further notice. */
drive.sel = 1; drive.sel = 1;
} else { } else {
/* SELA is deasserted (this drive is not selected). /* SELA is deasserted (this drive is not selected).
* Relinquish the bus by disabling all our asserted outputs. */ * Relinquish the bus by disabling all our asserted outputs. */
gpio_out->bsrr = _gpio_out_active; gpio_out->bsrr = _gpio_out_active;
/* Set pin_rdata to GPO_pushpull(_2MHz). */ /* Set pin_rdata as quiescent (GPO_bus). */
if (dma_rd && (dma_rd->state == DMA_active)) if (dma_rd && (dma_rd->state == DMA_active))
gpio_data->crl = (gpio_data->crl & ~(0xfu<<(pin_rdata<<2))) gpio_data->crl = (gpio_data->crl & ~(0xfu<<(pin_rdata<<2)))
| (2<<(pin_rdata<<2)); | ((GPO_bus&0xfu)<<(pin_rdata<<2));
/* Tell main code to leave the bus alone. */ /* Tell main code to leave the bus alone. */
drive.sel = 0; drive.sel = 0;
} }