- Timestamp:
- 08/01/2017 10:32:52 PM (7 years ago)
- Branches:
- master
- Children:
- 6e313dd
- Parents:
- ea878ba
- Location:
- emu
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
emu/all.h
rea878ba rbdd5a63 63 63 extern const char *disk; 64 64 65 extern SDL_atomic_t run; 66 65 67 extern void sdl_init(void); 66 68 extern void sdl_quit(void); 69 extern void sdl_loop(void); 67 70 71 extern SDL_mutex *cpu_mutex; 72 73 extern void cpu_init(void); 74 extern void cpu_quit(void); 68 75 extern void cpu_loop(void); 69 76 … … 98 105 extern void ser_write(uint32_t off, int32_t sz, uint32_t val); 99 106 107 extern void ser_sdl(void); 100 108 extern void ser_text(SDL_TextInputEvent *ev); 101 109 extern void ser_key(SDL_KeyboardEvent *ev); -
emu/cpu.c
rea878ba rbdd5a63 52 52 } hw_t; 53 53 54 static uint64_t freq; 55 static uint64_t quan; 56 57 SDL_mutex *cpu_mutex; 58 54 59 static bool reset = true; 55 60 … … 620 625 } 621 626 622 void cpu_loop(void) 623 { 627 void 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 624 640 hw_init(); 625 641 bios_init(); 626 642 627 inf("entering CPU loop");628 643 m68k_init(); 629 644 m68k_set_cpu_type(M68K_CPU_TYPE_68000); 630 645 m68k_set_instr_hook_callback(inst_cb); 631 646 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 649 void cpu_quit(void) 650 { 651 hw_quit(); 652 SDL_DestroyMutex(cpu_mutex); 653 } 654 655 void cpu_loop(void) 656 { 657 inf("entering CPU loop"); 658 659 while (SDL_AtomicGet(&run) != 0) { 644 660 uint64_t until = SDL_GetPerformanceCounter() + quan; 661 662 if (SDL_LockMutex(cpu_mutex) < 0) { 663 fail("SDL_LockMutex() failed: %s", SDL_GetError()); 664 } 645 665 646 666 m68k_execute(CPU_FREQ / PER_SEC); … … 653 673 m68k_set_irq(irq); 654 674 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()); 688 677 } 689 678 … … 694 683 695 684 inf("leaving CPU loop"); 696 hw_quit(); 697 } 685 } -
emu/main.c
rea878ba rbdd5a63 40 40 const char *bios = "bios.abs"; 41 41 const char *disk = "buchla.disk"; 42 43 SDL_atomic_t run; 42 44 43 45 static void usage(FILE *fh) … … 118 120 } 119 121 122 static int32_t cpu_thread(void *data) 123 { 124 (void)data; 125 126 cpu_loop(); 127 return 0; 128 } 129 120 130 int32_t main(int32_t argc, char *argv[]) 121 131 { 122 132 parse_args(argc, argv); 123 133 sdl_init(); 134 cpu_init(); 124 135 125 cpu_loop(); 136 SDL_AtomicSet(&run, 1); 137 SDL_Thread *thr = SDL_CreateThread(cpu_thread, "cpu", NULL); 126 138 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(); 127 147 sdl_quit(); 128 148 return 0; -
emu/sdl.c
rea878ba rbdd5a63 51 51 SDL_Quit(); 52 52 } 53 54 void 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 60 60 static SDL_Window *win; 61 61 static SDL_Renderer *ren; 62 static SDL_atomic_t frame; 62 63 63 64 static TTF_Font *fon; … … 70 71 static int32_t bel = 0; 71 72 72 static void update(void) 73 { 73 static 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 79 static 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 96 static 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 111 static void down(void) 112 { 113 if (cur_y < CON_H - 1) { 114 ++cur_y; 115 return; 116 } 117 118 scroll(); 119 } 120 121 static 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 155 static 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 170 void 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 74 184 if (SDL_FillRect(sur, NULL, bel == 0 ? CON_BGR : CON_BEL) < 0) { 75 185 fail("SDL_FillRect() failed: %s", SDL_GetError()); … … 86 196 87 197 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); 89 211 90 212 if (lin == NULL) { … … 118 240 } 119 241 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 209 242 void ser_key(SDL_KeyboardEvent *ev) 210 243 { … … 252 285 } 253 286 287 SDL_AtomicSet(&frame, 1); 288 254 289 SDL_RWops *ops = SDL_RWFromFile(CON_FONT, "rb"); 255 290 … … 286 321 mem[y][CON_W] = 0; 287 322 } 288 289 update();290 323 } 291 324 … … 309 342 310 343 if (bel == BEL_CYC - 1 || bel == 0) { 311 update();344 SDL_AtomicAdd(&frame, 1); 312 345 } 313 346 }
Note:
See TracChangeset
for help on using the changeset viewer.