Merge pull request #6 from brNX/master

Multiple I/O Regs fixes, OAM DMA from VRAM , RET cc opcode timing
This commit is contained in:
sorgelig
2018-11-13 16:11:27 +08:00
committed by GitHub
5 changed files with 157 additions and 118 deletions

33
gb.v
View File

@@ -53,6 +53,10 @@ wire sel_timer = (cpu_addr[15:4] == 12'hff0) && (cpu_addr[3:2] == 2'b01);
wire sel_video_reg = cpu_addr[15:4] == 12'hff4;
wire sel_video_oam = cpu_addr[15:8] == 8'hfe;
wire sel_joy = cpu_addr == 16'hff00; // joystick controller
wire sel_sb = cpu_addr == 16'hff01; // serial SB - Serial transfer data
wire sel_sc = cpu_addr == 16'hff02; // SC - Serial Transfer Control (R/W)
wire sel_nr50 = cpu_addr == 16'hff24; // Channel control / ON-OFF / Volume (R/W) //readonly no games use it
wire sel_nr51 = cpu_addr == 16'hff25; // Selection of Sound output terminal (R/W) //readonly no games use it
wire sel_rom = !cpu_addr[15]; // lower 32k are rom
wire sel_cram = cpu_addr[15:13] == 3'b101; // 8k cart ram at $a000
wire sel_vram = cpu_addr[15:13] == 3'b100; // 8k video ram at $8000
@@ -63,6 +67,13 @@ wire sel_zpram = (cpu_addr[15:7] == 9'b111111111) && // 127 bytes zero pageram a
(cpu_addr != 16'hffff);
wire sel_audio = (cpu_addr[15:8] == 8'hff) && // audio reg ff10 - ff3f
((cpu_addr[7:5] == 3'b001) || (cpu_addr[7:4] == 4'b0001));
//DMA can select from $0000 to $F100
wire dma_sel_rom = !dma_addr[15]; // lower 32k are rom
wire dma_sel_cram = dma_addr[15:13] == 3'b101; // 8k cart ram at $a000
wire dma_sel_vram = dma_addr[15:13] == 3'b100; // 8k video ram at $8000
wire dma_sel_iram = (dma_addr[15:14] == 2'b11) && (dma_addr[15:8] != 8'hff); // 8k internal ram at $c000
// the boot roms sees a special $42 flag in $ff50 if it's supposed to to a fast boot
wire sel_fast = fast_boot && cpu_addr == 16'hff50 && boot_rom_enabled;
@@ -72,9 +83,13 @@ wire [7:0] cpu_di =
irq_ack?irq_vec:
sel_fast?8'h42: // fast boot flag
sel_joy?joy_do: // joystick register
sel_sb?8'h0:
sel_sc?8'h7E:
sel_timer?timer_do: // timer registers
sel_video_reg?video_do: // video registers
sel_video_oam?video_do: // video object attribute memory
sel_nr50?8'h77:
sel_nr51?8'hF3:
sel_audio?audio_do: // audio registers
sel_rom?rom_do: // boot rom + cartridge rom
sel_cram?rom_do: // cartridge ram
@@ -82,7 +97,7 @@ wire [7:0] cpu_di =
sel_zpram?zpram_do: // zero page ram
sel_iram?iram_do: // internal ram
sel_ie?{3'b000, ie_r}: // interrupt enable register
sel_if?{3'b000, if_r}: // interrupt flag register
sel_if?{3'b111, if_r}: // interrupt flag register
8'hff;
wire cpu_wr_n;
@@ -143,7 +158,7 @@ wire [3:0] joy_p5 = ~{ joystick[7], joystick[6], joystick[5], joystick[4] } | {4
reg [1:0] p54;
always @(posedge clk) begin
if(reset) p54 <= 2'b11;
if(reset) p54 <= 2'b00;
else if(sel_joy && !cpu_wr_n) p54 <= cpu_do[5:4];
end
@@ -251,7 +266,7 @@ wire [7:0] video_do;
wire [12:0] video_addr;
wire [15:0] dma_addr;
wire video_rd, dma_rd;
wire [7:0] dma_data = (dma_addr[15:14]==2'b11)?iram_do:cart_do;
wire [7:0] dma_data = dma_sel_iram?iram_do:dma_sel_vram?vram_do:cart_do;
video video (
.reset ( reset ),
@@ -284,7 +299,7 @@ video video (
wire cpu_wr_vram = sel_vram && !cpu_wr_n;
wire [7:0] vram_do;
wire vram_wren = video_rd?1'b0:cpu_wr_vram;
wire [12:0] vram_addr = video_rd?video_addr:cpu_addr[12:0];
wire [12:0] vram_addr = video_rd?video_addr:(dma_rd&&dma_sel_vram)?dma_addr[12:0]:cpu_addr[12:0];
spram #(13) vram (
.clock ( clk ),
@@ -313,8 +328,8 @@ spram #(7) zpram (
// ------------------------- 8k internal ram --------------------------
// --------------------------------------------------------------------
wire iram_wren = dma_rd?1'b0:cpu_wr_iram;
wire [12:0] iram_addr = dma_rd?dma_addr[12:0]:cpu_addr[12:0];
wire iram_wren = (dma_rd&&dma_sel_iram)?1'b0:cpu_wr_iram;
wire [12:0] iram_addr = (dma_rd&&dma_sel_iram)?dma_addr[12:0]:cpu_addr[12:0];
wire cpu_wr_iram = sel_iram && !cpu_wr_n;
wire [7:0] iram_do;
@@ -342,9 +357,11 @@ end
// combine boot rom data with cartridge data
wire [7:0] rom_do = ((cpu_addr[14:8] == 7'h00) && boot_rom_enabled)?boot_rom_do:cart_do;
wire is_dma_cart_addr = (dma_sel_rom || dma_sel_cram); //rom or external ram
assign cart_di = cpu_do;
assign cart_addr = dma_rd?dma_addr:cpu_addr;
assign cart_rd = dma_rd || ((sel_rom || sel_cram) && !cpu_rd_n);
assign cart_addr = (dma_rd&&is_dma_cart_addr)?dma_addr:cpu_addr;
assign cart_rd = (dma_rd&&is_dma_cart_addr) || ((sel_rom || sel_cram) && !cpu_rd_n);
assign cart_wr = (sel_rom || sel_cram) && !cpu_wr_n;
wire [7:0] boot_rom_do;

View File

@@ -359,96 +359,6 @@ begin
null;
end case;
end if;
if s1_read = '1' then
case s1_addr is
-- Square 1
when "010000" => -- NR10 FF10 -PPP NSSS Sweep period, negate, shift
s1_readdata <= '1' & sq1_swper & sq1_swdir & sq1_swshift;
when "010001" => -- NR11 FF11 DDLL LLLL Duty, Length load (64-L)
s1_readdata <= sq1_duty & "111111";
when "010010" => -- NR12 FF12 VVVV APPP Starting volume, Envelope add mode, period
s1_readdata <= sq1_vol & sq1_envsgn & sq1_envper;
when "010011" => -- NR13 FF13 FFFF FFFF Frequency LSB
s1_readdata <= X"FF";
when "010100" => -- NR14 FF14 TL-- -FFF Trigger, Length enable, Frequency MSB
s1_readdata <= '0' & sq1_lenchk & "111111";
-- Square 2
when "010110" => -- NR21 FF16 DDLL LLLL Duty, Length load (64-L)
s1_readdata <= sq2_duty & "111111";
when "010111" => -- NR22 FF17 VVVV APPP Starting volume, Envelope add mode, period
s1_readdata <= sq2_vol & sq2_envsgn & sq2_envper;
when "011000" => -- NR23 FF18 FFFF FFFF Frequency LSB
s1_readdata <= X"FF";
when "011001" => -- NR24 FF19 TL-- -FFF Trigger, Length enable, Frequency MSB
s1_readdata <= '0' & sq2_lenchk & "111111";
when "100110" => -- NR52 FF26 P--- NW21 Power control/status, Channel length statuses
s1_readdata <= snd_enable & "00000" & sq2_playing & sq1_playing;
-- Wave
when "011010" => -- NR30 FF1A E--- ---- DAC power
s1_readdata <= wav_enable & "1111111";
when "011011" => -- NR31 FF1B LLLL LLLL Length load (256-L)
s1_readdata <= X"FF";
when "011100" => -- NR32 FF1C -VV- ---- Volume code (00=0%, 01=100%, 10=50%, 11=25%)
s1_readdata <= '1' & wav_volsh & "11111";
when "011101" => -- NR33 FF1D FFFF FFFF Frequency LSB
s1_readdata <= X"FF";
when "011110" => -- NR34 FF1E TL-- -FFF Trigger, Length enable, Frequency MSB
s1_readdata <= wav_trigger & wav_lenchk & "111111";
-- Noise
when "100000" => -- NR41 FF20 --LL LLLL Length load (64-L)
s1_readdata <= X"FF";
when "100001" => -- NR42 FF21 VVVV APPP Starting volume, Envelope add mode, period
s1_readdata <= noi_svol & noi_envsgn & noi_envper;
when "100010" => -- NR43 FF22 SSSS WDDD Clock shift, Width mode of LFSR, Divisor code
s1_readdata <= noi_freqsh & noi_short & noi_div;
when "100011" => -- NR44 FF23 TL-- ---- Trigger, Length enable
s1_readdata <= noi_trigger & noi_lenchk & "111111";
-- Wave Table
when "110000" => -- FF30 0000 1111 Samples 0 and 1
s1_readdata <= wav_ram(0) & wav_ram(1);
when "110001" => -- FF31 0000 1111 Samples 2 and 3
s1_readdata <= wav_ram(2) & wav_ram(3);
when "110010" => -- FF32 0000 1111 Samples 4 and 5
s1_readdata <= wav_ram(4) & wav_ram(5);
when "110011" => -- FF33 0000 1111 Samples 6 and 31
s1_readdata <= wav_ram(6) & wav_ram(7);
when "110100" => -- FF34 0000 1111 Samples 8 and 31
s1_readdata <= wav_ram(8) & wav_ram(9);
when "110101" => -- FF35 0000 1111 Samples 10 and 11
s1_readdata <= wav_ram(10) & wav_ram(11);
when "110110" => -- FF36 0000 1111 Samples 12 and 13
s1_readdata <= wav_ram(12) & wav_ram(13);
when "110111" => -- FF37 0000 1111 Samples 14 and 15
s1_readdata <= wav_ram(14) & wav_ram(15);
when "111000" => -- FF38 0000 1111 Samples 16 and 17
s1_readdata <= wav_ram(16) & wav_ram(17);
when "111001" => -- FF39 0000 1111 Samples 18 and 19
s1_readdata <= wav_ram(18) & wav_ram(19);
when "111010" => -- FF3A 0000 1111 Samples 20 and 21
s1_readdata <= wav_ram(20) & wav_ram(21);
when "111011" => -- FF3B 0000 1111 Samples 22 and 23
s1_readdata <= wav_ram(22) & wav_ram(23);
when "111100" => -- FF3C 0000 1111 Samples 24 and 25
s1_readdata <= wav_ram(24) & wav_ram(25);
when "111101" => -- FF3D 0000 1111 Samples 26 and 27
s1_readdata <= wav_ram(26) & wav_ram(27);
when "111110" => -- FF3E 0000 1111 Samples 28 and 29
s1_readdata <= wav_ram(28) & wav_ram(29);
when "111111" => -- FF3F 0000 1111 Samples 30 and 31
s1_readdata <= wav_ram(30) & wav_ram(31);
when others =>
s1_readdata <= X"FF";
end case;
end if;
wav_shift_r := wav_shift;
end if;
@@ -461,6 +371,96 @@ begin
end if;
end if;
end process;
process(s1_addr)
begin
case s1_addr is
-- Square 1
when "010000" => -- NR10 FF10 -PPP NSSS Sweep period, negate, shift
s1_readdata <= '1' & sq1_swper & sq1_swdir & sq1_swshift;
when "010001" => -- NR11 FF11 DDLL LLLL Duty, Length load (64-L)
s1_readdata <= sq1_duty & "111111";
when "010010" => -- NR12 FF12 VVVV APPP Starting volume, Envelope add mode, period
s1_readdata <= sq1_svol & sq1_envsgn & sq1_envper;
when "010011" => -- NR13 FF13 FFFF FFFF Frequency LSB
s1_readdata <= X"FF";
when "010100" => -- NR14 FF14 TL-- -FFF Trigger, Length enable, Frequency MSB
s1_readdata <= '1' & sq1_lenchk & "111111";
-- Square 2
when "010110" => -- NR21 FF16 DDLL LLLL Duty, Length load (64-L)
s1_readdata <= sq2_duty & "111111";
when "010111" => -- NR22 FF17 VVVV APPP Starting volume, Envelope add mode, period
s1_readdata <= sq2_vol & sq2_envsgn & sq2_envper;
when "011000" => -- NR23 FF18 FFFF FFFF Frequency LSB
s1_readdata <= X"FF";
when "011001" => -- NR24 FF19 TL-- -FFF Trigger, Length enable, Frequency MSB
s1_readdata <= '1' & sq2_lenchk & "111111";
when "100110" => -- NR52 FF26 P--- NW21 Power control/status, Channel length statuses
s1_readdata <= snd_enable & "11100" & sq2_playing & sq1_playing;
-- Wave
when "011010" => -- NR30 FF1A E--- ---- DAC power
s1_readdata <= wav_enable & "1111111";
when "011011" => -- NR31 FF1B LLLL LLLL Length load (256-L)
s1_readdata <= X"FF";
when "011100" => -- NR32 FF1C -VV- ---- Volume code (00=0%, 01=100%, 10=50%, 11=25%)
s1_readdata <= '1' & wav_volsh & "11111";
when "011101" => -- NR33 FF1D FFFF FFFF Frequency LSB
s1_readdata <= X"FF";
when "011110" => -- NR34 FF1E TL-- -FFF Trigger, Length enable, Frequency MSB
s1_readdata <= '1' & wav_lenchk & "111111";
-- Noise
when "100000" => -- NR41 FF20 --LL LLLL Length load (64-L)
s1_readdata <= X"FF";
when "100001" => -- NR42 FF21 VVVV APPP Starting volume, Envelope add mode, period
s1_readdata <= noi_svol & noi_envsgn & noi_envper;
when "100010" => -- NR43 FF22 SSSS WDDD Clock shift, Width mode of LFSR, Divisor code
s1_readdata <= noi_freqsh & noi_short & noi_div;
when "100011" => -- NR44 FF23 TL-- ---- Trigger, Length enable
s1_readdata <= '1' & noi_lenchk & "111111";
-- Wave Table
when "110000" => -- FF30 0000 1111 Samples 0 and 1
s1_readdata <= wav_ram(0) & wav_ram(1);
when "110001" => -- FF31 0000 1111 Samples 2 and 3
s1_readdata <= wav_ram(2) & wav_ram(3);
when "110010" => -- FF32 0000 1111 Samples 4 and 5
s1_readdata <= wav_ram(4) & wav_ram(5);
when "110011" => -- FF33 0000 1111 Samples 6 and 31
s1_readdata <= wav_ram(6) & wav_ram(7);
when "110100" => -- FF34 0000 1111 Samples 8 and 31
s1_readdata <= wav_ram(8) & wav_ram(9);
when "110101" => -- FF35 0000 1111 Samples 10 and 11
s1_readdata <= wav_ram(10) & wav_ram(11);
when "110110" => -- FF36 0000 1111 Samples 12 and 13
s1_readdata <= wav_ram(12) & wav_ram(13);
when "110111" => -- FF37 0000 1111 Samples 14 and 15
s1_readdata <= wav_ram(14) & wav_ram(15);
when "111000" => -- FF38 0000 1111 Samples 16 and 17
s1_readdata <= wav_ram(16) & wav_ram(17);
when "111001" => -- FF39 0000 1111 Samples 18 and 19
s1_readdata <= wav_ram(18) & wav_ram(19);
when "111010" => -- FF3A 0000 1111 Samples 20 and 21
s1_readdata <= wav_ram(20) & wav_ram(21);
when "111011" => -- FF3B 0000 1111 Samples 22 and 23
s1_readdata <= wav_ram(22) & wav_ram(23);
when "111100" => -- FF3C 0000 1111 Samples 24 and 25
s1_readdata <= wav_ram(24) & wav_ram(25);
when "111101" => -- FF3D 0000 1111 Samples 26 and 27
s1_readdata <= wav_ram(26) & wav_ram(27);
when "111110" => -- FF3E 0000 1111 Samples 28 and 29
s1_readdata <= wav_ram(28) & wav_ram(29);
when "111111" => -- FF3F 0000 1111 Samples 30 and 31
s1_readdata <= wav_ram(30) & wav_ram(31);
when others =>
s1_readdata <= X"FF";
end case;
end process;
sound : process(clk, snd_enable, en_snd, en_len, en_env, en_sweep)
constant duty_0 : std_logic_vector(0 to 7) := "00000001";

View File

@@ -1307,24 +1307,45 @@ begin
end case;
else
-- RET cc
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
Set_Addr_TO <= aSP;
else
MCycles <= "001";
end if;
TStates <= "101";
when 2 =>
IncDec_16 <= "0111";
Set_Addr_To <= aSP;
LDZ <= '1';
when 3 =>
Jump <= '1';
IncDec_16 <= "0111";
when others => null;
end case;
if Mode = 3 then
MCycles <= "101";
case to_integer(unsigned(MCycle)) is
when 2 =>
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
Set_Addr_TO <= aSP;
else
MCycles <= "010";
end if;
TStates <= "101";
when 3 =>
IncDec_16 <= "0111";
Set_Addr_To <= aSP;
LDZ <= '1';
when 4 =>
Jump <= '1';
IncDec_16 <= "0111";
when others => null;
end case;
else
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
Set_Addr_TO <= aSP;
else
MCycles <= "001";
end if;
TStates <= "101";
when 2 =>
IncDec_16 <= "0111";
Set_Addr_To <= aSP;
LDZ <= '1';
when 3 =>
Jump <= '1';
IncDec_16 <= "0111";
when others => null;
end case;
end if;
end if;
when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" =>
-- RST p

View File

@@ -106,6 +106,6 @@ assign cpu_do =
(cpu_addr == 2'b00)?div:
(cpu_addr == 2'b01)?tima:
(cpu_addr == 2'b10)?tma:
{5'b00000, tac};
{5'b11111, tac};
endmodule

View File

@@ -195,6 +195,7 @@ always @(posedge clk) begin
scx <= 8'h00;
wy <= 8'h00;
wx <= 8'h00;
stat <= 8'h00;
bgp <= 8'hfc;
obp0 <= 8'hff;
obp1 <= 8'hff;
@@ -221,7 +222,7 @@ end
assign cpu_do =
cpu_sel_oam?oam_do:
(cpu_addr[3:0] == 4'h0)?lcdc:
(cpu_addr[3:0] == 4'h1)?{stat[7:3], lyc_match, mode}:
(cpu_addr[3:0] == 4'h1)?{1'b1,stat[6:3], lyc_match, mode}:
(cpu_addr[3:0] == 4'h2)?scy:
(cpu_addr[3:0] == 4'h3)?scx:
(cpu_addr[3:0] == 4'h4)?ly: