From 4127d9bde8659feb32df697c420e73e0b80179b9 Mon Sep 17 00:00:00 2001 From: Maurizio Porrato Date: Thu, 23 Apr 2020 08:44:13 +0100 Subject: [PATCH] Add missing files --- .gitignore | 2 + data/c64-80x25-font.png | Bin 3330 -> 0 bytes data/font.png | Bin 0 -> 618 bytes data/png2c.py | 40 +++++ dev_clock.c | 62 +++++++ dev_debug.c | 62 +++++++ dev_lem1802.c | 361 ++++++++++++++++++++++++++++++++++++++++ device.c | 28 ++++ device.h | 27 +++ font.c | 132 +++++++++++++++ palette.c | 22 +++ 11 files changed, 736 insertions(+) delete mode 100644 data/c64-80x25-font.png create mode 100644 data/font.png create mode 100755 data/png2c.py create mode 100644 dev_clock.c create mode 100644 dev_debug.c create mode 100644 dev_lem1802.c create mode 100644 device.c create mode 100644 device.h create mode 100644 font.c create mode 100644 palette.c diff --git a/.gitignore b/.gitignore index c1df664..cb41444 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ *.o *.orig dsim +*.asm +*.bin diff --git a/data/c64-80x25-font.png b/data/c64-80x25-font.png deleted file mode 100644 index a09e9ea6cdaae801e180f9350b1a98b0e8799d71..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3330 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 literal 0 HcmV?d00001 diff --git a/data/png2c.py b/data/png2c.py new file mode 100755 index 0000000..d34cc3d --- /dev/null +++ b/data/png2c.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 + +from PIL import Image + +FONT_SIZE = (4, 8) + + +def convert(filename, subset=range(0,128)): + img = Image.open(filename) + print("""#include + +uint16_t font[] = {""") + grid = (img.size[0] // FONT_SIZE[0], img.size[1] // FONT_SIZE[1]) + ch = 0 + for r in range(grid[1]): + for c in range(grid[0]): + v = 0 + for x in range(FONT_SIZE[0]-1, -1, -1): + for y in range(FONT_SIZE[1]-1, -1, -1): + v <<= 1 + if img.getpixel((c*FONT_SIZE[0]+x,r*FONT_SIZE[1]+y)): + v |= 1 + h = (v >> 16) & 0xffff + l = v & 0xffff + if 32 <= ch < 127: + d = f'"{ch:c}" ' + else: + d = '' + if ch in subset: + print(f"\t0x{l:04x}, 0x{h:04x},\t/* {ch:3d} 0x{ch:02x} {d}*/") + ch += 1 + print("};") + + +if __name__ == '__main__': + import sys + + for fn in sys.argv[1:]: + convert(fn) + diff --git a/dev_clock.c b/dev_clock.c new file mode 100644 index 0000000..9138531 --- /dev/null +++ b/dev_clock.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include "device.h" + +struct timeval boot_time, last_jiffy; + +uint16_t clockdiv; +uint16_t intmsg; +uint64_t jiffies; +uint16_t clock_ticks; + +void clock_init() { + gettimeofday(&boot_time, NULL); + clockdiv = intmsg = clock_ticks = 0; + last_jiffy.tv_sec = last_jiffy.tv_usec = 0; + jiffies = 0; +} + +void clock_tick() +{ + // struct timeval now; + uint64_t delta; + + if (clockdiv != 0) { + // gettimeofday(&now, NULL); + delta = (time.tv_sec - last_jiffy.tv_sec)*10000 + (time.tv_usec - last_jiffy.tv_usec)/100; + if (delta >= 166) { + jiffies++; + last_jiffy.tv_sec = time.tv_sec; last_jiffy.tv_usec = time.tv_usec; + if (jiffies >= clockdiv) { + jiffies = 0; + clock_ticks++; + printf("Tick!\n"); + if (intmsg != 0) { + intq_push(intmsg); + } + } + } + } +} + +void clock_irqh() +{ + printf("Clock: A=0x%04x B=0x%04x\n", ra, rb); + switch (ra) { + case 0: + clockdiv = rb; + clock_ticks = 0; + break; + case 1: + rc = clock_ticks; + break; + case 2: + intmsg = rb; + break; + } +} + +struct dev_entry clock_dev = { 0x6d53647c, 0x12d0b402, 0x0000, clock_irqh, clock_init, NULL, clock_tick }; /* Clock device */ diff --git a/dev_debug.c b/dev_debug.c new file mode 100644 index 0000000..9c54993 --- /dev/null +++ b/dev_debug.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include "device.h" + +#define EMU_ID 0xed6f +#define EMU_VER 0x0000 + +void dumpregs() +{ + printf("%4s %4s %4s %4s %4s %4s %4s %4s %4s %4s %4s %4s\n", + "PC","SP","A","B","C","X","Y","Z","I","J","EX","IA"); + printf("%04hx %04hx %04hx %04hx %04hx %04hx %04hx %04hx %04hx %04hx %04hx %04hx\n", + rpc, rsp, ra, rb, rc, rx, ry, rz, ri, rj, rex, ria); +} + +void dump_ram(uint16_t addr, uint16_t count) +{ + uint16_t i, a; + + for (i=0; i +#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); + } + + if (glyph_tiles == NULL) { + glyph_tiles = SDL_CreateRGBSurface(0, glyph_shapes->w, glyph_shapes->h, 32, 0, 0, 0, 0); + } + + 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()); + } +} + +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; +// SDL_Quit(); +} + +void process_key(SDL_KeyboardEvent *ke) +{ + uint8_t k=0; + + if ((ke->keysym.sym >= 0x20) && (ke->keysym.sym <= 0x7f)) { + k = ke->keysym.sym; + } else { + switch (ke->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: + k = 0x90; + break; + case SDLK_LCTRL: + case SDLK_RCTRL: + 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 + process_key(&e.key); + } + } + + // 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 */ + gettimeofday(&poweron_time, NULL); + 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); + update_font(); + update_palette(); + } + } + } else { + if (rb == 0) { + /* LEM1802 power down */ + SDL_DestroyWindow(window); + window = NULL; + } + } + screen_iptr = rb; + break; + case 1: /* MEM_MAP_FONT */ + if (rb != font_iptr) { + font_iptr = rb; + update_font(); + } + break; + case 2: /* MEM_MAP_PALETTE */ + if (rb != palette_iptr) { + palette_iptr = rb; + update_palette(); + } + break; + case 3: /* SET_BORDER_COLOR */ + border = rb; + break; + case 4: /* MEM_DUMP_FONT */ + 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_irqh, lem1802_init, lem1802_free, lem1802_tick }; /* LEM1802 */ +struct dev_entry keyboard_dev = { 0x6d53647c, 0x30cf7406, 1, keyboard_irqh, keyboard_init, NULL, NULL }; /* Generic keyboard */ diff --git a/device.c b/device.c new file mode 100644 index 0000000..63c33fe --- /dev/null +++ b/device.c @@ -0,0 +1,28 @@ +#include +#include +#include "device.h" + +#ifdef DEV_DEBUG +extern struct dev_entry debug_dev; +#endif +#ifdef DEV_LEM1802 +extern struct dev_entry lem1802_dev; +extern struct dev_entry keyboard_dev; +#endif +#ifdef DEV_CLOCK +extern struct dev_entry clock_dev; +#endif + +struct dev_entry *iodevs[] = { +#ifdef DEV_DEBUG + &debug_dev, +#endif +#ifdef DEV_LEM1802 + &lem1802_dev, + &keyboard_dev, +#endif +#ifdef DEV_CLOCK + &clock_dev, +#endif + NULL +}; diff --git a/device.h b/device.h new file mode 100644 index 0000000..87c8259 --- /dev/null +++ b/device.h @@ -0,0 +1,27 @@ +#ifndef __DEVICE_H__ + +#include +#include +#include + +struct dev_entry { + uint32_t vendor; + uint32_t product; + uint16_t version; + void (*irqh)(); + void (*init)(); + void (*free)(); + void (*tick)(); +}; + +extern struct dev_entry *iodevs[]; + +extern bool running, trace; +extern uint16_t ram[0x10000]; +extern uint16_t ra, rb, rc, rx, ry, rz, ri, rj; +extern uint16_t rpc, rsp, rex, ria; +extern struct timeval time; + +extern void intq_push(uint16_t v); + +#endif diff --git a/font.c b/font.c new file mode 100644 index 0000000..c694018 --- /dev/null +++ b/font.c @@ -0,0 +1,132 @@ +#include + +uint16_t default_font[] = { + 0x9eb7, 0x8e38, /* 0 0x00 */ + 0x2c72, 0xf475, /* 1 0x01 */ + 0xbb19, 0x8f7f, /* 2 0x02 */ + 0xf985, 0x58b1, /* 3 0x03 */ + 0x2e24, 0x0024, /* 4 0x04 */ + 0x2a08, 0x0008, /* 5 0x05 */ + 0x0800, 0x0000, /* 6 0x06 */ + 0x0808, 0x0808, /* 7 0x07 */ + 0xff00, 0x0000, /* 8 0x08 */ + 0xf800, 0x0808, /* 9 0x09 */ + 0xf808, 0x0000, /* 10 0x0a */ + 0x0f08, 0x0000, /* 11 0x0b */ + 0x0f00, 0x0808, /* 12 0x0c */ + 0xff00, 0x0808, /* 13 0x0d */ + 0xf808, 0x0808, /* 14 0x0e */ + 0xff08, 0x0000, /* 15 0x0f */ + 0x0f08, 0x0808, /* 16 0x10 */ + 0xff08, 0x0808, /* 17 0x11 */ + 0x3366, 0xcc99, /* 18 0x12 */ + 0x3399, 0xcc66, /* 19 0x13 */ + 0xf8fe, 0x80e0, /* 20 0x14 */ + 0x1f7f, 0x0107, /* 21 0x15 */ + 0x0701, 0x7f1f, /* 22 0x16 */ + 0xe080, 0xfef8, /* 23 0x17 */ + 0x0055, 0x00aa, /* 24 0x18 */ + 0xaa55, 0xaa55, /* 25 0x19 */ + 0xaaff, 0x55ff, /* 26 0x1a */ + 0x0f0f, 0x0f0f, /* 27 0x1b */ + 0xf0f0, 0xf0f0, /* 28 0x1c */ + 0x0000, 0xffff, /* 29 0x1d */ + 0xffff, 0x0000, /* 30 0x1e */ + 0xffff, 0xffff, /* 31 0x1f */ + 0x0000, 0x0000, /* 32 0x20 " " */ + 0x5f00, 0x0000, /* 33 0x21 "!" */ + 0x0003, 0x0003, /* 34 0x22 """ */ + 0x143e, 0x003e, /* 35 0x23 "#" */ + 0x6b26, 0x0032, /* 36 0x24 "$" */ + 0x1c61, 0x0043, /* 37 0x25 "%" */ + 0x2936, 0x5076, /* 38 0x26 "&" */ + 0x0200, 0x0001, /* 39 0x27 "'" */ + 0x221c, 0x0041, /* 40 0x28 "(" */ + 0x2241, 0x001c, /* 41 0x29 ")" */ + 0x0814, 0x0014, /* 42 0x2a "*" */ + 0x1c08, 0x0008, /* 43 0x2b "+" */ + 0x2040, 0x0000, /* 44 0x2c "," */ + 0x0808, 0x0008, /* 45 0x2d "-" */ + 0x4000, 0x0000, /* 46 0x2e "." */ + 0x1c60, 0x0003, /* 47 0x2f "/" */ + 0x493e, 0x003e, /* 48 0x30 "0" */ + 0x7f42, 0x0040, /* 49 0x31 "1" */ + 0x5962, 0x0046, /* 50 0x32 "2" */ + 0x4922, 0x0036, /* 51 0x33 "3" */ + 0x080f, 0x007f, /* 52 0x34 "4" */ + 0x4527, 0x0039, /* 53 0x35 "5" */ + 0x493e, 0x0032, /* 54 0x36 "6" */ + 0x1961, 0x0007, /* 55 0x37 "7" */ + 0x4936, 0x0036, /* 56 0x38 "8" */ + 0x4926, 0x003e, /* 57 0x39 "9" */ + 0x2400, 0x0000, /* 58 0x3a ":" */ + 0x2440, 0x0000, /* 59 0x3b ";" */ + 0x1408, 0x0022, /* 60 0x3c "<" */ + 0x1414, 0x0014, /* 61 0x3d "=" */ + 0x1422, 0x0008, /* 62 0x3e ">" */ + 0x5902, 0x0006, /* 63 0x3f "?" */ + 0x593e, 0x005e, /* 64 0x40 "@" */ + 0x097e, 0x007e, /* 65 0x41 "A" */ + 0x497f, 0x0036, /* 66 0x42 "B" */ + 0x413e, 0x0022, /* 67 0x43 "C" */ + 0x417f, 0x003e, /* 68 0x44 "D" */ + 0x497f, 0x0041, /* 69 0x45 "E" */ + 0x097f, 0x0001, /* 70 0x46 "F" */ + 0x413e, 0x007a, /* 71 0x47 "G" */ + 0x087f, 0x007f, /* 72 0x48 "H" */ + 0x7f41, 0x0041, /* 73 0x49 "I" */ + 0x4020, 0x003f, /* 74 0x4a "J" */ + 0x087f, 0x0077, /* 75 0x4b "K" */ + 0x407f, 0x0040, /* 76 0x4c "L" */ + 0x067f, 0x007f, /* 77 0x4d "M" */ + 0x017f, 0x007e, /* 78 0x4e "N" */ + 0x413e, 0x003e, /* 79 0x4f "O" */ + 0x097f, 0x0006, /* 80 0x50 "P" */ + 0x613e, 0x007e, /* 81 0x51 "Q" */ + 0x097f, 0x0076, /* 82 0x52 "R" */ + 0x4926, 0x0032, /* 83 0x53 "S" */ + 0x7f01, 0x0001, /* 84 0x54 "T" */ + 0x403f, 0x007f, /* 85 0x55 "U" */ + 0x601f, 0x001f, /* 86 0x56 "V" */ + 0x307f, 0x007f, /* 87 0x57 "W" */ + 0x0877, 0x0077, /* 88 0x58 "X" */ + 0x7807, 0x0007, /* 89 0x59 "Y" */ + 0x4971, 0x0047, /* 90 0x5a "Z" */ + 0x7f00, 0x0041, /* 91 0x5b "[" */ + 0x1c03, 0x0060, /* 92 0x5c "\" */ + 0x7f41, 0x0000, /* 93 0x5d "]" */ + 0x0102, 0x0002, /* 94 0x5e "^" */ + 0x8080, 0x0080, /* 95 0x5f "_" */ + 0x0100, 0x0002, /* 96 0x60 "`" */ + 0x5424, 0x0078, /* 97 0x61 "a" */ + 0x447f, 0x0038, /* 98 0x62 "b" */ + 0x4438, 0x0028, /* 99 0x63 "c" */ + 0x4438, 0x007f, /* 100 0x64 "d" */ + 0x5438, 0x0058, /* 101 0x65 "e" */ + 0x7e08, 0x0009, /* 102 0x66 "f" */ + 0x5448, 0x003c, /* 103 0x67 "g" */ + 0x047f, 0x0078, /* 104 0x68 "h" */ + 0x7d04, 0x0000, /* 105 0x69 "i" */ + 0x4020, 0x003d, /* 106 0x6a "j" */ + 0x107f, 0x006c, /* 107 0x6b "k" */ + 0x7f01, 0x0000, /* 108 0x6c "l" */ + 0x187c, 0x007c, /* 109 0x6d "m" */ + 0x047c, 0x0078, /* 110 0x6e "n" */ + 0x4438, 0x0038, /* 111 0x6f "o" */ + 0x147c, 0x0008, /* 112 0x70 "p" */ + 0x1408, 0x007c, /* 113 0x71 "q" */ + 0x047c, 0x0008, /* 114 0x72 "r" */ + 0x5448, 0x0024, /* 115 0x73 "s" */ + 0x3e04, 0x0044, /* 116 0x74 "t" */ + 0x403c, 0x007c, /* 117 0x75 "u" */ + 0x601c, 0x001c, /* 118 0x76 "v" */ + 0x307c, 0x007c, /* 119 0x77 "w" */ + 0x106c, 0x006c, /* 120 0x78 "x" */ + 0x504c, 0x003c, /* 121 0x79 "y" */ + 0x5464, 0x004c, /* 122 0x7a "z" */ + 0x3608, 0x0041, /* 123 0x7b "{" */ + 0x7700, 0x0000, /* 124 0x7c "|" */ + 0x3641, 0x0008, /* 125 0x7d "}" */ + 0x0102, 0x0102, /* 126 0x7e "~" */ + 0x0502, 0x0002, /* 127 0x7f */ +}; diff --git a/palette.c b/palette.c new file mode 100644 index 0000000..c95b665 --- /dev/null +++ b/palette.c @@ -0,0 +1,22 @@ +#include + +/* CGA-like palette */ + +uint16_t default_palette[] = { + 0x0000, + 0x000a, + 0x00a0, + 0x00aa, + 0x0a00, + 0x0a0a, + 0x0a50, + 0x0aaa, + 0x0555, + 0x055f, + 0x05f5, + 0x05ff, + 0x0f55, + 0x0f5f, + 0x0ff5, + 0x0fff, +};