diff options
Diffstat (limited to 'rrxing.S')
| -rw-r--r-- | rrxing.S | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/rrxing.S b/rrxing.S new file mode 100644 index 0000000..61fb41c --- /dev/null +++ b/rrxing.S @@ -0,0 +1,198 @@ +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" |
