VAX: Fix Interval Timers
- Properly set the Interval Register when a running timer is stopped - Peoperly clear timer interrupt pending when CSR is updated - Properly handle the case when the timer is started with the interval register is 0. - Properly stop the running timer when it is restarted or adjusted with a new interval value. - Better debug info
This commit is contained in:
parent
fc25cf54fa
commit
ee4c33ead2
1 changed files with 29 additions and 16 deletions
|
@ -294,6 +294,7 @@ int32 ssc_rd (int32 pa);
|
||||||
void ssc_wr (int32 pa, int32 val, int32 lnt);
|
void ssc_wr (int32 pa, int32 val, int32 lnt);
|
||||||
int32 tmr_tir_rd (int32 tmr);
|
int32 tmr_tir_rd (int32 tmr);
|
||||||
void tmr_csr_wr (int32 tmr, int32 val);
|
void tmr_csr_wr (int32 tmr, int32 val);
|
||||||
|
int32 tmr_csr_rd (int32 tmr);
|
||||||
void tmr_sched (int32 tmr);
|
void tmr_sched (int32 tmr);
|
||||||
void tmr_incr (int32 tmr, uint32 inc);
|
void tmr_incr (int32 tmr, uint32 inc);
|
||||||
int32 tmr0_inta (void);
|
int32 tmr0_inta (void);
|
||||||
|
@ -1309,9 +1310,7 @@ switch (rg) {
|
||||||
return txcs_rd ();
|
return txcs_rd ();
|
||||||
|
|
||||||
case 0x40: /* T0CSR */
|
case 0x40: /* T0CSR */
|
||||||
sim_debug (DBG_REGR, &sysd_dev, "tmr_csr_rd(tmr=%d) - 0x%X", 0, tmr_csr[0]);
|
return tmr_csr_rd (0);
|
||||||
sim_debug_bits_hdr (DBG_REGR, &sysd_dev, " ", tmr_csr_bits, tmr_csr[0], tmr_csr[0], 1);
|
|
||||||
return tmr_csr[0];
|
|
||||||
|
|
||||||
case 0x41: /* T0INT */
|
case 0x41: /* T0INT */
|
||||||
return tmr_tir_rd (0);
|
return tmr_tir_rd (0);
|
||||||
|
@ -1325,9 +1324,7 @@ switch (rg) {
|
||||||
return tmr_tivr[0];
|
return tmr_tivr[0];
|
||||||
|
|
||||||
case 0x44: /* T1CSR */
|
case 0x44: /* T1CSR */
|
||||||
sim_debug (DBG_REGR, &sysd_dev, "tmr_csr_rd(tmr=%d) - 0x%X\n", 1, tmr_csr[1]);
|
return tmr_csr_rd (1);
|
||||||
sim_debug_bits_hdr (DBG_REGR, &sysd_dev, "tmr_csr_rd(tmr=1)", tmr_csr_bits, tmr_csr[1], tmr_csr[1], 1);
|
|
||||||
return tmr_csr[1];
|
|
||||||
|
|
||||||
case 0x45: /* T1INT */
|
case 0x45: /* T1INT */
|
||||||
return tmr_tir_rd (1);
|
return tmr_tir_rd (1);
|
||||||
|
@ -1512,6 +1509,13 @@ sim_debug (DBG_REGR, &sysd_dev, "tmr_tir_rd(tmr=%d) - 0x%X\n", tmr, tmr_tir[tmr]
|
||||||
return tmr_tir[tmr];
|
return tmr_tir[tmr];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 tmr_csr_rd (int32 tmr)
|
||||||
|
{
|
||||||
|
sim_debug (DBG_REGR, &sysd_dev, "tmr_csr_rd(tmr=%d) - 0x%X", tmr, tmr_csr[tmr]);
|
||||||
|
sim_debug_bits_hdr (DBG_REGR, &sysd_dev, " ", tmr_csr_bits, tmr_csr[tmr], tmr_csr[tmr], 1);
|
||||||
|
return tmr_csr[tmr];
|
||||||
|
}
|
||||||
|
|
||||||
void tmr_csr_wr (int32 tmr, int32 val)
|
void tmr_csr_wr (int32 tmr, int32 val)
|
||||||
{
|
{
|
||||||
int32 before_tmr_csr;
|
int32 before_tmr_csr;
|
||||||
|
@ -1520,20 +1524,23 @@ if ((tmr < 0) || (tmr > 1))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
before_tmr_csr = tmr_csr[tmr];
|
before_tmr_csr = tmr_csr[tmr];
|
||||||
sim_debug (DBG_REGW, &sysd_dev, "tmr_csr_wr(tmr=%d) - 0x%X", tmr, val);
|
sim_debug (DBG_REGW, &sysd_dev, "tmr_csr_wr(tmr=%d) - Writing 0x%X", tmr, val);
|
||||||
sim_debug_bits_hdr (DBG_REGW, &sysd_dev, " ", tmr_csr_bits, val, val, 1);
|
sim_debug_bits_hdr (DBG_REGW, &sysd_dev, " ", tmr_csr_bits, val, val, 1);
|
||||||
|
|
||||||
if ((val & TMR_CSR_RUN) == 0) { /* clearing run? */
|
if ((val & TMR_CSR_RUN) == 0) { /* clearing run? */
|
||||||
sim_cancel (&sysd_unit[tmr]); /* cancel timer */
|
|
||||||
if (tmr_csr[tmr] & TMR_CSR_RUN) /* run 1 -> 0? */
|
if (tmr_csr[tmr] & TMR_CSR_RUN) /* run 1 -> 0? */
|
||||||
tmr_tir[tmr] = tmr_tir_rd (tmr); /* update itr */
|
tmr_tir[tmr] = tmr_tir_rd (tmr); /* update itr */
|
||||||
|
sim_cancel (&sysd_unit[tmr]); /* cancel timer */
|
||||||
}
|
}
|
||||||
tmr_csr[tmr] = tmr_csr[tmr] & ~(val & TMR_CSR_W1C); /* W1C csr */
|
tmr_csr[tmr] = tmr_csr[tmr] & ~(val & TMR_CSR_W1C); /* W1C csr */
|
||||||
tmr_csr[tmr] = (tmr_csr[tmr] & ~TMR_CSR_RW) | /* new r/w */
|
tmr_csr[tmr] = (tmr_csr[tmr] & ~TMR_CSR_RW) | /* new r/w */
|
||||||
(val & TMR_CSR_RW);
|
(val & TMR_CSR_RW);
|
||||||
sim_debug_bits_hdr (DBG_REGW, &sysd_dev, "tmr_csr_wr() - Result", tmr_csr_bits, before_tmr_csr, tmr_csr[tmr], 1);
|
sim_debug (DBG_REGW, &sysd_dev, "tmr_csr_wr(tmr=%d) - ", tmr);
|
||||||
if (val & TMR_CSR_XFR) /* xfr set? */
|
sim_debug_bits_hdr (DBG_REGW, &sysd_dev, "Result", tmr_csr_bits, before_tmr_csr, tmr_csr[tmr], 1);
|
||||||
|
if (val & TMR_CSR_XFR) { /* xfr set? */
|
||||||
tmr_tir[tmr] = tmr_tnir[tmr];
|
tmr_tir[tmr] = tmr_tnir[tmr];
|
||||||
|
sim_debug (DBG_REGW, &sysd_dev, "tmr_csr_wr(tmr=%d) - XFR set TIR=0x%X\n", tmr, tmr_tir[tmr]);
|
||||||
|
}
|
||||||
if (val & TMR_CSR_RUN) { /* run? */
|
if (val & TMR_CSR_RUN) { /* run? */
|
||||||
if (val & TMR_CSR_XFR) /* new tir? */
|
if (val & TMR_CSR_XFR) /* new tir? */
|
||||||
sim_cancel (&sysd_unit[tmr]); /* stop prev */
|
sim_cancel (&sysd_unit[tmr]); /* stop prev */
|
||||||
|
@ -1546,8 +1553,8 @@ else
|
||||||
if (tmr_tir[tmr] == 0) /* if ovflo, */
|
if (tmr_tir[tmr] == 0) /* if ovflo, */
|
||||||
tmr_tir[tmr] = tmr_tnir[tmr]; /* reload tir */
|
tmr_tir[tmr] = tmr_tnir[tmr]; /* reload tir */
|
||||||
}
|
}
|
||||||
if ((tmr_csr[tmr] & (TMR_CSR_DON | TMR_CSR_IE)) != /* update int */
|
if ((before_tmr_csr & (TMR_CSR_DON | TMR_CSR_IE)) &&
|
||||||
(TMR_CSR_DON | TMR_CSR_IE)) {
|
((tmr_csr[tmr] & (TMR_CSR_DON | TMR_CSR_IE)) == 0)) {/* update int */
|
||||||
sim_debug (DBG_INT, &sysd_dev, "tmr_csr_wr(tmr=%d) - CLR_INT\n", tmr);
|
sim_debug (DBG_INT, &sysd_dev, "tmr_csr_wr(tmr=%d) - CLR_INT\n", tmr);
|
||||||
if (tmr)
|
if (tmr)
|
||||||
CLR_INT (TMR1);
|
CLR_INT (TMR1);
|
||||||
|
@ -1586,7 +1593,7 @@ if (new_tir < tmr_tir[tmr]) { /* ovflo? */
|
||||||
tmr_sched (tmr); /* reactivate */
|
tmr_sched (tmr); /* reactivate */
|
||||||
}
|
}
|
||||||
if (tmr_csr[tmr] & TMR_CSR_IE) { /* set int req */
|
if (tmr_csr[tmr] & TMR_CSR_IE) { /* set int req */
|
||||||
sim_debug (DBG_INT, &sysd_dev, "tmr_csr_wr(tmr=%d) - SET_INT\n", tmr);
|
sim_debug (DBG_INT, &sysd_dev, "tmr_incr(tmr=%d) - SET_INT\n", tmr);
|
||||||
if (tmr)
|
if (tmr)
|
||||||
SET_INT (TMR1);
|
SET_INT (TMR1);
|
||||||
else
|
else
|
||||||
|
@ -1605,27 +1612,33 @@ else {
|
||||||
void tmr_sched (int32 tmr)
|
void tmr_sched (int32 tmr)
|
||||||
{
|
{
|
||||||
uint32 usecs_sched = tmr_tir[tmr] ? (~tmr_tir[tmr] + 1) : 0xFFFFFFFF;
|
uint32 usecs_sched = tmr_tir[tmr] ? (~tmr_tir[tmr] + 1) : 0xFFFFFFFF;
|
||||||
|
double usecs_sched_d = tmr_tir[tmr] ? (double)(~tmr_tir[tmr] + 1) : (1.0 + (double)0xFFFFFFFFu);
|
||||||
|
|
||||||
|
sim_cancel (&sysd_unit[tmr]); /* Make sure not active */
|
||||||
|
if (sysd_unit[tmr].usecs_remaining != 0.0)
|
||||||
|
sim_debug (DBG_SCHD, &sysd_dev, "tmr_sched(tmr=%d) - BUG - usecs remaining = %.0f usecs\n", tmr, sysd_unit[tmr].usecs_remaining);
|
||||||
if ((ADDR_IS_ROM(fault_PC)) && /* running from ROM and */
|
if ((ADDR_IS_ROM(fault_PC)) && /* running from ROM and */
|
||||||
(usecs_sched < TMR_INC)) { /* short delay? */
|
(usecs_sched < TMR_INC)) { /* short delay? */
|
||||||
tmr_inst[tmr] = TRUE; /* wait for instructions */
|
tmr_inst[tmr] = TRUE; /* wait for instructions */
|
||||||
sim_debug (DBG_SCHD, &sysd_dev, "tmr_sched(tmr=%d) - after %u instructions\n", tmr, usecs_sched);
|
|
||||||
sim_activate (&sysd_unit[tmr], usecs_sched);
|
sim_activate (&sysd_unit[tmr], usecs_sched);
|
||||||
|
sim_debug (DBG_SCHD, &sysd_dev, "tmr_sched(tmr=%d) - after %u instructions - activate after: %.0f usecs\n", tmr, usecs_sched, sim_activate_time_usecs (&sysd_unit[tmr]));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tmr_inst[tmr] = FALSE;
|
tmr_inst[tmr] = FALSE;
|
||||||
sim_debug (DBG_SCHD, &sysd_dev, "tmr_sched(tmr=%d) - after %u usecs\n", tmr, usecs_sched);
|
sim_activate_after_d (&sysd_unit[tmr], usecs_sched_d);
|
||||||
sim_activate_after (&sysd_unit[tmr], usecs_sched);
|
sim_debug (DBG_SCHD, &sysd_dev, "tmr_sched(tmr=%d) - after %.0f usecs - activate after: %.0f usecs\n", tmr, usecs_sched_d, sim_activate_time_usecs (&sysd_unit[tmr]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 tmr0_inta (void)
|
int32 tmr0_inta (void)
|
||||||
{
|
{
|
||||||
|
sim_debug (DBG_INT, &sysd_dev, "tmr0_inta() - Int Ack - Vector=0x%X\n", tmr_tivr[0]);
|
||||||
return tmr_tivr[0];
|
return tmr_tivr[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 tmr1_inta (void)
|
int32 tmr1_inta (void)
|
||||||
{
|
{
|
||||||
|
sim_debug (DBG_INT, &sysd_dev, "tmr1_inta() - Int Ack - Vector=0x%X\n", tmr_tivr[1]);
|
||||||
return tmr_tivr[1];
|
return tmr_tivr[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue