- Timestamp:
- 08/25/2017 07:04:14 PM (7 years ago)
- Branches:
- master
- Children:
- 43ea417
- Parents:
- 657abdf
- Location:
- emu
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
emu/all.h
r657abdf r7ba68aa 111 111 extern void lcd_write(uint32_t off, int32_t sz, uint32_t val); 112 112 113 extern void lcd_sdl(void); 114 113 115 extern void ser_init(void); 114 116 extern void ser_quit(void); -
emu/lcd.c
r657abdf r7ba68aa 22 22 #define ver3(...) _ver(lcd_verbose, 2, __VA_ARGS__) 23 23 24 #define WIN_W (1520 * 2 / 3) 25 #define WIN_H (950 * 2 / 3) 26 27 #define CON_W 86 28 #define CON_H 25 29 30 #define CON_BGR 0x00000000 31 #define CON_BEL 0x00808080 32 #define CON_CUR 0x00e87000 33 #define CON_FGR ((SDL_Color){ .r = 255, .b = 255, .g = 255, .a = 255 }) 34 35 #define BEL_CYC 10000 36 37 #define G_INIT 0x40 38 #define G_MWRITE 0x42 39 #define G_MREAD 0x43 40 #define G_SETSAD 0x44 41 #define G_CRSWR 0x46 42 #define G_CRSRD 0x47 43 #define G_CRSMRT 0x4C 44 #define G_CRSMLT 0x4D 45 #define G_CRSMUP 0x4E 46 #define G_CRSMDN 0x4F 47 #define G_ERASE 0x52 48 #define G_SLEEP 0x53 49 #define G_DSPCTL 0x58 50 #define G_HSCRL 0x5A 51 #define G_OVRLAY 0x5B 52 #define G_CGRAM 0x5C 53 #define G_CRSFRM 0x5D 54 55 static uint8_t mem[CON_H][CON_W + 1]; 56 57 static SDL_Window *win; 58 static SDL_Renderer *ren; 59 static SDL_atomic_t frame; 60 61 static TTF_Font *fon; 62 static int32_t fon_w, fon_h; 63 64 static int32_t sur_w, sur_h; 65 static SDL_Surface *sur; 66 67 static int32_t cur_x = 0, cur_y = 0; 68 static int32_t bel = 0; 69 70 static int32_t current_op = 0x00; 71 static uint32_t cur_ad = 0; 72 static int32_t cur_ad_c = 0; 73 24 74 int32_t lcd_verbose = 0; 25 75 76 static void scroll(void) 77 { 78 memmove(mem, mem + 1, (CON_H - 1) * (CON_W + 1)); 79 memset(mem + (CON_H - 1), ' ', CON_W); 80 } 81 82 static void forw(void) 83 { 84 if (cur_x < CON_W - 1) { 85 ++cur_x; 86 return; 87 } 88 89 if (cur_y == CON_H - 1) { 90 cur_x = 0; 91 scroll(); 92 return; 93 } 94 95 cur_x = 0; 96 ++cur_y; 97 } 98 99 static void back(void) 100 { 101 if (cur_x > 0) { 102 --cur_x; 103 return; 104 } 105 106 if (cur_y == 0) { 107 return; 108 } 109 110 cur_x = CON_W - 1; 111 --cur_y; 112 } 113 114 static void down(void) 115 { 116 if (cur_y < CON_H - 1) { 117 ++cur_y; 118 return; 119 } 120 121 scroll(); 122 } 123 124 static void mvcur(uint32_t cur_addr) { 125 uint32_t n_cur_x = cur_addr % 85; 126 uint32_t n_cur_y = cur_addr / 85; 127 128 printf("Cur x %u\n", n_cur_x); 129 printf("Cur y %u\n", n_cur_y); 130 if (n_cur_x < CON_W - 1) { 131 cur_x = (int32_t) n_cur_x; 132 } 133 else { 134 err("invalid x cursor pos in lcd %u:%d", n_cur_x, CON_W); 135 } 136 137 if (n_cur_y < CON_H - 1) { 138 cur_y = (int32_t) n_cur_y; 139 } 140 else { 141 err("invalid y cursor pos in lcd %u:%d", n_cur_y, CON_H); 142 } 143 } 144 145 static void echo(uint8_t c) 146 { 147 if (c < 32) { 148 switch (c) { 149 case '\r': 150 cur_x = 0; 151 break; 152 153 case '\n': 154 down(); 155 break; 156 157 case '\b': 158 back(); 159 break; 160 161 case '\a': 162 bel = BEL_CYC; 163 break; 164 165 case 0: 166 mem[cur_y][cur_x] = ' '; 167 forw(); 168 break; 169 170 case 28: 171 // TODO 172 echo('^'); 173 echo((uint8_t)(c + '@')); 174 break; 175 176 default: 177 echo('^'); 178 echo((uint8_t)(c + '@')); 179 ver2("lcd default case echo %u", c); 180 return; 181 } 182 } 183 else { 184 mem[cur_y][cur_x] = c; 185 forw(); 186 } 187 188 SDL_AtomicAdd(&frame, 1); 189 } 190 191 void lcd_sdl(void) 192 { 193 ver3("lcd_sdl()"); 194 195 static int32_t last = 0; 196 int32_t now = SDL_AtomicGet(&frame); 197 198 if (last == now) { 199 ver3("no update"); 200 return; 201 } 202 203 last = now; 204 205 if (SDL_FillRect(sur, NULL, bel == 0 ? CON_BGR : CON_BEL) < 0) { 206 fail("SDL_FillRect() failed: %s", SDL_GetError()); 207 } 208 209 if (SDL_FillRect(sur, &(SDL_Rect){ 210 .x = cur_x * fon_w, 211 .y = cur_y * fon_h, 212 .w = fon_w, 213 .h = fon_h 214 }, CON_CUR) < 0) { 215 fail("SDL_FillRect() failed: %s", SDL_GetError()); 216 } 217 218 for (int32_t y = 0; y < CON_H; ++y) { 219 char line[CON_W + 1]; 220 221 if (SDL_LockMutex(cpu_mutex) < 0) { 222 fail("SDL_LockMutex() failed: %s", SDL_GetError()); 223 } 224 225 memcpy(line, mem[y], CON_W + 1); 226 227 if (SDL_UnlockMutex(cpu_mutex) < 0) { 228 fail("SDL_UnlockMutex() failed: %s", SDL_GetError()); 229 } 230 231 SDL_Surface *lin = TTF_RenderText_Blended(fon, line, CON_FGR); 232 233 if (lin == NULL) { 234 fail("TTF_RenderText_Blended() failed: %s", TTF_GetError()); 235 } 236 237 if (SDL_BlitSurface(lin, NULL, sur, &(SDL_Rect){ 238 .x = 0, 239 .y = y * fon_h, 240 .w = CON_W * fon_w, 241 .h = fon_h 242 })) { 243 fail("SDL_BlitSurface() failed: %s", SDL_GetError()); 244 } 245 246 SDL_FreeSurface(lin); 247 } 248 249 SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, sur); 250 251 if (tex == NULL) { 252 fail("SDL_CreateTextureFromSurface() failed: %s", SDL_GetError()); 253 } 254 255 if (SDL_RenderCopy(ren, tex, NULL, NULL) < 0) { 256 fail("SDL_RenderCopy() failed: %s", SDL_GetError()); 257 } 258 259 SDL_DestroyTexture(tex); 260 SDL_RenderPresent(ren); 261 } 262 263 26 264 void lcd_init(void) 27 265 { 28 266 ver("lcd init"); 267 268 win = SDL_CreateWindow("Front LCD", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 269 WIN_W, WIN_H, 0); 270 271 if (win == NULL) { 272 fail("SDL_CreateWindow() failed: %s", SDL_GetError()); 273 } 274 275 ren = SDL_CreateRenderer(win, -1, 0); 276 277 if (ren == NULL) { 278 fail("SDL_CreateRenderer() failed: %s", SDL_GetError()); 279 } 280 281 SDL_AtomicSet(&frame, 1); 282 283 SDL_RWops *ops = SDL_RWFromFile(font, "rb"); 284 285 if (ops == NULL) { 286 fail("error while opening font file %s: %s", font, SDL_GetError()); 287 } 288 289 fon = TTF_OpenFontRW(ops, 1, 32); 290 291 if (fon == NULL) { 292 fail("error while loading font file %s: %s", font, TTF_GetError()); 293 } 294 295 fon_h = TTF_FontLineSkip(fon); 296 297 if (TTF_GlyphMetrics(fon, 'X', NULL, NULL, NULL, NULL, &fon_w) < 0) { 298 fail("error while measuring font width: %s", TTF_GetError()); 299 } 300 301 sur_w = CON_W * fon_w; 302 sur_h = CON_H * fon_h; 303 304 sur = SDL_CreateRGBSurface(0, sur_w, sur_h, 32, 0, 0, 0, 0); 305 306 if (sur == NULL) { 307 fail("SDL_CreateRGBSurface() failed: %s", SDL_GetError()); 308 } 309 310 for (int32_t y = 0; y < CON_H; ++y) { 311 for (int32_t x = 0; x < CON_W; ++x) { 312 mem[y][x] = ' '; 313 } 314 315 mem[y][CON_W] = 0; 316 } 317 29 318 } 30 319 … … 32 321 { 33 322 ver("lcd quit"); 323 324 SDL_FreeSurface(sur); 325 TTF_CloseFont(fon); 326 327 SDL_DestroyRenderer(ren); 328 SDL_DestroyWindow(win); 34 329 } 35 330 … … 43 338 { 44 339 ver2("lcd rd %u:%d", off, sz * 8); 45 return 0; 340 341 uint32_t rv; 342 343 switch (current_op) { 344 case G_MREAD: 345 printf("current op: %d\n", current_op); 346 rv = mem[cur_y][cur_x]; 347 break; 348 default: 349 rv = 0x00; 350 break; 351 } 352 return rv; 46 353 } 47 354 … … 49 356 { 50 357 ver2("lcd wr %u:%d 0x%0*x", off, sz * 8, sz * 2, val); 51 } 358 359 if (off == 0) { 360 switch (current_op) { 361 case G_MWRITE: 362 echo((uint8_t)val); 363 break; 364 case G_CRSWR: 365 if (cur_ad_c == 0) { 366 cur_ad = val; 367 cur_ad_c++; 368 } else if (cur_ad_c == 1) { 369 cur_ad = cur_ad | (val << 8); 370 mvcur(cur_ad); 371 cur_ad_c = 0; 372 } 373 break; 374 default: 375 break; 376 } 377 } 378 else { 379 switch (val) { 380 case G_MWRITE: 381 current_op = G_MWRITE; 382 break; 383 case G_CRSMRT: 384 forw(); 385 break; 386 case G_CRSWR: 387 current_op = G_CRSWR; 388 break; 389 case G_MREAD: 390 current_op = G_MREAD; 391 break; 392 default: 393 current_op = 0x00; 394 break; 395 } 396 } 397 } -
emu/sdl.c
r657abdf r7ba68aa 27 27 28 28 static sdl_func_t sdl_funcs[] = { 29 ser_sdl, vid_sdl29 lcd_sdl, ser_sdl, vid_sdl 30 30 }; 31 31
Note:
See TracChangeset
for help on using the changeset viewer.