#include #include #include #include #include #include "device.h" #include #define BPP 4 #define CHAR_W 4 #define CHAR_H 8 #define TEXT_ROWS 12 #define TEXT_COLS 32 #define BORDER_L 16 #define BORDER_R 16 #define BORDER_T 16 #define BORDER_B 16 #define ZOOM 8 #define KBUF_SIZE 16 #define COLORS (1<pixels); for (i=0; i>j) & 1) != 0; // raster[x+y*glyph_shapes->w] = (pixel ? 1 : 0); for (fg=0; fgw] = (pixel ? fg : bg); } } SDL_UnlockSurface(glyph_shapes); update_glyph_tiles(); printf("update_font() completed\n"); } void update_palette() { int i; printf("update_palette()\n"); // if (palette == NULL) // palette = SDL_AllocPalette(256); for (i=0; icolors[i].r = ((PALETTE(i)>>8)&0xf)*0xff/0xf; palette->colors[i].g = ((PALETTE(i)>>4)&0xf)*0xff/0xf; palette->colors[i].b = ((PALETTE(i))&0xf)*0xff/0xf; palette->colors[i].a = 255; // printf("%2d %02x%02x%02x\n", i, palette->colors[i].r, palette->colors[i].g, palette->colors[i].b); } update_glyph_tiles(); printf("update_palette() completed\n"); } void lem1802_init() { screen_iptr = font_iptr = palette_iptr = border = 0; if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError()); } palette = SDL_AllocPalette(256); glyph_shapes = SDL_CreateRGBSurface(0, CHAR_W*128, CHAR_H*COLORS*COLORS, 8, 0, 0, 0, 0); if (glyph_shapes == NULL) { SDL_Log("SDL_CreateRGBSurface() failed: %s", SDL_GetError()); } // SDL_SetSurfacePalette(glyph_shapes, palette); glyph_tiles = SDL_CreateRGBSurface(0, glyph_shapes->w, glyph_shapes->h, 32, 0, 0, 0, 0); if (glyph_tiles == NULL) { SDL_Log("SDL_CreateRGBSurface() failed: %s", SDL_GetError()); } update_font(); update_palette(); } void keyboard_init() { khead = klen = 0; kint = 0; } void lem1802_free() { if (window) SDL_DestroyWindow(window); window = NULL; if (palette) SDL_FreePalette(palette); palette = NULL; if (glyph_tiles) SDL_FreeSurface(glyph_tiles); glyph_tiles = NULL; if (glyph_shapes) SDL_FreeSurface(glyph_shapes); glyph_shapes = NULL; // SDL_Quit(); } void process_key(SDL_Event *e) { uint8_t k=0; if ((e->type == SDL_TEXTINPUT) && (e->text.text[0] >= 0x20) && (e->text.text[0] <= 0x7f)) k = e->text.text[0]; else if (e->type == SDL_KEYDOWN) { switch (e->key.keysym.sym) { case SDLK_BACKSPACE: k = 0x10; break; case SDLK_RETURN: case SDLK_RETURN2: k = 0x11; break; case SDLK_INSERT: k = 0x12; break; case SDLK_DELETE: k = 0x13; break; case SDLK_UP: k = 0x80; break; case SDLK_DOWN: k = 0x81; break; case SDLK_LEFT: k = 0x82; break; case SDLK_RIGHT: k = 0x83; break; case SDLK_LSHIFT: case SDLK_RSHIFT: if (!ignore_modifiers) k = 0x90; break; case SDLK_LCTRL: case SDLK_RCTRL: if (!ignore_modifiers) k = 0x91; break; default: break; } } if (k != 0) { kbuf[khead] = k; khead = (khead + 1) % KBUF_SIZE; if (klen < KBUF_SIZE) { klen++; } if (kint != 0) intq_push(kint); } } void lem1802_tick() { uint16_t i; uint16_t cell; uint8_t ch, fg, bg; bool bl; SDL_Rect src, dst; SDL_Event e; static struct timeval last_frame = {0,0}; if (screen_iptr != 0) { // printf("Update\n"); while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) running = false; if (e.type == SDL_KEYDOWN) { if (e.key.keysym.sym == SDLK_F12) running = false; else if (e.key.keysym.sym == SDLK_F11) { update_font(); update_palette(); } else if (e.key.keysym.sym == SDLK_F10) { ignore_modifiers = !ignore_modifiers; } else process_key(&e); } if (e.type == SDL_TEXTINPUT) { // printf("Text input: %s\n", &e.text.text); process_key(&e); } } // gettimeofday(&t, NULL); if ((time.tv_sec - poweron_time.tv_sec)*100 + (time.tv_usec - poweron_time.tv_usec)/10000 < 100) return; if ((time.tv_sec - last_frame.tv_sec)*100 + (time.tv_usec - last_frame.tv_usec)/10000 < 2) return; last_frame.tv_sec = time.tv_sec; last_frame.tv_usec = time.tv_usec; src.x = 0; src.y = CHAR_H*((border&0xf)<<4|(border&0xf)); src.w = CHAR_W; src.h = CHAR_H; if (SDL_BlitScaled(glyph_tiles, &src, screenSurface, NULL) != 0) printf("BlitScaled() failed! SDL_Error: %s\n", SDL_GetError()); for (i=0; i> 8) & 0xf; fg = (bl && time.tv_usec>500000 ? bg : (cell >> 12) & 0xf); src.x = ch*CHAR_W; src.y = CHAR_H*(fg<<4|bg); src.w = CHAR_W; src.h = CHAR_H; dst.x = (BORDER_L+CHAR_W*(i%TEXT_COLS))*ZOOM; dst.y = (BORDER_T+CHAR_H*(i/TEXT_COLS))*ZOOM; dst.w = CHAR_W*ZOOM; dst.h = CHAR_H*ZOOM; if (SDL_BlitScaled(glyph_tiles, &src, screenSurface, &dst) != 0) printf("BlitScaled() failed! SDL_Error: %s\n", SDL_GetError()); } SDL_UpdateWindowSurface(window); } } void lem1802_irqh() { int i; switch (ra) { case 0: /* MEM_MAP_SCREEN */ if (screen_iptr == 0) { if (rb != 0) { /* LEM1802 power up */ poweron_time.tv_sec = time.tv_sec; poweron_time.tv_usec = time.tv_usec; window = SDL_CreateWindow("LEM1802", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_W, WINDOW_H, SDL_WINDOW_SHOWN); if(window == NULL) { printf("Window could not be created! SDL_Error: %s\n", SDL_GetError()); } else { screenSurface = SDL_GetWindowSurface(window); SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0x80, 0x80, 0x80)); SDL_UpdateWindowSurface(window); } } } else { if (rb == 0) { /* LEM1802 power down */ SDL_DestroyWindow(window); window = NULL; } } screen_iptr = rb; break; case 1: /* MEM_MAP_FONT */ font_iptr = rb; update_font(); break; case 2: /* MEM_MAP_PALETTE */ palette_iptr = rb; update_palette(); break; case 3: /* SET_BORDER_COLOR */ border = rb; break; case 4: /* MEM_DUMP_FONT */ printf("Dumping default font to 0x%04x\n", rb); for (i=0; i 0) { rc = kbuf[(khead+KBUF_SIZE-klen)%KBUF_SIZE]; klen--; } else rc = 0; break; case 2: /* Check key */ printf("Check if key 0x%04x is pressed\n", rb); rc = 0; break; case 3: /* Set interrupt message */ printf("Keyboard interrupt message: 0x%04x\n", rb); kint = rb; break; default: break; } } struct dev_entry lem1802_dev = { 0x1c6c8b36, 0x7349f615, 0x1802, "LEM1802 (SDL)", lem1802_irqh, lem1802_init, lem1802_free, lem1802_tick }; /* LEM1802 */ struct dev_entry keyboard_dev = { 0x6d53647c, 0x30cf7406, 1, "Keyboard (SDL)", keyboard_irqh, keyboard_init, NULL, NULL }; /* Generic keyboard */