diff --git a/gb.v b/gb.v index 424847b..5201914 100644 --- a/gb.v +++ b/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; diff --git a/gbc_snd.vhd b/gbc_snd.vhd index 7099b81..de794b7 100644 --- a/gbc_snd.vhd +++ b/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"; diff --git a/t80/T80_MCode.vhd b/t80/T80_MCode.vhd index 125d3df..f94afb5 100644 --- a/t80/T80_MCode.vhd +++ b/t80/T80_MCode.vhd @@ -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 diff --git a/timer.v b/timer.v index 4b47495..65d5510 100644 --- a/timer.v +++ b/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 diff --git a/video.v b/video.v index fa0d155..878bee6 100644 --- a/video.v +++ b/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: