From 62855dade0d114954844be7aff82985eadff638b Mon Sep 17 00:00:00 2001 From: harbaum Date: Fri, 3 Apr 2015 20:24:38 +0000 Subject: [PATCH] [ATARI ST] And another mfp fix. Fixing the Rtype Deluxe floppy access --- cores/mist/fdc.v | 31 ++++++++++++++------ cores/mist/mfp.v | 4 ++- cores/mist/mfp_srff16.v | 65 +++++++++++++++++++++-------------------- 3 files changed, 58 insertions(+), 42 deletions(-) diff --git a/cores/mist/fdc.v b/cores/mist/fdc.v index 90b0907..d45418f 100644 --- a/cores/mist/fdc.v +++ b/cores/mist/fdc.v @@ -76,23 +76,30 @@ wire cmd_type_2 = (cmd[7:6] == 2'b10); // ---------------- floppy motor simulation ------------- +// - all type 1 and 2 commands switch the motor on +// - if it was already running it just keeps running +// - if it was off it "spins up" +// - force interrupt basically enforces a spin-up even if motor is spinning + // timer to simulate motor-on. This runs for x/8000000 seconds after each command reg motor_start; +reg motor_force_spinup; reg [31:0] motor_on_counter; wire motor_on = (motor_on_counter != 0); // motor_on_counter > 16000000 means the motor is spinning up wire motor_spin_up_done = motor_on && (motor_on_counter <= 16000000); +wire motor_start_or_force = motor_start || motor_force_spinup; -always @(posedge clk or posedge motor_start) begin - if(motor_start) +always @(posedge clk or posedge motor_start_or_force) begin + if(motor_start_or_force) // motor runs for 2 seconds if it was already on. it rus for one // more second if if wasn't on yet (spin up) - motor_on_counter <= motor_on?32'd16000000:32'd24000000; + motor_on_counter <= (motor_on && !motor_force_spinup)?32'd16000000:32'd24000000; else begin // let "motor" run if(motor_on_counter != 0) - motor_on_counter <= motor_on_counter - 32'd1; + motor_on_counter <= motor_on_counter - 32'd1; end end @@ -116,11 +123,11 @@ end wire [7:0] status = { motor_on, wr_prot, - cmd_type_1?motor_spin_up_done:1'b0, + cmd_type_1?motor_spin_up_done:1'b0, // spin up done? RType Deluxe needs this 2'b00 /* track not found/crc err */, cmd_type_1?(track == 0):1'b0, - cmd_type_1?index_pulse:(state!=STATE_IDLE), - state != STATE_IDLE + cmd_type_1?index_pulse:(state == STATE_IO_WAIT), // drq + (state == STATE_INT_WAIT) || (state == STATE_IO_WAIT) }; // CPU register read @@ -144,10 +151,12 @@ always @(negedge clk or posedge reset) begin state <= STATE_IDLE; irq <= 1'b0; motor_start <= 1'b0; + motor_force_spinup <= 1'b0; delay <= 32'd0; end else begin motor_start <= 1'b0; + motor_force_spinup <= 1'b0; // DMA transfer has been ack'd by io controller if(dma_ack) begin @@ -193,8 +202,11 @@ always @(negedge clk or posedge reset) begin end if(cpu_din[7:4] == 4'b0001) begin // SEEK - track <= data; - delay <= 31'd200000; // 25ms delay + if(track != data) begin + track <= data; + delay <= 31'd200000; // 25ms delay + end else + state <= STATE_IRQ; end if(cpu_din[7:5] == 3'b001) begin // STEP @@ -239,6 +251,7 @@ always @(negedge clk or posedge reset) begin // ------------- TYPE IV commands ------------- if(cpu_din[7:4] == 4'b1101) begin // force intrerupt + motor_force_spinup <= 1'b1; if(cpu_din[3:0] == 4'b0000) state <= STATE_IDLE; // immediately else diff --git a/cores/mist/mfp.v b/cores/mist/mfp.v index ec646f6..4c4ad98 100644 --- a/cores/mist/mfp.v +++ b/cores/mist/mfp.v @@ -274,7 +274,8 @@ wire [15:0] ipr_set = { }; mfp_srff16 ipr_latch ( - .set ( ipr_set & ier ), + .set ( ipr_set ), + .mask ( ier ), .reset ( ipr_reset ), .out ( ipr ) ); @@ -287,6 +288,7 @@ reg [15:0] isr_set; // move highest pending irq into isr when s bit set and iack raises mfp_srff16 isr_latch ( .set ( isr_set ), + .mask ( 16'hffff ), .reset ( isr_reset ), .out ( isr ) ); diff --git a/cores/mist/mfp_srff16.v b/cores/mist/mfp_srff16.v index dc439b7..0b6e6ea 100644 --- a/cores/mist/mfp_srff16.v +++ b/cores/mist/mfp_srff16.v @@ -23,88 +23,89 @@ module mfp_srff16 ( input [15:0] set, + input [15:0] mask, input [15:0] reset, output reg [15:0] out ); always @(posedge set[0] or posedge reset[0]) begin - if(reset[0]) out[0] <= 1'b0; - else out[0] <= 1'b1; + if(reset[0]) out[0] <= 1'b0; + else if(mask[0]) out[0] <= 1'b1; end always @(posedge set[1] or posedge reset[1]) begin - if(reset[1]) out[1] <= 1'b0; - else out[1] <= 1'b1; + if(reset[1]) out[1] <= 1'b0; + else if(mask[1]) out[1] <= 1'b1; end always @(posedge set[2] or posedge reset[2]) begin - if(reset[2]) out[2] <= 1'b0; - else out[2] <= 1'b1; + if(reset[2]) out[2] <= 1'b0; + else if(mask[2]) out[2] <= 1'b1; end always @(posedge set[3] or posedge reset[3]) begin - if(reset[3]) out[3] <= 1'b0; - else out[3] <= 1'b1; + if(reset[3]) out[3] <= 1'b0; + else if(mask[3]) out[3] <= 1'b1; end always @(posedge set[4] or posedge reset[4]) begin - if(reset[4]) out[4] <= 1'b0; - else out[4] <= 1'b1; + if(reset[4]) out[4] <= 1'b0; + else if(mask[4]) out[4] <= 1'b1; end always @(posedge set[5] or posedge reset[5]) begin - if(reset[5]) out[5] <= 1'b0; - else out[5] <= 1'b1; + if(reset[5]) out[5] <= 1'b0; + else if(mask[5]) out[5] <= 1'b1; end always @(posedge set[6] or posedge reset[6]) begin - if(reset[6]) out[6] <= 1'b0; - else out[6] <= 1'b1; + if(reset[6]) out[6] <= 1'b0; + else if(mask[6]) out[6] <= 1'b1; end always @(posedge set[7] or posedge reset[7]) begin - if(reset[7]) out[7] <= 1'b0; - else out[7] <= 1'b1; + if(reset[7]) out[7] <= 1'b0; + else if(mask[7]) out[7] <= 1'b1; end always @(posedge set[8] or posedge reset[8]) begin - if(reset[8]) out[8] <= 1'b0; - else out[8] <= 1'b1; + if(reset[8]) out[8] <= 1'b0; + else if(mask[8]) out[8] <= 1'b1; end always @(posedge set[9] or posedge reset[9]) begin - if(reset[9]) out[9] <= 1'b0; - else out[9] <= 1'b1; + if(reset[9]) out[9] <= 1'b0; + else if(mask[9]) out[9] <= 1'b1; end always @(posedge set[10] or posedge reset[10]) begin - if(reset[10]) out[10] <= 1'b0; - else out[10] <= 1'b1; + if(reset[10]) out[10] <= 1'b0; + else if(mask[10]) out[10] <= 1'b1; end always @(posedge set[11] or posedge reset[11]) begin - if(reset[11]) out[11] <= 1'b0; - else out[11] <= 1'b1; + if(reset[11]) out[11] <= 1'b0; + else if(mask[11]) out[11] <= 1'b1; end always @(posedge set[12] or posedge reset[12]) begin - if(reset[12]) out[12] <= 1'b0; - else out[12] <= 1'b1; + if(reset[12]) out[12] <= 1'b0; + else if(mask[12]) out[12] <= 1'b1; end always @(posedge set[13] or posedge reset[13]) begin - if(reset[13]) out[13] <= 1'b0; - else out[13] <= 1'b1; + if(reset[13]) out[13] <= 1'b0; + else if(mask[13]) out[13] <= 1'b1; end always @(posedge set[14] or posedge reset[14]) begin - if(reset[14]) out[14] <= 1'b0; - else out[14] <= 1'b1; + if(reset[14]) out[14] <= 1'b0; + else if(mask[14]) out[14] <= 1'b1; end always @(posedge set[15] or posedge reset[15]) begin - if(reset[15]) out[15] <= 1'b0; - else out[15] <= 1'b1; + if(reset[15]) out[15] <= 1'b0; + else if(mask[15]) out[15] <= 1'b1; end endmodule