diff --git a/logicanalyzer/Als Garage Band - Alvin G 128x32 (PCA020A).sal b/logicanalyzer/Alvin G/Als Garage Band - Alvin G 128x32 (PCA020A).sal similarity index 100% rename from logicanalyzer/Als Garage Band - Alvin G 128x32 (PCA020A).sal rename to logicanalyzer/Alvin G/Als Garage Band - Alvin G 128x32 (PCA020A).sal diff --git a/logicanalyzer/Arcade Games/Island - redemption game.sal b/logicanalyzer/Arcade Games/Island - unknown 128x32.sal similarity index 100% rename from logicanalyzer/Arcade Games/Island - redemption game.sal rename to logicanalyzer/Arcade Games/Island - unknown 128x32.sal diff --git a/logicanalyzer/Airborne - Capcom 128x32.sal b/logicanalyzer/Capcom/Airborne - Capcom 128x32.sal similarity index 100% rename from logicanalyzer/Airborne - Capcom 128x32.sal rename to logicanalyzer/Capcom/Airborne - Capcom 128x32.sal diff --git a/logicanalyzer/Flipper Football - Capcom 256x64.sal b/logicanalyzer/Capcom/Flipper Football - Capcom 256x64.sal similarity index 100% rename from logicanalyzer/Flipper Football - Capcom 256x64.sal rename to logicanalyzer/Capcom/Flipper Football - Capcom 256x64.sal diff --git a/logicanalyzer/Stargate - Gottlieb 128x32.sal b/logicanalyzer/Gottlieb/Stargate - Gottlieb 128x32.sal similarity index 100% rename from logicanalyzer/Stargate - Gottlieb 128x32.sal rename to logicanalyzer/Gottlieb/Stargate - Gottlieb 128x32.sal diff --git a/logicanalyzer/World Challenge Soccer - Gottlieb 128x32.sal b/logicanalyzer/Gottlieb/World Challenge Soccer - Gottlieb 128x32.sal similarity index 100% rename from logicanalyzer/World Challenge Soccer - Gottlieb 128x32.sal rename to logicanalyzer/Gottlieb/World Challenge Soccer - Gottlieb 128x32.sal diff --git a/logicanalyzer/Baywatch - Sega 192x64.sal b/logicanalyzer/Sega & Data East/Baywatch - Sega 192x64.sal similarity index 100% rename from logicanalyzer/Baywatch - Sega 192x64.sal rename to logicanalyzer/Sega & Data East/Baywatch - Sega 192x64.sal diff --git a/logicanalyzer/Sega & Data East/Hook - Data East 128x16.sal b/logicanalyzer/Sega & Data East/Hook - Data East 128x16.sal new file mode 100644 index 0000000..1dbc3e7 Binary files /dev/null and b/logicanalyzer/Sega & Data East/Hook - Data East 128x16.sal differ diff --git a/logicanalyzer/Rocky and Bullwinkle - Data East 128x32.sal b/logicanalyzer/Sega & Data East/Rocky and Bullwinkle - Data East 128x32.sal similarity index 100% rename from logicanalyzer/Rocky and Bullwinkle - Data East 128x32.sal rename to logicanalyzer/Sega & Data East/Rocky and Bullwinkle - Data East 128x32.sal diff --git a/logicanalyzer/Sega & Data East/TMNT - Data East 128x16.sal b/logicanalyzer/Sega & Data East/TMNT - Data East 128x16.sal new file mode 100644 index 0000000..a0f39e8 Binary files /dev/null and b/logicanalyzer/Sega & Data East/TMNT - Data East 128x16.sal differ diff --git a/logicanalyzer/Ghostbusters - SPIKE 1 128x32.sal b/logicanalyzer/Stern/Ghostbusters - SPIKE 1 128x32.sal similarity index 100% rename from logicanalyzer/Ghostbusters - SPIKE 1 128x32.sal rename to logicanalyzer/Stern/Ghostbusters - SPIKE 1 128x32.sal diff --git a/logicanalyzer/Playboy - Whitestar 128x32.sal b/logicanalyzer/Stern/Playboy - Whitestar 128x32.sal similarity index 100% rename from logicanalyzer/Playboy - Whitestar 128x32.sal rename to logicanalyzer/Stern/Playboy - Whitestar 128x32.sal diff --git a/logicanalyzer/Walking Dead - SAM 128x32.sal b/logicanalyzer/Stern/Walking Dead - SAM 128x32.sal similarity index 100% rename from logicanalyzer/Walking Dead - SAM 128x32.sal rename to logicanalyzer/Stern/Walking Dead - SAM 128x32.sal diff --git a/src/dmd_interface.h b/src/dmd_interface.h index 4e60c5c..2bf49b7 100644 --- a/src/dmd_interface.h +++ b/src/dmd_interface.h @@ -11,6 +11,7 @@ #include "dmd_interface_alving.pio.h" #include "dmd_interface_capcom.pio.h" #include "dmd_interface_capcom_hd.pio.h" +#include "dmd_interface_de_x16.pio.h" #include "dmd_interface_desega.pio.h" #include "dmd_interface_gottlieb.pio.h" #include "dmd_interface_sega_hd.pio.h" diff --git a/src/dmd_interface_de_x16.pio b/src/dmd_interface_de_x16.pio new file mode 100644 index 0000000..1bfee53 --- /dev/null +++ b/src/dmd_interface_de_x16.pio @@ -0,0 +1,66 @@ +.define DE 7 +.define RDATA 6 +.define RCLK 5 +.define COLLAT 4 +.define DOTCLK 3 +.define SDATA 2 +.define SDATAEX 1 +.define FRAME_START_IRQ 5 + +.program dmd_reader_de_x16 + + ; set x, 31 ; load 31, 5 bits is max allowed (0b11111) + ; in x, 5 ; shift in 5 bits, isr is 31 now + ; set x, 1 ; load 1, 1 bit + ; in x, 1 ; shift in 1 bit, isr is 63 now + ; mov osr, isr ; copy 63 to osr + ; mov isr, null ; clear ISR and reset shift counter + + wait irq FRAME_START_IRQ + +.wrap_target + + set x, 31 + +lsb_msb_check: + nop[31] + nop[31] + jmp x-- lsb_msb_check[22] ; loop for ~22.25 µs + jmp pin reload_y_lsb_msb ; if DOTCLK is high, it means we will have LSB + MSB + + ; do stuff for no MSB + LSB case.. the question is what + in null 32 ; padding for row with only MSB ? + in null 32 ; padding for row with only MSB ? + +reload_y_lsb_msb: + set y, 1 +dotloop_lsb_msb: + set x, 31 +dotloop: + wait 1 gpio DOTCLK ; rising edge + in null 3 ; padding for 4bpp + in pins 2 ; read value of px 1 and 2 as they're sampled on the same DOTCLK edge + in null 3 ; padding for 4bpp + wait 0 gpio DOTCLK ; falling edge + jmp x-- dotloop + jmp y-- dotloop_lsb_msb + + wait 1 gpio COLLAT ; sync on COLLAT so our lsb_msb_check will work +.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_de_x16 +.wrap_target + +; Data East 128x16 frame detection +; When DE goes low, check for the next rising edge of DE. If RDATA is high at that point we have found the start. + +detect_loop: + wait 0 gpio DE + wait 1 gpio DE + jmp pin, frame_start ; Check if RDATA is high, otherwise back to beginning + jmp detect_loop + +frame_start: + irq FRAME_START_IRQ +.wrap diff --git a/src/dmdreader.cpp b/src/dmdreader.cpp index 76bccc3..1f0569b 100644 --- a/src/dmdreader.cpp +++ b/src/dmdreader.cpp @@ -324,7 +324,12 @@ DmdType detect_dmd() { (de < 4000) && (rdata > 115) && (rdata < 130)) { return DMD_WPC; - // Data East: DOTCLK: 640000 | DE: 5000 | RDATA: 80 + // Data East X16: DOTCLK: 121000 or 60544 | DE: 1955 | RDATA: 120 + } else if ((dotclk > 55000) && (dotclk < 125000) && (de > 1900) && + (de < 2000) && (rdata > 110) && (rdata < 120)) { + return DMD_DE_X16; + + // Data East X32: DOTCLK: 640000 | DE: 5000 | RDATA: 80 } else if ((dotclk > 630000) && (dotclk < 650000) && (de > 4930) && (de < 5070) && (rdata > 75) && (rdata < 85)) { return DMD_DESEGA; @@ -798,6 +803,30 @@ bool dmdreader_init(bool return_on_no_detection) { break; } + case DMD_DE_X16: { + uint input_pins[] = {DE, RDATA}; + gpio_set_inover(DOTCLK, GPIO_OVERRIDE_INVERT); // Needs to be inverted + // because it triggers on the falling edge in the original signal + dmdreader_programs_init(&dmd_reader_de_x16_program, + dmd_reader_de_x16_program_get_default_config, + &dmd_framedetect_de_x16_program, + dmd_framedetect_de_x16_program_get_default_config, + input_pins, 2, RDATA); + + source_width = 128; + source_height = 16; + source_bitsperpixel = 2; // Data East and Sega are 2bpp + target_bitsperpixel = 2; + // in DE-Sega, there's only one plane, + // containg one LSB row followed by one MSB row and so on + source_planesperframe = 1; + source_planehistoryperframe = 0; + // in DE-Sega each line is sent twice + source_lineoversampling = LINEOVERSAMPLING_2X; + source_mergeplanes = MERGEPLANES_NONE; + break; + } + case DMD_DESEGA: { uint input_pins[] = {DE}; dmdreader_programs_init(&dmd_reader_desega_program, diff --git a/src/dmdreader.h b/src/dmdreader.h index bee0400..a9f528b 100644 --- a/src/dmdreader.h +++ b/src/dmdreader.h @@ -22,6 +22,7 @@ enum DmdType : uint8_t { DMD_WHITESTAR, DMD_SPIKE1, DMD_SAM, + DMD_DE_X16, DMD_DESEGA, DMD_SEGA_HD, DMD_GOTTLIEB,