1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-02-05 07:44:46 +00:00

Gyruss: make it fully synchronous

This commit is contained in:
Gyorgy Szombathelyi
2021-07-31 14:05:30 +02:00
parent 270dedfda2
commit f4d9ab5519
3 changed files with 130 additions and 98 deletions

View File

@@ -666,13 +666,15 @@ wire cs_linebuffer, sprite_flip;
wire [5:0] k503_R;
k503 u9F
(
.clk(clk_49m),
.clk_en(cen_6m),
.OB(spriteram_reg[7:0]),
.VCNT(vcnt_lat),
.H4(h_cnt[2]),
.H8(0),
.H8(1'b0),
.LD(h_cnt[1:0] != 2'b11),
.OCS(cs_linebuffer),
.OFLP(sprite_flip),
.NE83(sprite_flip),
.R(k503_R)
);
assign spriterom_A[5] = k503_R[5];
@@ -819,11 +821,11 @@ wire [4:0] sprite_D;
wire sprite_lbuff_sel, sprite_lbuff_dec0, sprite_lbuff_dec1;
k502 u6B
(
.RESET(1),
.CK1(clk_49m),
.CK1_EN(cen_12m),
.CK2(clk_49m),
.CEN(cen_6m),
.LD0(h_cnt[2:0] == 3'b000),
.CK2_EN(cen_6m),
.LD0(h_cnt[2:0] != 3'b111),
.H2(h_cnt[1]),
.H256(h_cnt[8]),
.SPAL(sprite_lut_D),

View File

@@ -2,7 +2,8 @@
//
// SystemVerilog implementation of the Konami 502 custom chip, used for
// generating sprites on a number of '80s Konami arcade PCBs
// Copyright (C) 2020, 2021 Ace
//
// Copyright (C) 2020 Ace
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
@@ -29,7 +30,7 @@
_| |_
SPLB(0) |_|1 28|_| VCC
_| |_
SPLB(1) |_|2 27|_| RESET
SPLB(1) |_|2 27|_| ?
_| |_
SPLB(2) |_|3 26|_| SPLB(4)
_| |_
@@ -62,10 +63,10 @@ Note: The SPLB pins are bidirectional - this model splits these pins into separa
module k502
(
input RESET,
input CK1,
input CK1_EN,
input CK2,
input CEN, //Set to 1 if using this code to replace a real 502
input CK2_EN,
input LD0,
input H2,
input H256,
@@ -81,39 +82,57 @@ module k502
//As the Konami 502 doesn't have a dedicated input for bit 2 of the horizontal counter (H4), generate
//this signal internally by dividing H2 by 2
reg h2_div = 0;
`ifdef SIM
always_ff @(posedge H2) begin
h2_div <= ~h2_div;
end
wire h4 = h2_div;
//Latch H256 on rising edge of LD0 and delay by one cycle (set to 0 if 502 is held in reset)
reg h256_lat = 0;
always_ff @(posedge LD0 or negedge RESET) begin
if(!RESET)
h256_lat <= 0;
else
h256_lat <= H256;
end
reg h256_dly = 0;
always_ff @(posedge h256_lat or negedge RESET) begin
if(!RESET)
h256_dly <= 0;
else
h256_dly <= ~h256_dly;
end
//Generate OSEL, OLD and OCLR
reg [1:0] osel_reg;
always_ff @(negedge H2 or negedge RESET) begin
if(!RESET)
osel_reg <= 2'b00;
else begin
if(!h4)
osel_reg[1] <= h256_dly;
else
osel_reg[0] <= osel_reg[1];
`else
reg h2_d;
always @(posedge CK2) begin
if (CK2_EN) begin
h2_d <= H2;
if (h2_d & H2) h2_div <= !h2_div; // falling edge of H2
end
end
`endif
wire h4 = h2_div;
reg h256_lat = 0;
reg h256_dly = 0;
`ifdef SIM
//Latch H256 on rising edge of LD0 and delay by one cycle
always_ff @(posedge LD0) begin
h256_lat <= H256;
end
always_ff @(posedge h256_lat) begin
h256_dly <= ~h256_dly;
end
`else
always @(posedge CK2) begin
if (CK2_EN & !LD0) begin
h256_lat <= H256;
if (!h256_lat & H256) h256_dly <= ~h256_dly;
end
end
`endif
//Generate OSEL, OLD and OCLR
reg [1:0] osel_reg;
`ifdef SIM
always_ff @(negedge H2) begin
if(!h4)
osel_reg[1] <= h256_dly;
else
osel_reg[0] <= osel_reg[1];
end
`else
assign osel_reg[1] = h256_dly;
always @(posedge CK2) begin
if (CK2_EN & h2_d & H2) begin // falling edge of H2
if(!h4) osel_reg[0] <= osel_reg[1];
end
end
`endif
assign OLD = ~osel_reg[1];
assign OSEL = osel_reg[0];
assign OCLR = ~osel_reg[0];
@@ -121,23 +140,22 @@ assign OCLR = ~osel_reg[0];
//Multiplex incoming line buffer RAM data
wire [3:0] lbuff_Dmux = OCLR ? SPLBi[3:0] : SPLBi[7:4];
//Latch incoming line buffer RAM data on the falling edge of CK1
//Latch incoming line buffer RAM data on the rising edge of CK1
reg [7:0] lbuff_lat;
always_ff @(negedge CK1) begin
if(!RESET)
lbuff_lat <= 8'd0;
else if(CEN)
lbuff_lat <= SPLBi;
end
//Latch multiplexed line buffer RAM data on the falling edge of CK2
reg [3:0] lbuff_mux_lat;
always_ff @(negedge CK2) begin
if(!RESET)
lbuff_mux_lat <= 4'd0;
else if(CEN)
lbuff_mux_lat <= lbuff_Dmux;
`ifdef SIM
always_ff @(posedge CK1) begin
lbuff_lat <= SPLBi;
lbuff_mux_lat <= lbuff_Dmux;
end
`else
always_ff @(posedge CK1) begin
if (CK1_EN) begin
lbuff_lat <= SPLBi;
lbuff_mux_lat <= lbuff_Dmux;
end
end
`endif
//Assign sprite data output
assign COL[4] = ~(|lbuff_mux_lat[3:0]);
@@ -150,10 +168,14 @@ wire sprite_pal_sel1 = (~lbuff_lat[3] & ~lbuff_lat[2] & ~lbuff_lat[1] & ~lbuff_l
//Multiplex sprite data from line buffer with palette data (lower 4 bits)
wire [7:0] sprite_pal_mux;
assign sprite_pal_mux[3:0] = osel_reg[0] ? (sprite_pal_sel1 ? SPAL : SPLBi[3:0]) : 4'h0;
assign sprite_pal_mux[3:0] = osel_reg[0] ?
(sprite_pal_sel1 ? SPAL : SPLBi[3:0]):
4'h0;
//Multiplex sprite data from line buffer with palette data (upper 4 bits)
assign sprite_pal_mux[7:4] = ~osel_reg[0] ? (sprite_pal_sel2 ? SPAL : SPLBi[7:4]) : 4'h0;
assign sprite_pal_mux[7:4] = ~osel_reg[0] ?
(sprite_pal_sel2 ? SPAL : SPLBi[7:4]):
4'h0;
//Output data to sprite line buffer
assign SPLBo = sprite_pal_mux;

View File

@@ -2,7 +2,8 @@
//
// SystemVerilog implementation of the Konami 503 custom chip, used by
// several Konami arcade PCBs for handling sprite data
// Copyright (C) 2020, 2021 Ace
//
// Copyright (C) 2020 Ace
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
@@ -25,29 +26,29 @@
//============================================================================
//Chip pinout:
/* _____________
/* _____________
_| |_
OB(7) |_|1 40|_| VCC
_| |_
OB(6) |_|2 39|_| VCNT(7)
OB(6) |_|2 39|_| V128
_| |_
OB(5) |_|3 38|_| VCNT(6)
OB(5) |_|3 38|_| V64
_| |_
OB(4) |_|4 37|_| VCNT(5)
OB(4) |_|4 37|_| V32
_| |_
OB(3) |_|5 36|_| VCNT(4)
OB(3) |_|5 36|_| V16
_| |_
OB(2) |_|6 35|_| VCNT(3)
OB(2) |_|6 35|_| V8
_| |_
OB(1) |_|7 34|_| VCNT(2)
OB(1) |_|7 34|_| V4
_| |_
OB(0) |_|8 33|_| VCNT(1)
OB(0) |_|8 33|_| V2
_| |_
R(5) |_|9 32|_| VCNT(0)
R(5) |_|9 32|_| V1
_| |_
R(4) |_|10 31|_| NC
_| |_
R(3) |_|11 30|_| OFLP
R(3) |_|11 30|_| NE83
_| |_
R(2) |_|12 29|_| OCS
_| |_
@@ -71,49 +72,56 @@ GND |_|20 21|_| NC
module k503
(
input [7:0] OB, //Sprite data input
input [7:0] VCNT, //Vertical counter input
input H4, H8, //Horizontal counter bits 2 (H4) and 3 (H8)
input LD, //LD input (pulses low when bits 0 and 1 of the horizontal counter are both 1)
output OCS, //Sprite line buffer chip select output
output OFLP, //Sprite flip output
output ODAT, //Signal to latch upper bits of sprite address
output OCOL, //Signal to load addresses for sprite line buffer
output [5:0] R //Lower 6 bits of sprite address
input clk,
input clk_en,
input [7:0] OB,
input [7:0] VCNT,
input H4, H8,
input LD,
output OCS,
output NE83,
output ODAT, OCOL,
output [5:0] R
);
//Sum sprite bits with vertical counter
wire [7:0] sprite_sum = OB + VCNT;
//Sum object bits with vertical counter
wire [7:0] obj_sum = OB + VCNT;
//Sprite select signal
wire sprite_sel = ~(&sprite_sum[7:4]);
//Control signal for object enable output
wire obj_ctl = ~(&obj_sum[7:4]);
//Sprite flip control
reg hflip, vflip;
always_ff @(posedge H4) begin
hflip <= OB[6];
vflip <= OB[7];
//Sprite control
wire sprite_ctrl = ~(~LD & ~H4 & ~H8) /* synthesis keep */;
reg ob6_lat, ob7_lat;
always_ff @(posedge clk) begin
if (clk_en & ~sprite_ctrl) begin
ob6_lat <= OB[6];
ob7_lat <= OB[7];
end
end
//Latch sprite information
reg [6:0] sprite;
always_ff @(negedge H4) begin
sprite <= {sprite_sel, hflip, vflip, sprite_sum[3:0]};
//Latch object information
reg [6:0] obj;
always_ff @(posedge clk) begin
if (clk_en & ~objdata)
obj <= {obj_ctl, ob6_lat, ob7_lat, obj_sum[3:0]};
end
wire sprite_vflip = sprite[4];
assign OFLP = sprite[5];
assign OCS = sprite[6];
wire obj_dat = obj[4];
assign NE83 = obj[5];
assign OCS = obj[6];
//Assign OCOL (sprite color) and ODAT (sprite data) outputs
assign OCOL = ({H8, H4, LD} != 3'b100);
assign ODAT = ({H8, H4, LD} != 3'b010);
//Assign OCOL and ODAT outputs
assign OCOL = ~(~LD & ~H4 & H8);
wire objdata = ~(~LD & H4 & ~H8) /* synthesis keep */;
assign ODAT = objdata;
//XOR final output for R
assign R[5] = (sprite[3] ^ sprite_vflip);
assign R[4] = (OFLP ^ H8);
assign R[3] = (OFLP ^ ~H4);
assign R[2] = (sprite[2] ^ sprite_vflip);
assign R[1] = (sprite[1] ^ sprite_vflip);
assign R[0] = (sprite[0] ^ sprite_vflip);
assign R[5] = (obj[3] ^ obj_dat);
assign R[4] = (NE83 ^ H8);
assign R[3] = (NE83 ^ ~H4);
assign R[2] = (obj[2] ^ obj_dat);
assign R[1] = (obj[1] ^ obj_dat);
assign R[0] = (obj[0] ^ obj_dat);
endmodule