Changeset 18e37d6 in buchla-emu


Ignore:
Timestamp:
09/09/2017 12:30:42 PM (7 years ago)
Author:
Thomas Lopatic <thomas@…>
Branches:
master
Children:
cd50b8c
Parents:
a86b3ab
Message:

Refactoring for master merge.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • emu/lcd.c

    ra86b3ab r18e37d6  
    2222#define ver3(...) _ver(lcd_verbose, 2, __VA_ARGS__)
    2323
     24int32_t lcd_verbose = 0;
     25
    2426#define WIN_W (510 * 2)
    2527#define WIN_H (64 * 2)
     
    2931#define CON_FGR ((SDL_Color){ .r = 255, .b = 255, .g = 255, .a = 255 })
    3032
     33#define REG_ARG 0
     34#define REG_COM 1
     35
     36#define G_NONE          0x00
    3137#define G_INIT          0x40
    3238#define G_MWRITE        0x42
     
    5763#define BASE_GFX 0x2000
    5864
     65#define DIR_UP -85
     66#define DIR_DOWN 85
     67#define DIR_RIGHT 1
     68
    5969static uint8_t mem_txt[TXT_H * TXT_W];
    6070static uint8_t mem_gfx[GFX_H * GFX_W];
     
    6373static SDL_Renderer *ren;
    6474static SDL_atomic_t frame;
    65 static SDL_atomic_t clear;
    66 
    67 static uint32_t render = 0;
     75static SDL_atomic_t ena;
    6876
    6977static TTF_Font *fon;
     
    7482static SDL_Surface *gfx_sur;
    7583
    76 static int32_t cur = 0;
    77 static int32_t cur_c = 0;
    78 static int32_t dir = 1;
    79 
    80 static int32_t current_op = 0x00;
    81 
    82 static uint32_t last_val = 0x00;
    83 static uint32_t last_off = 0;
    84 static int32_t last_sz = -1;
    85 static int32_t mult_val_c = 0;
    86 
    87 int32_t lcd_verbose = 0;
     84static int32_t com;
     85static int32_t n_arg;
     86static int32_t cur = BASE_TXT;
     87static int32_t dir = DIR_RIGHT;
    8888
    8989void lcd_sdl(void)
    9090{
    9191        ver3("lcd_sdl()");
    92 
    93         if (SDL_AtomicGet(&clear)) {
    94                 if (SDL_SetRenderDrawColor(ren, 0x00, 0x00, 0x00, 0xff) < 0) {
    95                         fail("SDL_SetRenderDrawColor() failed: %s", SDL_GetError());
    96                 }
    97 
    98                 if (SDL_RenderClear(ren) < 0) {
    99                         fail("SDL_RenderClear() failed: %s", SDL_GetError());
    100                 }
    101 
    102                 SDL_RenderPresent(ren);
    103                 SDL_AtomicSet(&clear, 0);
    104                 return;
    105         }
    10692
    10793        static int32_t last = 0;
     
    119105        }
    120106
     107        if (SDL_AtomicGet(&ena) == 0) {
     108                return;
     109        }
     110
    121111        for (int32_t y = 0; y < TXT_H; ++y) {
    122112                char line[TXT_W + 1];
     
    126116                }
    127117
    128                 memcpy(line, mem_txt + y * TXT_W, TXT_W);
     118                for (int32_t x = 0; x < TXT_W; ++x) {
     119                        uint8_t c = mem_txt[y * TXT_W + x];
     120                        line[x] = (char)(c == 0x00 ? ' ' : c);
     121                }
     122
    129123                line[TXT_W] = 0;
    130124
     
    215209        }
    216210
    217         SDL_AtomicSet(&clear, 0);
    218 
    219211        SDL_AtomicSet(&frame, 1);
     212        SDL_AtomicSet(&ena, 0);
    220213
    221214        SDL_RWops *ops = SDL_RWFromFile(font, "rb");
     
    279272        ver2("lcd rd %u:%d", off, sz * 8);
    280273
    281         uint32_t rv;
    282 
    283         switch (current_op) {
    284                 case G_MREAD:
    285                         if (cur >= BASE_TXT && cur < BASE_TXT + TXT_W * TXT_H) {
    286                                 rv = mem_txt[cur - BASE_TXT];
     274        if (sz != 1 || off > 0) {
     275                fail("invalid lcd rd %u:%d", off, sz * 8);
     276        }
     277
     278        switch (com) {
     279        case G_MREAD:
     280                if (cur >= BASE_TXT && cur < BASE_TXT + TXT_W * TXT_H) {
     281                        return mem_txt[cur - BASE_TXT];
     282                }
     283
     284                if (cur >= BASE_GFX && cur < BASE_GFX + GFX_W * GFX_H) {
     285                        return mem_gfx[cur - BASE_GFX];
     286                }
     287
     288                return 0x00;
     289
     290        default:
     291                return 0x00;
     292        }
     293}
     294
     295static void proc_arg(int32_t val)
     296{
     297        switch (com) {
     298        case G_MWRITE:
     299                if (cur >= BASE_TXT && cur < BASE_TXT + TXT_W * TXT_H) {
     300                        mem_txt[cur - BASE_TXT] = (uint8_t)val;
     301                }
     302                else if (cur >= BASE_GFX && cur < BASE_GFX + GFX_W * GFX_H) {
     303                        mem_gfx[cur - BASE_GFX] = (uint8_t)val;
     304                }
     305
     306                cur += dir;
     307                SDL_AtomicAdd(&frame, 1);
     308                break;
     309
     310        case G_CRSWR:
     311                if (n_arg == 0) {
     312                        cur = val;
     313                }
     314                else if (n_arg == 1) {
     315                        cur |= val << 8;
     316
     317                        if (cur < BASE_TXT ||
     318                                        (cur >= BASE_TXT + TXT_W * TXT_H && cur < BASE_GFX) ||
     319                                        cur >= BASE_GFX + GFX_W * GFX_H) {
     320                                fail("invalid address 0x%04x", cur);
    287321                        }
    288                         else if (cur >= BASE_GFX && cur < BASE_GFX + GFX_W * GFX_H) {
    289                                 rv = mem_gfx[cur - BASE_GFX];
    290                         }
    291                         else {
    292                                 rv = 0x00;
    293                         }
    294                         break;
    295 
    296                 default:
    297                         rv = 0x00;
    298                         break;
    299         }
    300         return rv;
     322                }
     323
     324                break;
     325
     326        default:
     327                break;
     328        }
     329}
     330
     331static void proc_com(int32_t val)
     332{
     333        switch (val) {
     334        case G_CRSWR:
     335        case G_MREAD:
     336        case G_MWRITE:
     337                com = val;
     338                break;
     339
     340        case G_CRSMRT:
     341                dir = DIR_RIGHT;
     342                com = G_NONE;
     343                break;
     344
     345        case G_CRSMUP:
     346                dir = DIR_UP;
     347                com = G_NONE;
     348                break;
     349
     350        case G_CRSMDN:
     351                dir = DIR_DOWN;
     352                com = G_NONE;
     353                break;
     354
     355        case G_DSPOFF:
     356                SDL_AtomicSet(&ena, 0);
     357                com = G_NONE;
     358                break;
     359
     360        case G_DSPON:
     361                SDL_AtomicSet(&ena, 1);
     362                com = G_NONE;
     363                break;
     364
     365        default:
     366                com = G_NONE;
     367                break;
     368        }
    301369}
    302370
    303371void lcd_write(uint32_t off, int32_t sz, uint32_t val)
    304372{
    305         if (last_val != val && mult_val_c > 0) {
    306                 if (mult_val_c > 1) {
    307                         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);
    308                 }
    309                 else {
    310                         ver2("lcd wr %u:%d 0x%0*x", last_off, last_sz * 8, last_sz * 2, last_val);
    311                 }
    312 
    313                 ver2("lcd wr %u:%d 0x%0*x", off, sz * 8, sz * 2, val);
    314                 mult_val_c = 0;
    315         }
    316         else if (last_val == val && mult_val_c >= 0) {
    317                 ++mult_val_c;
    318         }
    319         else {
    320                 ver2("lcd wr %u:%d 0x%0*x", off, sz * 8, sz * 2, val);
    321         }
    322 
    323         last_val = val;
    324         last_off = off;
    325         last_sz = sz;
    326 
    327         if (off == 0) {
    328                 switch (current_op) {
    329                         case G_MWRITE:
    330                                         if (cur >= BASE_TXT && cur < BASE_TXT + TXT_W * TXT_H) {
    331                                                 if (val == 0) {
    332                                                         mem_txt[cur - BASE_TXT] = ' ';
    333                                                 }
    334                                                 else {
    335                                                         mem_txt[cur - BASE_TXT] = (uint8_t) val;
    336                                                 }
    337 
    338                                                 cur += dir;
    339 
    340                                                 if (render) {
    341                                                         SDL_AtomicAdd(&frame, 1);
    342                                                 }
    343                                         }
    344                                         else if (cur >= BASE_GFX && cur < BASE_GFX + GFX_W * GFX_H) {
    345                                                 mem_gfx[cur - BASE_GFX] = (uint8_t) val;
    346                                                 cur += dir;
    347 
    348                                                 if (render) {
    349                                                         SDL_AtomicAdd(&frame, 1);
    350                                                 }
    351                                         }
    352                                 break;
    353 
    354                         case G_CRSWR:
    355                                 if (cur_c == 0) {
    356                                         cur = (int32_t) val;
    357                                         cur_c++;
    358                                 }
    359                                 else if (cur_c == 1) {
    360                                         cur = cur | ((int32_t) val << 8);
    361                                         if (cur < BASE_TXT || (cur >= BASE_TXT + TXT_W * TXT_H && cur < BASE_GFX) || cur >= BASE_GFX + GFX_W * GFX_H) {
    362                                                 err("Invalid cur value %d", cur);
    363                                         }
    364                                         cur_c = 0;
    365                                 }
    366                                 break;
    367 
    368                         default:
    369                                 break;
    370                 }
    371         }
    372         else {
    373                 switch (val) {
    374                         case G_MWRITE:
    375                                 current_op = G_MWRITE;
    376                                 break;
    377 
    378                         case G_CRSMRT:
    379                                 dir = 1;
    380                                 current_op = G_CRSMRT;
    381                                 break;
    382 
    383                         case G_CRSMUP:
    384                                 dir = -85;
    385                                 current_op = G_CRSMUP;
    386                                 break;
    387 
    388                         case G_CRSMDN:
    389                                 dir = 85;
    390                                 current_op = G_CRSMDN;
    391                                 break;
    392 
    393                         case G_CRSWR:
    394                                 current_op = G_CRSWR;
    395                                 break;
    396 
    397                         case G_MREAD:
    398                                 current_op = G_MREAD;
    399                                 break;
    400 
    401                         case G_DSPOFF:
    402                                 SDL_AtomicSet(&clear, 1);
    403                                 render = 0;
    404                                 current_op = G_DSPOFF;
    405                                 break;
    406 
    407                         case G_DSPON:
    408                                 render = 1;
    409                                 current_op = G_DSPON;
    410                                 break;
    411 
    412                         default:
    413                                 current_op = 0x00;
    414                                 break;
    415                 }
    416         }
    417 }
     373        ver2("lcd wr %u:%d 0x%0*x", off, sz * 8, sz * 2, val);
     374
     375        if (sz != 1 || off > 1) {
     376                fail("invalid lcd wr %u:%d", off, sz * 8);
     377        }
     378
     379        switch (off) {
     380        case REG_ARG:
     381                proc_arg((int32_t)val);
     382                ++n_arg;
     383                break;
     384
     385        case REG_COM:
     386                proc_com((int32_t)val);
     387                n_arg = 0;
     388                break;
     389
     390        default:
     391                break;
     392        }
     393}
Note: See TracChangeset for help on using the changeset viewer.