diff --git a/3B2/3b2_defs.h b/3B2/3b2_defs.h index 52dca354..fcd1a168 100644 --- a/3B2/3b2_defs.h +++ b/3B2/3b2_defs.h @@ -105,6 +105,7 @@ noret __libc_longjmp (jmp_buf buf, int val); #define STOP_EX 5 /* Exception */ #define STOP_ESTK 6 /* Exception stack too deep */ #define STOP_MMU 7 /* Unimplemented MMU Feature */ +#define STOP_POWER 8 /* System power-off */ /* Exceptional conditions handled within the instruction loop */ #define ABORT_EXC 1 /* CPU exception */ diff --git a/3B2/3b2_iu.c b/3B2/3b2_iu.c index 6e4ed633..2029fda0 100644 --- a/3B2/3b2_iu.c +++ b/3B2/3b2_iu.c @@ -66,6 +66,9 @@ IU_PORT iu_contty; /* The timer state */ IU_TIMER_STATE iu_timer_state; +/* The power flag */ +t_bool iu_killpower = FALSE; + /* Flags for incrementing mode pointers */ t_bool iu_increment_a = FALSE; t_bool iu_increment_b = FALSE; @@ -632,6 +635,12 @@ void iu_write(uint32 pa, uint32 val, size_t size) sim_debug(EXECUTE_MSG, &contty_dev, ">>> SOPR written: %02x\n", (uint8) val); + /* Bit 2 of the IU output register is used as a soft power + * switch. When set, the machine will power down + * immediately. */ + if (val & IU_KILLPWR) { + stop_reason = STOP_POWER; + } break; case ROPR: sim_debug(EXECUTE_MSG, &contty_dev, diff --git a/3B2/3b2_iu.h b/3B2/3b2_iu.h index edcc7a3b..0d12962b 100644 --- a/3B2/3b2_iu.h +++ b/3B2/3b2_iu.h @@ -113,6 +113,9 @@ #define UM_MASK 0x70 #define UM_SHIFT 4 +/* Power-off bit */ +#define IU_KILLPWR 0x04 + #define PORT_A 0 #define PORT_B 1 diff --git a/3B2/3b2_sys.c b/3B2/3b2_sys.c index 6eb68881..2234ccf4 100644 --- a/3B2/3b2_sys.c +++ b/3B2/3b2_sys.c @@ -72,7 +72,8 @@ const char *sim_stop_messages[] = { "IRQ", "Exception/Trap", "Exception Stack Too Deep", - "Unimplemented MMU Feature" + "Unimplemented MMU Feature", + "System Powered Off" }; void full_reset()