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"