Compare commits
1 commit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b9850ffda |
3 changed files with 102 additions and 0 deletions
1
Rules.mk
1
Rules.mk
|
|
@ -15,6 +15,7 @@ FLAGS += -Wstrict-prototypes -Wredundant-decls -Wnested-externs
|
||||||
FLAGS += -fno-common -fno-exceptions -fno-strict-aliasing
|
FLAGS += -fno-common -fno-exceptions -fno-strict-aliasing
|
||||||
FLAGS += -mlittle-endian -mthumb -mfloat-abi=soft
|
FLAGS += -mlittle-endian -mthumb -mfloat-abi=soft
|
||||||
FLAGS += -Wno-unused-value -ffunction-sections
|
FLAGS += -Wno-unused-value -ffunction-sections
|
||||||
|
FLAGS += -DAPPLE2=1
|
||||||
|
|
||||||
## STM32F105
|
## STM32F105
|
||||||
ifeq ($(mcu),stm32f105)
|
ifeq ($(mcu),stm32f105)
|
||||||
|
|
|
||||||
|
|
@ -219,10 +219,12 @@ void board_init(void)
|
||||||
|
|
||||||
if (mcu_package == MCU_QFN32) {
|
if (mcu_package == MCU_QFN32) {
|
||||||
|
|
||||||
|
#if !defined(APPLE2)
|
||||||
/* The sole QFN32 board is a KC30 Rev 1 design. */
|
/* The sole QFN32 board is a KC30 Rev 1 design. */
|
||||||
has_kc30_header = 1;
|
has_kc30_header = 1;
|
||||||
|
|
||||||
pa_skip &= ~(1<<10); /* PA10 is not used as serial rx */
|
pa_skip &= ~(1<<10); /* PA10 is not used as serial rx */
|
||||||
|
#endif
|
||||||
pb_skip |= 1<<1; /* PB1 is a floppy input (WGATE) */
|
pb_skip |= 1<<1; /* PB1 is a floppy input (WGATE) */
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,15 @@
|
||||||
|
|
||||||
/* Input pins: DIR=PB0, STEP=PA1, SELA=PA0, SELB=PA3, WGATE=PB9, SIDE=PB4,
|
/* Input pins: DIR=PB0, STEP=PA1, SELA=PA0, SELB=PA3, WGATE=PB9, SIDE=PB4,
|
||||||
* MOTOR=PA15/PB15 */
|
* MOTOR=PA15/PB15 */
|
||||||
|
#if defined(APPLE2)
|
||||||
|
#define pin_pha0 6 /* PA6 */
|
||||||
|
#define pin_pha1 15 /* PA15 */
|
||||||
|
#define pin_pha2 0 /* PB0 */
|
||||||
|
#define pin_pha3 1 /* PA1 */
|
||||||
|
#else
|
||||||
#define pin_dir 0 /* PB0 */
|
#define pin_dir 0 /* PB0 */
|
||||||
#define pin_step 1 /* PA1 */
|
#define pin_step 1 /* PA1 */
|
||||||
|
#endif
|
||||||
#define pin_sel0 0 /* PA0 */
|
#define pin_sel0 0 /* PA0 */
|
||||||
#define pin_sel1 3 /* PA3 */
|
#define pin_sel1 3 /* PA3 */
|
||||||
static uint8_t pin_wgate = 9; /* PB9 */
|
static uint8_t pin_wgate = 9; /* PB9 */
|
||||||
|
|
@ -51,7 +58,12 @@ void IRQ_6(void) __attribute__((alias("IRQ_SELA_changed"))); /* EXTI0 */
|
||||||
void IRQ_7(void) __attribute__((alias("IRQ_WGATE_rotary"))); /* EXTI1 */
|
void IRQ_7(void) __attribute__((alias("IRQ_WGATE_rotary"))); /* EXTI1 */
|
||||||
void IRQ_10(void) __attribute__((alias("IRQ_SIDE_changed"))); /* EXTI4 */
|
void IRQ_10(void) __attribute__((alias("IRQ_SIDE_changed"))); /* EXTI4 */
|
||||||
void IRQ_23(void) __attribute__((alias("IRQ_WGATE_rotary"))); /* EXTI9_5 */
|
void IRQ_23(void) __attribute__((alias("IRQ_WGATE_rotary"))); /* EXTI9_5 */
|
||||||
|
#if defined(APPLE2)
|
||||||
|
static struct timer step_timer;
|
||||||
|
static void POLL_step(void *unused);
|
||||||
|
#else
|
||||||
void IRQ_28(void) __attribute__((alias("IRQ_STEP_changed"))); /* TMR2 */
|
void IRQ_28(void) __attribute__((alias("IRQ_STEP_changed"))); /* TMR2 */
|
||||||
|
#endif
|
||||||
void IRQ_40(void) __attribute__((alias("IRQ_MOTOR_CHGRST_rotary"))); /* EXTI15_10 */
|
void IRQ_40(void) __attribute__((alias("IRQ_MOTOR_CHGRST_rotary"))); /* EXTI15_10 */
|
||||||
#define MOTOR_CHGRST_IRQ 40
|
#define MOTOR_CHGRST_IRQ 40
|
||||||
static const struct exti_irq exti_irqs[] = {
|
static const struct exti_irq exti_irqs[] = {
|
||||||
|
|
@ -80,6 +92,7 @@ static volatile uint32_t *p_dma_rd_active;
|
||||||
|
|
||||||
bool_t floppy_ribbon_is_reversed(void)
|
bool_t floppy_ribbon_is_reversed(void)
|
||||||
{
|
{
|
||||||
|
#if !defined(APPLE2)
|
||||||
time_t t_start = time_now();
|
time_t t_start = time_now();
|
||||||
|
|
||||||
/* If ribbon is reversed then most/all inputs are grounded.
|
/* If ribbon is reversed then most/all inputs are grounded.
|
||||||
|
|
@ -91,6 +104,7 @@ bool_t floppy_ribbon_is_reversed(void)
|
||||||
if (time_since(t_start) > time_ms(1000))
|
if (time_since(t_start) > time_ms(1000))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +125,9 @@ static void board_floppy_init(void)
|
||||||
gpio->crl = (gpio->crl & ~(0xfu<<((pin)<<2))) \
|
gpio->crl = (gpio->crl & ~(0xfu<<((pin)<<2))) \
|
||||||
| (((mode)&0xfu)<<((pin)<<2))
|
| (((mode)&0xfu)<<((pin)<<2))
|
||||||
|
|
||||||
|
#if !defined(APPLE2)
|
||||||
gpio_configure_pin(gpioa, pin_step, GPI_bus);
|
gpio_configure_pin(gpioa, pin_step, GPI_bus);
|
||||||
|
#endif
|
||||||
gpio_configure_pin(gpio_data, pin_wdata, GPI_bus);
|
gpio_configure_pin(gpio_data, pin_wdata, GPI_bus);
|
||||||
gpio_configure_pin(gpio_data, pin_rdata, GPO_bus);
|
gpio_configure_pin(gpio_data, pin_rdata, GPO_bus);
|
||||||
|
|
||||||
|
|
@ -122,8 +138,10 @@ static void board_floppy_init(void)
|
||||||
| (((mode)&0x3u)<<((pin)<<1));
|
| (((mode)&0x3u)<<((pin)<<1));
|
||||||
#define afio syscfg
|
#define afio syscfg
|
||||||
|
|
||||||
|
#if !defined(APPLE2)
|
||||||
gpio_set_af(gpioa, pin_step, 1);
|
gpio_set_af(gpioa, pin_step, 1);
|
||||||
gpio_configure_pin(gpioa, pin_step, AFI(PUPD_none));
|
gpio_configure_pin(gpioa, pin_step, AFI(PUPD_none));
|
||||||
|
#endif
|
||||||
|
|
||||||
gpio_set_af(gpio_data, pin_wdata, 1);
|
gpio_set_af(gpio_data, pin_wdata, 1);
|
||||||
gpio_configure_pin(gpio_data, pin_wdata, AFI(PUPD_none));
|
gpio_configure_pin(gpio_data, pin_wdata, AFI(PUPD_none));
|
||||||
|
|
@ -149,7 +167,16 @@ static void board_floppy_init(void)
|
||||||
pin_wgate = 1; /* PB1 */
|
pin_wgate = 1; /* PB1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(APPLE2)
|
||||||
|
gpio_configure_pin(gpioa, pin_pha0, GPI_bus);
|
||||||
|
gpio_configure_pin(gpioa, pin_pha1, GPI_bus);
|
||||||
|
gpio_configure_pin(gpiob, pin_pha2, GPI_bus);
|
||||||
|
gpio_configure_pin(gpioa, pin_pha3, GPI_bus);
|
||||||
|
timer_init(&step_timer, POLL_step, NULL);
|
||||||
|
timer_set(&step_timer, time_now());
|
||||||
|
#else
|
||||||
gpio_configure_pin(gpiob, pin_dir, GPI_bus);
|
gpio_configure_pin(gpiob, pin_dir, GPI_bus);
|
||||||
|
#endif
|
||||||
gpio_configure_pin(gpioa, pin_sel0, GPI_bus);
|
gpio_configure_pin(gpioa, pin_sel0, GPI_bus);
|
||||||
gpio_configure_pin(gpiob, pin_wgate, GPI_bus);
|
gpio_configure_pin(gpiob, pin_wgate, GPI_bus);
|
||||||
gpio_configure_pin(gpiob, pin_side, GPI_bus);
|
gpio_configure_pin(gpiob, pin_side, GPI_bus);
|
||||||
|
|
@ -275,6 +302,76 @@ static void update_SELA_irq(bool_t amiga_hd_id)
|
||||||
#undef OFF
|
#undef OFF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(APPLE2)
|
||||||
|
|
||||||
|
static void POLL_step(void *unused)
|
||||||
|
{
|
||||||
|
static unsigned int _pha;
|
||||||
|
|
||||||
|
struct drive *drv = &drive;
|
||||||
|
uint16_t idr_a, idr_b;
|
||||||
|
unsigned int pha;
|
||||||
|
|
||||||
|
/* Latch inputs. */
|
||||||
|
idr_a = gpioa->idr;
|
||||||
|
idr_b = gpiob->idr;
|
||||||
|
|
||||||
|
/* Bail if drive not selected. */
|
||||||
|
if (idr_a & m(pin_sel0)) {
|
||||||
|
_pha = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Debounce the phase signals. */
|
||||||
|
pha = _pha;
|
||||||
|
_pha = ((idr_a >> pin_pha0) & 1)
|
||||||
|
| ((idr_a >> (pin_pha1-1)) & 2)
|
||||||
|
| ((idr_b << (2-pin_pha2)) & 4)
|
||||||
|
| ((idr_a << (3-pin_pha3)) & 8);
|
||||||
|
pha &= _pha;
|
||||||
|
|
||||||
|
/* Do nothing while we're mid-step. */
|
||||||
|
if (drv->step.state & STEP_active)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Rotate the phase bitmap so that the current phase is at bit 0. Note
|
||||||
|
* that the current phase is directly related to the current cylinder. */
|
||||||
|
pha = ((pha | (pha << 4)) >> (drv->cyl & 3)) & 0xf;
|
||||||
|
|
||||||
|
/* Conditions to action a head step:
|
||||||
|
* (1) Only one phase is asserted;
|
||||||
|
* (2) That phase is adjacent to the current phase;
|
||||||
|
* (3) We haven't hit a cylinder hard limit. */
|
||||||
|
switch (pha) {
|
||||||
|
case m(1): /* Phase +1 only */
|
||||||
|
if (drv->cyl == ff_cfg.max_cyl)
|
||||||
|
goto out;
|
||||||
|
drv->step.inward = TRUE;
|
||||||
|
break;
|
||||||
|
case m(3): /* Phase -1 only */
|
||||||
|
if (drv->cyl == 0)
|
||||||
|
goto out;
|
||||||
|
drv->step.inward = FALSE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Action a head step. */
|
||||||
|
if (dma_rd != NULL)
|
||||||
|
rdata_stop();
|
||||||
|
if (dma_wr != NULL)
|
||||||
|
wdata_stop();
|
||||||
|
drv->step.start = time_now();
|
||||||
|
drv->step.state = STEP_started;
|
||||||
|
IRQx_set_pending(FLOPPY_SOFTIRQ);
|
||||||
|
|
||||||
|
out:
|
||||||
|
timer_set(&step_timer, step_timer.deadline + time_ms(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
static bool_t drive_is_writing(void)
|
static bool_t drive_is_writing(void)
|
||||||
{
|
{
|
||||||
if (!dma_wr)
|
if (!dma_wr)
|
||||||
|
|
@ -335,6 +432,8 @@ static void IRQ_STEP_changed(void)
|
||||||
IRQx_set_pending(FLOPPY_SOFTIRQ);
|
IRQx_set_pending(FLOPPY_SOFTIRQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static void IRQ_SIDE_changed(void)
|
static void IRQ_SIDE_changed(void)
|
||||||
{
|
{
|
||||||
stk_time_t t = stk_now();
|
stk_time_t t = stk_now();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue