A2560K Keyboard LED Matrix

Added minor support for the LED matrix. Boot sequence animation and a KEYCOLOR setting in the CLI.
This commit is contained in:
Peter Weingartner 2022-03-28 20:25:44 -04:00
parent 41d1ad3ccc
commit e0ecfb6976
8 changed files with 14104 additions and 13950 deletions

View file

@ -17,6 +17,7 @@
#include "sys_general.h" #include "sys_general.h"
#include "vicky_general.h" #include "vicky_general.h"
#include "cli/cli.h" #include "cli/cli.h"
#include "dev/kbd_mo.h"
#include "dev/txt_screen.h" #include "dev/txt_screen.h"
#include "rsrc/font/quadrotextFONT.h" #include "rsrc/font/quadrotextFONT.h"
@ -26,7 +27,7 @@
#include "rsrc/bitmaps/splash_a2560k.h" #include "rsrc/bitmaps/splash_a2560k.h"
#endif #endif
#define SPLASH_WAIT_SEC 15 /* How many seconds to wait on the splash screen */ #define SPLASH_WAIT_SEC 10 /* How many seconds to wait on the splash screen */
/* /*
* Important scan codes * Important scan codes
@ -51,9 +52,31 @@ const char * MCP_INIT_SDC = "/sd/system/mcp.init"; /**< Path to config file on
const char * MCP_INIT_FDC = "/fd/system/mcp.init"; /**< Path to config file on the floppy drive */ const char * MCP_INIT_FDC = "/fd/system/mcp.init"; /**< Path to config file on the floppy drive */
const char * MCP_INIT_HDC = "/hd/system/mcp.init"; /**< Path to config file on the IDE drive */ const char * MCP_INIT_HDC = "/hd/system/mcp.init"; /**< Path to config file on the IDE drive */
// Colors for the A2560K keyboard LED matrix
const unsigned short kbd_colors[] = {0x000F, 0x0FF, 0x00F0, 0x0FF0, 0x0F70, 0x0F00};
short cli_screen = 0; /**< The default screen to use for the REPL of the CLI */ short cli_screen = 0; /**< The default screen to use for the REPL of the CLI */
char cli_command_path[MAX_PATH_LEN]; /**< Path to the command processor (empty string for built-in) */ char cli_command_path[MAX_PATH_LEN]; /**< Path to the command processor (empty string for built-in) */
/**
* On the A2560K, animate the LEDs based on the current time while we're waiting for a key press
*
* @param max_ticks the value of the jiffy counter when the boot screen will end
* @param ticks the current value of the jiffy counter
* @param min_ticks the starting value of the jiffy counter
*/
void boot_animate_keyboard(unsigned long max_ticks, unsigned long ticks, unsigned long min_ticks) {
#if MODEL == MODEL_FOENIX_A2560K
const int animation_steps = 7;
int current_step = (int)(((ticks - min_ticks) * animation_steps) / (max_ticks - min_ticks));
int i;
for (i = 0; i < current_step; i++) {
kbdmo_set_led_matrix_row(current_step - i - 1, kbd_colors[5 - i]);
}
#endif
}
/** /**
* Set the path of the command shell * Set the path of the command shell
* *
@ -161,7 +184,9 @@ short boot_screen() {
short screen = 0; short screen = 0;
char buffer[256]; char buffer[256];
char entry[50]; char entry[50];
long target_jiffies = 0; unsigned long target_jiffies = 0;
unsigned long min_jiffies = 0;
unsigned long current_jiffies = 0;
int i = 0; int i = 0;
const unsigned char * pixels; const unsigned char * pixels;
volatile unsigned char * vram = VRAM_Bank0; volatile unsigned char * vram = VRAM_Bank0;
@ -260,9 +285,13 @@ short boot_screen() {
print(screen, buffer); print(screen, buffer);
/* Wait until the target duration has been reached _or_ the user presses a key */ /* Wait until the target duration has been reached _or_ the user presses a key */
sprintf(buffer, "Booting using the default device."); sprintf(buffer, "Booting from default device...\n");
target_jiffies = sys_time_jiffies() + SPLASH_WAIT_SEC * 60; min_jiffies = sys_time_jiffies();
while (target_jiffies > sys_time_jiffies()) { target_jiffies = min_jiffies + SPLASH_WAIT_SEC * 60;
current_jiffies = sys_time_jiffies();
while (target_jiffies > current_jiffies) {
boot_animate_keyboard(target_jiffies, current_jiffies, min_jiffies);
short scan_code = sys_kbd_scancode(); short scan_code = sys_kbd_scancode();
if (scan_code != 0) { if (scan_code != 0) {
switch (scan_code) { switch (scan_code) {
@ -292,11 +321,18 @@ short boot_screen() {
} }
break; break;
} }
current_jiffies = sys_time_jiffies();
} }
txt_init_screen(screen); txt_init_screen(screen);
print(screen, buffer); print(screen, buffer);
#if MODEL == MODEL_FOENIX_A2560K
// Turn off the keyboard LEDs
kbdmo_set_led_matrix_fill(0);
#endif
return device; return device;
} }
@ -347,7 +383,7 @@ void boot_from_bdev(short device) {
if (device >= 0) { if (device >= 0) {
int i; int i;
for (i = 0; i < 512; i++) { for (i = 0; i < 512; i++) {
// Zero out the buffer // Zero out the buffer
BOOT_SECTOR_BUFFER[i] = 0; BOOT_SECTOR_BUFFER[i] = 0;

View file

@ -497,6 +497,23 @@ short cli_layout_get(short channel, char * value, short size) {
return 0; return 0;
} }
#if MODEL == MODEL_FOENIX_A2560K
unsigned short kbd_mo_color = 0x0000;
short cli_keycolor_set(short channel, const char * value) {
kbd_mo_color = (unsigned short)cli_eval_number(value);
kbdmo_set_led_matrix_fill(kbd_mo_color);
return 0;
}
short cli_keycolor_get(short channel, char * value, short size) {
sprintf(value, "%04x", kbd_mo_color);
return 0;
}
#endif
/* /*
* Initialize the settings tables * Initialize the settings tables
*/ */
@ -509,6 +526,9 @@ void cli_set_init() {
// cli_set_register("SOF", "SOF 1|0 -- Enable or disable the Start of Frame interrupt", cli_sof_set, cli_sof_get); // cli_set_register("SOF", "SOF 1|0 -- Enable or disable the Start of Frame interrupt", cli_sof_set, cli_sof_get);
cli_set_register("FONT", "FONT <path> -- set a font for the display", cli_font_set, cli_font_get); cli_set_register("FONT", "FONT <path> -- set a font for the display", cli_font_set, cli_font_get);
cli_set_register("KEYBOARD", "KEYBOARD <path> -- set the keyboard layout", cli_layout_set, cli_layout_get); cli_set_register("KEYBOARD", "KEYBOARD <path> -- set the keyboard layout", cli_layout_set, cli_layout_get);
#if MODEL == MODEL_FOENIX_A2560K
cli_set_register("KEYCOLOR", "KEYCOLOR 0x0RGB -- set the keyboard color", cli_keycolor_set, cli_keycolor_get);
#endif
cli_set_register("TIME", "TIME HH:MM:SS -- set the time in the realtime clock", cli_time_set, cli_time_get); cli_set_register("TIME", "TIME HH:MM:SS -- set the time in the realtime clock", cli_time_set, cli_time_get);
cli_set_register("VOLUME", "VOLUME <0 - 255> -- set the master volume", cli_volume_set, cli_volume_get); cli_set_register("VOLUME", "VOLUME <0 - 255> -- set the master volume", cli_volume_set, cli_volume_get);
} }

View file

@ -28,9 +28,9 @@
#include "uart_reg.h" #include "uart_reg.h"
#include "vicky_general.h" #include "vicky_general.h"
#define LPT_DATA_PORT ((volatile unsigned char *)0x00C02378) #define LPT_DATA_PORT ((volatile unsigned char *)0xFEC02378)
#define LPT_STAT_PORT ((volatile unsigned char *)0x00C02379) #define LPT_STAT_PORT ((volatile unsigned char *)0xFEC02379)
#define LPT_STAT_BUSY 0x80 #define LPT_STAT_BUSY 0x80
#define LPT_STAT_ACK 0x40 #define LPT_STAT_ACK 0x40
#define LPT_STAT_PO 0x20 #define LPT_STAT_PO 0x20
@ -38,7 +38,7 @@
#define LPT_STAT_ERROR 0x08 #define LPT_STAT_ERROR 0x08
#define LPT_STAT_IRQ 0x04 #define LPT_STAT_IRQ 0x04
#define LPT_CTRL_PORT ((volatile unsigned char *)0x00C0237A) #define LPT_CTRL_PORT ((volatile unsigned char *)0xFEC0237A)
#define LPT_CTRL_STROBE 0x01 #define LPT_CTRL_STROBE 0x01
#define LPT_CTRL_AL 0x02 #define LPT_CTRL_AL 0x02
#define LPT_CTRL_INIT 0x04 #define LPT_CTRL_INIT 0x04

View file

@ -12,10 +12,12 @@
#include "ring_buffer.h" #include "ring_buffer.h"
#include "gabe_reg.h" #include "gabe_reg.h"
#define KBD_MO_DATA ((volatile unsigned int *)0xFEC00040) /* Data register for the keyboard (scan codes will be here) */ #define KBD_MO_LEDMATRIX ((volatile unsigned short *)0xFEC01000) /* 6x16 array of 16-bit words: ARGB */
// #define KBD_MO_STAT ((volatile unsigned short *)0xFEC00042) /* Status register for the keyboard */ #define KBD_MO_LED_ROWS 6
#define KBD_MO_EMPTY 0x8000 /* Status flag that will be set if the keyboard buffer is empty */ #define KBD_MO_LED_COLUMNS 16
#define KBD_MO_FULL 0x4000 /* Status flag that will be set if the keyboard buffer is full */ #define KBD_MO_DATA ((volatile unsigned int *)0xFEC00040) /* Data register for the keyboard (scan codes will be here) */
#define KBD_MO_EMPTY 0x8000 /* Status flag that will be set if the keyboard buffer is empty */
#define KBD_MO_FULL 0x4000 /* Status flag that will be set if the keyboard buffer is full */
/* /*
* Modifier bit flags * Modifier bit flags
@ -180,6 +182,31 @@ static char g_us_sc_ctrl_shift[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0x78 - 0x7F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0x78 - 0x7F */
}; };
/**
* Set the color of the A2560K keyboard LED matrix
*
* @param row the number of the row to set (0 - 5)
* @param color the color for the LEDs: ARGB
*/
void kbdmo_set_led_matrix_row(unsigned char row, unsigned short color) {
int column;
for (column = 0; column < KBD_MO_LED_COLUMNS; column++) {
KBD_MO_LEDMATRIX[row * KBD_MO_LED_COLUMNS + column] = color;
}
}
/**
* Set all the LEDs to the same color
*
* @param color the color for the LEDs: ARGB
*/
void kbdmo_set_led_matrix_fill(unsigned short color) {
unsigned char row;
for (row = 0; row < KBD_MO_LED_ROWS; row++) {
kbdmo_set_led_matrix_row(row, color);
}
}
/* /*
* Make sure everything is removed from Mo's input buffer * Make sure everything is removed from Mo's input buffer
*/ */
@ -226,6 +253,9 @@ short kbdmo_init() {
int_disable(INT_KBD_A2560K); int_disable(INT_KBD_A2560K);
/* Turn off the LEDs */
kbdmo_set_led_matrix_fill(0);
/* Set up the ring buffers */ /* Set up the ring buffers */
rb_word_init(&g_kbdmo_control.sc_buf); /* Scan-code ring buffer is empty */ rb_word_init(&g_kbdmo_control.sc_buf); /* Scan-code ring buffer is empty */

View file

@ -18,6 +18,21 @@
*/ */
extern short kbdmo_init(); extern short kbdmo_init();
/**
* Set the color of the A2560K keyboard LED matrix
*
* @param row the number of the row to set (0 - 5)
* @param color the color for the LEDs: ARGB
*/
void kbdmo_set_led_matrix_row(unsigned char row, unsigned short color);
/**
* Set all the LEDs to the same color
*
* @param color the color for the LEDs: ARGB
*/
void kbdmo_set_led_matrix_fill(unsigned short color);
/* /*
* Check to see if a BREAK code has been pressed recently * Check to see if a BREAK code has been pressed recently
* If so, return 1 and reset the internal flag. * If so, return 1 and reset the internal flag.

File diff suppressed because it is too large Load diff

18388
src/mapfile

File diff suppressed because it is too large Load diff

View file

@ -154,84 +154,83 @@ void sid_test_external() {
unsigned int j; unsigned int j;
long jiffies; long jiffies;
// Attack = 2, Decay = 9 // Attack = 2, Decay = 9
*SID_EXT_L_V1_ATCK_DECY = 0x29; *SID_EXT_L_V1_ATCK_DECY = 0x29;
*SID_EXT_L_V2_ATCK_DECY = 0x29; *SID_EXT_L_V2_ATCK_DECY = 0x29;
*SID_EXT_L_V3_ATCK_DECY = 0x29; *SID_EXT_L_V3_ATCK_DECY = 0x29;
*SID_EXT_R_V1_ATCK_DECY = 0x29; *SID_EXT_R_V1_ATCK_DECY = 0x29;
*SID_EXT_R_V2_ATCK_DECY = 0x29; *SID_EXT_R_V2_ATCK_DECY = 0x29;
*SID_EXT_R_V3_ATCK_DECY = 0x29; *SID_EXT_R_V3_ATCK_DECY = 0x29;
// Sustain = 1, Release = 5 // Sustain = 1, Release = 5
*SID_EXT_L_V1_SSTN_RLSE = 0x1F; *SID_EXT_L_V1_SSTN_RLSE = 0x1F;
*SID_EXT_L_V2_SSTN_RLSE = 0x1F; *SID_EXT_L_V2_SSTN_RLSE = 0x1F;
*SID_EXT_L_V3_SSTN_RLSE = 0x1F; *SID_EXT_L_V3_SSTN_RLSE = 0x1F;
*SID_EXT_R_V1_SSTN_RLSE = 0x1F; *SID_EXT_R_V1_SSTN_RLSE = 0x1F;
*SID_EXT_R_V2_SSTN_RLSE = 0x1F; *SID_EXT_R_V2_SSTN_RLSE = 0x1F;
*SID_EXT_R_V3_SSTN_RLSE = 0x1F; *SID_EXT_R_V3_SSTN_RLSE = 0x1F;
*SID_EXT_L_MODE_VOL = 0x0F; *SID_EXT_L_MODE_VOL = 0x0F;
*SID_EXT_R_MODE_VOL = 0x0F; *SID_EXT_R_MODE_VOL = 0x0F;
// Set Voice 1 to F-3 // Set Voice 1 to F-3
*SID_EXT_L_V1_FREQ_LO = 96; *SID_EXT_L_V1_FREQ_LO = 96;
*SID_EXT_L_V1_FREQ_HI = 22; *SID_EXT_L_V1_FREQ_HI = 22;
*SID_EXT_R_V1_FREQ_LO = 96; *SID_EXT_R_V1_FREQ_LO = 96;
*SID_EXT_R_V1_FREQ_HI = 22; *SID_EXT_R_V1_FREQ_HI = 22;
*SID_EXT_L_V1_CTRL = 0x11; *SID_EXT_L_V1_CTRL = 0x11;
*SID_EXT_R_V1_CTRL = 0x11; *SID_EXT_R_V1_CTRL = 0x11;
jiffies = rtc_get_jiffies() + 3;
while (jiffies > rtc_get_jiffies());
*SID_EXT_L_V2_FREQ_LO = 49;
*SID_EXT_L_V2_FREQ_HI = 8;
*SID_EXT_R_V2_FREQ_LO = 49;
*SID_EXT_R_V2_FREQ_HI = 8;
*SID_EXT_L_V2_CTRL = 0x11;
*SID_EXT_R_V2_CTRL = 0x11;
jiffies = rtc_get_jiffies() + 3; jiffies = rtc_get_jiffies() + 3;
while (jiffies > rtc_get_jiffies()); while (jiffies > rtc_get_jiffies());
*SID_EXT_L_V2_FREQ_LO = 49; *SID_EXT_L_V3_FREQ_LO = 135;
*SID_EXT_L_V2_FREQ_HI = 8; *SID_EXT_L_V3_FREQ_HI = 33;
*SID_EXT_R_V2_FREQ_LO = 49; *SID_EXT_R_V3_FREQ_LO = 135;
*SID_EXT_R_V2_FREQ_HI = 8; *SID_EXT_R_V3_FREQ_HI = 33;
*SID_EXT_L_V2_CTRL = 0x11; *SID_EXT_L_V3_CTRL = 0x11;
*SID_EXT_R_V2_CTRL = 0x11; *SID_EXT_R_V3_CTRL = 0x11;
jiffies = rtc_get_jiffies() + 3;
while (jiffies > rtc_get_jiffies());
*SID_EXT_L_V3_FREQ_LO = 135;
*SID_EXT_L_V3_FREQ_HI = 33;
*SID_EXT_R_V3_FREQ_LO = 135;
*SID_EXT_R_V3_FREQ_HI = 33;
*SID_EXT_L_V3_CTRL = 0x11;
*SID_EXT_R_V3_CTRL = 0x11;
jiffies = rtc_get_jiffies() + 25; jiffies = rtc_get_jiffies() + 25;
while (jiffies > rtc_get_jiffies()); while (jiffies > rtc_get_jiffies());
*SID_EXT_L_V1_CTRL = 0x10; *SID_EXT_L_V1_CTRL = 0x10;
*SID_EXT_R_V1_CTRL = 0x10; *SID_EXT_R_V1_CTRL = 0x10;
jiffies = rtc_get_jiffies() + 3; jiffies = rtc_get_jiffies() + 3;
while (jiffies > rtc_get_jiffies()); while (jiffies > rtc_get_jiffies());
*SID_EXT_L_V2_CTRL = 0x10; *SID_EXT_L_V2_CTRL = 0x10;
*SID_EXT_R_V2_CTRL = 0x10; *SID_EXT_R_V2_CTRL = 0x10;
jiffies = rtc_get_jiffies() + 3; jiffies = rtc_get_jiffies() + 3;
while (jiffies > rtc_get_jiffies()); while (jiffies > rtc_get_jiffies());
*SID_EXT_L_V2_CTRL = 0x10; *SID_EXT_L_V2_CTRL = 0x10;
*SID_EXT_R_V2_CTRL = 0x10; *SID_EXT_R_V2_CTRL = 0x10;
jiffies = rtc_get_jiffies() + 10; jiffies = rtc_get_jiffies() + 10;
while (jiffies > rtc_get_jiffies()); while (jiffies > rtc_get_jiffies());
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
*SID_EXT_L_MODE_VOL = 15 - i; *SID_EXT_L_MODE_VOL = 15 - i;
*SID_EXT_R_MODE_VOL = 15 - i; *SID_EXT_R_MODE_VOL = 15 - i;
} }
*SID_EXT_L_MODE_VOL = 0;
*SID_EXT_R_MODE_VOL = 0;
*SID_EXT_L_MODE_VOL = 0;
*SID_EXT_R_MODE_VOL = 0;
} }