import common::*; module magic( input rst_n, input clk28, input ck35, cpu_bus bus, output [7:0] d_out, output d_out_active, input n_int, input n_int_next, output reg n_nmi, input magic_button, input pause_button, input div_paged, input basic48_paged, output reg magic_mode, output reg magic_map, output reg magic_reboot, output reg magic_beeper, output machine_t machine, output turbo_t turbo, output panning_t panning, output reg joy_sinclair, output reg divmmc_en, output reg zc_en, output reg ulaplus_en, output reg ay_en, output reg covox_en, output reg soundrive_en, output reg sd_indication_en ); localparam magic_on_start = 1'b1; reg magic_unmap_next; reg magic_map_next; always @(posedge clk28 or negedge rst_n) begin if (!rst_n) begin n_nmi <= 1'b1; magic_mode <= magic_on_start; magic_map <= magic_on_start; magic_map_next <= 0; magic_unmap_next <= 0; end else begin if ((magic_button || pause_button) && n_int == 1'b1 && n_int_next == 1'b0) begin if (!magic_mode) n_nmi <= 1'b0; magic_mode <= 1'b1; end if (magic_map && bus.memreq && bus.rd && bus.a == 16'hf000 && !magic_map_next) begin magic_unmap_next <= 1'b1; magic_mode <= 1'b0; end else if (magic_map && bus.memreq && bus.rd && bus.a == 16'hf008) begin magic_unmap_next <= 1'b1; magic_map_next <= 1'b1; end else if (magic_unmap_next && !bus.memreq) begin magic_map <= 1'b0; magic_unmap_next <= 1'b0; end else if (magic_mode && bus.m1 && bus.memreq_rise && (bus.a == 16'h0066 || magic_map_next)) begin n_nmi <= 1'b1; magic_map <= 1'b1; magic_map_next <= 1'b0; end end end /* MAGIC CONFIG */ turbo_t turbo0; reg autoturbo_en; wire config_cs = magic_map && bus.ioreq && bus.a[7:0] == 8'hFF; always @(posedge clk28 or negedge rst_n) begin if (!rst_n) begin magic_reboot <= 0; magic_beeper <= 0; machine <= MACHINE_PENT; turbo0 <= TURBO_NONE; panning <= PANNING_ABC; joy_sinclair <= 0; divmmc_en <= 0; zc_en <= 1'b1; ulaplus_en <= 1'b1; ay_en <= 1'b1; covox_en <= 1'b1; soundrive_en <= 1'b1; sd_indication_en <= 1'b1; autoturbo_en <= 1'b0; end else if (config_cs && bus.wr) case (bus.a[15:8]) 8'h01: {magic_reboot, magic_beeper} <= bus.d[1:0]; 8'h02: machine <= machine_t'(bus.d[2:0]); 8'h03: turbo0 <= turbo_t'(bus.d[2:0]); 8'h04: panning <= panning_t'(bus.d[1:0]); 8'h07: joy_sinclair <= bus.d[0]; 8'h08: ay_en <= bus.d[0]; 8'h09: {zc_en, divmmc_en} <= bus.d[1:0]; 8'h0A: ulaplus_en <= bus.d[0]; 8'h0B: {soundrive_en, covox_en} <= bus.d[1:0]; 8'h0C: sd_indication_en <= bus.d[0]; 8'h0E: autoturbo_en <= bus.d[0]; endcase end reg config_rd; wire [7:0] config_data = {4'b0000, div_paged, 1'b1, pause_button, magic_button}; always @(posedge clk28 or negedge rst_n) begin if (!rst_n) config_rd <= 0; else config_rd <= config_cs && bus.rd && bus.a[15:8] == 8'h00; end /* AUTOMATIC TURBO */ reg [11:0] portfe_noturbo; // 1170uS always @(posedge clk28 or negedge rst_n) begin if (!rst_n) portfe_noturbo <= 0; else if (bus.ioreq && !bus.a[0]) portfe_noturbo <= 1'b1; else if (|portfe_noturbo && ck35) portfe_noturbo <= portfe_noturbo + 1'b1; end reg basic48_ramclear_turbo; always @(posedge clk28 or negedge rst_n) begin if (!rst_n) basic48_ramclear_turbo <= 0; else if (basic48_paged && bus.m1 && bus.a[15:6] == 10'b0001000111) basic48_ramclear_turbo <= 1'b1; else if (!basic48_paged || (bus.m1 && bus.a[15:6] != 10'b0001000111)) basic48_ramclear_turbo <= 0; end always @(posedge clk28 or negedge rst_n) begin if (!rst_n) turbo <= TURBO_NONE; else if (autoturbo_en && div_paged && !magic_map) turbo <= TURBO_14; else if (autoturbo_en && |portfe_noturbo) turbo <= TURBO_NONE; else if (autoturbo_en && basic48_ramclear_turbo) turbo <= TURBO_14; else turbo <= turbo0; end /* BUS CONTROLLER */ assign d_out_active = config_rd; assign d_out = config_data; endmodule