@@ -76,6 +76,7 @@ enum DmdType {
7676 DMD_DESEGA,
7777 DMD_SEGA_HD,
7878 DMD_GOTTLIEB,
79+ DMD_ALVING,
7980 // CAPCOM need to be the last entries:
8081 DMD_CAPCOM,
8182 DMD_CAPCOM_HD,
@@ -375,6 +376,11 @@ DmdType detect_dmd() {
375376 (de < 13100 ) && (rdata > 370 ) && (rdata < 410 )) {
376377 return DMD_GOTTLIEB;
377378
379+ // Alvin G -> DOTCLK: 1192000 | DE: 9400 | RDATA: 73
380+ } else if ((dotclk > 1150000 ) && (dotclk < 1250000 ) && (de > 9200 ) &&
381+ (de < 9600 ) && (rdata > 65 ) && (rdata < 80 )) {
382+ return DMD_ALVING;
383+
378384 // Capcom -> DOTCLK: 4168000 | DE: 16280 | RDATA: 510
379385 } else if ((dotclk > 4000000 ) && (dotclk < 4300000 ) && (de > 16000 ) &&
380386 (de < 16500 ) && (rdata > 490 ) && (rdata < 530 )) {
@@ -628,17 +634,32 @@ void dmd_dma_handler() {
628634 src4 = src3 + source_dwordsperline;
629635 uint32_t v;
630636
631- for (int l = 0 ; l < source_height; l++) {
632- for (int w = 0 ; w < source_dwordsperline; w++) {
633- // On SAM line order is really messed up :-(
634- v = src4[w] * 8 + src3[w] * 1 + src2[w] * 4 + src1[w] * 2 ;
635- dst[w] = v;
637+ if (dmd_type == DMD_SAM) {
638+ for (int l = 0 ; l < source_height; l++) {
639+ for (int w = 0 ; w < source_dwordsperline; w++) {
640+ // On SAM line order is really messed up :-(
641+ v = src4[w] * 8 + src3[w] * 1 + src2[w] * 4 + src1[w] * 2 ;
642+ dst[w] = v;
643+ }
644+ src1 += source_dwordsperline * 4 ; // source skips 4 lines forward
645+ src2 += source_dwordsperline * 4 ;
646+ src3 += source_dwordsperline * 4 ;
647+ src4 += source_dwordsperline * 4 ;
648+ dst += source_dwordsperline; // destination skips only one line
649+ }
650+ } else { // Alvin G
651+ for (int l = 0 ; l < source_height; l++) {
652+ for (int w = 0 ; w < source_dwordsperline; w++) {
653+ // First row captured counts as intensity level 3 <--
654+ v = src4[w] * 4 + src3[w] * 4 + src2[w] * 4 + src1[w] * 3 ;
655+ dst[w] = v;
656+ }
657+ src1 += source_dwordsperline * 4 ; // source skips 4 lines forward
658+ src2 += source_dwordsperline * 4 ;
659+ src3 += source_dwordsperline * 4 ;
660+ src4 += source_dwordsperline * 4 ;
661+ dst += source_dwordsperline; // destination skips only one line
636662 }
637- src1 += source_dwordsperline * 4 ; // source skips 4 lines forward
638- src2 += source_dwordsperline * 4 ;
639- src3 += source_dwordsperline * 4 ;
640- src4 += source_dwordsperline * 4 ;
641- dst += source_dwordsperline; // destination skips only one line
642663 }
643664 }
644665 }
@@ -849,13 +870,32 @@ void dmdreader_init() {
849870 break ;
850871 }
851872
873+ case DMD_ALVING: {
874+ uint input_pins[] = {RDATA, RCLK, COLLAT};
875+ dmdreader_programs_init (
876+ &dmd_reader_alving_program,
877+ dmd_reader_alving_program_get_default_config,
878+ &dmd_framedetect_alving_program,
879+ dmd_framedetect_alving_program_get_default_config, input_pins, 2 , 0 );
880+
881+ source_width = 128 ;
882+ source_height = 32 ;
883+ source_bitsperpixel = 4 ;
884+ target_bitsperpixel = 4 ;
885+ source_planesperframe = 1 ; // in Alvin G there is one plane
886+ // with 4x line oversampling
887+ source_lineoversampling = LINEOVERSAMPLING_4X;
888+ source_mergeplanes = MERGEPLANES_NONE;
889+ break ;
890+ }
891+
852892 case DMD_CAPCOM: {
853893 uint input_pins[] = {RDATA, RCLK};
854894 dmdreader_programs_init (&dmd_reader_capcom_program,
855895 dmd_reader_capcom_program_get_default_config,
856896 &dmd_framedetect_capcom_program,
857897 dmd_framedetect_capcom_program_get_default_config,
858- input_pins, 2 , 0 );
898+ input_pins, 3 , 0 );
859899
860900 source_width = 128 ;
861901 source_height = 32 ;
0 commit comments