Added Cassette Overlay

This commit is contained in:
Alan Steremberg
2022-02-06 11:41:52 -08:00
parent ba9a182e93
commit a1ef69cc2a
10 changed files with 496 additions and 8 deletions

View File

@@ -552,7 +552,11 @@ ElectronFpga_core Electron
.joystick2_x( acorn_ajoy2[7:0]),
.joystick2_y( acorn_ajoy2[15:8]),
.joystick2_fire(acorn_joy2[4])
.joystick2_fire(acorn_joy2[4]),
.h_cnt(h_cnt),
.v_cnt(v_cnt)
/*
.m128_mode(m128),
.copro_mode(|status[6:5])*/
@@ -601,9 +605,9 @@ video_mixer #(.GAMMA(1)) video_mixer
.hq2x(scale==1),
.R({r,r}),
.G({g,g}),
.B({b,b}),
.R(o_r),
.G(o_g),
.B(o_b),
.HSync(hs),
.VSync(vs),
@@ -772,6 +776,35 @@ cassette cassette(
// .status(tape_status)
);
wire [10:0] h_cnt;
wire [9:0] v_cnt;
wire [7:0] o_r;
wire [7:0] o_g;
wire [7:0] o_b;
overlay #( .RGB(24'hEEEE22) ) overlay
(
.reset(reset),
.i_r({r,r}),
.i_g({g,g}),
.i_b({b,b}),
.i_clk(clk_64/*clk_sys*/),
.i_pix(ce_pix2),
.hcnt(h_cnt[9:0]),
.vcnt(v_cnt),
.o_r(o_r),
.o_g(o_g),
.o_b(o_b),
.pos(sdram_addr),
.max(tape_end),
.ena(cas_relay)
);
endmodule

View File

@@ -1,4 +1,5 @@
set_global_assignment -name VHDL_FILE rtl/ps2kybrd/keyboard.vhd
set_global_assignment -name QIP_FILE rtl/cassetteoverlay/cassetteoverlay.qip
set_global_assignment -name VHDL_FILE rtl/T6502/T65_Pack.vhd
set_global_assignment -name VHDL_FILE rtl/T6502/T65_MCode.vhd
set_global_assignment -name VHDL_FILE rtl/T6502/T65_ALU.vhd

View File

@@ -96,7 +96,9 @@ entity ElectronFpga_core is
joystick1_fire : in std_logic;
joystick2_x : in std_logic_vector(7 downto 0);
joystick2_y : in std_logic_vector(7 downto 0);
joystick2_fire : in std_logic
joystick2_fire : in std_logic;
h_cnt: out std_logic_vector(10 downto 0);
v_cnt: out std_logic_vector( 9 downto 0)
);
end;
@@ -226,7 +228,10 @@ begin
joystick1_fire =>joystick1_fire,
joystick2_x =>joystick2_x,
joystick2_y =>joystick2_y,
joystick2_fire =>joystick2_fire
joystick2_fire =>joystick2_fire,
h_cnt => h_cnt,
v_cnt => v_cnt
);

View File

@@ -93,7 +93,11 @@ entity ElectronULA is
joystick1_fire : in std_logic;
joystick2_x : in std_logic_vector(7 downto 0);
joystick2_y : in std_logic_vector(7 downto 0);
joystick2_fire : in std_logic
joystick2_fire : in std_logic;
h_cnt: out std_logic_vector(10 downto 0);
v_cnt: out std_logic_vector( 9 downto 0)
);
end;
@@ -1134,7 +1138,8 @@ begin
blue <= (others => ttxt_b_out) when mode7_enable = '1' else
blue_int;
h_cnt<=h_count;
v_cnt<=v_count;
-- alanswx -- for some reason this code set's vsync to 1 when it is in
-- 15khz mode, which breaks the MiSTer scaler. For now we are just going to
-- get rid of the logic.

View File

@@ -0,0 +1,52 @@
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00
00 95 83 83 83 83 83 83 83 83 83 83 83 83 83 83 83 83 83 83 83 83 89
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00
00 87 97 00 a6 a6 a6 a6 a6 a6 a6 a6 a6 a6 a6 a6 a6 a6 a6 a6 00 97 88
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00
00 87 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 88
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00
00 87 00 00 00 00 95 83 89 00 00 00 00 00 00 95 83 89 00 00 00 00 88
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00
00 87 00 00 00 00 87 2a 88 00 00 00 00 00 00 87 96 88 00 00 00 00 88
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00
00 87 00 00 00 00 8A 83 8B 00 00 00 00 00 00 8A 83 8B 00 00 00 00 88
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00
00 87 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 88
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00
00 87 00 00 00 00 AF AF AF AF AF AF AF AF AF AF AF AF 00 00 00 00 88
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00
00 87 00 00 00 8E 00 00 00 00 00 00 00 00 00 00 00 00 8D 00 00 00 88
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00
00 87 97 00 8E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 8D 00 97 88
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00
00 8A 83 83 83 83 83 83 83 83 83 83 83 83 83 83 83 83 83 83 83 83 8B
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

View File

@@ -0,0 +1,54 @@
`timescale 1ns / 1ps
module dpram #(
parameter width_a = 8,
parameter widthad_a = 10,
parameter init_file= ""
) (
// Port A
input wire clock_a,
input wire wren_a,
input wire [widthad_a-1:0] address_a,
input wire [width_a-1:0] data_a,
output reg [width_a-1:0] q_a,
// Port B
input wire clock_b,
input wire wren_b,
input wire [widthad_a-1:0] address_b,
input wire [width_a-1:0] data_b,
output reg [width_a-1:0] q_b,
input wire byteena_a,
input wire byteena_b
);
initial begin
$display("Loading rom.");
$display(init_file);
if (init_file>0)
$readmemh(init_file, mem);
end
// Shared memory
reg [width_a-1:0] mem [(2**widthad_a)-1:0];
// Port A
always @(posedge clock_a) begin
q_a <= mem[address_a];
if(wren_a) begin
q_a <= data_a;
mem[address_a] <= data_a;
end
end
// Port B
always @(posedge clock_b) begin
q_b <= mem[address_b];
if(wren_b) begin
q_b <= data_b;
mem[address_b] <= data_b;
end
end
endmodule

View File

@@ -0,0 +1,3 @@
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) overlay.v ]
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) charmap.v ]
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) bram.sv ]

View File

@@ -0,0 +1,46 @@
`timescale 1ns / 1ps
/*============================================================================
Aznable (custom 8-bit computer system) - Casval (character map)
Author: Jim Gregory - https://github.com/JimmyStones/
Version: 1.0
Date: 2021-10-20
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
module charmap (
input clk,
input reset,
input [9:0] hcnt,
input [9:0] vcnt,
input [7:0] chrom_data_out,
input [7:0] chmap_data_out,
output [11:0] chram_addr,
output [11:0] chrom_addr,
output a
);
// Character map
wire [2:0] chpos_x = 3'd7 - hcnt[2:0];
wire [2:0] chpos_y = vcnt[2:0];
wire [5:0] chram_x = hcnt[8:3];
wire [5:0] chram_y = vcnt[8:3];
assign a = hcnt > 'd511 ? 1'b0 : vcnt > 'd255 ? 1'b0 : chrom_data_out[chpos_x[2:0]];
//assign a = chrom_data_out[chpos_x[2:0]];
assign chram_addr = {chram_y, chram_x};
assign chrom_addr = {1'b0, chmap_data_out[7:0], chpos_y};
endmodule

View File

@@ -0,0 +1,96 @@
00 00 00 00 00 00 00 00 ff 00 ff 00 ff 00 ff 00
00 ff 00 ff 00 ff 00 00 00 00 ff 00 ff 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3c 66 60 60 60 66 3c 00 00 00 fc 00 fc 00 00 00
03 0f 3f ff 3f 0f 03 00 c0 f0 fc ff fc f0 c0 00
00 00 18 3c 7e 18 18 00 00 00 18 18 7e 3c 18 00
00 00 fc fc fc 00 00 00 00 00 3f 3f 3f 00 00 00
00 00 60 78 7e 78 60 00 00 38 44 44 fe fe fe 00
00 06 09 09 fc fc fc 00 00 fe c6 c6 c6 fe 00 00
00 fe fe fe fe fe 00 00 00 00 18 18 00 00 00 00
18 18 66 66 18 18 3c 00 36 7f 7f 7f 3e 1c 08 00
06 0c 18 3e 7c 18 30 60 38 fe 82 82 fe fe fe 00
00 00 00 00 00 00 00 00 18 18 18 18 00 00 18 00
66 66 66 00 00 00 00 00 66 66 ff 66 ff 66 66 00
18 3e 60 3c 06 7c 18 00 62 66 0c 18 30 66 46 00
3c 66 3c 38 67 66 3f 00 06 0c 18 00 00 00 00 00
0c 18 30 30 30 18 0c 00 30 18 0c 0c 0c 18 30 00
00 66 3c ff 3c 66 00 00 00 18 18 7e 18 18 00 00
00 00 00 00 00 18 18 30 00 00 00 7e 00 00 00 00
00 00 00 00 00 18 18 00 00 03 06 0c 18 30 60 00
3c 66 6e 76 66 66 3c 00 18 18 38 18 18 18 7e 00
3c 66 06 0c 30 60 7e 00 3c 66 06 1c 06 66 3c 00
06 0e 1e 66 7f 06 06 00 7e 60 7c 06 06 66 3c 00
3c 66 60 7c 66 66 3c 00 7e 66 0c 18 18 18 18 00
3c 66 66 3c 66 66 3c 00 3c 66 66 3e 06 66 3c 00
00 00 18 00 00 18 00 00 00 00 18 00 00 18 18 30
0e 18 30 60 30 18 0e 00 00 00 7e 00 7e 00 00 00
70 18 0c 06 0c 18 70 00 3c 66 06 0c 18 00 18 00
3c 66 6e 6e 60 62 3c 00 18 3c 66 7e 66 66 66 00
7c 66 66 7c 66 66 7c 00 3c 66 60 60 60 66 3c 00
78 6c 66 66 66 6c 78 00 7e 60 60 78 60 60 7e 00
7e 60 60 78 60 60 60 00 3c 66 60 6e 66 66 3c 00
66 66 66 7e 66 66 66 00 3c 18 18 18 18 18 3c 00
1e 0c 0c 0c 0c 6c 38 00 66 6c 78 70 78 6c 66 00
60 60 60 60 60 60 7e 00 63 77 7f 6b 63 63 63 00
66 76 7e 7e 6e 66 66 00 3c 66 66 66 66 66 3c 00
7c 66 66 7c 60 60 60 00 3c 66 66 66 66 3c 0e 00
7c 66 66 7c 78 6c 66 00 3c 66 60 3c 06 66 3c 00
7e 18 18 18 18 18 18 00 66 66 66 66 66 66 3c 00
66 66 66 66 66 3c 18 00 63 63 63 6b 7f 77 63 00
66 66 3c 18 3c 66 66 00 66 66 66 3c 18 18 18 00
7e 06 0c 18 30 60 7e 00 3c 30 30 30 30 30 3c 00
c0 e0 70 38 1c 0e 07 03 3c 0c 0c 0c 0c 0c 3c 00
00 18 3c 7e 18 18 18 18 00 00 00 00 00 ff ff 00
00 00 03 3e 76 36 36 00 00 00 3c 06 3e 66 3e 00
00 60 60 7c 66 66 7c 00 00 00 3c 60 60 60 3c 00
00 06 06 3e 66 66 3e 00 00 00 3c 66 7e 60 3c 00
00 0e 18 3e 18 18 18 00 00 00 3e 66 66 3e 06 7c
00 60 60 7c 66 66 66 00 00 18 00 38 18 18 3c 00
00 06 00 06 06 06 06 3c 00 60 60 6c 78 6c 66 00
00 38 18 18 18 18 3c 00 00 00 66 7f 7f 6b 63 00
00 00 7c 66 66 66 66 00 00 00 3c 66 66 66 3c 00
00 00 7c 66 66 7c 60 60 00 00 3e 66 66 3e 06 06
00 00 7c 66 60 60 60 00 00 00 3e 60 3c 06 7c 00
00 18 7e 18 18 18 0e 00 00 00 66 66 66 66 3e 00
00 00 66 66 66 3c 18 00 00 00 63 6b 7f 3e 36 00
00 00 66 3c 18 3c 66 00 00 00 66 66 66 3e 0c 78
00 00 7e 0c 18 30 7e 00 18 18 18 f8 f8 18 18 18
18 18 18 18 18 18 18 18 18 18 18 1f 1f 18 18 18
08 1c 3e 7f 7f 1c 3e 00 fe fe fe fe fe fe fe 00
00 00 00 ff ff 00 00 00 08 1c 3e 7f 7f 1c 3e 00
18 18 18 18 18 18 18 18 00 00 00 ff ff 00 00 00
00 00 ff ff 00 00 00 00 00 ff ff 00 00 00 00 00
00 00 00 00 ff ff 00 00 30 30 30 30 30 30 30 30
0c 0c 0c 0c 0c 0c 0c 0c 00 00 00 e0 f0 38 18 18
18 18 1c 0f 07 00 00 00 18 18 38 f0 e0 00 00 00
c0 c0 c0 c0 c0 c0 ff ff c0 e0 70 38 1c 0e 07 03
03 07 0e 1c 38 70 e0 c0 ff ff c0 c0 c0 c0 c0 c0
ff ff 03 03 03 03 03 03 00 3c 7e 7e 7e 7e 3c 00
00 00 00 00 00 ff ff 00 36 7f 7f 7f 3e 1c 08 00
60 60 60 60 60 60 60 60 00 00 00 07 0f 1c 18 18
c3 e7 7e 3c 3c 7e e7 c3 00 3c 7e 66 66 7e 3c 00
18 18 66 66 18 18 3c 00 06 06 06 06 06 06 06 06
08 1c 3e 7f 3e 1c 08 00 18 18 18 ff ff 18 18 18
c0 c0 30 30 c0 c0 30 30 18 18 18 18 18 18 18 18
00 00 03 3e 76 36 36 00 ff 7f 3f 1f 0f 07 03 01
00 00 00 00 00 00 00 00 f0 f0 f0 f0 f0 f0 f0 f0
00 00 00 00 ff ff ff ff ff 00 00 00 00 00 00 00
00 00 00 00 00 00 00 ff c0 c0 c0 c0 c0 c0 c0 c0
cc cc 33 33 cc cc 33 33 03 03 03 03 03 03 03 03
00 00 00 00 cc cc 33 33 ff fe fc f8 f0 e0 c0 80
03 03 03 03 03 03 03 03 18 18 18 1f 1f 18 18 18
00 00 00 00 0f 0f 0f 0f 18 18 18 1f 1f 00 00 00
00 00 00 f8 f8 18 18 18 00 00 00 00 00 00 ff ff
00 00 00 1f 1f 18 18 18 18 18 18 ff ff 00 00 00
00 00 00 ff ff 18 18 18 18 18 18 f8 f8 18 18 18
c0 c0 c0 c0 c0 c0 c0 c0 e0 e0 e0 e0 e0 e0 e0 e0
07 07 07 07 07 07 07 07 ff ff 00 00 00 00 00 00
ff ff ff 00 00 00 00 00 00 00 00 00 00 ff ff ff
03 03 03 03 03 03 ff ff 00 00 00 00 f0 f0 f0 f0
0f 0f 0f 0f 00 00 00 00 18 18 18 f8 f8 00 00 00
f0 f0 f0 f0 00 00 00 00 f0 f0 f0 f0 0f 0f 0f 0f

View File

@@ -0,0 +1,193 @@
`timescale 1ns / 1ps
module overlay #(
parameter [23:0] RGB = 24'hFFFFFF
) (
input reset,
input [7:0] i_r,
input [7:0] i_g,
input [7:0] i_b,
input i_clk,
input i_pix,
input [9:0] hcnt,
input [9:0] vcnt,
output [7:0] o_r,
output [7:0] o_g,
output [7:0] o_b,
input ena,
input [24:0] max,
input [24:0] pos
);
wire [7:0] charmap_r;
wire [7:0] charmap_g;
wire [7:0] charmap_b;
wire charmap_a;
// Casval - character map
wire [11:0] chram_addr;
wire [11:0] chrom_addr;
wire [7:0] chrom_data_out;
wire [7:0] chmap_data_out;
wire in_box = hcnt < 8*36 & vcnt < 10*10;
assign o_r= ~ena | ~in_box ? i_r : (charmap_a ) ? RGB[23:16] : i_r >> 2;
assign o_g= ~ena |~in_box ? i_g : (charmap_a ) ? RGB[15:8] : i_g >> 2;
assign o_b= ~ena | ~in_box ? i_b : (charmap_a ) ? RGB[7:0] : i_b >> 2;
reg [24:0] pos_r;
reg [11:0] wr_addr;
reg [7:0] wr_data;
reg wheel_state;
reg [1:0] state;
// this is an increment / 16 -- we have 10 now, so
// we need to make the bar 6 wider - AJS TODO
wire [24:0] increment={4'b0000,max[23:4]};
reg [24:0] inc_pos='d0;
reg [4:0] blocks;
reg [4:0] cur_block;
// a6 -- unfilled
// 7f -- filled bar
reg wr_ena;
always @(posedge i_clk)
begin
if (reset)
begin
state<=2'b0;
blocks<='d0;
end
// when the pos changes, we need to
// increment the tape gears
wr_ena<=1'b0;
pos_r<=pos;
if (pos!=pos_r)
begin
//$display("pos: %d pos_r %d blocks %d inc_pos %d increment %d\n",pos,pos_r,blocks,inc_pos,increment);
inc_pos<=inc_pos+25'd1;
if (inc_pos==increment)
begin
inc_pos<='d0;
blocks<=blocks+5'd1;
end
// do this afterwards, because we need to reset
// blocks
if (pos=='d0)
begin
//$display("pos is 0\n");
inc_pos<='d0;
blocks<='d0;
end
cur_block<='d0;
end
case (state)
2'b00:
begin
if (pos!=pos_r)
begin
//$display("pos: %d \n",pos);
wr_ena<=1'b1;
wr_addr<='d331;
if (wheel_state)
wr_data<='h2A;
else
wr_data<='h96;
state<=2'b01;
end
end
2'b01:
begin
wr_ena<=1'b1;
wr_addr<='d340;
if (wheel_state)
wr_data<='h96;
else
wr_data<='h2A;
wheel_state<=~wheel_state;
state<=2'b10;
end
2'b10:
begin
// draw the progress bar - 16 segments
if (cur_block=='d15)
state<=2'b11;
wr_ena<=1'b1;
wr_addr<=12'd136+cur_block;
if (cur_block>blocks)
wr_data<='hA6; // empty bar
else
wr_data<='h7F; // filled bar
cur_block<=cur_block+5'd1;
//$display("cur_block: %d blocks: %d pos: %d max: %d increment: %d\n",cur_block,blocks,pos,max,increment);
end
2'b11:
begin
state<=2'b00;
end
endcase
end
charmap casval
(
.clk(i_pix),
.reset(reset),
.hcnt(hcnt),
.vcnt(vcnt),
.chrom_data_out(chrom_data_out),
.chmap_data_out(chmap_data_out),
.chram_addr(chram_addr),
.chrom_addr(chrom_addr),
.a(charmap_a)
);
// Char ROM - 0x9000 - 0x97FF (0x0800 / 2048 bytes)
dpram #(.widthad_a(11),.width_a(8), .init_file("font.hex")) chrom
(
.clock_a(i_clk),
.address_a(chrom_addr[10:0]),
.wren_a(1'b0),
.data_a(),
.q_a(chrom_data_out),
.clock_b(i_clk),
.address_b(),
.wren_b(),
.data_b(),
.q_b()
);
// Char index RAM - 0x9800 - 0x9FFF (0x0800 / 2048 bytes)
dpram #(.widthad_a(11),.width_a(8), .init_file("background.hex")) chram
(
.clock_a(i_clk),
.address_a(wr_addr[10:0]),
.wren_a(wr_ena),
.data_a(wr_data),
.q_a(),
.clock_b(i_clk),
.address_b(chram_addr[10:0]),
.wren_b(1'b0),
.data_b(),
.q_b(chmap_data_out)
);
endmodule