From a331248b21f82ea2f0afdb7867e778bfcbf53bd8 Mon Sep 17 00:00:00 2001 From: Jim Gregory <47483038+JimmyStones@users.noreply.github.com> Date: Mon, 28 Jun 2021 22:42:42 +0100 Subject: [PATCH] Add ps2 keyboard support --- .gitignore | 1 + InputTest.sv | 25 ++-- README.MD | 5 +- rtl/spram.v | 20 ++-- rtl/system.v | 44 ++++--- src/os.c | 139 ++++++++++++++------- src/ps2.c | 233 ++++++++++++++++++++++++++++++++++++ src/sys.c | 7 +- src/ui.c | 35 ++++++ verilator/imgui.ini | 6 +- verilator/sim.v | 22 ++-- verilator/sim/sim_bus.cpp | 10 +- verilator/sim/sim_bus.h | 1 + verilator/sim/sim_input.cpp | 31 ++--- verilator/sim/sim_video.cpp | 2 +- verilator/sim/sim_video.h | 2 + verilator/sim_main.cpp | 51 +++++++- 17 files changed, 512 insertions(+), 122 deletions(-) create mode 100644 src/ps2.c diff --git a/.gitignore b/.gitignore index 664f1a3..c143053 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,4 @@ src/os.lst src/os.map src/os.noi src/os.sym +.vscode/settings.json diff --git a/InputTest.sv b/InputTest.sv index c50eed4..4ca70c5 100644 --- a/InputTest.sv +++ b/InputTest.sv @@ -192,13 +192,12 @@ localparam CONF_STR = { "-;", "O89,Aspect ratio,Original,Full Screen,[ARC1],[ARC2];", "-;", + "F0,BIN,Load BIOS", + "-;", "J1,A,B,C,X,Y,Z,L,R,Select,Start;", "V,v",`BUILD_DATE }; -// -// HPS is the module that communicates between the linux and fpga -// wire [31:0] status; wire [1:0] buttons; wire forced_scandoubler; @@ -237,6 +236,9 @@ wire [8:0] spinner_2; wire [8:0] spinner_3; wire [8:0] spinner_4; wire [8:0] spinner_5; +wire [10:0] ps2_key; +wire [24:0] ps2_mouse; +wire [15:0] ps2_mouse_ext; wire [21:0] gamma_bus; @@ -287,7 +289,11 @@ hps_io #(.CONF_STR(CONF_STR)) hps_io .spinner_2(spinner_2), .spinner_3(spinner_3), .spinner_4(spinner_4), - .spinner_5(spinner_5) + .spinner_5(spinner_5), + + .ps2_key(ps2_key), + .ps2_mouse(ps2_mouse), + .ps2_mouse_ext(ps2_mouse_ext) ); @@ -311,10 +317,7 @@ jtframe_cen24 divider /////////////////// VIDEO //////////////////// wire hblank, vblank; wire hs, vs; - -wire [7:0] r; -wire [7:0] g; -wire [7:0] b; +wire [7:0] r, g, b; wire [23:0] rgb = {r,g,b}; arcade_video #(320,24) arcade_video ( @@ -337,7 +340,7 @@ assign LED_USER = rom_download; system system( .clk_sys(clk_sys), .ce_pix(ce_pix), - .reset(reset | ioctl_download), + .reset(reset), .VGA_HS(hs), .VGA_VS(vs), .VGA_R(r), @@ -352,7 +355,9 @@ system system( .joystick({joystick_5,joystick_4,joystick_3,joystick_2,joystick_1,joystick_0}), .analog({joystick_analog_5,joystick_analog_4,joystick_analog_3,joystick_analog_2,joystick_analog_1,joystick_analog_0}), .paddle({paddle_5,paddle_4,paddle_3,paddle_2,paddle_1,paddle_0}), - .spinner({7'b0,spinner_5,7'b0,spinner_4,7'b0,spinner_3,7'b0,spinner_2,7'b0,spinner_1,7'b0,spinner_0}) + .spinner({7'b0,spinner_5,7'b0,spinner_4,7'b0,spinner_3,7'b0,spinner_2,7'b0,spinner_1,7'b0,spinner_0}), + .ps2_key(ps2_key), + .ps2_mouse({ps2_mouse_ext,7'b0,ps2_mouse}) ); endmodule diff --git a/README.MD b/README.MD index ee1f25a..0dd2354 100644 --- a/README.MD +++ b/README.MD @@ -33,6 +33,9 @@ Start|End|Length|Name 0x7100|0x715F|0x0060|Analog inputs 0x7200|0x722F|0x0030|Paddle inputs 0x7300|0x735F|0x0060|Spinner inputs +0x7400|0x740B|0x000C|PS2 key +0x7500|0x7530|0x0031|PS2 mouse + 0x8000|0x87FF|0x0800|Char RAM 0x8800|0x8FFF|0x0800|Colour RAM 0xC000|0xFFFF|0x4000|Work RAM @@ -49,7 +52,7 @@ File|Description /src/os.c|Main program ### ROMS -All required ROMs (compiled program and default MiSTer font) are hard-coded into this core +All required ROMs (compiled program and default MiSTer font) are built into this core. ## License This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. \ No newline at end of file diff --git a/rtl/spram.v b/rtl/spram.v index ddfd523..f7cf437 100644 --- a/rtl/spram.v +++ b/rtl/spram.v @@ -12,16 +12,16 @@ module spram #( localparam ramLength = (2**address_width); reg [data_width-1:0] mem [ramLength-1:0]; -`ifdef SIMULATION - integer j; - initial - begin - for (j = 0; j < ramLength; j = j + 1) - begin - mem[j] = 0; - end - end -`endif +// `ifdef SIMULATION +// integer j; +// initial +// begin +// for (j = 0; j < ramLength; j = j + 1) +// begin +// mem[j] = 0; +// end +// end +// `endif always @(posedge clock) begin q <= mem[address]; diff --git a/rtl/system.v b/rtl/system.v index efcc7d2..c8f7caf 100644 --- a/rtl/system.v +++ b/rtl/system.v @@ -20,6 +20,14 @@ module system ( // 6 devices, 16 bits eachspinner [7:0] -128..+127, [8] - toggle with every update, [9-15] padding input [95:0] spinner, + // ps2 alternative interface. + // [8] - extended, [9] - pressed, [10] - toggles with every press/release + input [10:0] ps2_key, + + // [0-23] mouse data, [24] - toggles with every event, [25-31] - padding, + // [32-39] - wheel movements, [40-47] - reserved(additional buttons) + input [47:0] ps2_mouse, + output VGA_HS, output VGA_VS, output [7:0] VGA_R, @@ -31,7 +39,6 @@ module system ( localparam [8:0] VGA_WIDTH = 9'd320; localparam [8:0] VGA_HEIGHT = 9'd240; -localparam [7:0] COLS = 8'd40; wire _hb; wire _vb; @@ -40,8 +47,6 @@ assign VGA_VB = ~_vb; wire [8:0] hcnt; wire [8:0] vcnt; -wire hinit; -wire vinit; // Display timing module from JTFRAME jtframe_vtimer #( @@ -53,8 +58,8 @@ jtframe_vtimer #( .pxl_cen(ce_pix), .V(vcnt), .H(hcnt), - .Hinit(hinit), - .Vinit(vinit), + .Hinit(), + .Vinit(), .LHBL(_hb), .LVBL(_vb), .HS(VGA_HS), @@ -121,10 +126,12 @@ wire [7:0] joystick_data_out = joystick[cpu_addr[7:0] +: 8]; wire [7:0] analog_data_out = analog[cpu_addr[6:0] +: 8]; wire [7:0] paddle_data_out = paddle[cpu_addr[5:0] +: 8]; wire [7:0] spinner_data_out = spinner[cpu_addr[6:0] +: 8]; +wire [7:0] ps2_key_data_out = ps2_key[cpu_addr[3:0] +: 8]; +wire [7:0] ps2_mouse_data_out = ps2_mouse[cpu_addr[5:0] +: 8]; // CPU address decodes wire pgrom_cs = cpu_addr[15:14] == 2'b00; -//wire chrom_cs = cpu_addr[15:12] == 4'b0100; // CPU never access the character ROM data directly +//wire chrom_cs = cpu_addr[15:12] == 4'b0100; // CPU never accesses the character ROM data directly wire chram_cs = cpu_addr[15:11] == 5'b10000; wire colram_cs = cpu_addr[15:11] == 5'b10001; wire wkram_cs = cpu_addr[15:14] == 2'b11; @@ -133,18 +140,21 @@ wire joystick_cs = cpu_addr[15:8] == 8'b01110000; wire analog_cs = cpu_addr[15:8] == 8'b01110001; wire paddle_cs = cpu_addr[15:8] == 8'b01110010; wire spinner_cs = cpu_addr[15:8] == 8'b01110011; +wire ps2_key_cs = cpu_addr[15:8] == 8'b01110100; +wire ps2_mouse_cs = cpu_addr[15:8] == 8'b01110101; // always @(posedge clk_sys) begin -// // if(pgrom_cs) $display("%x pgrom o %x", cpu_addr, pgrom_data_out); -// // if(wkram_cs) $display("%x wkram i %x o %x w %b", cpu_addr, cpu_dout, wkram_data_out, wkram_wr); -// // if(chram_cs) $display("%x chram i %x o %x w %b", cpu_addr, cpu_dout, chram_data_out, chram_wr); -// // if(colram_cs) $display("%x colram i %x o %x w %b", cpu_addr, cpu_dout, colram_data_out, colram_wr); -// // if(in0_cs) $display("%x in0 i %x o %x", cpu_addr, cpu_dout, in0_data_out); -// //if(joystick_cs) $display("joystick %b %b", joystick_bit, joystick_data_out); -// //if(analog_cs) $display("analog %b %b", analog_bit, analog_data_out); -// //if(paddle_cs) $display("paddle %b", paddle_data_out); -// // $display("%x", cpu_addr); -// end +// if(pgrom_cs) $display("%x pgrom o %x", cpu_addr, pgrom_data_out); +// if(wkram_cs) $display("%x wkram i %x o %x w %b", cpu_addr, cpu_dout, wkram_data_out, wkram_wr); +// if(chram_cs) $display("%x chram i %x o %x w %b", cpu_addr, cpu_dout, chram_data_out, chram_wr); +// if(colram_cs) $display("%x colram i %x o %x w %b", cpu_addr, cpu_dout, colram_data_out, colram_wr); +// if(in0_cs) $display("%x in0 i %x o %x", cpu_addr, cpu_dout, in0_data_out); +// if(joystick_cs) $display("joystick %b %b", joystick_bit, joystick_data_out); +// if(analog_cs) $display("analog %b %b", analog_bit, analog_data_out); +// if(paddle_cs) $display("paddle %b", paddle_data_out); +// if(ps2_key_cs) $display("ps2_key %b %x", ps2_key_data_out, cpu_addr[3:0]); +// $display("%x", cpu_addr); +// end // CPU data mux assign cpu_din = pgrom_cs ? pgrom_data_out : @@ -156,6 +166,8 @@ assign cpu_din = pgrom_cs ? pgrom_data_out : analog_cs ? analog_data_out : paddle_cs ? paddle_data_out : spinner_cs ? spinner_data_out : + ps2_key_cs ? ps2_key_data_out : + ps2_mouse_cs ? ps2_mouse_data_out : 8'b00000000; // Rom upload write enables diff --git a/src/os.c b/src/os.c index cab4da9..ac27386 100644 --- a/src/os.c +++ b/src/os.c @@ -3,6 +3,7 @@ #include #include "sys.c" #include "ui.c" +#include "ps2.c" unsigned char hsync; unsigned char hsync_last; @@ -27,12 +28,14 @@ void page_inputs() write_string(label, 0xFF - (j * 2), 2, 11 + j); sprintf(label, "SPN%d", j + 1); - write_string(label, 0xFF - (j * 2), 2, 18 + j); + write_string(label, 0xFF - (j * 2), 14, 11 + j); } + + // write_string("EXT PRS SHF SCN ASC CHR", 0xFF, 6, 18); + write_string("CON", 0xFF, 2, 18); + } -char asc_0 = 48; -char asc_1 = 49; char color = 0xAB; char state = 0; @@ -70,7 +73,8 @@ char fade = 0; char fadetimer = 0; char fadefreq = 4; -void start_inputtester(){ +void start_inputtester() +{ page_inputs(); state = 1; } @@ -158,7 +162,6 @@ void fadein() } } -char bpressed_left = 0; char bdown_left = 0; char bdown_left_last = 0; char bdown_right = 0; @@ -179,11 +182,23 @@ void pushhistory(char new) history[3] = new; } +char lastbufferlen = 0; +char inputindex = 0; +char fps; +char con_x; // Console cursor X position +char con_y; // Console cursor X position +char con_l = 2; // Console left edge X +char con_t = 21; // Console top edge Y +char con_r = 37; // Console right edge X +char con_b = 37; // Console bottom edge Y + void inputtester() { hsync = input0 & 0x80; vsync = input0 & 0x40; + handle_ps2(); + if (hsync && !hsync_last) { @@ -215,16 +230,20 @@ void inputtester() } } - char j = 0; - if (vsync && !vsync_last) { + inputindex++; + if (inputindex == 6) + { + inputindex = 0; + } color++; - write_string("--- MiSTer Input Tester ---", color, 6, 1); - - char hstr[10]; - sprintf(hstr, "%d %d %d %d", history[0], history[1], history[2], history[3]); + fps++; + write_string("- MiSTer Input Tester -", color, 8, 1); + write_stringf("%d", 0xbb, 0, 1, fps); + // char hstr[10]; + // sprintf(hstr, "%d %d %d %d", history[0], history[1], history[2], history[3]); if (history[0] == 4 && history[1] == 2 && history[2] == 3 && history[3] == 1) { nextstate = 6; @@ -232,20 +251,22 @@ void inputtester() start_fadeout(); return; } + // write_string(hstr, 0xFF, 6, 2); - write_string(hstr, 0xFF, 6, 2); - - int y = 4; + char x = 7; + char y = 4 + inputindex; + char inputoffset = (inputindex * 32); for (char b = 0; b < 2; b++) { char m = 0b00000001; for (char i = 0; i < 8; i++) { - char x = 7 + i + (b * 8); - for (j = 0; j < 6; j++) - { - write_char((joystick[(b * 8) + (j * 32)] & m) ? asc_1 : asc_0, 0xFF, x, 4 + j); - } + //(b * 8); + x++; + // for (inputindex = 0; inputindex < 6; inputindex++) + // { + write_char((joystick[(b * 8) + inputoffset] & m) ? asc_1 : asc_0, 0xFF, x, y); + // } m <<= 1; } } @@ -254,39 +275,72 @@ void inputtester() // ANALOG char m = 0b00000001; char stra[10]; - for (j = 0; j < 6; j++) - { - signed char jx = analog[(j * 16)]; - signed char jy = analog[(j * 16) + 8]; + // for (inputindex = 0; inputindex < 6; inputindex++) + // { + signed char jx = analog[(inputindex * 16)]; + signed char jy = analog[(inputindex * 16) + 8]; - sprintf(stra, "%4d %4d", jx, jy); - write_string(stra, 0xFF, 24, y + j); - m <<= 1; - } + sprintf(stra, "%4d %4d", jx, jy); + write_string(stra, 0xFF, 24, y + inputindex); + m <<= 1; + // } // PADDLE y = 11; m = 0b00000001; char strp[3]; - for (j = 0; j < 6; j++) - { - char px = paddle[(j * 8)]; - sprintf(strp, "%4d", px); - write_string(strp, 0xFF, 6, y + j); - m <<= 1; - } + // for (inputindex = 0; inputindex < 6; inputindex++) + // { + char px = paddle[(inputindex * 8)]; + sprintf(strp, "%4d", px); + write_string(strp, 0xFF, 6, y + inputindex); + m <<= 1; + // } // SPINNER - y = 18; + y = 11; m = 0b00000001; - char strs[3]; - for (j = 0; j < 6; j++) + // for (j = 0; j < 6; j++) + // { + signed char sx = spinner[(inputindex * 16)]; + write_stringf("%4d", 0xFF, 17, y + inputindex, sx); + m <<= 1; + // } + + // KEYBOARD + // write_stringf("%3d", 0xFF, 6, 19, kbd_extend); + // write_stringf("%3d", 0xFF, 10, 19, kbd_pressed); + // write_stringf("%3d", 0xFF, 14, 19, kbd_shift); + // write_stringf("%3d", 0xFF, 18, 19, kbd_lastscan); + // write_stringf("%3d", 0xFF, 22, 19, kbd_lastascii); + // write_char(kbd_lastascii, 0xFF, 26, 19); + + if (kbd_buffer_len > 0) { - signed char sx = spinner[(j * 16)]; - sprintf(strs, "%4d", sx); - write_string(strs, 0xFF, 7, y + j); - m <<= 1; + for (char k = 0; k < kbd_buffer_len; k++) + { + write_char(kbd_buffer[k], 0xFF, con_x, con_y); + con_x++; + if (con_x > con_r) + { + con_x = con_l; + con_y++; + if (con_y > con_b) + { + con_y = con_t; + } + } + } + kbd_buffer_len = 0; } + + // MOUSE + // write_stringf("%3d", 0xFF, 6, 23, mse_a1); + // write_stringf("%3d", 0xFF, 10, 23, mse_a2); + // write_stringf("%3d", 0xFF, 14, 23, mse_a3); + + // write_bits(ps2_mouse, 8, 0, 3, 0xFF, 6, 25); + // write_bits(ps2_mouse, 8, 3, 3, 0xFF, 6, 27); } hsync_last = hsync; @@ -392,7 +446,8 @@ void attract() void main() { chram_size = chram_cols * chram_rows; - + con_x = con_l; + con_y = con_t; while (1) { diff --git a/src/ps2.c b/src/ps2.c new file mode 100644 index 0000000..52a1ed2 --- /dev/null +++ b/src/ps2.c @@ -0,0 +1,233 @@ +#include "sys.c" + +// COMMAND KEYS +const char KEY_TAB = 0x0d; +const char KEY_CAPSLOCK = 0x58; +const char KEY_ENTER = 0x5a; +const char KEY_BACKSPACE = 0x66; +const char KEY_ESC = 0x76; +const char KEY_LEFTSHIFT = 0x12; +const char KEY_RIGHTSHIFT = 0x59; +const char KEY_ALT = 0x11; // EXT 0 = LEFT, EXT 1 = RIGHT +const char KEY_CTRL = 0x63; // EXT 0 = LEFT, EXT 1 = RIGHT + +// UNMAPPED COMMAND KEYS +// 0x7c, //55 KEY_KPASTERISK +// 0x05, //59 KEY_F1 +// 0x06, //60 KEY_F2 +// 0x04, //61 KEY_F3 +// 0x0c, //62 KEY_F4 +// 0x03, //63 KEY_F5 +// 0x0b, //64 KEY_F6 +// 0x83, //65 KEY_F7 +// 0x0a, //66 KEY_F8 +// 0x01, //67 KEY_F9 +// 0x09, //68 KEY_F10 +// 0x6c, //71 KEY_KP7 +// 0x75, //72 KEY_KP8 +// 0x7d, //73 KEY_KP9 +// 0x7b, //74 KEY_KPMINUS +// 0x6b, //75 KEY_KP4 +// 0x73, //76 KEY_KP5 +// 0x74, //77 KEY_KP6 +// 0x79, //78 KEY_KPPLUS +// 0x69, //79 KEY_KP1 +// 0x72, //80 KEY_KP2 +// 0x7a, //81 KEY_KP3 +// 0x70, //82 KEY_KP0 +// 0x71, //83 KEY_KPDOT +// 0x61, //86 KEY_102ND +// 0x78, //87 KEY_F11 +// 0x07, //88 KEY_F12 + +// EXTENSION KEYS +const char KEY_UP = 0x75; +const char KEY_LEFT = 0x6b; +const char KEY_RIGHT = 0x74; +const char KEY_DOWN = 0x72; + +// UNMAPPED EXTENSION KEYS +// EXT | 0x5a, //96 KEY_KPENTER +// EXT | 0x4a, //98 KEY_KPSLASH +// EXT | 0x6c, //102 KEY_HOME +// EXT | 0x7d, //104 KEY_PAGEUP +// EXT | 0x69, //107 KEY_END +// EXT | 0x7a, //109 KEY_PAGEDOWN +// EXT | 0x70, //110 KEY_INSERT +// EXT | 0x71, //111 KEY_DELETE + +char kbd_UK[256] = + { + 0, 0, // 0x00 + 0, 0, // 0x01 + 0, 0, // 0x02 + 0, 0, // 0x03 + 0, 0, // 0x04 + 0, 0, // 0x05 + 0, 0, // 0x06 + 0, 0, // 0x07 + 0, 0, // 0x08 + 0, 0, // 0x09 + 0, 0, // 0x0a + 0, 0, // 0x0b + 0, 0, // 0x0c + 0, 0, // 0x0d + '¬', '`', // 0x0e + 0, 0, // 0x0f + 0, 0, // 0x10 + 0, 0, // 0x11 + 0, 0, // 0x12 + 0, 0, // 0x13 + 0, 0, // 0x14 + 'Q', 'q', // 0x15 + '!', '1', // 0x16 + 0, 0, // 0x17 + 0, 0, // 0x18 + 0, 0, // 0x19 + 'Z', 'z', // 0x1a + 'S', 's', // 0x1b + 'A', 'a', // 0x1c + 'W', 'w', // 0x1d + '"', '2', // 0x1e + 0, 0, // 0x1f + 0, 0, // 0x20 + 'C', 'c', // 0x21 + 'X', 'x', // 0x22 + 'D', 'd', // 0x23 + 'E', 'e', // 0x24 + '$', '4', // 0x25 + '£', '3', // 0x26 + 0, 0, // 0x27 + 0, 0, // 0x28 + ' ', ' ', // 0x29 + 'V', 'v', // 0x2a + 'F', 'f', // 0x2b + 'T', 't', // 0x2c + 'R', 'r', // 0x2d + '%', '5', // 0x2e + 0, 0, // 0x2f + 0, 0, // 0x30 + 'N', 'n', // 0x31 + 'B', 'b', // 0x32 + 'H', 'h', // 0x33 + 'G', 'g', // 0x34 + 'Y', 'y', // 0x35 + '^', '6', // 0x36 + 0, 0, // 0x37 + 0, 0, // 0x38 + 0, 0, // 0x39 + 'M', 'm', // 0x3a + 'J', 'j', // 0x3b + 'U', 'u', // 0x3c + '&', '7', // 0x3d + '*', '8', // 0x3e + 0, 0, // 0x3f + 0, 0, // 0x40 + '<', ',', // 0x41 + 'K', 'k', // 0x42 + 'I', 'i', // 0x43 + 'O', 'o', // 0x44 + ')', '0', // 0x45 + '(', '9', // 0x46 + 0, 0, // 0x47 + 0, 0, // 0x48 + '>', '.', // 0x49 + '?', '/', // 0x4a + 'L', 'l', // 0x4b + ':', ';', // 0x4c + 'P', 'p', // 0x4d + '_', '-', // 0x4e + 0, 0, // 0x4f + 0, 0, // 0x50 + 0, 0, // 0x51 + '@', '\'', // 0x52 + 0, 0, // 0x53 + '{', '[', // 0x54 + '+', '=', // 0x55 + 0, 0, // 0x56 + 0, 0, // 0x57 + '+', '=', // 0x58 + 0, 0, // 0x59 (RSHIFT) + 0, 0, // 0x5a (ENTER) + '}', ']', // 0x5b + 0, 0, // 0x5c + '|', '\\', // 0x5d + 0, 0, // 0x5e + 0, 0, // 0x5f + 0, 0}; + +char kbd_in[2]; +char kbd_lastclock = 0; +char kbd_shift = 0; +char kbd_pressed; +char kbd_extend; +char kbd_lastscan = 0; +char kbd_lastascii = 0; + +// char mse_in[6]; +// char mse_lastclock = 0; +// char mse_a1; +// char mse_a2; +// char mse_a3; + +char kbd_buffer[128]; +char kbd_buffer_len = 0; + +void get_ascii(char scan) +{ + kbd_lastscan = scan; + char p = (kbd_lastscan * 2); + if (!kbd_shift) + { + p++; + } + kbd_lastascii = kbd_UK[p]; + if (kbd_lastascii > 0) + { + kbd_buffer[kbd_buffer_len] = kbd_lastascii; + kbd_buffer_len++; + } +} + +char kbd_clock_index = 10; + +void handle_ps2() +{ + bool kbd_clock = CHECK_BIT(ps2_key[kbd_clock_index], 0); + if (kbd_clock != kbd_lastclock) + { + for (char k = 0; k < 2; k++) + { + kbd_in[k] = ps2_key[k * 8]; + } + kbd_extend = CHECK_BIT(kbd_in[1], 0); + kbd_pressed = CHECK_BIT(kbd_in[1], 1); + char kbd_scan = kbd_in[0]; + if (kbd_pressed) + { + if (kbd_scan == KEY_LEFTSHIFT || kbd_scan == KEY_RIGHTSHIFT) + { + kbd_shift++; + } + } + else + { + if (kbd_scan == KEY_LEFTSHIFT || kbd_scan == KEY_RIGHTSHIFT) + { + kbd_shift--; + } + else + { + get_ascii(kbd_scan); + } + } + } + kbd_lastclock = kbd_clock; + + // bool mse_clock = CHECK_BIT(ps2_mouse[3], 0); + // if (mse_clock != mse_lastclock) + // { + // mse_a1++; + // } + // mse_lastclock = mse_clock; +} diff --git a/src/sys.c b/src/sys.c index 06c55e0..8929e01 100644 --- a/src/sys.c +++ b/src/sys.c @@ -10,10 +10,15 @@ unsigned char __at(0x7000) joystick[24]; unsigned char __at(0x7100) analog[12]; unsigned char __at(0x7200) paddle[6]; unsigned char __at(0x7300) spinner[12]; +unsigned char __at(0x7400) ps2_key[2]; +unsigned char __at(0x7500) ps2_mouse[6]; unsigned char __at(0x8000) chram[2048]; unsigned char __at(0x8800) colram[2048]; // Character map const unsigned char chram_cols = 64; const unsigned char chram_rows = 32; -unsigned int chram_size; \ No newline at end of file +unsigned int chram_size; + +// Macros +#define CHECK_BIT(var, pos) ((var) & (1 << (pos))) \ No newline at end of file diff --git a/src/ui.c b/src/ui.c index 671cf3b..cccb4d4 100644 --- a/src/ui.c +++ b/src/ui.c @@ -1,6 +1,9 @@ #pragma once #include "sys.c" +char asc_0 = 48; +char asc_1 = 49; + void clear_chars(char c) { for (unsigned int p = 0; p < chram_size; p++) @@ -20,6 +23,22 @@ void write_string(const char *string, char color, unsigned int x, unsigned int y p++; } } + +void write_stringf(const char *format, char color, unsigned int x, unsigned int y, char data) +{ + unsigned int p = (y * chram_cols) + x; + char temp[30]; + sprintf(temp, format, data); + unsigned char l = strlen(temp); + for (char c = 0; c < l; c++) + { + if(temp[c]==0){return;} + chram[p] = temp[c]; + colram[p] = color; + p++; + } +} + void write_char(unsigned char c, char color, unsigned int x, unsigned int y) { unsigned int p = (y * chram_cols) + x; @@ -27,6 +46,22 @@ void write_char(unsigned char c, char color, unsigned int x, unsigned int y) colram[p] = color; } +void write_bits(char bits[], char multi, unsigned char first, unsigned char length, char color, unsigned int x, unsigned int y) +{ + for (char b = first; b < first + length; b++) + { + write_char((b) ? asc_1 : asc_0, color, x, y - 1); + char m = 0b00000001; + for (char i = 0; i < 8; i++) + { + write_char((bits[b * multi] & m) ? asc_1 : asc_0, color, x, y); + x++; + m <<= 1; + } + x++; + } +} + void box(unsigned int tx, unsigned int ty, unsigned int bx, unsigned int by, char c, char color) { for (unsigned int x = tx; x <= bx; x++) diff --git a/verilator/imgui.ini b/verilator/imgui.ini index 923d2c5..0063c74 100644 --- a/verilator/imgui.ini +++ b/verilator/imgui.ini @@ -4,7 +4,7 @@ Size=400,400 Collapsed=0 [Window][Debug Log] -Pos=6,18 +Pos=19,6 Size=520,600 Collapsed=0 @@ -29,7 +29,7 @@ Size=560,393 Collapsed=0 [Window][CPU Registers] -Pos=1308,461 +Pos=1349,13 Size=269,188 Collapsed=0 @@ -44,7 +44,7 @@ Size=553,169 Collapsed=0 [Window][WKRAM Editor] -Pos=1037,656 +Pos=5,626 Size=540,370 Collapsed=0 diff --git a/verilator/sim.v b/verilator/sim.v index 3781722..c455d51 100644 --- a/verilator/sim.v +++ b/verilator/sim.v @@ -1,11 +1,4 @@ `timescale 1ns / 1ps -// -// top end ff for verilator -// - -//`define sdl_display -`define USE_VGA -//`define USE_CGA module top( @@ -40,6 +33,14 @@ module top( input [8:0] spinner_4, input [8:0] spinner_5, + // ps2 alternative interface. + // [8] - extended, [9] - pressed, [10] - toggles with every press/release + input [10:0] ps2_key, + + // [24] - toggles with every event + input [24:0] ps2_mouse, + input [15:0] ps2_mouse_ext, // 15:8 - reserved(additional buttons), 7:0 - wheel movements + output [7:0] VGA_R/*verilator public_flat*/, output [7:0] VGA_G/*verilator public_flat*/, output [7:0] VGA_B/*verilator public_flat*/, @@ -63,7 +64,8 @@ wire ce_pix; jtframe_cen24 divider ( .clk(clk_sys), - .cen12(ce_pix) + //.cen12(ce_pix), // <-- dodgy video speed for faster simulation, will cause bearable char map corruption + .cen4(ce_pix) // <-- correct video speed ); /* verilator lint_on PINMISSING */ @@ -86,7 +88,9 @@ system system( .joystick({joystick_5,joystick_4,joystick_3,joystick_2,joystick_1,joystick_0}), .analog({joystick_analog_5,joystick_analog_4,joystick_analog_3,joystick_analog_2,joystick_analog_1,joystick_analog_0}), .paddle({paddle_5,paddle_4,paddle_3,paddle_2,paddle_1,paddle_0}), - .spinner({7'b0,spinner_5,7'b0,spinner_4,7'b0,spinner_3,7'b0,spinner_2,7'b0,spinner_1,7'b0,spinner_0}) + .spinner({7'b0,spinner_5,7'b0,spinner_4,7'b0,spinner_3,7'b0,spinner_2,7'b0,spinner_1,7'b0,spinner_0}), + .ps2_key(ps2_key), + .ps2_mouse({ps2_mouse_ext,7'b0,ps2_mouse}) ); endmodule diff --git a/verilator/sim/sim_bus.cpp b/verilator/sim/sim_bus.cpp index bc72ac7..d12cc5c 100644 --- a/verilator/sim/sim_bus.cpp +++ b/verilator/sim/sim_bus.cpp @@ -34,6 +34,10 @@ void SimBus::QueueDownload(std::string file, int index) { downloadQueue.push(chunk); } +bool SimBus::HasQueue() { + return downloadQueue.size() > 0; +} + int nextchar = 0; void SimBus::BeforeEval() { @@ -62,7 +66,7 @@ void SimBus::BeforeEval() } if (ioctl_file) { - //console.AddLog("ioctl_download addr %x ioctl_wait %x", *ioctl_addr, *ioctl_wait); + console.AddLog("ioctl_download addr %x ioctl_wait %x", *ioctl_addr, *ioctl_wait); if (*ioctl_wait == 0) { *ioctl_download = 1; *ioctl_wr = 1; @@ -84,8 +88,8 @@ void SimBus::BeforeEval() } } else { - ioctl_download = 0; - ioctl_wr = 0; + *ioctl_download = 0; + *ioctl_wr = 0; } } diff --git a/verilator/sim/sim_bus.h b/verilator/sim/sim_bus.h index 3d2b539..795b7c4 100644 --- a/verilator/sim/sim_bus.h +++ b/verilator/sim/sim_bus.h @@ -41,6 +41,7 @@ public: void BeforeEval(void); void AfterEval(void); void QueueDownload(std::string file, int index); + bool HasQueue(); SimBus(DebugConsole c); ~SimBus(); diff --git a/verilator/sim/sim_input.cpp b/verilator/sim/sim_input.cpp index 05b39f4..c3aae20 100644 --- a/verilator/sim/sim_input.cpp +++ b/verilator/sim/sim_input.cpp @@ -4,10 +4,7 @@ #ifndef _MSC_VER #include - - const Uint8 *m_keyboardState; - - +const Uint8* m_keyboardState; #else #define WIN32 #include @@ -15,22 +12,11 @@ IDirectInput8* m_directInput; IDirectInputDevice8* m_keyboard; unsigned char m_keyboardState[256]; +unsigned char m_keyboardState_last[256]; #endif #include - -// - Core inputs -//#define VSW1 top->top__DOT__sw1 -//#define VSW2 top->top__DOT__sw2 -//#define PLAYERINPUT top->top__DOT__playerinput -//#define JS top->top__DOT__joystick -//void js_assert(int s) { JS &= ~(1 << s); } -//void js_deassert(int s) { JS |= 1 << s; } -//void playinput_assert(int s) { PLAYERINPUT &= ~(1 << s); } -//void playinput_deassert(int s) { PLAYERINPUT |= (1 << s); } - - bool ReadKeyboard() { #ifdef WIN32 @@ -45,7 +31,7 @@ bool ReadKeyboard() else { return false; } } #else - m_keyboardState= SDL_GetKeyboardState(NULL); + m_keyboardState = SDL_GetKeyboardState(NULL); #endif return true; @@ -85,18 +71,23 @@ void SimInput::Read() { inputs[i] = m_keyboardState[mappings[i]]; #endif } + + for (unsigned char k = 0; k < 256; k++) { + m_keyboardState_last[k] = m_keyboardState[k]; + } + } void SimInput::SetMapping(int index, int code) { -printf("index %d code %d\n",index,code); - if (code < 256) + printf("index %d code %d\n", index, code); + if (code < 256) mappings[index] = code; else mappings[index] = 0; } void SimInput::CleanUp() { - + #ifdef WIN32 // Release keyboard if (m_keyboard) { m_keyboard->Unacquire(); m_keyboard->Release(); m_keyboard = 0; } diff --git a/verilator/sim/sim_video.cpp b/verilator/sim/sim_video.cpp index 1149ed4..7f6a7ce 100644 --- a/verilator/sim/sim_video.cpp +++ b/verilator/sim/sim_video.cpp @@ -420,7 +420,7 @@ void SimVideo::Clock(bool hblank, bool vblank, bool hsync, bool vsync, uint32_t if (last_vsync && !vsync) { count_frame++; count_line = 0; - + frameChanged = 1; #ifdef WIN32 GetSystemTime(&actualtime); time_ms = (actualtime.wSecond * 1000) + actualtime.wMilliseconds; diff --git a/verilator/sim/sim_video.h b/verilator/sim/sim_video.h index 10595ca..2dfecdf 100644 --- a/verilator/sim/sim_video.h +++ b/verilator/sim/sim_video.h @@ -33,6 +33,8 @@ public: ImTextureID texture_id; + bool frameChanged; + SimVideo(int width, int height, int rotate); ~SimVideo(); void UpdateTexture(); diff --git a/verilator/sim_main.cpp b/verilator/sim_main.cpp index 62934bd..1b88169 100644 --- a/verilator/sim_main.cpp +++ b/verilator/sim_main.cpp @@ -95,7 +95,7 @@ int verilate() { // Set system clock in core top->clk_sys = clk_sys.clk; - + // Simulate both edges of system clock if (clk_sys.clk != clk_sys.old) { if (clk_sys.clk) { bus.BeforeEval(); } @@ -120,6 +120,11 @@ int verilate() { return 0; } +char ps2_scancode = 0; +char ps2_toggle = 0; +char ps2_timer = 0; + + int main(int argc, char** argv, char** env) { // Create core and initialise @@ -172,7 +177,6 @@ int main(int argc, char** argv, char** env) { if (video.Initialise(windowTitle) == 1) { return 1; } //bus.QueueDownload("../src/os.bin", 0); - //bus.QueueDownload("../src/snek/snek.bin", 0); //bus.QueueDownload("../MiSTer.pf", 1); @@ -239,15 +243,15 @@ int main(int argc, char** argv, char** env) { ImGui::Image(video.texture_id, ImVec2(video.output_width * m, video.output_height * m)); ImGui::End(); - ImGui::Begin("PGROM Editor"); + /*ImGui::Begin("PGROM Editor"); mem_edit_1.DrawContents(top->top__DOT__system__DOT__pgrom__DOT__mem, 16384, 0); ImGui::End(); ImGui::Begin("CHROM Editor"); mem_edit_1.DrawContents(top->top__DOT__system__DOT__chrom__DOT__mem, 2048, 0); + ImGui::End();*/ + ImGui::Begin("WKRAM Editor"); + mem_edit_2.DrawContents(top->top__DOT__system__DOT__wkram__DOT__mem, 16384, 0); ImGui::End(); - //ImGui::Begin("WKRAM Editor"); - //mem_edit_2.DrawContents(top->top__DOT__system__DOT__wkram__DOT__mem, 16384, 0); - //ImGui::End(); //ImGui::Begin("CHRAM Editor"); //mem_edit_3.DrawContents(top->top__DOT__system__DOT__chram__DOT__mem, 2048, 0); //ImGui::End(); @@ -283,6 +287,40 @@ int main(int argc, char** argv, char** env) { top->spinner_0 += 1; top->spinner_1 -= 1; + + if (video.frameChanged) { + top->ps2_key = 0; + + ps2_timer++; + if (ps2_timer == 2) { + ps2_scancode =0x16; + ps2_toggle = !ps2_toggle; + + ps2_timer = 0; + } + if (ps2_toggle) { + top->ps2_key &= ~(1UL << 10); + } + else { + top->ps2_key |= (1UL << 10); + } + + for (char b = 0; b < 8; b++) { + char bit = (ps2_scancode >> b) & 1U; + if (bit == 1) { + top->ps2_key |= (1UL << b); + } + } + } + video.frameChanged = 0; + + if (!bus.HasQueue() && input.inputs[input_pause]) { + bus.QueueDownload("../src/os.bin", 0); + } + + top->ps2_mouse += 1; + top->ps2_mouse_ext -= 1; + // Run simulation if (run_enable) { for (int step = 0; step < batchSize; step++) { verilate(); } @@ -295,6 +333,7 @@ int main(int argc, char** argv, char** env) { } } + // Clean up before exit // --------------------