mirror of
https://github.com/MiSTer-devel/Gameboy_MiSTer.git
synced 2026-04-19 03:04:09 +00:00
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:
33
gb.v
33
gb.v
@@ -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;
|
||||
|
||||
180
gbc_snd.vhd
180
gbc_snd.vhd
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
2
timer.v
2
timer.v
@@ -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
|
||||
|
||||
3
video.v
3
video.v
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user