|
From: kosmirror <kos...@us...> - 2025-08-24 04:29:39
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "A pseudo Operating System for the Dreamcast.".
The branch, master has been updated
via 88b9a64def662c8648d3dd8a810d5e443a767d49 (commit)
via 5139543bd089db771a9fb9d14fdc9c14047efa96 (commit)
from a36363f0469e8f95c275338d91dca59f6563b9d4 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 88b9a64def662c8648d3dd8a810d5e443a767d49
Author: QuzarDC <qu...@co...>
Date: Thu Aug 14 14:12:37 2025 -0400
vmu: Only send beep/clock/lcd commands to official VMUs
These functions are only supported on official VMUs and sending
them to 3rd party devices/VMS can cause hardware errors. To avoid
these we short-circuit if the device wouldn't support the function.
commit 5139543bd089db771a9fb9d14fdc9c14047efa96
Author: QuzarDC <qu...@co...>
Date: Thu Aug 14 13:23:14 2025 -0400
vmu: Detect VMS vs VMU and don't poll VMS units for buttons.
The VMU driver runs three independent devices that coexist in
the VMU: memcard, clock, and lcd. The polling for button presses
is something that is part of the clock device, which is not available
in VMS units which only have the memcard. Since button polling is
done for all devices at the driver level, enabling it would cause
any device that was run by the driver to get sent polls for buttons
even if they do not have buttons/clock.
The change here filters those out to prevent erroring out the device.
Unfortunately merely testing the well-documented `functions` value
that the device reports is not sufficient as most (possibly all) 3rd
party VMS devices just report that they have LCD/Clock even though
they don't. To make it more useful I test against one of the function
data codes that was gathered by experimentation and seems to always
be the same on official units and never present on unofficial ones.
-----------------------------------------------------------------------
Summary of changes:
kernel/arch/dreamcast/hardware/maple/vmu.c | 45 ++++++++++++++++++++++++++--
kernel/arch/dreamcast/include/dc/maple/vmu.h | 7 +++++
2 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/kernel/arch/dreamcast/hardware/maple/vmu.c b/kernel/arch/dreamcast/hardware/maple/vmu.c
index d95a392c..922f1754 100644
--- a/kernel/arch/dreamcast/hardware/maple/vmu.c
+++ b/kernel/arch/dreamcast/hardware/maple/vmu.c
@@ -29,6 +29,30 @@
#define VMU_BLOCK_WRITE_RETRY_TIME 100 /* time to sleep until retrying a failed write */
+/* This is the value that official VMUs report for function_data[0]. Have not
+ found any official ones that report a different value nor any third party
+ that report it.
+*/
+static const uint32_t vmu_official_function_data0 = 0x403f7e7e;
+
+/* Distinguish between VMU (only official, with screen/clock/buttons)
+ and VMS (memcard only). */
+static bool vmu_is_vmu(const maple_device_t *dev) {
+ /* If it doesn't have the known magic number, it's no official VMU. */
+ if(dev->info.function_data[0] != vmu_official_function_data0)
+ return false;
+
+ /* Give a secondary test to confirm that it's presenting all three
+ components of an official VMU. This alone is not sufficient to test
+ for VMU vs VMS though as most (all?) 3rd party VMS report that they
+ have the other functions.
+ */
+ if(dev->info.functions & (MAPLE_FUNC_MEMCARD | MAPLE_FUNC_LCD | MAPLE_FUNC_CLOCK))
+ return true;
+
+ return false;
+}
+
/* VMU's raw condition data: 0 = PRESSED, 1 = RELEASED */
typedef struct vmu_cond {
uint8_t raw_buttons;
@@ -127,8 +151,9 @@ static void vmu_poll_reply(maple_state_t *st, maple_frame_t *frm) {
static int vmu_poll(maple_device_t *dev) {
uint32_t *send_buf;
- /* Only query for button input on the front VMU of each controller. */
- if(dev->unit == 1) {
+ /* Only query for button input on the front VMU of each controller
+ AND the device actually has the functionality. */
+ if((dev->unit == 1) && vmu_is_vmu(dev)) {
if(maple_frame_lock(&dev->frame) < 0)
return 0;
@@ -292,6 +317,10 @@ int vmu_beep_raw(maple_device_t *dev, uint32_t beep) {
assert(dev);
+ /* Only send a beep if this is a real VMU */
+ if(!vmu_is_vmu(dev))
+ return MAPLE_EINVALID;
+
/* Lock the frame */
if(maple_frame_lock(&dev->frame) < 0)
return MAPLE_EAGAIN;
@@ -326,6 +355,10 @@ int vmu_draw_lcd(maple_device_t *dev, const void *bitmap) {
assert(dev != NULL);
+ /* Only try to draw to screen if this is a real VMU */
+ if(!vmu_is_vmu(dev))
+ return MAPLE_EINVALID;
+
/* Lock the frame */
if(maple_frame_lock(&dev->frame) < 0)
return MAPLE_EAGAIN;
@@ -618,6 +651,10 @@ int vmu_set_datetime(maple_device_t *dev, time_t unix) {
assert(dev);
+ /* Only set datetime if this is a real VMU */
+ if(!vmu_is_vmu(dev))
+ return MAPLE_EINVALID;
+
btime = localtime(&unix);
assert(btime); /* A failure here means an invalid unix timestamp was given. */
@@ -668,6 +705,10 @@ int vmu_get_datetime(maple_device_t *dev, time_t *unix) {
assert(dev);
+ /* Only get datetime if this is a real VMU */
+ if(!vmu_is_vmu(dev))
+ return MAPLE_EINVALID;
+
/* Lock the frame */
if(maple_frame_lock(&dev->frame) < 0)
return MAPLE_EAGAIN;
diff --git a/kernel/arch/dreamcast/include/dc/maple/vmu.h b/kernel/arch/dreamcast/include/dc/maple/vmu.h
index 1735d1d3..5ade196b 100644
--- a/kernel/arch/dreamcast/include/dc/maple/vmu.h
+++ b/kernel/arch/dreamcast/include/dc/maple/vmu.h
@@ -253,6 +253,7 @@ int vmu_get_icon_shape(maple_device_t *dev, uint8_t *icon_shape);
\retval MAPLE_EOK On success.
\retval MAPLE_EAGAIN If the command couldn't be sent. Try again later.
+ \retval MAPLE_EINVALID The device does not support this functionality (VMS).
\sa vmu_draw_lcd_rotated, vmu_draw_lcd_xbm, vmu_set_icon
*/
@@ -274,6 +275,7 @@ int vmu_draw_lcd(maple_device_t *dev, const void *bitmap);
\param bitmap The bitmap to show.
\retval MAPLE_EOK On success.
\retval MAPLE_EAGAIN If the command couldn't be sent. Try again later.
+ \retval MAPLE_EINVALID The device does not support this functionality (VMS).
\sa vmu_draw_lcd, vmu_draw_lcd_xbm, vmu_set_icon
*/
@@ -290,6 +292,7 @@ int vmu_draw_lcd_rotated(maple_device_t *dev, const void *bitmap);
\retval MAPLE_EOK On success.
\retval MAPLE_EAGAIN If the command couldn't be sent. Try again later.
+ \retval MAPLE_EINVALID The device does not support this functionality (VMS).
\sa vmu_draw_lcd, vmu_set_icon
*/
@@ -410,6 +413,7 @@ int vmu_block_write(maple_device_t *dev, uint16_t blocknum, const uint8_t *buffe
\retval MAPLE_EOK On success.
\retval MAPLE_EAGAIN If the command couldn't be sent. Try again later.
+ \retval MAPLE_EINVALID The device does not support this functionality (VMS).
\sa vmu_beep_waveform
*/
@@ -471,6 +475,7 @@ int vmu_beep_raw(maple_device_t *dev, uint32_t beep);
\retval MAPLE_EOK On success.
\retval MAPLE_EAGAIN If the command couldn't be sent. Try again later.
+ \retval MAPLE_EINVALID The device does not support this functionality (VMS).
*/
int vmu_beep_waveform(maple_device_t *dev, uint8_t period1, uint8_t duty_cycle1, uint8_t period2, uint8_t duty_cycle2);
@@ -493,6 +498,7 @@ int vmu_beep_waveform(maple_device_t *dev, uint8_t period1, uint8_t duty_cycle1,
\retval MAPLE_EOK On success.
\retval MAPLE_ETIMEOUT If the command timed out while blocking.
\retval MAPLE_EFAIL On errors other than timeout.
+ \retval MAPLE_EINVALID The device does not support this functionality (VMS).
\sa vmu_get_datetime
*/
@@ -513,6 +519,7 @@ int vmu_set_datetime(maple_device_t *dev, time_t unix);
\retval MAPLE_EOK On success.
\retval MAPLE_ETIMEOUT If the command timed out while blocking.
\retval MAPLE_EFAIL On errors other than timeout.
+ \retval MAPLE_EINVALID The device does not support this functionality (VMS).
\sa vmu_set_datetime
*/
hooks/post-receive
--
A pseudo Operating System for the Dreamcast.
|