From a6c2bc45c3883ddec1ebbd803cb13815df2d07d4 Mon Sep 17 00:00:00 2001 From: harbaum Date: Mon, 30 Mar 2015 14:33:40 +0000 Subject: [PATCH] [ATARI ST] FDC/YM bug fix and basic debug overlay --- cores/mist/YM2149_volmix.vhd | 2 +- cores/mist/audio.v | 2 +- cores/mist/fdc.v | 22 ++-- cores/mist/font.v | 15 +++ cores/mist/font8x8.memh | 35 ++++++ cores/mist/mist.qsf | 2 + cores/mist/mist_top.v | 27 ++-- cores/mist/overlay.v | 234 +++++++++++++++++++++++++++++++++++ cores/mist/video.v | 34 ++++- 9 files changed, 345 insertions(+), 28 deletions(-) create mode 100644 cores/mist/font.v create mode 100644 cores/mist/font8x8.memh create mode 100644 cores/mist/overlay.v diff --git a/cores/mist/YM2149_volmix.vhd b/cores/mist/YM2149_volmix.vhd index 32b971a..dce51fe 100644 --- a/cores/mist/YM2149_volmix.vhd +++ b/cores/mist/YM2149_volmix.vhd @@ -310,7 +310,7 @@ begin else O_DA <= reg(14); -- read output reg end if; - when x"F" => if (Reg(7)(7) = '0') then + when x"F" => if (reg(7)(7) = '0') then O_DA <= iob_inreg; else O_DA <= reg(15); diff --git a/cores/mist/audio.v b/cores/mist/audio.v index e82e897..0490fcf 100644 --- a/cores/mist/audio.v +++ b/cores/mist/audio.v @@ -90,7 +90,7 @@ wire [7:0] psg_dout; YM2149 ym2149 ( .I_DA ( din[15:8] ), - .O_DA ( psg_data_out ), + .O_DA ( psg_dout ), .O_DA_OE_L ( ), // control diff --git a/cores/mist/fdc.v b/cores/mist/fdc.v index b0ca3e1..90b0907 100644 --- a/cores/mist/fdc.v +++ b/cores/mist/fdc.v @@ -38,7 +38,7 @@ module fdc ( input cpu_sel, input cpu_rw, input [7:0] cpu_din, - output reg [7:0] cpu_dout, + output [7:0] cpu_dout, output reg irq ); @@ -63,7 +63,7 @@ assign status_byte = (status_sel == 0)?cmd: (status_sel == 1)?track: (status_sel == 2)?sector: - (status_sel == 3)?data: + (status_sel == 3)?8'h00: // data: (status_sel == 4)?{ 4'b0000, drv_sel, drv_side, state == STATE_IO_WAIT }: 8'h00; @@ -124,18 +124,12 @@ wire [7:0] status = { }; // CPU register read -always @(cpu_sel, cpu_addr, cpu_rw) begin - cpu_dout = 8'h00; - - if(cpu_sel && cpu_rw) begin - case(cpu_addr) - 0: cpu_dout = status; - 1: cpu_dout = track; - 2: cpu_dout = sector; - 3: cpu_dout = data; - endcase - end -end +assign cpu_dout = + (cpu_sel && cpu_rw)?( + (cpu_addr == 0)?status: + (cpu_addr == 1)?track: + (cpu_addr == 2)?sector: + data):8'h00; // CPU register write always @(negedge clk or posedge reset) begin diff --git a/cores/mist/font.v b/cores/mist/font.v new file mode 100644 index 0000000..d219510 --- /dev/null +++ b/cores/mist/font.v @@ -0,0 +1,15 @@ +module font ( + input clk, + input [9:0] a, + output reg [7:0] d + ); + +always @(posedge clk) + d <= rom[a]; + +reg [7:0] rom [0:767]; + +initial $readmemh("font8x8.memh",rom); + +endmodule // font + diff --git a/cores/mist/font8x8.memh b/cores/mist/font8x8.memh new file mode 100644 index 0000000..fec07bc --- /dev/null +++ b/cores/mist/font8x8.memh @@ -0,0 +1,35 @@ +/* http://srecord.sourceforge.net/ */ +@00000000 00 00 00 00 00 00 00 00 30 30 30 30 30 00 30 00 66 66 00 00 00 00 00 +@00000017 00 50 F8 50 F8 50 00 00 00 7C D2 D0 7C 16 D6 7C 10 E3 A6 EC 18 37 65 +@0000002E C7 00 38 4C 38 45 C6 CE 7A 01 0C 0C 18 00 00 00 00 00 10 60 C0 C0 C0 +@00000045 60 10 00 10 0C 06 06 06 0C 10 00 00 54 38 FE 38 54 00 00 00 18 18 7E +@0000005C 18 18 00 00 00 00 00 00 00 00 18 70 00 00 00 7E 00 00 00 00 00 00 00 +@00000073 00 00 00 0C 00 01 03 06 0C 18 30 60 C0 3C 66 66 66 66 66 3C 00 18 38 +@0000008A 18 18 18 18 3C 00 7C C6 06 0C 30 60 FE 00 7C C6 06 3C 06 C6 7C 00 0E +@000000A1 1E 36 66 FE 06 06 00 FE C0 C0 FC 06 06 FC 00 7C C6 C0 FC C6 C6 7C 00 +@000000B8 FE 06 0C 18 30 30 30 00 7C C6 C6 7C C6 C6 7C 00 7C C6 C6 7E 06 C6 7C +@000000CF 00 00 30 00 00 00 30 00 00 00 30 00 00 00 30 20 00 00 1C 30 60 30 1C +@000000E6 00 00 00 00 7E 00 7E 00 00 00 00 70 18 0C 18 70 00 00 7C C6 0C 18 30 +@000000FD 00 30 00 7C 82 BA AA BE 80 7C 00 38 6C C6 C6 FE C6 C6 00 FC C6 C6 FC +@00000114 C6 C6 FC 00 7C C6 C0 C0 C6 C6 7C 00 FC C6 C6 C6 C6 C6 FC 00 FE C0 C0 +@0000012B F8 C0 C0 FE 00 FE C2 C0 F8 C8 C0 C0 00 7C C6 C0 DE C2 C6 7A 00 C6 C6 +@00000142 C6 FE C6 C6 C6 00 7E 18 18 18 18 18 7E 00 1E 0C 0C 0C 0C CC 78 00 C6 +@00000159 CC D8 F0 D8 CC C6 00 F0 60 60 60 60 62 FE 00 C6 EE FE D6 D6 C6 C6 00 +@00000170 C6 E6 F6 DE CE C6 C6 00 7C C6 C6 C6 C6 C6 7C 00 FC 66 66 7C 60 60 F0 +@00000187 00 7C C6 C6 C6 DE CE 7C 06 FC 66 66 7C 66 66 E6 03 7C C2 C0 7C 06 C6 +@0000019E 7C 00 7E 18 18 18 18 18 18 00 C6 C6 C6 C6 C6 C6 7C 00 C6 C6 C6 C6 C6 +@000001B5 6C 38 00 C6 C6 D6 D6 D6 EE C6 00 C6 6C 38 10 38 6C C6 00 82 C6 6C 38 +@000001CC 10 10 38 00 FE 86 0C 18 30 62 FE 00 1C 18 18 18 18 18 18 1C C0 60 30 +@000001E3 18 0C 06 03 01 70 30 30 30 30 30 30 70 10 38 6C C6 00 00 00 00 00 00 +@000001FA 00 00 00 00 00 FF 30 30 18 00 00 00 00 00 00 00 7C 06 7E C6 7E 00 C0 +@00000211 C0 FC C6 C6 C6 FC 00 00 00 7C C6 C0 C6 7C 00 06 06 7E C6 C6 C6 7E 00 +@00000228 00 00 7C C6 FE C0 7C 00 3C 66 60 FC 60 60 60 00 00 00 7D C6 C6 7E 06 +@0000023F 7C C0 C0 FC C6 C6 C6 C6 00 18 00 38 18 18 18 3C 00 0C 00 1C 0C 0C 0C +@00000256 CC 78 C0 C0 C6 D8 F0 D8 C6 00 38 18 18 18 18 18 1C 00 00 00 C6 FE D6 +@0000026D D6 C6 00 00 00 FC C6 C6 C6 C6 00 00 00 7C C6 C6 C6 7C 00 00 00 FC C6 +@00000284 C6 FC C0 C0 00 00 7E C6 C6 7E 06 07 00 00 DE 76 66 60 60 00 00 00 7E +@0000029B C0 7C 06 FC 00 18 18 7E 18 18 18 1E 00 00 00 C6 C6 C6 C6 7E 00 00 00 +@000002B2 C6 C6 C6 6C 38 00 00 00 C6 D6 D6 EE C6 00 00 00 C6 6C 38 6C C6 00 00 +@000002C9 00 C6 C6 C6 7E 06 FC 00 00 FE 0C 10 62 FE 00 0E 18 18 70 18 18 0E 00 +@000002E0 18 18 18 00 18 18 18 00 E0 30 30 1C 30 30 E0 00 70 9B 0E 00 00 00 00 +@000002F7 00 00 00 10 28 44 FE 00 00 diff --git a/cores/mist/mist.qsf b/cores/mist/mist.qsf index 759c395..bbb29dc 100644 --- a/cores/mist/mist.qsf +++ b/cores/mist/mist.qsf @@ -325,6 +325,8 @@ set_global_assignment -name VERILOG_FILE user_io.v set_global_assignment -name VERILOG_FILE video.v set_global_assignment -name VERILOG_FILE shifter.v set_global_assignment -name VERILOG_FILE scandoubler.v +set_global_assignment -name VERILOG_FILE overlay.v +set_global_assignment -name VERILOG_FILE font.v set_global_assignment -name VERILOG_FILE sync_adjust.v set_global_assignment -name VERILOG_FILE viking.v set_global_assignment -name VERILOG_FILE video_modes.v diff --git a/cores/mist/mist_top.v b/cores/mist/mist_top.v index dd49fe3..bac66d9 100644 --- a/cores/mist/mist_top.v +++ b/cores/mist/mist_top.v @@ -74,19 +74,19 @@ wire tg68_berr = (dtack_timeout == 4'd15); // count bus errors for debugging purposes. we can thus trigger for a // certain bus error -reg [3:0] berr_cnt_out /* synthesis noprune */; -reg [3:0] berr_cnt; +reg [7:0] berr_cnt_out /* synthesis noprune */; +reg [7:0] berr_cnt; reg berrD; always @(negedge clk_8) begin berrD <= tg68_berr; if(reset) begin - berr_cnt <= 4'd0; + berr_cnt <= 8'd0; end else begin - berr_cnt_out <= 4'd0; + berr_cnt_out <= 8'd0; if(tg68_berr && !berrD) begin - berr_cnt_out <= berr_cnt + 4'd1; - berr_cnt <= berr_cnt + 4'd1; + berr_cnt_out <= berr_cnt + 8'd1; + berr_cnt <= berr_cnt + 8'd1; end end end @@ -265,6 +265,8 @@ end wire viking_active = (viking_in_use == 8'hff); +// xyz + video video ( .clk_128 (clk_128 ), .clk_32 (clk_32 ), @@ -296,6 +298,12 @@ video video ( .video_g (VGA_G ), .video_b (VGA_B ), + // debug overlay + .dbg_enable (switches[0] ), + .dbg_val_a (tg68_adr ), + .dbg_val_d ({tg68_dat_out, cpu_data_in }), + .dbg_val_s ({16'h0000, berr_cnt, 6'b000000, tg68_busstate } ), + // configuration signals .viking_enable ( viking_active ), // enable and activate viking video card .viking_himem ( steroids ), // let viking use memory from $e80000 @@ -638,7 +646,6 @@ end // tg68 bus interface. These are the signals which are latched // for the 8MHz bus. -wire [15:0] tg68_dat_in; reg [15:0] tg68_dat_out; reg [31:0] tg68_adr; wire [2:0] tg68_IPL; @@ -784,11 +791,12 @@ always @(negedge clk_32) begin // cpu does internal processing -> let it do this immediately // or cpu wants to read and the requested data is available from the cache -> run immediately +// if((clkcnt == 3) && (tg68_busstate == 2'b01)) begin if((tg68_busstate == 2'b01) || ((tg68_busstate[0] == 1'b0) && cacheReady)) begin clkena <= 1'b1; cpuDoes8MhzCycle <= 1'b0; end - + else begin // this ends a normal 8MHz bus cycle. This requires that the // cpu/chipset had the entire cycle and not e.g. started just in @@ -1107,6 +1115,7 @@ wire eth_tx_read_strobe, eth_tx_read_begin; wire [7:0] eth_rx_write_byte; wire eth_rx_write_strobe, eth_rx_write_begin; +wire [2:0] switches; wire scandoubler_disable; //// user io has an extra spi channel outside minimig core //// @@ -1159,7 +1168,7 @@ user_io user_io( // io controller requests to disable vga scandoubler .scandoubler_disable (scandoubler_disable), - + .SWITCHES (switches ), .CORE_TYPE (8'ha3) // mist core id ); diff --git a/cores/mist/overlay.v b/cores/mist/overlay.v new file mode 100644 index 0000000..2f76a17 --- /dev/null +++ b/cores/mist/overlay.v @@ -0,0 +1,234 @@ +module overlay ( + // OSDs pixel clock, should be synchronous to cores pixel clock to + // avoid jitter. + input pclk, + input enable, + + // values to be displayed + input [31:0] val_a, + input [31:0] val_d, + input [31:0] val_s, + + // VGA signals coming from core + input [5:0] red_in, + input [5:0] green_in, + input [5:0] blue_in, + input hs_in, + input vs_in, + + // VGA signals going to video connector + output [5:0] red_out, + output [5:0] green_out, + output [5:0] blue_out +); + +// **************************************************************************** +// video timing and sync polarity anaylsis +// **************************************************************************** + +// horizontal counter +reg [9:0] h_cnt; +reg hsD, hsD2; +reg [9:0] hs_low, hs_high; +wire hs_pol = hs_high < hs_low; + +always @(posedge pclk) begin + // bring hsync into local clock domain + hsD <= hs_in; + hsD2 <= hsD; + + // falling edge of hs_in + if(!hsD && hsD2) begin + h_cnt <= 10'd0; + hs_high <= h_cnt; + end + + // rising edge of hs_in + else if(hsD && !hsD2) begin + h_cnt <= 10'd0; + hs_low <= h_cnt; + end + + else + h_cnt <= h_cnt + 10'd1; +end + +// vertical counter +reg [9:0] v_cnt; +reg vsD, vsD2; +reg [9:0] vs_low, vs_high; +wire vs_pol = vs_high < vs_low; + +always @(posedge hs_in) begin + // bring vsync into local clock domain + vsD <= vs_in; + vsD2 <= vsD; + + // falling edge of vs_in + if(!vsD && vsD2) begin + v_cnt <= 10'd0; + vs_high <= v_cnt; + end + + // rising edge of vs_in + else if(vsD && !vsD2) begin + v_cnt <= 10'd0; + vs_low <= v_cnt; + end + + else + v_cnt <= v_cnt + 10'd1; +end + +parameter X = 13; +parameter Y = 1; + +// address entry (A:XXXXXXXX) +wire a_act; +wire [7:0] a_data; +entry entry_a ( + .h ( h_cnt ), + .v ( v_cnt ), + + .t ( "A" ), + .x ( X ), + .y ( Y ), + .val ( val_a ), + + .data ( a_data ), + .act ( a_act ) +); + +// data entry (D:XXXX) +wire d_act; +wire [7:0] d_data; +entry entry_d ( + .h ( h_cnt ), + .v ( v_cnt ), + + .t ( "D" ), + .x ( X+12 ), + .y ( Y ), + .val ( val_d ), + + .data ( d_data ), + .act ( d_act ) +); + +// s (S:XX) +wire s_act; +wire [7:0] s_data; +entry entry_s ( + .h ( h_cnt ), + .v ( v_cnt ), + + .t ( "S" ), + .x ( X+24 ), + .y ( Y ), + .val ( val_s ), + + .data ( s_data ), + .act ( s_act ) +); + +wire act = a_act || d_act || s_act; +wire [7:0] data = + a_act?a_data: + d_act?d_data: + s_act?s_data: + "-"; + +// ---------------- display ------------------- +reg oe; + +wire [6:0] font_chr = data-7'd32; +wire [2:0] font_line = v_cnt[4:2]; +wire [9:0] font_addr = { font_chr, font_line }; + +wire [7:0] font_data; + +// -=- include 8x8 font -=- +font font ( + .clk ( pclk ), + .a ( font_addr ), + .d ( font_data ) +); + +reg [7:0] obyte; +reg act_out; + +always @(posedge pclk) begin + oe <= 1'b0; + act_out <= act; + + // only process outside sync phase + if((vs_in != vs_pol) && (hs_in != hs_pol)) begin + if(act_out) begin + if(h_cnt[3:0] == 1) obyte <= font_data; + else if(h_cnt[0] == 1) obyte[7:1] <= obyte[6:0]; + oe <= 1'b1; + end + end +end + +wire fg = enable && oe && obyte[7]; +wire bg = enable && oe; + +// mix signal into vga data stream +assign red_out = fg?6'b111111:bg?{1'b0, red_in[5:1]}: red_in; +assign green_out = fg?6'b001000:bg?{1'b0,green_in[5:1]}:green_in; +assign blue_out = fg?6'b001000:bg?{1'b0, blue_in[5:1]}: blue_in; + +endmodule + +module entry ( + input [9:0] h, + input [9:0] v, + + input [7:0] t, + input [6:0] x, // first character x position 0-127 + input [5:0] y, // first character y position 0-63 + input [31:0] val, + + output [7:0] data, + output act // this entry is currently active +); + +assign act = (h[9:4] >= x) && (h[9:4] < x + 8 + 2) && (y == v[9:5]); + +// x position within "string" +wire [6:0] x_i = h[9:4]-x; + +wire [7:0] asc0, asc1, asc2, asc3, asc4, asc5, asc6, asc7; +hex2asc hex0 ( .in (val[31:28]), .out (asc0 ) ); +hex2asc hex1 ( .in (val[27:24]), .out (asc1 ) ); +hex2asc hex2 ( .in (val[23:20]), .out (asc2 ) ); +hex2asc hex3 ( .in (val[19:16]), .out (asc3 ) ); +hex2asc hex4 ( .in (val[15:12]), .out (asc4 ) ); +hex2asc hex5 ( .in ( val[11:8]), .out (asc5 ) ); +hex2asc hex6 ( .in ( val[7:4]), .out (asc6 ) ); +hex2asc hex7 ( .in ( val[3:0]), .out (asc7 ) ); + +assign data = (x_i==0)?t: + (x_i==1)?":": + (x_i==2)?asc0: + (x_i==3)?asc1: + (x_i==4)?asc2: + (x_i==5)?asc3: + (x_i==6)?asc4: + (x_i==7)?asc5: + (x_i==8)?asc6: + (x_i==9)?asc7: + "X"; + +endmodule + +module hex2asc ( + input [3:0] in, + output [7:0] out +); + +assign out = (in <= 9)?("0"+in): + ("A"-10+in); + +endmodule diff --git a/cores/mist/video.v b/cores/mist/video.v index 8f6832f..269877e 100644 --- a/cores/mist/video.v +++ b/cores/mist/video.v @@ -43,6 +43,12 @@ module video ( input cpu_rw, output [15:0] cpu_dout, + // debug overlay + input dbg_enable, + input [31:0] dbg_val_a, + input [31:0] dbg_val_d, + input [31:0] dbg_val_s, + // screen interface output hs, // H_SYNC output vs, // V_SYNC @@ -99,9 +105,9 @@ osd osd ( .hs ( stvid_hs ), .vs ( stvid_vs ), - .r_in ( {stvid_r, 2'b00}), - .g_in ( {stvid_g, 2'b00}), - .b_in ( {stvid_b, 2'b00}), + .r_in ( ovl_r ), + .g_in ( ovl_g ), + .b_in ( ovl_b ), // receive signal with OSD overlayed .r_out ( video_r ), @@ -109,6 +115,28 @@ osd osd ( .b_out ( video_b ) ); +// include debug overlay +wire [5:0] ovl_r, ovl_g, ovl_b; +overlay overlay ( + .pclk ( clk_32 ), + .enable ( dbg_enable ), + + .val_a ( dbg_val_a ), + .val_d ( dbg_val_d ), + .val_s ( dbg_val_s ), + + .red_in ( {stvid_r, 2'b00}), + .green_in ( {stvid_g, 2'b00}), + .blue_in ( {stvid_b, 2'b00}), + .hs_in ( stvid_hs ), + .vs_in ( stvid_vs ), + + // receive signal with OSD overlayed + .red_out ( ovl_r ), + .green_out ( ovl_g ), + .blue_out ( ovl_b ) +); + // ------------- combine scandoubled shifter with viking ------------- wire [3:0] stvid_r = viking_enable?viking_r:shifter_sd_sblank_r; wire [3:0] stvid_g = viking_enable?viking_g:shifter_sd_sblank_g;