main        MOV SP, #0xf00
            BL ttyStart
            BL getPassword          ; retrieve password
            ADD R1, PC, #fail       ; regardless of password, display "You fail.\n"
            BL printStr
halt        B halt

part2       ADD R1, PC, #succeed    ; this code is never reached
            BL printStr
            B halt

            ; Retrieves password entered by user
getPassword STMDB SP!, { LR }
            SUB SP, SP, #16         ; allocate 16 bytes on stack
            MOV R1, SP
            BL readLine             ; read line into 16 bytes
            ADD SP, SP, #16         ; deallocate 16 bytes
            LDMIA SP!, { PC }

fail        DCB "You fail.\n", 0
succeed     DCB "You passed Part 1!\n", 0

            ; Displays a NUL-terminated string.
            ; Argument (address of string's first character) is in R1
printStr    STMDB SP!, { R1, R2, LR }
            MOV R2, R1          ; R2 holds address of current char
printStr_a  LDRB R1, [R2], #1   ; load str[i] into R0, increment R1
            CMP R1, #'\0'       ; repeat if it is not '\0'
            BLNE printChar      ; display str[i]
            BNE printStr_a
            LDMIA SP!, { R1, R2, PC }

            ; Reads a line of text into the parameter array, creating a
            ; NUL-terminated string. The final '\n' is not included.
            ; Argument (address of string's first character) is in R1
readLine    STMDB SP!, { R0, R1, LR }
readLine_a  BL readChar
            CMP R0, #'\n'
            MOVEQ R0, #'\0'
            STRB R0, [R1], #1
            BNE readLine_a
            LDMIA SP!, { R0, R1, PC }

            ; Initializes the terminal for input and output.
ttyStart    STMDB SP!, { R0, R7, LR }
            MOV R7, #0xF2000000   ; load DBGU base address 0xFFFFF200 into R7
            MOV R7, R7, ASR #16
            MOV R0, #0x50         ; enable DBGU receipt and transmission
            STR R0, [R7, #0x0]
            LDMIA SP!, { R0, R7, PC }
            
            ; Reads a single character from the user. Program
            ; should have already called ttyStart previously.
            ; Result is placed in R0.
readChar    STMDB SP!, { R7, LR }
            MOV R7, #0xF2000000   ; load DBGU base address 0xFFFFF200 into R7
            MOV R7, R7, ASR #16
readChar_a  LDR R0, [R7, #0x14]   ; wait until DBGU has received character
            TST R0, #0x1
            BEQ readChar_a
            LDR R0, [R7, #0x18]   ; now accept it from DBGU
            LDMIA SP!, { R7, PC }

            ; Display a single character. Program should have already
            ; called ttyStart previously.
            ; Argument is found in R1
printChar   STMDB SP!, { R2, R7, LR }
            MOV R7, #0xF2000000   ; load DBGU base address 0xFFFFF200 into R7
            MOV R7, R7, ASR #16
printChar_a LDR R2, [R7, #0x14]   ; wait until DBGU ready to transmit
            TST R2, #0x2
            BEQ printChar_a
            STR R1, [R7, #0x1C]   ; send character for DBGU transmission
            LDMIA SP!, { R2, R7, PC }
