summaryrefslogtreecommitdiff
path: root/tb/vga.impl.hpp
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2022-12-12 14:34:05 -0600
committerAlejandro Soto <alejandro@34project.org>2022-12-16 16:29:10 -0600
commit02712d69cdd859d702cc7577e72db27d6f0c9ad5 (patch)
tree01d0c36111a99f596588816a2529f661ba56d023 /tb/vga.impl.hpp
parent397245139af754af07e61a10a91fdc9b9e72153f (diff)
Implement fast video
Diffstat (limited to 'tb/vga.impl.hpp')
-rw-r--r--tb/vga.impl.hpp73
1 files changed, 69 insertions, 4 deletions
diff --git a/tb/vga.impl.hpp b/tb/vga.impl.hpp
index 9c3294c..988259a 100644
--- a/tb/vga.impl.hpp
+++ b/tb/vga.impl.hpp
@@ -11,6 +11,8 @@
#include <SDL2/SDL_surface.h>
#include <SDL2/SDL_video.h>
+#include "avalon.hpp"
+
namespace
{
// https://web.mit.edu/6.111/www/s2004/NEWKIT/vga.shtml
@@ -35,10 +37,26 @@ namespace
namespace taller::vga
{
template<class Crtc>
- display<Crtc>::display(Crtc &crtc, std::uint32_t clock_hz) noexcept
- : crtc(crtc),
+ display<Crtc>::display(Crtc &crtc, std::uint32_t base, std::uint32_t clock_hz, std::uint32_t bus_hz) noexcept
+ : avalon::slave(base, 64 << 20, 4),
+ crtc(crtc),
clock_hz(clock_hz)
- {}
+ {
+ if(bus_hz > 0)
+ {
+ mode = &MODES[0];
+ max_addr = mode->h.active * mode->v.active;
+
+ refresh_ticks =
+ static_cast<float>(bus_hz)
+ / mode->pixel_clk
+ * (mode->h.active + mode->h.front_porch + mode->h.sync + mode->h.back_porch)
+ * (mode->v.active + mode->v.front_porch + mode->v.sync + mode->v.back_porch);
+
+ ticks = refresh_ticks - 1;
+ update_window();
+ }
+ }
template<class Crtc>
display<Crtc>::~display() noexcept
@@ -48,7 +66,54 @@ namespace taller::vga
}
template<class Crtc>
- void display<Crtc>::tick(bool clk) noexcept
+ void display<Crtc>::tick() noexcept
+ {
+ if(++ticks == refresh_ticks)
+ {
+ ticks = 0;
+ if(!window)
+ {
+ update_window();
+ }
+
+ if(window)
+ {
+ ::SDL_UpdateWindowSurface(window);
+ }
+ }
+ }
+
+ template<class Crtc>
+ bool display<Crtc>::read(std::uint32_t addr, std::uint32_t &data) noexcept
+ {
+ return true;
+ }
+
+ template<class Crtc>
+ bool display<Crtc>::write(std::uint32_t addr, std::uint32_t data, unsigned byte_enable) noexcept
+ {
+ if(!window || !mode)
+ {
+ return true;
+ }
+
+ auto *surface = ::SDL_GetWindowSurface(window);
+ if(!surface)
+ {
+ return true;
+ }
+
+ auto *pixels = static_cast<std::uint32_t*>(surface->pixels);
+ if(addr < max_addr)
+ {
+ pixels[addr] = data;
+ }
+
+ return true;
+ }
+
+ template<class Crtc>
+ void display<Crtc>::signal_tick(bool clk) noexcept
{
if(!clk)
{