Add missing files

This commit is contained in:
Maurizio Porrato 2020-04-23 08:44:13 +01:00
parent 2148ba60aa
commit 4127d9bde8
11 changed files with 736 additions and 0 deletions

2
.gitignore vendored
View File

@ -4,3 +4,5 @@
*.o
*.orig
dsim
*.asm
*.bin

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

BIN
data/font.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

40
data/png2c.py Executable file
View File

@ -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 <stdint.h>
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)

62
dev_clock.c Normal file
View File

@ -0,0 +1,62 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <sys/time.h>
#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 */

62
dev_debug.c Normal file
View File

@ -0,0 +1,62 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#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<count; i++) {
a = (addr + i) % sizeof(ram);
if ((i % 8) == 0)
printf("\n%04x: ", a);
printf("%04x ", ram[a]);
}
printf("\n");
}
void debug_tick()
{
if (trace)
dumpregs();
}
void debug_irqh()
{
switch (ra) {
case 0x0000:
running = false;
break;
case 0x0001:
dumpregs();
break;
case 0x0002:
dump_ram(ry, rx);
break;
case 0x0004:
trace = false;
break;
case 0x0005:
trace = true;
break;
case 0xffff:
rx = EMU_ID;
ry = EMU_VER;
break;
}
}
struct dev_entry debug_dev = { 0x6d53647c, 0x62e037d3, 0x0000, debug_irqh, NULL, NULL, debug_tick }; /* Debug device */

361
dev_lem1802.c Normal file
View File

@ -0,0 +1,361 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <sys/time.h>
#include "device.h"
#include <SDL.h>
#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<<BPP)
#define SCREEN_W (TEXT_COLS*CHAR_W)
#define SCREEN_H (TEXT_ROWS*CHAR_H)
#define SURFACE_W (BORDER_L+SCREEN_W+BORDER_R)
#define SURFACE_H (BORDER_T+SCREEN_H+BORDER_B)
#define WINDOW_W (SURFACE_W*ZOOM)
#define WINDOW_H (SURFACE_H*ZOOM)
uint16_t screen_iptr;
uint16_t font_iptr;
uint16_t palette_iptr;
uint16_t border;
#define PALETTE(x) (palette_iptr ? ram[(palette_iptr+(x))&0xffff] : default_palette[x])
#define FONT(x) (font_iptr ? ram[(font_iptr+(x))&0xffff] : default_font[x])
#define SCREEN(x) (ram[(screen_iptr+(x))&0xffff])
#include "font.c"
#include "palette.c"
SDL_Window *window = NULL;
SDL_Surface *screenSurface = NULL;
SDL_Surface *glyph_shapes = NULL;
SDL_Surface *glyph_tiles = NULL;
SDL_Palette *palette = NULL;
struct timeval poweron_time;
uint8_t kbuf[KBUF_SIZE];
uint8_t khead, klen;
uint16_t kint;
void update_glyph_tiles()
{
SDL_SetSurfacePalette(glyph_shapes, palette);
SDL_BlitSurface(glyph_shapes, NULL, glyph_tiles, NULL);
}
void update_font()
{
int x, y, i, j;
uint8_t fg, bg;
bool pixel;
uint8_t *raster;
printf("update_font()\n");
if (glyph_shapes == NULL) {
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_LockSurface(glyph_shapes);
raster = (uint8_t *)(glyph_shapes->pixels);
for (i=0; i<sizeof(default_font)/sizeof(default_font[0]); i++) {
for (j=0; j<16; j++) {
x = i*2+j/8;
y = j%8;
pixel = ((FONT(i)>>j) & 1) != 0;
// raster[x+y*glyph_shapes->w] = (pixel ? 1 : 0);
for (fg=0; fg<COLORS; fg++)
for (bg=0; bg<COLORS; bg++)
raster[x+(y+(fg<<4|bg)*CHAR_H)*glyph_shapes->w] = (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; i<COLORS; i++) {
palette->colors[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<TEXT_ROWS*TEXT_COLS; i++) {
cell = ram[(screen_iptr+i) & 0xffff];
ch = cell & 0x7f;
bl = (cell & 0x80) != 0;
bg = (cell >> 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<sizeof(default_font)/sizeof(default_font[0]); i++)
ram[(rb+i)&0xffff] = default_font[i];
break;
case 5: /* MEM_DUMP_PALETTE */
for (i=0; i<sizeof(default_palette)/sizeof(default_palette[0]); i++)
ram[(rb+i)&0xffff] = default_palette[i];
break;
default:
break;
}
}
void keyboard_irqh()
{
switch (ra) {
case 0: /* Clear buffer */
khead = klen = 0;
break;
case 1: /* Get next key */
if (klen > 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 */

28
device.c Normal file
View File

@ -0,0 +1,28 @@
#include <stdlib.h>
#include <stdint.h>
#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
};

27
device.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef __DEVICE_H__
#include <stdint.h>
#include <stdbool.h>
#include <sys/time.h>
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

132
font.c Normal file
View File

@ -0,0 +1,132 @@
#include <stdint.h>
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 */
};

22
palette.c Normal file
View File

@ -0,0 +1,22 @@
#include <stdint.h>
/* CGA-like palette */
uint16_t default_palette[] = {
0x0000,
0x000a,
0x00a0,
0x00aa,
0x0a00,
0x0a0a,
0x0a50,
0x0aaa,
0x0555,
0x055f,
0x05f5,
0x05ff,
0x0f55,
0x0f5f,
0x0ff5,
0x0fff,
};