diff --git a/hw/ise/nes.xise b/hw/ise/nes.xise index 73d0544..acb82be 100644 --- a/hw/ise/nes.xise +++ b/hw/ise/nes.xise @@ -9,10 +9,10 @@ - + - + @@ -122,11 +122,15 @@ + + + + - - + + @@ -140,6 +144,8 @@ + + @@ -156,62 +162,61 @@ + - + - + + + - - + + + - - + - - + + - - + - - - - + + - + + - - @@ -230,10 +235,12 @@ - + + + @@ -251,6 +258,7 @@ + @@ -263,29 +271,22 @@ - - - - - - - + - + - + - @@ -311,8 +312,8 @@ - - + + @@ -320,7 +321,8 @@ - + + @@ -337,7 +339,7 @@ - + @@ -354,7 +356,6 @@ - @@ -362,6 +363,7 @@ + @@ -369,10 +371,9 @@ - - + - + @@ -387,7 +388,8 @@ - + + @@ -411,22 +413,24 @@ - + + + - - - - + + + + @@ -434,7 +438,7 @@ - + diff --git a/hw/src/cpu/jp.v b/hw/src/cpu/jp.v index 6606556..9e63538 100644 --- a/hw/src/cpu/jp.v +++ b/hw/src/cpu/jp.v @@ -32,28 +32,27 @@ module jp input wire wr, // write enable signal input wire [15:0] addr, // 16-bit memory address input wire din, // data input bus - input wire jp_data1, // joypad 1 input signal - input wire jp_data2, // joypad 2 input signal - output wire jp_clk, // joypad output clk signal - output wire jp_latch, // joypad output latch signal + input wire [ 7:0] joypad_cfg_in, // joypad input signal + input wire joypad_cfg_upd_in, // joypad cfg input signal output reg [ 7:0] dout // data output bus ); +reg [ 7:0] joypad_cfg_latch; + +wire jp_latch; -// -// FFs for tracking/reading current controller state. -// reg [7:0] q_jp1_state, d_jp1_state; reg [7:0] q_jp2_state, d_jp2_state; reg q_jp_clk, d_jp_clk; reg q_jp_latch, d_jp_latch; reg [8:0] q_cnt, d_cnt; + always @(posedge clk) begin if (rst) begin q_jp1_state <= 8'h00; - q_jp2_state <= 8'h00; + q_jp2_state <= 8'h00; q_jp_clk <= 1'b0; q_jp_latch <= 1'b0; q_cnt <= 9'h00; @@ -61,7 +60,7 @@ always @(posedge clk) else begin q_jp1_state <= d_jp1_state; - q_jp2_state <= d_jp2_state; + q_jp2_state <= d_jp2_state; q_jp_clk <= d_jp_clk; q_jp_latch <= d_jp_latch; q_cnt <= d_cnt; @@ -74,7 +73,7 @@ always @* begin // Default most FFs to current state. d_jp1_state = q_jp1_state; - d_jp2_state = q_jp2_state; + d_jp2_state = q_jp2_state; d_jp_clk = q_jp_clk; d_jp_latch = q_jp_latch; @@ -84,8 +83,8 @@ always @* // clock 7 more times to read other 7 buttons. Controller states are active low. if (q_cnt[5:1] == 5'h00) begin - d_jp1_state[state_idx] = ~jp_data1; - d_jp2_state[state_idx] = ~jp_data2; + d_jp1_state[state_idx] = ~joypad_cfg_latch[state_idx]; + d_jp2_state[state_idx] = 1; if (q_cnt[8:1] == 8'h00) d_jp_latch = 1'b1; @@ -101,10 +100,8 @@ always @* assign state_idx = q_cnt[8:6] - 3'h1; assign jp_latch = q_jp_latch; -assign jp_clk = q_jp_clk; localparam [15:0] JOYPAD1_MMR_ADDR = 16'h4016; -localparam [15:0] JOYPAD2_MMR_ADDR = 16'h4017; localparam S_STROBE_WROTE_0 = 1'b0, S_STROBE_WROTE_1 = 1'b1; @@ -123,14 +120,12 @@ always @(posedge clk) begin q_addr <= 16'h0000; q_jp1_read_state <= 9'h000; - q_jp2_read_state <= 9'h000; q_strobe_state <= S_STROBE_WROTE_0; end else begin q_addr <= addr; q_jp1_read_state <= d_jp1_read_state; - q_jp2_read_state <= d_jp2_read_state; q_strobe_state <= d_strobe_state; end end @@ -141,7 +136,7 @@ always @* // Default FFs to current state. d_jp1_read_state = q_jp1_read_state; - d_jp2_read_state = q_jp2_read_state; + d_jp2_read_state = q_jp2_read_state; d_strobe_state = q_strobe_state; if (addr[15:1] == JOYPAD1_MMR_ADDR[15:1]) @@ -163,7 +158,7 @@ always @* begin d_strobe_state = S_STROBE_WROTE_0; d_jp1_read_state = { q_jp1_state, 1'b0 }; - d_jp2_read_state = { q_jp2_state, 1'b0 }; + d_jp2_read_state = { q_jp2_state, 1'b1 }; end end @@ -171,11 +166,19 @@ always @* // should be 1. else if (!wr && !addr[0]) d_jp1_read_state = { 1'b1, q_jp1_read_state[8:1] }; - else if (!wr && addr[0]) + else if (!wr && addr[0]) d_jp2_read_state = { 1'b1, q_jp2_read_state[8:1] }; end end end -endmodule +always @(posedge joypad_cfg_upd_in) + begin + if( !jp_latch ) + begin + joypad_cfg_latch = joypad_cfg_in; + end + end + +endmodule \ No newline at end of file diff --git a/hw/src/cpu/rp2a03.v b/hw/src/cpu/rp2a03.v index c586d97..bd4fbd0 100644 --- a/hw/src/cpu/rp2a03.v +++ b/hw/src/cpu/rp2a03.v @@ -40,13 +40,17 @@ module rp2a03 output wire [15:0] a_out, // address bus output wire r_nw_out, // read/write select (write low) output wire brk_out, // debug break signal - + + /* // Joypad signals. input wire jp_data1_in, // joypad 1 input signal input wire jp_data2_in, // joypad 2 input signal output wire jp_clk, // joypad output clk signal output wire jp_latch, // joypad output latch signal - + */ + // Joypad signals. + input wire [ 7:0] joypad_cfg_in, + input wire joypad_cfg_upd_in, // Audio signals. input wire [ 3:0] mute_in, // disable autio channels output wire audio_out, // pwm audio output @@ -113,10 +117,8 @@ jp jp_blk( .wr(~cpu_r_nw), .addr(cpu_a), .din(cpu_dout[0]), - .jp_data1(jp_data1_in), - .jp_data2(jp_data2_in), - .jp_clk(jp_clk), - .jp_latch(jp_latch), + .joypad_cfg_in(joypad_cfg_in), + .joypad_cfg_upd_in(joypad_cfg_upd_in), .dout(jp_dout) ); diff --git a/hw/src/hci/hci.v b/hw/src/hci/hci.v index 83e3001..dc5da18 100644 --- a/hw/src/hci/hci.v +++ b/hw/src/hci/hci.v @@ -47,7 +47,9 @@ module hci output wire [15:0] ppu_vram_a, // ppu memory address output wire [ 7:0] ppu_vram_dout, // ppu data bus [output] output wire [39:0] cart_cfg, // cartridge config data (from iNES header) - output wire cart_cfg_upd // pulse on cart_cfg update so cart can reset + output wire cart_cfg_upd, // pulse on cart_cfg update so cart can reset + output wire [ 7:0] joypad_cfg, + output wire joypad_cfg_upd ); // Debug packet opcodes. @@ -63,7 +65,8 @@ localparam [7:0] OP_ECHO = 8'h00, OP_PPU_MEM_RD = 8'h09, OP_PPU_MEM_WR = 8'h0A, OP_PPU_DISABLE = 8'h0B, - OP_CART_SET_CFG = 8'h0C; + OP_CART_SET_CFG = 8'h0C, + OP_JOYPAD_SET_CFG = 8'h0D; // Error code bit positions. localparam DBG_UART_PARITY_ERR = 0, @@ -88,7 +91,8 @@ localparam [4:0] S_DISABLED = 5'h00, S_PPU_MEM_WR_STG_1 = 5'h0F, S_PPU_DISABLE = 5'h10, S_CART_SET_CFG_STG_0 = 5'h11, - S_CART_SET_CFG_STG_1 = 5'h12; + S_CART_SET_CFG_STG_1 = 5'h12, + S_JOYPAD_CFG_STG_0 = 5'h13; reg [ 4:0] q_state, d_state; reg [ 2:0] q_decode_cnt, d_decode_cnt; @@ -97,6 +101,8 @@ reg [15:0] q_addr, d_addr; reg [ 1:0] q_err_code, d_err_code; reg [39:0] q_cart_cfg, d_cart_cfg; reg q_cart_cfg_upd, d_cart_cfg_upd; +reg [ 7:0] q_joypad_cfg, d_joypad_cfg; +reg q_joypad_cfg_upd, d_joypad_cfg_upd; // UART output buffer FFs. reg [7:0] q_tx_data, d_tx_data; @@ -121,6 +127,8 @@ always @(posedge clk) q_err_code <= 0; q_cart_cfg <= 40'h0000000000; q_cart_cfg_upd <= 1'b0; + q_joypad_cfg <= 8'h00; + q_joypad_cfg_upd <= 1'b0; q_tx_data <= 8'h00; q_wr_en <= 1'b0; end @@ -133,6 +141,8 @@ always @(posedge clk) q_err_code <= d_err_code; q_cart_cfg <= d_cart_cfg; q_cart_cfg_upd <= d_cart_cfg_upd; + q_joypad_cfg <= d_joypad_cfg; + q_joypad_cfg_upd <= d_joypad_cfg_upd; q_tx_data <= d_tx_data; q_wr_en <= d_wr_en; end @@ -140,7 +150,7 @@ always @(posedge clk) // Instantiate the serial controller block. uart #(.SYS_CLK_FREQ(100000000), - .BAUD_RATE(38400), + .BAUD_RATE(256000), .DATA_BITS(8), .STOP_BITS(1), .PARITY_MODE(1)) uart_blk @@ -168,6 +178,8 @@ always @* d_err_code = q_err_code; d_cart_cfg = q_cart_cfg; d_cart_cfg_upd = 1'b0; + d_joypad_cfg = q_joypad_cfg; + d_joypad_cfg_upd = 1'b0; rd_en = 1'b0; d_tx_data = 8'h00; @@ -205,6 +217,10 @@ always @* d_tx_data = 8'h00; // Write "0" over UART to indicate we are not in a debug break d_wr_en = 1'b1; end + else if (rd_data == OP_JOYPAD_SET_CFG) + begin + d_state = S_JOYPAD_CFG_STG_0; + end end end S_DECODE: @@ -227,6 +243,7 @@ always @* OP_PPU_MEM_WR: d_state = S_PPU_MEM_WR_STG_0; OP_PPU_DISABLE: d_state = S_PPU_DISABLE; OP_CART_SET_CFG: d_state = S_CART_SET_CFG_STG_0; + OP_JOYPAD_SET_CFG: d_state = S_JOYPAD_CFG_STG_0; OP_DBG_RUN: begin d_state = S_DISABLED; @@ -642,16 +659,31 @@ always @* d_cart_cfg_upd = 1'b1; end end - end + end + // --- JOYPAD_READ_FLAG --- + S_JOYPAD_CFG_STG_0: + begin + if (!rx_empty) + begin + rd_en = 1'b1; // pop packet byte off uart fifo + d_joypad_cfg = rd_data; + + // After last byte of packet, return to decode stage. + d_state = S_DISABLED; + d_joypad_cfg_upd = 1'b1; + end + end endcase end assign cpu_a = q_addr; -assign active = (q_state != S_DISABLED); +assign active = (q_state != S_DISABLED && q_state != S_JOYPAD_CFG_STG_0); assign ppu_vram_a = q_addr; assign ppu_vram_dout = rd_data; assign cart_cfg = q_cart_cfg; assign cart_cfg_upd = q_cart_cfg_upd; +assign joypad_cfg = q_joypad_cfg; +assign joypad_cfg_upd = q_joypad_cfg_upd; endmodule diff --git a/hw/src/nes.ucf b/hw/src/nes.ucf index cd5dc84..cbe1315 100644 --- a/hw/src/nes.ucf +++ b/hw/src/nes.ucf @@ -1,41 +1,55 @@ # ==== Clock inputs (CLK) ==== -NET "CLK_100MHZ" LOC=V10 | IOSTANDARD=LVCMOS33; +NET "CLK_100MHZ" LOC=E3 | IOSTANDARD=LVCMOS33; NET "CLK_100MHZ" TNM_NET = sys_clk_pin; TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 100000 kHz; # ==== Pushbuttons (BTN) ==== -NET "BTN_SOUTH" LOC = C9 | IOSTANDARD = LVCMOS33; -NET "BTN_EAST" LOC = D9 | IOSTANDARD = LVCMOS33; +NET "BTN_SOUTH" LOC = T16 | IOSTANDARD = LVCMOS33; +NET "BTN_EAST" LOC = R10 | IOSTANDARD = LVCMOS33; # ==== Slide Switch (SW0) ==== -NET "SW<0>" LOC = T10 | IOSTANDARD = LVCMOS33; -NET "SW<1>" LOC = T9 | IOSTANDARD = LVCMOS33; -NET "SW<2>" LOC = V9 | IOSTANDARD = LVCMOS33; -NET "SW<3>" LOC = M8 | IOSTANDARD = LVCMOS33; +NET "SW<0>" LOC = U9 | IOSTANDARD = LVCMOS33; +NET "SW<1>" LOC = U8 | IOSTANDARD = LVCMOS33; +NET "SW<2>" LOC = R7 | IOSTANDARD = LVCMOS33; +NET "SW<3>" LOC = R6 | IOSTANDARD = LVCMOS33; # ==== RS-232 Serial Ports (RS232) ==== -NET "RXD" LOC = N17 | IOSTANDARD=LVCMOS33; -NET "TXD" LOC = N18 | IOSTANDARD=LVCMOS33; +NET "RXD" LOC = C4 | IOSTANDARD=LVCMOS33; +NET "TXD" LOC = D4 | IOSTANDARD=LVCMOS33; # ==== Joypads ==== -NET "NES_JOYPAD_CLK" LOC = E12 | IOSTANDARD = LVCMOS33; -NET "NES_JOYPAD_LATCH" LOC = F12 | IOSTANDARD = LVCMOS33; -NET "NES_JOYPAD_DATA1" LOC = C12 | IOSTANDARD = LVCMOS33; -NET "NES_JOYPAD_DATA2" LOC = D12 | IOSTANDARD = LVCMOS33; +#NET "NES_JOYPAD_CLK" LOC = B13 | IOSTANDARD = LVCMOS33;#JA1 +#NET "NES_JOYPAD_LATCH" LOC = F14 | IOSTANDARD = LVCMOS33; +#NET "NES_JOYPAD_DATA1" LOC = D17 | IOSTANDARD = LVCMOS33; +#NET "NES_JOYPAD_DATA2" LOC = E17 | IOSTANDARD = LVCMOS33; +NET "led<0>" LOC = "T8" | IOSTANDARD = "LVCMOS33"; #Bank = 34, Pin name = IO_L24N_T3_34, Sch name = LED0 +NET "led<1>" LOC = "V9" | IOSTANDARD = "LVCMOS33"; #Bank = 34, Pin name = IO_L21N_T3_DQS_34, Sch name = LED1 +NET "led<2>" LOC = "R8" | IOSTANDARD = "LVCMOS33"; #Bank = 34, Pin name = IO_L24P_T3_34, Sch name = LED2 +NET "led<3>" LOC = "T6" | IOSTANDARD = "LVCMOS33"; #Bank = 34, Pin name = IO_L23N_T3_34, Sch name = LED3 +NET "led<4>" LOC = "T5" | IOSTANDARD = "LVCMOS33"; #Bank = 34, Pin name = IO_L12P_T1_MRCC_34, Sch name = LED4 +NET "led<5>" LOC = "T4" | IOSTANDARD = "LVCMOS33"; #Bank = 34, Pin name = IO_L12N_T1_MRCC_34, Sch name = LED5 +NET "led<6>" LOC = "U7" | IOSTANDARD = "LVCMOS33"; #Bank = 34, Pin name = IO_L22P_T3_34, Sch name = LED6 +NET "led<7>" LOC = "U6" | IOSTANDARD = "LVCMOS33"; #Bank = 34, Pin name = IO_L22N_T3_34, Sch name = LED7 + # ==== VGA Port (VGA) ==== -NET "VGA_HSYNC" LOC = N6 | IOSTANDARD = LVCMOS33; -NET "VGA_VSYNC" LOC = P7 | IOSTANDARD = LVCMOS33; -NET "VGA_RED<0>" LOC = U7 | IOSTANDARD = LVCMOS33; -NET "VGA_RED<1>" LOC = V7 | IOSTANDARD = LVCMOS33; -NET "VGA_RED<2>" LOC = N7 | IOSTANDARD = LVCMOS33; -NET "VGA_GREEN<0>" LOC = P8 | IOSTANDARD = LVCMOS33; -NET "VGA_GREEN<1>" LOC = T6 | IOSTANDARD = LVCMOS33; -NET "VGA_GREEN<2>" LOC = V6 | IOSTANDARD = LVCMOS33; -NET "VGA_BLUE<0>" LOC = R7 | IOSTANDARD = LVCMOS33; -NET "VGA_BLUE<1>" LOC = T7 | IOSTANDARD = LVCMOS33; +NET "VGA_HSYNC" LOC = B11 | IOSTANDARD = LVCMOS33; +NET "VGA_VSYNC" LOC = B12 | IOSTANDARD = LVCMOS33; +NET "VGA_RED<0>" LOC = A3 | IOSTANDARD = LVCMOS33; +NET "VGA_RED<1>" LOC = B4 | IOSTANDARD = LVCMOS33; +NET "VGA_RED<2>" LOC = C5 | IOSTANDARD = LVCMOS33; +NET "VGA_RED<3>" LOC = A4 | IOSTANDARD = LVCMOS33; +NET "VGA_GREEN<0>" LOC = C6 | IOSTANDARD = LVCMOS33; +NET "VGA_GREEN<1>" LOC = A5 | IOSTANDARD = LVCMOS33; +NET "VGA_GREEN<2>" LOC = B6 | IOSTANDARD = LVCMOS33; +NET "VGA_GREEN<3>" LOC = A6 | IOSTANDARD = LVCMOS33; +NET "VGA_BLUE<0>" LOC = B7 | IOSTANDARD = LVCMOS33; +NET "VGA_BLUE<1>" LOC = C7 | IOSTANDARD = LVCMOS33; +NET "VGA_BLUE<2>" LOC = D7 | IOSTANDARD = LVCMOS33; +NET "VGA_BLUE<3>" LOC = D8 | IOSTANDARD = LVCMOS33; # ==== Audio ==== -NET "AUDIO" LOC = "K2" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6; +NET "AUDIO" LOC = A11 | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6;#MONO AUDIO OUT +NET "AUDIO_SD" LOC = D12 | IOSTANDARD = LVCMOS33; diff --git a/hw/src/nes_palette.txt b/hw/src/nes_palette.txt new file mode 100644 index 0000000..3930682 --- /dev/null +++ b/hw/src/nes_palette.txt @@ -0,0 +1,64 @@ +3def +7c00 +5c00 +5ca8 +4012 +1015 +0055 +0051 +00ca +01e0 +01a0 +0160 +2d00 +0000 +0000 +0000 +5ef7 +7de0 +7d60 +7d0d +641b +2c1c +00ff +097c +01f5 +02e0 +02a0 +22a0 +4620 +0000 +0000 +0000 +7fff +7ee7 +7e2d +7df3 +7dff +4d7f +2dff +229f +02ff +0ff7 +2b6b +4feb +6fa0 +3def +0000 +0000 +7fff +7f94 +7ef7 +7efb +7eff +629f +5b5e +579f +3f7f +3ffb +5ff7 +6ff7 +7fe0 +7f7f +0000 +0000 \ No newline at end of file diff --git a/hw/src/nes_top.v b/hw/src/nes_top.v index c1ffd00..e7aed98 100644 --- a/hw/src/nes_top.v +++ b/hw/src/nes_top.v @@ -32,19 +32,23 @@ module nes_top input wire BTN_EAST, // console reset input wire RXD, // rs-232 rx signal input wire [3:0] SW, // switches - input wire NES_JOYPAD_DATA1, // joypad 1 input signal - input wire NES_JOYPAD_DATA2, // joypad 2 input signal + //input wire NES_JOYPAD_DATA1, // joypad 1 input signal + //input wire NES_JOYPAD_DATA2, // joypad 2 input signal output wire TXD, // rs-232 tx signal output wire VGA_HSYNC, // vga hsync signal output wire VGA_VSYNC, // vga vsync signal - output wire [2:0] VGA_RED, // vga red signal - output wire [2:0] VGA_GREEN, // vga green signal - output wire [1:0] VGA_BLUE, // vga blue signal - output wire NES_JOYPAD_CLK, // joypad output clk signal - output wire NES_JOYPAD_LATCH, // joypad output latch signal - output wire AUDIO // pwm output audio channel + output wire [3:0] VGA_RED, // vga red signal + output wire [3:0] VGA_GREEN, // vga green signal + output wire [3:0] VGA_BLUE, // vga blue signal + //output wire NES_JOYPAD_CLK, // joypad output clk signal + //output wire NES_JOYPAD_LATCH, // joypad output latch signal + output wire AUDIO, // pwm output audio channel + output wire AUDIO_SD, // OP enable/disable pin + output wire [7:0] led ); +assign AUDIO_SD = 1'b1; //enable AUD_SD + // // System Memory Buses // @@ -71,6 +75,10 @@ wire [ 7:0] rp2a03_dbgreg_din; wire rp2a03_dbgreg_wr; wire [ 7:0] rp2a03_dbgreg_dout; +// JOYPAD +wire [ 7:0] joypad_cfg; +wire joypad_cfg_upd; + rp2a03 rp2a03_blk( .clk_in(CLK_100MHZ), .rst_in(BTN_SOUTH), @@ -82,10 +90,14 @@ rp2a03 rp2a03_blk( .a_out(rp2a03_a), .r_nw_out(rp2a03_r_nw), .brk_out(rp2a03_brk), + /* .jp_data1_in(NES_JOYPAD_DATA1), .jp_data2_in(NES_JOYPAD_DATA2), .jp_clk(NES_JOYPAD_CLK), .jp_latch(NES_JOYPAD_LATCH), + */ + .joypad_cfg_in(joypad_cfg), + .joypad_cfg_upd_in(joypad_cfg_upd), .mute_in(SW), .audio_out(AUDIO), .dbgreg_sel_in(rp2a03_dbgreg_sel), @@ -234,7 +246,9 @@ hci hci_blk( .ppu_vram_a(hci_ppu_vram_a), .ppu_vram_dout(hci_ppu_vram_dout), .cart_cfg(cart_cfg), - .cart_cfg_upd(cart_cfg_upd) + .cart_cfg_upd(cart_cfg_upd), + .joypad_cfg(joypad_cfg), + .joypad_cfg_upd(joypad_cfg_upd) ); // Mux cpumc signals from rp2a03 or hci blk, depending on debug break state (hci_active). @@ -257,5 +271,7 @@ assign hci_ppu_vram_din = cart_chr_dout | vram_dout; // Issue NMI interupt on PPU vertical blank. assign rp2a03_nnmi = ppu_nvbl; +assign led = joypad_cfg; + endmodule diff --git a/hw/src/ppu/ppu.v b/hw/src/ppu/ppu.v index 9ec05d3..a638e9f 100644 --- a/hw/src/ppu/ppu.v +++ b/hw/src/ppu/ppu.v @@ -36,9 +36,9 @@ module ppu input wire [ 7:0] vram_d_in, // video memory data bus (input) output wire hsync_out, // vga hsync signal output wire vsync_out, // vga vsync signal - output wire [ 2:0] r_out, // vga red signal - output wire [ 2:0] g_out, // vga green signal - output wire [ 1:0] b_out, // vga blue signal + output wire [ 3:0] r_out, // vga red signal + output wire [ 3:0] g_out, // vga green signal + output wire [ 3:0] b_out, // vga blue signal output wire [ 7:0] ri_d_out, // register interface data out output wire nvbl_out, // /VBL (low during vertical blank) output wire [13:0] vram_a_out, // video memory address bus diff --git a/hw/src/ppu/ppu_vga.v b/hw/src/ppu/ppu_vga.v index 8ea4284..5943f52 100644 --- a/hw/src/ppu/ppu_vga.v +++ b/hw/src/ppu/ppu_vga.v @@ -32,14 +32,16 @@ module ppu_vga input wire [5:0] sys_palette_idx_in, // system palette index (selects output color) output wire hsync_out, // vga hsync signal output wire vsync_out, // vga vsync signal - output wire [2:0] r_out, // vga red signal - output wire [2:0] g_out, // vga green signal - output wire [1:0] b_out, // vga blue signal + output wire [3:0] r_out, // vga red signal + output wire [3:0] g_out, // vga green signal + output wire [3:0] b_out, // vga blue signal output wire [9:0] nes_x_out, // nes x coordinate output wire [9:0] nes_y_out, // nes y coordinate output wire [9:0] nes_y_next_out, // next line's nes y coordinate output wire pix_pulse_out, // 1 clk pulse prior to nes_x update output wire vblank_out // indicates a vblank is occuring (no PPU vram access) + //output wire [14:0] single_pixel, + //input wire [14:0] double_pixel ); // Display dimensions (640x480). @@ -62,6 +64,9 @@ wire [9:0] sync_y; // current vga y coordinate wire [9:0] sync_x_next; // vga x coordinate for next clock wire [9:0] sync_y_next; // vga y coordinate for next line +reg [14:0] pallut[0:63]; +initial $readmemh("nes_palette.txt", pallut); + vga_sync vga_sync_blk( .clk(clk_in), .hsync(hsync_out), @@ -76,8 +81,8 @@ vga_sync vga_sync_blk( // // Registers. // -reg [7:0] q_rgb; // output color latch (1 clk delay required by vga_sync) -reg [7:0] d_rgb; +reg [14:0] q_rgb; // output color latch (1 clk delay required by vga_sync) +reg [14:0] d_rgb; reg q_vblank; // current vblank state wire d_vblank; @@ -85,7 +90,7 @@ always @(posedge clk_in) begin if (rst_in) begin - q_rgb <= 8'h00; + q_rgb <= 14'h00; q_vblank <= 1'h0; end else @@ -122,81 +127,11 @@ always @* end else begin - // Lookup RGB values based on sys_palette_idx. Table is an approximation of the NES - // system palette. Taken from http://nesdev.parodius.com/NESTechFAQ.htm#nessnescompat. - case (sys_palette_idx_in) - 6'h00: d_rgb = { 3'h3, 3'h3, 2'h1 }; - 6'h01: d_rgb = { 3'h1, 3'h0, 2'h2 }; - 6'h02: d_rgb = { 3'h0, 3'h0, 2'h2 }; - 6'h03: d_rgb = { 3'h2, 3'h0, 2'h2 }; - 6'h04: d_rgb = { 3'h4, 3'h0, 2'h1 }; - 6'h05: d_rgb = { 3'h5, 3'h0, 2'h0 }; - 6'h06: d_rgb = { 3'h5, 3'h0, 2'h0 }; - 6'h07: d_rgb = { 3'h3, 3'h0, 2'h0 }; - 6'h08: d_rgb = { 3'h2, 3'h1, 2'h0 }; - 6'h09: d_rgb = { 3'h0, 3'h2, 2'h0 }; - 6'h0a: d_rgb = { 3'h0, 3'h2, 2'h0 }; - 6'h0b: d_rgb = { 3'h0, 3'h1, 2'h0 }; - 6'h0c: d_rgb = { 3'h0, 3'h1, 2'h1 }; - 6'h0d: d_rgb = { 3'h0, 3'h0, 2'h0 }; - 6'h0e: d_rgb = { 3'h0, 3'h0, 2'h0 }; - 6'h0f: d_rgb = { 3'h0, 3'h0, 2'h0 }; - - 6'h10: d_rgb = { 3'h5, 3'h5, 2'h2 }; - 6'h11: d_rgb = { 3'h0, 3'h3, 2'h3 }; - 6'h12: d_rgb = { 3'h1, 3'h1, 2'h3 }; - 6'h13: d_rgb = { 3'h4, 3'h0, 2'h3 }; - 6'h14: d_rgb = { 3'h5, 3'h0, 2'h2 }; - 6'h15: d_rgb = { 3'h7, 3'h0, 2'h1 }; - 6'h16: d_rgb = { 3'h6, 3'h1, 2'h0 }; - 6'h17: d_rgb = { 3'h6, 3'h2, 2'h0 }; - 6'h18: d_rgb = { 3'h4, 3'h3, 2'h0 }; - 6'h19: d_rgb = { 3'h0, 3'h4, 2'h0 }; - 6'h1a: d_rgb = { 3'h0, 3'h5, 2'h0 }; - 6'h1b: d_rgb = { 3'h0, 3'h4, 2'h0 }; - 6'h1c: d_rgb = { 3'h0, 3'h4, 2'h2 }; - 6'h1d: d_rgb = { 3'h0, 3'h0, 2'h0 }; - 6'h1e: d_rgb = { 3'h0, 3'h0, 2'h0 }; - 6'h1f: d_rgb = { 3'h0, 3'h0, 2'h0 }; - - 6'h20: d_rgb = { 3'h7, 3'h7, 2'h3 }; - 6'h21: d_rgb = { 3'h1, 3'h5, 2'h3 }; - 6'h22: d_rgb = { 3'h2, 3'h4, 2'h3 }; - 6'h23: d_rgb = { 3'h5, 3'h4, 2'h3 }; - 6'h24: d_rgb = { 3'h7, 3'h3, 2'h3 }; - 6'h25: d_rgb = { 3'h7, 3'h3, 2'h2 }; - 6'h26: d_rgb = { 3'h7, 3'h3, 2'h1 }; - 6'h27: d_rgb = { 3'h7, 3'h4, 2'h0 }; - 6'h28: d_rgb = { 3'h7, 3'h5, 2'h0 }; - 6'h29: d_rgb = { 3'h4, 3'h6, 2'h0 }; - 6'h2a: d_rgb = { 3'h2, 3'h6, 2'h1 }; - 6'h2b: d_rgb = { 3'h2, 3'h7, 2'h2 }; - 6'h2c: d_rgb = { 3'h0, 3'h7, 2'h3 }; - 6'h2d: d_rgb = { 3'h0, 3'h0, 2'h0 }; - 6'h2e: d_rgb = { 3'h0, 3'h0, 2'h0 }; - 6'h2f: d_rgb = { 3'h0, 3'h0, 2'h0 }; - - 6'h30: d_rgb = { 3'h7, 3'h7, 2'h3 }; - 6'h31: d_rgb = { 3'h5, 3'h7, 2'h3 }; - 6'h32: d_rgb = { 3'h6, 3'h6, 2'h3 }; - 6'h33: d_rgb = { 3'h6, 3'h6, 2'h3 }; - 6'h34: d_rgb = { 3'h7, 3'h6, 2'h3 }; - 6'h35: d_rgb = { 3'h7, 3'h6, 2'h3 }; - 6'h36: d_rgb = { 3'h7, 3'h5, 2'h2 }; - 6'h37: d_rgb = { 3'h7, 3'h6, 2'h2 }; - 6'h38: d_rgb = { 3'h7, 3'h7, 2'h2 }; - 6'h39: d_rgb = { 3'h7, 3'h7, 2'h2 }; - 6'h3a: d_rgb = { 3'h5, 3'h7, 2'h2 }; - 6'h3b: d_rgb = { 3'h5, 3'h7, 2'h3 }; - 6'h3c: d_rgb = { 3'h4, 3'h7, 2'h3 }; - 6'h3d: d_rgb = { 3'h0, 3'h0, 2'h0 }; - 6'h3e: d_rgb = { 3'h0, 3'h0, 2'h0 }; - 6'h3f: d_rgb = { 3'h0, 3'h0, 2'h0 }; - endcase + d_rgb = pallut[sys_palette_idx_in]; end end -assign { r_out, g_out, b_out } = q_rgb; +assign { r_out, g_out, b_out } = {q_rgb[4:1], q_rgb[9:6], q_rgb[14:11]}; assign pix_pulse_out = nes_x_next != nes_x_out; // Clear the VBLANK signal immediately before starting processing of the pre-0 garbage line. From @@ -208,5 +143,4 @@ assign d_vblank = ((sync_x == 730) && (sync_y == 477)) ? 1'b1 : assign vblank_out = q_vblank; -endmodule - +endmodule \ No newline at end of file diff --git a/sw/Release/nesdbg.exe b/sw/Release/nesdbg.exe new file mode 100644 index 0000000..1f21ad2 Binary files /dev/null and b/sw/Release/nesdbg.exe differ diff --git a/sw/nesdbg.sln b/sw/nesdbg.sln index 02b4a24..f3db855 100644 --- a/sw/nesdbg.sln +++ b/sw/nesdbg.sln @@ -1,6 +1,6 @@  Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C++ Express 2010 +# Visual Studio 2010 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nesdbg", "nesdbg.vcxproj", "{29F2F891-71B4-448F-BCC6-83F109705C79}" EndProject Global diff --git a/sw/nesdbg.vcxproj b/sw/nesdbg.vcxproj index 142f2f2..7b3708b 100644 --- a/sw/nesdbg.vcxproj +++ b/sw/nesdbg.vcxproj @@ -16,6 +16,7 @@ + @@ -23,6 +24,7 @@ + @@ -43,6 +45,7 @@ Application Unicode + false @@ -72,14 +75,14 @@ WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) true EnableFastChecks - MultiThreadedDebugDLL + MultiThreadedDebug Level3 EditAndContinue - .\lib\lua\lib\lua51.lib;%(AdditionalDependencies) + .\lib\lua\lib\lua51.lib;%(AdditionalDependencies);WinMM.lib true Windows MachineX86 @@ -99,7 +102,7 @@ ProgramDatabase - .\lib\lua\lib\lua51.lib;%(AdditionalDependencies) + .\lib\lua\lib\lua51.lib;%(AdditionalDependencies);WinMM.lib true Windows true diff --git a/sw/nesdbg.vcxproj.filters b/sw/nesdbg.vcxproj.filters index f8b87d1..c4caf32 100644 --- a/sw/nesdbg.vcxproj.filters +++ b/sw/nesdbg.vcxproj.filters @@ -38,6 +38,9 @@ Header Files + + Header Files + @@ -58,5 +61,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/sw/rsrc/nesdbg.rc b/sw/rsrc/nesdbg.rc index d7f45b9..d8a2cb2 100644 --- a/sw/rsrc/nesdbg.rc +++ b/sw/rsrc/nesdbg.rc @@ -1,5 +1,5 @@ -// Generated by ResEdit 1.5.11 -// Copyright (C) 2006-2012 +// Generated by ResEdit 1.6.2 +// Copyright (C) 2006-2014 // http://www.resedit.net #include @@ -16,17 +16,19 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL MainMenu MENU { - POPUP "File" + POPUP "Îļþ" { - MENUITEM "Load ROM...", IDM_FILE_LOADROM + MENUITEM "¼ÓÔØROM...", IDM_FILE_LOADROM MENUITEM SEPARATOR - MENUITEM "Exit", IDM_FILE_EXIT + MENUITEM "Í˳ö", IDM_FILE_EXIT } - POPUP "Tools" + POPUP "Tools", INACTIVE { MENUITEM "Raw Debug...", IDM_TOOLS_RAWDEBUG, MENUBREAK MENUITEM "Test Scripts...", IDM_TOOLS_TESTSCRIPTS } + MENUITEM "ÊÖ±ú", IDM_JOYPAD1 + MENUITEM "¹Ø±ÕÊÖ±ú", IDM_STOPJOYPAD_1 } @@ -40,44 +42,44 @@ STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VIS CAPTION "Raw Debug" FONT 8, "Ms Shell Dlg" { - PUSHBUTTON "Done", IDC_RAWDBG_DONE, 234, 161, 50, 14 - EDITTEXT IDC_RAWDBG_IN, 43, 4, 187, 13, ES_AUTOHSCROLL - LTEXT "Serial Data:", IDC_STATIC, 4, 7, 38, 8, SS_LEFT - DEFPUSHBUTTON "Send", IDC_RAWDBG_SEND, 234, 4, 50, 14 - EDITTEXT IDC_RAWDBG_OUT, 4, 37, 280, 119, WS_VSCROLL | NOT WS_TABSTOP | ES_AUTOVSCROLL | ES_MULTILINE - LTEXT "Raw Debug Output:", IDC_STATIC, 4, 25, 64, 8, SS_LEFT - PUSHBUTTON "Clear", IDC_RAWDBG_CLEAR, 181, 161, 50, 14 - CONTROL "", IDC_RAWDBG_PROGRESS, PROGRESS_CLASS, PBS_SMOOTH, 4, 162, 174, 12 + PUSHBUTTON "Done", IDC_RAWDBG_DONE, 234, 161, 50, 14, 0, WS_EX_LEFT + EDITTEXT IDC_RAWDBG_IN, 43, 4, 187, 13, ES_AUTOHSCROLL, WS_EX_LEFT + LTEXT "Serial Data:", IDC_STATIC, 4, 7, 38, 8, SS_LEFT, WS_EX_LEFT + DEFPUSHBUTTON "Send", IDC_RAWDBG_SEND, 234, 4, 50, 14, 0, WS_EX_LEFT + EDITTEXT IDC_RAWDBG_OUT, 4, 37, 280, 119, WS_VSCROLL | NOT WS_TABSTOP | ES_AUTOVSCROLL | ES_MULTILINE, WS_EX_LEFT + LTEXT "Raw Debug Output:", IDC_STATIC, 4, 25, 64, 8, SS_LEFT, WS_EX_LEFT + PUSHBUTTON "Clear", IDC_RAWDBG_CLEAR, 181, 161, 50, 14, 0, WS_EX_LEFT + CONTROL "", IDC_RAWDBG_PROGRESS, PROGRESS_CLASS, PBS_SMOOTH, 4, 162, 174, 12, WS_EX_LEFT } LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -TestScriptDlg DIALOG 0, 0, 453, 260 +RomLoadProgressDlg DIALOG 0, 0, 186, 19 STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU -EXSTYLE WS_EX_WINDOWEDGE -CAPTION "Test Scripts" +CAPTION "ROM¼ÓÔؽø³Ì" FONT 8, "Ms Shell Dlg" { - DEFPUSHBUTTON "Done", IDC_TESTSCRIPTS_DONE, 399, 242, 50, 14 - LTEXT "Test Scripts:", IDC_STATIC, 4, 4, 40, 8, SS_LEFT - DEFPUSHBUTTON "Run", IDC_TESTSCRIPTS_RUN, 347, 242, 50, 14 - CONTROL "", IDC_TESTSCRIPTS_PROGRESS, PROGRESS_CLASS, PBS_SMOOTH, 74, 79, 225, 11 - LTEXT "Progress:", IDC_TESTSCRIPTS_PROGRESSTXT, 4, 81, 65, 8, SS_LEFT - LISTBOX IDC_TESTSCRIPTS_LIST, 4, 15, 447, 60, WS_TABSTOP | WS_VSCROLL | LBS_NOINTEGRALHEIGHT | LBS_HASSTRINGS | LBS_EXTENDEDSEL | LBS_SORT | LBS_NOTIFY - EDITTEXT IDC_TESTSCRIPTS_OUTPUT, 4, 107, 447, 131, WS_VSCROLL | NOT WS_TABSTOP | ES_AUTOHSCROLL | ES_MULTILINE | ES_READONLY - LTEXT "Test Output:", IDC_STATIC, 4, 96, 40, 8, SS_LEFT - LTEXT "Results: 0 Pass / 0 Fail / 0 Error", IDC_TESTSCRIPTS_RESULTSTXT, 310, 81, 135, 8, SS_LEFT - DEFPUSHBUTTON "Clear", IDC_TESTSCRIPTS_CLEAR, 4, 242, 50, 14 + CONTROL "", IDC_ROMLOAD_PROGRESS, PROGRESS_CLASS, PBS_SMOOTH, 2, 4, 182, 11, WS_EX_LEFT } LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -RomLoadProgressDlg DIALOG 0, 0, 186, 19 +TestScriptDlg DIALOG 0, 0, 453, 260 STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU -CAPTION "ROM Load Progress" +EXSTYLE WS_EX_WINDOWEDGE +CAPTION "Test Scripts" FONT 8, "Ms Shell Dlg" { - CONTROL "", IDC_ROMLOAD_PROGRESS, PROGRESS_CLASS, PBS_SMOOTH, 2, 4, 182, 11 + DEFPUSHBUTTON "Done", IDC_TESTSCRIPTS_DONE, 399, 242, 50, 14, 0, WS_EX_LEFT + LTEXT "Test Scripts:", IDC_STATIC, 4, 4, 40, 8, SS_LEFT, WS_EX_LEFT + DEFPUSHBUTTON "Run", IDC_TESTSCRIPTS_RUN, 347, 242, 50, 14, 0, WS_EX_LEFT + CONTROL "", IDC_TESTSCRIPTS_PROGRESS, PROGRESS_CLASS, PBS_SMOOTH, 74, 79, 225, 11, WS_EX_LEFT + LTEXT "Progress:", IDC_TESTSCRIPTS_PROGRESSTXT, 4, 81, 65, 8, SS_LEFT, WS_EX_LEFT + LISTBOX IDC_TESTSCRIPTS_LIST, 4, 15, 447, 60, WS_TABSTOP | WS_VSCROLL | LBS_NOINTEGRALHEIGHT | LBS_HASSTRINGS | LBS_EXTENDEDSEL | LBS_SORT | LBS_NOTIFY, WS_EX_LEFT + EDITTEXT IDC_TESTSCRIPTS_OUTPUT, 4, 107, 447, 131, WS_VSCROLL | NOT WS_TABSTOP | ES_AUTOHSCROLL | ES_MULTILINE | ES_READONLY, WS_EX_LEFT + LTEXT "Test Output:", IDC_STATIC, 4, 96, 40, 8, SS_LEFT, WS_EX_LEFT + LTEXT "Results: 0 Pass / 0 Fail / 0 Error", IDC_TESTSCRIPTS_RESULTSTXT, 310, 81, 135, 8, SS_LEFT, WS_EX_LEFT + DEFPUSHBUTTON "Clear", IDC_TESTSCRIPTS_CLEAR, 4, 242, 50, 14, 0, WS_EX_LEFT } diff --git a/sw/rsrc/resource.h b/sw/rsrc/resource.h index f8c9f9e..ce434bd 100644 --- a/sw/rsrc/resource.h +++ b/sw/rsrc/resource.h @@ -7,6 +7,8 @@ #define IDM_TOOLS_RAWDEBUG 40001 #define IDM_TOOLS_TESTSCRIPTS 40002 #define IDM_FILE_LOADROM 40003 +#define IDM_JOYPAD1 40004 +#define IDM_STOPJOYPAD_1 40005 #define IDC_TESTSCRIPTS_PROGRESS 40011 #define IDC_TESTSCRIPTS_RUN 40013 #define IDC_TESTSCRIPTS_DONE 40014 diff --git a/sw/src/dbgpacket.cpp b/sw/src/dbgpacket.cpp index b4fbe10..6e2469a 100644 --- a/sw/src/dbgpacket.cpp +++ b/sw/src/dbgpacket.cpp @@ -477,3 +477,25 @@ UINT CartSetCfgPacket::SizeInBytes() const { return sizeof(BYTE) + (5 * sizeof(BYTE)); } + +/*************************************************************************************************** +** % Method: JoypadCfgPacket::JoypadCfgPacket() +* % Description: JoypadCfgPacket constructor. +***************************************************************************************************/ +JoypadCfgPacket::JoypadCfgPacket( + const BYTE pJOYPADCONTROL) // iNES header pointer (should point at byte 0) +{ + m_pData = new BYTE [1 + 1]; + + m_pData[0] = DbgPacketOpCodeJoypadSetCfg; + m_pData[1] = pJOYPADCONTROL; +} + +/*************************************************************************************************** +** % Method: CartSetCfgPacket::SizeInBytes() +* % Description: Returns total packet size, in bytes. +***************************************************************************************************/ +UINT JoypadCfgPacket::SizeInBytes() const +{ + return sizeof(BYTE) + (1 * sizeof(BYTE)); +} diff --git a/sw/src/dbgpacket.h b/sw/src/dbgpacket.h index a04c667..6ec78bb 100644 --- a/sw/src/dbgpacket.h +++ b/sw/src/dbgpacket.h @@ -45,6 +45,7 @@ enum DbgPacketOpCode DbgPacketOpCodePpuMemWr = 0x0A, // write PPU memory DbgPacketOpCodePpuDisable = 0x0B, // disable PPU DbgPacketOpCodeCartSetCfg = 0x0C, // set cartridge config from iNES header + DbgPacketOpCodeJoypadSetCfg = 0x0D // joypad control config }; enum CpuReg @@ -308,4 +309,23 @@ class CartSetCfgPacket : public DbgPacket CartSetCfgPacket(const CartSetCfgPacket&); }; +/*************************************************************************************************** +** % Class: JoypadCfgPacket +* % Description: Send Joypad control info to fpga. +***************************************************************************************************/ +class JoypadCfgPacket : public DbgPacket +{ +public: + JoypadCfgPacket(const BYTE pJOYPADCONTROL); + virtual ~JoypadCfgPacket() {}; + + virtual UINT SizeInBytes() const; + virtual UINT ReturnBytesExpected() const { return 0; } + +private: + JoypadCfgPacket(); + JoypadCfgPacket& operator=(const JoypadCfgPacket&); + JoypadCfgPacket(const JoypadCfgPacket&); +}; + #endif // DBGPACKET_H diff --git a/sw/src/main.cpp b/sw/src/main.cpp index 7fec348..cc88a2d 100644 --- a/sw/src/main.cpp +++ b/sw/src/main.cpp @@ -59,6 +59,12 @@ static LRESULT CALLBACK WndProc( case IDM_TOOLS_TESTSCRIPTS: g_pNesDbg->LaunchTestScriptDlg(); break; + case IDM_JOYPAD1: + g_pNesDbg->TestJoypad(); + break; + case IDM_STOPJOYPAD_1: + g_pNesDbg->StopJoypad(); + break; } break; case WM_DESTROY: @@ -82,13 +88,14 @@ INT WINAPI WinMain( LPSTR pCmdLine, // command line string, excluding program name INT cmdShow) // controls how window should be shown { + WNDCLASSEX wcex = {0}; HWND hWnd = NULL; INT ret = 0; BOOL success = TRUE; static TCHAR* pWndClassName = _T("nesdbg"); - static TCHAR* pWndTitle = _T("FPGA NES Debugger"); + static TCHAR* pWndTitle = _T("FPGA NES µ÷ÊÔÆ÷"); wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; diff --git a/sw/src/nesdbg.cpp b/sw/src/nesdbg.cpp index 9e5f976..49d256d 100644 --- a/sw/src/nesdbg.cpp +++ b/sw/src/nesdbg.cpp @@ -31,6 +31,61 @@ #include "scriptmgr.h" #include "serialcomm.h" +HANDLE th = NULL; + +class ThreadX +{ +public: + bool loopJudge; + + ThreadX() + { + loopJudge = true; + } + + static unsigned __stdcall ThreadStaticEntryPoint(void * pThis) + { + ThreadX * pthX = (ThreadX*)pThis; // the tricky cast + pthX->ThreadEntryPoint(); // now call the true entry-point-function + return 1; // the thread exit code + } + + void ThreadEntryPoint() + { + int last_keys = -1; + while(loopJudge) + { + JOYINFOEX joy; + joy.dwSize = sizeof(joy); + joy.dwFlags = JOY_RETURNALL; + if (joyGetPosEx(JOYSTICKID1, &joy) != MMSYSERR_NOERROR) { + MessageBox(NULL, _T("JoyPad Error."), _T("NesDbg"), MB_OK); + break; + } + unsigned char keys = 0; + keys |= !!(joy.dwButtons & 4) * 1; + keys |= !!(joy.dwButtons & 8) * 2; + keys |= !!(joy.dwButtons & 0x40) * 4; + keys |= !!(joy.dwButtons & 0x80) * 8; + keys |= (joy.dwYpos < 0x4000) * 16; + keys |= (joy.dwYpos >= 0xC000) * 32; + keys |= (joy.dwXpos < 0x4000) * 64; + keys |= (joy.dwXpos >= 0xC000) * 128; + + keys = ~keys; + //if (keys != last_keys) { + JoypadCfgPacket joypadCfgPacket(keys); + g_pNesDbg->GetSerialComm()->SendData(joypadCfgPacket.PacketData(), + joypadCfgPacket.SizeInBytes()); + last_keys = keys; + //} + } + } +}; + +ThreadX* o1; + + /*************************************************************************************************** ** % Method: NesDbg::NesDbg() * % Description: NesDbg constructor. @@ -348,13 +403,35 @@ VOID NesDbg::LoadRom() } } +VOID NesDbg::TestJoypad() +{ + o1 = new ThreadX(); + unsigned uiThreadID; + + th = (HANDLE)_beginthreadex( NULL, // security + 0, // stack size + ThreadX::ThreadStaticEntryPoint, + o1, // arg list + CREATE_SUSPENDED, // so we can later call ResumeThread() + &uiThreadID ); + ResumeThread(th); +} + +VOID NesDbg::StopJoypad() +{ + if(th != NULL) + { + o1->loopJudge = false; + } +} + /*************************************************************************************************** ** % Method: NesDbg::GetMessageBoxTitle() * % Description: Returns a string to be used as the title of all message boxes for the app. ***************************************************************************************************/ const TCHAR* NesDbg::GetMessageBoxTitle() { - static const TCHAR* pMsgBoxTitle = _T("NesDbg"); + static const TCHAR* pMsgBoxTitle = _T("FPGA NES µ÷ÊÔÆ÷"); return pMsgBoxTitle; } @@ -504,4 +581,4 @@ BOOL CALLBACK NesDbg::RomLoadProgressDlgProc( } return ret; -} +} \ No newline at end of file diff --git a/sw/src/nesdbg.h b/sw/src/nesdbg.h index c7171a9..496e6e9 100644 --- a/sw/src/nesdbg.h +++ b/sw/src/nesdbg.h @@ -31,8 +31,10 @@ #include #include #include +#include #include "util.h" +#include "debug.h" class ScriptMgr; class SerialComm; @@ -52,6 +54,8 @@ class NesDbg VOID LaunchRawDbgDlg(); VOID LaunchTestScriptDlg(); VOID LoadRom(); + VOID TestJoypad(); + VOID StopJoypad(); ScriptMgr* GetScriptMgr() { return m_pScriptMgr; } SerialComm* GetSerialComm() { return m_pSerialComm; } @@ -80,5 +84,7 @@ class NesDbg extern NesDbg* g_pNesDbg; + + #endif // NESDBG_H diff --git a/sw/src/serialcomm.cpp b/sw/src/serialcomm.cpp index c8b312e..c3c3431 100644 --- a/sw/src/serialcomm.cpp +++ b/sw/src/serialcomm.cpp @@ -63,30 +63,42 @@ BOOL SerialComm::Init() { BOOL ret = TRUE; + LPWSTR *szArgList; + int argCount; + + szArgList = CommandLineToArgvW(GetCommandLine(), &argCount); + + WCHAR* comPath = (WCHAR*)malloc((wcslen(L"\\\\.\\COM")+10)*sizeof(WCHAR)); + wcscpy(comPath, L"\\\\.\\COM"); + wcscat(comPath, szArgList[1]); + if (ret) { - m_hSerialComm = CreateFile(_T("COM5"), + m_hSerialComm = CreateFile(comPath, GENERIC_READ | GENERIC_WRITE, 0, - 0, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, - 0); + NULL); if (m_hSerialComm == INVALID_HANDLE_VALUE) { ret = FALSE; if (GetLastError() == ERROR_FILE_NOT_FOUND) { - MessageBox(NULL, _T("\"COM5\" file not found."), _T("NesDbg"), MB_OK); + MessageBox(NULL, _T("\"COM23\" file not found."), _T("NesDbg"), MB_OK); } else { - MessageBox(NULL, _T("Unknown error initializing COM5"), _T("NesDbg"), MB_OK); + MessageBox(NULL, _T("Unknown error initializing COM23"), _T("NesDbg"), MB_OK); } } } + LocalFree(szArgList); + free(comPath); + DCB serialConfig = {0}; if (ret) { @@ -95,13 +107,13 @@ BOOL SerialComm::Init() if (!GetCommState(m_hSerialComm, &serialConfig)) { ret = FALSE; - MessageBox(NULL, _T("Error getting comm state for COM5."), _T("NesDbg"), MB_OK); + MessageBox(NULL, _T("Error getting comm state for COM23."), _T("NesDbg"), MB_OK); } } if (ret) { - serialConfig.BaudRate = CBR_38400; + serialConfig.BaudRate = CBR_256000 ; serialConfig.ByteSize = 8; serialConfig.StopBits = ONESTOPBIT; serialConfig.Parity = ODDPARITY; @@ -172,6 +184,7 @@ BOOL SerialComm::SendData( UINT numBytes) // number of bytes to transmit { BOOL ret = TRUE; + DWORD bytesWritten = 0; ret = WriteFile(m_hSerialComm, pData, numBytes, &bytesWritten, NULL); @@ -181,7 +194,7 @@ BOOL SerialComm::SendData( { ret = FALSE; } - + return ret; } @@ -196,6 +209,7 @@ BOOL SerialComm::ReceiveData( UINT numBytes) // number of bytes to receive { BOOL ret = TRUE; + DWORD bytesRead = 0; ret = ReadFile(m_hSerialComm, pData, numBytes, &bytesRead, NULL); @@ -205,6 +219,6 @@ BOOL SerialComm::ReceiveData( { ret = FALSE; } - + return ret; }