From 1b7b87bbb3609bbcb9cae944f72406a797f25b5a Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Wed, 5 Nov 2025 20:28:11 +0100 Subject: [PATCH 1/5] Take basics of whitestar, use previously done framedetect --- src/dmd_interface_desega.pio | 52 +++++++++++++----------------------- 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/src/dmd_interface_desega.pio b/src/dmd_interface_desega.pio index f9fb416a..d358c88e 100644 --- a/src/dmd_interface_desega.pio +++ b/src/dmd_interface_desega.pio @@ -4,66 +4,50 @@ .define COLLAT 4 .define DOTCLK 3 .define SDATA 2 +.define FRAME_START 4 .program dmd_reader_desega - -; Send using an external clock on the SPI interface - - ; initialize y with 4096 = number of pixels (128x32) - set x, 1 - in x, 1 - in null, 13 - mov y, isr + ; initialize y with 8191, number of pixels ((128 x LSB + 128 x MSB) x 32) - 1 because counting starts at 0. + set x, 31 ; x = 31 (max 5-bit value) + in x, 5 ; shift in 5 bits, isr = 31 + set x, 31 ; x = 31 + in x, 5 ; shift in 5 bits, isr = 1023 + set x, 15 ; x = 15 + in x, 3 ; shift in 3 bits, isr = 8191 + in null, 3 ; pad with 3 zeros + mov y, isr ; y = 8191 .wrap_target mov x, y ; load number of pixels mov isr, null ; reset shift counter - irq clear 4 - wait irq 4 + irq clear FRAME_START + wait irq FRAME_START - -; this is the loop for the most significant bit -dotloop1: +dotloop: wait 0 gpio DOTCLK ; falling edge - wait 1 gpio DOTCLK ; raising edge - in pins 1 ; read pin data - in null 1 ; right padding - jmp x-- dotloop1 - - mov x, y ; load number of pixels - mov isr, null ; reset shift counter - -; There's an empty line between LSB and HSB plane - wait 0 gpio RCLK - wait 1 gpio RCLK - -; this is the loop for the least significant bit -; in this loop, the bit value is multipled by 2 by shifting it one bit -dotloop2: - wait 0 gpio DOTCLK ; falling edge - wait 1 gpio DOTCLK ; raising edge in null 1 ; left padding + wait 1 gpio DOTCLK ; raising edge in pins 1 ; read pin data - jmp x-- dotloop2 - + jmp x-- dotloop +; There's an empty row with 256 dots at the end of a frame. +; It is ignored because we already read the specified amount of dots and now wait for a new frame. .wrap .program dmd_framedetect_desega - .wrap_target ; Data East/Sega frame start detection ; ~7.86µs is the longest state in which DE can be low without it being a new frame ; Each nop [31] = 32 cycles = 256 ns @125 MHz ; We go with 10 µs to be safe and confirm the start of a new frame, which is 256ns * 39 = 9.98 µs + wait_low: wait 0 gpio DE ; Wait for DE to go low - set x, 20 ; Use x as storage for 20 iterations delay_loop: From 025ea57ffeab81260aaa03cb6b4a35e1023ca349 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Wed, 5 Nov 2025 20:44:37 +0100 Subject: [PATCH 2/5] remove rclk because unused, fix other irq --- src/dmd_interface_desega.pio | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/dmd_interface_desega.pio b/src/dmd_interface_desega.pio index d358c88e..fc0c6fed 100644 --- a/src/dmd_interface_desega.pio +++ b/src/dmd_interface_desega.pio @@ -43,7 +43,6 @@ dotloop: ; Data East/Sega frame start detection ; ~7.86µs is the longest state in which DE can be low without it being a new frame -; Each nop [31] = 32 cycles = 256 ns @125 MHz ; We go with 10 µs to be safe and confirm the start of a new frame, which is 256ns * 39 = 9.98 µs wait_low: @@ -57,7 +56,7 @@ delay_loop: ; After ~10 µs, check if still low jmp pin, wait_low ; If pin went high early → back to wait_low - irq 4 ; Pin remained low long enough → trigger IRQ + irq FRAME_START ; Pin remained low long enough → frame started wait 1 gpio DE ; Wait again for it to go high before restarting cycle jmp wait_low ; went high, time to go back to wait_low @@ -73,11 +72,9 @@ static inline void dmd_reader_desega_program_init(PIO pio, uint sm, uint offset) sm_config_set_in_pins(&c, 2); // SDATA // Set the pin direction at the PIO - pio_sm_set_consecutive_pindirs(pio, sm, 5, 1, false); // RCLK pio_sm_set_consecutive_pindirs(pio, sm, 2, 2, false); // SDATA, DOTCLK // Connect these GPIOs to this PIO block - pio_gpio_init(pio, 5); // RCLK pio_gpio_init(pio, 3); // DOTCLK pio_gpio_init(pio, 2); // SDATA From 4ca17039d1d1939cbfb7c82e415b7c961eff1f49 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Wed, 5 Nov 2025 20:57:35 +0100 Subject: [PATCH 3/5] Adjust DE-Sega values to reflect whitestar as it's the same frame construction --- src/dmd_reader.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/dmd_reader.c b/src/dmd_reader.c index c66b09bd..5c1f1e31 100644 --- a/src/dmd_reader.c +++ b/src/dmd_reader.c @@ -650,12 +650,13 @@ bool init() { lcd_width = 128; lcd_height = 32; - lcd_bitsperpixel = 2; // Data East/ Sega is 2bpp + lcd_bitsperpixel = 2; // DE-Sega is 2bpp lcd_pixelsperbyte = 8 / lcd_bitsperpixel; - lcd_planesperframe = 2; // in DE/Sega, there's a MSB and a LSB plane + lcd_planesperframe = 1; // in DE-Sega, there's only one plane, containg + // one LSB row followed by one MSB row and so on lcd_lineoversampling = - LINEOVERSAMPLING_2X; // in DE/Sega each line is sent twice - lcd_mergeplanes = MERGEPLANES_ADDSHIFT; // required for correct 2bpp merge + LINEOVERSAMPLING_2X; // in DE-Sega each line is sent twice + lcd_mergeplanes = MERGEPLANES_NONE; // required for correct 2bpp merge } else { printf("Unknown DMD type, aborting\n"); return false; From 76ef9b9fe03a5fb1baf58717723d6c907cca4203 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Wed, 5 Nov 2025 20:59:39 +0100 Subject: [PATCH 4/5] comment does not reflect DE/Sega logic --- src/dmd_interface_desega.pio | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/dmd_interface_desega.pio b/src/dmd_interface_desega.pio index fc0c6fed..2439909e 100644 --- a/src/dmd_interface_desega.pio +++ b/src/dmd_interface_desega.pio @@ -33,8 +33,6 @@ dotloop: in pins 1 ; read pin data jmp x-- dotloop -; There's an empty row with 256 dots at the end of a frame. -; It is ignored because we already read the specified amount of dots and now wait for a new frame. .wrap From 0af95a24a8b326504a1f928459be836e13c54717 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Wed, 5 Nov 2025 21:27:02 +0100 Subject: [PATCH 5/5] fixed DE-Sega manufacturer detection --- src/dmd_reader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dmd_reader.c b/src/dmd_reader.c index 5c1f1e31..65d9fdd0 100644 --- a/src/dmd_reader.c +++ b/src/dmd_reader.c @@ -376,8 +376,8 @@ int detect_dmd() { spi_notify_onoff(DMD_SAM); return DMD_SAM; - } else if ((dotclk > 640000) && (dotclk < 700000) && (de > 5000) && - (de < 5300) && (rdata > 3800) && (rdata < 4000)) { + } else if ((dotclk > 600000) && (dotclk < 680000) && (de > 4800) && + (de < 5200) && (rdata > 2500) && (rdata < 2650)) { printf("Data East/Sega detected\n"); spi_notify_onoff(DMD_DESEGA); return DMD_DESEGA;