mirror of
https://github.com/MiSTer-devel/Arcade-LadyBug_MiSTer.git
synced 2026-05-17 03:02:25 +00:00
Merge pull request #10 from JimmyStones/merge-cores
Merge in Snap Jack, Cosmic Avenger and Dorodon
This commit is contained in:
@@ -193,61 +193,39 @@ assign FB_FORCE_BLANK = '0;
|
||||
|
||||
wire [1:0] ar = status[20:19];
|
||||
|
||||
assign VIDEO_ARX = (!ar) ? ((status[2] ) ? 8'd4 : 8'd3) : (ar - 1'd1);
|
||||
assign VIDEO_ARY = (!ar) ? ((status[2] ) ? 8'd3 : 8'd4) : 12'd0;
|
||||
assign VIDEO_ARX = (!ar) ? ((status[2] | landscape) ? 8'd4 : 8'd3) : (ar - 1'd1);
|
||||
assign VIDEO_ARY = (!ar) ? ((status[2] | landscape) ? 8'd3 : 8'd4) : 12'd0;
|
||||
|
||||
|
||||
`include "build_id.v"
|
||||
localparam CONF_STR = {
|
||||
"A.LADYBG;;",
|
||||
"H0OJK,Aspect ratio,Original,Full Screen,[ARC1],[ARC2];",
|
||||
"H0O2,Orientation,Vert,Horz;",
|
||||
"H1H0O2,Orientation,Vert,Horz;",
|
||||
"O35,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%,CRT 75%;",
|
||||
"-;",
|
||||
"O89,Difficulty,Easy,Medium,Hard,Hardest;",
|
||||
"OB,Lives,3,5;",
|
||||
"OC,Cabinet,Upright,Cocktail;",
|
||||
"O6,Pause when OSD is open,On,Off;",
|
||||
"P1,Pause options;",
|
||||
"P1OP,Pause when OSD is open,On,Off;",
|
||||
"P1OQ,Dim video after 10s,On,Off;",
|
||||
"-;",
|
||||
"DIP;",
|
||||
"-;",
|
||||
"R0,Reset;",
|
||||
"J1,Start 1P,Start 2P,Coin,Pause;",
|
||||
"jn,Start,Select,R,L;",
|
||||
"J1,Fire,Bomb,Start 1P,Start 2P,Coin,Pause;",
|
||||
"jn,A,B,Start,Select,R,L;",
|
||||
"V,v",`BUILD_DATE
|
||||
};
|
||||
/*
|
||||
-- Lives ------------------------------------------------------------------
|
||||
-- 0 = 5 Lives
|
||||
-- 1 = 3 Lives
|
||||
'0' &
|
||||
-- Free Play --------------------------------------------------------------
|
||||
-- 0 = Free Play
|
||||
-- 1 = No Free Play
|
||||
'1' &
|
||||
-- Cabinet ----------------------------------------------------------------
|
||||
-- 0 = Upright
|
||||
-- 1 = Cocktail
|
||||
'0' &
|
||||
-- Screen Freeze ----------------------------------------------------------
|
||||
-- 0 = Freeze
|
||||
-- 1 = No Freeze
|
||||
'1' &
|
||||
-- Rack Test (Cheat) ------------------------------------------------------
|
||||
-- 0 = On
|
||||
-- 1 = Off
|
||||
'1' &
|
||||
-- High Score Initials ----------------------------------------------------
|
||||
-- 0 = 3-Letter Initials
|
||||
-- 1 = 10-Letter Initials
|
||||
'1' &
|
||||
-- Difficulty -------------------------------------------------------------
|
||||
-- 11 = Easy
|
||||
-- 10 = Medium
|
||||
-- 01 = Hard
|
||||
-- 00 = Hardest
|
||||
"10";
|
||||
*/
|
||||
wire [7:0] m_dip = {~status[11],1'b1,status[12],1'b1,1'b1,1'b1,~status[9:8]};
|
||||
|
||||
// Read DIPs from MRA
|
||||
reg [7:0] m_dip[8]; // Active-LOW
|
||||
always @(posedge clk_sys) if(ioctl_wr && (ioctl_index==254) && !ioctl_addr[24:3]) m_dip[ioctl_addr[2:0]] <= ioctl_dout;
|
||||
|
||||
// Read game index from MRA
|
||||
localparam mod_ladybug = 0;
|
||||
localparam mod_snapjack = 1;
|
||||
localparam mod_cosmicavenger = 2;
|
||||
reg [7:0] mod = 0;
|
||||
always @(posedge clk_sys) if (ioctl_wr & (ioctl_index==1)) mod <= ioctl_dout;
|
||||
|
||||
//////////////////// CLOCKS ///////////////////
|
||||
|
||||
@@ -278,9 +256,7 @@ wire [24:0] ioctl_addr;
|
||||
wire [7:0] ioctl_dout;
|
||||
wire [7:0] ioctl_din;
|
||||
|
||||
wire [15:0] joystick_0,joystick_1;
|
||||
wire [15:0] joy1 = joystick_0;
|
||||
wire [15:0] joy2 = joystick_1;
|
||||
wire [15:0] joy1,joy2;
|
||||
|
||||
wire [21:0] gamma_bus;
|
||||
|
||||
@@ -294,7 +270,7 @@ hps_io #(.STRLEN($size(CONF_STR)>>3)) hps_io
|
||||
|
||||
.buttons(buttons),
|
||||
.status(status),
|
||||
.status_menumask(direct_video),
|
||||
.status_menumask({landscape,direct_video}),
|
||||
.forced_scandoubler(forced_scandoubler),
|
||||
.gamma_bus(gamma_bus),
|
||||
.direct_video(direct_video),
|
||||
@@ -307,86 +283,84 @@ hps_io #(.STRLEN($size(CONF_STR)>>3)) hps_io
|
||||
.ioctl_din(ioctl_din),
|
||||
.ioctl_index(ioctl_index),
|
||||
|
||||
.joystick_0(joystick_0),
|
||||
.joystick_1(joystick_1)
|
||||
.joystick_0(joy1),
|
||||
.joystick_1(joy2)
|
||||
);
|
||||
|
||||
|
||||
wire no_rotate = status[2] | direct_video ;
|
||||
wire m_up = joy1[3];
|
||||
wire m_down = joy1[2];
|
||||
wire m_left = joy1[1];
|
||||
wire m_right = joy1[0];
|
||||
wire m_fire = joy1[4];
|
||||
wire m_bomb = joy1[5];
|
||||
wire m_up_2 = joy2[3];
|
||||
wire m_down_2 = joy2[2];
|
||||
wire m_left_2 = joy2[1];
|
||||
wire m_right_2 = joy2[0];
|
||||
wire m_fire_2 = joy2[5];
|
||||
wire m_bomb_2 = joy2[6];
|
||||
wire m_start1 = joy1[6] | joy2[6];
|
||||
wire m_start2 = joy1[7] | joy2[7];
|
||||
wire m_coin = joy1[8] | joy2[8];
|
||||
wire m_pause = joy1[9] | joy2[9];
|
||||
reg [1:0] but_up_s;
|
||||
reg [1:0] but_down_s;
|
||||
reg [1:0] but_left_s;
|
||||
reg [1:0] but_right_s;
|
||||
|
||||
wire m_up,m_down,m_left,m_right;
|
||||
joyonedir jod
|
||||
(
|
||||
clk_sys,
|
||||
1'b0,
|
||||
{
|
||||
joy1[3],
|
||||
joy1[2],
|
||||
joy1[1],
|
||||
joy1[0]
|
||||
},
|
||||
{m_up,m_down,m_left,m_right}
|
||||
);
|
||||
// One-directional control generators for Lady Bug
|
||||
wire [3:0] m_joyod_1;
|
||||
wire [3:0] m_joyod_2;
|
||||
joyonedir jod_1(clk_sys,1'b0,{m_up,m_down,m_left,m_right},m_joyod_1);
|
||||
joyonedir jod_2(clk_sys,1'b0,{m_up_2,m_down_2,m_left_2,m_right_2},m_joyod_2);
|
||||
|
||||
wire m_up_2,m_down_2,m_left_2,m_right_2;
|
||||
joyonedir jod_2
|
||||
(
|
||||
clk_sys,
|
||||
1'b0,
|
||||
{
|
||||
joy2[3],
|
||||
joy2[2],
|
||||
joy2[1],
|
||||
joy2[0]
|
||||
},
|
||||
{m_up_2,m_down_2,m_left_2,m_right_2}
|
||||
);
|
||||
// Set game specific options
|
||||
reg landscape;
|
||||
always @(*) begin
|
||||
landscape <= 1'b0;
|
||||
but_up_s <= {m_up_2,m_up};
|
||||
but_down_s <= {m_down_2,m_down};
|
||||
but_left_s <= {m_left_2,m_left};
|
||||
but_right_s <= {m_right_2,m_right};
|
||||
|
||||
|
||||
wire m_fire = 1'b0;
|
||||
wire m_fire_2 = 1'b0;
|
||||
|
||||
wire m_start1 = joy1[4] | joy2[4];
|
||||
wire m_start2 = joy1[5] | joy2[5];
|
||||
wire m_coin = joy1[6] | joy2[6];
|
||||
wire m_pause = joy1[7] | joy2[7];
|
||||
|
||||
// PAUSE SYSTEM
|
||||
reg pause; // Pause signal (active-high)
|
||||
reg pause_toggle = 1'b0; // User paused (active-high)
|
||||
reg [31:0] pause_timer; // Time since pause
|
||||
reg [31:0] pause_timer_dim = 32'hBEBC200; // Time until screen dim (10 seconds @ 20Mhz)
|
||||
reg dim_video; // Dim video output (active-high)
|
||||
|
||||
// Pause when highscore module requires access, user has pressed pause, or OSD is open and option is set
|
||||
assign pause = hs_access | pause_toggle | (OSD_STATUS && ~status[6]);
|
||||
assign dim_video = (pause_timer >= pause_timer_dim) ? 1'b1 : 1'b0;
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
reg old_pause;
|
||||
old_pause <= m_pause;
|
||||
if(~old_pause & m_pause) pause_toggle <= ~pause_toggle;
|
||||
if(pause)
|
||||
begin
|
||||
if(reset) pause_toggle <= 0;
|
||||
if(pause_timer<pause_timer_dim)
|
||||
begin
|
||||
pause_timer <= pause_timer + 1'b1;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
pause_timer <= 1'b0;
|
||||
end
|
||||
case (mod)
|
||||
mod_ladybug:
|
||||
begin
|
||||
but_up_s <= {m_joyod_2[3],m_joyod_1[3]};
|
||||
but_down_s <= {m_joyod_2[2],m_joyod_1[2]};
|
||||
but_left_s <= {m_joyod_2[1],m_joyod_1[1]};
|
||||
but_right_s <= {m_joyod_2[0],m_joyod_1[0]};
|
||||
end
|
||||
mod_snapjack:
|
||||
begin
|
||||
landscape <= 1'b1;
|
||||
end
|
||||
mod_cosmicavenger:
|
||||
begin
|
||||
landscape <= 1'b1;
|
||||
end
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
|
||||
wire no_rotate = status[2] | direct_video | landscape;
|
||||
|
||||
|
||||
// PAUSE SYSTEM
|
||||
wire pause_cpu;
|
||||
wire [5:0] rgb_out;
|
||||
pause #(2,2,2,20) pause (
|
||||
.*,
|
||||
.user_button(m_pause),
|
||||
.pause_request(hs_pause),
|
||||
.options(~status[26:25])
|
||||
);
|
||||
|
||||
wire hblank, vblank;
|
||||
wire hs, vs;
|
||||
wire ce_vid;
|
||||
wire [1:0] r,g;
|
||||
wire [1:0] b;
|
||||
wire [5:0] rgb_out = dim_video ? {r >> 1,g >> 1, b >> 1} : {r,g,b};
|
||||
wire [1:0] r,g, b;
|
||||
|
||||
reg ce_pix;
|
||||
always @(posedge clk_40) begin
|
||||
@@ -418,7 +392,7 @@ assign AUDIO_L = {audio, 8'd0};
|
||||
assign AUDIO_R = AUDIO_L;
|
||||
assign AUDIO_S = 1;
|
||||
|
||||
wire rom_download = ioctl_download & !ioctl_index;
|
||||
wire rom_download = ioctl_download & (ioctl_index==2'd1|| ioctl_index==2'd2);
|
||||
wire reset = RESET | status[0] | buttons[1] | rom_download;
|
||||
|
||||
ladybug ladybug
|
||||
@@ -437,22 +411,23 @@ ladybug ladybug
|
||||
|
||||
.dn_addr(ioctl_addr[15:0]),
|
||||
.dn_data(ioctl_dout),
|
||||
.dn_wr(ioctl_wr & rom_download),
|
||||
.dn_wr(ioctl_wr),
|
||||
.dn_index(ioctl_index),
|
||||
|
||||
.O_AUDIO(audio),
|
||||
|
||||
.but_coin_s(~{1'b0,m_coin}),
|
||||
.but_fire_s(~{m_fire_2,m_fire}),
|
||||
.but_bomb_s(~{1'b0,1'b0}),
|
||||
.but_bomb_s(~{m_bomb_2,m_bomb}),
|
||||
.but_tilt_s(~{1'b0,1'b0}),
|
||||
.but_select_s(~{m_start2,m_start1}),
|
||||
.but_up_s(~{m_up_2,m_up}),
|
||||
.but_down_s(~{m_down_2,m_down}),
|
||||
.but_left_s(~{m_left_2,m_left}),
|
||||
.but_right_s(~{m_right_2,m_right}),
|
||||
.dip_block_1_s(m_dip),
|
||||
.but_up_s(~but_up_s),
|
||||
.but_down_s(~but_down_s),
|
||||
.but_left_s(~but_left_s),
|
||||
.but_right_s(~but_right_s),
|
||||
.dip_block_1_s(~m_dip[0]),
|
||||
|
||||
.pause(pause),
|
||||
.pause(pause_cpu),
|
||||
|
||||
.hs_address(hs_address),
|
||||
.hs_data_out(ioctl_din),
|
||||
@@ -468,6 +443,7 @@ wire [15:0]hs_address;
|
||||
wire [7:0]hs_data_in;
|
||||
wire hs_write;
|
||||
wire hs_access;
|
||||
wire hs_pause;
|
||||
|
||||
hiscore #(
|
||||
.HS_ADDRESSWIDTH(16),
|
||||
@@ -486,7 +462,8 @@ hiscore #(
|
||||
.ram_address(hs_address),
|
||||
.data_to_ram(hs_data_in),
|
||||
.ram_write(hs_write),
|
||||
.ram_access(hs_access)
|
||||
.ram_access(hs_access),
|
||||
.pause_cpu(hs_pause)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_decrypt.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_3.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_2.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_1.vhd
|
||||
#set_global_assignment -name VHDL_FILE rtl/ROM/prom_decrypt.vhd
|
||||
#set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_3.vhd
|
||||
#set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_2.vhd
|
||||
#set_global_assignment -name VHDL_FILE rtl/ROM/prom_10_1.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_top.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_tone.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sound/sn76489/sn76489_noise.vhd
|
||||
@@ -37,5 +37,6 @@ set_global_assignment -name VHDL_FILE rtl/ladybug_chute.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_char.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug_addr_dec.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ladybug.vhd
|
||||
set_global_assignment -name VERILOG_FILE rtl/pause.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/hiscore.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE "Arcade-LadyBug.sv"
|
||||
|
||||
BIN
releases/Arcade-LadyBug_20210419.rbf
Normal file
BIN
releases/Arcade-LadyBug_20210419.rbf
Normal file
Binary file not shown.
80
releases/Cosmic Avenger.mra
Normal file
80
releases/Cosmic Avenger.mra
Normal file
@@ -0,0 +1,80 @@
|
||||
<misterromdescription>
|
||||
<name>Cosmic Avenger</name>
|
||||
<mameversion>0220</mameversion>
|
||||
<setname>cavenger</setname>
|
||||
<mratimestamp>20200427161917</mratimestamp>
|
||||
<year>1981</year>
|
||||
<manufacturer>Universal</manufacturer>
|
||||
<category>Space / Defender</category>
|
||||
<rbf>ladybug</rbf>
|
||||
<buttons names="Fire,Bomb,Start 1P,Start 2P,Coin,Pause" default="A,B,Start,Select,R,L"/>
|
||||
<switches default="38">
|
||||
<dip bits="6,7" name="Lives" ids="3,4,5,2"/>
|
||||
<dip bits="4,5" name="Initial High Score" ids="5000,8000,0,10000"/>
|
||||
<dip bits="3" name="Cabinet" ids="Cocktail,Upright"/>
|
||||
<dip bits="2" name="High Score Initials" ids="10,3"/>
|
||||
<dip bits="0,1" name="Difficulty" ids="Easy,Medium,Hard,Hardest"/>
|
||||
</switches>
|
||||
<rom index="1">
|
||||
<part>02</part>
|
||||
</rom>
|
||||
<rom index="0" zip="cavenger.zip" md5="f1233ff57be1767247bdd18c7b0bdf69">
|
||||
<part crc="9e0cc781" name="1.c4"/>
|
||||
<part crc="5ce5b950" name="2.d4"/>
|
||||
<part crc="bc28218d" name="3.e4"/>
|
||||
<part crc="2b32e9f5" name="4.h4"/>
|
||||
<part crc="d117153e" name="5.j4"/>
|
||||
<part crc="c7d366cb" name="6.k4"/>
|
||||
<part crc="b022bf2d" name="8.l7"/>
|
||||
<part crc="b022bf2d" name="8.l7"/>
|
||||
<part crc="63357785" name="9.f7"/>
|
||||
<part crc="52ad1133" name="0.h7"/>
|
||||
</rom>
|
||||
<rom index="2" zip="cavenger.zip" md5="121daaf5de7cca6f0855097fa2571581">
|
||||
<part crc="d736b8de" name="10-1.f4"/>
|
||||
<part crc="42a24dd5" name="10-2.k1"/>
|
||||
<part crc="27fa3a50" name="10-3.c4"/>
|
||||
<part repeat="160">00</part>
|
||||
<part crc="none">
|
||||
00 01 02 03 04 05 06 07
|
||||
08 09 0A 0B 0C 0D 0E 0F
|
||||
10 11 12 13 14 15 16 17
|
||||
18 19 1A 1B 1C 1D 1E 1F
|
||||
20 21 22 23 24 25 26 27
|
||||
28 29 2A 2B 2C 2D 2E 2F
|
||||
30 31 32 33 34 35 36 37
|
||||
38 39 3A 3B 3C 3D 3E 3F
|
||||
40 41 42 43 44 45 46 47
|
||||
48 49 4A 4B 4C 4D 4E 4F
|
||||
50 51 52 53 54 55 56 57
|
||||
58 59 5A 5B 5C 5D 5E 5F
|
||||
60 61 62 63 64 65 66 67
|
||||
68 69 6A 6B 6C 6D 6E 6F
|
||||
70 71 72 73 74 75 76 77
|
||||
78 79 7A 7B 7C 7D 7E 7F
|
||||
80 81 82 83 84 85 86 87
|
||||
88 89 8A 8B 8C 8D 8E 8F
|
||||
90 91 92 93 94 95 96 97
|
||||
98 99 9A 9B 9C 9D 9E 9F
|
||||
A0 A1 A2 A3 A4 A5 A6 A7
|
||||
A8 A9 AA AB AC AD AE AF
|
||||
B0 B1 B2 B3 B4 B5 B6 B7
|
||||
B8 B9 BA BB BC BD BE BF
|
||||
C0 C1 C2 C3 C4 C5 C6 C7
|
||||
C8 C9 CA CB CC CD CE CF
|
||||
D0 D1 D2 D3 D4 D5 D6 D7
|
||||
D8 D9 DA DB DC DD DE DF
|
||||
E0 E1 E2 E3 E4 E5 E6 E7
|
||||
E8 E9 EA EB EC ED EE EF
|
||||
F0 F1 F2 F3 F4 F5 F6 F7
|
||||
F8 F9 FA FB FC FD FE FF
|
||||
</part>
|
||||
</rom>
|
||||
<rom index="3" md5="none">
|
||||
<part>
|
||||
00 00 00 00 00 FF 00 02 00 02 00 01 00 FF 00 00
|
||||
00 00 60 25 00 41 00 28
|
||||
</part>
|
||||
</rom>
|
||||
<nvram index="4" size="65"/>
|
||||
</misterromdescription>
|
||||
80
releases/Dorodon.mra
Normal file
80
releases/Dorodon.mra
Normal file
@@ -0,0 +1,80 @@
|
||||
<misterromdescription>
|
||||
<name>Dorodon (set 1)</name>
|
||||
<mameversion>0220</mameversion>
|
||||
<setname>dorodon</setname>
|
||||
<mratimestamp>20200427161917</mratimestamp>
|
||||
<year>1982</year>
|
||||
<manufacturer>UPL (Falcon license?)</manufacturer>
|
||||
<category>Maze</category>
|
||||
<rbf>ladybug</rbf>
|
||||
<buttons names="-,-,Start 1P,Start 2P,Coin,Pause" default="Start,Select,R,L"/>
|
||||
<switches default="20">
|
||||
<dip bits="7" name="Lives" ids="3,5"/>
|
||||
<dip bits="6" name="Free play" ids="No,Yes"/>
|
||||
<dip bits="5" name="Cabinet" ids="Cocktail,Upright"/>
|
||||
<dip bits="4" name="Freeze" ids="No,Yes"/>
|
||||
<dip bits="3" name="Rack Test" ids="No,Yes"/>
|
||||
<dip bits="2" name="Bonus Life" ids="20000,30000"/>
|
||||
<dip bits="0,1" name="Difficulty" ids="Easy,Medium,Hard,Hardest"/>
|
||||
</switches>
|
||||
<rom index="1">
|
||||
<part>04</part>
|
||||
</rom>
|
||||
<rom index="0" zip="dorodon.zip" md5="72cf4f0a5baf5a53342df3908589c359">
|
||||
<part crc="460aaf26" name="dorodon.0"/>
|
||||
<part crc="d2451eb6" name="dorodon.1"/>
|
||||
<part crc="d3c6ee6c" name="dorodon.2"/>
|
||||
<part crc="d70bb50a" name="dorodon.4"/>
|
||||
<part crc="e44e59e6" name="dorodon.3"/>
|
||||
<part crc="5eee2b85" name="dorodon.5"/>
|
||||
<part crc="395ac25a" name="dorodon.6"/>
|
||||
</rom>
|
||||
<rom index="2" zip="dorodon.zip" md5="535617ce1663c1a933777909b9ee0f2d">
|
||||
<part crc="3f209be4" name="dorodon.bp1"/>
|
||||
<part crc="8fcf0bc8" name="dorodon.bp0"/>
|
||||
<part crc="27fa3a50" name="dorodon.bp2"/>
|
||||
<part repeat="160">00</part>
|
||||
<part crc="none">
|
||||
00 F1 3F 86 4F 66 07 73
|
||||
71 64 A7 59 2B 56 FB 8B
|
||||
8F B6 9E 9D 04 11 BC 80
|
||||
12 CB 18 5D D2 7A 85 75
|
||||
B5 BE 7E 05 6E 3E D5 4B
|
||||
2E 52 15 84 38 6A 6C 53
|
||||
FA C8 08 B8 D4 E9 5C 22
|
||||
1D 49 BD AD 46 1F E1 0A
|
||||
19 5B 41 45 4A 2A B4 4D
|
||||
57 90 8E 3A BB 9B E4 29
|
||||
8A EB AA F0 CE EE 88 5F
|
||||
33 31 C6 60 3C 9A 3D B7
|
||||
63 6D AB 62 E3 78 E5 B9
|
||||
EF 5E 7B 83 94 E6 D6 A1
|
||||
D9 36 47 3B C4 DF 21 0C
|
||||
14 E7 C3 1A 1C 28 4C 9C
|
||||
50 40 91 55 D8 A4 76 9F
|
||||
98 10 6B 2F A3 43 39 B1
|
||||
42 72 7D 65 03 8D F2 F5
|
||||
69 27 0D CA CF 1B 35 EC
|
||||
A2 F7 93 70 CD 68 97 2D
|
||||
37 F9 AE 26 96 E8 48 99
|
||||
95 D7 B0 06 DC C9 ED 87
|
||||
7F B3 17 A0 0F 25 DB DE
|
||||
23 74 79 89 B2 FC 24 13
|
||||
81 8C D3 C5 BF A6 16 44
|
||||
0B 34 F8 D1 0E E0 09 EA
|
||||
02 DD 92 F4 C1 BA 32 D0
|
||||
7C 2C FD F3 61 A5 CC DA
|
||||
5A 67 30 6F 82 20 AF 54
|
||||
AC E2 1E C2 FE A9 58 01
|
||||
77 C0 4E C7 A8 51 F6 FF
|
||||
</part>
|
||||
</rom>
|
||||
<rom index="3" md5="none">
|
||||
<part>
|
||||
03 FF FF FF 00 FF 00 02 00 02 00 01 00 FF 00 00
|
||||
00 00 60 73 00 1B 01 00
|
||||
00 00 D3 81 00 46 0F 17
|
||||
</part>
|
||||
</rom>
|
||||
<nvram index="4" size="97"/>
|
||||
</misterromdescription>
|
||||
@@ -8,6 +8,19 @@
|
||||
<category>Maze</category>
|
||||
<category>Maze / Bugs</category>
|
||||
<rbf>ladybug</rbf>
|
||||
<buttons names="-,-,Start 1P,Start 2P,Coin,Pause" default="Start,Select,R,L"/>
|
||||
<switches default="20">
|
||||
<dip bits="7" name="Lives" ids="3,5"/>
|
||||
<dip bits="6" name="Free play" ids="No,Yes"/>
|
||||
<dip bits="5" name="Cabinet" ids="Cocktail,Upright"/>
|
||||
<dip bits="4" name="Freeze" ids="No,Yes"/>
|
||||
<dip bits="3" name="Rack Test" ids="No,Yes"/>
|
||||
<dip bits="2" name="High Score Initials" ids="10,3"/>
|
||||
<dip bits="0,1" name="Difficulty" ids="Easy,Medium,Hard,Hardest"/>
|
||||
</switches>
|
||||
<rom index="1">
|
||||
<part>00</part>
|
||||
</rom>
|
||||
<rom index="0" zip="ladybug.zip" md5="89d961d878363b9859930a3e2c463867">
|
||||
<part crc="d09e0adb" name="l1.c4"/>
|
||||
<part crc="88bc4a0a" name="l2.d4"/>
|
||||
@@ -20,6 +33,46 @@
|
||||
<part crc="77b1da1e" name="l9.f7"/>
|
||||
<part crc="aa82e00b" name="l0.h7"/>
|
||||
</rom>
|
||||
<rom index="2" zip="ladybug.zip" md5="0a1fac7e0e66624d5cb8836f16da9310">
|
||||
<part crc="40640d8f" name="10-1.f4"/>
|
||||
<part crc="df091e52" name="10-2.k1"/>
|
||||
<part crc="27fa3a50" name="10-3.c4"/>
|
||||
<part repeat="160">00</part>
|
||||
<part crc="none">
|
||||
00 01 02 03 04 05 06 07
|
||||
08 09 0A 0B 0C 0D 0E 0F
|
||||
10 11 12 13 14 15 16 17
|
||||
18 19 1A 1B 1C 1D 1E 1F
|
||||
20 21 22 23 24 25 26 27
|
||||
28 29 2A 2B 2C 2D 2E 2F
|
||||
30 31 32 33 34 35 36 37
|
||||
38 39 3A 3B 3C 3D 3E 3F
|
||||
40 41 42 43 44 45 46 47
|
||||
48 49 4A 4B 4C 4D 4E 4F
|
||||
50 51 52 53 54 55 56 57
|
||||
58 59 5A 5B 5C 5D 5E 5F
|
||||
60 61 62 63 64 65 66 67
|
||||
68 69 6A 6B 6C 6D 6E 6F
|
||||
70 71 72 73 74 75 76 77
|
||||
78 79 7A 7B 7C 7D 7E 7F
|
||||
80 81 82 83 84 85 86 87
|
||||
88 89 8A 8B 8C 8D 8E 8F
|
||||
90 91 92 93 94 95 96 97
|
||||
98 99 9A 9B 9C 9D 9E 9F
|
||||
A0 A1 A2 A3 A4 A5 A6 A7
|
||||
A8 A9 AA AB AC AD AE AF
|
||||
B0 B1 B2 B3 B4 B5 B6 B7
|
||||
B8 B9 BA BB BC BD BE BF
|
||||
C0 C1 C2 C3 C4 C5 C6 C7
|
||||
C8 C9 CA CB CC CD CE CF
|
||||
D0 D1 D2 D3 D4 D5 D6 D7
|
||||
D8 D9 DA DB DC DD DE DF
|
||||
E0 E1 E2 E3 E4 E5 E6 E7
|
||||
E8 E9 EA EB EC ED EE EF
|
||||
F0 F1 F2 F3 F4 F5 F6 F7
|
||||
F8 F9 FA FB FC FD FE FF
|
||||
</part>
|
||||
</rom>
|
||||
<rom index="3" md5="none">
|
||||
<part>
|
||||
03 FF FF FF 00 FF 00 02 00 02 00 01 00 FF 00 00
|
||||
|
||||
81
releases/Snap Jack.mra
Normal file
81
releases/Snap Jack.mra
Normal file
@@ -0,0 +1,81 @@
|
||||
<misterromdescription>
|
||||
<name>Snap Jack</name>
|
||||
<mameversion>0220</mameversion>
|
||||
<setname>snapjack</setname>
|
||||
<mratimestamp>20200427161917</mratimestamp>
|
||||
<year>1982</year>
|
||||
<manufacturer>Universal</manufacturer>
|
||||
<category>Platform / Water Diving</category>
|
||||
<rbf>ladybug</rbf>
|
||||
<buttons names="-,-,Start 1P,Start 2P,Coin,Pause" default="Start,Select,R,L"/>
|
||||
<switches default="38">
|
||||
<dip bits="6,7" name="Lives" ids="3,4,5,2"/>
|
||||
<dip bits="5" name="Unused 2" ids="Yes,No"/>
|
||||
<dip bits="4" name="Unused 1" ids="Yes,No"/>
|
||||
<dip bits="3" name="Cabinet" ids="Cocktail,Upright"/>
|
||||
<dip bits="2" name="High Score Initials" ids="10,3"/>
|
||||
<dip bits="0,1" name="Difficulty" ids="Easy,Medium,Hard,Hardest"/>
|
||||
</switches>
|
||||
<rom index="1">
|
||||
<part>01</part>
|
||||
</rom>
|
||||
<rom index="0" zip="snapjack.zip" md5="c84aa7495fa0af63de7a6c72c1c8b730">
|
||||
<part crc="6b30fcda" name="sj1.c4"/>
|
||||
<part crc="1f1088d1" name="sj2.d4"/>
|
||||
<part crc="edd65f3a" name="sj3.e4"/>
|
||||
<part crc="f4481192" name="sj4.h4"/>
|
||||
<part crc="1bff7d05" name="sj5.j4"/>
|
||||
<part crc="21793edf" name="sj6.k4"/>
|
||||
<part crc="b7f105b6" name="sj8.l7"/>
|
||||
<part crc="1cdb03a8" name="sj7.m7"/>
|
||||
<part crc="ff2011c7" name="sj9.f7"/>
|
||||
<part crc="f097babb" name="sj0.h7"/>
|
||||
</rom>
|
||||
<rom index="2" zip="snapjack.zip" md5="e8003cb15596c20d9a0456d6f9c36689">
|
||||
<part crc="5b16fbd2" name="10-2.k1"/>
|
||||
<part crc="cbbd9dd1" name="10-1.f4"/>
|
||||
<part crc="27fa3a50" name="10-3.c4"/>
|
||||
<part repeat="160">00</part>
|
||||
<part crc="none">
|
||||
00 01 02 03 04 05 06 07
|
||||
08 09 0A 0B 0C 0D 0E 0F
|
||||
10 11 12 13 14 15 16 17
|
||||
18 19 1A 1B 1C 1D 1E 1F
|
||||
20 21 22 23 24 25 26 27
|
||||
28 29 2A 2B 2C 2D 2E 2F
|
||||
30 31 32 33 34 35 36 37
|
||||
38 39 3A 3B 3C 3D 3E 3F
|
||||
40 41 42 43 44 45 46 47
|
||||
48 49 4A 4B 4C 4D 4E 4F
|
||||
50 51 52 53 54 55 56 57
|
||||
58 59 5A 5B 5C 5D 5E 5F
|
||||
60 61 62 63 64 65 66 67
|
||||
68 69 6A 6B 6C 6D 6E 6F
|
||||
70 71 72 73 74 75 76 77
|
||||
78 79 7A 7B 7C 7D 7E 7F
|
||||
80 81 82 83 84 85 86 87
|
||||
88 89 8A 8B 8C 8D 8E 8F
|
||||
90 91 92 93 94 95 96 97
|
||||
98 99 9A 9B 9C 9D 9E 9F
|
||||
A0 A1 A2 A3 A4 A5 A6 A7
|
||||
A8 A9 AA AB AC AD AE AF
|
||||
B0 B1 B2 B3 B4 B5 B6 B7
|
||||
B8 B9 BA BB BC BD BE BF
|
||||
C0 C1 C2 C3 C4 C5 C6 C7
|
||||
C8 C9 CA CB CC CD CE CF
|
||||
D0 D1 D2 D3 D4 D5 D6 D7
|
||||
D8 D9 DA DB DC DD DE DF
|
||||
E0 E1 E2 E3 E4 E5 E6 E7
|
||||
E8 E9 EA EB EC ED EE EF
|
||||
F0 F1 F2 F3 F4 F5 F6 F7
|
||||
F8 F9 FA FB FC FD FE FF
|
||||
</part>
|
||||
</rom>
|
||||
<rom index="3" md5="none">
|
||||
<part>
|
||||
00 00 00 00 00 FF 00 02 00 02 00 01 00 FF 00 00
|
||||
00 00 6A 94 00 41 01 24
|
||||
</part>
|
||||
</rom>
|
||||
<nvram index="4" size="65"/>
|
||||
</misterromdescription>
|
||||
@@ -15,7 +15,7 @@ entity dpram is
|
||||
address_b : IN STD_LOGIC_VECTOR (addr_width_g-1 DOWNTO 0);
|
||||
clock_a : IN STD_LOGIC := '1';
|
||||
clock_b : IN STD_LOGIC ;
|
||||
data_a : IN STD_LOGIC_VECTOR (data_width_g-1 DOWNTO 0);
|
||||
data_a : IN STD_LOGIC_VECTOR (data_width_g-1 DOWNTO 0) := (others => '0');
|
||||
data_b : IN STD_LOGIC_VECTOR (data_width_g-1 DOWNTO 0) := (others => '0');
|
||||
enable_a : IN STD_LOGIC := '1';
|
||||
enable_b : IN STD_LOGIC := '1';
|
||||
|
||||
234
rtl/hiscore.v
234
rtl/hiscore.v
@@ -29,6 +29,7 @@
|
||||
0004 - 2021-03-15 - Fix ram_access assignment
|
||||
0005 - 2021-03-18 - Add configurable score table width, clean up some stupid mistakes
|
||||
0006 - 2021-03-27 - Move 'tweakable' parameters into MRA data header
|
||||
0007 - 2021-04-15 - Improve state machine maintainability, add new 'pause padding' states
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
@@ -56,16 +57,40 @@ module hiscore
|
||||
output [HS_ADDRESSWIDTH-1:0] ram_address, // Address in game RAM to read/write score data
|
||||
output [7:0] data_to_ram, // Data to write to game RAM
|
||||
output reg ram_write, // Write to game RAM (active high)
|
||||
output ram_access // RAM read or write required (active high)
|
||||
output ram_access, // RAM read or write required (active high)
|
||||
output reg pause_cpu // Pause core CPU to prepare for/relax after RAM access
|
||||
);
|
||||
|
||||
// Parameters read from config header
|
||||
reg [31:0] START_WAIT =1'b0; // Delay before beginning check process
|
||||
reg [15:0] CHECK_WAIT =8'hFF; // Delay between start/end check attempts
|
||||
reg [15:0] CHECK_HOLD =8'd2; // Hold time for start/end check reads
|
||||
reg [15:0] WRITE_HOLD =8'd2; // Hold time for game RAM writes
|
||||
reg [15:0] WRITE_REPEATCOUNT =8'b1; // Number of times to write score to game RAM
|
||||
reg [15:0] WRITE_REPEATWAIT =8'b1111; // Delay between subsequent write attempts to game RAM
|
||||
reg [31:0] START_WAIT =32'd0; // Delay before beginning check process
|
||||
reg [15:0] CHECK_WAIT =16'hFF; // Delay between start/end check attempts
|
||||
reg [15:0] CHECK_HOLD =16'd2; // Hold time for start/end check reads
|
||||
reg [15:0] WRITE_HOLD =16'd2; // Hold time for game RAM writes
|
||||
reg [15:0] WRITE_REPEATCOUNT =16'b1; // Number of times to write score to game RAM
|
||||
reg [15:0] WRITE_REPEATWAIT =16'b1111; // Delay between subsequent write attempts to game RAM
|
||||
reg [7:0] ACCESS_PAUSEPAD =8'd4; // Cycles to wait with paused CPU before and after RAM access
|
||||
|
||||
|
||||
// State machine constants
|
||||
localparam SM_STATEWIDTH = 4; // Width of state machine net
|
||||
|
||||
localparam SM_INIT = 0;
|
||||
localparam SM_TIMER = 1;
|
||||
|
||||
localparam SM_CHECKPREP = 2;
|
||||
localparam SM_CHECKBEGIN = 3;
|
||||
localparam SM_CHECKSTARTVAL = 4;
|
||||
localparam SM_CHECKENDVAL = 5;
|
||||
localparam SM_CHECKCANCEL = 6;
|
||||
|
||||
localparam SM_WRITEPREP = 7;
|
||||
localparam SM_WRITEBEGIN = 8;
|
||||
localparam SM_WRITEREADY = 9;
|
||||
localparam SM_WRITEDONE = 10;
|
||||
localparam SM_WRITECOMPLETE = 11;
|
||||
localparam SM_WRITERETRY = 12;
|
||||
|
||||
localparam SM_STOPPED = 13;
|
||||
|
||||
/*
|
||||
Hiscore config data structure (version 1)
|
||||
@@ -107,9 +132,9 @@ Hiscore config data structure (version 1)
|
||||
|
||||
*/
|
||||
|
||||
localparam HS_VERSION =6; // Version identifier for module
|
||||
localparam HS_VERSION =7; // Version identifier for module
|
||||
localparam HS_DUMPFORMAT =1; // Version identifier for dump format
|
||||
localparam HS_HEADERLENGTH =4'b1111; // Size of header chunk (default=16 bytes)
|
||||
localparam HS_HEADERLENGTH =16; // Size of header chunk (default=16 bytes)
|
||||
|
||||
// HS_DUMPFORMAT = 1 --> No header, just the extracted hiscore data
|
||||
|
||||
@@ -132,18 +157,18 @@ assign uploading_dump = ioctl_upload && (ioctl_index==HS_DUMPINDEX);
|
||||
assign ram_access = uploading_dump | writing_scores | checking_scores;
|
||||
assign ram_address = ram_addr[HS_ADDRESSWIDTH-1:0];
|
||||
|
||||
reg [3:0] state = 4'b0000; // Current state machine index
|
||||
reg [3:0] next_state = 4'b0000; // Next state machine index to move to after wait timer expires
|
||||
reg [(SM_STATEWIDTH-1):0] state = SM_INIT; // Current state machine index
|
||||
reg [(SM_STATEWIDTH-1):0] next_state = SM_INIT; // Next state machine index to move to after wait timer expires
|
||||
reg [31:0] wait_timer; // Wait timer for inital/read/write delays
|
||||
|
||||
reg [CFG_ADDRESSWIDTH-1:0] counter = 1'b0; // Index for current config table entry
|
||||
reg [CFG_ADDRESSWIDTH-1:0] total_entries=1'b0; // Total count of config table entries
|
||||
reg [CFG_ADDRESSWIDTH-1:0] total_entries = 1'b0; // Total count of config table entries
|
||||
reg reset_last = 1'b0; // Last cycle reset
|
||||
reg [7:0] write_counter = 1'b0; // Index of current game RAM write attempt
|
||||
|
||||
reg [7:0] last_ioctl_index; // Last cycle HPS IO index
|
||||
reg last_ioctl_download=0; // Last cycle HPS IO download
|
||||
reg last_ioctl_upload=0; // Last cycle HPS IO upload
|
||||
reg last_ioctl_download = 0;// Last cycle HPS IO download
|
||||
reg last_ioctl_upload = 0; // Last cycle HPS IO upload
|
||||
reg [7:0] last_ioctl_dout; // Last cycle HPS IO data out
|
||||
reg [7:0] last_ioctl_dout2; // Last cycle +1 HPS IO data out
|
||||
reg [7:0] last_ioctl_dout3; // Last cycle +2 HPS IO data out
|
||||
@@ -235,12 +260,16 @@ begin
|
||||
// Get header chunk data
|
||||
if(parsing_header)
|
||||
begin
|
||||
if(ioctl_wr & (header_chunk == 4'd3)) START_WAIT <= { last_ioctl_dout3, last_ioctl_dout2, last_ioctl_dout, ioctl_dout };
|
||||
if(ioctl_wr & (header_chunk == 4'd5)) CHECK_WAIT <= { last_ioctl_dout, ioctl_dout };
|
||||
if(ioctl_wr & (header_chunk == 4'd7)) CHECK_HOLD <= { last_ioctl_dout, ioctl_dout };
|
||||
if(ioctl_wr & (header_chunk == 4'd9)) WRITE_HOLD <= { last_ioctl_dout, ioctl_dout };
|
||||
if(ioctl_wr & (header_chunk == 4'd11)) WRITE_REPEATCOUNT <= { last_ioctl_dout, ioctl_dout };
|
||||
if(ioctl_wr & (header_chunk == 4'd13)) WRITE_REPEATWAIT <= { last_ioctl_dout, ioctl_dout };
|
||||
if(ioctl_wr)
|
||||
begin
|
||||
if(header_chunk == 4'd3) START_WAIT <= { last_ioctl_dout3, last_ioctl_dout2, last_ioctl_dout, ioctl_dout };
|
||||
if(header_chunk == 4'd5) CHECK_WAIT <= { last_ioctl_dout, ioctl_dout };
|
||||
if(header_chunk == 4'd7) CHECK_HOLD <= { last_ioctl_dout, ioctl_dout };
|
||||
if(header_chunk == 4'd9) WRITE_HOLD <= { last_ioctl_dout, ioctl_dout };
|
||||
if(header_chunk == 4'd11) WRITE_REPEATCOUNT <= { last_ioctl_dout, ioctl_dout };
|
||||
if(header_chunk == 4'd13) WRITE_REPEATWAIT <= { last_ioctl_dout, ioctl_dout };
|
||||
if(header_chunk == 4'd14) ACCESS_PAUSEPAD <= ioctl_dout;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
@@ -285,8 +314,8 @@ begin
|
||||
if (reset_last == 1'b1 && reset == 1'b0)
|
||||
begin
|
||||
wait_timer <= START_WAIT;
|
||||
next_state <= 4'b0000;
|
||||
state <= 4'b1111;
|
||||
next_state <= SM_INIT;
|
||||
state <= SM_TIMER;
|
||||
counter <= 1'b0;
|
||||
initialised <= initialised + 1'b1;
|
||||
end
|
||||
@@ -317,34 +346,45 @@ begin
|
||||
begin
|
||||
// State machine to write data to game RAM
|
||||
case (state)
|
||||
4'b0000: // Start state machine
|
||||
SM_INIT: // Start state machine
|
||||
begin
|
||||
// Setup base addresses
|
||||
local_addr <= 0;
|
||||
base_io_addr <= 25'b0;
|
||||
// Reset entry counter and states
|
||||
counter <= 0;
|
||||
writing_scores <= 1'b0;
|
||||
checking_scores <= 1'b0;
|
||||
state <= 4'b0001;
|
||||
// Setup base addresses
|
||||
local_addr <= 0;
|
||||
base_io_addr <= 25'b0;
|
||||
// Reset entry counter and states
|
||||
counter <= 0;
|
||||
writing_scores <= 1'b0;
|
||||
checking_scores <= 1'b0;
|
||||
pause_cpu <= 1'b0;
|
||||
state <= SM_CHECKPREP;
|
||||
end
|
||||
|
||||
4'b0001: // Start start/end check run
|
||||
// Start/end check states
|
||||
// ----------------------
|
||||
SM_CHECKPREP: // Prepare start/end check run - pause CPU in readiness for RAM access
|
||||
begin
|
||||
checking_scores <= 1'b1;
|
||||
ram_addr <= {1'b0, addr_base};
|
||||
state <= 4'b0010;
|
||||
wait_timer <= CHECK_HOLD;
|
||||
state <= SM_TIMER;
|
||||
next_state <= SM_CHECKBEGIN;
|
||||
pause_cpu <= 1'b1;
|
||||
wait_timer <= ACCESS_PAUSEPAD;
|
||||
end
|
||||
|
||||
4'b0010: // Start check
|
||||
SM_CHECKBEGIN: // Begin start/end check run - enable RAM access
|
||||
begin
|
||||
checking_scores <= 1'b1;
|
||||
ram_addr <= {1'b0, addr_base};
|
||||
state <= SM_CHECKSTARTVAL;
|
||||
wait_timer <= CHECK_HOLD;
|
||||
end
|
||||
|
||||
SM_CHECKSTARTVAL: // Start check
|
||||
begin
|
||||
// Check for matching start value
|
||||
if(wait_timer != CHECK_HOLD & ioctl_din == start_val)
|
||||
begin
|
||||
// Prepare end check
|
||||
ram_addr <= end_addr;
|
||||
state <= 4'b0100;
|
||||
state <= SM_CHECKENDVAL;
|
||||
wait_timer <= CHECK_HOLD;
|
||||
end
|
||||
else
|
||||
@@ -357,24 +397,24 @@ begin
|
||||
else
|
||||
begin
|
||||
// - If no match after read wait then stop check run and schedule restart of state machine
|
||||
next_state <= 4'b0000;
|
||||
state <= 4'b1111;
|
||||
next_state <= SM_CHECKCANCEL;
|
||||
state <= SM_TIMER;
|
||||
checking_scores <= 1'b0;
|
||||
wait_timer <= CHECK_WAIT;
|
||||
wait_timer <= ACCESS_PAUSEPAD;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
4'b0100: // End check
|
||||
SM_CHECKENDVAL: // End check
|
||||
begin
|
||||
// Check for matching end value
|
||||
if (wait_timer != CHECK_HOLD & ioctl_din == end_val)
|
||||
begin
|
||||
if (counter == total_entries)
|
||||
begin
|
||||
// If this was the last entry then move to phase II, copying scores into game ram
|
||||
// If this was the last entry then move on to writing scores to game ram
|
||||
checking_scores <= 1'b0;
|
||||
state <= 4'b1001;
|
||||
state <= SM_WRITEBEGIN; // Bypass SM_WRITEPREP as we are already paused
|
||||
counter <= 1'b0;
|
||||
write_counter <= 1'b0;
|
||||
ram_write <= 1'b0;
|
||||
@@ -384,7 +424,7 @@ begin
|
||||
begin
|
||||
// Increment counter and restart state machine to check next entry
|
||||
counter <= counter + 1'b1;
|
||||
state <= 4'b0001;
|
||||
state <= SM_CHECKBEGIN;
|
||||
end
|
||||
end
|
||||
else
|
||||
@@ -396,25 +436,58 @@ begin
|
||||
end
|
||||
else
|
||||
begin
|
||||
// - If no match after read wait then stop check run and reset state machine
|
||||
state <= 4'b0000;
|
||||
// - If no match after read wait then stop check run and schedule restart of state machine
|
||||
next_state <= SM_CHECKCANCEL;
|
||||
state <= SM_TIMER;
|
||||
checking_scores <= 1'b0;
|
||||
wait_timer <= CHECK_WAIT;
|
||||
wait_timer <= ACCESS_PAUSEPAD;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// this section walks through our temporary ram and copies into game ram
|
||||
// it needs to happen in chunks, because the game ram isn't necessarily consecutive
|
||||
4'b0110:
|
||||
SM_CHECKCANCEL: // Cancel start/end check run - disable RAM access and keep CPU paused
|
||||
begin
|
||||
local_addr <= local_addr + 1'b1;
|
||||
pause_cpu <= 1'b0;
|
||||
next_state <= SM_INIT;
|
||||
state <= SM_TIMER;
|
||||
wait_timer <= CHECK_WAIT;
|
||||
end
|
||||
|
||||
// Write to game RAM states
|
||||
// ----------------------
|
||||
SM_WRITEPREP: // Prepare to write scores - pause CPU in readiness for RAM access (only used on subsequent write attempts)
|
||||
begin
|
||||
state <= SM_TIMER;
|
||||
next_state <= SM_WRITEBEGIN;
|
||||
pause_cpu <= 1'b1;
|
||||
wait_timer <= ACCESS_PAUSEPAD;
|
||||
end
|
||||
|
||||
SM_WRITEBEGIN: // Writing scores to game RAM begins
|
||||
begin
|
||||
writing_scores <= 1'b1; // Enable muxes if necessary
|
||||
write_counter <= write_counter + 1'b1;
|
||||
state <= SM_WRITEREADY;
|
||||
end
|
||||
|
||||
SM_WRITEREADY: // local ram should be correct, start write to game RAM
|
||||
begin
|
||||
ram_addr <= addr_base + (local_addr - base_io_addr);
|
||||
state <= SM_TIMER;
|
||||
next_state <= SM_WRITEDONE;
|
||||
wait_timer <= WRITE_HOLD;
|
||||
ram_write <= 1'b1;
|
||||
end
|
||||
|
||||
SM_WRITEDONE:
|
||||
begin
|
||||
local_addr <= local_addr + 1'b1; // Increment to next byte of entry
|
||||
if (ram_addr == end_addr)
|
||||
begin
|
||||
// End of entry reached
|
||||
if (counter == total_entries)
|
||||
begin
|
||||
state <= 4'b1000;
|
||||
state <= SM_WRITECOMPLETE;
|
||||
end
|
||||
else
|
||||
begin
|
||||
@@ -422,58 +495,49 @@ begin
|
||||
counter <= counter + 1'b1;
|
||||
write_counter <= 1'b0;
|
||||
base_io_addr <= local_addr + 1'b1;
|
||||
state <= 4'b1001;
|
||||
state <= SM_WRITEBEGIN;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
state <= 4'b1010;
|
||||
state <= SM_WRITEREADY;
|
||||
end
|
||||
ram_write <= 1'b0;
|
||||
end
|
||||
|
||||
4'b1000: // Hiscore write to RAM completed
|
||||
SM_WRITECOMPLETE: // Hiscore write to RAM completed
|
||||
begin
|
||||
ram_write <= 1'b0;
|
||||
writing_scores <= 1'b0;
|
||||
state <= SM_TIMER;
|
||||
if(write_counter < WRITE_REPEATCOUNT)
|
||||
begin
|
||||
// Schedule next write
|
||||
state <= 4'b1111;
|
||||
next_state <= 4'b1001;
|
||||
next_state <= SM_WRITERETRY;
|
||||
local_addr <= 0;
|
||||
wait_timer <= WRITE_REPEATWAIT;
|
||||
end
|
||||
end
|
||||
|
||||
4'b1001: // Writing scores to game RAM begins
|
||||
begin
|
||||
writing_scores <= 1'b1; // indicate that writing has begun, will hold pause until write is complete if hooked up in core
|
||||
write_counter <= write_counter + 1'b1;
|
||||
state <= 4'b1010;
|
||||
end
|
||||
|
||||
4'b1010: // local ram is correct
|
||||
begin
|
||||
state <= 4'b1110;
|
||||
ram_addr <= addr_base + (local_addr - base_io_addr);
|
||||
ram_write <= 1'b1;
|
||||
wait_timer <= WRITE_HOLD;
|
||||
end
|
||||
|
||||
4'b1110: // hold write for wait_timer
|
||||
begin
|
||||
if (wait_timer > 1'b0)
|
||||
begin
|
||||
wait_timer <= wait_timer - 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
state <= 4'b0110;
|
||||
next_state <= SM_STOPPED;
|
||||
wait_timer <= ACCESS_PAUSEPAD;
|
||||
end
|
||||
end
|
||||
|
||||
4'b1111: // timer wait state
|
||||
|
||||
SM_WRITERETRY: // Stop pause and schedule next write
|
||||
begin
|
||||
pause_cpu <= 1'b0;
|
||||
state <= SM_TIMER;
|
||||
next_state <= SM_WRITEPREP;
|
||||
wait_timer <= WRITE_REPEATWAIT;
|
||||
end
|
||||
|
||||
SM_STOPPED:
|
||||
begin
|
||||
pause_cpu <= 1'b0;
|
||||
end
|
||||
|
||||
SM_TIMER: // timer wait state
|
||||
begin
|
||||
if (wait_timer > 1'b0)
|
||||
wait_timer <= wait_timer - 1'b1;
|
||||
|
||||
@@ -57,6 +57,7 @@ port (
|
||||
dn_addr : in std_logic_vector(15 downto 0);
|
||||
dn_data : in std_logic_vector(7 downto 0);
|
||||
dn_wr : in std_logic;
|
||||
dn_index : in std_logic_vector(7 downto 0);
|
||||
|
||||
-- VGA Interface ----------------------------------------------------------
|
||||
O_VIDEO_R : out std_logic_vector( 1 downto 0);
|
||||
@@ -137,6 +138,8 @@ architecture struct of ladybug is
|
||||
signal but_chute_s : std_logic_vector( 1 downto 0) := (others=>'0');
|
||||
|
||||
signal rom_cpu1_cs, rom_cpu2_cs, rom_cpu3_cs, rom_sprite_l_cs, rom_sprite_u_cs, rom_char_l_cs, rom_char_u_cs : std_logic;
|
||||
|
||||
signal rom_download : std_logic;
|
||||
begin
|
||||
|
||||
O_PIXCE <= clk_en_5mhz_s;
|
||||
@@ -189,7 +192,11 @@ begin
|
||||
hs_data_in => hs_data_in,
|
||||
hs_data_out => hs_data_out,
|
||||
hs_write => hs_write,
|
||||
hs_access => hs_access
|
||||
hs_access => hs_access,
|
||||
dn_addr => dn_addr,
|
||||
dn_data => dn_data,
|
||||
dn_wr => dn_wr,
|
||||
dn_index => dn_index
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
@@ -211,12 +218,13 @@ begin
|
||||
rom_sprite_u_cs <= '1' when dn_addr(15 downto 12)=X"7" else '0';
|
||||
rom_char_l_cs <= '1' when dn_addr(15 downto 12)=X"8" else '0';
|
||||
rom_char_u_cs <= '1' when dn_addr(15 downto 12)=X"9" else '0';
|
||||
rom_download <= '1' when dn_wr = '1' and dn_index(7 downto 0) = "00000000" else '0';
|
||||
|
||||
inst_rom_spritel : work.dpram generic map (12,8)
|
||||
port map
|
||||
(
|
||||
clock_a => clk_20mhz_s,
|
||||
wren_a => dn_wr and rom_sprite_l_cs,
|
||||
wren_a => rom_download and rom_sprite_l_cs,
|
||||
address_a => dn_addr(11 downto 0),
|
||||
data_a => dn_data,
|
||||
|
||||
@@ -229,7 +237,7 @@ begin
|
||||
port map
|
||||
(
|
||||
clock_a => clk_20mhz_s,
|
||||
wren_a => dn_wr and rom_sprite_u_cs,
|
||||
wren_a => rom_download and rom_sprite_u_cs,
|
||||
address_a => dn_addr(11 downto 0),
|
||||
data_a => dn_data,
|
||||
|
||||
@@ -242,7 +250,7 @@ begin
|
||||
port map
|
||||
(
|
||||
clock_a => clk_20mhz_s,
|
||||
wren_a => dn_wr and rom_char_l_cs,
|
||||
wren_a => rom_download and rom_char_l_cs,
|
||||
address_a => dn_addr(11 downto 0),
|
||||
data_a => dn_data,
|
||||
|
||||
@@ -255,7 +263,7 @@ begin
|
||||
port map
|
||||
(
|
||||
clock_a => clk_20mhz_s,
|
||||
wren_a => dn_wr and rom_char_u_cs,
|
||||
wren_a => rom_download and rom_char_u_cs,
|
||||
address_a => dn_addr(11 downto 0),
|
||||
data_a => dn_data,
|
||||
|
||||
@@ -268,7 +276,7 @@ begin
|
||||
port map
|
||||
(
|
||||
clock_a => clk_20mhz_s,
|
||||
wren_a => dn_wr and rom_cpu1_cs,
|
||||
wren_a => rom_download and rom_cpu1_cs,
|
||||
address_a => dn_addr(12 downto 0),
|
||||
data_a => dn_data,
|
||||
|
||||
@@ -281,7 +289,7 @@ begin
|
||||
port map
|
||||
(
|
||||
clock_a => clk_20mhz_s,
|
||||
wren_a => dn_wr and rom_cpu2_cs,
|
||||
wren_a => rom_download and rom_cpu2_cs,
|
||||
address_a => dn_addr(12 downto 0),
|
||||
data_a => dn_data,
|
||||
|
||||
@@ -294,7 +302,7 @@ begin
|
||||
port map
|
||||
(
|
||||
clock_a => clk_20mhz_s,
|
||||
wren_a => dn_wr and rom_cpu3_cs,
|
||||
wren_a => rom_download and rom_cpu3_cs,
|
||||
address_a => dn_addr(12 downto 0),
|
||||
data_a => dn_data,
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity ladybug_cpu_unit is
|
||||
port (
|
||||
@@ -78,6 +79,11 @@ entity ladybug_cpu_unit is
|
||||
cs12_n_o : out std_logic;
|
||||
cs13_n_o : out std_logic;
|
||||
|
||||
dn_addr : in std_logic_vector(15 downto 0);
|
||||
dn_data : in std_logic_vector(7 downto 0);
|
||||
dn_wr : in std_logic;
|
||||
dn_index : in std_logic_vector(7 downto 0);
|
||||
|
||||
pause : in std_logic;
|
||||
|
||||
hs_address : in std_logic_vector(15 downto 0);
|
||||
@@ -114,6 +120,8 @@ architecture struct of ladybug_cpu_unit is
|
||||
signal ram_cpu_cs_n_s : std_logic;
|
||||
|
||||
signal vcc_s : std_logic;
|
||||
|
||||
signal decrypt_prom_wr : std_logic;
|
||||
|
||||
begin
|
||||
vcc_s <= '1';
|
||||
@@ -156,24 +164,24 @@ begin
|
||||
-----------------------------------------------------------------------------
|
||||
-- The CPU RAM
|
||||
-----------------------------------------------------------------------------
|
||||
cpu_ram_b : entity work.ladybug_cpu_ram
|
||||
port map (
|
||||
clk1_i => clk_20mhz_i,
|
||||
clk_en1_i => clk_en_4mhz_i,
|
||||
a1_i => a_s(11 downto 0),
|
||||
cs1_n_i => cs_n_s(6),
|
||||
we1_n_i => wr_n_s,
|
||||
d1_i => d_from_cpu_s,
|
||||
d1_o => d_from_ram_s,
|
||||
cpu_ram_b : entity work.ladybug_cpu_ram
|
||||
port map (
|
||||
clk1_i => clk_20mhz_i,
|
||||
clk_en1_i => clk_en_4mhz_i,
|
||||
a1_i => a_s(11 downto 0),
|
||||
cs1_n_i => cs_n_s(6),
|
||||
we1_n_i => wr_n_s,
|
||||
d1_i => d_from_cpu_s,
|
||||
d1_o => d_from_ram_s,
|
||||
|
||||
clk2_i => clk_20mhz_i,
|
||||
clk_en2_i => '1',
|
||||
a2_i => hs_address(11 downto 0),
|
||||
cs2_n_i => '0',
|
||||
we2_n_i => not hs_write,
|
||||
d2_i => hs_data_in,
|
||||
d2_o => hs_data_out
|
||||
);
|
||||
clk2_i => clk_20mhz_i,
|
||||
clk_en2_i => '1',
|
||||
a2_i => hs_address(11 downto 0),
|
||||
cs2_n_i => '0',
|
||||
we2_n_i => not hs_write,
|
||||
d2_i => hs_data_in,
|
||||
d2_o => hs_data_out
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- The Address Decoder
|
||||
@@ -228,12 +236,19 @@ begin
|
||||
-- Decrytion PROMs
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
decrypt_prom : entity work.prom_decrypt
|
||||
port map (
|
||||
CLK => clk_20mhz_i,
|
||||
ADDR => rom_cpu_d_i,
|
||||
DATA => d_decrypted_s
|
||||
);
|
||||
decrypt_prom_wr <= '1' when (dn_wr = '1' and dn_index(7 downto 0) = "00000010" and dn_addr(8) = '1') else '0';
|
||||
|
||||
decrypt_prom : entity work.dpram generic map(8,8)
|
||||
port map (
|
||||
clock_a => clk_20mhz_i,
|
||||
address_a => dn_addr(7 downto 0),
|
||||
data_a => dn_data,
|
||||
wren_a => decrypt_prom_wr,
|
||||
|
||||
clock_b => clk_20mhz_i,
|
||||
address_b => rom_cpu_d_i,
|
||||
q_b => d_decrypted_s
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Only opcodes (i.e. instruction fetches) have to be decrypted
|
||||
|
||||
@@ -91,6 +91,11 @@ entity ladybug_machine is
|
||||
rom_sprite_a_o : out std_logic_vector(11 downto 0);
|
||||
rom_sprite_d_i : in std_logic_vector(15 downto 0);
|
||||
|
||||
dn_addr : in std_logic_vector(15 downto 0);
|
||||
dn_data : in std_logic_vector(7 downto 0);
|
||||
dn_wr : in std_logic;
|
||||
dn_index : in std_logic_vector(7 downto 0);
|
||||
|
||||
pause : in std_logic;
|
||||
-- Hiscore
|
||||
hs_address : in std_logic_vector(15 downto 0);
|
||||
@@ -253,7 +258,11 @@ begin
|
||||
hs_address => hs_address,
|
||||
hs_data_in => hs_data_in,
|
||||
hs_data_out => hs_data_out_cpu,
|
||||
hs_write => hs_write and hs_cs_cpu
|
||||
hs_write => hs_write and hs_cs_cpu,
|
||||
dn_addr => dn_addr,
|
||||
dn_data => dn_data,
|
||||
dn_wr => dn_wr,
|
||||
dn_index => dn_index
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
@@ -302,7 +311,11 @@ begin
|
||||
hs_address => hs_address,
|
||||
hs_data_in => hs_data_in,
|
||||
hs_data_out => hs_data_out_vram,
|
||||
hs_write => hs_write and hs_cs_vram
|
||||
hs_write => hs_write and hs_cs_vram,
|
||||
dn_addr => dn_addr,
|
||||
dn_data => dn_data,
|
||||
dn_wr => dn_wr,
|
||||
dn_index => dn_index
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
@@ -57,7 +57,11 @@ entity ladybug_rgb is
|
||||
sig_i : in std_logic_vector(4 downto 1);
|
||||
rgb_r_o : out std_logic_vector(1 downto 0);
|
||||
rgb_g_o : out std_logic_vector(1 downto 0);
|
||||
rgb_b_o : out std_logic_vector(1 downto 0)
|
||||
rgb_b_o : out std_logic_vector(1 downto 0);
|
||||
dn_addr : in std_logic_vector(15 downto 0);
|
||||
dn_data : in std_logic_vector(7 downto 0);
|
||||
dn_wr : in std_logic;
|
||||
dn_index : in std_logic_vector(7 downto 0)
|
||||
);
|
||||
|
||||
end ladybug_rgb;
|
||||
@@ -68,6 +72,8 @@ architecture rtl of ladybug_rgb is
|
||||
signal rgb_s : std_logic_vector(8 downto 1);
|
||||
signal rgb_n_q : std_logic_vector(8 downto 1);
|
||||
|
||||
signal prom_wr : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
@@ -98,12 +104,20 @@ begin
|
||||
-----------------------------------------------------------------------------
|
||||
-- The RGB Conversion PROM
|
||||
-----------------------------------------------------------------------------
|
||||
rgb_prom_b : entity work.prom_10_2
|
||||
port map (
|
||||
CLK => clk_20mhz_i,
|
||||
ADDR => a_s,
|
||||
DATA => rgb_s
|
||||
);
|
||||
|
||||
prom_wr <= '1' when (dn_wr = '1' and dn_index(7 downto 0) = "00000010" and dn_addr(8 downto 5) = "0001") else '0';
|
||||
|
||||
rgb_prom_b : entity work.dpram generic map(5,8)
|
||||
port map (
|
||||
clock_a => clk_20mhz_i,
|
||||
address_a => dn_addr(4 downto 0),
|
||||
data_a => dn_data,
|
||||
wren_a => prom_wr,
|
||||
|
||||
clock_b => clk_20mhz_i,
|
||||
address_b => a_s,
|
||||
q_b => rgb_s
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process rgb_latch
|
||||
|
||||
@@ -81,7 +81,12 @@ port (
|
||||
sig_o : out std_logic_vector( 4 downto 1);
|
||||
-- Sprite ROM Interface ---------------------------------------------------
|
||||
rom_sprite_a_o : out std_logic_vector(11 downto 0);
|
||||
rom_sprite_d_i : in std_logic_vector(15 downto 0)
|
||||
rom_sprite_d_i : in std_logic_vector(15 downto 0);
|
||||
|
||||
dn_addr : in std_logic_vector(15 downto 0);
|
||||
dn_data : in std_logic_vector(7 downto 0);
|
||||
dn_wr : in std_logic;
|
||||
dn_index : in std_logic_vector(7 downto 0)
|
||||
);
|
||||
|
||||
end ladybug_sprite;
|
||||
@@ -169,6 +174,9 @@ architecture rtl of ladybug_sprite is
|
||||
|
||||
signal vram_q : std_logic_vector(15 downto 0);
|
||||
|
||||
signal prom_F4_wr : std_logic;
|
||||
signal prom_C4_wr : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
@@ -505,11 +513,18 @@ begin
|
||||
lu_a_s(1) <= qh2_s;
|
||||
lu_a_s(0) <= qh1_s;
|
||||
|
||||
prom_F4 : entity work.prom_10_1
|
||||
prom_F4_wr <= '1' when (dn_wr = '1' and dn_index(7 downto 0) = "00000010" and dn_addr(8 downto 5) = "0000") else '0';
|
||||
|
||||
prom_F4 : entity work.dpram generic map(5,8)
|
||||
port map (
|
||||
CLK => clk_20mhz_i,
|
||||
ADDR => lu_a_s,
|
||||
DATA => lu_d_s
|
||||
clock_a => clk_20mhz_i,
|
||||
address_a => dn_addr(4 downto 0),
|
||||
data_a => dn_data,
|
||||
wren_a => prom_F4_wr,
|
||||
|
||||
clock_b => clk_20mhz_i,
|
||||
address_b => lu_a_s,
|
||||
q_b => lu_d_s
|
||||
);
|
||||
|
||||
lu_d_mux_s <= lu_d_s(3 downto 0) when cl_q(3) = '0' else lu_d_s(7 downto 4);
|
||||
@@ -523,13 +538,19 @@ begin
|
||||
ctrl_lu_a_s(3) <= h_i(0);
|
||||
ctrl_lu_a_s(4) <= h_i(1);
|
||||
|
||||
prom_C4 : entity work.prom_10_3
|
||||
prom_C4_wr <= '1' when (dn_wr = '1' and dn_index(7 downto 0) = "00000010" and dn_addr(8 downto 5) = "0010") else '0';
|
||||
prom_C4 : entity work.dpram generic map(5,8)
|
||||
port map (
|
||||
CLK => clk_20mhz_i,
|
||||
ADDR => ctrl_lu_a_s,
|
||||
DATA => ctrl_lu_d_s
|
||||
);
|
||||
clock_a => clk_20mhz_i,
|
||||
address_a => dn_addr(4 downto 0),
|
||||
data_a => dn_data,
|
||||
wren_a => prom_C4_wr,
|
||||
|
||||
clock_b => clk_20mhz_i,
|
||||
address_b => ctrl_lu_a_s,
|
||||
q_b => ctrl_lu_d_s
|
||||
);
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process ctrl_lu_seq
|
||||
--
|
||||
|
||||
@@ -87,6 +87,11 @@ entity ladybug_video_unit is
|
||||
rom_sprite_a_o : out std_logic_vector(11 downto 0);
|
||||
rom_sprite_d_i : in std_logic_vector(15 downto 0);
|
||||
|
||||
dn_addr : in std_logic_vector(15 downto 0);
|
||||
dn_data : in std_logic_vector(7 downto 0);
|
||||
dn_wr : in std_logic;
|
||||
dn_index : in std_logic_vector(7 downto 0);
|
||||
|
||||
pause : in std_logic;
|
||||
|
||||
hs_address : in std_logic_vector(15 downto 0);
|
||||
@@ -220,7 +225,11 @@ begin
|
||||
blank_i => blank_s,
|
||||
sig_o => sig_s,
|
||||
rom_sprite_a_o => rom_sprite_a_o,
|
||||
rom_sprite_d_i => rom_sprite_d_i
|
||||
rom_sprite_d_i => rom_sprite_d_i,
|
||||
dn_addr => dn_addr,
|
||||
dn_data => dn_data,
|
||||
dn_wr => dn_wr,
|
||||
dn_index => dn_index
|
||||
);
|
||||
|
||||
|
||||
@@ -236,10 +245,13 @@ begin
|
||||
sig_i => sig_s,
|
||||
rgb_r_o => rgb_r_o,
|
||||
rgb_g_o => rgb_g_o,
|
||||
rgb_b_o => rgb_b_o
|
||||
rgb_b_o => rgb_b_o,
|
||||
dn_addr => dn_addr,
|
||||
dn_data => dn_data,
|
||||
dn_wr => dn_wr,
|
||||
dn_index => dn_index
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Bus Multiplexer
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
93
rtl/pause.v
Normal file
93
rtl/pause.v
Normal file
@@ -0,0 +1,93 @@
|
||||
//============================================================================
|
||||
// Generic pause handling for MiSTer cores.
|
||||
//
|
||||
// https://github.com/JimmyStones/Pause_MiSTer
|
||||
//
|
||||
// Copyright (c) 2021 Jim Gregory
|
||||
//
|
||||
// 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, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//============================================================================
|
||||
/*
|
||||
Features:
|
||||
- Pause can be triggered by user input, hiscore module or OSD opening (optionally controlled by setting in OSD)
|
||||
- When paused the RGB outputs will be halved after 10 seconds to reduce burn-in (optionally controlled by setting in OSD)
|
||||
- Reset signal will cancel user triggered pause
|
||||
|
||||
Version history:
|
||||
0001 - 2021-03-15 - First marked release
|
||||
============================================================================
|
||||
*/
|
||||
module pause #(
|
||||
parameter RW=8, // Width of red channel
|
||||
parameter GW=8, // Width of green channel
|
||||
parameter BW=8, // Width of blue channel
|
||||
parameter CLKSPD = 12 // Main clock speed in MHz
|
||||
)
|
||||
(
|
||||
input clk_sys, // Core system clock (should match HPS module)
|
||||
input reset, // CPU reset signal (active-high)
|
||||
input user_button, // User pause button signal (active-high)
|
||||
input pause_request, // Pause requested by other code (active-high)
|
||||
input [1:0] options, // Pause options from OSD
|
||||
// [0] = pause in OSD (active-high)
|
||||
// [1] = dim video (active-high)
|
||||
input OSD_STATUS, // OSD is open (active-high)
|
||||
input [(RW-1):0] r, // Red channel
|
||||
input [(GW-1):0] g, // Green channel
|
||||
input [(BW-1):0] b, // Blue channel
|
||||
|
||||
output pause_cpu, // Pause signal to CPU (active-high)
|
||||
output [(RW+GW+BW-1):0] rgb_out // RGB output to arcade_video module
|
||||
|
||||
);
|
||||
|
||||
// Option constants
|
||||
localparam pause_in_osd = 1'b0;
|
||||
localparam dim_video = 1'b1;
|
||||
|
||||
reg pause_toggle = 1'b0; // User paused (active-high)
|
||||
reg [31:0] pause_timer = 1'b0; // Time since pause
|
||||
reg [31:0] dim_timeout = (CLKSPD*10000000); // Time until video output dim (10 seconds @ CLKSPD Mhz)
|
||||
|
||||
assign pause_cpu = (pause_request | pause_toggle | (OSD_STATUS & options[pause_in_osd])) & !reset;
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
|
||||
// Track user pause button down
|
||||
reg user_button_last;
|
||||
user_button_last <= user_button;
|
||||
if(!user_button_last & user_button) pause_toggle <= ~pause_toggle;
|
||||
|
||||
// Clear user pause on reset
|
||||
if(pause_toggle & reset) pause_toggle <= 0;
|
||||
|
||||
if(pause_cpu & options[dim_video])
|
||||
begin
|
||||
// Track pause duration for video dim
|
||||
if((pause_timer<dim_timeout))
|
||||
begin
|
||||
pause_timer <= pause_timer + 1'b1;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
pause_timer <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// Dim video output if pause timer exceeds threshold
|
||||
assign rgb_out = (pause_timer >= dim_timeout) ? {r >> 1,g >> 1, b >> 1} : {r,g,b};
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user