diff options
Diffstat (limited to 'uisimulator/lcd.c')
-rw-r--r-- | uisimulator/lcd.c | 91 |
1 files changed, 78 insertions, 13 deletions
diff --git a/uisimulator/lcd.c b/uisimulator/lcd.c index 0db77e09bb..8607477d82 100644 --- a/uisimulator/lcd.c +++ b/uisimulator/lcd.c | |||
@@ -21,8 +21,10 @@ | |||
21 | * This file is meant for generic LCD defines and global variables etc. | 21 | * This file is meant for generic LCD defines and global variables etc. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #define DISP_X 112 /* Display width in pixels */ | 24 | #include "lcd.h" |
25 | #define DISP_Y 64 /* Display height in pixels */ | 25 | |
26 | #define DISP_X LCD_WIDTH /* Display width in pixels */ | ||
27 | #define DISP_Y LCD_HEIGHT /* Display height in pixels */ | ||
26 | 28 | ||
27 | #define CHAR_X 6 /* Character width in pixels */ | 29 | #define CHAR_X 6 /* Character width in pixels */ |
28 | #define CHAR_Y 8 /* Character height in pixels */ | 30 | #define CHAR_Y 8 /* Character height in pixels */ |
@@ -38,7 +40,7 @@ | |||
38 | #define ASCII_MIN 0x20 /* First char in table */ | 40 | #define ASCII_MIN 0x20 /* First char in table */ |
39 | #define ASCII_MAX 0x7f /* Last char in table */ | 41 | #define ASCII_MAX 0x7f /* Last char in table */ |
40 | 42 | ||
41 | static const uchar char_gen[ASCII_MAX-ASCII_MIN+1][CHAR_X-1] = | 43 | static const unsigned char char_gen[ASCII_MAX-ASCII_MIN+1][CHAR_X-1] = |
42 | { | 44 | { |
43 | 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x2f */ | 45 | 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x2f */ |
44 | 0x00, 0x00, 0x4f, 0x00, 0x00, | 46 | 0x00, 0x00, 0x4f, 0x00, 0x00, |
@@ -150,30 +152,93 @@ static const uchar char_gen[ASCII_MAX-ASCII_MIN+1][CHAR_X-1] = | |||
150 | * Bits within a byte are arranged veritcally, LSB at top. | 152 | * Bits within a byte are arranged veritcally, LSB at top. |
151 | * Byte 0 is top left, byte 1 is 2nd left, byte DISP_X starts 2nd row. | 153 | * Byte 0 is top left, byte 1 is 2nd left, byte DISP_X starts 2nd row. |
152 | */ | 154 | */ |
153 | static uchar display[DISP_Y/8][DISP_X]; | 155 | unsigned char display[LCD_HEIGHT/8][LCD_WIDTH]; |
154 | 156 | ||
155 | static uint16 lcd_y; /* Current pixel row */ | 157 | static unsigned char lcd_y; /* Current pixel row */ |
156 | static uint16 lcd_x; /* Current pixel column */ | 158 | static unsigned char lcd_x; /* Current pixel column */ |
157 | 159 | ||
158 | /* | 160 | /* |
159 | * Set current x,y position | 161 | * Set current x,y position |
160 | */ | 162 | */ |
161 | void lcd_position (int x, int y) | 163 | void lcd_position(int x, int y) |
162 | { | 164 | { |
163 | if (x >= 0 && x < DISP_X && y >= 0 && y < DISP_Y) | 165 | if (x >= 0 && x < DISP_X && y >= 0 && y < DISP_Y) { |
164 | { | 166 | lcd_x = x; |
165 | lcd_x = x; | 167 | lcd_y = y; |
166 | lcd_y = y; | 168 | } |
167 | } | ||
168 | } | 169 | } |
169 | 170 | ||
170 | /* | 171 | /* |
171 | * Clear the display | 172 | * Clear the display |
172 | */ | 173 | */ |
173 | void lcd_clear (void) | 174 | void lcd_clear(void) |
174 | { | 175 | { |
175 | lcd_x = 0; | 176 | lcd_x = 0; |
176 | lcd_y = 0; | 177 | lcd_y = 0; |
177 | memset (display, 0, sizeof display); | 178 | memset (display, 0, sizeof display); |
178 | } | 179 | } |
179 | 180 | ||
181 | /* | ||
182 | * Display a character at current position. | ||
183 | * This writes a 5x8 character within a 6x8 cell. | ||
184 | * The cell does not have to be aligned to a display byte. | ||
185 | * The top left of the cell is displayed at the current position. | ||
186 | * invert is TRUE to display in reverse video. | ||
187 | */ | ||
188 | void lcd_char (int ch, char invert) | ||
189 | { | ||
190 | unsigned char (*dp)[DISP_X] = (void *) &display[lcd_y/8][lcd_x]; | ||
191 | unsigned long shift, mask, col; | ||
192 | |||
193 | /* Limit to char generation table */ | ||
194 | if (ch < ASCII_MIN || ch > ASCII_MAX) | ||
195 | ch = ASCII_MAX; | ||
196 | |||
197 | /* Calculate shift and masks for cell bit position */ | ||
198 | shift = (lcd_y & 0x7); | ||
199 | mask = ~(COL_MASK << shift); | ||
200 | if (invert) | ||
201 | invert = ~mask; | ||
202 | |||
203 | /* Write each char column */ | ||
204 | for (col = 0; col < CHAR_X-1; col++) { | ||
205 | unsigned long data = (char_gen[ch-ASCII_MIN][col] << shift) ^ invert; | ||
206 | dp[0][col] = (dp[0][col] & mask) | data; | ||
207 | if (lcd_y < DISP_Y-8) | ||
208 | dp[1][col] = (dp[1][col] & (mask >> 8)) | (data >> 8); | ||
209 | } | ||
210 | |||
211 | /* Column after char */ | ||
212 | dp[0][CHAR_X-1] = (dp[0][CHAR_X-1] & mask) | invert; | ||
213 | if (lcd_y < DISP_Y-8) | ||
214 | dp[1][CHAR_X-1] = (dp[1][CHAR_X-1] & (mask >> 8)) | (invert >> 8); | ||
215 | } | ||
216 | |||
217 | /* | ||
218 | * Output a string at current position | ||
219 | */ | ||
220 | void lcd_string(const char *text, char invert) | ||
221 | { | ||
222 | int ch; | ||
223 | |||
224 | while ((ch = *text++) != '\0') { | ||
225 | if (lcd_y > DISP_Y-CHAR_Y) { | ||
226 | /* Scroll (8 pixels) */ | ||
227 | memcpy (display[0], display[1], DISP_X*(DISP_Y/8-1)); | ||
228 | lcd_y -= 8; | ||
229 | } | ||
230 | |||
231 | if (ch == '\n') | ||
232 | lcd_x = DISP_X; | ||
233 | else { | ||
234 | lcd_char (ch, invert); | ||
235 | lcd_x += CHAR_X; | ||
236 | } | ||
237 | |||
238 | if (lcd_x > DISP_X-CHAR_X) { | ||
239 | /* Wrap to next line */ | ||
240 | lcd_x = 0; | ||
241 | lcd_y += CHAR_Y; | ||
242 | } | ||
243 | } | ||
244 | } | ||