From 803384db0cf4906b6b5d3a415ce3c8e67549fe3b Mon Sep 17 00:00:00 2001 From: jimmystones Date: Sat, 3 Jul 2021 12:21:13 +0100 Subject: [PATCH 1/6] Improve spinner display --- InputTest.sv | 1 - src/os.c | 128 ++++++++++++++++++++++------------------- src/ui.c | 14 +++++ verilator/sim_main.cpp | 11 +++- 4 files changed, 92 insertions(+), 62 deletions(-) diff --git a/InputTest.sv b/InputTest.sv index 6afdcb0..5d5f06a 100644 --- a/InputTest.sv +++ b/InputTest.sv @@ -264,7 +264,6 @@ hps_io #(.CONF_STR(CONF_STR)) hps_io .buttons(buttons), .status(status), .status_menumask({direct_video}), - .forced_scandoubler(forced_scandoubler), .direct_video(direct_video), diff --git a/src/os.c b/src/os.c index ac6604d..ea4bdbd 100644 --- a/src/os.c +++ b/src/os.c @@ -42,6 +42,9 @@ void page_inputs() write_string("AX", 0xFF, 26, 3); write_string("AY", 0xFF, 31, 3); + write_string("POS", 0xFF, 7, 11); + write_string("SPD POS", 0xFF, 18, 11); + char label[5]; for (unsigned char j = 0; j < 6; j++) { @@ -49,20 +52,18 @@ void page_inputs() write_string(label, 0xFF - (j * 2), 2, 4 + j); sprintf(label, "PAD%d", j + 1); - write_string(label, 0xFF - (j * 2), 2, 11 + j); + write_string(label, 0xFF - (j * 2), 2, 12 + j); sprintf(label, "SPN%d", j + 1); - write_string(label, 0xFF - (j * 2), 14, 11 + j); + write_string(label, 0xFF - (j * 2), 14, 12 + j); } - - // write_string("EXT PRS SHF SCN ASC CHR", 0xFF, 6, 18); - write_string("CON", 0xFF, 2, 18); + write_string("CON", 0xFF, 2, 19); } // Application state char state = 0; char nextstate = 0; -// state = 0 - inputtester +// state = 0 - inputtester (advanced) // state = 1 - fadeout // state = 2 - fadein // state = 3 - startfadein @@ -95,12 +96,13 @@ unsigned char fadefreq = 4; unsigned char attractstate = 0; // Input tester variables -unsigned char inputindex = 0; unsigned char __at(0xC200) joystick_last[12]; signed char __at(0xC210) ax_last[6]; signed char __at(0xC220) ay_last[6]; unsigned char __at(0xC230) px_last[6]; -signed char __at(0xC240) sx_last[6]; +signed char __at(0xC240) sx_toggle_last[6]; +signed char __at(0xC250) sx_last[6]; +unsigned long __at(0xC260) sx_pos[6]; unsigned char con_x; // Console cursor X position unsigned char con_y; // Console cursor X position @@ -139,7 +141,9 @@ void start_inputtester() ax_last[i] = 1; ay_last[i] = 1; px_last[i] = 1; + sx_toggle_last[i] = 1; sx_last[i] = 1; + sx_pos[i] = 0; } } @@ -240,6 +244,42 @@ void pushhistory(char new) history[3] = new; } +void handle_codes() +{ + // Track input history of P1 DPAD for secret codes! + bdown_up_last = bdown_up; + bdown_down_last = bdown_down; + bdown_left_last = bdown_left; + bdown_right_last = bdown_right; + bdown_up = CHECK_BIT(joystick[0], 3); + bdown_down = CHECK_BIT(joystick[0], 2); + bdown_left = CHECK_BIT(joystick[0], 1); + bdown_right = CHECK_BIT(joystick[0], 0); + if (!bdown_up && bdown_up_last) + { + pushhistory(1); + } + if (!bdown_down && bdown_down_last) + { + pushhistory(2); + } + if (!bdown_left && bdown_left_last) + { + pushhistory(3); + } + if (!bdown_right && bdown_right_last) + { + pushhistory(4); + } + // Check for SNEK code + if (history[0] == 4 && history[1] == 2 && history[2] == 3 && history[3] == 1) + { + nextstate = 6; + pushhistory(0); + start_fadeout(); + return; + } +} // Input tester state void inputtester() @@ -248,55 +288,17 @@ void inputtester() // Handle PS/2 inputs whenever possible to improve latency handle_ps2(); + // Handle secret code detection (joypad 1 directions) if (hsync && !hsync_last) { - // Track input history of P1 DPAD for secret codes! - bdown_up_last = bdown_up; - bdown_down_last = bdown_down; - bdown_left_last = bdown_left; - bdown_right_last = bdown_right; - bdown_up = CHECK_BIT(joystick[0], 3); - bdown_down = CHECK_BIT(joystick[0], 2); - bdown_left = CHECK_BIT(joystick[0], 1); - bdown_right = CHECK_BIT(joystick[0], 0); - if (!bdown_up && bdown_up_last) - { - pushhistory(1); - } - if (!bdown_down && bdown_down_last) - { - pushhistory(2); - } - if (!bdown_left && bdown_left_last) - { - pushhistory(3); - } - if (!bdown_right && bdown_right_last) - { - pushhistory(4); - } + handle_codes(); } + // As soon as vsync is detected start drawing screen updates if (vsync && !vsync_last) { - // Rotate index of inputs to show this loop - inputindex++; - if (inputindex == 6) - { - inputindex = 0; - } - - // Check for SNEK code - if (history[0] == 4 && history[1] == 2 && history[2] == 3 && history[3] == 1) - { - nextstate = 6; - pushhistory(0); - start_fadeout(); - return; - } - - // Draw joystick inputs + // Draw joystick inputs (only update each byte if value has changed) for (char inputindex = 0; inputindex < 6; inputindex++) { char m = 0b00000001; @@ -326,7 +328,7 @@ void inputtester() joystick_last[lastindex] = joy; } - // Draw analog inputs + // Draw analog inputs (only update if value has changed) signed char ax = analog[(inputindex * 16)]; signed char ay = analog[(inputindex * 16) + 8]; if (ax != ax_last[inputindex] || ay != ay_last[inputindex]) @@ -338,25 +340,34 @@ void inputtester() ax_last[inputindex] = ax; ay_last[inputindex] = ay; - // Draw paddle inputs + // Draw paddle inputs (only update if value has changed) unsigned char px = paddle[(inputindex * 8)]; if (px != px_last[inputindex]) { char strp[5]; sprintf(strp, "%4d", px); - write_string(strp, 0xFF, 6, 11 + inputindex); + write_string(strp, 0xFF, 6, 12 + inputindex); } px_last[inputindex] = px; - // Draw spinner inputs + // Draw spinner inputs (only update when update clock changes) + bool sx_toggle = CHECK_BIT(spinner[(inputindex * 16) + 8], 0); signed char sx = spinner[(inputindex * 16)]; - if (sx != sx_last[inputindex]) + if (sx_toggle != sx_toggle_last[inputindex]) { - char strs[5]; - sprintf(strs, "%4d", sx); - write_string(strs, 0xFF, 17, 11 + inputindex); + sx_pos[inputindex] += sx; + write_stringf("%4d", 0xFF, 22, 12 + inputindex, sx_pos[inputindex] / 16); + } + else + { + sx = 0; + } + if (sx_last[inputindex] != sx) + { + write_stringfs("%4d", 0xFF, 17, 12 + inputindex, sx); } sx_last[inputindex] = sx; + sx_toggle_last[inputindex] = sx_toggle; } // Keyboard test console @@ -424,7 +435,6 @@ void inputtester() con_cursortimer = con_cursorfreq; write_char(con_cursor ? '|' : ' ', 0xFF, con_x, con_y); } - } } diff --git a/src/ui.c b/src/ui.c index b65189e..b884462 100644 --- a/src/ui.c +++ b/src/ui.c @@ -45,6 +45,20 @@ void write_string(const char *string, char color, unsigned int x, unsigned int y } } +void write_stringfs(const char *format, char color, unsigned int x, unsigned int y, signed 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_stringf(const char *format, char color, unsigned int x, unsigned int y, char data) { unsigned int p = (y * chram_cols) + x; diff --git a/verilator/sim_main.cpp b/verilator/sim_main.cpp index 4f8c32b..c1a7b72 100644 --- a/verilator/sim_main.cpp +++ b/verilator/sim_main.cpp @@ -128,6 +128,7 @@ char ps2_scancode = 0; char ps2_toggle = 0; char ps2_timer = 0; +char spinner_toggle = 0; int main(int argc, char** argv, char** env) { @@ -297,7 +298,7 @@ int main(int argc, char** argv, char** env) { //top->joystick_3 = top->joystick_0; //top->joystick_4 = top->joystick_0; //top->joystick_5 = top->joystick_0; - + top->joystick_analog_0 += 1; top->joystick_analog_0 -= 256; //top->joystick_analog_1 -= 1; @@ -318,7 +319,13 @@ int main(int argc, char** argv, char** env) { //top->paddle_4 += 1; //top->paddle_5 -= 1; - top->spinner_0 += 1; + if (input.inputs[0] || input.inputs[1]) { + spinner_toggle = !spinner_toggle; + top->spinner_0 = (input.inputs[0]) ? 16 : -16; + for (char b = 8; b < 16; b++) { + top->spinner_0 &= ~(1UL << b); + } + if (spinner_toggle) { top->spinner_0 |= 1UL << 8; } } //top->spinner_1 -= 1; //top->spinner_2 += 1; //top->spinner_3 -= 1; From 7757973f7b89eb82c1863c1a27e1df70b0b3d112 Mon Sep 17 00:00:00 2001 From: jimmystones Date: Sat, 3 Jul 2021 13:46:25 +0100 Subject: [PATCH 2/6] Clean up state machine --- src/os.c | 155 ++++++++++++++++++++++++++++++++----------------------- src/ui.c | 10 ++++ 2 files changed, 99 insertions(+), 66 deletions(-) diff --git a/src/os.c b/src/os.c index ea4bdbd..fe4934b 100644 --- a/src/os.c +++ b/src/os.c @@ -31,46 +31,25 @@ bool hsync_last; bool vsync; bool vsync_last; -// Draw static elements for input test page -void page_inputs() -{ - clear_chars(0); - page_border(0b00000111); - - write_string("- MiSTer Input Tester -", 0b11100011, 8, 1); - write_string("RLDUABXYLRsSCZ", 0xFF, 7, 3); - write_string("AX", 0xFF, 26, 3); - write_string("AY", 0xFF, 31, 3); - - write_string("POS", 0xFF, 7, 11); - write_string("SPD POS", 0xFF, 18, 11); - - char label[5]; - for (unsigned char j = 0; j < 6; j++) - { - sprintf(label, "JOY%d", j + 1); - write_string(label, 0xFF - (j * 2), 2, 4 + j); - - sprintf(label, "PAD%d", j + 1); - write_string(label, 0xFF - (j * 2), 2, 12 + j); - - sprintf(label, "SPN%d", j + 1); - write_string(label, 0xFF - (j * 2), 14, 12 + j); - } - write_string("CON", 0xFF, 2, 19); -} - // Application state -char state = 0; -char nextstate = 0; -// state = 0 - inputtester (advanced) -// state = 1 - fadeout -// state = 2 - fadein -// state = 3 - startfadein -// state = 4 - startgame -// state = 5 - gameplaying -// state = 7 - startattract -// state = 8 - attract +#define STATE_START_INPUTTESTER 0 +#define STATE_INPUTTESTER 1 + +#define STATE_START_INPUTTESTERADV 2 +#define STATE_INPUTTESTERADV 3 + +#define STATE_FADEOUT 8 +#define STATE_START_FADEIN 9 +#define STATE_FADEIN 10 + +#define STATE_START_ATTRACT 16 +#define STATE_ATTRACT 17 + +#define STATE_START_GAME 24 +#define STATE_GAME 25 + +char state = STATE_START_INPUTTESTERADV; +char nextstate = STATE_START_INPUTTESTERADV; // SNEK variables unsigned char movefreqinit = 14; @@ -125,13 +104,37 @@ bool bdown_down = 0; bool bdown_down_last = 0; char history[4]; -// Initialise inputtester state and draw static elements -void start_inputtester() +// Draw static elements for input test page +void page_inputtester_adv() +{ + clear_chars(0); + page_border(0b00000111); + + write_string("- MiSTer Input Tester -", 0b11100011, 8, 1); + write_string("RLDUABXYLRsSCZ", 0xFF, 7, 3); + write_string("AX", 0xFF, 26, 3); + write_string("AY", 0xFF, 31, 3); + + write_string("POS", 0xFF, 7, 11); + write_string("SPD POS", 0xFF, 18, 11); + + char label[5]; + for (unsigned char j = 0; j < 6; j++) + { + sprintf(label, "JOY%d", j + 1); + write_string(label, 0xFF - (j * 2), 2, 4 + j); + + sprintf(label, "PAD%d", j + 1); + write_string(label, 0xFF - (j * 2), 2, 12 + j); + + sprintf(label, "SPN%d", j + 1); + write_string(label, 0xFF - (j * 2), 14, 12 + j); + } + write_string("CON", 0xFF, 2, 19); +} + +void reset_inputstates() { - page_inputs(); - state = 1; - con_x = con_l; - con_y = con_t; for (char i = 0; i < 12; i++) { joystick_last[i] = 1; @@ -147,10 +150,26 @@ void start_inputtester() } } +// Initialise advanced inputtester state and draw static elements +void start_inputtester_adv() +{ + state = STATE_INPUTTESTERADV; + + // Draw page + page_inputtester_adv(); + + // Reset console cursor + con_x = con_l; + con_y = con_t; + + // Reset last states for inputs + reset_inputstates(); +} + // Initialise fadeout state void start_fadeout() { - state = 2; + state = STATE_FADEOUT; fadetimer = fadefreq; fade = 0; } @@ -158,7 +177,7 @@ void start_fadeout() // Initialise fadein state void start_fadein() { - state = 3; + state = STATE_FADEIN; fadetimer = fadefreq; fade = 15; } @@ -166,7 +185,7 @@ void start_fadein() // Initialise attract state and draw static elements void start_attract() { - state = 7; + state = STATE_ATTRACT; attractstate = 0; clear_chars(0); page_border(0b00000111); @@ -178,7 +197,7 @@ void start_attract() // Initialise attract state and draw static elements void start_gameplay() { - state = 5; + state = STATE_GAME; length = 0; x = 20; y = 15; @@ -274,7 +293,7 @@ void handle_codes() // Check for SNEK code if (history[0] == 4 && history[1] == 2 && history[2] == 3 && history[3] == 1) { - nextstate = 6; + nextstate = STATE_START_ATTRACT; pushhistory(0); start_fadeout(); return; @@ -282,7 +301,7 @@ void handle_codes() } // Input tester state -void inputtester() +void inputtester_adv() { // Handle PS/2 inputs whenever possible to improve latency @@ -467,7 +486,7 @@ void gameplay() if (joystick[0] & 0b00010000) { - start_inputtester(); + start_inputtester_adv(); return; } } @@ -546,30 +565,34 @@ void main() vsync = input0 & 0x40; switch (state) { - case 0: - start_inputtester(); + case STATE_START_INPUTTESTERADV: + start_inputtester_adv(); break; - case 1: - inputtester(); + case STATE_INPUTTESTERADV: + inputtester_adv(); break; - case 2: + + case STATE_FADEOUT: fadeout(); break; - case 3: + case STATE_FADEIN: fadein(); break; - case 4: - start_gameplay(); - break; - case 5: - gameplay(); - break; - case 6: + + case STATE_START_ATTRACT: start_attract(); break; - case 7: + case STATE_ATTRACT: attract(); break; + + case STATE_START_GAME: + start_gameplay(); + break; + case STATE_GAME: + gameplay(); + break; + default: break; } diff --git a/src/ui.c b/src/ui.c index b884462..d82f5bd 100644 --- a/src/ui.c +++ b/src/ui.c @@ -25,6 +25,7 @@ char asc_0 = 48; char asc_1 = 49; +// Set all character RAM to specified character void clear_chars(char c) { for (unsigned int p = 0; p < chram_size; p++) @@ -33,6 +34,7 @@ void clear_chars(char c) } } +// Write string to character RAM void write_string(const char *string, char color, unsigned int x, unsigned int y) { unsigned int p = (y * chram_cols) + x; @@ -45,6 +47,7 @@ void write_string(const char *string, char color, unsigned int x, unsigned int y } } +// Write formatted string to character RAM (signed char data) void write_stringfs(const char *format, char color, unsigned int x, unsigned int y, signed char data) { unsigned int p = (y * chram_cols) + x; @@ -59,6 +62,8 @@ void write_stringfs(const char *format, char color, unsigned int x, unsigned int p++; } } + +// Write formatted string to character RAM (unsigned char data) void write_stringf(const char *format, char color, unsigned int x, unsigned int y, char data) { unsigned int p = (y * chram_cols) + x; @@ -74,6 +79,7 @@ void write_stringf(const char *format, char color, unsigned int x, unsigned int } } +// Write single char to character RAM void write_char(unsigned char c, char color, unsigned int x, unsigned int y) { unsigned int p = (y * chram_cols) + x; @@ -81,6 +87,7 @@ void write_char(unsigned char c, char color, unsigned int x, unsigned int y) colram[p] = color; } +// Write grouped bits to character RAM 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++) @@ -97,6 +104,7 @@ void write_bits(char bits[], char multi, unsigned char first, unsigned char leng } } +// Draw box outline with specified character 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++) @@ -111,6 +119,8 @@ void box(unsigned int tx, unsigned int ty, unsigned int bx, unsigned int by, cha } } + +// Draw page border void page_border(char color) { write_char(128, color, 0, 0); From e6fed59bb93d09bb396d1ff2462261681865af26 Mon Sep 17 00:00:00 2001 From: jimmystones Date: Sat, 3 Jul 2021 13:58:11 +0100 Subject: [PATCH 3/6] Fix sim inputs --- verilator/sim_main.cpp | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/verilator/sim_main.cpp b/verilator/sim_main.cpp index c1a7b72..66aeece 100644 --- a/verilator/sim_main.cpp +++ b/verilator/sim_main.cpp @@ -40,14 +40,14 @@ const int input_right = 0; const int input_left = 1; const int input_down = 2; const int input_up = 3; -const int input_fire1 = 4; -const int input_fire2 = 5; -const int input_start_1 = 6; -const int input_start_2 = 7; -const int input_coin_1 = 8; -const int input_coin_2 = 9; -const int input_coin_3 = 10; -const int input_pause = 11; +const int input_a = 4; +const int input_b = 5; +const int input_x = 6; +const int input_y = 7; +const int input_l = 8; +const int input_r= 9; +const int input_select = 10; +const int input_start = 11; // Video // ----- @@ -159,13 +159,15 @@ int main(int argc, char** argv, char** env) { input.SetMapping(input_right, DIK_RIGHT); input.SetMapping(input_down, DIK_DOWN); input.SetMapping(input_left, DIK_LEFT); - input.SetMapping(input_fire1, DIK_SPACE); - input.SetMapping(input_start_1, DIK_1); - input.SetMapping(input_start_2, DIK_2); - input.SetMapping(input_coin_1, DIK_5); - input.SetMapping(input_coin_2, DIK_6); - input.SetMapping(input_coin_3, DIK_7); - input.SetMapping(input_pause, DIK_P); + input.SetMapping(input_a, DIK_Z); // A + input.SetMapping(input_b, DIK_X); // B + input.SetMapping(input_x, DIK_A); // X + input.SetMapping(input_y, DIK_S); // Y + input.SetMapping(input_l, DIK_Q); // L + input.SetMapping(input_r, DIK_W); // R + input.SetMapping(input_select, DIK_1); // Select + input.SetMapping(input_start, DIK_5); // Start + #else input.SetMapping(input_up, SDL_SCANCODE_UP); input.SetMapping(input_right, SDL_SCANCODE_RIGHT); From d9aad0bbfd9d5338c90da05005e41caee7dadbc7 Mon Sep 17 00:00:00 2001 From: jimmystones Date: Sat, 3 Jul 2021 13:58:23 +0100 Subject: [PATCH 4/6] Fix game/attract buttons --- src/os.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/os.c b/src/os.c index fe4934b..efec2bc 100644 --- a/src/os.c +++ b/src/os.c @@ -484,7 +484,7 @@ void gameplay() nyd = 0; } - if (joystick[0] & 0b00010000) + if (CHECK_BIT(joystick[8], 2)) // select to quit { start_inputtester_adv(); return; @@ -537,7 +537,7 @@ void attract() if (hsync && !hsync_last) { - if (joystick[1] & 0b00100000) // start + if (CHECK_BIT(joystick[8], 3)) // start { start_gameplay(); } From 2ab89eb71d436ff1a352bbffad9ef11197f05433 Mon Sep 17 00:00:00 2001 From: jimmystones Date: Sat, 3 Jul 2021 15:04:48 +0100 Subject: [PATCH 5/6] Fix shift bug in ps2 sim --- src/ps2.c | 230 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 120 insertions(+), 110 deletions(-) diff --git a/src/ps2.c b/src/ps2.c index 1ac51eb..cd2867c 100644 --- a/src/ps2.c +++ b/src/ps2.c @@ -79,114 +79,116 @@ const char KEY_DOWN = 0x72; 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) - '\n', '\n',// 0x5a (ENTER) - '}', ']', // 0x5b - 0, 0, // 0x5c - '|', '\\', // 0x5d - 0, 0, // 0x5e - 0, 0, // 0x5f - 0, 0, // 0x60 - 0, 0, // 0x61 - 0, 0, // 0x62 - 0, 0, // 0x63 - 0, 0, // 0x64 - 0, 0, // 0x65 - '\b', '\b',// 0x66 + 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) + '\n', '\n', // 0x5a (ENTER) + '}', ']', // 0x5b + 0, 0, // 0x5c + '|', '\\', // 0x5d + 0, 0, // 0x5e + 0, 0, // 0x5f + 0, 0, // 0x60 + 0, 0, // 0x61 + 0, 0, // 0x62 + 0, 0, // 0x63 + 0, 0, // 0x64 + 0, 0, // 0x65 + '\b', '\b', // 0x66 0, 0}; char kbd_in[2]; char kbd_lastclock = 0; -char kbd_shift = 0; +char kbd_shift_left = 0; +char kbd_shift_right = 0; +char kbd_scan = 0; char kbd_pressed; char kbd_extend; char kbd_lastscan = 0; @@ -205,7 +207,7 @@ void get_ascii(char scan) { kbd_lastscan = scan; char p = (kbd_lastscan * 2); - if (!kbd_shift) + if (!(kbd_shift_left || kbd_shift_right)) { p++; } @@ -230,19 +232,27 @@ void handle_ps2() } kbd_extend = CHECK_BIT(kbd_in[1], 0); kbd_pressed = CHECK_BIT(kbd_in[1], 1); - char kbd_scan = kbd_in[0]; + kbd_scan = kbd_in[0]; if (kbd_pressed) { - if (kbd_scan == KEY_LEFTSHIFT || kbd_scan == KEY_RIGHTSHIFT) + if (kbd_scan == KEY_LEFTSHIFT) { - kbd_shift++; + kbd_shift_left = 1; + } + else if (kbd_scan == KEY_RIGHTSHIFT) + { + kbd_shift_right = 1; } } else { - if (kbd_scan == KEY_LEFTSHIFT || kbd_scan == KEY_RIGHTSHIFT) + if (kbd_scan == KEY_LEFTSHIFT) { - kbd_shift--; + kbd_shift_left = 0; + } + else if (kbd_scan == KEY_RIGHTSHIFT) + { + kbd_shift_right = 0; } else { From 821be47bb48064078fab20badcaecc2be3717100 Mon Sep 17 00:00:00 2001 From: jimmystones Date: Sat, 3 Jul 2021 16:12:37 +0100 Subject: [PATCH 6/6] Add 'graphical' input tester mode --- InputTest.sv | 1 - src/os.c | 184 +++++++++++++++++++++++++++++++++--- verilator/sim/sim_input.cpp | 1 + verilator/sim_main.cpp | 2 +- 4 files changed, 174 insertions(+), 14 deletions(-) diff --git a/InputTest.sv b/InputTest.sv index 5d5f06a..69f22cf 100644 --- a/InputTest.sv +++ b/InputTest.sv @@ -260,7 +260,6 @@ hps_io #(.CONF_STR(CONF_STR)) hps_io ( .clk_sys(clk_sys), .HPS_BUS(HPS_BUS), - .buttons(buttons), .status(status), .status_menumask({direct_video}), diff --git a/src/os.c b/src/os.c index efec2bc..4c75ed8 100644 --- a/src/os.c +++ b/src/os.c @@ -48,8 +48,8 @@ bool vsync_last; #define STATE_START_GAME 24 #define STATE_GAME 25 -char state = STATE_START_INPUTTESTERADV; -char nextstate = STATE_START_INPUTTESTERADV; +char state = STATE_START_INPUTTESTER; +char nextstate = STATE_START_INPUTTESTER; // SNEK variables unsigned char movefreqinit = 14; @@ -75,13 +75,20 @@ unsigned char fadefreq = 4; unsigned char attractstate = 0; // Input tester variables -unsigned char __at(0xC200) joystick_last[12]; -signed char __at(0xC210) ax_last[6]; -signed char __at(0xC220) ay_last[6]; -unsigned char __at(0xC230) px_last[6]; -signed char __at(0xC240) sx_toggle_last[6]; -signed char __at(0xC250) sx_last[6]; -unsigned long __at(0xC260) sx_pos[6]; +// unsigned char __at(0xC200) joystick_last[12]; +// signed char __at(0xC210) ax_last[6]; +// signed char __at(0xC220) ay_last[6]; +// unsigned char __at(0xC230) px_last[6]; +// signed char __at(0xC240) sx_toggle_last[6]; +// signed char __at(0xC250) sx_last[6]; +// unsigned long __at(0xC260) sx_pos[6]; +unsigned char joystick_last[12]; +signed char ax_last[6]; +signed char ay_last[6]; +unsigned char px_last[6]; +signed char sx_toggle_last[6]; +signed char sx_last[6]; +unsigned long sx_pos[6]; unsigned char con_x; // Console cursor X position unsigned char con_y; // Console cursor X position @@ -92,6 +99,7 @@ unsigned char con_b = 37; // Console bottom edge Y bool con_cursor; unsigned char con_cursortimer = 1; unsigned char con_cursorfreq = 30; +char modeswitchtimer = 0; // DPAD tracker bool bdown_left = 0; @@ -104,13 +112,95 @@ bool bdown_down = 0; bool bdown_down_last = 0; char history[4]; -// Draw static elements for input test page +char color_pad_outline = 0xFE; + +#define PAD_COUNT 2 +#define BUTTON_COUNT 12 + +char pad_offset_x[PAD_COUNT] = {6, 6}; +char pad_offset_y[PAD_COUNT] = {6, 18}; +char button_name[BUTTON_COUNT][6] = { + "R", + "L", + "D", + "U", + "A", + "B", + "X", + "Y", + "L", + "R", + "Sel", + "Start"}; +char button_x[BUTTON_COUNT] = {6, 2, 4, 4, 24, 22, 22, 20, 3, 23, 9, 13}; +char button_y[BUTTON_COUNT] = {3, 3, 4, 2, 3, 4, 2, 3, 0, 0, 3, 3}; + +void draw_pad(char xo, char yo) +{ + // Outline + write_char(134, color_pad_outline, xo, yo + 1); + for (char x = 1; x < 26; x++) + { + write_char(135, color_pad_outline, xo + x, yo + 1); + } + write_char(136, color_pad_outline, xo + 26, yo + 1); + for (char y = 2; y < 5; y++) + { + write_char(137, color_pad_outline, xo, yo + y); + write_char(137, color_pad_outline, xo + 26, yo + y); + } + write_char(139, color_pad_outline, xo, yo + 5); + write_char(138, color_pad_outline, xo + 26, yo + 5); + + write_char(138, color_pad_outline, xo + 8, yo + 5); + write_char(139, color_pad_outline, xo + 18, yo + 5); + write_char(134, color_pad_outline, xo + 8, yo + 4); + write_char(136, color_pad_outline, xo + 18, yo + 4); + for (char x = 1; x < 8; x++) + { + write_char(135, color_pad_outline, xo + x, yo + 5); + } + for (char x = 9; x < 18; x++) + { + write_char(135, color_pad_outline, xo + x, yo + 4); + } + for (char x = 19; x < 26; x++) + { + write_char(135, color_pad_outline, xo + x, yo + 5); + } + // Shoulders + write_char(134, color_pad_outline, xo + 1, yo); + write_char(136, color_pad_outline, xo + 5, yo); + write_char(134, color_pad_outline, xo + 21, yo); + write_char(136, color_pad_outline, xo + 25, yo); +} + +// Draw static elements for basic input test page +void page_inputtester() +{ + clear_chars(0); + page_border(0b00000111); + + write_string("- MiSTer Input Tester -", 0b11100011, 8, 1); + write_string("Hold for basic mode", 0b11100011, 4, 29); + write_string("RLDUABXYLRsSCZ", 0xFF, 7, 3); write_string("AX", 0xFF, 26, 3); write_string("AY", 0xFF, 31, 3); @@ -135,6 +225,7 @@ void page_inputtester_adv() void reset_inputstates() { + modeswitchtimer = 0; for (char i = 0; i < 12; i++) { joystick_last[i] = 1; @@ -150,6 +241,18 @@ void reset_inputstates() } } +// Initialise basic inputtester state and draw static elements +void start_inputtester() +{ + state = STATE_INPUTTESTER; + + // Draw page + page_inputtester(); + + // Reset last states for inputs + reset_inputstates(); +} + // Initialise advanced inputtester state and draw static elements void start_inputtester_adv() { @@ -263,9 +366,9 @@ void pushhistory(char new) history[3] = new; } +// Track input history of P1 DPAD for secret codes! void handle_codes() { - // Track input history of P1 DPAD for secret codes! bdown_up_last = bdown_up; bdown_down_last = bdown_down; bdown_left_last = bdown_left; @@ -300,7 +403,47 @@ void handle_codes() } } -// Input tester state +// Advanced input tester state +void inputtester() +{ + + // Handle PS/2 inputs whenever possible to improve latency + handle_ps2(); + + // Handle secret code detection (joypad 1 directions) + if (hsync && !hsync_last) + { + handle_codes(); + } + + // As soon as vsync is detected start drawing screen updates + if (vsync && !vsync_last) + { + // Switch to basic mode if select is held for 1 second + if (CHECK_BIT(joystick[8], 2)) + { + modeswitchtimer++; + if (modeswitchtimer == 60) + { + start_inputtester_adv(); + return; + } + } + + // Draw control pad buttons + for (char joy = 0; joy < PAD_COUNT; joy++) + { + char index = joy * 32; + for (char button = 0; button < BUTTON_COUNT; button++) + { + char color = (button < 8 ? CHECK_BIT(joystick[index], button) : CHECK_BIT(joystick[index + 8], button - 8)) ? 0xFF : 0b10010010; + write_string(button_name[button], color, pad_offset_x[joy] + button_x[button], pad_offset_y[joy] + button_y[button]); + } + } + } +} + +// Advanced input tester state void inputtester_adv() { @@ -316,6 +459,16 @@ void inputtester_adv() // As soon as vsync is detected start drawing screen updates if (vsync && !vsync_last) { + // Switch to basic mode if select is held for 1 second + if (CHECK_BIT(joystick[8], 2)) + { + modeswitchtimer++; + if (modeswitchtimer == 60) + { + start_inputtester(); + return; + } + } // Draw joystick inputs (only update each byte if value has changed) for (char inputindex = 0; inputindex < 6; inputindex++) @@ -565,6 +718,13 @@ void main() vsync = input0 & 0x40; switch (state) { + case STATE_START_INPUTTESTER: + start_inputtester(); + break; + case STATE_INPUTTESTER: + inputtester(); + break; + case STATE_START_INPUTTESTERADV: start_inputtester_adv(); break; diff --git a/verilator/sim/sim_input.cpp b/verilator/sim/sim_input.cpp index 9f69670..0fa9bef 100644 --- a/verilator/sim/sim_input.cpp +++ b/verilator/sim/sim_input.cpp @@ -372,6 +372,7 @@ bool ps2_clock = 0; void SimInput::BeforeEval() { if (keyEventTimer == 0) { + if (keyEvents.size() > 0) { // Get chunk from queue SimInput_PS2KeyEvent evt = keyEvents.front(); diff --git a/verilator/sim_main.cpp b/verilator/sim_main.cpp index 66aeece..6bad272 100644 --- a/verilator/sim_main.cpp +++ b/verilator/sim_main.cpp @@ -166,7 +166,7 @@ int main(int argc, char** argv, char** env) { input.SetMapping(input_l, DIK_Q); // L input.SetMapping(input_r, DIK_W); // R input.SetMapping(input_select, DIK_1); // Select - input.SetMapping(input_start, DIK_5); // Start + input.SetMapping(input_start, DIK_2); // Start #else input.SetMapping(input_up, SDL_SCANCODE_UP);