Prepare uxn ppu initialization
This commit is contained in:
parent
9f81a64787
commit
bfd3c8ece9
7
Makefile
7
Makefile
|
@ -1,9 +1,10 @@
|
|||
BASE_UXN := src/uxn/src
|
||||
SRC_DIR ?= src
|
||||
BUILD_DIR ?= build
|
||||
SRC_MAIN ?= $(SRC_DIR)/main.c
|
||||
EXE_NAME ?= fbtest
|
||||
BIN := $(BUILD_DIR)/$(EXE_NAME)
|
||||
BASE_UXN := src/uxn/src/uxn.h
|
||||
UXN_HEAD := $(BASE_UXN)/uxn.h
|
||||
|
||||
CC ?= cc
|
||||
CFLAGS := -Wall -Wextra -pedantic
|
||||
|
@ -24,13 +25,13 @@ endif
|
|||
|
||||
main: $(BIN)
|
||||
|
||||
$(BIN): $(SRC_MAIN) $(BUILD_DIR) $(BASE_UXN)
|
||||
$(BIN): $(SRC_MAIN) $(BUILD_DIR) $(UXN_HEAD)
|
||||
$(CC) $(CFLAGS) -o $(BIN) $(SRC_MAIN)
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $(BUILD_DIR)
|
||||
|
||||
$(BASE_UXN):
|
||||
$(UXN_HEAD):
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
|
|
60
src/main.c
60
src/main.c
|
@ -1,45 +1,36 @@
|
|||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#include<stdint.h>
|
||||
#include<stdbool.h>
|
||||
#include<unistd.h>
|
||||
#include<fcntl.h>
|
||||
#include<linux/fb.h>
|
||||
#include<sys/ioctl.h>
|
||||
#include<sys/mman.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/fb.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "shorthand.h"
|
||||
#include "ppu.c"
|
||||
#include "uxn-fast.c"
|
||||
#include "rom.c"
|
||||
|
||||
// static Uxn u;
|
||||
// static Device *devscreen;
|
||||
// static Device *devctrl;
|
||||
// static Device *devmouse;
|
||||
// static Device *devaudio;
|
||||
|
||||
int
|
||||
main(void) {
|
||||
// Open frambuffer and get the size.
|
||||
int fb = open("/dev/fb0", O_RDWR);
|
||||
if (fb <= 0) {
|
||||
fprintf(stderr, "couldn't open the framebuffer\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
struct fb_var_screeninfo info;
|
||||
if (ioctl(fb, FBIOGET_VSCREENINFO, &info) != 0) {
|
||||
fprintf(stderr, "couldn't get the framebuffer size\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Mmap the framebuffer to a buffer object.
|
||||
size_t width = info.xres;
|
||||
size_t height = info.yres;
|
||||
size_t len = 4 * width * height;
|
||||
uint32_t *buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
|
||||
if (buf == MAP_FAILED) {
|
||||
fprintf(stderr, "couldn't mmap the framebuffer\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
ppu_init();
|
||||
|
||||
// Main loop.
|
||||
uint8_t shade = 0;
|
||||
size_t counter = 0;
|
||||
size_t direction = 1;
|
||||
while (true) {
|
||||
for (size_t j = 0; j < height; j++) {
|
||||
for (size_t i = 0; i < width; i++) {
|
||||
buf[j * width + i] = shade;
|
||||
for (size_t j = 0; j < screen_height; j++) {
|
||||
for (size_t i = 0; i < screen_width; i++) {
|
||||
framebuffer[j * screen_width + i] = shade;
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
|
@ -54,8 +45,5 @@ main(void) {
|
|||
}
|
||||
}
|
||||
|
||||
// Cleanup.
|
||||
munmap(buf, len);
|
||||
close(fb);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "ppu.h"
|
||||
|
||||
/*
|
||||
Copyright (c) 2021 Devine Lu Linvega
|
||||
Copyright (c) 2021 Andrew Alderwick
|
||||
Copyright (c) 2021 Bad Diode
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
static size_t screen_width = 0;
|
||||
static size_t screen_height = 0;
|
||||
|
||||
static u32 *framebuffer = 0;
|
||||
|
||||
static u32 palette[16];
|
||||
static u8 *pixels_buf;
|
||||
static u8 *dirty_lines;
|
||||
static u8 reqdraw = 0;
|
||||
// TODO: Probably should consider this
|
||||
// static u32 rgb_order;
|
||||
|
||||
static u8 blending[5][16] = {
|
||||
{0, 0, 0, 0, 1, 0, 1, 1, 2, 2, 0, 2, 3, 3, 3, 0},
|
||||
{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3},
|
||||
{1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1},
|
||||
{2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2},
|
||||
{1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0}};
|
||||
|
||||
void
|
||||
ppu_pixel(u8 layer, u16 x, u16 y, u8 color) {
|
||||
size_t idx = y * screen_width + x;
|
||||
u8 *pixel = &pixels_buf[idx], shift = layer * 2;
|
||||
if(x < screen_width && y < screen_height) {
|
||||
*pixel = (*pixel & ~(0x3 << shift)) | (color << shift);
|
||||
}
|
||||
dirty_lines[y] |= 1;
|
||||
}
|
||||
|
||||
void
|
||||
ppu_1bpp(u8 layer, u16 x, u16 y, u8 *sprite, u8 color, u8 flipx, u8 flipy) {
|
||||
u16 v, h;
|
||||
for(v = 0; v < 8; v++)
|
||||
for(h = 0; h < 8; h++) {
|
||||
u8 ch1 = (sprite[v] >> (7 - h)) & 0x1;
|
||||
if(ch1 || blending[4][color])
|
||||
ppu_pixel(layer,
|
||||
x + (flipx ? 7 - h : h),
|
||||
y + (flipy ? 7 - v : v),
|
||||
blending[ch1][color]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ppu_2bpp(u8 layer, u16 x, u16 y, u8 *sprite, u8 color, u8 flipx, u8 flipy) {
|
||||
u16 v, h;
|
||||
for(v = 0; v < 8; v++)
|
||||
for(h = 0; h < 8; h++) {
|
||||
u8 ch1 = ((sprite[v] >> (7 - h)) & 0x1);
|
||||
u8 ch2 = ((sprite[v + 8] >> (7 - h)) & 0x1);
|
||||
u8 ch = ch1 + ch2 * 2;
|
||||
if(ch || blending[4][color])
|
||||
ppu_pixel(layer,
|
||||
x + (flipx ? 7 - h : h),
|
||||
y + (flipy ? 7 - v : v),
|
||||
blending[ch][color]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
redraw_screen(void) {
|
||||
for (size_t j = 0; j < screen_height; j++) {
|
||||
dirty_lines[j] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ppu_init(void) {
|
||||
// Open frambuffer and get the size.
|
||||
int fb = open("/dev/fb0", O_RDWR);
|
||||
if (fb <= 0) {
|
||||
fprintf(stderr, "couldn't open the framebuffer\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
struct fb_var_screeninfo info;
|
||||
if (ioctl(fb, FBIOGET_VSCREENINFO, &info) != 0) {
|
||||
fprintf(stderr, "couldn't get the framebuffer size\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Mmap the framebuffer to a buffer object.
|
||||
screen_width = info.xres;
|
||||
screen_height = info.yres;
|
||||
size_t len = 4 * screen_width * screen_height;
|
||||
framebuffer = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
|
||||
if (framebuffer == MAP_FAILED) {
|
||||
fprintf(stderr, "couldn't mmap the framebuffer\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Allocate intermediate buffers.
|
||||
pixels_buf = malloc(screen_width * screen_height);
|
||||
dirty_lines = malloc(screen_height);
|
||||
|
||||
// Initialize default palette.
|
||||
palette[0] = 0x444444;
|
||||
palette[1] = 0xffffff;
|
||||
palette[2] = 0x7777ff;
|
||||
palette[3] = 0xff7777;
|
||||
|
||||
// Clear pixel buffer memory.
|
||||
memset(pixels_buf, 0, screen_width * screen_height);
|
||||
memset(dirty_lines, 1, screen_height);
|
||||
|
||||
// Make sure we perform an initial screen drawing.
|
||||
reqdraw = 1;
|
||||
redraw_screen();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
blit_framebuffer(void) {
|
||||
if (reqdraw == 0) {
|
||||
return;
|
||||
}
|
||||
for (size_t j = 0; j < screen_height; j++) {
|
||||
if (dirty_lines[j] != 0) {
|
||||
for (size_t i = 0; i < screen_width; i++) {
|
||||
size_t idx = i + j * screen_width;
|
||||
framebuffer[idx] = palette[pixels_buf[idx] % 16];
|
||||
}
|
||||
}
|
||||
dirty_lines[j] = 0;
|
||||
}
|
||||
reqdraw = 0;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
Copyright (c) 2021 Devine Lu Linvega
|
||||
Copyright (c) 2021 Andrew Alderwick
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
typedef unsigned char Uint8;
|
||||
typedef unsigned short Uint16;
|
||||
typedef unsigned int Uint32;
|
||||
|
||||
int ppu_init(void);
|
||||
void ppu_pixel(Uint8 layer, Uint16 x, Uint16 y, Uint8 color);
|
||||
void ppu_1bpp(Uint8 layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy);
|
||||
void ppu_2bpp(Uint8 layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy);
|
|
@ -0,0 +1,52 @@
|
|||
const u16 uxn_rom[] = {
|
||||
0x0120, 0x8043, 0x3720, 0xf020, 0x807f, 0x3708, 0xf020, 0x80e0,
|
||||
0x370a, 0xf020, 0x80c0, 0x370c, 0x2280, 0x8036, 0x3f01, 0x0020,
|
||||
0x3920, 0x0280, 0x8031, 0x3624, 0x0180, 0x803f, 0x3104, 0x0120,
|
||||
0x2ed4, 0x0220, 0x2e2f, 0x0220, 0x2e71, 0x0220, 0x2eae, 0x0320,
|
||||
0x2e3a, 0x8000, 0x3000, 0x2321, 0x0080, 0x8031, 0x3002, 0x0020,
|
||||
0x3848, 0x2880, 0x8037, 0x3004, 0x0020, 0x3950, 0x2a80, 0x8037,
|
||||
0x0f01, 0x0305, 0x0480, 0x801f, 0x0500, 0x3080, 0x203f, 0x9103,
|
||||
0x8038, 0x372c, 0x80cf, 0x172f, 0x0f80, 0x801c, 0x0500, 0x3080,
|
||||
0x203f, 0x9103, 0x8038, 0x372c, 0x2880, 0x2036, 0x0800, 0x8038,
|
||||
0x3728, 0x80cf, 0x172f, 0x8003, 0x1f04, 0x0080, 0x8005, 0x3f30,
|
||||
0x0320, 0x3891, 0x2c80, 0x8037, 0x3628, 0x0020, 0x3808, 0x2880,
|
||||
0xcf37, 0x2f80, 0x8017, 0x1c0f, 0x0080, 0x8005, 0x3f30, 0x0320,
|
||||
0x3891, 0x2c80, 0x8037, 0x3628, 0x0020, 0x3808, 0x2880, 0x4f37,
|
||||
0x2f80, 0x0017, 0x1080, 0x0080, 0x8003, 0x1f30, 0x0080, 0x2005,
|
||||
0x9103, 0x8038, 0x372c, 0x8003, 0x1f30, 0x0080, 0x8005, 0x3002,
|
||||
0x0020, 0x3940, 0x8038, 0x3728, 0x0480, 0x2030, 0x5000, 0x8039,
|
||||
0x372a, 0x0180, 0x2f80, 0x0317, 0x3080, 0x801f, 0x0500, 0x0480,
|
||||
0x2030, 0x4000, 0x3839, 0x2a80, 0x8037, 0x3002, 0x0020, 0x3950,
|
||||
0x2880, 0x8037, 0x8001, 0x172f, 0x8a01, 0xab80, 0x220d, 0x206c,
|
||||
0x8103, 0x2c80, 0x8037, 0x8000, 0x0300, 0x0f80, 0x801c, 0x1f40,
|
||||
0x0180, 0x801f, 0x0500, 0x0280, 0x2030, 0x4000, 0x3839, 0x2880,
|
||||
0x0337, 0xf080, 0x801c, 0x1f01, 0x0080, 0x8005, 0x3004, 0x0020,
|
||||
0x3940, 0x8038, 0x372a, 0x8003, 0x172f, 0x8901, 0xca80, 0x220d,
|
||||
0x806c, 0x8010, 0x8f00, 0x8003, 0x1f02, 0x0080, 0x8005, 0x3f40,
|
||||
0x0480, 0x2030, 0x4000, 0x3839, 0x032f, 0x0380, 0x801c, 0x0500,
|
||||
0x4080, 0x203f, 0x4000, 0x8038, 0x3002, 0x0020, 0x3808, 0x6f38,
|
||||
0x804f, 0x2000, 0xe702, 0x012e, 0x808a, 0x0dc9, 0x6c22, 0x1080,
|
||||
0x0080, 0x038f, 0x0280, 0x801f, 0x0500, 0x4080, 0x803f, 0x3004,
|
||||
0x2f38, 0x8003, 0x1c03, 0x0080, 0x8005, 0x3f40, 0x0020, 0x3840,
|
||||
0x0280, 0x2030, 0x0800, 0x3838, 0x4f6f, 0x8080, 0x0220, 0x2ee7,
|
||||
0x8a01, 0xcd80, 0x220d, 0x186c, 0x200f, 0x8103, 0x2c80, 0x8037,
|
||||
0x372a, 0x2880, 0x8037, 0xcf00, 0x8018, 0x172f, 0x2880, 0x2036,
|
||||
0x0800, 0x8038, 0x3728, 0x1080, 0x18cf, 0x2f80, 0x8017, 0x3628,
|
||||
0x0020, 0x3908, 0x2880, 0x8037, 0x362a, 0x0020, 0x3808, 0x2a80,
|
||||
0x8037, 0xcf20, 0x8018, 0x172f, 0x2880, 0x2036, 0x0800, 0x8038,
|
||||
0x3728, 0x3080, 0x184f, 0x2f80, 0x6c17, 0x0480, 0x2030, 0x4000,
|
||||
0x8039, 0x372a, 0x0280, 0x2030, 0x4800, 0x8038, 0x3728, 0x0080,
|
||||
0x2e80, 0x8017, 0x3002, 0x0020, 0x3849, 0x2880, 0x8037, 0x8001,
|
||||
0x172e, 0x0280, 0x2030, 0x4a00, 0x8038, 0x3728, 0x0280, 0x2e80,
|
||||
0x8017, 0x3002, 0x0020, 0x384b, 0x2880, 0x8037, 0x8003, 0x172e,
|
||||
0x0f6c, 0x6738, 0xdf5f, 0xbfbf, 0x00bf, 0x1807, 0x2320, 0x4844,
|
||||
0x0048, 0x827c, 0x8282, 0x8282, 0x007c, 0x1030, 0x1010, 0x1010,
|
||||
0x0010, 0x827c, 0x7c02, 0x8080, 0x00fe, 0x827c, 0x1c02, 0x8202,
|
||||
0x007c, 0x140c, 0x4424, 0xfe84, 0x0004, 0x80fe, 0x7c80, 0x8202,
|
||||
0x007c, 0x827c, 0xfc80, 0x8282, 0x007c, 0x827c, 0x1e02, 0x0202,
|
||||
0x0002, 0x827c, 0x7c82, 0x8282, 0x007c, 0x827c, 0x7e82, 0x8202,
|
||||
0x007c, 0x827c, 0x7e02, 0x8282, 0x007e, 0x82fc, 0xfc82, 0x8282,
|
||||
0x00fc, 0x827c, 0x8080, 0x8280, 0x007c, 0x82fc, 0x8282, 0x8282,
|
||||
0x00fc, 0x827c, 0xf080, 0x8280, 0x007c, 0x827c, 0xf080, 0x8080,
|
||||
0x8080,
|
||||
};
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
Copyright (c) 2021 Bad Diode
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UTILS_SHORTHAND_H
|
||||
#define UTILS_SHORTHAND_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
//
|
||||
// This simple header just typedefs the basic C define types to a shorter name,
|
||||
// loads the quality of life bool macro for _Bool and defines shorthand macros
|
||||
// for byte sizes.
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
typedef int8_t s8;
|
||||
typedef int16_t s16;
|
||||
typedef int32_t s32;
|
||||
typedef int64_t s64;
|
||||
typedef volatile u8 vu8;
|
||||
typedef volatile u16 vu16;
|
||||
typedef volatile u32 vu32;
|
||||
typedef volatile u64 vu64;
|
||||
typedef volatile s8 vs8;
|
||||
typedef volatile s16 vs16;
|
||||
typedef volatile s32 vs32;
|
||||
typedef volatile s64 vs64;
|
||||
|
||||
#define KB(N) ((u64)(N) * 1024)
|
||||
#define MB(N) ((u64)KB(N) * 1024)
|
||||
#define GB(N) ((u64)MB(N) * 1024)
|
||||
#define TB(N) ((u64)GB(N) * 1024)
|
||||
|
||||
#endif // UTILS_SHORTHAND_H
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
Copyright (c) 2021 Devine Lu Linvega
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
typedef unsigned char Uint8;
|
||||
typedef signed char Sint8;
|
||||
typedef unsigned short Uint16;
|
||||
typedef signed short Sint16;
|
||||
|
||||
#define PAGE_PROGRAM 0x0100
|
||||
|
||||
typedef struct {
|
||||
Uint8 ptr, kptr, error;
|
||||
Uint8 dat[256];
|
||||
} Stack;
|
||||
|
||||
typedef struct {
|
||||
Uint16 ptr;
|
||||
Uint8 dat[65536];
|
||||
} Memory;
|
||||
|
||||
typedef struct Device {
|
||||
struct Uxn *u;
|
||||
Uint8 addr, dat[16], *mem;
|
||||
void (*talk)(struct Device *d, Uint8, Uint8);
|
||||
} Device;
|
||||
|
||||
typedef struct Uxn {
|
||||
Stack wst, rst, *src, *dst;
|
||||
Memory ram;
|
||||
Device dev[16];
|
||||
} Uxn;
|
||||
|
||||
struct Uxn;
|
||||
|
||||
void mempoke16(Uint8 *m, Uint16 a, Uint16 b);
|
||||
Uint16 mempeek16(Uint8 *m, Uint16 a);
|
||||
|
||||
int uxn_boot(Uxn *c);
|
||||
int uxn_eval(Uxn *u, Uint16 vec);
|
||||
int uxn_halt(Uxn *u, Uint8 error, char *name, int id);
|
||||
Device *uxn_port(Uxn *u, Uint8 id, char *name, void (*talkfn)(Device *, Uint8, Uint8));
|
Loading…
Reference in New Issue