From a4c4affd885c750d3dfcf07aca5b379e6ac18d77 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Mon, 1 Dec 2025 20:13:44 +0100 Subject: [PATCH 01/15] Add verified capcom autodetect values --- src/dmdreader.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index 840bb27..710f1b1 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -327,7 +327,14 @@ int detect_dmd() { } else if ((dotclk > 645000) && (dotclk < 669000) && (de > 5075) && (de < 5200) && (rdata > 75) && (rdata < 85)) { return DMD_WHITESTAR; + + // Capcom -> DOTCLK: 2084000 | DE: 16280 | RDATA: 510 + } else if ((dotclk > 2000000) && (dotclk < 2150000) && (de > 16000) && + (de < 16500) && (rdata > 490) && (rdata < 530)) { + return DMD_CAPCOM; } + + #endif return DMD_UNKNOWN; From 43149562b12434e6473ed9c26d16f8aba27016bc Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Mon, 1 Dec 2025 20:14:49 +0100 Subject: [PATCH 02/15] remove some spaces --- src/dmdreader.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index 710f1b1..6f07314 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -333,8 +333,6 @@ int detect_dmd() { (de < 16500) && (rdata > 490) && (rdata < 530)) { return DMD_CAPCOM; } - - #endif return DMD_UNKNOWN; From 8b2c31a007b2b52f4701a516230b3a5701295cff Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Mon, 1 Dec 2025 20:18:48 +0100 Subject: [PATCH 03/15] add capcom entry --- src/dmdreader.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index 6f07314..7125a0c 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -70,6 +70,7 @@ typedef struct __attribute__((__packed__)) block_pix_crc_header_t { #define DMD_SPIKE1 3 #define DMD_SAM 4 #define DMD_DESEGA 5 +#define DMD_CAPCOM 6 // Line oversampling #define LINEOVERSAMPLING_NONE 1 @@ -654,6 +655,36 @@ void dmdreader_init() { source_mergeplanes = MERGEPLANES_NONE; break; } + + case DMD_CAPCOM: { + dmd_pio = pio0; + offset = pio_add_program(dmd_pio, &dmd_reader_capcom_program); + dmd_sm = pio_claim_unused_sm(dmd_pio, true); + pio_sm_config dmd_config = + dmd_reader_desega_program_get_default_config(offset); + dmd_reader_program_init(dmd_pio, dmd_sm, offset, dmd_config); + + // The framedetect program just runs and detects the beginning of a new + // frame + uint input_pins[] = {DE}; + frame_pio = pio0; + offset = pio_add_program(frame_pio, &dmd_framedetect_capcom_program); + frame_sm = pio_claim_unused_sm(frame_pio, true); + pio_sm_config frame_config = + dmd_framedetect_desega_program_get_default_config(offset); + dmd_framedetect_program_init(frame_pio, frame_sm, offset, frame_config, + input_pins, 1, DE); + pio_sm_set_enabled(frame_pio, frame_sm, true); + + source_width = 128; + source_height = 32; + source_bitsperpixel = 2; + source_pixelsperbyte = 8 / source_bitsperpixel; + source_planesperframe = 1; + source_lineoversampling = LINEOVERSAMPLING_2X; + source_mergeplanes = MERGEPLANES_NONE; + break; + } } // Calculate display parameters From cd9df87d629b662712110e223ee0c9f1dc3716a4 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Mon, 1 Dec 2025 20:21:52 +0100 Subject: [PATCH 04/15] add header and take SAM as base --- src/dmd_interface.h | 1 + src/dmd_interface_capcom.pio | 40 ++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 src/dmd_interface_capcom.pio diff --git a/src/dmd_interface.h b/src/dmd_interface.h index cbd18cb..5d22633 100644 --- a/src/dmd_interface.h +++ b/src/dmd_interface.h @@ -11,6 +11,7 @@ #include "dmd_interface_desega.pio.h" #include "dmd_interface_whitestar.pio.h" #include "dmd_interface_wpc.pio.h" +#include "dmd_interface_capcom.pio.h" #include "dmdreader_pins.h" #include "hardware/gpio.h" #include "hardware/pio.h" diff --git a/src/dmd_interface_capcom.pio b/src/dmd_interface_capcom.pio new file mode 100644 index 0000000..b8240f7 --- /dev/null +++ b/src/dmd_interface_capcom.pio @@ -0,0 +1,40 @@ +.define DE 7 +.define RDATA 6 +.define RCLK 5 +.define COLLAT 4 +.define DOTCLK 3 +.define SDATA 2 +.define FRAME_START_IRQ 4 + +.program dmd_reader_capcom + ; initialize y with 16383, number of pixels (128x32x4) - 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, 4 ; shift in 4 bits, isr = 16383 + mov y, isr ; y = 16383 + +.wrap_target + mov x, y ; load number of pixels + mov isr, null ; reset shift counter + + irq clear FRAME_START_IRQ + wait irq FRAME_START_IRQ + +dotloop: + wait 0 gpio DOTCLK ; falling edge + in null, 3 ; left padding with 3 zeros + wait 1 gpio DOTCLK ; raising edge + in pins 1 ; read pin data + jmp x-- dotloop +.wrap + +; Frame detection program runs in parallel to the reader program and signals the start of a new frame using an IRQ. +.program dmd_framedetect_capcom +.wrap_target + wait 0 gpio RDATA + wait 1 gpio RDATA + irq FRAME_START_IRQ +.wrap From ae81c2399ca7f732c06384a9b8a320874b1802b4 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Mon, 1 Dec 2025 20:25:39 +0100 Subject: [PATCH 05/15] change naming to capcom --- src/dmdreader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index 7125a0c..a758ed7 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -661,7 +661,7 @@ void dmdreader_init() { offset = pio_add_program(dmd_pio, &dmd_reader_capcom_program); dmd_sm = pio_claim_unused_sm(dmd_pio, true); pio_sm_config dmd_config = - dmd_reader_desega_program_get_default_config(offset); + dmd_reader_capcom_program_get_default_config(offset); dmd_reader_program_init(dmd_pio, dmd_sm, offset, dmd_config); // The framedetect program just runs and detects the beginning of a new @@ -671,7 +671,7 @@ void dmdreader_init() { offset = pio_add_program(frame_pio, &dmd_framedetect_capcom_program); frame_sm = pio_claim_unused_sm(frame_pio, true); pio_sm_config frame_config = - dmd_framedetect_desega_program_get_default_config(offset); + dmd_framedetect_capcom_program_get_default_config(offset); dmd_framedetect_program_init(frame_pio, frame_sm, offset, frame_config, input_pins, 1, DE); pio_sm_set_enabled(frame_pio, frame_sm, true); From dcb5d3240e0e3df746601b8ce3e98fbc4ce10866 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Tue, 2 Dec 2025 18:01:28 +0100 Subject: [PATCH 06/15] start from WPC template, add framedetect --- src/dmd_interface_capcom.pio | 40 ++++++++++++++++++------------------ src/dmdreader.cpp | 8 ++++---- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/dmd_interface_capcom.pio b/src/dmd_interface_capcom.pio index b8240f7..4cacddb 100644 --- a/src/dmd_interface_capcom.pio +++ b/src/dmd_interface_capcom.pio @@ -4,31 +4,30 @@ .define COLLAT 4 .define DOTCLK 3 .define SDATA 2 -.define FRAME_START_IRQ 4 +.define PLANE_START_IRQ 4 .program dmd_reader_capcom - ; initialize y with 16383, number of pixels (128x32x4) - 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, 4 ; shift in 4 bits, isr = 16383 - mov y, isr ; y = 16383 + set x, 31 ; load 31, 5 bits is max allowed (0b11111) + in x, 5 ; shift in 5 bits, isr is 31 now + set x, 31 ; load 31, 5 bits is max allowed (0b11111) + in x, 5 ; shift in 5 bits, isr is 1023 now + set x, 3 ; load 3 + in x, 2 ; shift in 2 bits, isr is 4095 now (128x32 - 1) + mov y, isr ; copy 4095 to y .wrap_target - mov x, y ; load number of pixels - mov isr, null ; reset shift counter + mov x, y ; load number of pixels per plane (128x32 - 1) + mov isr, null ; reset shift counter - irq clear FRAME_START_IRQ - wait irq FRAME_START_IRQ + irq clear PLANE_START_IRQ + wait irq PLANE_START_IRQ -dotloop: - wait 0 gpio DOTCLK ; falling edge - in null, 3 ; left padding with 3 zeros - wait 1 gpio DOTCLK ; raising edge - in pins 1 ; read pin data - jmp x-- dotloop +plane_loop: + wait 0 gpio DOTCLK ; no DOTCLK period or faling edge of the previous + in null 1 ; left padding a 0 to the output as Capcom is 2bit/px + wait 1 gpio DOTCLK ; raising edge + in pins 1 ; read 1 bit pin data + jmp x-- plane_loop .wrap ; Frame detection program runs in parallel to the reader program and signals the start of a new frame using an IRQ. @@ -36,5 +35,6 @@ dotloop: .wrap_target wait 0 gpio RDATA wait 1 gpio RDATA - irq FRAME_START_IRQ + wait 0 gpio RCLK + irq PLANE_START_IRQ .wrap diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index a758ed7..ea11b28 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -673,16 +673,16 @@ void dmdreader_init() { pio_sm_config frame_config = dmd_framedetect_capcom_program_get_default_config(offset); dmd_framedetect_program_init(frame_pio, frame_sm, offset, frame_config, - input_pins, 1, DE); + input_pins, 1, 0); pio_sm_set_enabled(frame_pio, frame_sm, true); source_width = 128; source_height = 32; source_bitsperpixel = 2; source_pixelsperbyte = 8 / source_bitsperpixel; - source_planesperframe = 1; - source_lineoversampling = LINEOVERSAMPLING_2X; - source_mergeplanes = MERGEPLANES_NONE; + source_planesperframe = 3; + source_lineoversampling = LINEOVERSAMPLING_NONE; + source_mergeplanes = MERGEPLANES_ADD; break; } } From 197dd5016656c4eef1c889f0a5be803d5bd13f02 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Tue, 2 Dec 2025 19:08:59 +0100 Subject: [PATCH 07/15] first version of pio, configuration adjusted too --- src/dmd_interface_capcom.pio | 28 +++++++++++++++++----------- src/dmdreader.cpp | 2 +- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/dmd_interface_capcom.pio b/src/dmd_interface_capcom.pio index 4cacddb..6b22b6a 100644 --- a/src/dmd_interface_capcom.pio +++ b/src/dmd_interface_capcom.pio @@ -9,32 +9,38 @@ .program dmd_reader_capcom set x, 31 ; load 31, 5 bits is max allowed (0b11111) in x, 5 ; shift in 5 bits, isr is 31 now - set x, 31 ; load 31, 5 bits is max allowed (0b11111) - in x, 5 ; shift in 5 bits, isr is 1023 now set x, 3 ; load 3 - in x, 2 ; shift in 2 bits, isr is 4095 now (128x32 - 1) - mov y, isr ; copy 4095 to y + in x, 2 ; shift in 2 bits, isr is 127 now + mov osr, isr ; copy 127 to OSR + mov isr, null ; reset shift counter .wrap_target - mov x, y ; load number of pixels per plane (128x32 - 1) - mov isr, null ; reset shift counter + set y, 31 ; number of rows + mov x, osr ; load number of dots to skip (128) irq clear PLANE_START_IRQ wait irq PLANE_START_IRQ -plane_loop: +skip_loop: + wait 0 gpio DOTCLK ; no DOTCLK period or faling edge of the previous + wait 1 gpio DOTCLK + jmp x-- skip_loop ; skip 128 dots + + mov x, osr ; load number of pixels to read (128) +read_loop: wait 0 gpio DOTCLK ; no DOTCLK period or faling edge of the previous - in null 1 ; left padding a 0 to the output as Capcom is 2bit/px + in null 1 ; left padding a 0 to the output as WPC is 2bit/px wait 1 gpio DOTCLK ; raising edge in pins 1 ; read 1 bit pin data - jmp x-- plane_loop + jmp x-- read_loop + jmp y-- skip_loop .wrap ; Frame detection program runs in parallel to the reader program and signals the start of a new frame using an IRQ. .program dmd_framedetect_capcom .wrap_target - wait 0 gpio RDATA wait 1 gpio RDATA wait 0 gpio RCLK irq PLANE_START_IRQ -.wrap + wait 0 gpio RDATA +.wrap \ No newline at end of file diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index ea11b28..c0db3e8 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -666,7 +666,7 @@ void dmdreader_init() { // The framedetect program just runs and detects the beginning of a new // frame - uint input_pins[] = {DE}; + uint input_pins[] = {RDATA, RCLK}; frame_pio = pio0; offset = pio_add_program(frame_pio, &dmd_framedetect_capcom_program); frame_sm = pio_claim_unused_sm(frame_pio, true); From fe1280a12138dde8319f9dda9e83ff38af0e81b2 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Tue, 2 Dec 2025 19:09:29 +0100 Subject: [PATCH 08/15] we use RDATA and RCLK --- src/dmdreader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index c0db3e8..be978f3 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -673,7 +673,7 @@ void dmdreader_init() { pio_sm_config frame_config = dmd_framedetect_capcom_program_get_default_config(offset); dmd_framedetect_program_init(frame_pio, frame_sm, offset, frame_config, - input_pins, 1, 0); + input_pins, 2, 0); pio_sm_set_enabled(frame_pio, frame_sm, true); source_width = 128; From 01e1d5e1ea49e9cd73de13f2f6c24f5de87a69e2 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Tue, 2 Dec 2025 19:45:20 +0100 Subject: [PATCH 09/15] adjust the DOTCLK, was not multiplied by 2.. --- src/dmdreader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index be978f3..bb2f387 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -330,7 +330,7 @@ int detect_dmd() { return DMD_WHITESTAR; // Capcom -> DOTCLK: 2084000 | DE: 16280 | RDATA: 510 - } else if ((dotclk > 2000000) && (dotclk < 2150000) && (de > 16000) && + } else if ((dotclk > 4000000) && (dotclk < 4300000) && (de > 16000) && (de < 16500) && (rdata > 490) && (rdata < 530)) { return DMD_CAPCOM; } From 34cad760b6871c51f59e2b00ca51dbd4787a77bd Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Tue, 2 Dec 2025 19:47:58 +0100 Subject: [PATCH 10/15] adjust comment --- src/dmdreader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index bb2f387..8e1b361 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -329,7 +329,7 @@ int detect_dmd() { (de < 5200) && (rdata > 75) && (rdata < 85)) { return DMD_WHITESTAR; - // Capcom -> DOTCLK: 2084000 | DE: 16280 | RDATA: 510 + // Capcom -> DOTCLK: 4168000 | DE: 16280 | RDATA: 510 } else if ((dotclk > 4000000) && (dotclk < 4300000) && (de > 16000) && (de < 16500) && (rdata > 490) && (rdata < 530)) { return DMD_CAPCOM; From 0739180e675e2c6e617f3dc077dc68a7ae392511 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Tue, 2 Dec 2025 20:04:55 +0100 Subject: [PATCH 11/15] add outshift entry for reader program --- src/dmd_interface.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/dmd_interface.h b/src/dmd_interface.h index 5d22633..30ab188 100644 --- a/src/dmd_interface.h +++ b/src/dmd_interface.h @@ -36,6 +36,11 @@ void dmd_reader_program_init(PIO pio, uint sm, uint offset, pio_sm_config c) { 32 // autopush threshold ); + sm_config_set_out_shift(&c, + false, // shift-to-right = false + false, // no autopush + 0); + // We only send, so disable the TX FIFO to make the RX FIFO deeper. sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX); From 1143a21f887542d8ed80c10ffb747a0d941af37f Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Tue, 2 Dec 2025 20:08:47 +0100 Subject: [PATCH 12/15] comment out fifo join --- src/dmd_interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmd_interface.h b/src/dmd_interface.h index 30ab188..ffbe35a 100644 --- a/src/dmd_interface.h +++ b/src/dmd_interface.h @@ -42,7 +42,7 @@ void dmd_reader_program_init(PIO pio, uint sm, uint offset, pio_sm_config c) { 0); // We only send, so disable the TX FIFO to make the RX FIFO deeper. - sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX); + // sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX); // For the 200MHz clock sm_config_set_clkdiv(&c, 1.6f); From 655a9f0ac2d17004cb38f1f414557924e75be75c Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Tue, 2 Dec 2025 20:17:15 +0100 Subject: [PATCH 13/15] add back fifo join --- src/dmd_interface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmd_interface.h b/src/dmd_interface.h index ffbe35a..30ab188 100644 --- a/src/dmd_interface.h +++ b/src/dmd_interface.h @@ -42,7 +42,7 @@ void dmd_reader_program_init(PIO pio, uint sm, uint offset, pio_sm_config c) { 0); // We only send, so disable the TX FIFO to make the RX FIFO deeper. - // sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX); + sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX); // For the 200MHz clock sm_config_set_clkdiv(&c, 1.6f); From eec34c2d6a184b41657b9f9419674106edd10ec8 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Tue, 2 Dec 2025 20:42:05 +0100 Subject: [PATCH 14/15] adjust pio, change back dmd_interface to previous state --- src/dmd_interface.h | 5 ----- src/dmd_interface_capcom.pio | 13 +++++++------ 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/dmd_interface.h b/src/dmd_interface.h index 30ab188..5d22633 100644 --- a/src/dmd_interface.h +++ b/src/dmd_interface.h @@ -36,11 +36,6 @@ void dmd_reader_program_init(PIO pio, uint sm, uint offset, pio_sm_config c) { 32 // autopush threshold ); - sm_config_set_out_shift(&c, - false, // shift-to-right = false - false, // no autopush - 0); - // We only send, so disable the TX FIFO to make the RX FIFO deeper. sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX); diff --git a/src/dmd_interface_capcom.pio b/src/dmd_interface_capcom.pio index 6b22b6a..71a1a9d 100644 --- a/src/dmd_interface_capcom.pio +++ b/src/dmd_interface_capcom.pio @@ -16,24 +16,25 @@ .wrap_target set y, 31 ; number of rows - mov x, osr ; load number of dots to skip (128) irq clear PLANE_START_IRQ wait irq PLANE_START_IRQ -skip_loop: +row_loop: + mov x, osr ; load number of dots to skip (128) +dot_skip_loop: wait 0 gpio DOTCLK ; no DOTCLK period or faling edge of the previous wait 1 gpio DOTCLK - jmp x-- skip_loop ; skip 128 dots + jmp x-- dot_skip_loop ; skip 128 dots mov x, osr ; load number of pixels to read (128) -read_loop: +dot_read_loop: wait 0 gpio DOTCLK ; no DOTCLK period or faling edge of the previous in null 1 ; left padding a 0 to the output as WPC is 2bit/px wait 1 gpio DOTCLK ; raising edge in pins 1 ; read 1 bit pin data - jmp x-- read_loop - jmp y-- skip_loop + jmp x-- dot_read_loop + jmp y-- row_loop .wrap ; Frame detection program runs in parallel to the reader program and signals the start of a new frame using an IRQ. From 5d5265dd4e0bcb5968fc9bcf9ad7ab01aecba038 Mon Sep 17 00:00:00 2001 From: Jan Vos Date: Tue, 2 Dec 2025 20:55:34 +0100 Subject: [PATCH 15/15] 4 planes instead of 3 --- src/dmdreader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index 8e1b361..f868453 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -680,7 +680,7 @@ void dmdreader_init() { source_height = 32; source_bitsperpixel = 2; source_pixelsperbyte = 8 / source_bitsperpixel; - source_planesperframe = 3; + source_planesperframe = 4; source_lineoversampling = LINEOVERSAMPLING_NONE; source_mergeplanes = MERGEPLANES_ADD; break;