- Timestamp:
- 09/09/2017 11:11:32 PM (7 years ago)
- Branches:
- master
- Children:
- 0d83ce8
- Parents:
- e26a632 (diff), 18cbd53 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - git-author:
- Thomas Lopatic <thomas@…> (09/09/2017 11:11:27 PM)
- git-committer:
- Thomas Lopatic <thomas@…> (09/09/2017 11:11:32 PM)
- Location:
- emu
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
emu/all.h
re26a632 r67fecc3 69 69 extern uint32_t vid_win; 70 70 extern uint32_t ser_win; 71 extern uint32_t lcd_win; 71 72 72 73 extern void sdl_init(void); … … 113 114 extern uint32_t lcd_read(uint32_t off, int32_t sz); 114 115 extern void lcd_write(uint32_t off, int32_t sz, uint32_t val); 116 117 extern void lcd_sdl(void); 115 118 116 119 extern void ser_init(void); … … 162 165 extern void kbd_write(uint32_t off, int32_t sz, uint32_t val); 163 166 164 extern void kbd_key(SDL_KeyboardEvent *ev, bool dn);167 extern void kbd_key(SDL_KeyboardEvent *ev, bool vid, bool dn); -
emu/kbd.c
re26a632 r67fecc3 104 104 } 105 105 106 static void slid(int32_t sig, bool on, int32_t val) 107 { 108 out((uint8_t)(0x80 | sig)); 109 out(on ? 0x01 : 0x00); 110 out((uint8_t)val); 111 } 112 106 113 #if defined NOT_YET 107 static void pot _128(int32_t sig, int32_t val)114 static void pot(int32_t sig, int32_t val) 108 115 { 109 116 out((uint8_t)(0x80 | sig)); 110 117 out((uint8_t)val); 111 118 } 112 113 static void pot_256(int32_t sig, int32_t val)114 {115 out((uint8_t)(0x80 | sig));116 out((uint8_t)((val >> 7) & 0x01));117 out((uint8_t)(val & 0x7f));118 }119 119 #endif 120 120 121 void kbd_key(SDL_KeyboardEvent *ev, bool dn)121 static void vid_key(SDL_KeyboardEvent *ev, bool dn) 122 122 { 123 123 if ((ev->keysym.mod & KMOD_SHIFT) != 0 && … … 173 173 } 174 174 175 static void lcd_key(SDL_KeyboardEvent *ev, bool dn) 176 { 177 if ((ev->keysym.mod & KMOD_CTRL) != 0 && 178 ev->keysym.sym >= SDLK_a && ev->keysym.sym <= SDLK_n) { 179 int32_t i = ev->keysym.sym - SDLK_a; 180 ver2("kbd lcd %d %s", i, dn ? "dn" : "up"); 181 182 if (dn) { 183 but_on(39 + i); 184 } 185 else { 186 but_off(39 + i); 187 } 188 189 return; 190 } 191 192 if (ev->keysym.sym >= SDLK_a && ev->keysym.sym <= SDLK_n) { 193 static int32_t lev[14] = { 194 64, 0, 0, 0, 0, 64, 64, 64, 64, 0, 0, 0, 64, 0 195 }; 196 197 int32_t i = ev->keysym.sym - SDLK_a; 198 int32_t val = lev[i]; 199 200 if (!dn) { 201 if ((ev->keysym.mod & KMOD_SHIFT) != 0) { 202 val = val > 10 ? val - 10 : 0; 203 } 204 else { 205 val = val < 117 ? val + 10 : 127; 206 } 207 } 208 209 ver2("kbd sli %d %s %d", i, dn ? "dn" : "up", val); 210 slid(25 + i, dn, val); 211 212 lev[i] = val; 213 return; 214 } 215 } 216 217 void kbd_key(SDL_KeyboardEvent *ev, bool vid, bool dn) 218 { 219 if (vid) { 220 vid_key(ev, dn); 221 } 222 else { 223 lcd_key(ev, dn); 224 } 225 } 226 175 227 void kbd_init(void) 176 228 { -
emu/lcd.c
re26a632 r67fecc3 24 24 int32_t lcd_verbose = 0; 25 25 26 #define WIN_W (1615 * 2 / 3) 27 #define WIN_H (304 * 2 / 3) 28 29 #define GFX_BGR 0x00000000 30 #define GFX_FGR 0xFFFFFFFF 31 32 #define TXT_BGR 0x000000FF 33 #define TXT_FGR ((SDL_Color){ .r = 255, .b = 255, .g = 255, .a = 255 }) 34 35 #define REG_ARG 0 36 #define REG_COM 1 37 38 #define COM_NONE 0x00 39 #define COM_MWRITE 0x42 40 #define COM_MREAD 0x43 41 #define COM_CRSWR 0x46 42 #define COM_CRSMRT 0x4C 43 #define COM_CRSMUP 0x4E 44 #define COM_CRSMDN 0x4F 45 #define COM_DSPOFF 0x58 46 #define COM_DSPON 0x59 47 48 #define TXT_W 85 49 #define TXT_H 8 50 51 #define GFX_W 85 52 #define GFX_H 64 53 #define GFX_PIX 6 54 55 #define BASE_TXT 0x0000 56 #define BASE_GFX 0x2000 57 58 #define DIR_UP -85 59 #define DIR_DOWN 85 60 #define DIR_RIGHT 1 61 62 static uint8_t mem_txt[TXT_H * TXT_W]; 63 static uint8_t mem_gfx[GFX_H * GFX_W]; 64 65 static SDL_Window *win; 66 uint32_t lcd_win; 67 68 static SDL_Renderer *ren; 69 static SDL_atomic_t frame; 70 static SDL_atomic_t ena; 71 72 static TTF_Font *fon; 73 static int32_t fon_w, fon_h; 74 75 static int32_t txt_w, txt_h; 76 static SDL_Surface *txt; 77 static SDL_Texture *gfx; 78 79 static int32_t com; 80 static int32_t n_arg; 81 static int32_t cur = BASE_TXT; 82 static int32_t dir = DIR_RIGHT; 83 84 void lcd_sdl(void) 85 { 86 ver3("lcd_sdl()"); 87 88 static int32_t last = 0; 89 int32_t now = SDL_AtomicGet(&frame); 90 91 if (last == now) { 92 ver3("no update"); 93 return; 94 } 95 96 last = now; 97 98 if (SDL_FillRect(txt, NULL, TXT_BGR) < 0) { 99 fail("SDL_FillRect() failed: %s", SDL_GetError()); 100 } 101 102 if (SDL_AtomicGet(&ena) == 0) { 103 SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, txt); 104 105 if (tex == NULL) { 106 fail("SDL_CreateTextureFromSurface() failed: %s", SDL_GetError()); 107 } 108 109 if (SDL_RenderCopy(ren, tex, NULL, NULL) < 0) { 110 fail("SDL_RenderCopy() failed: %s", SDL_GetError()); 111 } 112 113 SDL_DestroyTexture(tex); 114 SDL_RenderPresent(ren); 115 return; 116 } 117 118 for (int32_t y = 0; y < TXT_H; ++y) { 119 char line[TXT_W + 1]; 120 line[TXT_W] = 0; 121 122 if (SDL_LockMutex(cpu_mutex) < 0) { 123 fail("SDL_LockMutex() failed: %s", SDL_GetError()); 124 } 125 126 memcpy(line, mem_txt + y * TXT_W, TXT_W); 127 128 if (SDL_UnlockMutex(cpu_mutex) < 0) { 129 fail("SDL_UnlockMutex() failed: %s", SDL_GetError()); 130 } 131 132 for (int32_t x = 0; x < TXT_W; ++x) { 133 if (line[x] == 0x00) { 134 line[x] = ' '; 135 } 136 } 137 138 SDL_Surface *lin = TTF_RenderText_Blended(fon, line, TXT_FGR); 139 140 if (lin == NULL) { 141 fail("TTF_RenderText_Blended() failed: %s", TTF_GetError()); 142 } 143 144 if (SDL_BlitSurface(lin, NULL, txt, &(SDL_Rect){ 145 .x = 0, 146 .y = y * fon_h, 147 .w = TXT_W * fon_w, 148 .h = fon_h 149 })) { 150 fail("SDL_BlitSurface() failed: %s", SDL_GetError()); 151 } 152 153 SDL_FreeSurface(lin); 154 } 155 156 SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, txt); 157 158 if (tex == NULL) { 159 fail("SDL_CreateTextureFromSurface() failed: %s", SDL_GetError()); 160 } 161 162 if (SDL_RenderCopy(ren, tex, NULL, NULL) < 0) { 163 fail("SDL_RenderCopy() failed: %s", SDL_GetError()); 164 } 165 166 SDL_DestroyTexture(tex); 167 168 void *buf; 169 int32_t pitch; 170 171 if (SDL_LockTexture(gfx, NULL, &buf, &pitch) < 0) { 172 fail("SDL_LockTexture() failed: %s", SDL_GetError()); 173 } 174 175 uint32_t *pix = buf; 176 177 for (int32_t y = 0; y < GFX_H; ++y) { 178 for (int32_t x = 0; x < GFX_W; ++x) { 179 uint8_t b = mem_gfx[y * GFX_W + x]; 180 181 for (int32_t p = 0; p < GFX_PIX; ++p) { 182 bool set = (b & (1 << (7 - p))) != 0; 183 *pix++ = set ? GFX_FGR : GFX_BGR; 184 } 185 } 186 187 pix += pitch / 4 - GFX_W * GFX_PIX; 188 } 189 190 SDL_UnlockTexture(gfx); 191 192 if (SDL_RenderCopy(ren, gfx, NULL, NULL) < 0) { 193 fail("SDL_RenderCopy() failed: %s", SDL_GetError()); 194 } 195 196 SDL_RenderPresent(ren); 197 } 198 26 199 void lcd_init(void) 27 200 { 28 201 ver("lcd init"); 202 203 win = SDL_CreateWindow("LCD", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 204 WIN_W, WIN_H, 0); 205 206 if (win == NULL) { 207 fail("SDL_CreateWindow() failed: %s", SDL_GetError()); 208 } 209 210 lcd_win = SDL_GetWindowID(win); 211 212 if (lcd_win == 0) { 213 fail("SDL_GetWindowID() failed: %s", SDL_GetError()); 214 } 215 216 ren = SDL_CreateRenderer(win, -1, 0); 217 218 if (ren == NULL) { 219 fail("SDL_CreateRenderer() failed: %s", SDL_GetError()); 220 } 221 222 gfx = SDL_CreateTexture(ren, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, 223 GFX_W * GFX_PIX, GFX_H); 224 225 if (gfx == NULL) { 226 fail("SDL_CreateTexture() failed: %s", SDL_GetError()); 227 } 228 229 if (SDL_SetTextureBlendMode(gfx, SDL_BLENDMODE_BLEND) < 0) { 230 fail("SDL_SetTextureBlendMode() failed: %s", SDL_GetError()); 231 } 232 233 SDL_RWops *ops = SDL_RWFromFile(font, "rb"); 234 235 if (ops == NULL) { 236 fail("error while opening font file %s: %s", font, SDL_GetError()); 237 } 238 239 fon = TTF_OpenFontRW(ops, 1, 32); 240 241 if (fon == NULL) { 242 fail("error while loading font file %s: %s", font, TTF_GetError()); 243 } 244 245 fon_h = TTF_FontLineSkip(fon); 246 247 if (TTF_GlyphMetrics(fon, 'X', NULL, NULL, NULL, NULL, &fon_w) < 0) { 248 fail("error while measuring font width: %s", TTF_GetError()); 249 } 250 251 txt_w = TXT_W * fon_w; 252 txt_h = TXT_H * fon_h; 253 254 txt = SDL_CreateRGBSurfaceWithFormat(0, txt_w, txt_h, 32, SDL_PIXELFORMAT_RGBA8888); 255 256 if (txt == NULL) { 257 fail("SDL_CreateRGBSurface() failed: %s", SDL_GetError()); 258 } 259 260 for (int32_t i = 0; i < TXT_W * TXT_H; ++i) { 261 mem_txt[i] = ' '; 262 } 29 263 } 30 264 … … 32 266 { 33 267 ver("lcd quit"); 268 269 SDL_FreeSurface(txt); 270 TTF_CloseFont(fon); 271 272 SDL_DestroyTexture(gfx); 273 274 SDL_DestroyRenderer(ren); 275 SDL_DestroyWindow(win); 34 276 } 35 277 … … 43 285 { 44 286 ver2("lcd rd %u:%d", off, sz * 8); 45 return 0; 287 288 if (sz != 1 || off != 1) { 289 fail("invalid lcd rd %u:%d", off, sz * 8); 290 } 291 292 switch (com) { 293 case COM_MREAD: 294 if (cur >= BASE_TXT && cur < BASE_TXT + TXT_W * TXT_H) { 295 return mem_txt[cur - BASE_TXT]; 296 } 297 298 if (cur >= BASE_GFX && cur < BASE_GFX + GFX_W * GFX_H) { 299 return mem_gfx[cur - BASE_GFX]; 300 } 301 302 return 0x00; 303 304 default: 305 return 0x00; 306 } 307 } 308 309 static void proc_arg(int32_t val) 310 { 311 switch (com) { 312 case COM_MWRITE: 313 if (cur >= BASE_TXT && cur < BASE_TXT + TXT_W * TXT_H) { 314 mem_txt[cur - BASE_TXT] = (uint8_t)val; 315 } 316 else if (cur >= BASE_GFX && cur < BASE_GFX + GFX_W * GFX_H) { 317 mem_gfx[cur - BASE_GFX] = (uint8_t)val; 318 } 319 320 cur += dir; 321 SDL_AtomicAdd(&frame, 1); 322 break; 323 324 case COM_CRSWR: 325 if (n_arg == 0) { 326 cur = val; 327 } 328 else if (n_arg == 1) { 329 cur |= val << 8; 330 331 if (cur < BASE_TXT || 332 (cur >= BASE_TXT + TXT_W * TXT_H && cur < BASE_GFX) || 333 cur >= BASE_GFX + GFX_W * GFX_H) { 334 fail("invalid address 0x%04x", cur); 335 } 336 } 337 338 break; 339 340 default: 341 break; 342 } 343 } 344 345 static void proc_com(int32_t val) 346 { 347 switch (val) { 348 case COM_CRSWR: 349 case COM_MREAD: 350 case COM_MWRITE: 351 com = val; 352 break; 353 354 case COM_CRSMRT: 355 dir = DIR_RIGHT; 356 com = COM_NONE; 357 break; 358 359 case COM_CRSMUP: 360 dir = DIR_UP; 361 com = COM_NONE; 362 break; 363 364 case COM_CRSMDN: 365 dir = DIR_DOWN; 366 com = COM_NONE; 367 break; 368 369 case COM_DSPOFF: 370 SDL_AtomicSet(&ena, 0); 371 com = COM_NONE; 372 break; 373 374 case COM_DSPON: 375 SDL_AtomicSet(&ena, 1); 376 com = COM_NONE; 377 break; 378 379 default: 380 com = COM_NONE; 381 break; 382 } 46 383 } 47 384 … … 49 386 { 50 387 ver2("lcd wr %u:%d 0x%0*x", off, sz * 8, sz * 2, val); 51 } 388 389 if (sz != 1 || off > 1) { 390 fail("invalid lcd wr %u:%d", off, sz * 8); 391 } 392 393 switch (off) { 394 case REG_ARG: 395 proc_arg((int32_t)val); 396 ++n_arg; 397 break; 398 399 case REG_COM: 400 proc_com((int32_t)val); 401 n_arg = 0; 402 break; 403 404 default: 405 break; 406 } 407 } -
emu/sdl.c
re26a632 r67fecc3 27 27 28 28 static sdl_func_t sdl_funcs[] = { 29 ser_sdl, vid_sdl29 lcd_sdl, ser_sdl, vid_sdl 30 30 }; 31 31 … … 161 161 } 162 162 else if (win == vid_win) { 163 kbd_key(&ev.key, true); 163 kbd_key(&ev.key, true, true); 164 } 165 else if (win == lcd_win) { 166 kbd_key(&ev.key, false, true); 164 167 } 165 168 … … 171 174 172 175 if (win == vid_win) { 173 kbd_key(&ev.key, false); 176 kbd_key(&ev.key, true, false); 177 } 178 else if (win == lcd_win) { 179 kbd_key(&ev.key, false, false); 174 180 } 175 181 -
emu/vid.c
re26a632 r67fecc3 244 244 ver("vid init"); 245 245 246 win = SDL_CreateWindow(" Display", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,246 win = SDL_CreateWindow("Screen", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 247 247 WIN_W, WIN_H, 0); 248 248
Note:
See TracChangeset
for help on using the changeset viewer.