@@ -50,7 +50,7 @@ package vga_pkg is
50
50
type vga_control_registers_interface is record
51
51
crx: std_ulogic_vector (6 downto 0 ); -- Cursor position X
52
52
cry: std_ulogic_vector (5 downto 0 ); -- Cursor position Y
53
- ctl: std_ulogic_vector (4 downto 0 ); -- Control register
53
+ ctl: std_ulogic_vector (5 downto 0 ); -- Control register
54
54
end record ;
55
55
56
56
constant vga_control_registers_initialize: vga_control_registers_interface := (
@@ -75,6 +75,7 @@ package vga_pkg is
75
75
vga_din: in std_ulogic_vector (15 downto 0 );
76
76
vga_addr: in std_ulogic_vector (12 downto 0 );
77
77
base: in std_ulogic_vector (12 downto 0 );
78
+ raw_do: out std_ulogic_vector (15 downto 0 );
78
79
79
80
-- VGA control registers
80
81
i_font_sel: in std_ulogic_vector (0 downto 0 );
@@ -97,7 +98,7 @@ package vga_pkg is
97
98
--
98
99
ocrx: in std_ulogic_vector (6 downto 0 );
99
100
ocry: in std_ulogic_vector (5 downto 0 );
100
- octl: in std_ulogic_vector (4 downto 0 );
101
+ octl: in std_ulogic_vector (5 downto 0 );
101
102
--
102
103
o_vga: out vga_physical_interface);
103
104
end component ;
@@ -134,7 +135,12 @@ package vga_pkg is
134
135
char: in std_ulogic_vector (7 downto 0 );
135
136
136
137
busy: out std_ulogic ;
137
- o_vga: out vga_physical_interface);
138
+ o_vga: out vga_physical_interface;
139
+
140
+ raw_addr_we: in std_ulogic ;
141
+ raw_data_we: in std_ulogic ;
142
+ raw_di: in std_ulogic_vector (15 downto 0 );
143
+ raw_do: out std_ulogic_vector (15 downto 0 ));
138
144
end component ;
139
145
140
146
-- VGA test bench, not-synthesizeable
@@ -217,7 +223,12 @@ begin
217
223
we => we,
218
224
char => char,
219
225
busy => busy,
220
- o_vga => physical);
226
+ o_vga => physical,
227
+
228
+ raw_addr_we => '0' ,
229
+ raw_data_we => '0' ,
230
+ raw_di => x"0000" ,
231
+ raw_do => open );
221
232
222
233
stimulus_process : process
223
234
begin
@@ -395,7 +406,12 @@ entity vt100 is
395
406
char: in std_ulogic_vector (7 downto 0 );
396
407
397
408
busy: out std_ulogic ;
398
- o_vga: out vga_physical_interface);
409
+ o_vga: out vga_physical_interface;
410
+
411
+ raw_addr_we: in std_ulogic ;
412
+ raw_data_we: in std_ulogic ;
413
+ raw_di: in std_ulogic_vector (15 downto 0 );
414
+ raw_do: out std_ulogic_vector (15 downto 0 ));
399
415
end entity ;
400
416
401
417
-- A better way of structuring this would be to process numbers in parallel
@@ -424,7 +440,7 @@ architecture rtl of vt100 is
424
440
constant lsqb: unsigned (char'range ) := x"5b" ; -- '['
425
441
constant ascii_c: unsigned (char'range ) := x"63" ; -- 'c'
426
442
constant attr_default: unsigned (7 downto 0 ) := "00111000" ;
427
- constant ctl_default: unsigned (4 downto 0 ) := "01111 " ;
443
+ constant ctl_default: unsigned (5 downto 0 ) := "001111 " ;
428
444
429
445
signal addr: std_ulogic_vector (12 downto 0 ) := (others => '0' );
430
446
signal data_we: std_ulogic := '0' ;
@@ -479,7 +495,23 @@ architecture rtl of vt100 is
479
495
480
496
signal saved_base_n, saved_base_c: unsigned (base_c'range ) := (others => '0' );
481
497
signal is_base_saved_n, is_base_saved_c: boolean := false ;
498
+
499
+ signal raw_addr: std_ulogic_vector (addr'range ) := (others => '0' );
500
+ signal raw_data: std_ulogic_vector (raw_di'range ) := (others => '0' );
501
+ signal raw_data_we_delayed: std_ulogic := '0' ;
482
502
begin
503
+ raw_data_reg: work.util.reg
504
+ generic map (g => g, N => raw_di'length )
505
+ port map (clk => clk, rst => rst, di => raw_di, we => raw_data_we, do => raw_data);
506
+ raw_addr_reg_we: work.util.reg
507
+ generic map (g => g, N => 1 )
508
+ port map (clk => clk, rst => rst, di(0 ) => raw_addr_we, we => '1' , do(0 ) => raw_data_we_delayed);
509
+
510
+ -- NB. Auto increment feature on addr might be useful
511
+ raw_addr_reg: work.util.reg
512
+ generic map (g => g, N => raw_addr'length )
513
+ port map (clk => clk, rst => rst, di => raw_di(raw_addr'range ), we => raw_addr_we, do => raw_addr);
514
+
483
515
accumulator_0: work.vga_pkg.atoi
484
516
generic map (g => g, N => number)
485
517
port map (
@@ -496,11 +528,13 @@ begin
496
528
address : block
497
529
signal mul: unsigned (15 downto 0 ) := (others => '0' );
498
530
signal addr_int: unsigned (addr'range ) := (others => '0' );
531
+ signal addr_cooked: std_ulogic_vector (addr'range ) := (others => '0' );
499
532
begin
500
533
mul <= to_unsigned (to_integer (y_c) * width , mul'length );
501
534
addr_int <= mul(addr_int'range ) + ("000000" & x_c);
502
535
addr_sel <= addr_int when state_c /= ERASING else count_c;
503
- addr <= std_ulogic_vector (addr_sel + (base_c & "0000" ));
536
+ addr_cooked <= std_ulogic_vector (addr_sel + (base_c & "0000" ));
537
+ addr <= addr_cooked when ctl_c(5 ) = '0' else raw_addr;
504
538
end block ;
505
539
506
540
x_minus_one <= x_c - 1 ;
@@ -531,28 +565,31 @@ begin
531
565
signal vga_ctr: vga_control_registers_interface := vga_control_registers_initialize;
532
566
signal attr: unsigned (attr_c'range ) := attr_default;
533
567
signal ch: std_ulogic_vector (c_c'range ) := (others => '0' );
568
+ signal top_we: std_ulogic := '0' ;
534
569
begin
535
570
ch <= std_ulogic_vector (asterisk) when conceal_c else std_ulogic_vector (c_c);
536
571
attr <= attr_c when state_c /= ERASING else attr_default;
537
- vga_din <= std_ulogic_vector (attr) & ch;
572
+ vga_din <= std_ulogic_vector (attr) & ch when ctl_c( 5 ) = '0' else raw_data ;
538
573
vga_ctr.crx <= std_ulogic_vector (x_plus_one); -- not limited, goes off screen edge
539
574
vga_ctr.cry <= std_ulogic_vector (y_c);
540
575
vga_ctr.ctl <= std_ulogic_vector (ctl_c);
541
576
vga_ctr_we.crx <= cursor_we;
542
577
vga_ctr_we.cry <= cursor_we;
543
578
vga_ctr_we.ctl <= cursor_we;
579
+ top_we <= data_we when ctl_c(5 ) = '0' else raw_data_we_delayed;
544
580
545
581
vga_0: work.vga_pkg.vga_top
546
582
generic map (g => g)
547
583
port map (
548
584
clk => clk,
549
585
clk25MHz => clk25MHz,
550
586
rst => rst,
551
- vga_we_ram => data_we ,
587
+ vga_we_ram => top_we ,
552
588
vga_din => vga_din,
553
589
vga_addr => addr,
554
590
base(base_c'range )=> std_ulogic_vector (base_c),
555
591
base(3 downto 0 ) => "0000" ,
592
+ raw_do => raw_do,
556
593
i_font_sel => font_sel_c,
557
594
i_vga_control_we => vga_ctr_we,
558
595
i_vga_control => vga_ctr,
@@ -762,6 +799,15 @@ begin
762
799
when x"6d" => -- CSI n 'm' : SGR
763
800
state_n <= ATTRIB;
764
801
802
+ when x"68" =>
803
+ if n1_c = X"02" then -- 80x40 (in MS-DOS it is 80x25)
804
+ ctl_n(5 ) <= '0' ;
805
+ elsif n1_c = X"05" then -- 320x200 monochrome
806
+ ctl_n(5 ) <= '1' ;
807
+ else
808
+ -- unsupported mode
809
+ end if ;
810
+ state_n <= ACCEPT;
765
811
-- NB. Number parameter does nothing.
766
812
when x"53" => -- CSI n 'S' : scroll up
767
813
saved_base_n <= base_c;
@@ -903,6 +949,7 @@ begin
903
949
when x"2D" => reverse_video("101" , false );
904
950
when x"2E" => reverse_video("110" , false );
905
951
when x"2F" => reverse_video("111" , false );
952
+
906
953
when others =>
907
954
end case ;
908
955
state_n <= ACCEPT;
@@ -938,6 +985,7 @@ entity vga_top is
938
985
vga_din: in std_ulogic_vector (15 downto 0 );
939
986
vga_addr: in std_ulogic_vector (12 downto 0 );
940
987
base: in std_ulogic_vector (12 downto 0 );
988
+ raw_do: out std_ulogic_vector (15 downto 0 );
941
989
942
990
-- VGA control registers
943
991
i_font_sel: in std_ulogic_vector (0 downto 0 );
@@ -1039,7 +1087,7 @@ begin
1039
1087
a_dre => '1' ,
1040
1088
a_addr => vga_addr,
1041
1089
a_din => vga_din,
1042
- a_dout => open ,
1090
+ a_dout => raw_do ,
1043
1091
-- Internal interface
1044
1092
b_clk => clk25MHz,
1045
1093
b_dwe => '0' ,
@@ -1087,7 +1135,7 @@ entity vga_core is
1087
1135
--
1088
1136
ocrx: in std_ulogic_vector (6 downto 0 );
1089
1137
ocry: in std_ulogic_vector (5 downto 0 );
1090
- octl: in std_ulogic_vector (4 downto 0 );
1138
+ octl: in std_ulogic_vector (5 downto 0 );
1091
1139
--
1092
1140
o_vga: out vga_physical_interface);
1093
1141
end entity ;
@@ -1126,12 +1174,15 @@ architecture rtl of vga_core is
1126
1174
1127
1175
signal bell_c, bell_n: std_ulogic := '0' ;
1128
1176
signal bell_on_c, bell_on_n: std_ulogic := '0' ;
1177
+
1178
+ signal raw_mode: std_ulogic := '0' ;
1129
1179
begin
1130
1180
-- Control register. Individual control signal
1131
1181
bell_n <= octl(4 );
1132
1182
bell <= bell_c xor bell_n;
1133
1183
vga_en <= octl(3 );
1134
- cur_en <= octl(2 );
1184
+ raw_mode <= octl(5 );
1185
+ cur_en <= octl(2 ) and not raw_mode;
1135
1186
cur_blink <= octl(1 );
1136
1187
cur_mode <= octl(0 );
1137
1188
@@ -1205,7 +1256,7 @@ begin
1205
1256
-- Proboscide99 31/08/08
1206
1257
blank <= '0' when (hctr < 8 ) or (hctr > 647 ) or (vctr > 479 ) else '1' ;
1207
1258
1208
- -- flip-flips for sync of R, G y B signal, initialized with '0'
1259
+ -- flip-flops for sync of R, G y B signal, initialized with '0'
1209
1260
process (rst, clk25MHz)
1210
1261
begin
1211
1262
if rst = '1' and g.asynchronous_reset then
0 commit comments