Test for increased pixel width during mode 7 calibration

pull/180/head
IanSB 2021-01-30 19:47:01 +00:00
rodzic b82453d27f
commit b7c2c737ba
3 zmienionych plików z 332 dodań i 18 usunięć

Wyświetl plik

@ -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]

Wyświetl plik

@ -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);

Wyświetl plik

@ -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++) {