diff --git a/3B2/3b2_cpu.c b/3B2/3b2_cpu.c index c41e06eb..b4de1283 100644 --- a/3B2/3b2_cpu.c +++ b/3B2/3b2_cpu.c @@ -3455,7 +3455,7 @@ static void cpu_calc_ints() cpu_int_ipl = cpu_int_vec = CPU_ID_IF_IPL; } else if ((csr_data & CSRUART) || (csr_data & CSRDMA)) { cpu_int_ipl = cpu_int_vec = CPU_IU_DMA_IPL; - } else if (csr_data & CSRCLK) { + } else if ((csr_data & CSRCLK) || (csr_data & CSRTIMO)) { cpu_int_ipl = cpu_int_vec = CPU_TMR_IPL; } else { cpu_int_ipl = cpu_int_vec = 0; diff --git a/3B2/3b2_sysdev.c b/3B2/3b2_sysdev.c index 1414992c..58c046a7 100644 --- a/3B2/3b2_sysdev.c +++ b/3B2/3b2_sysdev.c @@ -433,8 +433,14 @@ REG timer_reg[] = { { NULL } }; +MTAB timer_mod[] = { + { MTAB_XTD|MTAB_VDV|MTAB_VALR|MTAB_NC, 0, NULL, "SHUTDOWN", + &timer_set_shutdown, NULL, NULL, "Soft Power Shutdown" }, + { 0 } +}; + DEVICE timer_dev = { - "TIMER", timer_unit, timer_reg, NULL, + "TIMER", timer_unit, timer_reg, timer_mod, 1, 16, 8, 4, 16, 32, NULL, NULL, &timer_reset, NULL, NULL, NULL, NULL, @@ -468,6 +474,23 @@ t_stat timer_reset(DEVICE *dptr) { return SCPE_OK; } +t_stat timer_set_shutdown(UNIT *uptr, int32 val, CONST char* cptr, void* desc) +{ + struct timer_ctr *sanity = timer_unit[0].tmr; + + sim_debug(EXECUTE_MSG, &timer_dev, + "[%08x] Setting sanity timer to 0 for shutdown.\n", R[NUM_PC]); + + sanity->val = 0; + csr_data &= ~CSRCLK; + csr_data |= CSRTIMO; + + return SCPE_OK; +} + +/* + * Sanity Timer + */ t_stat timer0_svc(UNIT *uptr) { struct timer_ctr *ctr; @@ -486,6 +509,9 @@ t_stat timer0_svc(UNIT *uptr) return SCPE_OK; } +/* + * Interval Timer + */ t_stat timer1_svc(UNIT *uptr) { struct timer_ctr *ctr; @@ -505,6 +531,9 @@ t_stat timer1_svc(UNIT *uptr) return SCPE_OK; } +/* + * Bus Timeout Timer + */ t_stat timer2_svc(UNIT *uptr) { struct timer_ctr *ctr; diff --git a/3B2/3b2_sysdev.h b/3B2/3b2_sysdev.h index 63394a8f..8f749150 100644 --- a/3B2/3b2_sysdev.h +++ b/3B2/3b2_sysdev.h @@ -69,6 +69,7 @@ void timer_write(uint32 pa, uint32 val, size_t size); t_stat timer0_svc(UNIT *uptr); t_stat timer1_svc(UNIT *uptr); t_stat timer2_svc(UNIT *uptr); +t_stat timer_set_shutdown(UNIT *uptr, int32 val, CONST char *cptr, void *desc); /* CSR */ t_stat csr_svc(UNIT *uptr);