Skip to content
CS 233 // Spimbot
Pages

Interrupts

The game raises five interrupt lines. A line stays raised until the bot acknowledges it by writing any value to its ACK register, which is the interrupt's name followed by _ACK, such as BONK_ACK.

Interrupt Line Mask Kind Raised when
TIMER IP7 0x8000 Latch The cycle written to TIMER arrives
TERRITORY_DISCONNECTED IP5 0x2000 Counter The opponent's completed trail cuts some of the bot's territory off from its base
BONK IP4 0x1000 Latch The bot bonks
REQUEST_PUZZLE IP3 0x0800 Counter A requested puzzle arrives in its buffer
TRAIL_CANCELLED IP2 0x0400 Counter The bot is canceled

The mask is the line's bit in both Cause and Status. The kind sets how events add up:

  • Latch: one flag. Events while it is raised merge into it, and one ACK clears it.
  • Counter: a count of events. Each ACK takes one off, and the line stays raised while the count is above 0.

LAST_TRAIL_CANCEL_REASON holds only the latest reason, however many TRAIL_CANCELLED events are pending.

A write to TIMER sets one target cycle, replacing any earlier one. The line rises at the end of that cycle, or at the end of the current cycle if the target has passed.

Taking an interrupt

#

A bot takes an interrupt when Status.IE is set, Status.EXL is clear, and the line's bit is set in both Cause and Status. The simulator reference describes the mechanism. Cause shows the raised lines whether or not interrupts are enabled, so a bot can also poll Cause. This bot enables only the timer line and acknowledges it in its handler:

	.text
main:
	mfc0	$t1, $12		# Status
	li	$t2, 0xffff00ff
	and	$t1, $t1, $t2		# clear every mask bit
	ori	$t1, $t1, 0x8001	# TIMER line and IE
	mtc0	$t1, $12
	li	$t0, 0xffff0000
	lw	$t1, 0x1c($t0)		# TIMER: the current cycle
	addiu	$t1, $t1, 50000
	sw	$t1, 0x1c($t0)		# a TIMER interrupt in 50,000 cycles
loop:
	j	loop

	.ktext	0x80000180
	lui	$k0, 0xffff
	sw	$zero, 0x6c($k0)	# TIMER_ACK
	eret