kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Integer scaling supports double height frame buffer, change scanlines to write to line above, display clock info in geometry menu
rodzic
c2d17bfe94
commit
64c29a590b
|
@ -67,6 +67,7 @@ file( GLOB core_files
|
|||
capture_line_default_sixbits_4bpp_8bpp.S
|
||||
capture_line_fast_4bpp_8bpp.S
|
||||
capture_line_fast_sixbits_4bpp_8bpp.S
|
||||
capture_line_ntsc_sixbits_4bpp_8bpp.S
|
||||
capture_line_inband_4bpp_8bpp.S
|
||||
capture_line_oddeven_4bpp_8bpp.S
|
||||
capture_line_half_4bpp_8bpp.S
|
||||
|
|
|
@ -88,7 +88,7 @@ loop:
|
|||
tst r3, #BIT_SCANLINES
|
||||
movne r10, #0
|
||||
tst r3, #BIT_NO_LINE_DOUBLE
|
||||
streq r10, [r0, r2]
|
||||
streq r10, [r0, -r2]
|
||||
add r0, r0, #4
|
||||
|
||||
subs r1, r1, #1
|
||||
|
|
|
@ -52,7 +52,7 @@ loop:
|
|||
tst r3, #BIT_SCANLINES
|
||||
movne r10, #0
|
||||
tst r3, #BIT_NO_LINE_DOUBLE
|
||||
streq r10, [r0, r2]
|
||||
streq r10, [r0, -r2]
|
||||
add r0, r0, #4
|
||||
|
||||
subs r1, r1, #1
|
||||
|
|
|
@ -50,9 +50,9 @@ loop:
|
|||
movne r7, #0
|
||||
movne r10, #0
|
||||
tst r3, #BIT_NO_LINE_DOUBLE
|
||||
addeq r0, r0, r2
|
||||
stmeqia r0, {r7, r10}
|
||||
subeq r0, r0, r2
|
||||
stmeqia r0, {r7, r10}
|
||||
addeq r0, r0, r2
|
||||
add r0, r0, #8
|
||||
subs r1, r1, #1
|
||||
bne loop
|
||||
|
@ -101,9 +101,9 @@ loop_8bpp:
|
|||
movne r7, #0
|
||||
movne r10, #0
|
||||
tst r3, #BIT_NO_LINE_DOUBLE
|
||||
addeq r0, r0, r2
|
||||
stmeqia r0, {r5, r6, r7, r10}
|
||||
subeq r0, r0, r2
|
||||
stmeqia r0, {r5, r6, r7, r10}
|
||||
addeq r0, r0, r2
|
||||
add r0, r0, #16
|
||||
subs r1, r1, #1
|
||||
bne loop_8bpp
|
||||
|
|
|
@ -56,9 +56,9 @@ loop:
|
|||
movne r7, #0
|
||||
movne r10, #0
|
||||
tst r3, #BIT_NO_LINE_DOUBLE
|
||||
addeq r0, r0, r2
|
||||
stmeqia r0, {r7, r10}
|
||||
subeq r0, r0, r2
|
||||
stmeqia r0, {r7, r10}
|
||||
addeq r0, r0, r2
|
||||
add r0, r0, #8
|
||||
|
||||
sub r1, r1, #2
|
||||
|
@ -79,7 +79,7 @@ loop:
|
|||
tst r3, #BIT_SCANLINES
|
||||
movne r7, #0
|
||||
tst r3, #BIT_NO_LINE_DOUBLE
|
||||
addeq r0, r0, r2
|
||||
subeq r0, r0, r2
|
||||
stmeqia r0, {r7}
|
||||
|
||||
pop {r0, pc}
|
||||
|
@ -133,9 +133,9 @@ loop_8bpp:
|
|||
movne r7, #0
|
||||
movne r10, #0
|
||||
tst r3, #BIT_NO_LINE_DOUBLE
|
||||
addeq r0, r0, r2
|
||||
stmeqia r0, {r5, r6, r7, r10}
|
||||
subeq r0, r0, r2
|
||||
stmeqia r0, {r5, r6, r7, r10}
|
||||
addeq r0, r0, r2
|
||||
add r0, r0, #16
|
||||
|
||||
sub r1, r1, #2
|
||||
|
@ -158,7 +158,7 @@ loop_8bpp:
|
|||
movne r5, #0
|
||||
movne r6, #0
|
||||
tst r3, #BIT_NO_LINE_DOUBLE
|
||||
addeq r0, r0, r2
|
||||
subeq r0, r0, r2
|
||||
stmeqia r0, {r5, r6}
|
||||
pop {r0, pc}
|
||||
|
||||
|
|
|
@ -0,0 +1,209 @@
|
|||
#include "rpi-base.h"
|
||||
#include "defs.h"
|
||||
|
||||
#include "macros.S"
|
||||
|
||||
.macro YCAPTURE_LOW_BITS_8BPP_WIDE reg
|
||||
// Pixel 0 in GPIO 7.. 2 -> 7.. 0
|
||||
// Pixel 1 in GPIO 13.. 8 -> 15.. 8
|
||||
mov r10, #0
|
||||
and r9, r8, #(0x07 << PIXEL_BASE)
|
||||
cmp r9, # (0x06 << PIXEL_BASE)
|
||||
orreq r10, r10, #0x01
|
||||
cmp r9, # (0x05 << PIXEL_BASE)
|
||||
orreq r10, r10, #0x02
|
||||
cmp r9, # (0x07 << PIXEL_BASE)
|
||||
orreq r10, r10, #0x03
|
||||
.endm
|
||||
|
||||
|
||||
.macro YCAPTURE_HIGH_BITS_8BPP_WIDE reg
|
||||
// Pixel 2 in GPIO 7.. 2 -> 23..16
|
||||
// Pixel 3 in GPIO 13.. 8 -> 31..24
|
||||
|
||||
and r9, r8, #(0x07 << PIXEL_BASE)
|
||||
cmp r9, # (0x06 << PIXEL_BASE)
|
||||
orreq r10, r10, #0x04
|
||||
cmp r9, # (0x05 << PIXEL_BASE)
|
||||
orreq r10, r10, #0x05
|
||||
cmp r9, # (0x07 << PIXEL_BASE)
|
||||
orreq r10, r10, #0x0c
|
||||
orr r10, r10, #0x40
|
||||
orr \reg, r10, r10, lsl#8
|
||||
orr \reg, \reg, \reg, lsl#16
|
||||
.endm
|
||||
|
||||
.macro XCAPTURE_LOW_BITS_8BPP_WIDE reg
|
||||
// Pixel 0 in GPIO 7.. 2 -> 7.. 0
|
||||
// Pixel 1 in GPIO 13.. 8 -> 15.. 8
|
||||
mov r10, #0
|
||||
and r9, r8, #(0x3f << PIXEL_BASE)
|
||||
and r14, r8, #(0x3f << (PIXEL_BASE + 6))
|
||||
cmp r9, #0
|
||||
orrne r10, r10, #8
|
||||
cmp r14, #0
|
||||
orrne r10, r10, #4
|
||||
.endm
|
||||
|
||||
|
||||
.macro XCAPTURE_HIGH_BITS_8BPP_WIDE reg
|
||||
// Pixel 2 in GPIO 7.. 2 -> 23..16
|
||||
// Pixel 3 in GPIO 13.. 8 -> 31..24
|
||||
|
||||
and r9, r8, #(0x3f << PIXEL_BASE)
|
||||
and r14, r8, #(0x3f << (PIXEL_BASE + 6))
|
||||
cmp r9, #0
|
||||
orrne r10, r10, #2
|
||||
cmp r14, #0
|
||||
orrne r10, r10, #1
|
||||
orr r10, r10, #0x40
|
||||
orr \reg, r10, r10, lsl#8
|
||||
orr \reg, \reg, \reg, lsl#16
|
||||
.endm
|
||||
|
||||
.text
|
||||
|
||||
.global capture_line_ntsc_sixbits_4bpp
|
||||
.global capture_line_ntsc_sixbits_8bpp
|
||||
|
||||
// The capture line function is provided the following:
|
||||
// r0 = pointer to current line in frame buffer
|
||||
// r1 = number of complete psync cycles to capture (=param_chars_per_line)
|
||||
// r2 = frame buffer line pitch in bytes (=param_fb_pitch)
|
||||
// r3 = flags register
|
||||
// r4 = GPLEV0 constant
|
||||
// r5 = line number count down to 0 (initial value =param_nlines)
|
||||
// r6 = scan line count modulo 10
|
||||
// r7 = number of psyncs to skip
|
||||
// r8 = frame buffer height (=param_fb_height)
|
||||
//
|
||||
// All registers are available as scratch registers (i.e. nothing needs to be preserved)
|
||||
|
||||
b preload_capture_line_ntsc_sixbits
|
||||
capture_line_ntsc_sixbits_4bpp:
|
||||
push {lr}
|
||||
tst r3, #BIT_VSYNC_MARKER
|
||||
ldrne r11, =0x11111111
|
||||
moveq r11, #0
|
||||
tst r3, #BIT_DEBUG
|
||||
eorne r11, r11, #0x50 //magenta in leftmost
|
||||
eorne r11, r11, #0x02000000 //green in rightmost
|
||||
|
||||
SKIP_PSYNC_NO_H_SCROLL
|
||||
push {r14}
|
||||
loop:
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
CAPTURE_0_BITS_WIDE r11 // input in r8, result in r10, corrupts r9
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
CAPTURE_1_BITS_WIDE // input in r8, result in r10, corrupts r9
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
CAPTURE_2_BITS_WIDE // input in r8, result in r10, corrupts r9
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
CAPTURE_3_BITS_WIDE r7 // input in r8, result in r7, corrupts r9
|
||||
|
||||
cmp r1, #1
|
||||
stmeqia r0!, {r7}
|
||||
popeq {r0, pc}
|
||||
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
CAPTURE_0_BITS_WIDE r11 // input in r8, result in r10, corrupts r9
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
CAPTURE_1_BITS_WIDE // input in r8, result in r10, corrupts r9
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
CAPTURE_2_BITS_WIDE // input in r8, result in r10, corrupts r9
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
CAPTURE_3_BITS_WIDE r10 // input in r8, result in r10, corrupts r9
|
||||
|
||||
stmia r0!, {r7, r10}
|
||||
subs r1, r1, #2
|
||||
bne loop
|
||||
|
||||
pop {r0, pc}
|
||||
|
||||
preload_capture_line_ntsc_sixbits:
|
||||
SETUP_DUMMY_PARAMETERS
|
||||
b capture_line_ntsc_sixbits_4bpp
|
||||
|
||||
.ltorg
|
||||
|
||||
// *** 8 bit ***
|
||||
|
||||
b preload_capture_line_ntsc_sixbits_8bpp
|
||||
capture_line_ntsc_sixbits_8bpp:
|
||||
push {lr}
|
||||
tst r3, #BIT_VSYNC_MARKER
|
||||
ldrne r11, =0x01010101
|
||||
moveq r11, #0
|
||||
movne r12, r11
|
||||
moveq r12, #0
|
||||
tst r3, #BIT_DEBUG
|
||||
eorne r11, r11, #0x05 //magenta in leftmost
|
||||
eorne r12, r12, #0x02000000 //green in rightmost
|
||||
|
||||
ldr r11, =0x10101010
|
||||
ldr r12, =0x10101010
|
||||
|
||||
SKIP_PSYNC_NO_OLD_CPLD
|
||||
push {r14}
|
||||
loop_8bpp:
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
XCAPTURE_LOW_BITS_8BPP_WIDE r11 // input in r8, result in r10, corrupts r9
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
XCAPTURE_HIGH_BITS_8BPP_WIDE r5 // input in r8, result in r5, corrupts r9
|
||||
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
XCAPTURE_LOW_BITS_8BPP_WIDE r12 // input in r8, result in r10, corrupts r9
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
XCAPTURE_HIGH_BITS_8BPP_WIDE r6 // input in r8, result in r6, corrupts r9
|
||||
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
XCAPTURE_LOW_BITS_8BPP_WIDE r11 // input in r8, result in r10, corrupts r9
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
XCAPTURE_HIGH_BITS_8BPP_WIDE r7 // input in r8, result in r7, corrupts r9
|
||||
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
XCAPTURE_LOW_BITS_8BPP_WIDE r12 // input in r8, result in r10, corrupts r9
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
XCAPTURE_HIGH_BITS_8BPP_WIDE r10 // input in r8, result in r10, corrupts r9
|
||||
|
||||
stmia r0, {r5, r6, r7, r10}
|
||||
tst r3, #BIT_SCANLINES
|
||||
movne r5, #0
|
||||
movne r6, #0
|
||||
movne r7, #0
|
||||
movne r10, #0
|
||||
tst r3, #BIT_NO_LINE_DOUBLE
|
||||
subeq r0, r0, r2
|
||||
stmeqia r0, {r5, r6, r7, r10}
|
||||
addeq r0, r0, r2
|
||||
add r0, r0, #16
|
||||
|
||||
sub r1, r1, #2
|
||||
cmp r1, #1
|
||||
bgt loop_8bpp
|
||||
popne {r0, pc}
|
||||
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
XCAPTURE_LOW_BITS_8BPP_WIDE r11 // input in r8, result in r10, corrupts r9
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
XCAPTURE_HIGH_BITS_8BPP_WIDE r5 // input in r8, result in r5, corrupts r9
|
||||
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
XCAPTURE_LOW_BITS_8BPP_WIDE r12 // input in r8, result in r10, corrupts r9
|
||||
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
|
||||
XCAPTURE_HIGH_BITS_8BPP_WIDE r6 // input in r8, result in r6, corrupts r9
|
||||
|
||||
stmia r0, {r5, r6}
|
||||
tst r3, #BIT_SCANLINES
|
||||
movne r5, #0
|
||||
movne r6, #0
|
||||
tst r3, #BIT_NO_LINE_DOUBLE
|
||||
subeq r0, r0, r2
|
||||
stmeqia r0, {r5, r6}
|
||||
pop {r0, pc}
|
||||
|
||||
|
||||
|
||||
preload_capture_line_ntsc_sixbits_8bpp:
|
||||
SETUP_DUMMY_PARAMETERS
|
||||
b capture_line_ntsc_sixbits_8bpp
|
|
@ -541,45 +541,45 @@ static void cpld_update_capture_info(capture_info_t *capinfo) {
|
|||
if (!mode7) {
|
||||
if (capinfo->bpp == 8) {
|
||||
switch (capinfo->px_sampling) {
|
||||
case PS_NORMAL:
|
||||
capinfo->capture_line = capture_line_normal_8bpp_table;
|
||||
break;
|
||||
case PS_NORMAL_O:
|
||||
capinfo->capture_line = capture_line_odd_8bpp_table;
|
||||
break;
|
||||
case PS_NORMAL_E:
|
||||
capinfo->capture_line = capture_line_even_8bpp_table;
|
||||
break;
|
||||
case PS_HALF_O:
|
||||
capinfo->capture_line = capture_line_half_odd_8bpp_table;
|
||||
break;
|
||||
case PS_HALF_E:
|
||||
capinfo->capture_line = capture_line_half_even_8bpp_table;
|
||||
break;
|
||||
case PS_DOUBLE:
|
||||
capinfo->capture_line = capture_line_double_8bpp_table;
|
||||
break;
|
||||
case PS_NORMAL:
|
||||
capinfo->capture_line = capture_line_normal_8bpp_table;
|
||||
break;
|
||||
case PS_NORMAL_O:
|
||||
capinfo->capture_line = capture_line_odd_8bpp_table;
|
||||
break;
|
||||
case PS_NORMAL_E:
|
||||
capinfo->capture_line = capture_line_even_8bpp_table;
|
||||
break;
|
||||
case PS_HALF_O:
|
||||
capinfo->capture_line = capture_line_half_odd_8bpp_table;
|
||||
break;
|
||||
case PS_HALF_E:
|
||||
capinfo->capture_line = capture_line_half_even_8bpp_table;
|
||||
break;
|
||||
case PS_DOUBLE:
|
||||
capinfo->capture_line = capture_line_double_8bpp_table;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (capinfo->px_sampling) {
|
||||
case PS_NORMAL:
|
||||
capinfo->capture_line = capture_line_normal_4bpp_table;
|
||||
break;
|
||||
case PS_NORMAL_O:
|
||||
capinfo->capture_line = capture_line_odd_4bpp_table;
|
||||
break;
|
||||
case PS_NORMAL_E:
|
||||
capinfo->capture_line = capture_line_even_4bpp_table;
|
||||
break;
|
||||
case PS_HALF_O:
|
||||
capinfo->capture_line = capture_line_half_odd_4bpp_table;
|
||||
break;
|
||||
case PS_HALF_E:
|
||||
capinfo->capture_line = capture_line_half_even_4bpp_table;
|
||||
break;
|
||||
case PS_DOUBLE:
|
||||
capinfo->capture_line = capture_line_double_4bpp_table;
|
||||
break;
|
||||
case PS_NORMAL:
|
||||
capinfo->capture_line = capture_line_normal_4bpp_table;
|
||||
break;
|
||||
case PS_NORMAL_O:
|
||||
capinfo->capture_line = capture_line_odd_4bpp_table;
|
||||
break;
|
||||
case PS_NORMAL_E:
|
||||
capinfo->capture_line = capture_line_even_4bpp_table;
|
||||
break;
|
||||
case PS_HALF_O:
|
||||
capinfo->capture_line = capture_line_half_odd_4bpp_table;
|
||||
break;
|
||||
case PS_HALF_E:
|
||||
capinfo->capture_line = capture_line_half_even_4bpp_table;
|
||||
break;
|
||||
case PS_DOUBLE:
|
||||
capinfo->capture_line = capture_line_double_4bpp_table;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -248,4 +248,10 @@ typedef struct {
|
|||
#define PIXELVALVE2_VERTA (volatile uint32_t *)(PERIPHERAL_BASE + 0x807014)
|
||||
#define PIXELVALVE2_VERTB (volatile uint32_t *)(PERIPHERAL_BASE + 0x807018)
|
||||
|
||||
|
||||
#define PM_RSTC (volatile uint32_t *)(PERIPHERAL_BASE + 0x10001c)
|
||||
#define PM_WDOG (volatile uint32_t *)(PERIPHERAL_BASE + 0x100024)
|
||||
#define PM_PASSWORD 0x5a000000
|
||||
#define PM_RSTC_WRCFG_FULL_RESET 0x00000020
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,7 +35,7 @@ static param_t params[] = {
|
|||
{ FB_HEIGHTX2,"FB double height", 0, 1, 1 },
|
||||
{ FB_BPP, "FB Bits/pixel", 4, 8, 4 },
|
||||
{ CLOCK, "Clock freq", 1000000, 40000000, 1000 },
|
||||
{ LINE_LEN, "Line len", 100, 5000, 1 },
|
||||
{ LINE_LEN, "Line length", 100, 5000, 1 },
|
||||
{ CLOCK_PPM, "Clock Tolerance", 0, 100000, 100 },
|
||||
{ LINES_FRAME, "Lines per frame", 250, 1200, 1 },
|
||||
{ SYNC_TYPE, "Sync type", 0,NUM_SYNC-1, 1 },
|
||||
|
@ -261,16 +261,16 @@ void geometry_get_fb_params(capture_info_t *capinfo) {
|
|||
int adjusted_height = geometry->v_height << geometry->fb_heightx2;
|
||||
double hscalef = (double) h_size43 / adjusted_width;
|
||||
int hscale = (int) hscalef;
|
||||
int hborder = (h_size - (adjusted_width * hscale)) / hscale;
|
||||
int hborder43 = (h_size43 - (adjusted_width * hscale)) / hscale;
|
||||
double vscalef = (double) v_size43 / adjusted_height;
|
||||
int hborder = (h_size - adjusted_width * hscale) / hscale;
|
||||
int hborder43 = (h_size43 - adjusted_width * hscale) / hscale;
|
||||
double vscalef = (double) v_size43 / geometry->v_height;
|
||||
int vscale = (int) vscalef;
|
||||
int vborder = (v_size - (adjusted_height * vscale)) / vscale;
|
||||
int vborder43 = (v_size43 - (adjusted_height * vscale)) / vscale;
|
||||
int vborder = ((v_size - geometry->v_height * vscale) << geometry->fb_heightx2) / vscale;
|
||||
int vborder43 = ((v_size43 - geometry->v_height * vscale) << geometry->fb_heightx2) / vscale;
|
||||
int newhborder43 = vborder43 * 4 / 3;
|
||||
int newvborder43 = hborder43 * 3 / 4;
|
||||
|
||||
//log_info("scaling size = %d, %d, %f",adjusted_width, geometry->v_height << geometry->fb_heightx2, ratio);
|
||||
//log_info("scaling size = %d, %d, %f",adjusted_width, adjusted_height, ratio);
|
||||
//log_info("scaling h = %d, %d, %f, %d, %d, %d, %d",h_size, h_size43, hscalef, hscale, hborder, hborder43, newhborder43);
|
||||
//log_info("scaling v = %d, %d, %f, %d, %d, %d, %d",v_size, v_size43, vscalef, vscale, vborder, vborder43, newvborder43);
|
||||
|
||||
|
|
12
src/macros.S
12
src/macros.S
|
@ -570,7 +570,7 @@ skip_psync_loop_no_h_scroll\@:
|
|||
tst r3, #BIT_SCANLINES
|
||||
movne r10, #0
|
||||
tst r3, #BIT_NO_LINE_DOUBLE
|
||||
streq r10, [r0, r2]
|
||||
streq r10, [r0, -r2]
|
||||
add r0, r0, #4
|
||||
.endm
|
||||
|
||||
|
@ -578,13 +578,13 @@ skip_psync_loop_no_h_scroll\@:
|
|||
eor r9, r9, r5 //eor in vsync and debug
|
||||
eor r10, r10, r6 //eor in vsync and debug
|
||||
stmia r0, {r9, r10}
|
||||
add r0, r0, r2
|
||||
sub r0, r0, r2
|
||||
tst r3, #BIT_SCANLINES
|
||||
movne r9, #0
|
||||
movne r10, #0
|
||||
tst r3, #BIT_NO_LINE_DOUBLE
|
||||
stmeqia r0, {r9, r10}
|
||||
subs r0, r0, r2
|
||||
add r0, r0, r2
|
||||
add r0, r0, #8
|
||||
.endm
|
||||
|
||||
|
@ -599,7 +599,7 @@ skip_psync_loop_no_h_scroll\@:
|
|||
tst r3, #BIT_SCANLINES
|
||||
movne r10, #0
|
||||
tst r3, #BIT_NO_LINE_DOUBLE
|
||||
streq r10, [r0, r2]
|
||||
streq r10, [r0, -r2]
|
||||
add r0, r0, #4
|
||||
.endm
|
||||
|
||||
|
@ -618,13 +618,13 @@ skip_psync_loop_no_h_scroll\@:
|
|||
eorne r9, r9, #0x05 //magenta in leftmost
|
||||
eorne r10, r10, #0x02000000 //green in rightmost
|
||||
stmia r0, {r9, r10}
|
||||
add r0, r0, r2
|
||||
sub r0, r0, r2
|
||||
tst r3, #BIT_SCANLINES
|
||||
movne r9, #0
|
||||
movne r10, #0
|
||||
tst r3, #BIT_NO_LINE_DOUBLE
|
||||
stmeqia r0, {r9, r10}
|
||||
subs r0, r0, r2
|
||||
add r0, r0, r2
|
||||
add r0, r0, #8
|
||||
.endm
|
||||
|
||||
|
|
50
src/osd.c
50
src/osd.c
|
@ -456,6 +456,7 @@ static int key_capture = OSD_SW2;
|
|||
|
||||
// Whether the menu back pointer is at the start (0) or end (1) of the menu
|
||||
static int return_at_end = 1;
|
||||
|
||||
static char default_buffer[MAX_BUFFER_SIZE];
|
||||
static char main_buffer[MAX_BUFFER_SIZE];
|
||||
static char sub_default_buffer[MAX_BUFFER_SIZE];
|
||||
|
@ -874,8 +875,42 @@ uint32_t osd_get_palette(int index) {
|
|||
void osd_update_palette() {
|
||||
int m;
|
||||
int num_colours = (capinfo->bpp == 8) ? 256 : 16;
|
||||
char col[16];
|
||||
col[0] = 0b000000; // black
|
||||
col[1] = 0b000111; // light blue
|
||||
col[2] = 0b000011; // blue
|
||||
col[3] = 0b001011; // light blue
|
||||
col[4] = 0b100000; // red
|
||||
col[5] = 0b011110; // acqua;
|
||||
col[6] = 0b101010; // gray
|
||||
col[7] = 0b011111; // light cyan
|
||||
col[8] = 0b110000; // light red
|
||||
col[9] = 0b101111; // light cyan
|
||||
col[10] = 0b111011; // light dmagn
|
||||
col[11] = 0b001111; // light purple
|
||||
col[12] = 0b110100; // orange
|
||||
col[13] = 0b111110; // light yellow
|
||||
col[14] = 0b111010; // salmon
|
||||
col[15] = 0b111111; // white;
|
||||
|
||||
|
||||
|
||||
col[0] = 0b000000; // black
|
||||
col[1] = 0b001001; // green
|
||||
col[2] = 0b010011; // blue
|
||||
col[3] = 0b001011; // light blue
|
||||
col[4] = 0b100000; // red
|
||||
col[5] = 0b101010; // gray
|
||||
col[6] = 0b110011; // dmagn
|
||||
col[7] = 0b111011; // pink
|
||||
col[8] = 0b000100; // dark green
|
||||
col[9] = 0b001100; // light green
|
||||
col[10] = 0b010101; // dark gray
|
||||
col[11] = 0b011110; // acqua
|
||||
col[12] = 0b110100; // orange
|
||||
col[13] = 0b111100; // light yellow
|
||||
col[14] = 0b111010; // salmon
|
||||
col[15] = 0b111111; // white
|
||||
|
||||
for (int i = 0; i < num_colours; i++) {
|
||||
|
||||
int r = (i & 1) ? 255 : 0;
|
||||
|
@ -905,6 +940,8 @@ void osd_update_palette() {
|
|||
}
|
||||
break;
|
||||
case PALETTE_RGBICGA:
|
||||
if (i<0x40)
|
||||
{
|
||||
m = (num_colours == 16) ? 0x08 : 0x10; // intensity is actually on lsb green pin on 9 way D
|
||||
r = (i & 1) ? 0xaa : 0x00;
|
||||
g = (i & 2) ? 0xaa : 0x00;
|
||||
|
@ -919,6 +956,17 @@ void osd_update_palette() {
|
|||
}
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
r = (col[i & 0x0f]>>4) & 0x03;
|
||||
g = (col[i & 0x0f]>>2) & 0x03;
|
||||
b = col[i & 0x0f] & 0x03;
|
||||
|
||||
r = r | (r<<2) | (r<<4) | (r<<6);
|
||||
g = g | (g<<2) | (g<<4) | (g<<6);
|
||||
b = b | (b<<2) | (b<<4) | (b<<6);
|
||||
break;
|
||||
}
|
||||
|
||||
case PALETTE_RrGgBb:
|
||||
r = (i & 1) ? 0xaa : 0x00;
|
||||
g = (i & 2) ? 0xaa : 0x00;
|
||||
|
|
|
@ -344,6 +344,9 @@ skip_mode_test:
|
|||
// Correct the relative positions of the odd and even frames
|
||||
// In Mode 0..6, reduce the number of active lines by one for the even frame
|
||||
// In Mode 7, increment the frame buffer pointer by one line for the even field
|
||||
|
||||
tst r3, #(BIT_NO_LINE_DOUBLE | BIT_MODE7)
|
||||
addeq r11, r11, r2
|
||||
tst r3, #BIT_ELK
|
||||
bne skip_line_loop
|
||||
tst r3, #BIT_MODE7
|
||||
|
@ -1044,8 +1047,8 @@ capture_line_normal_4bpp_table:
|
|||
.word capture_line_fast_sixbits_4bpp
|
||||
.word capture_line_inband_4bpp
|
||||
.word capture_line_default_sixbits_4bpp // placeholder for in band six bits
|
||||
.word capture_line_default_4bpp // placeholder for ntsc artifacting
|
||||
.word capture_line_default_sixbits_4bpp // placeholder for ntsc artifacting
|
||||
.word capture_line_default_4bpp // placeholder for ntsc artifacting
|
||||
.word capture_line_ntsc_sixbits_4bpp
|
||||
|
||||
capture_line_odd_4bpp_table:
|
||||
capture_line_even_4bpp_table:
|
||||
|
@ -1087,8 +1090,8 @@ capture_line_normal_8bpp_table:
|
|||
.word capture_line_fast_sixbits_8bpp
|
||||
.word capture_line_inband_8bpp
|
||||
.word capture_line_default_sixbits_8bpp // placeholder for in band six bits
|
||||
.word capture_line_default_8bpp // placeholder for ntsc artifacting
|
||||
.word capture_line_default_sixbits_8bpp // placeholder for ntsc artifacting
|
||||
.word capture_line_default_8bpp // placeholder for ntsc artifacting
|
||||
.word capture_line_ntsc_sixbits_8bpp // placeholder for ntsc artifacting
|
||||
|
||||
capture_line_odd_8bpp_table:
|
||||
capture_line_even_8bpp_table:
|
||||
|
|
|
@ -80,20 +80,21 @@ static int vlockmode = 3;
|
|||
static int vlockline = 10;
|
||||
static int lines_per_frame = 0;
|
||||
static int one_line_time_ns = 0;
|
||||
static int adjusted_clock;
|
||||
#ifdef MULTI_BUFFER
|
||||
static int nbuffers = 0;
|
||||
#endif
|
||||
|
||||
static int current_vlockmode = -1;
|
||||
static const char *sync_names[] = {
|
||||
"-H -V",
|
||||
"+H -V",
|
||||
"-H +V",
|
||||
"+H +V",
|
||||
"Composite",
|
||||
"Inverted"
|
||||
"Composite -V",
|
||||
"Inverted -V"
|
||||
"-H-V",
|
||||
"+H-V",
|
||||
"-H+V",
|
||||
"+H+V",
|
||||
"Comp",
|
||||
"Inv"
|
||||
"C-V",
|
||||
"I-V"
|
||||
};
|
||||
static const char *mixed_names[] = {
|
||||
"Separate H & V CPLD",
|
||||
|
@ -126,6 +127,12 @@ static framebuf *fbp = (framebuf *) (UNCACHED_MEM_BASE + 0x10000);
|
|||
// Private methods
|
||||
// =============================================================
|
||||
|
||||
void reboot() {
|
||||
*PM_WDOG = PM_PASSWORD | 1;
|
||||
*PM_RSTC = PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET;
|
||||
while(1);
|
||||
}
|
||||
|
||||
// 0 0 Hz Ground
|
||||
// 1 19.2 MHz oscillator
|
||||
// 2 0 Hz testdebug0
|
||||
|
@ -136,7 +143,6 @@ static framebuf *fbp = (framebuf *) (UNCACHED_MEM_BASE + 0x10000);
|
|||
// 7 216 MHz HDMI auxiliary
|
||||
// 8-15 0 Hz Ground
|
||||
|
||||
|
||||
// Source 1 = OSC = 19.2MHz
|
||||
// Source 4 = PLLA = 0MHz
|
||||
// Source 5 = PLLC = core_freq * 3
|
||||
|
@ -310,8 +316,9 @@ static int calibrate_sampling_clock() {
|
|||
double error = (double) nlines_time_ns / (double) nlines_ref_ns;
|
||||
clock_error_ppm = ((error - 1.0) * 1e6);
|
||||
log_info(" Clock error = %d PPM", clock_error_ppm);
|
||||
|
||||
|
||||
int new_clock;
|
||||
|
||||
if (clkinfo.clock_ppm > 0 && abs(clock_error_ppm) > clkinfo.clock_ppm) {
|
||||
if (old_clock > 0 && sub_profiles_available(profile) == 0) {
|
||||
log_warn("PPM error too large, using previous clock");
|
||||
|
@ -326,7 +333,9 @@ static int calibrate_sampling_clock() {
|
|||
|
||||
old_clock = new_clock;
|
||||
|
||||
log_info(" Error adjusted clock = %d Hz", new_clock / cpld->get_divider());
|
||||
adjusted_clock = new_clock / cpld->get_divider();
|
||||
|
||||
log_info(" Error adjusted clock = %d Hz", adjusted_clock);
|
||||
|
||||
// Pick the best value for core_freq and gpclk_divisor given the following constraints
|
||||
// 1. Core Freq should be as high as possible, but <= 400MHz
|
||||
|
@ -1449,6 +1458,8 @@ void setup_profile() {
|
|||
log_info("Window: H = %d to %d, V = %d to %d, S = %s", hsync_comparison_lo, hsync_comparison_hi, vsync_comparison_lo, vsync_comparison_hi, sync_names[capinfo->sync_type]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void rgb_to_hdmi_main() {
|
||||
|
||||
int result = RET_SYNC_TIMING_CHANGED; // make sure autoswitch works first time
|
||||
|
@ -1461,9 +1472,11 @@ void rgb_to_hdmi_main() {
|
|||
int ncapture;
|
||||
int last_profile = -1;
|
||||
int last_subprofile = -1;
|
||||
char osdline[80];
|
||||
capture_info_t last_capinfo;
|
||||
clk_info_t last_clkinfo;
|
||||
|
||||
|
||||
// Setup defaults (these may be overridden by the CPLD)
|
||||
default_capinfo.capture_line = capture_line_normal_4bpp_table;
|
||||
mode7_capinfo.capture_line = capture_line_mode7_4bpp_table;
|
||||
|
@ -1482,13 +1495,14 @@ void rgb_to_hdmi_main() {
|
|||
log_info("-----------------------LOOP------------------------");
|
||||
setup_profile();
|
||||
|
||||
|
||||
if (autoswitch == AUTOSWITCH_PC && ((result & RET_SYNC_TIMING_CHANGED) || profile != last_profile || last_subprofile != subprofile)) {
|
||||
int new_sub_profile = autoswitch_detect(one_line_time_ns, lines_per_frame, capinfo->detected_sync_type & SYNC_BIT_MASK);
|
||||
if (new_sub_profile >= 0) {
|
||||
set_subprofile(new_sub_profile);
|
||||
process_sub_profile(get_profile(), new_sub_profile);
|
||||
setup_profile();
|
||||
} else {
|
||||
log_info("Autoswitch: No profile matched");
|
||||
}
|
||||
}
|
||||
last_profile = profile;
|
||||
|
@ -1497,9 +1511,14 @@ void rgb_to_hdmi_main() {
|
|||
log_debug("Setting up frame buffer");
|
||||
init_framebuffer(capinfo);
|
||||
log_debug("Done setting up frame buffer");
|
||||
|
||||
clear = BIT_CLEAR;
|
||||
|
||||
osd_refresh();
|
||||
|
||||
// unsigned int *i;
|
||||
// for (i=(unsigned int *)(PERIPHERAL_BASE + 0x400000); i<(unsigned int *)(PERIPHERAL_BASE + 0x4000e4); i++) {
|
||||
// log_info(" Regs:%08x %08x = %02x",PERIPHERAL_BASE, i, *i);
|
||||
// }
|
||||
|
||||
do {
|
||||
int flags = extra_flags() | mode7 | clear;
|
||||
|
@ -1543,6 +1562,8 @@ void rgb_to_hdmi_main() {
|
|||
// (this also re-selects the appropriate line capture)
|
||||
cpld->update_capture_info(capinfo);
|
||||
capinfo->palette_control = paletteControl;
|
||||
|
||||
|
||||
log_debug("Entering rgb_to_fb, flags=%08x", flags);
|
||||
result = rgb_to_fb(capinfo, flags);
|
||||
log_debug("Leaving rgb_to_fb, result=%04x", result);
|
||||
|
@ -1590,6 +1611,11 @@ void rgb_to_hdmi_main() {
|
|||
calibrate_sampling_clock();
|
||||
// Recalculate the HDMI clock (if the vlockmode property requires this)
|
||||
recalculate_hdmi_clock_line_locked_update();
|
||||
|
||||
if (osd_active()) {
|
||||
sprintf(osdline, "%dHz %dPPM %d %s", adjusted_clock, clock_error_ppm, lines_per_frame, sync_names[capinfo->detected_sync_type & SYNC_BIT_MASK]);
|
||||
osd_set(1, 0, osdline);
|
||||
}
|
||||
}
|
||||
|
||||
} while (!mode_changed && !fb_size_changed);
|
||||
|
|
Ładowanie…
Reference in New Issue