- Timestamp:
- 09/07/2017 11:42:45 AM (7 years ago)
- Branches:
- master
- Children:
- c9d372a
- Parents:
- f51359c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
emu/lcd.c
rf51359c rc8a92ef 22 22 #define ver3(...) _ver(lcd_verbose, 2, __VA_ARGS__) 23 23 24 #define WIN_W (1634 * 2 / 3) 25 #define WIN_H (342 * 2 / 3) 26 27 #define CON_W 86 28 #define CON_H 9 24 #define WIN_W (510 * 2) 25 #define WIN_H (64 * 2) 29 26 30 27 #define CON_BGR 0x00000000 31 #define CON_BEL 0x00808080 32 #define CON_CUR 0x00e87000 28 #define CON_DRW 0xFFFFFFFF 33 29 #define CON_FGR ((SDL_Color){ .r = 255, .b = 255, .g = 255, .a = 255 }) 34 35 #define BEL_CYC 1000036 30 37 31 #define G_INIT 0x40 … … 54 48 #define G_CRSFRM 0x5D 55 49 56 static uint8_t mem[CON_H][CON_W + 1]; 50 #define TXT_W 85 51 #define TXT_H 8 52 53 #define GFX_W 85 54 #define GFX_H 64 55 56 #define BASE_TXT 0x0000 57 #define BASE_GFX 0x2000 58 59 static uint8_t mem_txt[TXT_H * TXT_W]; 60 static uint8_t mem_gfx[GFX_H * GFX_W]; 57 61 58 62 static SDL_Window *win; 59 63 static SDL_Renderer *ren; 60 64 static SDL_atomic_t frame; 65 static SDL_atomic_t clear; 61 66 62 67 static uint32_t render = 0; … … 68 73 static SDL_Surface *sur; 69 74 70 static int32_t cur_x = 0, cur_y = 0; 71 static int32_t bel = 0; 75 static SDL_Surface *gfx_sur; 76 77 static int32_t cur = 0; 78 static int32_t cur_c = 0; 79 static int32_t dir = 1; 72 80 73 81 static int32_t current_op = 0x00; 74 static uint32_t cur_ad = 0;75 static int32_t cur_ad_c = 0;76 82 77 83 static uint32_t last_val = 0x00; … … 80 86 static int32_t mult_val_c = 0; 81 87 82 static void (*cursdir)(void);83 84 88 int32_t lcd_verbose = 0; 85 89 86 static void scroll(void) 87 { 88 memmove(mem, mem + 1, (CON_H - 1) * (CON_W + 1)); 89 memset(mem + (CON_H - 1), ' ', CON_W); 90 } 91 92 static void forw(void) 93 { 94 if (cur_x < CON_W - 1) { 95 ++cur_x; 90 91 void lcd_sdl(void) 92 { 93 ver3("lcd_sdl()"); 94 95 if (SDL_AtomicGet(&clear)) { 96 if (SDL_SetRenderDrawColor(ren, 0x00, 0x00, 0x00, 0xff) < 0) { 97 fail("SDL_SetRenderDrawColor() failed: %s", SDL_GetError()); 98 } 99 100 if (SDL_RenderClear(ren) < 0) { 101 fail("SDL_RenderClear() failed: %s", SDL_GetError()); 102 } 103 104 SDL_RenderPresent(ren); 105 SDL_AtomicSet(&clear, 0); 96 106 return; 97 107 } 98 99 if (cur_y == CON_H - 1) {100 cur_x = 0;101 scroll();102 return;103 }104 105 cur_x = 0;106 ++cur_y;107 }108 109 static void back(void)110 {111 if (cur_x > 0) {112 --cur_x;113 return;114 }115 116 if (cur_y == 0) {117 return;118 }119 120 cur_x = CON_W - 1;121 --cur_y;122 }123 124 static void up(void)125 {126 if (cur_y > 0) {127 --cur_y;128 return;129 }130 131 // TODO: What happens when cursor out of bounds132 }133 134 static void down(void)135 {136 if (cur_y < CON_H - 1) {137 ++cur_y;138 return;139 }140 141 // TODO: What happens when cursor out of bounds142 }143 144 static void mvcur(uint32_t cur_addr) {145 uint32_t n_cur_x = cur_addr % 85;146 uint32_t n_cur_y = cur_addr / 85;147 148 ver2("lcd cur x %u\n", n_cur_x);149 ver2("lcd cur y %u\n", n_cur_y);150 151 if (n_cur_x < CON_W - 1) {152 cur_x = (int32_t) n_cur_x;153 }154 else {155 err("invalid x cursor pos in lcd %u:%d", n_cur_x, CON_W);156 }157 158 if (n_cur_y < CON_H - 1) {159 cur_y = (int32_t) n_cur_y;160 }161 else {162 cur_x = 0;163 cur_y = 9;164 err("invalid y cursor pos in lcd %u:%d", n_cur_y, CON_H);165 }166 }167 168 static void echo(uint8_t c)169 {170 if (c >127) {171 return;172 }173 else if (c < 32) {174 switch (c) {175 case '\r':176 cur_x = 0;177 break;178 179 case '\n':180 down();181 break;182 183 case '\b':184 back();185 break;186 187 case '\a':188 bel = BEL_CYC;189 break;190 191 case 0:192 mem[cur_y][cur_x] = ' ';193 (*cursdir)();194 break;195 196 case 28:197 // TODO198 echo('^');199 echo((uint8_t)(c + '@'));200 break;201 202 default:203 echo('^');204 echo((uint8_t)(c + '@'));205 ver2("lcd default case echo %u", c);206 return;207 }208 }209 else {210 mem[cur_y][cur_x] = c;211 (*cursdir)();212 }213 214 if (render) {215 SDL_AtomicAdd(&frame, 1);216 }217 }218 219 static void clear_mem(void) {220 for (int32_t y = 0; y < CON_H; ++y) {221 for (int32_t x = 0; x < CON_W; ++x) {222 mem[y][x] = ' ';223 }224 225 mem[y][CON_W] = 0;226 }227 }228 229 void lcd_sdl(void)230 {231 ver3("lcd_sdl()");232 108 233 109 static int32_t last = 0; … … 241 117 last = now; 242 118 243 if (SDL_FillRect(sur, NULL, bel == 0 ? CON_BGR : CON_BEL) < 0) {119 if (SDL_FillRect(sur, NULL, CON_BGR) < 0) { 244 120 fail("SDL_FillRect() failed: %s", SDL_GetError()); 245 121 } 246 122 247 if (SDL_FillRect(sur, &(SDL_Rect){ 248 .x = cur_x * fon_w, 249 .y = cur_y * fon_h, 250 .w = fon_w, 251 .h = fon_h 252 }, CON_CUR) < 0) { 253 fail("SDL_FillRect() failed: %s", SDL_GetError()); 254 } 255 256 for (int32_t y = 0; y < CON_H; ++y) { 257 char line[CON_W + 1]; 123 for (int32_t y = 0; y < TXT_H; ++y) { 124 char line[TXT_W + 1]; 258 125 259 126 if (SDL_LockMutex(cpu_mutex) < 0) { … … 261 128 } 262 129 263 memcpy(line, mem[y], CON_W + 1); 130 memcpy(line, mem_txt + y * TXT_W, TXT_W); 131 line[TXT_W] = 0; 264 132 265 133 if (SDL_UnlockMutex(cpu_mutex) < 0) { … … 276 144 .x = 0, 277 145 .y = y * fon_h, 278 .w = CON_W * fon_w,146 .w = TXT_W * fon_w, 279 147 .h = fon_h 280 148 })) { … … 295 163 } 296 164 165 for (int32_t y = 0; y < GFX_H * GFX_W; ++y) { 166 for (int32_t p = 7; p > 1; --p) { 167 uint32_t col = CON_BGR; 168 if ((mem_gfx[y] & (1 << p)) > 0) { 169 col = CON_DRW; 170 } 171 172 if (SDL_FillRect(gfx_sur, &(SDL_Rect){ 173 .x = y % 85 * fon_w + (8 - p) * fon_w / 6, 174 .y = y / 85 * fon_h / 8, 175 .w = fon_w / 6 + 1, 176 .h = fon_h / 8 + 1 177 }, col) < 0) { 178 fail("SDL_FillRect() failed: %s", SDL_GetError()); 179 } 180 } 181 } 182 183 SDL_Texture *gfx_tex = SDL_CreateTextureFromSurface(ren, gfx_sur); 184 185 if (gfx_tex == NULL) { 186 fail("SDL_CreateTextureFromSurface() failed: %s", SDL_GetError()); 187 } 188 189 if (SDL_SetTextureBlendMode(gfx_tex, SDL_BLENDMODE_ADD) < 0) { 190 fail("SDL_SetTextureBlendMode() failed: %s", SDL_GetError()); 191 } 192 193 if (SDL_RenderCopy(ren, gfx_tex, NULL, NULL) < 0) { 194 fail("SDL_RenderCopy() failed: %s", SDL_GetError()); 195 } 196 297 197 SDL_DestroyTexture(tex); 198 SDL_DestroyTexture(gfx_tex); 298 199 SDL_RenderPresent(ren); 299 200 } … … 317 218 } 318 219 220 SDL_AtomicSet(&clear, 0); 221 319 222 SDL_AtomicSet(&frame, 1); 320 223 … … 337 240 } 338 241 339 sur_w = CON_W * fon_w;340 sur_h = CON_H * fon_h;242 sur_w = TXT_W * fon_w; 243 sur_h = TXT_H * fon_h; 341 244 342 245 sur = SDL_CreateRGBSurface(0, sur_w, sur_h, 32, 0, 0, 0, 0); … … 346 249 } 347 250 348 clear_mem(); 349 251 gfx_sur = SDL_CreateRGBSurface(0, sur_w, sur_h, 32, 0, 0, 0, 0); 252 253 if (gfx_sur == NULL) { 254 fail("SDL_CreateRGBSurface() failed: %s", SDL_GetError()); 255 } 256 257 for (int32_t y = 0; y < TXT_W * TXT_H; ++y) { 258 mem_txt[y] = ' '; 259 } 350 260 } 351 261 … … 355 265 356 266 SDL_FreeSurface(sur); 267 SDL_FreeSurface(gfx_sur); 357 268 TTF_CloseFont(fon); 358 269 … … 375 286 switch (current_op) { 376 287 case G_MREAD: 377 ver2("lcd current op: %d\n", current_op); 378 rv = mem[cur_y][cur_x]; 288 if (cur >= BASE_TXT && cur < BASE_TXT + TXT_W * TXT_H) { 289 rv = mem_txt[cur - BASE_TXT]; 290 } 291 else if (cur >= BASE_GFX && cur < BASE_TXT + GFX_W * GFX_H) { 292 rv = mem_gfx[cur - BASE_GFX]; 293 } 294 else { 295 rv = 0x00; 296 } 379 297 break; 380 298 … … 388 306 void lcd_write(uint32_t off, int32_t sz, uint32_t val) 389 307 { 390 391 if(last_val != val && mult_val_c > 0) { 392 if(mult_val_c > 1) { 308 if (last_val != val && mult_val_c > 0) { 309 if (mult_val_c > 1) { 393 310 ver2("lcd wr %u:%d 0x%0*x was called %u more times", last_off, last_sz * 8, last_sz * 2, last_val, mult_val_c); 394 311 } … … 400 317 mult_val_c = 0; 401 318 } 402 else if (last_val == val && mult_val_c >= 0) {319 else if (last_val == val && mult_val_c >= 0) { 403 320 ++mult_val_c; 404 321 } … … 414 331 switch (current_op) { 415 332 case G_MWRITE: 416 echo((uint8_t)val); 333 if (cur >= BASE_TXT && cur < BASE_TXT + TXT_W * TXT_H) { 334 if (val == 0) { 335 mem_txt[cur - BASE_TXT] = ' '; 336 } 337 else { 338 mem_txt[cur - BASE_TXT] = (uint8_t) val; 339 } 340 341 cur += dir; 342 343 if (render) { 344 SDL_AtomicAdd(&frame, 1); 345 } 346 } 347 else if (cur >= BASE_GFX && cur < BASE_GFX + GFX_W * GFX_H) { 348 mem_gfx[cur - BASE_GFX] = (uint8_t) val; 349 cur += dir; 350 351 if (render) { 352 SDL_AtomicAdd(&frame, 1); 353 } 354 } 355 else { 356 err("Invalid cur value %d", cur); 357 } 417 358 break; 418 359 419 360 case G_CRSWR: 420 if (cur_ad_c == 0) { 421 cur_ad = val; 422 cur_ad_c++; 423 } else if (cur_ad_c == 1) { 424 cur_ad = cur_ad | (val << 8); 425 mvcur(cur_ad); 426 cur_ad_c = 0; 361 if (cur_c == 0) { 362 cur = (int32_t) val; 363 cur_c++; 427 364 } 428 break;429 430 case G_DSPON:431 // TODO Configure blinking of cursor(s)365 else if (cur_c == 1) { 366 cur = cur | ((int32_t) val << 8); 367 cur_c = 0; 368 } 432 369 break; 433 370 … … 443 380 444 381 case G_CRSMRT: 445 cursdir = &forw;382 dir = 1; 446 383 current_op = G_CRSMRT; 447 384 break; 448 385 449 386 case G_CRSMUP: 450 cursdir = &up;387 dir = -85; 451 388 current_op = G_CRSMUP; 452 389 break; 453 390 454 391 case G_CRSMDN: 455 cursdir = &down;392 dir = 85; 456 393 current_op = G_CRSMDN; 457 394 break; … … 466 403 467 404 case G_DSPOFF: 468 if (SDL_SetRenderDrawColor(ren, 0x00, 0x00, 0x00, 0xff) < 0) { 469 fail("SDL_SetRenderDrawColor() failed: %s", SDL_GetError()); 470 } 471 if (SDL_RenderClear(ren) < 0) { 472 fail("SDL_RenderClear() failed: %s", SDL_GetError()); 473 } 474 SDL_RenderPresent(ren); 405 SDL_AtomicSet(&clear, 1); 475 406 render = 0; 476 407 current_op = G_DSPOFF; … … 482 413 break; 483 414 484 case G_CRSFRM:485 // TODO Setup Cursor Form...486 current_op = 0x00;487 break;488 489 415 default: 490 416 current_op = 0x00;
Note:
See TracChangeset
for help on using the changeset viewer.