From 730af4dd536b2d043c7aa13405bc4dc332adbced Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 4 Aug 2022 23:52:25 +0200 Subject: [PATCH] Implemented more previously unimplemented AT NVR behavior. --- src/nvr_at.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/nvr_at.c b/src/nvr_at.c index bb4c38b85..eb749ff49 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -467,10 +467,10 @@ timer_update(void *priv) nvr->regs[RTC_REGC] |= REGC_AF; if (nvr->regs[RTC_REGB] & REGB_AIE) { /* Generate an interrupt. */ - if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) - picint(1 << nvr->irq); - - nvr->regs[RTC_REGC] |= REGC_IRQF; + if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) { + picintlevel(1 << nvr->irq); + nvr->regs[RTC_REGC] |= REGC_IRQF; + } } } @@ -481,10 +481,10 @@ timer_update(void *priv) nvr->regs[RTC_REGC] |= REGC_UF; if (nvr->regs[RTC_REGB] & REGB_UIE) { /* Generate an interrupt. */ - if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) - picint(1 << nvr->irq); - - nvr->regs[RTC_REGC] |= REGC_IRQF; + if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) { + picintlevel(1 << nvr->irq); + nvr->regs[RTC_REGC] |= REGC_IRQF; + } } } } @@ -533,10 +533,10 @@ timer_intr(void *priv) nvr->regs[RTC_REGC] |= REGC_PF; if (nvr->regs[RTC_REGB] & REGB_PIE) { /* Generate an interrupt. */ - if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) - picint(1 << nvr->irq); - - nvr->regs[RTC_REGC] |= REGC_IRQF; + if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) { + picintlevel(1 << nvr->irq); + nvr->regs[RTC_REGC] |= REGC_IRQF; + } } } } @@ -592,6 +592,7 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv) local_t *local = (local_t *)nvr->data; struct tm tm; uint8_t old; + uint8_t irq = 0, old_irq = 0; old = nvr->regs[reg]; switch(reg) { @@ -601,12 +602,21 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv) break; case RTC_REGB: + old_irq = (nvr->regs[RTC_REGB] & nvr->regs[RTC_REGC]) & 0x70; nvr->regs[RTC_REGB] = val; if (((old^val) & REGB_SET) && (val & REGB_SET)) { /* According to the datasheet... */ nvr->regs[RTC_REGA] &= ~REGA_UIP; nvr->regs[RTC_REGB] &= ~REGB_UIE; } + irq = (nvr->regs[RTC_REGB] & nvr->regs[RTC_REGC]) & 0x70; + if (old_irq && !irq) { + picintc(1 << nvr->irq); + nvr->regs[RTC_REGC] &= ~REGC_IRQF; + } else if (!old_irq && irq) { + picintlevel(1 << nvr->irq); + nvr->regs[RTC_REGC] |= REGC_IRQF; + } break; case RTC_REGC: /* R/O */ @@ -694,8 +704,8 @@ nvr_read(uint16_t addr, void *priv) break; case RTC_REGC: - picintc(1 << nvr->irq); ret = nvr->regs[RTC_REGC]; + picintc(1 << nvr->irq); nvr->regs[RTC_REGC] = 0x00; break;