kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Test for increased pixel width during mode 7 calibration
rodzic
b82453d27f
commit
b7c2c737ba
289
src/rgb_to_fb.S
289
src/rgb_to_fb.S
|
@ -56,6 +56,8 @@
|
|||
.global line_timeout
|
||||
.global vsync_retry_count
|
||||
.global wait_for_pi_fieldsync
|
||||
.global scan_for_single_pixels_4bpp
|
||||
.global scan_for_single_pixels_12bpp
|
||||
|
||||
#ifdef USE_MULTICORE
|
||||
.global run_core
|
||||
|
@ -2568,9 +2570,287 @@ capture_line_half_even_3bpp_table:
|
|||
.word capture_line_half_even_4bpp
|
||||
.word capture_line_half_even_8bpp
|
||||
|
||||
// ======================================================================
|
||||
// Poll only keys (for when CPLD is unprogrammed)
|
||||
// ======================================================================
|
||||
|
||||
.macro COUNT_PIXELS_3BPP reg
|
||||
// enters with r4,r5,r6 already loaded
|
||||
mov r7, \reg, lsr #4 //pixel 1
|
||||
and r7, r7, #7
|
||||
|
||||
cmp r5, r6
|
||||
cmpeq r4, #0
|
||||
cmpeq r7, #0
|
||||
bne nocomp1\@
|
||||
|
||||
cmp r5, #0
|
||||
cmpne r5, r4
|
||||
cmpne r5, r7
|
||||
addne r2, r2, #1
|
||||
nocomp1\@:
|
||||
|
||||
and r4, \reg, #7 //pixel 2
|
||||
|
||||
cmp r6, r7
|
||||
cmpeq r4, #0
|
||||
cmpeq r5, #0
|
||||
bne nocomp2\@
|
||||
cmp r6, #0
|
||||
cmpne r6, r5
|
||||
cmpne r6, r4
|
||||
addne r2, r2, #1
|
||||
nocomp2\@:
|
||||
|
||||
mov r5, \reg, lsr #12 //pixel 3
|
||||
and r5, r5, #7
|
||||
|
||||
cmp r7, r4
|
||||
cmpeq r5, #0
|
||||
cmpeq r6, #0
|
||||
bne nocomp3\@
|
||||
cmp r7, #0
|
||||
cmpne r7, r6
|
||||
cmpne r7, r5
|
||||
addne r2, r2, #1
|
||||
nocomp3\@:
|
||||
|
||||
mov r6, \reg, lsr #8 //pixel 4
|
||||
and r6, r6, #7
|
||||
|
||||
cmp r4, r5
|
||||
cmpeq r6, #0
|
||||
cmpeq r7, #0
|
||||
bne nocomp4\@
|
||||
cmp r4, #0
|
||||
cmpne r4, r7
|
||||
cmpne r4, r6
|
||||
addne r2, r2, #1
|
||||
nocomp4\@:
|
||||
|
||||
mov r7, \reg, lsr #20 //pixel 5
|
||||
and r7, r7, #7
|
||||
|
||||
cmp r5, r6
|
||||
cmpeq r4, #0
|
||||
cmpeq r7, #0
|
||||
bne nocomp5\@
|
||||
cmp r5, #0
|
||||
cmpne r5, r4
|
||||
cmpne r5, r7
|
||||
addne r2, r2, #1
|
||||
nocomp5\@:
|
||||
|
||||
mov r4, \reg, lsr #16 //pixel 6
|
||||
and r4, r4, #7
|
||||
|
||||
cmp r6, r7
|
||||
cmpeq r4, #0
|
||||
cmpeq r5, #0
|
||||
bne nocomp6\@
|
||||
cmp r6, #0
|
||||
cmpne r6, r5
|
||||
cmpne r6, r4
|
||||
addne r2, r2, #1
|
||||
nocomp6\@:
|
||||
|
||||
mov r5, \reg, lsr #28 //pixel 7
|
||||
and r5, r5, #7
|
||||
|
||||
cmp r7, r4
|
||||
cmpeq r5, #0
|
||||
cmpeq r6, #0
|
||||
bne nocomp7\@
|
||||
cmp r7, #0
|
||||
cmpne r7, r6
|
||||
cmpne r7, r5
|
||||
addne r2, r2, #1
|
||||
nocomp7\@:
|
||||
|
||||
mov r6, \reg, lsr #24 //pixel 8
|
||||
and r6, r6, #7
|
||||
|
||||
cmp r4, r5
|
||||
cmpeq r6, #0
|
||||
cmpeq r7, #0
|
||||
bne nocomp8\@
|
||||
cmp r4, #0
|
||||
cmpne r4, r7
|
||||
cmpne r4, r6
|
||||
addne r2, r2, #1
|
||||
nocomp8\@:
|
||||
.endm
|
||||
|
||||
.macro COUNT_PIXELS_12BPP
|
||||
and r7, r8, r3 //pixel 1
|
||||
|
||||
cmp r5, r6
|
||||
cmpeq r4, r12
|
||||
cmpeq r7, r12
|
||||
tsteq r4, #0x8000
|
||||
tsteq r5, #0x8000
|
||||
tsteq r6, #0x8000
|
||||
tsteq r7, #0x8000
|
||||
bne nocomp1b\@
|
||||
cmp r5, r12
|
||||
cmpne r5, r4
|
||||
cmpne r5, r7
|
||||
addne r2, r2, #1
|
||||
nocomp1b\@:
|
||||
|
||||
mov r4, r8, lsr #16 //pixel 2
|
||||
|
||||
cmp r6, r7
|
||||
cmpeq r4, r12
|
||||
cmpeq r5, r12
|
||||
tsteq r4, #0x8000
|
||||
tsteq r5, #0x8000
|
||||
tsteq r6, #0x8000
|
||||
tsteq r7, #0x8000
|
||||
bne nocomp2b\@
|
||||
cmp r6, r12
|
||||
cmpne r6, r5
|
||||
cmpne r6, r4
|
||||
addne r2, r2, #1
|
||||
nocomp2b\@:
|
||||
|
||||
and r5, r9, r3 //pixel 3
|
||||
|
||||
cmp r7, r4
|
||||
cmpeq r5, r12
|
||||
cmpeq r6, r12
|
||||
tsteq r4, #0x8000
|
||||
tsteq r5, #0x8000
|
||||
tsteq r6, #0x8000
|
||||
tsteq r7, #0x8000
|
||||
bne nocomp3b\@
|
||||
cmp r7, r12
|
||||
cmpne r7, r6
|
||||
cmpne r7, r5
|
||||
addne r2, r2, #1
|
||||
nocomp3b\@:
|
||||
|
||||
mov r6, r9, lsr #16 //pixel 4
|
||||
|
||||
cmp r4, r5
|
||||
cmpeq r6, r12
|
||||
cmpeq r7, r12
|
||||
tsteq r4, #0x8000
|
||||
tsteq r5, #0x8000
|
||||
tsteq r6, #0x8000
|
||||
tsteq r7, #0x8000
|
||||
bne nocomp4b\@
|
||||
cmp r4, r12
|
||||
cmpne r4, r7
|
||||
cmpne r4, r6
|
||||
addne r2, r2, #1
|
||||
nocomp4b\@:
|
||||
|
||||
and r7, r10, r3 //pixel 5
|
||||
|
||||
cmp r5, r6
|
||||
cmpeq r4, r12
|
||||
cmpeq r7, r12
|
||||
tsteq r4, #0x8000
|
||||
tsteq r5, #0x8000
|
||||
tsteq r6, #0x8000
|
||||
tsteq r7, #0x8000
|
||||
bne nocomp5b\@
|
||||
cmp r5, r12
|
||||
cmpne r5, r4
|
||||
cmpne r5, r7
|
||||
addne r2, r2, #1
|
||||
nocomp5b\@:
|
||||
|
||||
mov r4, r10, lsr #16 //pixel 6
|
||||
|
||||
cmp r6, r7
|
||||
cmpeq r4, r12
|
||||
cmpeq r5, r12
|
||||
tsteq r4, #0x8000
|
||||
tsteq r5, #0x8000
|
||||
tsteq r6, #0x8000
|
||||
tsteq r7, #0x8000
|
||||
bne nocomp6b\@
|
||||
cmp r6, r12
|
||||
cmpne r6, r5
|
||||
cmpne r6, r4
|
||||
addne r2, r2, #1
|
||||
nocomp6b\@:
|
||||
|
||||
and r5, r11, r3 //pixel 7
|
||||
|
||||
cmp r7, r4
|
||||
cmpeq r5, r12
|
||||
cmpeq r6, r12
|
||||
tsteq r4, #0x8000
|
||||
tsteq r5, #0x8000
|
||||
tsteq r6, #0x8000
|
||||
tsteq r7, #0x8000
|
||||
bne nocomp7b\@
|
||||
cmp r7, r12
|
||||
cmpne r7, r6
|
||||
cmpne r7, r5
|
||||
addne r2, r2, #1
|
||||
nocomp7b\@:
|
||||
|
||||
mov r6, r11, lsr #16 //pixel 8
|
||||
|
||||
cmp r4, r5
|
||||
cmpeq r6, r12
|
||||
cmpeq r7, r12
|
||||
tsteq r4, #0x8000
|
||||
tsteq r5, #0x8000
|
||||
tsteq r6, #0x8000
|
||||
tsteq r7, #0x8000
|
||||
bne nocomp8b\@
|
||||
cmp r4, r12
|
||||
cmpne r4, r7
|
||||
cmpne r4, r6
|
||||
addne r2, r2, #1
|
||||
nocomp8b\@:
|
||||
|
||||
.endm
|
||||
|
||||
scan_for_single_pixels_12bpp:
|
||||
push {r2-r12, lr}
|
||||
// r0 = pointer to start of memory
|
||||
add r1, r0, r1
|
||||
// r1 = pointer to end of memory
|
||||
mov r2, #0
|
||||
mov r3, #0xff
|
||||
orr r3, r3, #0xff00
|
||||
ldr r12, [r0]
|
||||
and r12, r12, r3 //first pixel used as background colour reference
|
||||
mov r4, #0 //pixel 6
|
||||
mov r5, #0 //pixel 7
|
||||
mov r6, #0 //pixel 8
|
||||
scan_loop12:
|
||||
ldmia r0!, {r8-r11}
|
||||
COUNT_PIXELS_12BPP
|
||||
cmp r0, r1
|
||||
blt scan_loop12
|
||||
mov r0, r2
|
||||
//on exit, r0= number of single pixels detected
|
||||
pop {r2-r12, pc}
|
||||
|
||||
scan_for_single_pixels_4bpp:
|
||||
push {r2-r12, lr}
|
||||
// r0 = pointer to start of memory
|
||||
add r1, r0, r1
|
||||
// r1 = pointer to end of memory
|
||||
mov r2, #0
|
||||
mov r4, #0 //pixel 6
|
||||
mov r5, #0 //pixel 7
|
||||
mov r6, #0 //pixel 8
|
||||
scan_loop:
|
||||
ldmia r0!, {r8-r11}
|
||||
COUNT_PIXELS_3BPP r8
|
||||
COUNT_PIXELS_3BPP r9
|
||||
COUNT_PIXELS_3BPP r10
|
||||
COUNT_PIXELS_3BPP r11
|
||||
cmp r0, r1
|
||||
blt scan_loop
|
||||
mov r0, r2
|
||||
//on exit, r0= number of single pixels detected
|
||||
pop {r2-r12, pc}
|
||||
|
||||
wait_for_pi_fieldsync:
|
||||
push {r4-r12, lr}
|
||||
|
@ -2585,6 +2865,9 @@ wait_for_pi_loop:
|
|||
CLEAR_VSYNC
|
||||
pop {r4-r12, pc}
|
||||
|
||||
// ======================================================================
|
||||
// Poll only keys (for when CPLD is unprogrammed)
|
||||
// ======================================================================
|
||||
poll_keys_only:
|
||||
push {r4-r12, lr}
|
||||
ldr r12, [r0, #O_NCAPTURE]
|
||||
|
|
|
@ -97,6 +97,8 @@ void osd_update_palette();
|
|||
void delay_in_arm_cycles(int delay);
|
||||
|
||||
void wait_for_pi_fieldsync();
|
||||
int scan_for_single_pixels_4bpp(uint32_t * start, int length);
|
||||
int scan_for_single_pixels_12bpp(uint32_t * start, int length);
|
||||
|
||||
int benchmarkRAM(int address);
|
||||
|
||||
|
|
|
@ -1818,25 +1818,25 @@ int *diff_N_frames_by_sample(capture_info_t *capinfo, int n, int mode7, int elk)
|
|||
case 4:
|
||||
pix_mask = 0x00000007;
|
||||
osd_mask = 0x77777777;
|
||||
capinfo->ncapture = (capinfo->video_type != VIDEO_PROGRESSIVE) ? 2 : 1;
|
||||
break;
|
||||
case 8:
|
||||
pix_mask = 0x0000007F;
|
||||
osd_mask = 0x77777777;
|
||||
capinfo->ncapture = (capinfo->video_type != VIDEO_PROGRESSIVE) ? 2 : 1;
|
||||
break;
|
||||
case 16:
|
||||
default:
|
||||
pix_mask = 0x0000ffff;
|
||||
pix_mask = 0x00000fff;
|
||||
osd_mask = 0xffffffff;
|
||||
if (capinfo->video_type == VIDEO_INTERLACED && capinfo->detected_sync_type & SYNC_BIT_INTERLACED) {
|
||||
mask_BIT_OSD = ~BIT_OSD;
|
||||
}
|
||||
//if (capinfo->video_type == VIDEO_INTERLACED && capinfo->detected_sync_type & SYNC_BIT_INTERLACED) {
|
||||
// mask_BIT_OSD = ~BIT_OSD;
|
||||
//}
|
||||
capinfo->ncapture = 1;
|
||||
break;
|
||||
}
|
||||
//capinfo->video_type == VIDEO_INTERLACED && capinfo->detected_sync_type & SYNC_BIT_INTERLACED
|
||||
geometry_get_fb_params(capinfo); // required as calibration sets delay to 0 and the 2 high bits of that adjust the h offset
|
||||
// In mode 0..6, capture one field
|
||||
// In mode 7, capture two fields
|
||||
capinfo->ncapture = (capinfo->video_type != VIDEO_PROGRESSIVE) ? 2 : 1;
|
||||
|
||||
#ifdef INSTRUMENT_CAL
|
||||
t = _get_cycle_counter();
|
||||
|
@ -1868,9 +1868,9 @@ int *diff_N_frames_by_sample(capture_info_t *capinfo, int n, int mode7, int elk)
|
|||
t_capture += _get_cycle_counter() - t;
|
||||
t = _get_cycle_counter();
|
||||
#endif
|
||||
|
||||
// memcpy((void *)latest, (void *)(capinfo->fb + ((ret >> OFFSET_LAST_BUFFER) & 3) * capinfo->height * capinfo->pitch), capinfo->height * capinfo->pitch);
|
||||
|
||||
int single_pixel_count = 0;
|
||||
// Compare the frames
|
||||
uint32_t *fbp = (uint32_t *)(capinfo->fb + ((ret >> OFFSET_LAST_BUFFER) & 3) * capinfo->height * capinfo->pitch + capinfo->v_adjust * capinfo->pitch);
|
||||
uint32_t *lastp = (uint32_t *)last + capinfo->v_adjust * (capinfo->pitch >> 2);
|
||||
|
@ -1914,6 +1914,7 @@ int *diff_N_frames_by_sample(capture_info_t *capinfo, int n, int mode7, int elk)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (skip) {
|
||||
// For debugging it's useful to see if the lines being eliminated align with the cursor
|
||||
// for (int x = 0; x < capinfo->pitch; x += 4) {
|
||||
|
@ -1924,6 +1925,10 @@ int *diff_N_frames_by_sample(capture_info_t *capinfo, int n, int mode7, int elk)
|
|||
} else {
|
||||
switch (bpp) {
|
||||
case 4:
|
||||
{
|
||||
if (mode7) {
|
||||
single_pixel_count += scan_for_single_pixels_4bpp(fbp, capinfo->pitch);
|
||||
}
|
||||
for (int x = 0; x < capinfo->pitch; x += 4) {
|
||||
uint32_t d = osd_get_equivalence(*fbp++ & osd_mask) ^ osd_get_equivalence(*lastp++ & osd_mask);
|
||||
int index = (x << 1) % NUM_OFFSETS; //2 pixels per byte
|
||||
|
@ -1935,7 +1940,9 @@ int *diff_N_frames_by_sample(capture_info_t *capinfo, int n, int mode7, int elk)
|
|||
index = (index + 1) % NUM_OFFSETS;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
for (int x = 0; x < capinfo->pitch; x += 4) {
|
||||
uint32_t d = osd_get_equivalence(*fbp++ & osd_mask) ^ osd_get_equivalence(*lastp++ & osd_mask);
|
||||
|
@ -1951,18 +1958,27 @@ int *diff_N_frames_by_sample(capture_info_t *capinfo, int n, int mode7, int elk)
|
|||
break;
|
||||
case 16:
|
||||
default:
|
||||
for (int x = 0; x < capinfo->pitch; x += 4) {
|
||||
uint32_t d = *fbp++ ^ *lastp++;
|
||||
{
|
||||
if (mode7) {
|
||||
single_pixel_count += scan_for_single_pixels_12bpp(fbp, capinfo->pitch);
|
||||
}
|
||||
for (int x = 0; x < capinfo->pitch; x += 4) {
|
||||
uint32_t n = *fbp++;
|
||||
uint32_t o = *lastp++;
|
||||
uint32_t d = n ^ o;
|
||||
int index = (x >> 1) % NUM_OFFSETS; //half pixel per byte
|
||||
while (d) {
|
||||
if (d & pix_mask) {
|
||||
diff[index]++;
|
||||
if ((n & 0x80008000) == 0 && (o & 0x80008000) == 0) {
|
||||
while (d) {
|
||||
if (d & pix_mask) {
|
||||
diff[index]++;
|
||||
}
|
||||
d >>= 16;
|
||||
index = (index + 1) % NUM_OFFSETS;
|
||||
}
|
||||
d >>= 16;
|
||||
index = (index + 1) % NUM_OFFSETS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1980,6 +1996,17 @@ int *diff_N_frames_by_sample(capture_info_t *capinfo, int n, int mode7, int elk)
|
|||
// Mutate the result to correctly order the sample points:
|
||||
// Then the downstream algorithms don't have to worry
|
||||
|
||||
//log_info("count = %d, %d", mode7, single_pixel_count);
|
||||
if (mode7 && single_pixel_count == 0) { //generate fake diff errors if thick verticals detected
|
||||
diff[0] += 1000;
|
||||
diff[1] += 1000;
|
||||
diff[2] += 1000;
|
||||
diff[3] += 1000;
|
||||
diff[4] += 1000;
|
||||
diff[5] += 1000;
|
||||
}
|
||||
|
||||
|
||||
if (bpp == 4) {
|
||||
// A F C B E D => A B C D E F
|
||||
int f = diff[1];
|
||||
|
@ -2009,6 +2036,8 @@ int *diff_N_frames_by_sample(capture_info_t *capinfo, int n, int mode7, int elk)
|
|||
max[j] = diff[j];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#if 0
|
||||
for (int i = 0; i < NUM_OFFSETS; i++) {
|
||||
|
|
Ładowanie…
Reference in New Issue