aboutsummaryrefslogtreecommitdiff
path: root/vga-hacks
diff options
context:
space:
mode:
authorgithub-classroom[bot] <66690702+github-classroom[bot]@users.noreply.github.com>2026-02-05 19:36:36 +0000
committerGitHub <noreply@github.com>2026-02-05 19:36:36 +0000
commitead28dd6fed440ccf4667c459778012bb0d95733 (patch)
treebbc326fa1b487efc0fe163ef733a76c8a241fbb0 /vga-hacks
Initial commit
Diffstat (limited to '')
-rw-r--r--vga-hacks/vga_adapter_sim.sv22
-rw-r--r--vga-hacks/vga_adapter_window.sv24
-rw-r--r--vga-hacks/vga_window.tcl85
3 files changed, 131 insertions, 0 deletions
diff --git a/vga-hacks/vga_adapter_sim.sv b/vga-hacks/vga_adapter_sim.sv
new file mode 100644
index 0000000..1fb0142
--- /dev/null
+++ b/vga-hacks/vga_adapter_sim.sv
@@ -0,0 +1,22 @@
+// For simulation only
+
+module vga_adapter(input logic resetn, input logic clock, input logic [2:0] colour,
+ input logic [7:0] x, input logic [6:0] y, input logic plot,
+ output logic [9:0] VGA_R, output logic [9:0] VGA_G, output logic [9:0] VGA_B,
+ output logic VGA_HS, output logic VGA_VS, output logic VGA_BLANK,
+ output logic VGA_SYNC, output logic VGA_CLK);
+ parameter BITS_PER_COLOUR_CHANNEL = 1;
+ parameter MONOCHROME = "FALSE";
+ parameter RESOLUTION = "320x240";
+ parameter BACKGROUND_IMAGE = "background.mif";
+ parameter USING_DE1 = "FALSE";
+
+ always_ff @(posedge clock, negedge resetn) begin
+ if (~resetn) begin
+ $display("VGA: reset");
+ end else if (plot) begin
+ $display("VGA: plot (%d,%d) colour %03b", x, y, colour);
+ end
+ end
+endmodule: vga_adapter
+
diff --git a/vga-hacks/vga_adapter_window.sv b/vga-hacks/vga_adapter_window.sv
new file mode 100644
index 0000000..278903c
--- /dev/null
+++ b/vga-hacks/vga_adapter_window.sv
@@ -0,0 +1,24 @@
+// For simulation only
+
+module vga_adapter(input logic resetn, input logic clock, input logic [2:0] colour,
+ input logic [7:0] x, input logic [6:0] y, input logic plot,
+ output logic [9:0] VGA_R, output logic [9:0] VGA_G, output logic [9:0] VGA_B,
+ output logic VGA_HS, output logic VGA_VS, output logic VGA_BLANK,
+ output logic VGA_SYNC, output logic VGA_CLK);
+ parameter BITS_PER_COLOUR_CHANNEL = 1;
+ parameter MONOCHROME = "FALSE";
+ parameter RESOLUTION = "320x240";
+ parameter BACKGROUND_IMAGE = "background.mif";
+ parameter USING_DE1 = "FALSE";
+
+ always_ff @(posedge clock, negedge resetn) begin
+ if (!resetn) begin
+ void'(mti_fli::mti_Cmd("vga::reset"));
+ end else if (plot) begin
+ if ((^x === 1'bx) || (^y === 1'bx) || (^colour === 1'bx))
+ $error("cannot plot undefined values");
+ else
+ void'(mti_fli::mti_Cmd($sformatf("vga::plot %d %d %d", x, y, colour)));
+ end
+ end
+endmodule: vga_adapter
diff --git a/vga-hacks/vga_window.tcl b/vga-hacks/vga_window.tcl
new file mode 100644
index 0000000..5ad7aaf
--- /dev/null
+++ b/vga-hacks/vga_window.tcl
@@ -0,0 +1,85 @@
+namespace eval vga {
+ set zoom 4
+ set width 160
+ set height 120
+ set bg "#808080"
+ set count 0
+}
+
+proc vga::init {} {
+ toplevel .vga -padx 5 -pady 5
+ wm title .vga "fake VGA screen"
+
+ frame .vga.draw
+ pack .vga.draw -expand 1 -fill both
+
+ frame .vga.status
+ button .vga.status.reset -width 5 -relief ridge -text "reset" -command { vga::reset }
+ label .vga.status.count_legend -text " count:"
+ label .vga.status.count_val -relief groove -width 10
+
+ label .vga.status.drawn_legend -text "last:"
+ label .vga.status.drawn_pos -relief groove -width 7
+ label .vga.status.click_legend -text " clicked:"
+ label .vga.status.click_pos -relief groove -width 7
+ label .vga.status.mouse_legend -text " mouse:"
+ label .vga.status.mouse_pos -relief groove -width 7
+ pack .vga.status.reset .vga.status.count_legend .vga.status.count_val -side left
+ pack .vga.status.mouse_pos .vga.status.mouse_legend .vga.status.click_pos .vga.status.click_legend \
+ .vga.status.drawn_pos .vga.status.drawn_legend -side right
+ pack .vga.status -side bottom -fill x
+ .vga.status.drawn_pos configure -text "-,-"
+ .vga.status.mouse_pos configure -text "-,-"
+ .vga.status.click_pos configure -text "-,-"
+
+ set w [expr $vga::width * $vga::zoom]
+ set h [expr {$vga::height * $vga::zoom}]
+ canvas .vga.draw.c -width $w -height $h -bg $vga::bg
+ pack .vga.draw.c -expand 1 -fill both
+ bind .vga.draw.c <Motion> { vga::show_mouse %x %y }
+ bind .vga.draw.c <ButtonPress> { vga::show_click %x %y }
+ bind .vga.draw.c <Leave> { .vga.status.mouse_pos configure -text "-,-" }
+}
+
+proc vga::reset {} {
+ .vga.draw.c create rectangle 0 0 [expr $vga::width * $vga::zoom - 1] [expr $vga::height * $vga::zoom - 1] -outline $vga::bg -fill $vga::bg
+ set vga::count 0
+ .vga.status.count_val configure -text "$vga::count"
+ .vga.status.drawn_pos configure -text "-,-"
+}
+
+proc vga::rgb_to_hex {c} {
+ set b [expr ($c & 1) * 255]
+ set g [expr (($c >> 1) & 1) * 255]
+ set r [expr (($c >> 2) & 1) * 255]
+ return [format "#%02x%02x%02x" $r $g $b]
+}
+
+proc vga::plot {x y c} {
+ if {[expr $x < 0]} { return }
+ if {[expr $x >= $vga::width]} { return }
+ if {[expr $y < 0]} { return }
+ if {[expr $y >= $vga::height]} { return }
+ if !({[winfo exists .vga]}) {vga::init}
+ set x0 [expr $x * $vga::zoom]
+ set y0 [expr $y * $vga::zoom]
+ set x1 [expr ($x+1) * $vga::zoom - 1]
+ set y1 [expr ($y+1) * $vga::zoom - 1]
+ set clr [vga::rgb_to_hex $c]
+ .vga.draw.c create rectangle $x0 $y0 $x1 $y1 -outline $clr -fill $clr
+ incr vga::count
+ .vga.status.count_val configure -text "$vga::count"
+ .vga.status.drawn_pos configure -text "$x,$y:$c"
+}
+
+proc vga::show_mouse {x0 y0} {
+ set x [expr $x0 / $vga::zoom]
+ set y [expr $y0 / $vga::zoom]
+ .vga.status.mouse_pos configure -text "$x,$y"
+}
+
+proc vga::show_click {x0 y0} {
+ set x [expr $x0 / $vga::zoom]
+ set y [expr $y0 / $vga::zoom]
+ .vga.status.click_pos configure -text "$x,$y"
+}