organize source files by components
This commit is contained in:
parent
e577dd7810
commit
5031e6760e
|
@ -1,5 +1,5 @@
|
|||
#ifndef _VFPGA_COMPONENT_H
|
||||
#define _VFPGA_COMPONENT_H
|
||||
#ifndef __COMPONENT_H__
|
||||
#define __COMPONENT_H__
|
||||
|
||||
#include <SDL.h>
|
||||
#include <vector>
|
||||
|
@ -25,7 +25,7 @@ private:
|
|||
|
||||
public:
|
||||
Component(SDL_Renderer *rend, int cnt, int init_val, int ct);
|
||||
|
||||
|
||||
bool in_rect(int x, int y) const;
|
||||
SDL_Renderer *get_renderer() const;
|
||||
int get_component_type() const;
|
||||
|
@ -66,10 +66,17 @@ public:
|
|||
void init_components(SDL_Renderer *renderer);
|
||||
void init_gui(SDL_Renderer *renderer);
|
||||
|
||||
void add_component(Component *c);
|
||||
void update_components(SDL_Renderer *renderer);
|
||||
void delete_components();
|
||||
|
||||
#define GET_SEGA(i) (SEG0A + 8 * i)
|
||||
#define GET_DECP(i) (SEG0A + 8 * i + 7)
|
||||
static inline SDL_Rect operator+(const SDL_Rect &A, const SDL_Rect &B) {
|
||||
SDL_Rect ret;
|
||||
ret.x = A.x + B.x;
|
||||
ret.y = A.y + B.y;
|
||||
ret.w = A.w + B.w;
|
||||
ret.h = A.h + B.h;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef _VFPGA_CONFIGS_H
|
||||
#define _VFPGA_CONFIGS_H
|
||||
#ifndef __CONFIGS_H__
|
||||
#define __CONFIGS_H__
|
||||
|
||||
// I. Mapping
|
||||
// 1. Mapping
|
||||
// You can replace pictures used in GUI
|
||||
|
||||
// 640*480 png
|
||||
|
@ -20,14 +20,20 @@
|
|||
#define SEG_BKGND_CUSTOM
|
||||
#define VSEGLED_BG_PATH "vsegled_bg.png"
|
||||
|
||||
// II. Hardware options
|
||||
// 2. Hardware options
|
||||
|
||||
#define VGA_ENA
|
||||
|
||||
// III. Experimental Function
|
||||
// 3. Experimental Function
|
||||
|
||||
//#define HARDWARE_ACC
|
||||
|
||||
//#define VSYNC
|
||||
|
||||
// 4. Windows options
|
||||
|
||||
#define WINDOW_WIDTH (640 * 2)
|
||||
#define WINDOW_HEIGHT (480 * 2)
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
#ifndef _VFPGA_KEYBOARD_H
|
||||
#define _VFPGA_KEYBOARD_H
|
||||
#ifndef __KEYBOARD_H__
|
||||
#define __KEYBOARD_H__
|
||||
|
||||
#include <queue>
|
||||
#include <assert.h>
|
||||
#include <component.h>
|
||||
#include <map>
|
||||
#include <at_scancode.h>
|
||||
|
||||
#define NOT_A_KEY -1
|
||||
#define CLK_NUM 10
|
||||
|
|
|
@ -2,10 +2,18 @@
|
|||
#define __NVBOARD_H__
|
||||
|
||||
#include <pins.h>
|
||||
#include <string>
|
||||
#include <component.h>
|
||||
#include <configs.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL_image.h>
|
||||
|
||||
void nvboard_init(int vga_clk_cycle = 1);
|
||||
void nvboard_quit();
|
||||
void nvboard_bind_pin(void *signal, int len, ...);
|
||||
void nvboard_update();
|
||||
extern std::string nvboard_home;
|
||||
void set_redraw();
|
||||
|
||||
static inline void fill_rect_texture(SDL_Renderer *renderer, SDL_Surface **surface, SDL_Texture **texture, int r, int g, int b) {
|
||||
SDL_FillRect(*surface, NULL, SDL_MapRGB((*surface)->format, r, g, b));
|
||||
*texture = SDL_CreateTextureFromSurface(renderer, *surface);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,61 +1,10 @@
|
|||
#ifndef _VFPGA_CONSTRS_H
|
||||
#define _VFPGA_CONSTRS_H
|
||||
#ifndef __PINS_H__
|
||||
#define __PINS_H__
|
||||
|
||||
#include <../usr/include/pins.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
// RST is defined but not used. NVBoard contains some internal states in *.cpp
|
||||
// file. Only resetting the RTL design in *.v file may make the RTL design and
|
||||
// NVBoard inconsistent. The easy way to reset the whole system is to exit
|
||||
// NVBoard and re-run. The reset work for RTL design is done by the verilator
|
||||
// wrapper. See `example/csrc/main.cpp` for more details.
|
||||
#define BTN_INPUT BTNC, BTNU, BTND, BTNL, BTNR, RST
|
||||
|
||||
#define SW_INPUT SW0, SW1, SW2, SW3, \
|
||||
SW4, SW5, SW6, SW7, \
|
||||
SW8, SW9, SW10, SW11, \
|
||||
SW12, SW13, SW14, SW15
|
||||
|
||||
#define NAIVE_LEDS_OUTPUT LD0, LD1, LD2, LD3, \
|
||||
LD4, LD5, LD6, LD7, \
|
||||
LD8, LD9, LD10, LD11, \
|
||||
LD12, LD13, LD14, LD15
|
||||
|
||||
#define RGB_LEDS_OUTPUT R16, G16, B16, R17, G17, B17
|
||||
|
||||
|
||||
#define SEG7_SEGS_OUTPUT SEG0A, SEG0B, SEG0C, SEG0D, SEG0E, SEG0F, SEG0G, DEC0P, \
|
||||
SEG1A, SEG1B, SEG1C, SEG1D, SEG1E, SEG1F, SEG1G, DEC1P, \
|
||||
SEG2A, SEG2B, SEG2C, SEG2D, SEG2E, SEG2F, SEG2G, DEC2P, \
|
||||
SEG3A, SEG3B, SEG3C, SEG3D, SEG3E, SEG3F, SEG3G, DEC3P, \
|
||||
SEG4A, SEG4B, SEG4C, SEG4D, SEG4E, SEG4F, SEG4G, DEC4P, \
|
||||
SEG5A, SEG5B, SEG5C, SEG5D, SEG5E, SEG5F, SEG5G, DEC5P, \
|
||||
SEG6A, SEG6B, SEG6C, SEG6D, SEG6E, SEG6F, SEG6G, DEC6P, \
|
||||
SEG7A, SEG7B, SEG7C, SEG7D, SEG7E, SEG7F, SEG7G, DEC7P
|
||||
|
||||
//#define UART_OUTPUT
|
||||
|
||||
#define VGA_OUTPUT VGA_VSYNC, VGA_HSYNC, VGA_BLANK_N, \
|
||||
VGA_R0, VGA_R1, VGA_R2, VGA_R3, VGA_R4, VGA_R5, VGA_R6, VGA_R7, \
|
||||
VGA_G0, VGA_G1, VGA_G2, VGA_G3, VGA_G4, VGA_G5, VGA_G6, VGA_G7, \
|
||||
VGA_B0, VGA_B1, VGA_B2, VGA_B3, VGA_B4, VGA_B5, VGA_B6, VGA_B7
|
||||
|
||||
#define KEYBOARD_INPUT PS2_CLK, PS2_DAT
|
||||
|
||||
enum {
|
||||
BTN_INPUT,
|
||||
SW_INPUT,
|
||||
KEYBOARD_INPUT,
|
||||
NR_INPUT_PINS,
|
||||
NAIVE_LEDS_OUTPUT,
|
||||
RGB_LEDS_OUTPUT,
|
||||
SEG7_ENBS_OUTPUT,
|
||||
SEG7_SEGS_OUTPUT,
|
||||
VGA_OUTPUT,
|
||||
NR_PINS,
|
||||
NR_OUTPUT_PINS = NR_PINS - NR_INPUT_PINS
|
||||
};
|
||||
|
||||
typedef struct PinNode {
|
||||
void *ptr;
|
||||
uint8_t data;
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
#ifndef VFPGA_RENDER_H
|
||||
#define VFPGA_RENDER_H
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#define WINDOW_WIDTH (640 * 2)
|
||||
#define WINDOW_HEIGHT (480 * 2)
|
||||
|
||||
#define SWITCH_X 60
|
||||
#define SWITCH_Y 400
|
||||
#define SWITCH_SEP 10
|
||||
#define SWITCH_WIDTH 20
|
||||
#define SWITCH_HEIGHT 40
|
||||
|
||||
#define BTNC_X 520
|
||||
#define BTNC_Y 250
|
||||
#define BTNC_SEP 20
|
||||
#define BTNC_WIDTH 30
|
||||
#define BTNC_HEIGHT 30
|
||||
|
||||
#define LED_X 60 + (4/2)
|
||||
#define LED_Y 360
|
||||
#define LED_SEP 14
|
||||
#define LED_WIDTH 16
|
||||
#define LED_HEIGHT 8
|
||||
|
||||
#define SEG_X 60
|
||||
#define SEG_Y 225
|
||||
|
||||
#define SEG_VER_WIDTH 3
|
||||
#define SEG_VER_HEIGHT 30
|
||||
#define SEG_HOR_WIDTH 30
|
||||
#define SEG_HOR_HEIGHT 3
|
||||
#define SEG_DOT_WIDTH 4
|
||||
#define SEG_DOT_HEIGHT 4
|
||||
|
||||
#define SEG_SEP 3
|
||||
|
||||
#define SEG_TOT_WIDTH (SEG_SEP * 18 + SEG_VER_WIDTH * 16 + SEG_DOT_WIDTH * 8 + SEG_HOR_WIDTH * 8)
|
||||
#define SEG_TOT_HEIGHT (SEG_SEP * 4 + SEG_VER_HEIGHT * 2 + SEG_HOR_HEIGHT * 3)
|
||||
|
||||
void load_background(SDL_Renderer *renderer);
|
||||
void load_texture(SDL_Renderer *renderer);
|
||||
void set_redraw();
|
||||
|
||||
#endif
|
|
@ -1,8 +1,7 @@
|
|||
#ifndef _VFPGA_VGA_H
|
||||
#define _VFPGA_VGA_H
|
||||
#ifndef __VGA_H__
|
||||
#define __VGA_H__
|
||||
|
||||
#include <component.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#define VGA_DEFAULT_WIDTH 640
|
||||
#define VGA_DEFAULT_HEIGHT 480
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
NVBOARD_SRC = $(NVBOARD_HOME)/src
|
||||
NVBOARD_SRCS := $(shell find $(NVBOARD_SRC) -name "*.cpp")
|
||||
NVBOARD_INC = $(NVBOARD_HOME)/include
|
||||
INC_PATH += $(NVBOARD_INC)
|
||||
NVBOARD_USR_INC = $(NVBOARD_HOME)/usr/include
|
||||
INC_PATH += $(NVBOARD_USR_INC)
|
||||
|
||||
NVBOARD_BUILD_DIR = $(NVBOARD_HOME)/build
|
||||
NVBOARD_OBJS := $(addprefix $(NVBOARD_BUILD_DIR)/, $(addsuffix .o, $(basename $(notdir $(NVBOARD_SRCS)))))
|
||||
|
@ -14,7 +15,7 @@ CXXFLAGS += -MMD -O3 $(shell sdl2-config --cflags)
|
|||
$(NVBOARD_BUILD_DIR)/%.o: $(NVBOARD_SRC)/%.cpp
|
||||
@echo + CXX "->" NVBOARD_HOME/$(shell realpath $< --relative-to $(NVBOARD_HOME))
|
||||
@mkdir -p $(dir $@)
|
||||
@$(CXX) $(CXXFLAGS) -I$(NVBOARD_INC) -c -o $@ $<
|
||||
@$(CXX) -I$(NVBOARD_INC) $(CXXFLAGS) -c -o $@ $<
|
||||
|
||||
# Build the archive of NVBoard
|
||||
$(NVBOARD_ARCHIVE): $(NVBOARD_OBJS)
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
#include <nvboard.h>
|
||||
|
||||
#define BTNC_X 520
|
||||
#define BTNC_Y 250
|
||||
#define BTNC_SEP 20
|
||||
#define BTNC_WIDTH 30
|
||||
#define BTNC_HEIGHT 30
|
||||
|
||||
static SDL_Texture *tbutton_on, *tbutton_off;
|
||||
static SDL_Surface *sbutton_on, *sbutton_off;
|
||||
|
||||
static SDL_Rect btn_rects[6] = {
|
||||
{BTNC_X, BTNC_Y, BTNC_WIDTH, BTNC_HEIGHT },
|
||||
{BTNC_X, BTNC_Y - BTNC_HEIGHT - BTNC_SEP, BTNC_WIDTH, BTNC_HEIGHT },
|
||||
{BTNC_X, BTNC_Y + BTNC_HEIGHT + BTNC_SEP, BTNC_WIDTH, BTNC_HEIGHT },
|
||||
{BTNC_X - BTNC_WIDTH - BTNC_SEP, BTNC_Y, BTNC_WIDTH, BTNC_HEIGHT },
|
||||
{BTNC_X + BTNC_WIDTH + BTNC_SEP, BTNC_Y, BTNC_WIDTH, BTNC_HEIGHT },
|
||||
{BTNC_X + BTNC_WIDTH + BTNC_SEP/2, BTNC_Y - 2 * (BTNC_HEIGHT + BTNC_SEP), BTNC_WIDTH, BTNC_HEIGHT } // RST, but not draw
|
||||
};
|
||||
|
||||
static void load_texture(SDL_Renderer *renderer) {
|
||||
sbutton_on = IMG_Load((nvboard_home + "/pic/" + VBTN_ON_PATH).c_str());
|
||||
assert(sbutton_on != nullptr);
|
||||
tbutton_on = SDL_CreateTextureFromSurface(renderer, sbutton_on);
|
||||
sbutton_off = IMG_Load((nvboard_home + "/pic/" + VBTN_OFF_PATH).c_str());
|
||||
assert(sbutton_off != nullptr);
|
||||
tbutton_off = SDL_CreateTextureFromSurface(renderer, sbutton_off);
|
||||
}
|
||||
|
||||
void init_button(SDL_Renderer *renderer) {
|
||||
load_texture(renderer);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
Component *ptr = new Component(renderer, 2, 0, BUTTON_TYPE);
|
||||
|
||||
// off
|
||||
SDL_Rect *rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = btn_rects[i];
|
||||
ptr->set_rect(rect_ptr, 0);
|
||||
ptr->set_texture(tbutton_off, 0);
|
||||
|
||||
// on
|
||||
rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = btn_rects[i];
|
||||
ptr->set_rect(rect_ptr, 1);
|
||||
ptr->set_texture(tbutton_on, 1);
|
||||
|
||||
ptr->add_pin(BTNC + i);
|
||||
add_component(ptr);
|
||||
}
|
||||
}
|
|
@ -1,14 +1,5 @@
|
|||
#include <configs.h>
|
||||
#include <vga.h>
|
||||
#include <keyboard.h>
|
||||
#include <render.h>
|
||||
#include <pins.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <SDL.h>
|
||||
|
||||
std::vector<Component *> components;
|
||||
#include <nvboard.h>
|
||||
#include <macro.h>
|
||||
|
||||
Component::Component(SDL_Renderer *rend, int cnt, int init_val, int ct) {
|
||||
m_renderer = rend;
|
||||
|
@ -104,171 +95,24 @@ void RGB_LED::update_state() {
|
|||
}
|
||||
#endif
|
||||
|
||||
SEGS7::SEGS7(SDL_Renderer *rend, int cnt, int init_val, int ct, bool is_len8)
|
||||
: Component(rend, cnt, init_val, ct), is_len8(is_len8) {}
|
||||
|
||||
void SEGS7::update_gui() {
|
||||
int newval = get_state();
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
int texture_idx = (7 - i) * 2 + (((newval >> i) & 1) ? 0 : 1);
|
||||
SDL_RenderCopy(get_renderer(), get_texture(texture_idx), NULL, get_rect(texture_idx));
|
||||
}
|
||||
set_redraw();
|
||||
}
|
||||
|
||||
void SEGS7::update_state() {
|
||||
int newval = 0;
|
||||
if (is_len8) {
|
||||
newval = pin_peek8(get_pin());
|
||||
} else {
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
newval |= (pin_peek(get_pin(7 - i)) << i);
|
||||
}
|
||||
}
|
||||
if (newval != get_state()) {
|
||||
set_state(newval);
|
||||
update_gui();
|
||||
}
|
||||
}
|
||||
|
||||
extern SDL_Texture *tbutton_on, *tbutton_off;
|
||||
extern SDL_Texture *tswitch_on, *tswitch_off;
|
||||
extern SDL_Texture *tsegled_ver_off, *tsegled_ver_on,
|
||||
*tsegled_hor_off, *tsegled_hor_on,
|
||||
*tsegled_dot_off, *tsegled_dot_on;
|
||||
extern SDL_Texture *tled_off, *tled_r, *tled_g, *tled_b,
|
||||
*tled_rg, *tled_rb, *tled_gb, *tled_rgb;
|
||||
extern SDL_Texture *tfpga_background, *tseg7_background;
|
||||
|
||||
extern SDL_Rect segs_rect[8], btn_rects[6];
|
||||
|
||||
SDL_Rect operator+(const SDL_Rect &A, const SDL_Rect &B) {
|
||||
SDL_Rect ret;
|
||||
ret.x = A.x + B.x;
|
||||
ret.y = A.y + B.y;
|
||||
ret.w = A.w + B.w;
|
||||
ret.h = A.h + B.h;
|
||||
return ret;
|
||||
}
|
||||
|
||||
SDL_Texture *segs_texture(int index, int val);
|
||||
|
||||
void init_components(SDL_Renderer *renderer) {
|
||||
Component *ptr = nullptr;
|
||||
SDL_Rect *rect_ptr = nullptr;
|
||||
|
||||
// init buttons
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
ptr = new Component(renderer, 2, 0, BUTTON_TYPE);
|
||||
|
||||
// off
|
||||
rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = btn_rects[i];
|
||||
ptr->set_rect(rect_ptr, 0);
|
||||
ptr->set_texture(tbutton_off, 0);
|
||||
|
||||
// on
|
||||
rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = btn_rects[i];
|
||||
ptr->set_rect(rect_ptr, 1);
|
||||
ptr->set_texture(tbutton_on, 1);
|
||||
|
||||
ptr->add_pin(BTNC + i);
|
||||
components.push_back(ptr);
|
||||
}
|
||||
|
||||
// init switches
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
ptr = new Component(renderer, 2, 0, SWITCH_TYPE);
|
||||
|
||||
// off
|
||||
rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = (SDL_Rect){SWITCH_X + (15 - i) * (SWITCH_WIDTH + SWITCH_SEP), SWITCH_Y, SWITCH_WIDTH, SWITCH_HEIGHT};
|
||||
ptr->set_rect(rect_ptr, 0);
|
||||
ptr->set_texture(tswitch_off, 0);
|
||||
|
||||
// on
|
||||
rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = (SDL_Rect){SWITCH_X + (15 - i) * (SWITCH_WIDTH + SWITCH_SEP), SWITCH_Y, SWITCH_WIDTH, SWITCH_HEIGHT};
|
||||
ptr->set_rect(rect_ptr, 1);
|
||||
ptr->set_texture(tswitch_on, 1);
|
||||
|
||||
ptr->add_pin(SW0 + i);
|
||||
components.push_back(ptr);
|
||||
}
|
||||
|
||||
// init naive leds
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
ptr = new Component(renderer, 2, 0, NAIVE_LED_TYPE);
|
||||
|
||||
// off
|
||||
rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = (SDL_Rect){LED_X + (15 - i) * (LED_WIDTH + LED_SEP), LED_Y, LED_WIDTH, LED_HEIGHT};
|
||||
ptr->set_rect(rect_ptr, 0);
|
||||
ptr->set_texture(tled_off, 0);
|
||||
|
||||
// on
|
||||
rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = (SDL_Rect){LED_X + (15 - i) * (LED_WIDTH + LED_SEP), LED_Y, LED_WIDTH, LED_HEIGHT};
|
||||
ptr->set_rect(rect_ptr, 1);
|
||||
ptr->set_texture(tled_g, 1);
|
||||
|
||||
ptr->add_pin(LD0 + i);
|
||||
components.push_back(ptr);
|
||||
}
|
||||
|
||||
// init 7-segment display
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
SDL_Rect mv = {SEG_X + SEG_SEP + (7 - i) * (SEG_HOR_WIDTH + SEG_DOT_WIDTH + SEG_VER_WIDTH * 2 + SEG_SEP * 2), SEG_Y + SEG_SEP, 0, 0};
|
||||
bool is_len8 = (pin_array[GET_SEGA(i)].vector_len == 8);
|
||||
ptr = new SEGS7(renderer, 16, 0x5555, SEGS7_TYPE, is_len8);
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = mv + segs_rect[j];
|
||||
ptr->set_texture(segs_texture(j, 0), j << 1 | 0);
|
||||
ptr->set_rect(rect_ptr, j << 1 | 0);
|
||||
rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = mv + segs_rect[j];
|
||||
ptr->set_texture(segs_texture(j, 1), j << 1 | 1);
|
||||
ptr->set_rect(rect_ptr, j << 1 | 1);
|
||||
}
|
||||
|
||||
for (int p = GET_SEGA(i); p <= GET_DECP(i); p ++) {
|
||||
ptr->add_pin(p);
|
||||
}
|
||||
components.push_back(ptr);
|
||||
}
|
||||
|
||||
#ifdef VGA_ENA
|
||||
// init vga
|
||||
extern VGA* vga;
|
||||
vga = new VGA(renderer, 1, 0, VGA_TYPE);
|
||||
rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = (SDL_Rect){0, WINDOW_HEIGHT / 2, VGA_DEFAULT_WIDTH, VGA_DEFAULT_HEIGHT};
|
||||
vga->set_rect(rect_ptr, 0);
|
||||
for (int p = VGA_VSYNC; p <= VGA_B7; p ++) {
|
||||
vga->add_pin(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
// init keyboard
|
||||
extern KEYBOARD* kb;
|
||||
kb = new KEYBOARD(renderer, 0, 0, KEYBOARD_TYPE);
|
||||
for (int p = PS2_CLK; p <= PS2_DAT; p ++) {
|
||||
kb->add_pin(p);
|
||||
}
|
||||
#define COMPONENT_LIST(f) f(led) f(switch) f(button) f(segs7) f(keyboard) f(vga)
|
||||
#define INIT_FN(c) { void concat(init_, c)(SDL_Renderer *); concat(init_, c)(renderer); }
|
||||
COMPONENT_LIST(INIT_FN);
|
||||
}
|
||||
|
||||
static void delete_components(std::vector<Component *> *c) {
|
||||
for (auto comp_ptr : *c) {
|
||||
comp_ptr->remove();
|
||||
delete comp_ptr;
|
||||
}
|
||||
c->clear();
|
||||
std::vector<Component *> components;
|
||||
|
||||
void add_component(Component *c) {
|
||||
components.push_back(c);
|
||||
}
|
||||
|
||||
void delete_components() {
|
||||
delete_components(&components);
|
||||
for (auto comp_ptr : components) {
|
||||
comp_ptr->remove();
|
||||
delete comp_ptr;
|
||||
}
|
||||
components.clear();
|
||||
}
|
||||
|
||||
// render buttons, switches, leds and 7-segs
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
#include <SDL.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <keyboard.h>
|
||||
#include <pins.h>
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <keyboard.h>
|
||||
#include <pins.h>
|
||||
#include <assert.h>
|
||||
#include "at_scancode.h"
|
||||
|
||||
KEYBOARD* kb = NULL;
|
||||
bool is_kb_idle = true;
|
||||
|
@ -11,27 +11,16 @@ bool is_kb_idle = true;
|
|||
static int keymap_first[256] = {};
|
||||
static int keymap_second[256] = {};
|
||||
|
||||
void keymap_init(){
|
||||
MAP(SCANCODE_LIST, FILL_KEYMAP_FIRST)
|
||||
MAP(SCANCODE_LIST, FILL_KEYMAP_DECOND)
|
||||
}
|
||||
|
||||
int sdl2at(int scancode, int is_first){
|
||||
return is_first? keymap_first[scancode] : keymap_second[scancode];
|
||||
}
|
||||
|
||||
KEYBOARD::KEYBOARD(SDL_Renderer *rend, int cnt, int init_val, int ct):
|
||||
Component(rend, cnt, init_val, ct),
|
||||
data_idx(0), left_clk(0), cur_key(NOT_A_KEY) {
|
||||
keymap_init();
|
||||
}
|
||||
data_idx(0), left_clk(0), cur_key(NOT_A_KEY) { }
|
||||
|
||||
|
||||
void KEYBOARD::push_key(uint8_t sdl_key, bool is_keydown){
|
||||
uint8_t at_key = sdl2at(sdl_key, 1);
|
||||
uint8_t at_key = keymap_first[sdl_key];
|
||||
if(at_key == 0xe0){
|
||||
all_keys.push(0xe0);
|
||||
at_key = sdl2at(sdl_key, 0);
|
||||
at_key = keymap_second[sdl_key];
|
||||
}
|
||||
if(!is_keydown) all_keys.push(0xf0);
|
||||
all_keys.push(at_key);
|
||||
|
@ -72,3 +61,12 @@ void KEYBOARD::update_state(){
|
|||
left_clk --;
|
||||
}
|
||||
}
|
||||
|
||||
void init_keyboard(SDL_Renderer *renderer) {
|
||||
kb = new KEYBOARD(renderer, 0, 0, KEYBOARD_TYPE);
|
||||
for (int p = PS2_CLK; p <= PS2_DAT; p ++) {
|
||||
kb->add_pin(p);
|
||||
}
|
||||
MAP(SCANCODE_LIST, FILL_KEYMAP_FIRST)
|
||||
MAP(SCANCODE_LIST, FILL_KEYMAP_DECOND)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
#include <nvboard.h>
|
||||
|
||||
#define LED_X 60 + (4/2)
|
||||
#define LED_Y 360
|
||||
#define LED_SEP 14
|
||||
#define LED_WIDTH 16
|
||||
#define LED_HEIGHT 8
|
||||
|
||||
static SDL_Surface *sled_off, *sled_r, *sled_g, *sled_b,
|
||||
*sled_rg, *sled_rb, *sled_gb, *sled_rgb;
|
||||
static SDL_Texture *tled_off, *tled_r, *tled_g, *tled_b,
|
||||
*tled_rg, *tled_rb, *tled_gb, *tled_rgb;
|
||||
|
||||
static void load_texture(SDL_Renderer *renderer) {
|
||||
sled_off = SDL_CreateRGBSurface(0, LED_WIDTH, LED_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &sled_off, &tled_off, 0x7f, 0x7f, 0x7f);
|
||||
|
||||
sled_r = SDL_CreateRGBSurface(0, LED_WIDTH, LED_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &sled_r, &tled_r, 0xff, 0x00, 0x00);
|
||||
|
||||
sled_g = SDL_CreateRGBSurface(0, LED_WIDTH, LED_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &sled_g, &tled_g, 0x00, 0xff, 0x00);
|
||||
|
||||
sled_b = SDL_CreateRGBSurface(0, LED_WIDTH, LED_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &sled_b, &tled_b, 0x00, 0x00, 0xff);
|
||||
|
||||
sled_rg = SDL_CreateRGBSurface(0, LED_WIDTH, LED_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &sled_rg, &tled_rg, 0xff, 0xff, 0x00);
|
||||
|
||||
sled_rb = SDL_CreateRGBSurface(0, LED_WIDTH, LED_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &sled_rb, &tled_rb, 0xff, 0x00, 0xff);
|
||||
|
||||
sled_gb = SDL_CreateRGBSurface(0, LED_WIDTH, LED_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &sled_gb, &tled_gb, 0x00, 0xff, 0xff);
|
||||
|
||||
sled_rgb = SDL_CreateRGBSurface(0, LED_WIDTH, LED_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &sled_rgb, &tled_rgb, 0xff, 0xff, 0xff);
|
||||
}
|
||||
|
||||
void init_led(SDL_Renderer *renderer) {
|
||||
load_texture(renderer);
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
Component *ptr = new Component(renderer, 2, 0, NAIVE_LED_TYPE);
|
||||
|
||||
// off
|
||||
SDL_Rect *rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = (SDL_Rect){LED_X + (15 - i) * (LED_WIDTH + LED_SEP), LED_Y, LED_WIDTH, LED_HEIGHT};
|
||||
ptr->set_rect(rect_ptr, 0);
|
||||
ptr->set_texture(tled_off, 0);
|
||||
|
||||
// on
|
||||
rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = (SDL_Rect){LED_X + (15 - i) * (LED_WIDTH + LED_SEP), LED_Y, LED_WIDTH, LED_HEIGHT};
|
||||
ptr->set_rect(rect_ptr, 1);
|
||||
ptr->set_texture(tled_g, 1);
|
||||
|
||||
ptr->add_pin(LD0 + i);
|
||||
add_component(ptr);
|
||||
}
|
||||
}
|
|
@ -1,13 +1,7 @@
|
|||
#include <SDL.h>
|
||||
#include <SDL_image.h>
|
||||
#include <nvboard.h>
|
||||
#include <keyboard.h>
|
||||
#include <vga.h>
|
||||
#include <render.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <assert.h>
|
||||
#include <string>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define FPS 60
|
||||
|
@ -28,6 +22,8 @@ static uint64_t get_time() {
|
|||
|
||||
static SDL_Window *main_window = nullptr;
|
||||
static SDL_Renderer *main_renderer = nullptr;
|
||||
static SDL_Surface *sfpga_background;
|
||||
static SDL_Texture *tfpga_background;
|
||||
std::string nvboard_home;
|
||||
PinNode pin_array[NR_PINS];
|
||||
|
||||
|
@ -66,6 +62,13 @@ void nvboard_update() {
|
|||
}
|
||||
}
|
||||
|
||||
static void load_background(SDL_Renderer *renderer) {
|
||||
sfpga_background = IMG_Load((nvboard_home + "/pic/" + BG_PATH).c_str());
|
||||
tfpga_background = SDL_CreateTextureFromSurface(renderer, sfpga_background);
|
||||
SDL_Rect rect_bg = {0, 0, WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2};
|
||||
SDL_RenderCopy(renderer, tfpga_background, NULL, &rect_bg);
|
||||
}
|
||||
|
||||
void nvboard_init(int vga_clk_cycle) {
|
||||
printf("NVBoard v0.3 (2024.01.02)\n");
|
||||
// init SDL and SDL_image
|
||||
|
@ -84,11 +87,10 @@ void nvboard_init(int vga_clk_cycle) {
|
|||
#endif
|
||||
0
|
||||
);
|
||||
|
||||
|
||||
nvboard_home = getenv("NVBOARD_HOME");
|
||||
|
||||
|
||||
load_background(main_renderer);
|
||||
load_texture(main_renderer);
|
||||
init_components(main_renderer);
|
||||
init_gui(main_renderer);
|
||||
|
||||
|
|
159
src/render.cpp
159
src/render.cpp
|
@ -1,159 +0,0 @@
|
|||
#include <render.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <SDL.h>
|
||||
#include <SDL_image.h>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <configs.h>
|
||||
#include <component.h>
|
||||
|
||||
SDL_Surface *sbutton_on, *sbutton_off;
|
||||
SDL_Surface *sswitch_on, *sswitch_off;
|
||||
SDL_Surface *ssegled_ver_off, *ssegled_ver_on,
|
||||
*ssegled_hor_off, *ssegled_hor_on,
|
||||
*ssegled_dot_off, *ssegled_dot_on;
|
||||
SDL_Surface *sled_off, *sled_r, *sled_g, *sled_b,
|
||||
*sled_rg, *sled_rb, *sled_gb, *sled_rgb;
|
||||
SDL_Surface *sfpga_background;
|
||||
SDL_Surface *sseg7_background;
|
||||
|
||||
SDL_Texture *tbutton_on, *tbutton_off;
|
||||
SDL_Texture *tswitch_on, *tswitch_off;
|
||||
SDL_Texture *tsegled_ver_off, *tsegled_ver_on,
|
||||
*tsegled_hor_off, *tsegled_hor_on,
|
||||
*tsegled_dot_off, *tsegled_dot_on;
|
||||
SDL_Texture *tled_off, *tled_r, *tled_g, *tled_b,
|
||||
*tled_rg, *tled_rb, *tled_gb, *tled_rgb;
|
||||
SDL_Texture *tfpga_background, *tseg7_background;
|
||||
|
||||
SDL_Rect segs_rect[8] = {
|
||||
{SEG_SEP + SEG_VER_WIDTH, SEG_SEP , SEG_HOR_WIDTH, SEG_HOR_HEIGHT },
|
||||
{SEG_SEP + SEG_VER_WIDTH + SEG_HOR_WIDTH, SEG_SEP + SEG_HOR_HEIGHT , SEG_VER_WIDTH, SEG_VER_HEIGHT },
|
||||
{SEG_SEP + SEG_VER_WIDTH + SEG_HOR_WIDTH, SEG_SEP + 2*SEG_HOR_HEIGHT + SEG_VER_HEIGHT , SEG_VER_WIDTH, SEG_VER_HEIGHT },
|
||||
{SEG_SEP + SEG_VER_WIDTH, SEG_SEP + 2*SEG_HOR_HEIGHT + 2*SEG_VER_HEIGHT , SEG_HOR_WIDTH, SEG_HOR_HEIGHT },
|
||||
{SEG_SEP, SEG_SEP + 2*SEG_HOR_HEIGHT + SEG_VER_HEIGHT , SEG_VER_WIDTH, SEG_VER_HEIGHT },
|
||||
{SEG_SEP, SEG_SEP + SEG_HOR_HEIGHT , SEG_VER_WIDTH, SEG_VER_HEIGHT },
|
||||
{SEG_SEP + SEG_VER_WIDTH, SEG_SEP + SEG_HOR_HEIGHT + SEG_VER_HEIGHT , SEG_HOR_WIDTH, SEG_HOR_HEIGHT },
|
||||
{2*SEG_SEP + 2*SEG_VER_WIDTH + SEG_HOR_WIDTH, SEG_SEP + 3*SEG_HOR_HEIGHT + 2*SEG_VER_HEIGHT - SEG_DOT_HEIGHT , SEG_DOT_WIDTH, SEG_DOT_HEIGHT }
|
||||
};
|
||||
|
||||
SDL_Texture *segs_texture(int index, int val) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
case 3:
|
||||
case 6:
|
||||
return val ? tsegled_hor_on : tsegled_hor_off;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 5:
|
||||
return val ? tsegled_ver_on : tsegled_ver_off;
|
||||
break;
|
||||
case 7:
|
||||
return val ? tsegled_dot_on : tsegled_dot_off;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SDL_Rect btn_rects[6] = {
|
||||
{BTNC_X, BTNC_Y, BTNC_WIDTH, BTNC_HEIGHT },
|
||||
{BTNC_X, BTNC_Y - BTNC_HEIGHT - BTNC_SEP, BTNC_WIDTH, BTNC_HEIGHT },
|
||||
{BTNC_X, BTNC_Y + BTNC_HEIGHT + BTNC_SEP, BTNC_WIDTH, BTNC_HEIGHT },
|
||||
{BTNC_X - BTNC_WIDTH - BTNC_SEP, BTNC_Y, BTNC_WIDTH, BTNC_HEIGHT },
|
||||
{BTNC_X + BTNC_WIDTH + BTNC_SEP, BTNC_Y, BTNC_WIDTH, BTNC_HEIGHT },
|
||||
{BTNC_X + BTNC_WIDTH + BTNC_SEP/2, BTNC_Y - 2 * (BTNC_HEIGHT + BTNC_SEP), BTNC_WIDTH, BTNC_HEIGHT } // RST, but not draw
|
||||
};
|
||||
|
||||
extern std::string nvboard_home;
|
||||
|
||||
void load_background(SDL_Renderer *renderer) {
|
||||
sfpga_background = IMG_Load((nvboard_home + "/pic/" + BG_PATH).c_str());
|
||||
tfpga_background = SDL_CreateTextureFromSurface(renderer, sfpga_background);
|
||||
SDL_Rect rect_bg = {0, 0, WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2};
|
||||
SDL_RenderCopy(renderer, tfpga_background, NULL, &rect_bg);
|
||||
|
||||
#ifdef SEG_BKGND_ENA
|
||||
#ifdef SEG_BKGND_CUSTOM
|
||||
sseg7_background = IMG_Load((nvboard_home + "/pic/" + VSEGLED_BG_PATH).c_str());
|
||||
#else
|
||||
sseg7_background = SDL_CreateRGBSurface(0, SEG_TOT_WIDTH, SEG_TOT_HEIGHT, 32, 0, 0, 0, 0);
|
||||
SDL_FillRect(sseg7_background, NULL, SDL_MapRGB(sseg7_background->format, 0x00, 0x00, 0x00));
|
||||
#endif
|
||||
|
||||
tseg7_background = SDL_CreateTextureFromSurface(renderer, sseg7_background);
|
||||
SDL_Rect rect_seg7 = {SEG_X, SEG_Y, SEG_TOT_WIDTH, SEG_TOT_HEIGHT};
|
||||
SDL_RenderCopy(renderer, tseg7_background, NULL, &rect_seg7);
|
||||
#endif
|
||||
}
|
||||
|
||||
void fill_rect_texture(SDL_Renderer *renderer, SDL_Surface **surface, SDL_Texture **texture, int r, int g, int b) {
|
||||
SDL_FillRect(*surface, NULL, SDL_MapRGB((*surface)->format, r, g, b));
|
||||
*texture = SDL_CreateTextureFromSurface(renderer, *surface);
|
||||
}
|
||||
|
||||
void load_texture(SDL_Renderer *renderer) {
|
||||
// buttons
|
||||
sbutton_on = IMG_Load((nvboard_home + "/pic/" + VBTN_ON_PATH).c_str());
|
||||
assert(sbutton_on != nullptr);
|
||||
tbutton_on = SDL_CreateTextureFromSurface(renderer, sbutton_on);
|
||||
sbutton_off = IMG_Load((nvboard_home + "/pic/" + VBTN_OFF_PATH).c_str());
|
||||
assert(sbutton_off != nullptr);
|
||||
tbutton_off = SDL_CreateTextureFromSurface(renderer, sbutton_off);
|
||||
|
||||
// switches
|
||||
sswitch_on = IMG_Load((nvboard_home + "/pic/" + VSW_ON_PATH).c_str());
|
||||
tswitch_on = SDL_CreateTextureFromSurface(renderer, sswitch_on);
|
||||
sswitch_off = IMG_Load((nvboard_home + "/pic/" + VSW_OFF_PATH).c_str());
|
||||
tswitch_off = SDL_CreateTextureFromSurface(renderer, sswitch_off);
|
||||
|
||||
// 7 segs
|
||||
// vertical
|
||||
ssegled_ver_on = SDL_CreateRGBSurface(0, SEG_VER_WIDTH, SEG_VER_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &ssegled_ver_on, &tsegled_ver_on, 0xff, 0x00, 0x00);
|
||||
ssegled_ver_off = SDL_CreateRGBSurface(0, SEG_VER_WIDTH, SEG_VER_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &ssegled_ver_off, &tsegled_ver_off, 0x2b, 0x2b, 0x2b);
|
||||
|
||||
// horizontal
|
||||
ssegled_hor_on = SDL_CreateRGBSurface(0, SEG_HOR_WIDTH, SEG_HOR_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &ssegled_hor_on, &tsegled_hor_on, 0xff, 0x00, 0x00);
|
||||
ssegled_hor_off = SDL_CreateRGBSurface(0, SEG_HOR_WIDTH, SEG_HOR_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &ssegled_hor_off, &tsegled_hor_off, 0x2b, 0x2b, 0x2b);
|
||||
|
||||
// dot
|
||||
ssegled_dot_on = SDL_CreateRGBSurface(0, SEG_DOT_WIDTH, SEG_DOT_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &ssegled_dot_on, &tsegled_dot_on, 0xff, 0x00, 0x00);
|
||||
ssegled_dot_off = SDL_CreateRGBSurface(0, SEG_DOT_WIDTH, SEG_DOT_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &ssegled_dot_off, &tsegled_dot_off, 0x2b, 0x2b, 0x2b);
|
||||
|
||||
// LEDs
|
||||
sled_off = SDL_CreateRGBSurface(0, LED_WIDTH, LED_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &sled_off, &tled_off, 0x7f, 0x7f, 0x7f);
|
||||
|
||||
sled_r = SDL_CreateRGBSurface(0, LED_WIDTH, LED_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &sled_r, &tled_r, 0xff, 0x00, 0x00);
|
||||
|
||||
sled_g = SDL_CreateRGBSurface(0, LED_WIDTH, LED_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &sled_g, &tled_g, 0x00, 0xff, 0x00);
|
||||
|
||||
sled_b = SDL_CreateRGBSurface(0, LED_WIDTH, LED_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &sled_b, &tled_b, 0x00, 0x00, 0xff);
|
||||
|
||||
sled_rg = SDL_CreateRGBSurface(0, LED_WIDTH, LED_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &sled_rg, &tled_rg, 0xff, 0xff, 0x00);
|
||||
|
||||
sled_rb = SDL_CreateRGBSurface(0, LED_WIDTH, LED_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &sled_rb, &tled_rb, 0xff, 0x00, 0xff);
|
||||
|
||||
sled_gb = SDL_CreateRGBSurface(0, LED_WIDTH, LED_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &sled_gb, &tled_gb, 0x00, 0xff, 0xff);
|
||||
|
||||
sled_rgb = SDL_CreateRGBSurface(0, LED_WIDTH, LED_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &sled_rgb, &tled_rgb, 0xff, 0xff, 0xff);
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
#include <nvboard.h>
|
||||
|
||||
#define SEG_X 60
|
||||
#define SEG_Y 225
|
||||
|
||||
#define SEG_VER_WIDTH 3
|
||||
#define SEG_VER_HEIGHT 30
|
||||
#define SEG_HOR_WIDTH 30
|
||||
#define SEG_HOR_HEIGHT 3
|
||||
#define SEG_DOT_WIDTH 4
|
||||
#define SEG_DOT_HEIGHT 4
|
||||
|
||||
#define SEG_SEP 3
|
||||
|
||||
#define SEG_TOT_WIDTH (SEG_SEP * 18 + SEG_VER_WIDTH * 16 + SEG_DOT_WIDTH * 8 + SEG_HOR_WIDTH * 8)
|
||||
#define SEG_TOT_HEIGHT (SEG_SEP * 4 + SEG_VER_HEIGHT * 2 + SEG_HOR_HEIGHT * 3)
|
||||
|
||||
#define GET_SEGA(i) (SEG0A + 8 * i)
|
||||
#define GET_DECP(i) (SEG0A + 8 * i + 7)
|
||||
|
||||
static SDL_Texture *tsegled_ver_off, *tsegled_ver_on,
|
||||
*tsegled_hor_off, *tsegled_hor_on,
|
||||
*tsegled_dot_off, *tsegled_dot_on;
|
||||
static SDL_Surface *ssegled_ver_off, *ssegled_ver_on,
|
||||
*ssegled_hor_off, *ssegled_hor_on,
|
||||
*ssegled_dot_off, *ssegled_dot_on;
|
||||
static SDL_Surface *sseg7_background;
|
||||
static SDL_Texture *tseg7_background;
|
||||
|
||||
static SDL_Rect segs_rect[8] = {
|
||||
{SEG_SEP + SEG_VER_WIDTH, SEG_SEP , SEG_HOR_WIDTH, SEG_HOR_HEIGHT },
|
||||
{SEG_SEP + SEG_VER_WIDTH + SEG_HOR_WIDTH, SEG_SEP + SEG_HOR_HEIGHT , SEG_VER_WIDTH, SEG_VER_HEIGHT },
|
||||
{SEG_SEP + SEG_VER_WIDTH + SEG_HOR_WIDTH, SEG_SEP + 2*SEG_HOR_HEIGHT + SEG_VER_HEIGHT , SEG_VER_WIDTH, SEG_VER_HEIGHT },
|
||||
{SEG_SEP + SEG_VER_WIDTH, SEG_SEP + 2*SEG_HOR_HEIGHT + 2*SEG_VER_HEIGHT , SEG_HOR_WIDTH, SEG_HOR_HEIGHT },
|
||||
{SEG_SEP, SEG_SEP + 2*SEG_HOR_HEIGHT + SEG_VER_HEIGHT , SEG_VER_WIDTH, SEG_VER_HEIGHT },
|
||||
{SEG_SEP, SEG_SEP + SEG_HOR_HEIGHT , SEG_VER_WIDTH, SEG_VER_HEIGHT },
|
||||
{SEG_SEP + SEG_VER_WIDTH, SEG_SEP + SEG_HOR_HEIGHT + SEG_VER_HEIGHT , SEG_HOR_WIDTH, SEG_HOR_HEIGHT },
|
||||
{2*SEG_SEP + 2*SEG_VER_WIDTH + SEG_HOR_WIDTH, SEG_SEP + 3*SEG_HOR_HEIGHT + 2*SEG_VER_HEIGHT - SEG_DOT_HEIGHT , SEG_DOT_WIDTH, SEG_DOT_HEIGHT }
|
||||
};
|
||||
|
||||
static SDL_Texture *segs_texture(int index, int val) {
|
||||
switch (index) {
|
||||
case 0: case 3: case 6: return val ? tsegled_hor_on : tsegled_hor_off;
|
||||
case 1: case 2: case 4: case 5: return val ? tsegled_ver_on : tsegled_ver_off;
|
||||
case 7: return val ? tsegled_dot_on : tsegled_dot_off;
|
||||
default: assert(0); return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
SEGS7::SEGS7(SDL_Renderer *rend, int cnt, int init_val, int ct, bool is_len8)
|
||||
: Component(rend, cnt, init_val, ct), is_len8(is_len8) {}
|
||||
|
||||
void SEGS7::update_gui() {
|
||||
int newval = get_state();
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
int texture_idx = (7 - i) * 2 + (((newval >> i) & 1) ? 0 : 1);
|
||||
SDL_RenderCopy(get_renderer(), get_texture(texture_idx), NULL, get_rect(texture_idx));
|
||||
}
|
||||
set_redraw();
|
||||
}
|
||||
|
||||
void SEGS7::update_state() {
|
||||
int newval = 0;
|
||||
if (is_len8) {
|
||||
newval = pin_peek8(get_pin());
|
||||
} else {
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
newval |= (pin_peek(get_pin(7 - i)) << i);
|
||||
}
|
||||
}
|
||||
if (newval != get_state()) {
|
||||
set_state(newval);
|
||||
update_gui();
|
||||
}
|
||||
}
|
||||
|
||||
static void load_texture(SDL_Renderer *renderer) {
|
||||
// vertical
|
||||
ssegled_ver_on = SDL_CreateRGBSurface(0, SEG_VER_WIDTH, SEG_VER_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &ssegled_ver_on, &tsegled_ver_on, 0xff, 0x00, 0x00);
|
||||
ssegled_ver_off = SDL_CreateRGBSurface(0, SEG_VER_WIDTH, SEG_VER_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &ssegled_ver_off, &tsegled_ver_off, 0x2b, 0x2b, 0x2b);
|
||||
|
||||
// horizontal
|
||||
ssegled_hor_on = SDL_CreateRGBSurface(0, SEG_HOR_WIDTH, SEG_HOR_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &ssegled_hor_on, &tsegled_hor_on, 0xff, 0x00, 0x00);
|
||||
ssegled_hor_off = SDL_CreateRGBSurface(0, SEG_HOR_WIDTH, SEG_HOR_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &ssegled_hor_off, &tsegled_hor_off, 0x2b, 0x2b, 0x2b);
|
||||
|
||||
// dot
|
||||
ssegled_dot_on = SDL_CreateRGBSurface(0, SEG_DOT_WIDTH, SEG_DOT_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &ssegled_dot_on, &tsegled_dot_on, 0xff, 0x00, 0x00);
|
||||
ssegled_dot_off = SDL_CreateRGBSurface(0, SEG_DOT_WIDTH, SEG_DOT_HEIGHT, 32, 0, 0, 0, 0);
|
||||
fill_rect_texture(renderer, &ssegled_dot_off, &tsegled_dot_off, 0x2b, 0x2b, 0x2b);
|
||||
|
||||
#ifdef SEG_BKGND_ENA
|
||||
#ifdef SEG_BKGND_CUSTOM
|
||||
sseg7_background = IMG_Load((nvboard_home + "/pic/" + VSEGLED_BG_PATH).c_str());
|
||||
#else
|
||||
sseg7_background = SDL_CreateRGBSurface(0, SEG_TOT_WIDTH, SEG_TOT_HEIGHT, 32, 0, 0, 0, 0);
|
||||
SDL_FillRect(sseg7_background, NULL, SDL_MapRGB(sseg7_background->format, 0x00, 0x00, 0x00));
|
||||
#endif
|
||||
|
||||
tseg7_background = SDL_CreateTextureFromSurface(renderer, sseg7_background);
|
||||
SDL_Rect rect_seg7 = {SEG_X, SEG_Y, SEG_TOT_WIDTH, SEG_TOT_HEIGHT};
|
||||
SDL_RenderCopy(renderer, tseg7_background, NULL, &rect_seg7);
|
||||
#endif
|
||||
}
|
||||
|
||||
void init_segs7(SDL_Renderer *renderer) {
|
||||
load_texture(renderer);
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
SDL_Rect mv = {SEG_X + SEG_SEP + (7 - i) * (SEG_HOR_WIDTH + SEG_DOT_WIDTH + SEG_VER_WIDTH * 2 + SEG_SEP * 2), SEG_Y + SEG_SEP, 0, 0};
|
||||
bool is_len8 = (pin_array[GET_SEGA(i)].vector_len == 8);
|
||||
Component *ptr = new SEGS7(renderer, 16, 0x5555, SEGS7_TYPE, is_len8);
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
SDL_Rect *rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = mv + segs_rect[j];
|
||||
ptr->set_texture(segs_texture(j, 0), j << 1 | 0);
|
||||
ptr->set_rect(rect_ptr, j << 1 | 0);
|
||||
rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = mv + segs_rect[j];
|
||||
ptr->set_texture(segs_texture(j, 1), j << 1 | 1);
|
||||
ptr->set_rect(rect_ptr, j << 1 | 1);
|
||||
}
|
||||
|
||||
for (int p = GET_SEGA(i); p <= GET_DECP(i); p ++) {
|
||||
ptr->add_pin(p);
|
||||
}
|
||||
add_component(ptr);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#include <nvboard.h>
|
||||
|
||||
#define SWITCH_X 60
|
||||
#define SWITCH_Y 400
|
||||
#define SWITCH_SEP 10
|
||||
#define SWITCH_WIDTH 20
|
||||
#define SWITCH_HEIGHT 40
|
||||
|
||||
static SDL_Surface *sswitch_on, *sswitch_off;
|
||||
static SDL_Texture *tswitch_on, *tswitch_off;
|
||||
|
||||
static void load_texture(SDL_Renderer *renderer) {
|
||||
// switches
|
||||
sswitch_on = IMG_Load((nvboard_home + "/pic/" + VSW_ON_PATH).c_str());
|
||||
tswitch_on = SDL_CreateTextureFromSurface(renderer, sswitch_on);
|
||||
sswitch_off = IMG_Load((nvboard_home + "/pic/" + VSW_OFF_PATH).c_str());
|
||||
tswitch_off = SDL_CreateTextureFromSurface(renderer, sswitch_off);
|
||||
}
|
||||
|
||||
void init_switch(SDL_Renderer *renderer) {
|
||||
load_texture(renderer);
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
Component *ptr = new Component(renderer, 2, 0, SWITCH_TYPE);
|
||||
|
||||
// off
|
||||
SDL_Rect *rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = (SDL_Rect){SWITCH_X + (15 - i) * (SWITCH_WIDTH + SWITCH_SEP), SWITCH_Y, SWITCH_WIDTH, SWITCH_HEIGHT};
|
||||
ptr->set_rect(rect_ptr, 0);
|
||||
ptr->set_texture(tswitch_off, 0);
|
||||
|
||||
// on
|
||||
rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = (SDL_Rect){SWITCH_X + (15 - i) * (SWITCH_WIDTH + SWITCH_SEP), SWITCH_Y, SWITCH_WIDTH, SWITCH_HEIGHT};
|
||||
ptr->set_rect(rect_ptr, 1);
|
||||
ptr->set_texture(tswitch_on, 1);
|
||||
|
||||
ptr->add_pin(SW0 + i);
|
||||
add_component(ptr);
|
||||
}
|
||||
}
|
15
src/vga.cpp
15
src/vga.cpp
|
@ -1,9 +1,6 @@
|
|||
#include <nvboard.h>
|
||||
#include <vga.h>
|
||||
#include <keyboard.h>
|
||||
#include <pins.h>
|
||||
#include <render.h>
|
||||
#include <macro.h>
|
||||
#include <assert.h>
|
||||
|
||||
VGA* vga = NULL;
|
||||
|
||||
|
@ -104,3 +101,13 @@ void VGA::update_state() {
|
|||
void vga_set_clk_cycle(int cycle) {
|
||||
vga_clk_cycle = cycle;
|
||||
}
|
||||
|
||||
void init_vga(SDL_Renderer *renderer) {
|
||||
vga = new VGA(renderer, 1, 0, VGA_TYPE);
|
||||
SDL_Rect *rect_ptr = new SDL_Rect;
|
||||
*rect_ptr = (SDL_Rect){0, WINDOW_HEIGHT / 2, VGA_DEFAULT_WIDTH, VGA_DEFAULT_HEIGHT};
|
||||
vga->set_rect(rect_ptr, 0);
|
||||
for (int p = VGA_VSYNC; p <= VGA_B7; p ++) {
|
||||
vga->add_pin(p);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef __NVBOARD_H__
|
||||
#define __NVBOARD_H__
|
||||
|
||||
#include <pins.h>
|
||||
|
||||
void nvboard_init(int vga_clk_cycle = 1);
|
||||
void nvboard_quit();
|
||||
void nvboard_bind_pin(void *signal, int len, ...);
|
||||
void nvboard_update();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef _NVBOARD_PINS_H
|
||||
#define _NVBOARD_PINS_H
|
||||
|
||||
// RST is defined but not used. NVBoard contains some internal states in *.cpp
|
||||
// file. Only resetting the RTL design in *.v file may make the RTL design and
|
||||
// NVBoard inconsistent. The easy way to reset the whole system is to exit
|
||||
// NVBoard and re-run. The reset work for RTL design is done by the verilator
|
||||
// wrapper. See `example/csrc/main.cpp` for more details.
|
||||
#define BTN_INPUT BTNC, BTNU, BTND, BTNL, BTNR, RST
|
||||
|
||||
#define SW_INPUT SW0, SW1, SW2, SW3, \
|
||||
SW4, SW5, SW6, SW7, \
|
||||
SW8, SW9, SW10, SW11, \
|
||||
SW12, SW13, SW14, SW15
|
||||
|
||||
#define NAIVE_LEDS_OUTPUT LD0, LD1, LD2, LD3, \
|
||||
LD4, LD5, LD6, LD7, \
|
||||
LD8, LD9, LD10, LD11, \
|
||||
LD12, LD13, LD14, LD15
|
||||
|
||||
#define RGB_LEDS_OUTPUT R16, G16, B16, R17, G17, B17
|
||||
|
||||
|
||||
#define SEG7_SEGS_OUTPUT SEG0A, SEG0B, SEG0C, SEG0D, SEG0E, SEG0F, SEG0G, DEC0P, \
|
||||
SEG1A, SEG1B, SEG1C, SEG1D, SEG1E, SEG1F, SEG1G, DEC1P, \
|
||||
SEG2A, SEG2B, SEG2C, SEG2D, SEG2E, SEG2F, SEG2G, DEC2P, \
|
||||
SEG3A, SEG3B, SEG3C, SEG3D, SEG3E, SEG3F, SEG3G, DEC3P, \
|
||||
SEG4A, SEG4B, SEG4C, SEG4D, SEG4E, SEG4F, SEG4G, DEC4P, \
|
||||
SEG5A, SEG5B, SEG5C, SEG5D, SEG5E, SEG5F, SEG5G, DEC5P, \
|
||||
SEG6A, SEG6B, SEG6C, SEG6D, SEG6E, SEG6F, SEG6G, DEC6P, \
|
||||
SEG7A, SEG7B, SEG7C, SEG7D, SEG7E, SEG7F, SEG7G, DEC7P
|
||||
|
||||
//#define UART_OUTPUT
|
||||
|
||||
#define VGA_OUTPUT VGA_VSYNC, VGA_HSYNC, VGA_BLANK_N, \
|
||||
VGA_R0, VGA_R1, VGA_R2, VGA_R3, VGA_R4, VGA_R5, VGA_R6, VGA_R7, \
|
||||
VGA_G0, VGA_G1, VGA_G2, VGA_G3, VGA_G4, VGA_G5, VGA_G6, VGA_G7, \
|
||||
VGA_B0, VGA_B1, VGA_B2, VGA_B3, VGA_B4, VGA_B5, VGA_B6, VGA_B7
|
||||
|
||||
#define KEYBOARD_INPUT PS2_CLK, PS2_DAT
|
||||
|
||||
enum {
|
||||
BTN_INPUT,
|
||||
SW_INPUT,
|
||||
KEYBOARD_INPUT,
|
||||
NR_INPUT_PINS,
|
||||
NAIVE_LEDS_OUTPUT,
|
||||
RGB_LEDS_OUTPUT,
|
||||
SEG7_ENBS_OUTPUT,
|
||||
SEG7_SEGS_OUTPUT,
|
||||
VGA_OUTPUT,
|
||||
NR_PINS,
|
||||
NR_OUTPUT_PINS = NR_PINS - NR_INPUT_PINS
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue