Skip to content

Instantly share code, notes, and snippets.

@cheapie
Last active May 4, 2026 09:34
Show Gist options
  • Select an option

  • Save cheapie/864a0df90c9ab744f4829f911e88fa80 to your computer and use it in GitHub Desktop.

Select an option

Save cheapie/864a0df90c9ab744f4829f911e88fa80 to your computer and use it in GitHub Desktop.
li a7,134 # Clear digilines buffer
ecall
restart:
# Hardware initialization
# Make sure light is off
li a7,129 # Send digilines message
la a0,lightchannel
la a1,lightoffmsg
ecall
# Make sure bell is off
li a7,129 # Send digilines message
la a0,bellchannel
la a1,belloffmsg
ecall
# Make sure gate is up
li a7,129 # Send digilines message
la a0,gatechannel
la a1,gateupmsg
ecall
receiveloop:
li a7,133 # Get digilines buffer level
ecall
beq a0,x0,receiveloop # If no messages yet, restart the loop
li a7,135 # Read digilines message
la a0,channelbuf
li a1,16 # Channel buffer size
la a2,msgbuf
li a3,16 # Message buffer size
ecall
# Check if it's the right channel
la a0,channelbuf
la a1,detectchannel
call strcmp
beq a0,x0,receiveloop # Not the right channel, ignore it
# Turn the light yellow
li a7,129 # Send digilines message
la a0,lightchannel
la a1,lightyellowmsg
ecall
# Wait 1 second
li a0,1
call sleep
# Turn the bell on
li a7,129 # Send digilines message
la a0,bellchannel
la a1,bellonmsg
ecall
# Wait 2 seconds
li a0,2
call sleep
# Turn the light red
li a7,129 # Send digilines message
la a0,lightchannel
la a1,lightredmsg
ecall
# Wait 3 seconds
li a0,3
call sleep
# Lower the gate
li a7,129 # Send digilines message
la a0,gatechannel
la a1,gatedownmsg
ecall
# Wait 5 seconds
li a0,5
call sleep
# Turn the bell off
li a7,129 # Send digilines message
la a0,bellchannel
la a1,belloffmsg
ecall
waitlonger:
# Wait 10 seconds
li a0,10
call sleep
# Check if any more trains have been detected
receiveloop2:
li a7,133 # Get digilines buffer level
ecall
beq a0,x0,raise # If no messages yet, go ahead with timing out
# If there is a message, check if it's a train
li a7,135 # Read digilines message
la a0,channelbuf
li a1,16 # Channel buffer size
la a2,msgbuf
li a3,16 # Message buffer size
ecall
# Check if it's the right channel
la a0,channelbuf
la a1,detectchannel
call strcmp
beq a0,x0,receiveloop2 # Not the right channel, ignore this message and go on to the next
# If it is the right channel, then get rid of the rest of the messages (if any)
li a7,134 # Clear digilines buffer
ecall
j waitlonger # And go wait another 10 seconds
raise:
# Raise the gate
li a7,129 # Send digilines message
la a0,gatechannel
la a1,gateupmsg
ecall
# Wait 2 seconds
li a0,2
call sleep
# Turn the light off
li a7,129 # Send digilines message
la a0,lightchannel
la a1,lightoffmsg
ecall
# And go wait for the next train
j restart
sleep:
# Expects a number of seconds in a0
# Uses t0
rdtime t0
add a0,t0,a0
sleep_loop:
rdtime t0
bltu t0,a0,sleep_loop
ret
strcmp:
# Expects string pointers in a0 and a1
# Compares until a NUL is reached on the first string
# Uses t0, t1, and t2
# Returns a0=1 if strings match, a0=0 otherwise
li t0,0 # t0 is the loop counter
strcmp_loop:
# Calculate addresses
add t1,a0,t0 # t1 is the pointer for the first string
add t2,a1,t0 # t2 is the pointer for the second string
# Read the bytes from each string
lb t1,0(t1)
lb t2,0(t2)
# Increment the loop counter
addi t0,t0,1
# And compare
bne t1,t2,strcmp_mismatch
# Check if a terminator was reached yet, keep going otherwise
li t2,0
bne t1,t2,strcmp_loop
# If we got here they match
li a0,1
ret
strcmp_mismatch:
li a0,0
ret
channelbuf: .ascii " "
msgbuf: .ascii " "
lightchannel: .asciz "light"
bellchannel: .asciz "bell"
gatechannel: .asciz "gate"
lightoffmsg: .asciz "OFF"
lightyellowmsg: .asciz "YELLOW"
lightredmsg: .asciz "RED"
bellonmsg: .asciz "on"
belloffmsg: .asciz "off"
gateupmsg: .asciz "up"
gatedownmsg: .asciz "down"
detectchannel: .asciz "detect"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment