Changes in / [f51359c:ca77925] in buchla-emu


Ignore:
Location:
emu
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • emu/all.h

    rf51359c rca77925  
    114114extern void lcd_write(uint32_t off, int32_t sz, uint32_t val);
    115115
    116 extern void lcd_sdl(void);
    117 
    118116extern void ser_init(void);
    119117extern void ser_quit(void);
  • emu/lcd.c

    rf51359c rca77925  
    2222#define ver3(...) _ver(lcd_verbose, 2, __VA_ARGS__)
    2323
    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
    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_DSPOFF        0x58
    50 #define G_DSPON         0x59
    51 #define G_HSCRL         0x5A
    52 #define G_OVRLAY        0x5B
    53 #define G_CGRAM         0x5C
    54 #define G_CRSFRM        0x5D
    55 
    56 static uint8_t mem[CON_H][CON_W + 1];
    57 
    58 static SDL_Window *win;
    59 static SDL_Renderer *ren;
    60 static SDL_atomic_t frame;
    61 
    62 static uint32_t render = 0;
    63 
    64 static TTF_Font *fon;
    65 static int32_t fon_w, fon_h;
    66 
    67 static int32_t sur_w, sur_h;
    68 static SDL_Surface *sur;
    69 
    70 static int32_t cur_x = 0, cur_y = 0;
    71 static int32_t bel = 0;
    72 
    73 static int32_t current_op = 0x00;
    74 static uint32_t cur_ad = 0;
    75 static int32_t cur_ad_c = 0;
    76 
    77 static uint32_t last_val = 0x00;
    78 static uint32_t last_off = 0;
    79 static int32_t last_sz = -1;
    80 static int32_t mult_val_c = 0;
    81 
    82 static void (*cursdir)(void);
    83 
    8424int32_t lcd_verbose = 0;
    85 
    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;
    96                 return;
    97         }
    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 bounds
    132 }
    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 bounds
    142 }
    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                         // TODO
    198                         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 
    233         static int32_t last = 0;
    234         int32_t now = SDL_AtomicGet(&frame);
    235 
    236         if (last == now) {
    237                 ver3("no update");
    238                 return;
    239         }
    240 
    241         last = now;
    242 
    243         if (SDL_FillRect(sur, NULL, bel == 0 ? CON_BGR : CON_BEL) < 0) {
    244                 fail("SDL_FillRect() failed: %s", SDL_GetError());
    245         }
    246 
    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];
    258 
    259                 if (SDL_LockMutex(cpu_mutex) < 0) {
    260                         fail("SDL_LockMutex() failed: %s", SDL_GetError());
    261                 }
    262 
    263                 memcpy(line, mem[y], CON_W + 1);
    264 
    265                 if (SDL_UnlockMutex(cpu_mutex) < 0) {
    266                         fail("SDL_UnlockMutex() failed: %s", SDL_GetError());
    267                 }
    268 
    269                 SDL_Surface *lin = TTF_RenderText_Blended(fon, line, CON_FGR);
    270 
    271                 if (lin == NULL) {
    272                         fail("TTF_RenderText_Blended() failed: %s", TTF_GetError());
    273                 }
    274 
    275                 if (SDL_BlitSurface(lin, NULL, sur, &(SDL_Rect){
    276                         .x = 0,
    277                         .y = y * fon_h,
    278                         .w = CON_W * fon_w,
    279                         .h = fon_h
    280                 })) {
    281                         fail("SDL_BlitSurface() failed: %s", SDL_GetError());
    282                 }
    283 
    284                 SDL_FreeSurface(lin);
    285         }
    286 
    287         SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, sur);
    288 
    289         if (tex == NULL) {
    290                 fail("SDL_CreateTextureFromSurface() failed: %s", SDL_GetError());
    291         }
    292 
    293         if (SDL_RenderCopy(ren, tex, NULL, NULL) < 0) {
    294                 fail("SDL_RenderCopy() failed: %s", SDL_GetError());
    295         }
    296 
    297         SDL_DestroyTexture(tex);
    298         SDL_RenderPresent(ren);
    299 }
    300 
    30125
    30226void lcd_init(void)
    30327{
    30428        ver("lcd init");
    305 
    306         win = SDL_CreateWindow("Front LCD", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
    307                         WIN_W, WIN_H, 0);
    308 
    309         if (win == NULL) {
    310                 fail("SDL_CreateWindow() failed: %s", SDL_GetError());
    311         }
    312 
    313         ren = SDL_CreateRenderer(win, -1, 0);
    314 
    315         if (ren == NULL) {
    316                 fail("SDL_CreateRenderer() failed: %s", SDL_GetError());
    317         }
    318 
    319         SDL_AtomicSet(&frame, 1);
    320 
    321         SDL_RWops *ops = SDL_RWFromFile(font, "rb");
    322 
    323         if (ops == NULL) {
    324                 fail("error while opening font file %s: %s", font, SDL_GetError());
    325         }
    326 
    327         fon = TTF_OpenFontRW(ops, 1, 32);
    328 
    329         if (fon == NULL) {
    330                 fail("error while loading font file %s: %s", font, TTF_GetError());
    331         }
    332 
    333         fon_h = TTF_FontLineSkip(fon);
    334 
    335         if (TTF_GlyphMetrics(fon, 'X', NULL, NULL, NULL, NULL, &fon_w) < 0) {
    336                 fail("error while measuring font width: %s", TTF_GetError());
    337         }
    338 
    339         sur_w = CON_W * fon_w;
    340         sur_h = CON_H * fon_h;
    341 
    342         sur = SDL_CreateRGBSurface(0, sur_w, sur_h, 32, 0, 0, 0, 0);
    343 
    344         if (sur == NULL) {
    345                 fail("SDL_CreateRGBSurface() failed: %s", SDL_GetError());
    346         }
    347 
    348         clear_mem();
    349 
    35029}
    35130
     
    35332{
    35433        ver("lcd quit");
    355 
    356         SDL_FreeSurface(sur);
    357         TTF_CloseFont(fon);
    358 
    359         SDL_DestroyRenderer(ren);
    360         SDL_DestroyWindow(win);
    36134}
    36235
     
    37043{
    37144        ver2("lcd rd %u:%d", off, sz * 8);
    372 
    373         uint32_t rv;
    374 
    375         switch (current_op) {
    376                 case G_MREAD:
    377                         ver2("lcd current op: %d\n", current_op);
    378                         rv = mem[cur_y][cur_x];
    379                         break;
    380 
    381                 default:
    382                         rv = 0x00;
    383                         break;
    384         }
    385         return rv;
     45        return 0;
    38646}
    38747
    38848void lcd_write(uint32_t off, int32_t sz, uint32_t val)
    38949{
    390 
    391         if(last_val != val && mult_val_c > 0) {
    392                 if(mult_val_c > 1) {
    393                         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                 }
    395                 else {
    396                         ver2("lcd wr %u:%d 0x%0*x", last_off, last_sz * 8, last_sz * 2, last_val);
    397                 }
    398 
    399                 ver2("lcd wr %u:%d 0x%0*x", off, sz * 8, sz * 2, val);
    400                 mult_val_c = 0;
    401         }
    402         else if(last_val == val && mult_val_c >= 0) {
    403                 ++mult_val_c;
    404         }
    405         else {
    406                 ver2("lcd wr %u:%d 0x%0*x", off, sz * 8, sz * 2, val);
    407         }
    408 
    409         last_val = val;
    410         last_off = off;
    411         last_sz = sz;
    412 
    413         if (off == 0) {
    414                 switch (current_op) {
    415                         case G_MWRITE:
    416                                         echo((uint8_t)val);
    417                                 break;
    418 
    419                         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;
    427                                 }
    428                                 break;
    429 
    430                         case G_DSPON:
    431                                 // TODO Configure blinking of cursor(s)
    432                                 break;
    433 
    434                         default:
    435                                 break;
    436                 }
    437         }
    438         else {
    439                 switch (val) {
    440                         case G_MWRITE:
    441                                 current_op = G_MWRITE;
    442                                 break;
    443 
    444                         case G_CRSMRT:
    445                                 cursdir = &forw;
    446                                 current_op = G_CRSMRT;
    447                                 break;
    448 
    449                         case G_CRSMUP:
    450                                 cursdir = &up;
    451                                 current_op = G_CRSMUP;
    452                                 break;
    453 
    454                         case G_CRSMDN:
    455                                 cursdir = &down;
    456                                 current_op = G_CRSMDN;
    457                                 break;
    458 
    459                         case G_CRSWR:
    460                                 current_op = G_CRSWR;
    461                                 break;
    462 
    463                         case G_MREAD:
    464                                 current_op = G_MREAD;
    465                                 break;
    466 
    467                         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);
    475                                 render = 0;
    476                                 current_op = G_DSPOFF;
    477                                 break;
    478 
    479                         case G_DSPON:
    480                                 render = 1;
    481                                 current_op = G_DSPON;
    482                                 break;
    483 
    484                         case G_CRSFRM:
    485                                 // TODO Setup Cursor Form...
    486                                 current_op = 0x00;
    487                                 break;
    488 
    489                         default:
    490                                 current_op = 0x00;
    491                                 break;
    492                 }
    493         }
     50        ver2("lcd wr %u:%d 0x%0*x", off, sz * 8, sz * 2, val);
    49451}
  • emu/sdl.c

    rf51359c rca77925  
    2727
    2828static sdl_func_t sdl_funcs[] = {
    29         lcd_sdl, ser_sdl, vid_sdl
     29        ser_sdl, vid_sdl
    3030};
    3131
Note: See TracChangeset for help on using the changeset viewer.