Search code examples
assembly

Problem with the input in assembly program


I have the following code of assembly language and I need to make a timer in each quiz question. If the user doesn't respond in less than 10 seconds then the program shows the Time's up message and finish. The timer is working fine but the problem is that during those 10 seconds, it doesn't allow me to type anything so I can't answer the questions. I'm kinda new to this so I'm not seeing the problem

.data

welcomeMsg: .asciiz "Welcome to the Quiz Game!\nPlease choose a subject to play:\n1. Math\n2. English\n3. History\n4. Soccer Sport\n"

chooseMsg: .asciiz "Enter your choice (1 for Math, 2 for English, 3 for History, 4 for Soccer Sport): "

invalidChoiceMsg: .asciiz "Invalid choice. Please enter a number between 1 and 4.\n"

mathWelcomeMsg: .asciiz "You chose Math! Let's solve some equations.\n"

englishWelcomeMsg: .asciiz "You chose English! Let's work on some exercises.\n"

historyWelcomeMsg: .asciiz "You chose History! Let's dive into the past.\n"

soccerWelcomeMsg: .asciiz "You chose Soccer Sport! Let's test your knowledge of football.\n"

questionMath: .asciiz "What is 5 + 3?\n"

answerMath: .asciiz "8\n"

questionEnglish: .asciiz "Correct the following sentence: 'He go to school every day.'\n"

answerEnglish: .asciiz "He goes to school every day."

questionHistory: .asciiz "In which year did the American Civil War end?\n"

answerHistory: .word 1865

questionSoccer: .asciiz "Who is known as the 'King of Football'?\n"

answerSoccer: .asciiz "Pele\n"

userInputBuffer: .space 100

positiveFeedback: .asciiz "Correct answer! You earned 20 points.\n"

incorrectFeedback: .asciiz "Incorrect answer. The correct answer is "

incorrectFeedbackEnd: .asciiz ".\n"

timeUpMsg: .asciiz "Time's up! Please try again.\n"

.text

.globl main

main:

    li $v0, 4
    la $a0, welcomeMsg
    syscall

    li $v0, 4
    la $a0, chooseMsg
    syscall

    li $v0, 5
    syscall

    move $t0, $v0

    li $t1, 1
    li $t2, 2
    li $t3, 3
    li $t4, 4

    beq $t0, $t1, math_quiz
    beq $t0, $t2, english_quiz
    beq $t0, $t3, history_quiz
    beq $t0, $t4, soccer_quiz

    li $v0, 4
    la $a0, invalidChoiceMsg
    syscall

    j main

math_quiz:

    li $v0, 4
    la $a0, mathWelcomeMsg
    syscall

    li $v0, 4
    la $a0, questionMath
    syscall

    # Start the timer
    li $a0, 15
    jal timer_start

    # Get user input
    li $v0, 8
    la $a0, userInputBuffer
    li $a1, 100
    syscall

    # Compare answer
    la $a0, userInputBuffer
    la $a1, answerMath
    jal strcmp

    beq $v0, $zero, correct_answer_math
    j incorrect_answer_math

correct_answer_math:

    li $v0, 4
    la $a0, positiveFeedback
    syscall
    j finish

incorrect_answer_math:

    li $v0, 4
    la $a0, incorrectFeedback
    syscall

    li $v0, 4
    la $a0, answerMath
    syscall

    li $v0, 4
    la $a0, incorrectFeedbackEnd
    syscall
    j finish

english_quiz:

    li $v0, 4
    la $a0, englishWelcomeMsg
    syscall

    li $v0, 4
    la $a0, questionEnglish
    syscall

    # Start the timer
    li $a0, 15
    jal timer_start

    # Get user input
    li $v0, 8
    la $a0, userInputBuffer
    li $a1, 100
    syscall

    # Compare answer
    la $a0, userInputBuffer
    la $a1, answerEnglish
    jal strcmp

    beq $v0, $zero, correct_answer_english
    j incorrect_answer_english

correct_answer_english:

    li $v0, 4
    la $a0, positiveFeedback
    syscall
    j finish

incorrect_answer_english:

    li $v0, 4
    la $a0, incorrectFeedback
    syscall

    li $v0, 4
    la $a0, answerEnglish
    syscall

    li $v0, 4
    la $a0, incorrectFeedbackEnd
    syscall
    j finish

history_quiz:

    li $v0, 4
    la $a0, historyWelcomeMsg
    syscall

    li $v0, 4
    la $a0, questionHistory
    syscall

    # Start the timer
    li $a0, 15
    jal timer_start

    # Get user input as an integer (year)
    li $v0, 5
    syscall

    move $t5, $v0 # Store user input in $t5

    # Load correct answer
    lw $t6, answerHistory

    # Compare answer
    bne $t5, $t6, incorrect_answer_history
    j correct_answer_history

correct_answer_history:

    li $v0, 4
    la $a0, positiveFeedback
    syscall
    j finish

incorrect_answer_history:

    li $v0, 4
    la $a0, incorrectFeedback
    syscall

    li $v0, 1
    lw $a0, answerHistory
    syscall

    li $v0, 4
    la $a0, incorrectFeedbackEnd
    syscall
    j finish

soccer_quiz:

    li $v0, 4
    la $a0, soccerWelcomeMsg
    syscall

    li $v0, 4
    la $a0, questionSoccer
    syscall

    # Start the timer
    li $a0, 15
    jal timer_start

    # Get user input as a string
    li $v0, 8
    la $a0, userInputBuffer
    li $a1, 100
    syscall

    # Compare answer
    la $a0, userInputBuffer
    la $a1, answerSoccer
    jal strcmp

    beq $v0, $zero, correct_answer_soccer
    j incorrect_answer_soccer

correct_answer_soccer:

    li $v0, 4
    la $a0, positiveFeedback
    syscall
    j finish

incorrect_answer_soccer:

    li $v0, 4
    la $a0, incorrectFeedback
    syscall

    li $v0, 4
    la $a0, answerSoccer
    syscall

    li $v0, 4
    la $a0, incorrectFeedbackEnd
    syscall
    j finish

strcmp:

    # Compare two null-terminated strings, returns 0 if equal, 1 otherwise
    li $t1, 0

compare_loop:

    lb $t2, 0($a0)
    lb $t3, 0($a1)
    beq $t2, $zero, compare_end
    bne $t2, $t3, compare_fail
    addi $a0, $a0, 1
    addi $a1, $a1, 1
    j compare_loop

compare_fail:

    li $v0, 1
    jr $ra

compare_end:

    li $v0, 0
    jr $ra

timer_start:

    move $t1, $a0 # Store initial count in $t1

timer_loop:

    blez $t1, timer_end # Exit loop if count is zero or less

    # Simulate a 1-second delay
    li $t0, 0
    li $t2, 1000000 # Adjust based on the speed of your MIPS environment

delay_loop:

    addi $t0, $t0, 1
    bne $t0, $t2, delay_loop

    subi $t1, $t1, 1 # Decrement timer
    j timer_loop # Repeat timer

timer_end:

    li $v0, 4
    la $a0, timeUpMsg
    syscall
    j finish # Jump to finish the program

finish:

    li $v0, 10 # Exit program
    syscall

The expectations were that for every quiz question, the user has 10 seconds to respond, if he doesn't it has to show a Time's up message but the problem is that it isn't allowing the user to type anything


Solution

  • Timers and I/O are things that are done by the OS and the OS support routines, not by a (user-level) program. That means you need to call a syscall that will get input with a timeout, and if your OS support does not provide that, there's no way to do it without changing your OS.

    If your OS here is SPIM or MARS (simulator), there is no way of doing this -- these systems do not provide any way of timing out an input or having much in the way of a timers at all. The closest you can do (on MARS -- there's no time of any kind on SPIM) is to use syscall 30 -- this will get you the current time, so you can do something like:

    1. print prompt for input
    2. get current time
    3. get input (this will wait for input)
    4. get current time again
    5. if the time difference between 4 and 2 is too big, print a message "you took too long"

    but there's no way to "interrupt" the wait for input after some amount of time.