1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-02-07 16:31:17 +00:00

peripheral handling cleanup

This commit is contained in:
harbaum
2013-03-26 20:15:53 +00:00
parent 42c649d651
commit 04ec1aca44
8 changed files with 162 additions and 210 deletions

View File

@@ -4,11 +4,10 @@ module acia (
input reset,
input [7:0] din,
input sel,
input [7:0] addr,
input [1:0] addr,
input ds,
input rw,
output reg [7:0] dout,
output dtack,
output irq,
// data from io controller to acia
@@ -47,7 +46,7 @@ always @(negedge clk) begin
ikbd_strobe_inD2 <= ikbd_strobe_inD;
// read on kbd data register
if(sel && ~ds && rw && (addr == 8'h02))
if(sel && ~ds && rw && (addr == 2'd1))
data_read <= 1'b1;
else
data_read <= 1'b0;
@@ -65,7 +64,7 @@ always @(negedge clk) begin
// Some programs (e.g. bolo) need a pause between two ikbd bytes.
// The ikbd runs at 7812.5 bit/s 1 start + 8 data + 1 stop bit.
// One bit is 1/718.25 seconds. A pause of ~1ms is thus required
// One byte is 1/718.25 seconds. A pause of ~1ms is thus required
// 8000000/718.25 = 11138.18
readTimer <= 14'd11138;
end
@@ -97,22 +96,18 @@ always @(posedge clk) begin
readPout <= readPout + 4'd1;
end
// dtack
assign dtack = sel;
always @(sel, ds, rw, addr, dataInAvail, rxd) begin
if(sel && ~ds && rw) begin
dout = 8'h00;
if(sel && ~ds && rw) begin
// keyboard acia read
if(addr == 8'h00) dout = 8'h02 | (dataInAvail?8'h81:8'h00); // status
else if(addr == 8'h02) dout = rxd; // data
if(addr == 2'd0) dout = 8'h02 | (dataInAvail?8'h81:8'h00); // status
if(addr == 2'd1) dout = rxd; // data
// midi acia read
else if(addr == 8'h04) dout = 8'h02; // status
else if(addr == 8'h06) dout = 8'h00; // data
else dout = 8'h00;
end else
dout = 8'h00;
if(addr == 2'd2) dout = 8'h02; // status
if(addr == 2'd3) dout = 8'h00; // data
end
end
always @(negedge clk) begin
@@ -120,7 +115,7 @@ always @(negedge clk) begin
writePout <= 0;
end else begin
// keyboard acia data register writes into buffer
if(sel && ~ds && ~rw && addr == 8'h02) begin
if(sel && ~ds && ~rw && addr == 2'd1) begin
fifoOut[writePout] <= din;
writePout <= writePout + 4'd1;
end

View File

@@ -126,7 +126,7 @@ module clock (
altpll_component.clk2_divide_by = 18,
altpll_component.clk2_duty_cycle = 50,
altpll_component.clk2_multiply_by = 85,
altpll_component.clk2_phase_shift = "-2000",
altpll_component.clk2_phase_shift = "-1500",
altpll_component.clk3_divide_by = 27000000,
altpll_component.clk3_duty_cycle = 50,
altpll_component.clk3_multiply_by = 2457599,
@@ -265,7 +265,7 @@ endmodule
// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "-2000.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "-1500.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT3 STRING "0.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
@@ -323,7 +323,7 @@ endmodule
// Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "18"
// Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50"
// Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "85"
// Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "-2000"
// Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "-1500"
// Retrieval info: CONSTANT: CLK3_DIVIDE_BY NUMERIC "27000000"
// Retrieval info: CONSTANT: CLK3_DUTY_CYCLE NUMERIC "50"
// Retrieval info: CONSTANT: CLK3_MULTIPLY_BY NUMERIC "2457599"

View File

@@ -37,6 +37,7 @@ module clock (
c0,
c1,
c2,
c3,
locked);
input areset;
@@ -44,6 +45,7 @@ module clock (
output c0;
output c1;
output c2;
output c3;
output locked;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
@@ -77,12 +79,15 @@ endmodule
// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "18"
// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "72"
// Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "18"
// Retrieval info: PRIVATE: DIV_FACTOR3 NUMERIC "1"
// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
// Retrieval info: PRIVATE: DUTY_CYCLE2 STRING "50.00000000"
// Retrieval info: PRIVATE: DUTY_CYCLE3 STRING "50.00000000"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "127.500000"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "31.875000"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "127.500000"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE3 STRING "2.457600"
// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
@@ -105,32 +110,40 @@ endmodule
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "deg"
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT2 STRING "deg"
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT3 STRING "ps"
// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
// Retrieval info: PRIVATE: MIRROR_CLK2 STRING "0"
// Retrieval info: PRIVATE: MIRROR_CLK3 STRING "0"
// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "85"
// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "85"
// Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "85"
// Retrieval info: PRIVATE: MULT_FACTOR3 NUMERIC "1"
// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "100.00000000"
// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "32.00000000"
// Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "100.00000000"
// Retrieval info: PRIVATE: OUTPUT_FREQ3 STRING "2.45760000"
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0"
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "0"
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE3 STRING "1"
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT2 STRING "MHz"
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT3 STRING "MHz"
// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "-2500.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "-1500.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT3 STRING "0.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "ps"
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT2 STRING "ps"
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT3 STRING "ps"
// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
@@ -155,15 +168,18 @@ endmodule
// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
// Retrieval info: PRIVATE: STICKY_CLK2 STRING "1"
// Retrieval info: PRIVATE: STICKY_CLK3 STRING "1"
// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
// Retrieval info: PRIVATE: USE_CLK1 STRING "1"
// Retrieval info: PRIVATE: USE_CLK2 STRING "1"
// Retrieval info: PRIVATE: USE_CLK3 STRING "1"
// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
// Retrieval info: PRIVATE: USE_CLKENA2 STRING "0"
// Retrieval info: PRIVATE: USE_CLKENA3 STRING "0"
// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
@@ -179,7 +195,11 @@ endmodule
// Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "18"
// Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50"
// Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "85"
// Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "-2500"
// Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "-1500"
// Retrieval info: CONSTANT: CLK3_DIVIDE_BY NUMERIC "27000000"
// Retrieval info: CONSTANT: CLK3_DUTY_CYCLE NUMERIC "50"
// Retrieval info: CONSTANT: CLK3_MULTIPLY_BY NUMERIC "2457599"
// Retrieval info: CONSTANT: CLK3_PHASE_SHIFT STRING "0"
// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
@@ -214,7 +234,7 @@ endmodule
// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
@@ -234,6 +254,7 @@ endmodule
// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1"
// Retrieval info: USED_PORT: c2 0 0 0 0 OUTPUT_CLK_EXT VCC "c2"
// Retrieval info: USED_PORT: c3 0 0 0 0 OUTPUT_CLK_EXT VCC "c3"
// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
// Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0
@@ -242,6 +263,7 @@ endmodule
// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1
// Retrieval info: CONNECT: c2 0 0 0 0 @clk 0 0 1 2
// Retrieval info: CONNECT: c3 0 0 0 0 @clk 0 0 1 3
// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
// Retrieval info: GEN_FILE: TYPE_NORMAL clock.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL clock.ppf TRUE

View File

@@ -4,12 +4,11 @@ module dma (
input reset,
input [15:0] din,
input sel,
input [7:0] addr,
input [2:0] addr,
input uds,
input lds,
input rw,
output reg [15:0] dout,
output dtack,
// output to mfp
output irq,
@@ -64,9 +63,6 @@ reg [7:0] fdc_data;
reg [23:0] base;
reg [7:0] scnt;
// dtack
assign dtack = sel;
// virtual head is over track 0
wire track0;
assign track0 = (fdc_track == 8'd0);
@@ -90,7 +86,7 @@ always @(sel, rw, addr, mode, base, fdc_data, fdc_sector, fdc_status, fdc_track,
dout = 16'h0000;
if(sel && rw) begin
if((addr == 8'h04) && (mode[4] == 1'b0)) begin
if((addr == 3'h2) && (mode[4] == 1'b0)) begin
// controller access register
if(mode[3] == 1'b0) begin
// fdc
@@ -105,19 +101,19 @@ always @(sel, rw, addr, mode, base, fdc_data, fdc_sector, fdc_status, fdc_track,
end
end
if(addr == 8'h06)
if(addr == 3'h3)
dout = dma_status;
// sector count register
if((addr == 8'h04) && (mode[4] == 1'b1))
if((addr == 3'h2) && (mode[4] == 1'b1))
dout = { 8'h00, scnt };
// dma base address read back
if(addr == 8'h09)
if(addr == 3'h4)
dout = { 8'h00, base[23:16] };
if(addr == 8'h0b)
if(addr == 3'h5)
dout = { 8'h00, base[15:8] };
if(addr == 8'h0d)
if(addr == 3'h6)
dout = { 8'h00, base[7:0] };
end
end
@@ -151,7 +147,7 @@ always @(negedge clk) begin
// dma control and mode register
if(sel && ~rw) begin
if(~lds && (addr == 8'h04) && (mode[4] == 1'b0)) begin
if(~lds && (addr == 3'h2) && (mode[4] == 1'b0)) begin
// controller access register
if(mode[3] == 1'b0) begin
// fdc register write
@@ -222,17 +218,17 @@ always @(negedge clk) begin
end
// sector count register
if(~lds && (addr == 8'h04) && (mode[4] == 1'b1))
if(~lds && (addr == 3'h2) && (mode[4] == 1'b1))
scnt <= din[7:0];
if(addr == 8'h06)
if(addr == 3'h3)
mode <= din;
if(~lds && (addr == 8'h09))
if(~lds && (addr == 3'h4))
base[23:16] <= din[7:0];
if(~lds && (addr == 8'h0b))
if(~lds && (addr == 3'h5))
base[15:8] <= din[7:0];
if(~lds && (addr == 8'h0d))
if(~lds && (addr == 3'h6))
base[7:0] <= din[7:0];
end
end

View File

@@ -6,11 +6,10 @@ module mfp (
input reset,
input [7:0] din,
input sel,
input [7:0] addr,
input [4:0] addr,
input ds,
input rw,
output reg [7:0] dout,
output dtack,
output irq,
input iack,
@@ -67,10 +66,10 @@ mfp_timer timer_a (
.RST (reset),
.CTRL_I (din[4:0]),
.CTRL_O (timera_ctrl_o),
.CTRL_WE ((addr == 8'h19) && write),
.CTRL_WE ((addr == 5'h0c) && write),
.DAT_I (din),
.DAT_O (timera_dat_o),
.DAT_WE ((addr == 8'h1f) && write),
.DAT_WE ((addr == 5'h0f) && write),
.T_O_PULSE (timera_done)
);
@@ -85,10 +84,10 @@ mfp_timer timer_b (
.RST (reset),
.CTRL_I (din[4:0]),
.CTRL_O (timerb_ctrl_o),
.CTRL_WE ((addr == 8'h1b) && write),
.CTRL_WE ((addr == 5'h0d) && write),
.DAT_I (din),
.DAT_O (timerb_dat_o),
.DAT_WE ((addr == 8'h21) && write),
.DAT_WE ((addr == 5'h10) && write),
.T_I (de),
.T_O_PULSE (timerb_done)
);
@@ -103,10 +102,10 @@ mfp_timer timer_c (
.RST (reset),
.CTRL_I ({2'b00, din[6:4]}),
.CTRL_O (timerc_ctrl_o),
.CTRL_WE ((addr == 8'h1d) && write),
.CTRL_WE ((addr == 5'h0e) && write),
.DAT_I (din),
.DAT_O (timerc_dat_o),
.DAT_WE ((addr == 8'h23) && write),
.DAT_WE ((addr == 5'h11) && write),
.T_O_PULSE (timerc_done)
);
@@ -120,16 +119,13 @@ mfp_timer timer_d (
.RST (reset),
.CTRL_I ({2'b00, din[2:0]}),
.CTRL_O (timerd_ctrl_o),
.CTRL_WE ((addr == 8'h1d) && write),
.CTRL_WE ((addr == 5'h0e) && write),
.DAT_I (din),
.DAT_O (timerd_dat_o),
.DAT_WE ((addr == 8'h25) && write),
.DAT_WE ((addr == 5'h12) && write),
.T_O_PULSE (timerd_done)
);
// dtack
assign dtack = sel || iack;
reg [7:0] aer, ddr, gpip;
// the mfp can handle 16 irqs, 8 internal and 8 external
@@ -208,31 +204,31 @@ always @(iack, sel, ds, rw, addr, gpip_cpu_out, aer, ddr, ier, ipr, isr, imr,
dout = 8'd0;
if(sel && ~ds && rw) begin
if(addr == 8'h01) dout = gpip_cpu_out;
if(addr == 8'h03) dout = aer;
if(addr == 8'h05) dout = ddr;
if(addr == 5'h00) dout = gpip_cpu_out;
if(addr == 5'h01) dout = aer;
if(addr == 5'h02) dout = ddr;
if(addr == 8'h07) dout = ier[15:8];
if(addr == 8'h0b) dout = ipr[15:8];
if(addr == 8'h0f) dout = isr[15:8];
if(addr == 8'h13) dout = imr[15:8];
if(addr == 8'h09) dout = ier[7:0];
if(addr == 8'h0d) dout = ipr[7:0];
if(addr == 8'h11) dout = isr[7:0];
if(addr == 8'h15) dout = imr[7:0];
if(addr == 8'h17) dout = vr;
if(addr == 5'h03) dout = ier[15:8];
if(addr == 5'h05) dout = ipr[15:8];
if(addr == 5'h07) dout = isr[15:8];
if(addr == 5'h09) dout = imr[15:8];
if(addr == 5'h04) dout = ier[7:0];
if(addr == 5'h06) dout = ipr[7:0];
if(addr == 5'h08) dout = isr[7:0];
if(addr == 5'h0a) dout = imr[7:0];
if(addr == 5'h0b) dout = vr;
// timers
if(addr == 8'h19) dout = { 3'b000, timera_ctrl_o};
if(addr == 8'h1b) dout = { 3'b000, timerb_ctrl_o};
if(addr == 8'h1d) dout = { timerc_ctrl_o[3:0], timerd_ctrl_o[3:0]};
if(addr == 8'h1f) dout = timera_dat_o;
if(addr == 8'h21) dout = timerb_dat_o;
if(addr == 8'h23) dout = timerc_dat_o;
if(addr == 8'h25) dout = timerd_dat_o;
if(addr == 5'h0c) dout = { 3'b000, timera_ctrl_o};
if(addr == 5'h0d) dout = { 3'b000, timerb_ctrl_o};
if(addr == 5'h0e) dout = { timerc_ctrl_o[3:0], timerd_ctrl_o[3:0]};
if(addr == 5'h0f) dout = timera_dat_o;
if(addr == 5'h10) dout = timerb_dat_o;
if(addr == 5'h11) dout = timerc_dat_o;
if(addr == 5'h12) dout = timerd_dat_o;
// uart: report "tx buffer empty" if fifo is not full
if(addr == 8'h2d) dout = serial_data_out_fifo_full?8'h00:8'h80;
if(addr == 5'h16) dout = serial_data_out_fifo_full?8'h00:8'h80;
end else if(iack) begin
dout = irq_vec;
@@ -292,47 +288,30 @@ always @(negedge clk) begin
end
if(sel && ~ds && ~rw) begin
if(addr == 8'h01)
gpip <= din;
if(addr == 8'h03)
aer <= din;
if(addr == 8'h05)
ddr <= din;
if(addr == 5'h00) gpip <= din;
if(addr == 5'h01) aer <= din;
if(addr == 5'h02) ddr <= din;
if(addr == 8'h07) begin
if(addr == 5'h03) begin
ier[15:8] <= din;
ipr[15:8]<= ipr[15:8] & din; // clear pending interrupts
end
if(addr == 8'h0b)
ipr[15:8] <= ipr[15:8] & din;
if(addr == 5'h05) ipr[15:8] <= ipr[15:8] & din;
if(addr == 5'h07) isr[15:8] <= isr[15:8] & din; // zero bits are cleared
if(addr == 5'h09) imr[15:8] <= din;
if(addr == 8'h0f)
isr[15:8] <= isr[15:8] & din; // zero bits are cleared
if(addr == 8'h13)
imr[15:8] <= din;
if(addr == 8'h09) begin
if(addr == 5'h04) begin
ier[7:0] <= din;
ipr[7:0] <= ipr[7:0] & din; // clear pending interrupts
end
if(addr == 8'h0d)
ipr[7:0] <= ipr[7:0] & din;
if(addr == 8'h11)
isr[7:0] <= isr[7:0] & din; // zero bits are cleared
if(addr == 8'h15)
imr[7:0] <= din;
if(addr == 8'h17)
vr <= din;
if(addr == 5'h06) ipr[7:0] <= ipr[7:0] & din;
if(addr == 5'h08) isr[7:0] <= isr[7:0] & din; // zero bits are cleared
if(addr == 5'h0a) imr[7:0] <= din;
if(addr == 5'h0b) vr <= din;
if(addr == 8'h2f) begin
if(addr == 5'h17) begin
fifoOut[writePout] <= din;
writePout <= writePout + 4'd1;
end

View File

@@ -5,9 +5,7 @@
module mist_top (
// clock inputs
input wire [ 2-1:0] CLOCK_32, // 32 MHz
input wire [ 2-1:0] CLOCK_27, // 27 MHz
input wire [ 2-1:0] CLOCK_50, // 50 MHz
// LED outputs
output wire LED, // LED Yellow
// UART
@@ -35,7 +33,7 @@ module mist_top (
output wire AUDIO_L, // sigma-delta DAC output left
output wire AUDIO_R, // sigma-delta DAC output right
// SPI
inout wire SPI_DO, // inout
inout wire SPI_DO,
input wire SPI_DI,
input wire SPI_SCK,
input wire SPI_SS2, // fpga
@@ -52,23 +50,14 @@ wire video_de, video_hs;
// on-board io
wire [1:0] buttons;
// TODO: Clean this up as all dtacks are directly generated from their sel's
wire io_dtack;
assign io_dtack =
vreg_sel?vreg_dtack:
(mmu_sel?mmu_dtack:
((mfp_sel||mfp_iack)?mfp_dtack:
(acia_sel?acia_dtack:
(psg_sel?psg_dtack:
(dma_sel?dma_dtack:
(auto_iack?auto_iack:
1'b0))))));
// generate dtack for all implemented peripherals
wire io_dtack = vreg_sel || mmu_sel || mfp_sel || mfp_iack ||
acia_sel || psg_sel || dma_sel || auto_iack;
// the original tg68k did not contain working support for bus fault exceptions. While earlier
// TOS versions cope with that, TOS versions with blitter support need this to work as this is
// required to properly detect that a blitter is not present.
// a bus error is now generated once no dtack is seen for 63 clock cycles. The tg68k requires
// a dtack to be generated with the bus error to continue operation
// a bus error is now generated once no dtack is seen for 63 clock cycles.
wire tg68_berr = (dtack_timeout == 6'd63); // || cpu_write_illegal;
wire cpu_write = cpu_cycle && cpu2io && data_strobe && !tg68_rw;
@@ -100,63 +89,55 @@ assign mfp_iack = cpu_cycle && cpu2iack && data_strobe && (tg68_adr[3:1] == 3'b1
// entirely to non-autovector interrupts. This means that i now have to provide
// the vectors for those interrupts that oin the ST are autovector ones. This needs
// to be done for IPL2 (hbi) and IPL4 (vbi)
wire auto_iack;
assign auto_iack = cpu_cycle && cpu2iack && data_strobe &&
((tg68_adr[3:1] == 3'b100) || (tg68_adr[3:1] == 3'b010));
wire [7:0] auto_vector;
assign auto_vector = (tg68_adr[3:1] == 3'b100)?8'h1c:8'h1a;
// mmu cpu interface at $ff8001
wire mmu_sel;
wire mmu_dtack;
wire auto_iack = cpu_cycle && cpu2iack && data_strobe &&
((tg68_adr[3:1] == 3'b100) || (tg68_adr[3:1] == 3'b010));
wire [7:0] auto_vector_vbi = (auto_iack && (tg68_adr[3:1] == 3'b100))?8'h1c:8'h00;
wire [7:0] auto_vector_hbi = (auto_iack && (tg68_adr[3:1] == 3'b010))?8'h1a:8'h00;
wire [7:0] auto_vector = auto_vector_vbi | auto_vector_hbi;
// interfaces not implemented:
// $fff00000 - $fff000ff - IDE
// $ffff8780 - $ffff878f - SCSI
// $ffff8901 - $ffff893f - STE DMA audio
// $ffff8a00 - $ffff8a3f - Blitter
// $ffff9200 - $ffff923f - STE joystick ports
// $fffffa40 - $fffffa7f - FPU
// $fffffc20 - $fffffc3f - RTC
wire io_sel = cpu_cycle && cpu2io && data_strobe ;
// mmu 8 bit interface at $ff8000 - $ff8801
wire mmu_sel = io_sel && ({tg68_adr[15:1], 1'd0} == 16'h8000);
wire [7:0] mmu_data_out;
assign mmu_sel = cpu_cycle && cpu2io && data_strobe && ({tg68_adr[15:1], 1'b0} == 16'h8000);
// video controller cpu interface at $ff8200
wire vreg_sel;
wire vreg_dtack;
// video controller 16 bit interface at $ff8200 - $ff827f
wire vreg_sel = io_sel && ({tg68_adr[15:7], 7'd0} == 16'h8200);
wire [15:0] vreg_data_out;
assign vreg_sel = cpu_cycle && cpu2io && data_strobe && (tg68_adr[15:8] == 8'h82);
// mfp cpu interface at $fffa00 - $fffa3f
wire mfp_sel;
wire mfp_dtack;
// mfp 8 bit interface at $fffa00 - $fffa3f
wire mfp_sel = io_sel && ({tg68_adr[15:6], 6'd0} == 16'hfa00);
wire [7:0] mfp_data_out;
assign mfp_sel = cpu_cycle && cpu2io && data_strobe && (tg68_adr[15:8] == 8'hfa) &&
(tg68_adr[7:6] == 2'b00);
// acia cpu interface at $fffc00
wire acia_sel;
wire acia_dtack;
// acia 8 bit interface at $fffc00 - $fffc07
wire acia_sel = io_sel && ({tg68_adr[15:3], 3'd0} == 16'hfc00);
wire [7:0] acia_data_out;
assign acia_sel = cpu_cycle && cpu2io && data_strobe && (tg68_adr[15:8] == 8'hfc);
// psg interface at $ff8800
wire psg_sel;
wire psg_dtack;
// psg 8 bit interface at $ff8800 - $ff8803
wire psg_sel = io_sel && ({tg68_adr[15:2], 2'd0} == 16'h8800);
wire [7:0] psg_data_out;
assign psg_sel = cpu_cycle && cpu2io && data_strobe && (tg68_adr[15:8] == 8'h88);
// dma interface at $ff8600
wire dma_sel;
wire dma_dtack;
// dma 16 bit interface at $ff8600 - $ff860f
wire dma_sel = io_sel && ({tg68_adr[15:4], 4'd0} == 16'h8600);
wire [15:0] dma_data_out;
assign dma_sel = cpu_cycle && cpu2io && data_strobe && (tg68_adr[15:8] == 8'h86);
// de-multiplex the various io data output ports into one
wire [15:0] io_data_out;
assign io_data_out =
vreg_sel?vreg_data_out:
(mmu_sel?{8'h00, mmu_data_out}:
((mfp_sel||mfp_iack)?{8'h00, mfp_data_out}:
(auto_iack?{8'h00, auto_vector}:
(acia_sel?{acia_data_out, 8'h00}:
(psg_sel?{psg_data_out, 8'h00}:
(dma_sel?dma_data_out:
16'h0000))))));
wire [7:0] io_data_out_8u = acia_data_out | psg_data_out;
wire [7:0] io_data_out_8l = mmu_data_out | mfp_data_out | auto_vector;
wire [15:0] io_data_out = vreg_data_out | dma_data_out |
{8'h00, io_data_out_8l} | {io_data_out_8u, 8'h00};
wire init;
assign init = ~pll_locked;
wire init = ~pll_locked;
video video (
.reset (init ), // reset input
@@ -173,12 +154,11 @@ video video (
.reg_reset (reset ),
.reg_din (tg68_dat_out),
.reg_sel (vreg_sel ),
.reg_addr (tg68_adr[7:0]),
.reg_addr (tg68_adr[6:1]),
.reg_uds (tg68_uds ),
.reg_lds (tg68_lds ),
.reg_rw (tg68_rw ),
.reg_dout (vreg_data_out),
.reg_dtack (vreg_dtack ),
.vaddr (video_address ),
.data (video_data ),
@@ -204,8 +184,7 @@ mmu mmu (
.sel (mmu_sel ),
.ds (tg68_lds ),
.rw (tg68_rw ),
.dout (mmu_data_out),
.dtack (mmu_dtack )
.dout (mmu_data_out)
);
wire acia_irq, dma_irq;
@@ -216,11 +195,10 @@ mfp mfp (
.reset (reset ),
.din (tg68_dat_out[7:0]),
.sel (mfp_sel ),
.addr (tg68_adr[7:0]),
.addr (tg68_adr[5:1]),
.ds (tg68_lds ),
.rw (tg68_rw ),
.dout (mfp_data_out),
.dtack (mfp_dtack ),
.irq (mfp_irq ),
.iack (mfp_iack ),
@@ -243,11 +221,10 @@ acia acia (
.reset (reset ),
.din (tg68_dat_out[15:8]),
.sel (acia_sel ),
.addr (tg68_adr[7:0]),
.addr (tg68_adr[2:1]),
.ds (tg68_uds ),
.rw (tg68_rw ),
.dout (acia_data_out),
.dtack (acia_dtack ),
.irq (acia_irq ),
// ikbd interface
@@ -271,8 +248,6 @@ assign floppy_sel = port_a_out[2:1];
wire [7:0] audio_out;
assign AUDIO_R = AUDIO_L;
assign psg_dtack = psg_sel;
sigma_delta_dac sigma_delta_dac (
.DACout (AUDIO_L),
.DACin (audio_out),
@@ -324,12 +299,11 @@ dma dma (
.reset (reset ),
.din (tg68_dat_out[15:0]),
.sel (dma_sel ),
.addr (tg68_adr[7:0]),
.addr (tg68_adr[3:1]),
.uds (tg68_uds ),
.lds (tg68_lds ),
.rw (tg68_rw ),
.dout (dma_data_out),
.dtack (dma_dtack ),
.irq (dma_irq ),

View File

@@ -6,13 +6,9 @@ module mmu (
input sel,
input ds,
input rw,
output reg [7:0] dout,
output dtack
output reg [7:0] dout
);
// dtack
assign dtack = sel;
reg [7:0] memconfig;
always @(sel, ds, rw) begin

View File

@@ -35,12 +35,11 @@ module video (
input reg_reset,
input [15:0] reg_din,
input reg_sel,
input [7:0] reg_addr,
input [5:0] reg_addr,
input reg_uds,
input reg_lds,
input reg_rw,
output reg [15:0] reg_dout,
output reg_dtack,
// screen interface
output hs, // H_SYNC
@@ -180,46 +179,43 @@ wire low = (shmode == 2'd0);
reg [1:0] syncmode;
wire pal = (syncmode[1] == 1'b1);
// dtack
assign reg_dtack = reg_sel;
// 16 colors with 3*3 bits each
reg [2:0] palette_r[15:0];
reg [2:0] palette_g[15:0];
reg [2:0] palette_b[15:0];
always @(reg_sel, reg_rw, reg_uds, reg_lds, reg_addr, _v_bas_ad, shmode, vaddr) begin
reg_dout = { 16'h0000 };
reg_dout = 16'h0000;
// read registers
if(reg_sel && reg_rw) begin
if(reg_addr == 8'h01 && ~reg_lds)
if(reg_addr == 6'h00 && ~reg_lds)
reg_dout = { 8'h00, _v_bas_ad[22:15]};
if(reg_addr == 8'h03 && ~reg_lds)
if(reg_addr == 6'h01 && ~reg_lds)
reg_dout = { 8'h00, _v_bas_ad[14:7]};
if(reg_addr == 8'h05 && ~reg_lds)
if(reg_addr == 6'h02 && ~reg_lds)
reg_dout = { 8'h00, vaddr[22:15]};
if(reg_addr == 8'h07 && ~reg_lds)
if(reg_addr == 6'h03 && ~reg_lds)
reg_dout = { 8'h00, vaddr[14:7]};
if(reg_addr == 8'h09 && ~reg_lds)
if(reg_addr == 6'h04 && ~reg_lds)
reg_dout = { 8'h00, vaddr[6:0], 1'b0 };
if(reg_addr == 8'h0a && ~reg_uds)
if(reg_addr == 6'h05 && ~reg_uds)
reg_dout = { 6'h00, syncmode, 8'h00};
// the color palette registers
if(reg_addr >= 8'h40 && reg_addr < 8'h60 ) begin
reg_dout[2:0] = palette_b[reg_addr[4:1]];
reg_dout[6:4] = palette_g[reg_addr[4:1]];
reg_dout[10:8] = palette_r[reg_addr[4:1]];
if(reg_addr >= 6'h20 && reg_addr < 6'h30 ) begin
reg_dout[2:0] = palette_b[reg_addr[3:0]];
reg_dout[6:4] = palette_g[reg_addr[3:0]];
reg_dout[10:8] = palette_r[reg_addr[3:0]];
end
if(reg_addr == 8'h60 && ~reg_uds)
if(reg_addr == 6'h30 && ~reg_uds)
reg_dout = { 6'h00, shmode, 8'h00};
end
end
@@ -254,29 +250,23 @@ always @(negedge reg_clk) begin
end else begin
// write registers
if(reg_sel && ~reg_rw) begin
if(reg_addr == 8'h01 && ~reg_lds)
_v_bas_ad[22:15] <= reg_din[7:0];
if(reg_addr == 8'h03 && ~reg_lds)
_v_bas_ad[14:7] <= reg_din[7:0];
if(reg_addr == 8'h0a && ~reg_uds)
syncmode <= reg_din[9:8];
if(reg_addr == 6'h00 && ~reg_lds) _v_bas_ad[22:15] <= reg_din[7:0];
if(reg_addr == 6'h01 && ~reg_lds) _v_bas_ad[14:7] <= reg_din[7:0];
if(reg_addr == 6'h05 && ~reg_uds) syncmode <= reg_din[9:8];
// the color palette registers
if(reg_addr >= 8'h40 && reg_addr < 8'h60 ) begin
if(reg_addr >= 6'h20 && reg_addr < 6'h30 ) begin
if(~reg_uds) begin
palette_r[reg_addr[4:1]] <= reg_din[10:8];
palette_r[reg_addr[3:0]] <= reg_din[10:8];
end
if(~reg_lds) begin
palette_g[reg_addr[4:1]] <= reg_din[6:4];
palette_b[reg_addr[4:1]] <= reg_din[2:0];
palette_g[reg_addr[3:0]] <= reg_din[6:4];
palette_b[reg_addr[3:0]] <= reg_din[2:0];
end
end
if(reg_addr == 8'h60 && ~reg_uds)
shmode <= reg_din[9:8];
if(reg_addr == 6'h30 && ~reg_uds) shmode <= reg_din[9:8];
end
end