diff --git a/c/test_programs/vga_fractional.c b/c/test_programs/vga_fractional.c new file mode 100644 index 00000000..1ffa3577 --- /dev/null +++ b/c/test_programs/vga_fractional.c @@ -0,0 +1,145 @@ +/* VGA Fractional Scaling demonstration + * + * How to compile: qvc vga_fractional.c conio.c -O3 -c99 + * + * done by MJoergen in November 2020 +*/ + +#include +#include "conio.h" + +//convenient mechanism to access QNICE's Memory Mapped IO registers +#define MMIO( __x ) *((unsigned int volatile *) __x ) + +const char text[73][30] = { + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + "It is a period of civil war.\0", + "Rebel spaceships, striking\0", + "from a hidden base, have won\0", + "their first victory against\0", + "the evil Galactic Empire.\0", + " \0", + "During the battle, Rebel\0", + "spies managed to steal secret\0", + "plans to the Empire's\0", + "ultimate weapon, the DEATH\0", + "STAR, an armored space\0", + "station with enough power to\0", + "destroy an entire planet.\0", + " \0", + "Pursued by the Empire's\0", + "sinister agents, Princess\0", + "Leia races home aboard her\0", + "starship, custodian of the\0", + "stolen plans that can save\0", + "her people and restore\0", + "freedom to the galaxy....\0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0", + " \0"}; + +int main() +{ + MMIO(VGA_STATE) &= ~VGA_EN_HW_CURSOR; // Disable hardware cursor. + qmon_vga_cls(); // Clear screen. + + int counter = 12*10; + int startline = 0; + while (1) + { + int dy = counter/10; // Scrolling speed of 6 pixels/second. + + if (counter >= 12*10) + { + counter = 0; + dy = 0; + MMIO(VGA_ADJUST_Y) = 0; + startline += 1; + + // Display text on screen + for (int y=0; y<26; ++y) + { + cputsxy(5, y+14, text[y+startline], 0); + } + } + MMIO(VGA_ADJUST_Y) = dy; + + int y; + while ((y = MMIO(VGA_SCAN_LINE)) >= 480) + {} + while ((y = MMIO(VGA_SCAN_LINE)) < 480) + { + y += dy; + MMIO(VGA_PIXEL_X_SCALE) = (20*256)/(y/12); + MMIO(VGA_ADJUST_X) = ((y-480)/12)*160/(y/12); + } + + if (MMIO(IO_UART_SRA) & 1) + { + unsigned int tmp = MMIO(IO_UART_RHRA); + break; + } + if (MMIO(IO_KBD_STATE) & KBD_NEW_ANY) + { + unsigned int tmp = MMIO(IO_KBD_DATA); + break; + } + + counter += 1; // Should increment once every frame, i.e. at 60 Hz. + } // while + + MMIO(VGA_PIXEL_X_SCALE) = 0x0100; + MMIO(VGA_PIXEL_Y_SCALE) = 0x0100; + MMIO(VGA_ADJUST_X) = 0; + MMIO(VGA_ADJUST_Y) = 0; + return 0; +} // int main() + diff --git a/c/vbcc/machines/qnice/sysdef.h b/c/vbcc/machines/qnice/sysdef.h index c633e945..d9c44981 100644 --- a/c/vbcc/machines/qnice/sysdef.h +++ b/c/vbcc/machines/qnice/sysdef.h @@ -199,6 +199,8 @@ #define VGA_PALETTE_OFFS 0xFF39 // Offset in words into the Palette RAM used for display #define VGA_PALETTE_ADDR 0xFF3A // Palette Address #define VGA_PALETTE_DATA 0xFF3B // Palette Data +#define VGA_PIXEL_X_SCALE 0xFF3C // Horizontal scaling in units of 256 +#define VGA_PIXEL_Y_SCALE 0xFF3D // Vertical scaling in units of 256 #define VGA_ADJUST_X 0xFF40 // Pixels to adjust screen in X direction #define VGA_ADJUST_Y 0xFF41 // Pixels to adjust screen in Y direction #define VGA_SCAN_LINE 0xFF42 // Current scan line diff --git a/monitor/sysdef.asm b/monitor/sysdef.asm index cf2673c7..a64b197b 100644 --- a/monitor/sysdef.asm +++ b/monitor/sysdef.asm @@ -208,6 +208,8 @@ VGA$FONT_DATA .EQU 0xFF38 ; Font Data VGA$PALETTE_OFFS .EQU 0xFF39 ; Offset in words into the Palette RAM used for display VGA$PALETTE_ADDR .EQU 0xFF3A ; Palette Address VGA$PALETTE_DATA .EQU 0xFF3B ; Palette Data +VGA$PIXEL_X_SCALE .EQU 0xFF3C ; Horizontal scaling in units of 256 +VGA$PIXEL_Y_SCALE .EQU 0xFF3D ; Vertical scaling in units of 256 VGA$ADJUST_X .EQU 0xFF40 ; Pixels to adjust screen in X direction VGA$ADJUST_Y .EQU 0xFF41 ; Pixels to adjust screen in Y direction VGA$SCAN_LINE .EQU 0xFF42 ; Current scan line diff --git a/vhdl/vga/Makefile b/vhdl/vga/Makefile index a56cfb1c..6fcbb9d2 100644 --- a/vhdl/vga/Makefile +++ b/vhdl/vga/Makefile @@ -18,10 +18,10 @@ SOURCES += ../vga_multicolor.vhd #TB = tb_vga_text_mode #TB_SOURCES = tb_vga_text_mode.vhd -TB = tb_vga_sprite -TB_SOURCES = tb_vga_sprite.vhd -#TB = tb_vga_multicolor -#TB_SOURCES = tb_vga_multicolor.vhd +#TB = tb_vga_sprite +#TB_SOURCES = tb_vga_sprite.vhd +TB = tb_vga_multicolor +TB_SOURCES = tb_vga_multicolor.vhd WAVE = $(TB).ghw SAVE = $(TB).gtkw @@ -30,6 +30,6 @@ SAVE = $(TB).gtkw sim: $(SOURCES) ghdl -i --work=work $(SOURCES) $(TB_SOURCES) ghdl -m --ieee=synopsys -fexplicit $(TB) - ghdl -r -fsynopsys $(TB) --wave=$(WAVE) --max-stack-alloc=1024 --stop-time=55us + ghdl -r --ieee=synopsys $(TB) --wave=$(WAVE) --max-stack-alloc=1024 --stop-time=55us gtkwave $(WAVE) $(SAVE) diff --git a/vhdl/vga/tb_vga_sprite.vhd b/vhdl/vga/tb_vga_sprite.vhd index c2aef58b..52bba01a 100644 --- a/vhdl/vga/tb_vga_sprite.vhd +++ b/vhdl/vga/tb_vga_sprite.vhd @@ -50,10 +50,14 @@ begin G_FRAME_COUNT => 60 ) port map ( - clk_i => clk, - pixel_x_o => pixel_x, - pixel_y_o => pixel_y, - frame_o => open + clk_i => clk, + pixel_scale_x_i => X"0100", + pixel_scale_y_i => X"0100", + buffer_pixel_x_o => pixel_x, + buffer_pixel_y_o => pixel_y, + monitor_pixel_x_o => pixel_x, + monitor_pixel_y_o => pixel_y, + monitor_frame_o => open ); -- i_vga_pixel_counters diff --git a/vhdl/vga/vga_output.vhd b/vhdl/vga/vga_output.vhd index 624051ab..4a69bc23 100644 --- a/vhdl/vga/vga_output.vhd +++ b/vhdl/vga/vga_output.vhd @@ -27,6 +27,8 @@ entity vga_output is cursor_x_i : in std_logic_vector(6 downto 0); -- 0 to 79 cursor_y_i : in std_logic_vector(5 downto 0); -- 0 to 39 pixel_y_o : out std_logic_vector(9 downto 0); -- 0 to 524 + pixel_scale_x_i : in std_logic_vector(15 downto 0); + pixel_scale_y_i : in std_logic_vector(15 downto 0); adjust_x_i : in std_logic_vector(9 downto 0); adjust_y_i : in std_logic_vector(9 downto 0); @@ -58,18 +60,21 @@ architecture synthesis of vga_output is constant H_PIXELS : integer := 640; constant V_PIXELS : integer := 480; - signal pixel_x : std_logic_vector(9 downto 0); -- 0 to 799 - signal pixel_y : std_logic_vector(9 downto 0); -- 0 to 524 - signal frame : std_logic_vector(5 downto 0); -- 0 to 59 - signal color_text : std_logic_vector(15 downto 0); - signal color_sprite : std_logic_vector(15 downto 0); - signal delay_text : std_logic_vector(9 downto 0); - signal delay_sprite : std_logic_vector(9 downto 0); - signal delay : std_logic_vector(9 downto 0); - signal pixel_x_text : std_logic_vector(9 downto 0); - signal pixel_y_text : std_logic_vector(9 downto 0); - signal pixel_x_sprite : std_logic_vector(9 downto 0); - signal pixel_y_sprite : std_logic_vector(9 downto 0); + signal buffer_pixel_x : std_logic_vector(9 downto 0); -- 0 to 799 + signal buffer_pixel_y : std_logic_vector(9 downto 0); -- 0 to 524 + signal monitor_pixel_x : std_logic_vector(9 downto 0); -- 0 to 799 + signal monitor_pixel_y : std_logic_vector(9 downto 0); -- 0 to 524 + signal monitor_frame : std_logic_vector(5 downto 0); -- 0 to 59 + + signal color_text : std_logic_vector(15 downto 0); + signal color_sprite : std_logic_vector(15 downto 0); + signal delay_text : std_logic_vector(9 downto 0); + signal delay_sprite : std_logic_vector(9 downto 0); + signal delay : std_logic_vector(9 downto 0); + signal pixel_x_text : std_logic_vector(9 downto 0); + signal pixel_y_text : std_logic_vector(9 downto 0); + signal pixel_x_sprite : std_logic_vector(9 downto 0); + signal pixel_y_sprite : std_logic_vector(9 downto 0); begin @@ -84,10 +89,14 @@ begin G_FRAME_COUNT => 60 ) port map ( - clk_i => clk_i, - pixel_x_o => pixel_x, - pixel_y_o => pixel_y, - frame_o => frame + clk_i => clk_i, + pixel_scale_x_i => pixel_scale_x_i, + pixel_scale_y_i => pixel_scale_y_i, + buffer_pixel_x_o => buffer_pixel_x, + buffer_pixel_y_o => buffer_pixel_y, + monitor_pixel_x_o => monitor_pixel_x, + monitor_pixel_y_o => monitor_pixel_y, + monitor_frame_o => monitor_frame ); -- i_vga_pixel_counters @@ -95,8 +104,8 @@ begin -- Instantiate Text Mode ------------------------- - pixel_x_text <= pixel_x + adjust_x_i; - pixel_y_text <= pixel_y + adjust_y_i; + pixel_x_text <= buffer_pixel_x + adjust_x_i; + pixel_y_text <= buffer_pixel_y + adjust_y_i; i_vga_text_mode : entity work.vga_text_mode port map ( @@ -113,7 +122,7 @@ begin -- Pixel Counters pixel_x_i => pixel_x_text, pixel_y_i => pixel_y_text, - frame_i => frame, + frame_i => monitor_frame, -- Interface to Video RAM display_addr_o => display_addr_o, display_data_i => display_data_i, @@ -131,8 +140,8 @@ begin -- Instantiate Sprites ----------------------- - pixel_x_sprite <= pixel_x - delay_text; - pixel_y_sprite <= pixel_y; + pixel_x_sprite <= buffer_pixel_x - delay_text; + pixel_y_sprite <= buffer_pixel_y; i_vga_sprite : entity work.vga_sprite generic map ( @@ -169,8 +178,8 @@ begin port map ( clk_i => clk_i, output_en_i => output_enable_i, - pixel_x_i => pixel_x, - pixel_y_i => pixel_y, + pixel_x_i => monitor_pixel_x, + pixel_y_i => monitor_pixel_y, color_i => color_sprite(14 downto 0), delay_i => delay, hsync_o => hsync_o, @@ -182,10 +191,10 @@ begin p_pixel_y : process (clk_i) begin if rising_edge(clk_i) then - pixel_y_o <= pixel_y; - if conv_integer(pixel_x) >= H_PIXELS then - pixel_y_o <= pixel_y+1; - if conv_integer(pixel_y) = 524 then + pixel_y_o <= monitor_pixel_y; + if conv_integer(monitor_pixel_x) >= H_PIXELS then + pixel_y_o <= monitor_pixel_y+1; + if conv_integer(monitor_pixel_y) = 524 then pixel_y_o <= (others => '0'); end if; end if; diff --git a/vhdl/vga/vga_pixel_counters.vhd b/vhdl/vga/vga_pixel_counters.vhd index 1b31b88a..7eadc8ac 100644 --- a/vhdl/vga/vga_pixel_counters.vhd +++ b/vhdl/vga/vga_pixel_counters.vhd @@ -16,18 +16,24 @@ entity vga_pixel_counters is G_FRAME_COUNT : integer ); port ( - clk_i : in std_logic; - pixel_x_o : out std_logic_vector(9 downto 0); - pixel_y_o : out std_logic_vector(9 downto 0); - frame_o : out std_logic_vector(5 downto 0) + clk_i : in std_logic; + pixel_scale_x_i : in std_logic_vector(15 downto 0); + pixel_scale_y_i : in std_logic_vector(15 downto 0); + buffer_pixel_x_o : out std_logic_vector(9 downto 0); + buffer_pixel_y_o : out std_logic_vector(9 downto 0); + monitor_pixel_x_o : out std_logic_vector(9 downto 0); + monitor_pixel_y_o : out std_logic_vector(9 downto 0); + monitor_frame_o : out std_logic_vector(5 downto 0) ); end vga_pixel_counters; architecture synthesis of vga_pixel_counters is - signal pixel_x : std_logic_vector(9 downto 0) := std_logic_vector(to_unsigned(600, 10)); - signal pixel_y : std_logic_vector(9 downto 0) := std_logic_vector(to_unsigned(524, 10)); - signal frame : std_logic_vector(5 downto 0) := (others => '0'); + signal buffer_pixel_x : std_logic_vector(17 downto 0) := std_logic_vector(to_unsigned(600*256, 18)); + signal buffer_pixel_y : std_logic_vector(17 downto 0) := std_logic_vector(to_unsigned(524*256, 18)); + signal monitor_pixel_x : std_logic_vector(9 downto 0) := std_logic_vector(to_unsigned(600, 10)); + signal monitor_pixel_y : std_logic_vector(9 downto 0) := std_logic_vector(to_unsigned(524, 10)); + signal monitor_frame : std_logic_vector(5 downto 0) := (others => '0'); begin @@ -36,12 +42,19 @@ begin ------------------------------------- p_pixel_x : process (clk_i) + variable sum : std_logic_vector(17 downto 0); begin if rising_edge(clk_i) then - if unsigned(pixel_x) = G_PIXEL_X_COUNT-1 then - pixel_x <= (others => '0'); + if unsigned(monitor_pixel_x) = G_PIXEL_X_COUNT-1 then + monitor_pixel_x <= (others => '0'); + buffer_pixel_x <= (others => '0'); else - pixel_x <= std_logic_vector(unsigned(pixel_x) + 1); + monitor_pixel_x <= std_logic_vector(unsigned(monitor_pixel_x) + 1); + + sum := std_logic_vector(unsigned(buffer_pixel_x) + unsigned("00" & pixel_scale_x_i)); + if sum > buffer_pixel_x then + buffer_pixel_x <= sum; + end if; end if; end if; end process p_pixel_x; @@ -52,13 +65,20 @@ begin ----------------------------------- p_pixel_y : process (clk_i) + variable sum : std_logic_vector(17 downto 0); begin if rising_edge(clk_i) then - if unsigned(pixel_x) = G_PIXEL_X_COUNT-1 then - if unsigned(pixel_y) = G_PIXEL_Y_COUNT-1 then - pixel_y <= (others => '0'); + if unsigned(monitor_pixel_x) = G_PIXEL_X_COUNT-1 then + if unsigned(monitor_pixel_y) = G_PIXEL_Y_COUNT-1 then + monitor_pixel_y <= (others => '0'); + buffer_pixel_y <= (others => '0'); else - pixel_y <= std_logic_vector(unsigned(pixel_y) + 1); + monitor_pixel_y <= std_logic_vector(unsigned(monitor_pixel_y) + 1); + + sum := std_logic_vector(unsigned(buffer_pixel_y) + unsigned("00" & pixel_scale_y_i)); + if sum > buffer_pixel_y then + buffer_pixel_y <= sum; + end if; end if; end if; end if; @@ -72,12 +92,12 @@ begin p_frame : process (clk_i) begin if rising_edge(clk_i) then - if unsigned(pixel_x) = G_PIXEL_X_COUNT-1 then - if unsigned(pixel_y) = G_PIXEL_Y_COUNT-1 then - if unsigned(frame) = G_FRAME_COUNT-1 then - frame <= (others => '0'); + if unsigned(monitor_pixel_x) = G_PIXEL_X_COUNT-1 then + if unsigned(monitor_pixel_y) = G_PIXEL_Y_COUNT-1 then + if unsigned(monitor_frame) = G_FRAME_COUNT-1 then + monitor_frame <= (others => '0'); else - frame <= std_logic_vector(unsigned(frame) + 1); + monitor_frame <= std_logic_vector(unsigned(monitor_frame) + 1); end if; end if; end if; @@ -89,9 +109,11 @@ begin -- Drive output signals ------------------------ - pixel_x_o <= pixel_x; - pixel_y_o <= pixel_y; - frame_o <= frame; + buffer_pixel_x_o <= buffer_pixel_x(17 downto 8); + buffer_pixel_y_o <= buffer_pixel_y(17 downto 8); + monitor_pixel_x_o <= monitor_pixel_x; + monitor_pixel_y_o <= monitor_pixel_y; + monitor_frame_o <= monitor_frame; end architecture synthesis; diff --git a/vhdl/vga/vga_register_map.vhd b/vhdl/vga/vga_register_map.vhd index 88958dfe..10ea390f 100644 --- a/vhdl/vga/vga_register_map.vhd +++ b/vhdl/vga/vga_register_map.vhd @@ -46,6 +46,8 @@ entity vga_register_map is display_offset_o : out std_logic_vector(15 downto 0); font_offset_o : out std_logic_vector(15 downto 0); palette_offset_o : out std_logic_vector(15 downto 0); + pixel_scale_x_o : out std_logic_vector(15 downto 0); + pixel_scale_y_o : out std_logic_vector(15 downto 0); adjust_x_o : out std_logic_vector(9 downto 0); adjust_y_o : out std_logic_vector(9 downto 0); pixel_y_i : in std_logic_vector(9 downto 0) @@ -67,6 +69,8 @@ architecture synthesis of vga_register_map is constant C_REG_PALETTE_OFFSET : integer := 9; constant C_REG_PALETTE_ADDRESS : integer := 10; constant C_REG_PALETTE_DATA : integer := 11; + constant C_REG_PIXEL_X_SCALE : integer := 12; + constant C_REG_PIXEL_Y_SCALE : integer := 13; constant C_REG_ADJUST_X : integer := 16; constant C_REG_ADJUST_Y : integer := 17; constant C_REG_SCAN_CURRENT : integer := 18; @@ -175,6 +179,8 @@ begin if rst_i = '1' then register_map <= (others => (others => '0')); register_map(C_REG_SCAN_INTERRUPT)(15) <= '1'; -- Disable scanline interrupt + register_map(C_REG_PIXEL_X_SCALE) <= X"0100"; + register_map(C_REG_PIXEL_Y_SCALE) <= X"0100"; end if; end if; end process p_register_map; @@ -210,6 +216,8 @@ begin cursor_y_o <= cursor_y; adjust_x_o <= register_map(C_REG_ADJUST_X)(9 downto 0); adjust_y_o <= register_map(C_REG_ADJUST_Y)(9 downto 0); + pixel_scale_x_o <= register_map(C_REG_PIXEL_X_SCALE); + pixel_scale_y_o <= register_map(C_REG_PIXEL_Y_SCALE); display_offset_o <= display_offset; font_offset_o <= register_map(C_REG_FONT_OFFSET); diff --git a/vhdl/vga/vga_text_mode.vhd b/vhdl/vga/vga_text_mode.vhd index 8893d51c..043f4b1e 100644 --- a/vhdl/vga/vga_text_mode.vhd +++ b/vhdl/vga/vga_text_mode.vhd @@ -133,7 +133,7 @@ begin -- Decode value read from Display RAM stage1.color_bg <= display_data_i(15 downto 12); stage1.color_fg <= display_data_i(11 downto 8); - stage1.tile <= display_data_i(7 downto 0); + stage1.tile <= display_data_i(7 downto 0); -- Just copy char_offset_y because it is constant during a raster line. stage1.char_offset_y <= stage0.char_offset_y; @@ -180,7 +180,8 @@ begin stage2.bitmap_index <= C_CHAR_WIDTH-1 - stage2.char_offset_x; -- Get pixel from font bitmap - stage2.font_pixel <= stage2.bitmap(stage2.bitmap_index); + stage2.font_pixel <= stage2.bitmap(stage2.bitmap_index) when stage2.char_column < 80 and stage2.char_row < 40 else + '0'; -- Generate cursor blink frequency (2 Hz). stage2.cursor_blink <= std_logic_vector(unsigned(frame_i) / 15); diff --git a/vhdl/vga_multicolor.vhd b/vhdl/vga_multicolor.vhd index 0f69766f..e4882771 100644 --- a/vhdl/vga_multicolor.vhd +++ b/vhdl/vga_multicolor.vhd @@ -67,6 +67,8 @@ architecture synthesis of vga_multicolor is signal cpu_cursor_x : std_logic_vector(6 downto 0); signal cpu_cursor_y : std_logic_vector(5 downto 0); signal cpu_pixel_y : std_logic_vector(9 downto 0); + signal cpu_pixel_scale_x : std_logic_vector(15 downto 0); + signal cpu_pixel_scale_y : std_logic_vector(15 downto 0); signal cpu_adjust_x : std_logic_vector(9 downto 0); signal cpu_adjust_y : std_logic_vector(9 downto 0); @@ -97,6 +99,8 @@ architecture synthesis of vga_multicolor is signal meta_cursor_x : std_logic_vector(6 downto 0); signal meta_cursor_y : std_logic_vector(5 downto 0); signal meta_pixel_y : std_logic_vector(9 downto 0); + signal meta_pixel_scale_x : std_logic_vector(15 downto 0); + signal meta_pixel_scale_y : std_logic_vector(15 downto 0); signal meta_adjust_x : std_logic_vector(9 downto 0); signal meta_adjust_y : std_logic_vector(9 downto 0); @@ -112,6 +116,8 @@ architecture synthesis of vga_multicolor is signal vga_cursor_x : std_logic_vector(6 downto 0); signal vga_cursor_y : std_logic_vector(5 downto 0); signal vga_pixel_y : std_logic_vector(9 downto 0); + signal vga_pixel_scale_x : std_logic_vector(15 downto 0); + signal vga_pixel_scale_y : std_logic_vector(15 downto 0); signal vga_adjust_x : std_logic_vector(9 downto 0); signal vga_adjust_y : std_logic_vector(9 downto 0); @@ -141,6 +147,8 @@ architecture synthesis of vga_multicolor is attribute ASYNC_REG of meta_cursor_size : signal is true; attribute ASYNC_REG of meta_cursor_x : signal is true; attribute ASYNC_REG of meta_cursor_y : signal is true; + attribute ASYNC_REG of meta_pixel_scale_x : signal is true; + attribute ASYNC_REG of meta_pixel_scale_y : signal is true; attribute ASYNC_REG of meta_adjust_x : signal is true; attribute ASYNC_REG of meta_adjust_y : signal is true; attribute ASYNC_REG of meta_pixel_y : signal is true; @@ -154,6 +162,8 @@ architecture synthesis of vga_multicolor is attribute ASYNC_REG of vga_cursor_size : signal is true; attribute ASYNC_REG of vga_cursor_x : signal is true; attribute ASYNC_REG of vga_cursor_y : signal is true; + attribute ASYNC_REG of vga_pixel_scale_x : signal is true; + attribute ASYNC_REG of vga_pixel_scale_y : signal is true; attribute ASYNC_REG of vga_adjust_x : signal is true; attribute ASYNC_REG of vga_adjust_y : signal is true; attribute ASYNC_REG of cpu_pixel_y : signal is true; @@ -209,6 +219,8 @@ begin display_offset_o => cpu_display_offset, -- Reg 5 font_offset_o => cpu_font_offset, -- Reg 6 palette_offset_o => cpu_palette_offset, -- Reg 9 + pixel_scale_x_o => cpu_pixel_scale_x, -- Reg 12 + pixel_scale_y_o => cpu_pixel_scale_y, -- Reg 13 adjust_x_o => cpu_adjust_x, -- Reg 16 adjust_y_o => cpu_adjust_y, -- Reg 17 pixel_y_i => cpu_pixel_y -- Reg 18 @@ -278,6 +290,8 @@ begin meta_cursor_size <= cpu_cursor_size; meta_cursor_x <= cpu_cursor_x; meta_cursor_y <= cpu_cursor_y; + meta_pixel_scale_x <= cpu_pixel_scale_x; + meta_pixel_scale_y <= cpu_pixel_scale_y; meta_adjust_x <= cpu_adjust_x; meta_adjust_y <= cpu_adjust_y; @@ -291,6 +305,8 @@ begin vga_cursor_size <= meta_cursor_size; vga_cursor_x <= meta_cursor_x; vga_cursor_y <= meta_cursor_y; + vga_pixel_scale_x <= meta_pixel_scale_x; + vga_pixel_scale_y <= meta_pixel_scale_y; vga_adjust_x <= meta_adjust_x; vga_adjust_y <= meta_adjust_y; end if; @@ -330,6 +346,8 @@ begin cursor_x_i => vga_cursor_x, cursor_y_i => vga_cursor_y, pixel_y_o => vga_pixel_y, + pixel_scale_x_i => vga_pixel_scale_x, + pixel_scale_y_i => vga_pixel_scale_y, adjust_x_i => vga_adjust_x, adjust_y_i => vga_adjust_y,