-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPrint.s
167 lines (143 loc) · 5.4 KB
/
Print.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
; Print.s
; Student names: change this to your names or look very silly
; Last modification date: change this to the last modification date or look very silly
; Runs on LM4F120 or TM4C123
; EE319K lab 7 device driver for any LCD
;
; As part of Lab 7, students need to implement these LCD_OutDec and LCD_OutFix
; This driver assumes two low-level LCD functions
; ST7735_OutChar outputs a single 8-bit ASCII character
; ST7735_OutString outputs a null-terminated string
IMPORT ST7735_OutChar
IMPORT ST7735_OutString
EXPORT LCD_OutDec
EXPORT LCD_OutFix
AREA |.text|, CODE, READONLY, ALIGN=2
THUMB
n EQU 0
;-----------------------LCD_OutDec-----------------------
; Output a 32-bit number in unsigned decimal format
; Input: R0 (call by value) 32-bit unsigned number
; Output: none
; Invariables: This function must not permanently modify registers R4 to R11
LCD_OutDec
;push all the registers
;push each number as it comes up
;the n value will be frame pointed to for both computation and to point where the stack began
PUSH {R0, LR} ;n is initialized to the input variable. size is just allocated
MOV R12, SP ;R12 is now a frame pointer
MOV R2, #10 ;this is for decimal modulus math
CMP R0, #0 ;handle the zero edgecase
BNE decbegin
ADD R0, R0, #0x30 ;this will just print zero and end the printing
BL ST7735_OutChar
POP {R0, LR} ;deallocates everything
BX LR
decbegin
LDR R0, [R12, #n] ;load from the memory location
CMP R0, #0
BEQ decprinter ;if its zero, we are done
UDIV R1, R0, R2 ;divide first, and integer division will roun down
MUL R1, R1, R2 ;multiply. this number will be less than or equal to R0
SUB R1, R0, R1 ;subtract R1 from R0 for the remainder. that mod is stored to R1
ADD R1, R1, #0x30 ;add the mod to get an ascii character
PUSH {R1, R2} ;push onto the stack for easy navigation. R2 is pushed for alignment
UDIV R0, R0, R2 ;divide n by 10 and store it into its memory spot. this readies up the next digit
STR R0, [R12, #n]
B decbegin
decprinter
CMP R12, SP ;if the frame pointer is equal to the stack pointer, all the digits were pushed and printed
BEQ decexit
;the top of the stack has the most significant digit
POP {R0, R2} ;pushing to E2 also for alignment
BL ST7735_OutChar
B decprinter
decexit
POP {R0, LR} ;pop the variable and the LR, which was changed when going to outchar
BX LR
;* * * * * * * * End of LCD_OutDec * * * * * * * *
; -----------------------LCD _OutFix----------------------
; Output characters to LCD display in fixed-point format
; unsigned decimal, resolution 0.01, range 0.00 to 9.99
; Inputs: R0 is an unsigned 32-bit number
; Outputs: none
; E.g., R0=0, then output "0.00 "
; R0=3, then output "0.03 "
; R0=89, then output "0.89 "
; R0=123, then output "1.23 "
; R0=999, then output "9.99 "
; R0>999, then output "*.** "
; Invariables: This function must not permanently modify registers R4 to R11
LCD_OutFix
;push all the registers
;push each number as it comes up
;the n value will be frame pointed to for both computation and to point where the stack began
PUSH {R0, LR} ;n is initialized to the input variable
MOV R12, SP ;R12 is now a frame pointer
MOV R2, #1000 ;this will be to make sure the numbers not out of bounds
MOV R3, #3 ;a counter for checking where the decimal should go
CMP R0, #0 ;handle the zero edgecase
BNE checkbig
ADD R0, R0, #0x30 ;this will just print 0.00 and end the printing
BL ST7735_OutChar
MOV R0, #0x2E
BL ST7735_OutChar
MOV R0, #0x30
BL ST7735_OutChar
MOV R0, #0x30
BL ST7735_OutChar
POP {R0, LR} ;deallocates everything
BX LR
checkbig
CMP R0, R2 ;handle the max value edgecase
BLO fixbegin
MOV R0, #0x2A ;this will just print *.** and end the printing
BL ST7735_OutChar
MOV R0, #0x2E
BL ST7735_OutChar
MOV R0, #0x2A
BL ST7735_OutChar
MOV R0, #0x2A
BL ST7735_OutChar
POP {R0, LR} ;deallocates everything
BX LR
fixbegin
MOV R2, #10 ;for decimal modulus
LDR R0, [R12, #n]
CMP R0, #0
BEQ fixfiller
UDIV R1, R0, R2 ;divide first, and integer division will roun down
MUL R1, R1, R2 ;multiply. this number will be less than or equal to R0
SUB R1, R0, R1 ;subtract R1 from R0 for the remainder. that mod is stored to R1
ADD R1, R1, #0x30 ;add the mod to get an ascii character
PUSH {R1, R2} ;push onto the stack for easy navigation. R2 is pushed for alignment
UDIV R0, R0, R2 ;divide n by 10 and store it into its memory spot
STR R0, [R12, #n]
SUB R3, R3, #1
B fixbegin
fixfiller ;pads the rest of the number with zeroes, since its of a fixed length
MOV R1, #0x30
CMP R3, #0 ;use the counter to see how many more zeroes need to be added
BEQ fixprinter
PUSH {R1, R3}
SUB R3, R3, #1
B fixfiller
fixprinter
CMP R12, SP
BEQ fixexit
;the top of the stack has the most significant digit
POP {R0, R2}
BL ST7735_OutChar
SUB R2, R12, #16
CMP R2, SP ;if the top character was just printed, be sure to add a decimal point
BNE dotskip
MOV R0, #0x2E
BL ST7735_OutChar
dotskip
B fixprinter
fixexit
POP {R0, LR}
BX LR
;* * * * * * * * End of LCD_OutFix * * * * * * * *
ALIGN ; make sure the end of this section is aligned
END ; end of file