Changeset bdd5a63 in buchla-emu


Ignore:
Timestamp:
08/01/2017 10:32:52 PM (7 years ago)
Author:
Thomas Lopatic <thomas@…>
Branches:
master
Children:
6e313dd
Parents:
ea878ba
Message:

Separate thread for rendering.

Location:
emu
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • emu/all.h

    rea878ba rbdd5a63  
    6363extern const char *disk;
    6464
     65extern SDL_atomic_t run;
     66
    6567extern void sdl_init(void);
    6668extern void sdl_quit(void);
     69extern void sdl_loop(void);
    6770
     71extern SDL_mutex *cpu_mutex;
     72
     73extern void cpu_init(void);
     74extern void cpu_quit(void);
    6875extern void cpu_loop(void);
    6976
     
    98105extern void ser_write(uint32_t off, int32_t sz, uint32_t val);
    99106
     107extern void ser_sdl(void);
    100108extern void ser_text(SDL_TextInputEvent *ev);
    101109extern void ser_key(SDL_KeyboardEvent *ev);
  • emu/cpu.c

    rea878ba rbdd5a63  
    5252} hw_t;
    5353
     54static uint64_t freq;
     55static uint64_t quan;
     56
     57SDL_mutex *cpu_mutex;
     58
    5459static bool reset = true;
    5560
     
    620625}
    621626
    622 void cpu_loop(void)
    623 {
     627void cpu_init(void)
     628{
     629        cpu_mutex = SDL_CreateMutex();
     630
     631        if (cpu_mutex == NULL) {
     632                fail("SDL_CreateMutex() failed: %s", SDL_GetError());
     633        }
     634
     635        freq = SDL_GetPerformanceFrequency();
     636        quan = freq / PER_SEC;
     637
     638        inf("freq %" PRIu64 " quan %" PRIu64, freq, quan);
     639
    624640        hw_init();
    625641        bios_init();
    626642
    627         inf("entering CPU loop");
    628643        m68k_init();
    629644        m68k_set_cpu_type(M68K_CPU_TYPE_68000);
    630645        m68k_set_instr_hook_callback(inst_cb);
    631646        m68k_pulse_reset();
    632 
    633         uint64_t freq = SDL_GetPerformanceFrequency();
    634         uint64_t quan = freq / PER_SEC;
    635         inf("freq %" PRIu64 " quan %" PRIu64, freq, quan);
    636 
    637         bool run = true;
    638 
    639 #if defined EMU_LINUX
    640         SDL_Scancode down = SDL_SCANCODE_UNKNOWN;
    641 #endif
    642 
    643         while (run) {
     647}
     648
     649void cpu_quit(void)
     650{
     651        hw_quit();
     652        SDL_DestroyMutex(cpu_mutex);
     653}
     654
     655void cpu_loop(void)
     656{
     657        inf("entering CPU loop");
     658
     659        while (SDL_AtomicGet(&run) != 0) {
    644660                uint64_t until = SDL_GetPerformanceCounter() + quan;
     661
     662                if (SDL_LockMutex(cpu_mutex) < 0) {
     663                        fail("SDL_LockMutex() failed: %s", SDL_GetError());
     664                }
    645665
    646666                m68k_execute(CPU_FREQ / PER_SEC);
     
    653673                m68k_set_irq(irq);
    654674
    655                 SDL_Event ev;
    656 
    657                 while (SDL_PollEvent(&ev) > 0) {
    658 #if defined EMU_LINUX
    659                         // Work around duplicate key-down events on Linux.
    660 
    661                         if (ev.type == SDL_KEYDOWN) {
    662                                 if (down == ev.key.keysym.scancode) {
    663                                         continue;
    664                                 }
    665 
    666                                 down = ev.key.keysym.scancode;
    667                         }
    668                         else if (ev.type == SDL_KEYUP) {
    669                                 down = SDL_SCANCODE_UNKNOWN;
    670                         }
    671 #endif
    672 
    673                         if (ev.type == SDL_QUIT ||
    674                                         (ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_ESCAPE)) {
    675                                 run = false;
    676                                 continue;
    677                         }
    678 
    679                         if (ev.type == SDL_TEXTINPUT) {
    680                                 ser_text(&ev.text);
    681                                 continue;
    682                         }
    683 
    684                         if (ev.type == SDL_KEYDOWN) {
    685                                 ser_key(&ev.key);
    686                                 continue;
    687                         }
     675                if (SDL_UnlockMutex(cpu_mutex) < 0) {
     676                        fail("SDL_UnlockMutex() failed: %s", SDL_GetError());
    688677                }
    689678
     
    694683
    695684        inf("leaving CPU loop");
    696         hw_quit();
    697 }
     685}
  • emu/main.c

    rea878ba rbdd5a63  
    4040const char *bios = "bios.abs";
    4141const char *disk = "buchla.disk";
     42
     43SDL_atomic_t run;
    4244
    4345static void usage(FILE *fh)
     
    118120}
    119121
     122static int32_t cpu_thread(void *data)
     123{
     124        (void)data;
     125
     126        cpu_loop();
     127        return 0;
     128}
     129
    120130int32_t main(int32_t argc, char *argv[])
    121131{
    122132        parse_args(argc, argv);
    123133        sdl_init();
     134        cpu_init();
    124135
    125         cpu_loop();
     136        SDL_AtomicSet(&run, 1);
     137        SDL_Thread *thr = SDL_CreateThread(cpu_thread, "cpu", NULL);
    126138
     139        if (thr == NULL) {
     140                fail("SDL_CreateThread() failed: %s", SDL_GetError());
     141        }
     142
     143        sdl_loop();
     144        SDL_WaitThread(thr, NULL);
     145
     146        cpu_quit();
    127147        sdl_quit();
    128148        return 0;
  • emu/sdl.c

    rea878ba rbdd5a63  
    5151        SDL_Quit();
    5252}
     53
     54void sdl_loop(void)
     55{
     56        inf("entering SDL loop");
     57
     58#if defined EMU_LINUX
     59        SDL_Scancode down = SDL_SCANCODE_UNKNOWN;
     60#endif
     61
     62        while (SDL_AtomicGet(&run) != 0) {
     63                ser_sdl();
     64
     65                SDL_Event ev;
     66
     67                while (SDL_PollEvent(&ev) > 0) {
     68#if defined EMU_LINUX
     69                        // Work around duplicate key-down events on Linux.
     70
     71                        if (ev.type == SDL_KEYDOWN) {
     72                                if (down == ev.key.keysym.scancode) {
     73                                        continue;
     74                                }
     75
     76                                down = ev.key.keysym.scancode;
     77                        }
     78                        else if (ev.type == SDL_KEYUP) {
     79                                down = SDL_SCANCODE_UNKNOWN;
     80                        }
     81#endif
     82
     83                        if (ev.type == SDL_QUIT ||
     84                                        (ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_ESCAPE)) {
     85                                ver("quit");
     86                                SDL_AtomicSet(&run, 0);
     87                                continue;
     88                        }
     89
     90                        if (ev.type == SDL_TEXTINPUT) {
     91                                ser_text(&ev.text);
     92                                continue;
     93                        }
     94
     95                        if (ev.type == SDL_KEYDOWN) {
     96                                ser_key(&ev.key);
     97                                continue;
     98                        }
     99
     100                        SDL_Delay(50);
     101                }
     102        }
     103
     104        inf("leaving SDL loop");
     105}
  • emu/ser.c

    rea878ba rbdd5a63  
    6060static SDL_Window *win;
    6161static SDL_Renderer *ren;
     62static SDL_atomic_t frame;
    6263
    6364static TTF_Font *fon;
     
    7071static int32_t bel = 0;
    7172
    72 static void update(void)
    73 {
     73static void scroll(void)
     74{
     75        memmove(mem, mem + 1, (CON_H - 1) * (CON_W + 1));
     76        memset(mem + (CON_H - 1), ' ', CON_W);
     77}
     78
     79static void forw(void)
     80{
     81        if (cur_x < CON_W - 1) {
     82                ++cur_x;
     83                return;
     84        }
     85
     86        if (cur_y == CON_H - 1) {
     87                cur_x = 0;
     88                scroll();
     89                return;
     90        }
     91
     92        cur_x = 0;
     93        ++cur_y;
     94}
     95
     96static void back(void)
     97{
     98        if (cur_x > 0) {
     99                --cur_x;
     100                return;
     101        }
     102
     103        if (cur_y == 0) {
     104                return;
     105        }
     106
     107        cur_x = CON_W - 1;
     108        --cur_y;
     109}
     110
     111static void down(void)
     112{
     113        if (cur_y < CON_H - 1) {
     114                ++cur_y;
     115                return;
     116        }
     117
     118        scroll();
     119}
     120
     121static void echo(uint8_t c)
     122{
     123        if (c < 32) {
     124                switch (c) {
     125                case '\r':
     126                        cur_x = 0;
     127                        break;
     128
     129                case '\n':
     130                        down();
     131                        break;
     132
     133                case '\b':
     134                        back();
     135                        break;
     136
     137                case '\a':
     138                        bel = BEL_CYC;
     139                        break;
     140
     141                default:
     142                        echo('^');
     143                        echo((uint8_t)(c + '@'));
     144                        return;
     145                }
     146        }
     147        else {
     148                mem[cur_y][cur_x] = c;
     149                forw();
     150        }
     151
     152        SDL_AtomicAdd(&frame, 1);
     153}
     154
     155static void out(int32_t un, uint8_t c)
     156{
     157        if (SDL_LockMutex(cpu_mutex) < 0) {
     158                fail("SDL_LockMutex() failed: %s", SDL_GetError());
     159        }
     160
     161        state[un].rdr = c;
     162        state[un].rdr_ok = true;
     163        state[un].irq_r = true;
     164
     165        if (SDL_UnlockMutex(cpu_mutex) < 0) {
     166                fail("SDL_UnlockMutex() failed: %s", SDL_GetError());
     167        }
     168}
     169
     170void ser_sdl(void)
     171{
     172        ver3("ser_sdl()");
     173
     174        static int32_t last = 0;
     175        int32_t now = SDL_AtomicGet(&frame);
     176
     177        if (last == now) {
     178                ver3("no update");
     179                return;
     180        }
     181
     182        last = now;
     183
    74184        if (SDL_FillRect(sur, NULL, bel == 0 ? CON_BGR : CON_BEL) < 0) {
    75185                fail("SDL_FillRect() failed: %s", SDL_GetError());
     
    86196
    87197        for (int32_t y = 0; y < CON_H; ++y) {
    88                 SDL_Surface *lin = TTF_RenderText_Blended(fon, (char *)mem[y], CON_FGR);
     198                char line[CON_W + 1];
     199
     200                if (SDL_LockMutex(cpu_mutex) < 0) {
     201                        fail("SDL_LockMutex() failed: %s", SDL_GetError());
     202                }
     203
     204                memcpy(line, mem[y], CON_W + 1);
     205
     206                if (SDL_UnlockMutex(cpu_mutex) < 0) {
     207                        fail("SDL_UnlockMutex() failed: %s", SDL_GetError());
     208                }
     209
     210                SDL_Surface *lin = TTF_RenderText_Blended(fon, line, CON_FGR);
    89211
    90212                if (lin == NULL) {
     
    118240}
    119241
    120 static void scroll(void)
    121 {
    122         memmove(mem, mem + 1, (CON_H - 1) * (CON_W + 1));
    123         memset(mem + (CON_H - 1), ' ', CON_W);
    124 }
    125 
    126 static void forw(void)
    127 {
    128         if (cur_x < CON_W - 1) {
    129                 ++cur_x;
    130                 return;
    131         }
    132 
    133         if (cur_y == CON_H - 1) {
    134                 cur_x = 0;
    135                 scroll();
    136                 return;
    137         }
    138 
    139         cur_x = 0;
    140         ++cur_y;
    141 }
    142 
    143 static void back(void)
    144 {
    145         if (cur_x > 0) {
    146                 --cur_x;
    147                 return;
    148         }
    149 
    150         if (cur_y == 0) {
    151                 return;
    152         }
    153 
    154         cur_x = CON_W - 1;
    155         --cur_y;
    156 }
    157 
    158 static void down(void)
    159 {
    160         if (cur_y < CON_H - 1) {
    161                 ++cur_y;
    162                 return;
    163         }
    164 
    165         scroll();
    166 }
    167 
    168 static void echo(uint8_t c)
    169 {
    170         if (c < 32) {
    171                 switch (c) {
    172                 case '\r':
    173                         cur_x = 0;
    174                         break;
    175 
    176                 case '\n':
    177                         down();
    178                         break;
    179 
    180                 case '\b':
    181                         back();
    182                         break;
    183 
    184                 case '\a':
    185                         bel = BEL_CYC;
    186                         break;
    187 
    188                 default:
    189                         echo('^');
    190                         echo((uint8_t)(c + '@'));
    191                         return;
    192                 }
    193         }
    194         else {
    195                 mem[cur_y][cur_x] = c;
    196                 forw();
    197         }
    198 
    199         update();
    200 }
    201 
    202 static void out(int32_t un, uint8_t c)
    203 {
    204         state[un].rdr = c;
    205         state[un].rdr_ok = true;
    206         state[un].irq_r = true;
    207 }
    208 
    209242void ser_key(SDL_KeyboardEvent *ev)
    210243{
     
    252285        }
    253286
     287        SDL_AtomicSet(&frame, 1);
     288
    254289        SDL_RWops *ops = SDL_RWFromFile(CON_FONT, "rb");
    255290
     
    286321                mem[y][CON_W] = 0;
    287322        }
    288 
    289         update();
    290323}
    291324
     
    309342
    310343                if (bel == BEL_CYC - 1 || bel == 0) {
    311                         update();
     344                        SDL_AtomicAdd(&frame, 1);
    312345                }
    313346        }
Note: See TracChangeset for help on using the changeset viewer.