; ttyStart: Initializes the terminal for input and output. ttyStart MOV R3, #0xF2000000 ; load DBGU base address 0xFFFFF200 into R3 MOV R3, R3, ASR #16 MOV R0, #0x50 ; enable DBGU receipt and transmission STR R0, [R3, #0x0] MOV PC, LR ; getChar: Reads and returns in R0 a single character from the user. ; Program should have already called ttyStart. ; (Subroutine changes R0 and R3.) getChar MOV R3, #0xF2000000 ; load DBGU base address 0xFFFFF200 into R3 MOV R3, R3, ASR #16 LDR R0, [R3, #0x14] ; wait until DBGU has received character TST R0, #0x1 BEQ getChar LDR R0, [R3, #0x18] ; now accept it from DBGU MOV PC, LR ; printChar: Displays a single character whose ASCII value is in R0. ; Program should have already called ttyStart. ; (Subroutine changes R1 and R3.) printChar MOV R3, #0xF2000000 ; load DBGU base address 0xFFFFF200 into R3 MOV R3, R3, ASR #16 LDR R1, [R3, #0x14] ; wait until DBGU ready to transmit TST R1, #0x2 BEQ printChar STR R0, [R3, #0x1C] ; send character for DBGU transmission MOV PC, LR ; getInt: Reads and returns in R0 a nonnegative base-10 integer typed by ; the user. Continues reading digits until user enters a non-digit ; character. The terminating non-digit character is consumed from the ; input. Program should have already called ttyStart. getInt STMDB SP!, { LR } MOV R1, #0 MOV R2, #0 ; R2 accumulates integer typed B getInt_get ; go to retrieving first character getInt_loop ADD R1, R1, #1 ADD R2, R2, R2, LSL #2 ; R2 = 10 * R2 + digit in R0 ADD R2, R0, R2, LSL #1 getInt_get BL getChar ; retrieve character, repeat if is digit SUB R0, R0, #'0' CMP R0, #10 BLO getInt_loop CMN R0, #3 ; check whether '-' was typed (-3 = '-' - '0') CMPEQ R1, #0 ; if so, check whether this is the first digit MVNEQ R1, #0xFF ; and if it is, set R1 to very negative BEQ getInt_get ; and repeat looking for first character MOV R0, R2 TST R1, R1 ; negate return value if R1 < 0 RSBLT R0, R0, #0 LDMIA SP!, { PC } ; printStr: Displays a NUL-terminated string whose first character's ; address is found in R0. Program should have already called ttyStart. printStr STMDB SP!, { LR } ; save LR on stack, since BL changes LR MOV R2, R0 ; R2 holds address of current char printStr_0 LDRB R0, [R2], #1 ; load str[i] into R0, increment R2 CMP R0, #0 ; if it is '\0', return LDMEQIA SP!, { PC } BL printChar ; display str[i] B printStr_0 ; printHex: Displays the value found in R0 as unsigned integer in base 16. ; Program should have already called ttyStart. printHex STMDB SP!, { R4, LR } MOV R2, R0 MOV R4, #0 printHex_1 ADD R4, R4, #4 MOVS R0, R2, LSR R4 BNE printHex_1 SUB R4, R4, #4 printHex_2 MOV R0, R2, LSR R4 AND R0, R0, #0xF CMP R0, #10 ADDLT R0, R0, #'0' ADDGE R0, R0, #87 BL printChar printHex_3 SUBS R4, R4, #4 BGE printHex_2 LDMIA SP!, { R4, PC } ; printInt: Displays the value found in R0 as signed integer in base 10. ; Program should have already called ttyStart. printInt STMDB SP!, { LR } SUB SP, SP, #12 ; reserve 12 bytes on stack for digits CMP R0, #0 BGE printInt_0 RSB R2, R0, #0 ; R0 is negative - print '-' and negate MOV R0, #'-' BL printChar MOV R0, R2 printInt_0 MOV R2, SP ; load digits into array MOV R3, #0x19000000 ; starting with 1's digit ORR R3, R3, #0x990000 ORR R3, R3, #0x9900 ORR R3, R3, #0x9A printInt_1 UMULL R12, R1, R0, R3 ADD R12, R1, R1, LSL #2 SUB R12, R0, R12, LSL #1 ADD R12, R12, #'0' STRB R12, [R2], #1 MOVS R0, R1 BGT printInt_1 printInt_2 LDRB R0, [R2, #-1]! ; go through array in reverse BL printChar ; displaying digits CMP R2, SP BGT printInt_2 ADD SP, SP, #12 LDMIA SP!, { PC }