Add full CGA artifact decoding using reenigne's code (Requires multicore Pi such as Pi zero 2W - doesn't work on original Pi zero)

pull/306/head
IanSB 2022-01-22 02:14:36 +00:00
rodzic d70d64164f
commit 2b314d3e35
13 zmienionych plików z 691 dodań i 456 usunięć

Wyświetl plik

@ -8,6 +8,9 @@
.global capture_line_default_sixbits_8bpp
.global capture_line_default_sixbits_16bpp
.extern palette_data_16
.extern debug_value
// 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)
@ -110,7 +113,6 @@ preload_capture_line_default_sixbits_8bpp:
SETUP_DUMMY_PARAMETERS
b capture_line_default_sixbits_8bpp
.ltorg
// *** 16 bit ***
@ -121,37 +123,32 @@ capture_line_default_sixbits_16bpp:
SETUP_VSYNC_DEBUG_16BPP_R11
SKIP_PSYNC_NO_OLD_CPLD
mov r1, r1, lsr #2
SETUP_TWELVE_BITS_MASK_R14
ldr r14, =palette_data_16
loop_16bpp:
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_16BPP_LO r11 // input in r8
CAPTURE_SIX_BITS_16BPP r11 r5 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_16BPP_HI r5 // input in r8
CAPTURE_SIX_BITS_16BPP r11 r6 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_16BPP_LO r11 // input in r8
CAPTURE_SIX_BITS_16BPP r11 r7 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_16BPP_HI r6 // input in r8
WRITE_R5_R6_IF_LAST_16BPP
cmp r1, #1
popeq {r0, pc}
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_16BPP_LO r11 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_16BPP_HI r7 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_16BPP_LO r11 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_16BPP_HI r10 // input in r8
CAPTURE_SIX_BITS_16BPP r11 r10 // input in r8
WRITE_R5_R6_R7_R10_16BPP
subs r1, r1, #2
subs r1, r1, #1
bne loop_16bpp
pop {r0, pc}
preload_capture_line_default_sixbits_16bpp:
ldr r0, =palette_data_16
mov r1, #64
preload_loop:
ldr r2, [r0], #4
subs r1, r1, #1
bne preload_loop
SETUP_DUMMY_PARAMETERS
b capture_line_default_sixbits_16bpp
.ltorg

Wyświetl plik

@ -102,29 +102,28 @@ capture_line_default_sixbits_double_16bpp:
SETUP_VSYNC_DEBUG_16BPP_R11
SKIP_PSYNC_NO_OLD_CPLD
mov r1, r1, lsr #1
SETUP_TWELVE_BITS_MASK_R14
ldr r14, =palette_data_16
loop_16bpp:
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_DOUBLE_16BPP r11 r5 // input in r8
CAPTURE_SIX_BITS_DOUBLE_16BPP_LO r11 r5 // input in r8
CAPTURE_SIX_BITS_DOUBLE_16BPP_HI r11 r6 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_DOUBLE_16BPP r11 r6 // input in r8
WRITE_R5_R6_IF_LAST_16BPP
cmp r1, #1
popeq {r0, pc}
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_DOUBLE_16BPP r11 r7 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_DOUBLE_16BPP r11 r10 // input in r8
CAPTURE_SIX_BITS_DOUBLE_16BPP_LO r11 r7 // input in r8
CAPTURE_SIX_BITS_DOUBLE_16BPP_HI r11 r10 // input in r8
WRITE_R5_R6_R7_R10_16BPP
subs r1, r1, #2
subs r1, r1, #1
bne loop_16bpp
pop {r0, pc}
preload_capture_line_default_sixbits_double_16bpp:
ldr r0, =palette_data_16
mov r1, #64
preload_loop:
ldr r2, [r0], #4
subs r1, r1, #1
bne preload_loop
SETUP_DUMMY_PARAMETERS
b capture_line_default_sixbits_double_16bpp

Wyświetl plik

@ -117,36 +117,29 @@ capture_line_fast_sixbits_16bpp:
SETUP_VSYNC_DEBUG_16BPP_R11
SKIP_PSYNC_NO_OLD_CPLD
mov r1, r1, lsr #2
SETUP_TWELVE_BITS_MASK_R14
ldr r14, =palette_data_16
loop_16bpp:
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_16BPP_LO r11 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_16BPP_HI r5 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_16BPP_LO r11 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_16BPP_HI r6 // input in r8
cmp r1, #1
stmeqia r0, {r5, r6}
popeq {r0, pc}
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_16BPP_LO r11 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_16BPP_HI r7 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_16BPP_LO r11 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_TWELVE_BITS_16BPP_HI r10 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_SIX_BITS_16BPP r11 r5 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_SIX_BITS_16BPP r11 r6 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_SIX_BITS_16BPP r11 r7 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_SIX_BITS_16BPP r11 r10 // input in r8
stmia r0!, {r5, r6, r7, r10}
subs r1, r1, #2
subs r1, r1, #1
bne loop_16bpp
pop {r0, pc}
preload_capture_line_fast_sixbits_16bpp:
ldr r0, =palette_data_16
mov r1, #64
preload_loop:
ldr r2, [r0], #4
subs r1, r1, #1
bne preload_loop
SETUP_DUMMY_PARAMETERS
b capture_line_fast_sixbits_16bpp

Wyświetl plik

@ -1440,73 +1440,242 @@ loop_8bppd_auto:
pop {r0, pc}
.ltorg
.macro CAPTURE_SIX_BITS_16BPP_LO reg
.macro CAPTURE_SIX_BITS_16BPP_0 reg
// Pixel 0 in GPIO 7.. 2 -> 7.. 0
// Pixel 1 in GPIO 13.. 8 -> 15.. 8
and r9, r8, #(0x3f << PIXEL_BASE)
orr r9, r9, r9, lsl #6
eor r10, \reg, r9, lsr #(PIXEL_BASE)
ldr r12, [r0]
mov \reg, #0
tst r8, #(0x01 << PIXEL_BASE)
orrne \reg, #0x01
tst r8, #(0x02 << PIXEL_BASE)
orrne \reg, #0x04
tst r8, #(0x04 << PIXEL_BASE)
orrne \reg, #0x02
tst r8, #(0x10 << PIXEL_BASE)
orrne \reg, #0x08
.endm
.macro CAPTURE_SIX_BITS_16BPP_HI reg
.macro CAPTURE_SIX_BITS_16BPP_1 reg
// Pixel 2 in GPIO 7.. 2 -> 23..16
// Pixel 3 in GPIO 13.. 8 -> 31..24
and r9, r8, #(0x3f << (PIXEL_BASE + 6))
orr r9, r9, r9, lsr #6
eor \reg, r10, r9, lsl #(16 - PIXEL_BASE)
// ldr r12, [r0, #64]
tst r8, #(0x01 << (PIXEL_BASE + 6))
orrne \reg, #0x0100
tst r8, #(0x02 << (PIXEL_BASE + 6))
orrne \reg, #0x0400
tst r8, #(0x04 << (PIXEL_BASE + 6))
orrne \reg, #0x0200
tst r8, #(0x10 << (PIXEL_BASE + 6))
orrne \reg, #0x0800
.endm
.macro CAPTURE_SIX_BITS_16BPP_2 reg
// Pixel 0 in GPIO 7.. 2 -> 7.. 0
// Pixel 1 in GPIO 13.. 8 -> 15.. 8
tst r8, #(0x01 << PIXEL_BASE)
orrne \reg, #0x010000
tst r8, #(0x02 << PIXEL_BASE)
orrne \reg, #0x040000
tst r8, #(0x04 << PIXEL_BASE)
orrne \reg, #0x020000
tst r8, #(0x10 << PIXEL_BASE)
orrne \reg, #0x080000
.endm
.macro CAPTURE_SIX_BITS_16BPP_3 reg
// Pixel 2 in GPIO 7.. 2 -> 23..16
// Pixel 3 in GPIO 13.. 8 -> 31..24
tst r8, #(0x01 << (PIXEL_BASE + 6))
orrne \reg, #0x01000000
tst r8, #(0x02 << (PIXEL_BASE + 6))
orrne \reg, #0x04000000
tst r8, #(0x04 << (PIXEL_BASE + 6))
orrne \reg, #0x02000000
tst r8, #(0x10 << (PIXEL_BASE + 6))
orrne \reg, #0x08000000
.endm
.global cga_screen_pointer
.global cga_process_artifact
.global cga_render_words
.align 6
cga_rgbi_table:
.space 2048, 0
cga_screen_pointer:
.word 0
cga_write_pointer:
.word 0
cga_screen_blocks:
.word 0
cga_screen_pitch:
.word 0
cga_screen_flags:
.word 0
cga_screen_alpha:
.word 0
cga_screen_intensity:
.word 0
.align 6
// *** 16 bit ***
b preload_capture_line_default_twelvebits_16bpp
capture_line_ntsc_sixbits_16bpp_cga:
push {lr}
SETUP_VSYNC_DEBUG_16BPP_R11
subs r7, r7, #3
moveq r7, #1
movmi r7, #1
SKIP_PSYNC_NO_OLD_CPLD_HIGH_LATENCY
mov r1, r1, lsr #2
SETUP_TWELVE_BITS_MASK_R14
add r1, r1, #1
str r1, cga_screen_blocks
add r1, r1, #1
str r2, cga_screen_pitch
str r3, cga_screen_flags
str r11, cga_screen_alpha
str r12, cga_screen_intensity
adrl r5, cga_rgbi_table
loop_16bpp:
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_SIX_BITS_16BPP_LO r11 // input in r8
// WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_SIX_BITS_16BPP_HI r5 // input in r8
CAPTURE_SIX_BITS_16BPP_0 r6 // input in r8
CAPTURE_SIX_BITS_16BPP_1 r6 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_SIX_BITS_16BPP_LO r11 // input in r8
// WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_SIX_BITS_16BPP_HI r6 // input in r8
CAPTURE_SIX_BITS_16BPP_2 r6 // input in r8
CAPTURE_SIX_BITS_16BPP_3 r6 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_SIX_BITS_16BPP_LO r11 // input in r8
// WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_SIX_BITS_16BPP_HI r7 // input in r8
CAPTURE_SIX_BITS_16BPP_0 r7 // input in r8
CAPTURE_SIX_BITS_16BPP_1 r7 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_SIX_BITS_16BPP_LO r11 // input in r8
// WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_SIX_BITS_16BPP_HI r10 // input in r8
CAPTURE_SIX_BITS_16BPP_2 r7 // input in r8
CAPTURE_SIX_BITS_16BPP_3 r7 // input in r8
WRITE_R5_R6_R7_R10_16BPP
stmia r5!, {r6-r7}
subs r1, r1, #1
bne loop_16bpp
pop {r0, pc}
str r0, cga_screen_pointer
dmb
sev
pop {r0, pc}
cga_process_artifact:
push {lr}
ldr r2, cga_screen_pointer
str r2, cga_write_pointer
mov r3, #0
str r3, cga_screen_pointer
ldr r0, cga_screen_blocks
adrl r1, cga_rgbi_table
bl Composite_Process
pop {pc}
cga_render_words:
push {r4-r12, lr}
ldr r11, cga_screen_alpha
ldr r12, cga_screen_intensity
orr r5, r0, r11
orr r6, r1, r11
orr r7, r2, r11
orr r10, r3, r11
adrl r4, cga_write_pointer
ldmia r4, {r0-r3}
WRITE_R5_R6_R7_R10_16BPP
str r0, cga_write_pointer
pop {r4-r12, pc}
preload_capture_line_default_twelvebits_16bpp:
SETUP_DUMMY_PARAMETERS
b capture_line_ntsc_sixbits_16bpp_cga
.ltorg
.macro CAPTURE_SIX_BITS_MONO_16BPP_0 reg
// Pixel 0 in GPIO 7.. 2 -> 7.. 0
// Pixel 1 in GPIO 13.. 8 -> 15.. 8
mov \reg, #0
tst r8, #(0x02 << PIXEL_BASE)
orrne \reg, #0x0F
.endm
.macro CAPTURE_SIX_BITS_MONO_16BPP_1 reg
// Pixel 2 in GPIO 7.. 2 -> 23..16
// Pixel 3 in GPIO 13.. 8 -> 31..24
tst r8, #(0x02 << (PIXEL_BASE + 6))
orrne \reg, #0x0F00
.endm
.macro CAPTURE_SIX_BITS_MONO_16BPP_2 reg
// Pixel 0 in GPIO 7.. 2 -> 7.. 0
// Pixel 1 in GPIO 13.. 8 -> 15.. 8
tst r8, #(0x02 << PIXEL_BASE)
orrne \reg, #0x0F0000
.endm
.macro CAPTURE_SIX_BITS_MONO_16BPP_3 reg
// Pixel 2 in GPIO 7.. 2 -> 23..16
// Pixel 3 in GPIO 13.. 8 -> 31..24
tst r8, #(0x02 << (PIXEL_BASE + 6))
orrne \reg, #0x0F000000
.endm
.global capture_line_ntsc_sixbits_16bpp_mono
.global capture_line_ntsc_sixbits_16bpp_mono_auto
.ltorg
.align 6
// *** 16 bit ***
b preload_capture_line_default_twelvebits_16bpp
capture_line_ntsc_sixbits_16bpp_mono:
capture_line_ntsc_sixbits_16bpp_mono_auto:
push {lr}
SETUP_VSYNC_DEBUG_16BPP_R11
subs r7, r7, #3
moveq r7, #1
movmi r7, #1
SKIP_PSYNC_NO_OLD_CPLD_HIGH_LATENCY
mov r1, r1, lsr #2
add r1, r1, #1
str r1, cga_screen_blocks
add r1, r1, #1
str r2, cga_screen_pitch
str r3, cga_screen_flags
str r11, cga_screen_alpha
str r12, cga_screen_intensity
adrl r5, cga_rgbi_table
loop_16bpp_MONO:
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_SIX_BITS_MONO_16BPP_0 r6 // input in r8
CAPTURE_SIX_BITS_MONO_16BPP_1 r6 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_SIX_BITS_MONO_16BPP_2 r6 // input in r8
CAPTURE_SIX_BITS_MONO_16BPP_3 r6 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_SIX_BITS_MONO_16BPP_0 r7 // input in r8
CAPTURE_SIX_BITS_MONO_16BPP_1 r7 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_SIX_BITS_MONO_16BPP_2 r7 // input in r8
CAPTURE_SIX_BITS_MONO_16BPP_3 r7 // input in r8
stmia r5!, {r6-r7}
subs r1, r1, #1
bne loop_16bpp_MONO
str r0, cga_screen_pointer
dmb
sev
pop {r0, pc}

Wyświetl plik

@ -22,6 +22,8 @@
#define CACHED_SCREEN_SIZE 0x00100000 // size of cached screen area
#endif
#define USE_MULTICORE
// Define how the Pi Framebuffer is initialized
// - if defined, use the property interface (Channel 8)
// - if not defined, use to the the framebuffer interface (Channel 1)

Wyświetl plik

@ -821,6 +821,35 @@ skip_psync_loop_simple_fast_loop\@:
orr \reg2, r10, r10, lsl #8
.endm
.macro CAPTURE_SIX_BITS_16BPP reg1 reg2
// Pixel 0 in GPIO 7.. 2 -> 7.. 0
// Pixel 1 in GPIO 13.. 8 -> 15.. 8
and r9, r8, #(0x3f << PIXEL_BASE)
ldr r9, [r14, r9]
eor r10, r9, \reg1
and r9, r8, #(0x3f << (PIXEL_BASE + 6))
ldr r9, [r14, r9, lsr #6]
eor \reg2, r10, r9, lsl #16
.endm
.macro CAPTURE_SIX_BITS_DOUBLE_16BPP_LO reg1 reg2
// Pixel 0 in GPIO 7.. 2 -> 7.. 0
// Pixel 1 in GPIO 13.. 8 -> 15.. 8
and r9, r8, #(0x3f << PIXEL_BASE)
ldr r9, [r14, r9]
eor r10, r9, \reg1
eor \reg2, r10, r9, lsl #16
.endm
.macro CAPTURE_SIX_BITS_DOUBLE_16BPP_HI reg1 reg2
// Pixel 0 in GPIO 7.. 2 -> 7.. 0
// Pixel 1 in GPIO 13.. 8 -> 15.. 8
and r9, r8, #(0x3f << (PIXEL_BASE + 6))
ldr r9, [r14, r9, lsr #6]
eor r10, r9, \reg1
eor \reg2, r10, r9, lsl #16
.endm
.macro SETUP_EIGHT_BITS_MASK_R14
tst r3, #BIT_OSD
movne r14, #0x7f

332
src/osd.c
Wyświetl plik

@ -21,6 +21,7 @@
#include "fatfs/ff.h"
#include "jtag/update_cpld.h"
#include "startup.h"
#include "vid_cga_comp.h"
#include <math.h>
// =============================================================
@ -1110,6 +1111,19 @@ static void cycle_menus() {
cycle_menu(&settings_menu);
}
int get_tint(){
return tint;
}
int get_saturation(){
return saturation;
}
int get_contrast(){
return contrast;
}
int get_brightness(){
return brightness;
}
static int get_feature(int num) {
switch (num) {
case F_PROFILE:
@ -1319,18 +1333,22 @@ static void set_feature(int num, int value) {
case F_TINT:
tint = value;
osd_update_palette();
update_cga16_color();
break;
case F_SAT:
saturation = value;
osd_update_palette();
update_cga16_color();
break;
case F_CONT:
contrast = value;
osd_update_palette();
update_cga16_color();
break;
case F_BRIGHT:
brightness = value;
osd_update_palette();
update_cga16_color();
break;
case F_GAMMA:
Pgamma = value;
@ -4181,163 +4199,165 @@ void osd_write_palette(int new_active) {
}
void osd_update_palette() {
int r = 0;
int g = 0;
int b = 0;
int m = 0;
int num_colours = (capinfo->bpp >= 8) ? 256 : 16;
int design_type = (cpld->get_version() >> VERSION_DESIGN_BIT) & 0x0F;
//copy selected palette to current palette, translating for Atom cpld and inverted Y setting (required for 6847 direct Y connection)
for (int i = 0; i < num_colours; i++) {
int i_adj = i;
if (capinfo->bpp == 8 && capinfo->sample_width >= SAMPLE_WIDTH_9LO) {
//if capturing 9 or 12bpp to an 8bpp frame buffer bits are captured in the wrong order so rearrange the palette order to match
//convert B1,G3,G2,R3,R2,B3,B2,R1
//to B1,R1,B2,G2,R2,B3,G3,R3
i_adj = ((i & 0x01) << 6)
| ((i & 0x02) << 4)
| (i & 0x8c)
| ((i & 0x10) >> 4)
| ((i & 0x20) >> 1)
| ((i & 0x40) >> 5);
}
if(design_type == DESIGN_ATOM) {
switch (i) {
case 0x00:
i_adj = 0x00 | (bz + rz); break; //black
case 0x01:
i_adj = 0x10 | (bz + rp); break; //red
case 0x02:
i_adj = 0x10 | (bm + rm); break; //green
case 0x03:
i_adj = 0x12 | (bm + rz); break; //yellow
case 0x04:
i_adj = 0x10 | (bp + rz); break; //blue
case 0x05:
i_adj = 0x10 | (bp + rp); break; //magenta
case 0x06:
i_adj = 0x10 | (bz + rm); break; //cyan
case 0x07:
i_adj = 0x12 | (bz + rz); break; //white
case 0x0b:
i_adj = 0x10 | (bm + rp); break; //orange
case 0x13:
i_adj = 0x12 | (bm + rp); break; //bright orange
case 0x08:
i_adj = 0x00 | (bm + rm); break; //dark green
case 0x10:
i_adj = 0x00 | (bm + rp); break; //dark orange
default:
i_adj = 0x00 | (bz + rz); break; //black
}
}
if (((get_paletteControl() == PALETTECONTROL_NTSCARTIFACT_CGA && get_ntsccolour() != 0)
|| (get_paletteControl() == PALETTECONTROL_NTSCARTIFACT_BW)
|| (get_paletteControl() == PALETTECONTROL_NTSCARTIFACT_BW_AUTO))
&& capinfo->bpp == 8 && capinfo->sample_width <= SAMPLE_WIDTH_6) {
if ((i & 0x7f) < 0x40) {
if (get_paletteControl() == PALETTECONTROL_NTSCARTIFACT_CGA) {
palette_data[i] = create_NTSC_artifact_colours_palette_320(i & 0x7f);
} else {
palette_data[i] = palette_array[palette][i_adj];
}
} else {
int filtered_bitcount = ((i & 0x3f) >> 4) + 1;
palette_data[i] = create_NTSC_artifact_colours(i & 0x3f, filtered_bitcount);
}
} else {
if (get_feature(F_INVERT) == INVERT_Y) {
i_adj ^= 0x12;
}
palette_data[i] = palette_array[palette][i_adj];
}
palette_data[i] = adjust_palette(palette_data[i]);
}
//scan translated palette for equivalences
for (int i = 0; i < num_colours; i++) {
for(int j = 0; j < num_colours; j++) {
if (palette_data[i] == palette_data[j]) {
equivalence[i] = (char) j;
break;
}
}
}
// modify translated palette for remaining settings
for (int i = 0; i < num_colours; i++) {
if (paletteFlags & BIT_MODE2_PALETTE) {
r = customPalette[i & 0x7f] & 0xff;
g = (customPalette[i & 0x7f]>>8) & 0xff;
b = (customPalette[i & 0x7f]>>16) & 0xff;
m = ((299 * r + 587 * g + 114 * b + 500) / 1000);
if (m > 255) {
m = 255;
}
} else {
r = palette_data[i] & 0xff;
g = (palette_data[i] >> 8) & 0xff;
b = (palette_data[i] >>16) & 0xff;
m = (palette_data[i] >>24);
}
if (get_feature(F_INVERT) == INVERT_RGB) {
r = 255 - r;
g = 255 - g;
b = 255 - b;
m = 255 - m;
}
if (get_feature(F_COLOUR) != COLOUR_NORMAL) {
switch (get_feature(F_COLOUR)) {
case COLOUR_MONO:
r = m;
g = m;
b = m;
break;
case COLOUR_GREEN:
r = 0;
g = m;
b = 0;
break;
case COLOUR_AMBER:
r = m*0xdf/0xff;
g = m;
b = 0;
break;
}
}
palette_data_16[i] = ((r >> 4) << 8) | ((g >> 4) << 4) | (b >> 4);
if (i >= (num_colours >> 1)) {
osd_palette_data[i] = 0xFFFFFFFF;
} else {
if (!inhibit_palette_dimming) {
osd_palette_data[i] = 0xFF000000 | ((b >> 1) << 16) | ((g >> 1) << 8) | (r >> 1);
} else {
osd_palette_data[i] = 0xFF000000 | (b << 16) | (g << 8) | r;
}
}
if ((i >= (num_colours >> 1)) && get_feature(F_SCANLINES)) {
int scanline_intensity = get_feature(F_SCANLINESINT) ;
r = (r * scanline_intensity) / 15;
g = (g * scanline_intensity) / 15;
b = (b * scanline_intensity) / 15;
palette_data[i] = 0xFF000000 | (b << 16) | (g << 8) | r;
} else {
palette_data[i] = 0xFF000000 | (b << 16) | (g << 8) | r;
}
if (get_debug()) {
palette_data[i] |= 0x00101010;
osd_palette_data[i] |= 0x00101010;
}
}
if (capinfo->bpp < 16) {
int r = 0;
int g = 0;
int b = 0;
int m = 0;
int num_colours = (capinfo->bpp == 8) ? 256 : 16;
int design_type = (cpld->get_version() >> VERSION_DESIGN_BIT) & 0x0F;
//copy selected palette to current palette, translating for Atom cpld and inverted Y setting (required for 6847 direct Y connection)
for (int i = 0; i < num_colours; i++) {
int i_adj = i;
if (capinfo->bpp == 8 && capinfo->sample_width >= SAMPLE_WIDTH_9LO) {
//if capturing 9 or 12bpp to an 8bpp frame buffer bits are captured in the wrong order so rearrange the palette order to match
//convert B1,G3,G2,R3,R2,B3,B2,R1
//to B1,R1,B2,G2,R2,B3,G3,R3
i_adj = ((i & 0x01) << 6)
| ((i & 0x02) << 4)
| (i & 0x8c)
| ((i & 0x10) >> 4)
| ((i & 0x20) >> 1)
| ((i & 0x40) >> 5);
}
if(design_type == DESIGN_ATOM) {
switch (i) {
case 0x00:
i_adj = 0x00 | (bz + rz); break; //black
case 0x01:
i_adj = 0x10 | (bz + rp); break; //red
case 0x02:
i_adj = 0x10 | (bm + rm); break; //green
case 0x03:
i_adj = 0x12 | (bm + rz); break; //yellow
case 0x04:
i_adj = 0x10 | (bp + rz); break; //blue
case 0x05:
i_adj = 0x10 | (bp + rp); break; //magenta
case 0x06:
i_adj = 0x10 | (bz + rm); break; //cyan
case 0x07:
i_adj = 0x12 | (bz + rz); break; //white
case 0x0b:
i_adj = 0x10 | (bm + rp); break; //orange
case 0x13:
i_adj = 0x12 | (bm + rp); break; //bright orange
case 0x08:
i_adj = 0x00 | (bm + rm); break; //dark green
case 0x10:
i_adj = 0x00 | (bm + rp); break; //dark orange
default:
i_adj = 0x00 | (bz + rz); break; //black
}
}
if (((get_paletteControl() == PALETTECONTROL_NTSCARTIFACT_CGA && get_ntsccolour() != 0)
|| (get_paletteControl() == PALETTECONTROL_NTSCARTIFACT_BW)
|| (get_paletteControl() == PALETTECONTROL_NTSCARTIFACT_BW_AUTO))
&& capinfo->bpp == 8 && capinfo->sample_width <= SAMPLE_WIDTH_6) {
if ((i & 0x7f) < 0x40) {
if (get_paletteControl() == PALETTECONTROL_NTSCARTIFACT_CGA) {
palette_data[i] = create_NTSC_artifact_colours_palette_320(i & 0x7f);
} else {
palette_data[i] = palette_array[palette][i_adj];
}
} else {
int filtered_bitcount = ((i & 0x3f) >> 4) + 1;
palette_data[i] = create_NTSC_artifact_colours(i & 0x3f, filtered_bitcount);
}
} else {
if (get_feature(F_INVERT) == INVERT_Y) {
i_adj ^= 0x12;
}
palette_data[i] = palette_array[palette][i_adj];
}
palette_data[i] = adjust_palette(palette_data[i]);
}
//scan translated palette for equivalences
for (int i = 0; i < num_colours; i++) {
for(int j = 0; j < num_colours; j++) {
if (palette_data[i] == palette_data[j]) {
equivalence[i] = (char) j;
break;
}
}
}
// modify translated palette for remaining settings
for (int i = 0; i < num_colours; i++) {
if (paletteFlags & BIT_MODE2_PALETTE) {
r = customPalette[i & 0x7f] & 0xff;
g = (customPalette[i & 0x7f]>>8) & 0xff;
b = (customPalette[i & 0x7f]>>16) & 0xff;
m = ((299 * r + 587 * g + 114 * b + 500) / 1000);
if (m > 255) {
m = 255;
}
} else {
r = palette_data[i] & 0xff;
g = (palette_data[i] >> 8) & 0xff;
b = (palette_data[i] >>16) & 0xff;
m = (palette_data[i] >>24);
}
if (get_feature(F_INVERT) == INVERT_RGB) {
r = 255 - r;
g = 255 - g;
b = 255 - b;
m = 255 - m;
}
if (get_feature(F_COLOUR) != COLOUR_NORMAL) {
switch (get_feature(F_COLOUR)) {
case COLOUR_MONO:
r = m;
g = m;
b = m;
break;
case COLOUR_GREEN:
r = 0;
g = m;
b = 0;
break;
case COLOUR_AMBER:
r = m*0xdf/0xff;
g = m;
b = 0;
break;
}
}
if (i >= (num_colours >> 1)) {
osd_palette_data[i] = 0xFFFFFFFF;
} else {
if (!inhibit_palette_dimming) {
osd_palette_data[i] = 0xFF000000 | ((b >> 1) << 16) | ((g >> 1) << 8) | (r >> 1);
} else {
osd_palette_data[i] = 0xFF000000 | (b << 16) | (g << 8) | r;
}
}
if ((i >= (num_colours >> 1)) && get_feature(F_SCANLINES)) {
int scanline_intensity = get_feature(F_SCANLINESINT) ;
r = (r * scanline_intensity) / 15;
g = (g * scanline_intensity) / 15;
b = (b * scanline_intensity) / 15;
palette_data[i] = 0xFF000000 | (b << 16) | (g << 8) | r;
} else {
palette_data[i] = 0xFF000000 | (b << 16) | (g << 8) | r;
}
if (get_debug()) {
palette_data[i] |= 0x00101010;
osd_palette_data[i] |= 0x00101010;
}
}
RPI_PropertyInit();
if (active) {
RPI_PropertyAddTag(TAG_SET_PALETTE, num_colours, osd_palette_data);

Wyświetl plik

@ -14,6 +14,7 @@ extern int clock_error_ppm;
extern int customPalette[];
extern char paletteHighNibble[];
extern int paletteFlags;
extern int palette_data_16[];
enum {
HDMI_EXACT,
@ -211,7 +212,10 @@ enum {
FRINGE_SOFT,
NUM_FRINGE
};
int get_tint();
int get_saturation();
int get_contrast();
int get_brightness();
void osd_init();
void osd_clear();
void osd_write_palette(int new_active);

Wyświetl plik

@ -43,6 +43,7 @@
.global param_sync_edge
.global sw1_power_up
.global osd_timer
.global palette_data_16
.global field_type_threshold
.global elk_lo_field_sync_threshold
@ -2297,16 +2298,23 @@ gpu_bench:
#ifdef USE_MULTICORE
.ltorg
run_core:
mov r0, 0
mov r1, 0
mov r0, #0
mov r1, #0
bl enable_MMU_and_IDCaches
// bl _enable_unaligned_access //do not use for an armv6 to armv8 compatible binary
bl _init_cycle_counter
run_core_loop:
wfe
wfe // put core to sleep until an event
ldr r0, =cga_screen_pointer
wait_for_address:
ldr r1, [r0]
cmp r1, #0
beq wait_for_address
bl cga_process_artifact
b run_core_loop
#endif
.ltorg
.align 6
customPalette:
.space 2048, 0
@ -2423,9 +2431,9 @@ capture_line_normal_6bpp_table:
.word capture_line_default_sixbits_8bpp // placeholder inband
.word capture_line_ntsc_sixbits_16bpp_cga
.word capture_line_ntsc_sixbits_8bpp_cga
.word capture_line_default_sixbits_16bpp
.word capture_line_ntsc_sixbits_16bpp_mono
.word capture_line_ntsc_sixbits_8bpp_mono
.word capture_line_default_sixbits_16bpp
.word capture_line_ntsc_sixbits_16bpp_mono_auto
.word capture_line_ntsc_sixbits_8bpp_mono_auto
.word capture_line_default_sixbits_16bpp
.word capture_line_default_sixbits_8bpp
@ -3305,6 +3313,11 @@ poll_keys_exit:
mov pc, lr
.ltorg
.align 6
palette_data_16:
.space (256*4), 0
.align 6
line_buffer:
.space 4096, 0

Wyświetl plik

@ -22,6 +22,8 @@ extern int clear_menu_bits();
extern int measure_n_lines(int n);
extern int get_cycle_counter();
extern int validate_cga(int rgbi_pixels);
extern int cga_render_words(uint32_t srgb0, uint32_t srgb1, uint32_t srgb2, uint32_t srgb3);
extern int sw1counter;

Wyświetl plik

@ -2930,6 +2930,7 @@ void set_ntscphase(int value) {
if (ntscphase != value) {
ntscphase = value;
osd_update_palette();
update_cga16_color();
}
}
@ -2939,6 +2940,7 @@ int get_ntscphase() {
void set_ntscfringe(int value) {
ntscfringe = value;
update_cga16_color();
}
int get_ntscfringe() {
@ -3350,17 +3352,21 @@ void rgb_to_hdmi_main() {
log_info("ARM: GPIO read = %dns, MBOX read = %dns, Triple MBOX read = %dns (%dns/word)", (int)((double) benchmarkRAM(3) * 1000 / cpuspeed / 100000 + 0.5), (int)((double) benchmarkRAM(4) * 1000 / cpuspeed / 100000 + 0.5), triple, triple / 3);
log_info("GPU: GPIO read = %dns, MBOX write = %dns", (int)((double) benchmarkRAM(1) * 1000 / cpuspeed / 100000 + 0.5), (int)((double) benchmarkRAM(2) * 1000 / cpuspeed / 100000 + 0.5));
log_info("RAM: Cached read = %dns, Uncached screen read = %dns", (int)((double) benchmarkRAM(0x2000000) * 1000 / cpuspeed / 100000 + 0.5), (int)((double) benchmarkRAM((int)capinfo->fb) * 1000 / cpuspeed / 100000 + 0.5));
//***********test CGA artifact decode*********************
cga_comp_init(0);
Bit32u pixels[1024];
//***********test CGA artifact decode*********************
update_cga16_color();
Bit8u pixels[1024];
for(int i=0; i<1024;i++) pixels[i] = i & 0x0f; //put some 4 bit pixel data in the pixel words
int startcycle = get_cycle_counter();
Composite_Process(0, 720/4, pixels); //720 pixels to include some border
int startcycle = get_cycle_counter();
Composite_Process(720/8, pixels, 0); //720 pixels to include some border
int duration = abs(get_cycle_counter() - startcycle);
log_info("CGA 720 pixel artifact decode: = %dns", duration);
//***********end of test CGA artifact decode***************
log_info("Composite_Process 720 pixel artifact decode: = %dns", duration);
startcycle = get_cycle_counter();
Test_Composite_Process(720/8, pixels, 0); //720 pixels to include some border
duration = abs(get_cycle_counter() - startcycle);
log_info("Test_Composite_Process 720 pixel artifact decode: = %dns", duration);
//***********end of test CGA artifact decode***************
if (cpld_fail_state == CPLD_MANUAL) {
@ -3533,7 +3539,6 @@ void rgb_to_hdmi_main() {
result = rgb_to_fb(capinfo, flags);
log_debug("Leaving rgb_to_fb, result=%04x", result);
if (result & RET_SYNC_TIMING_CHANGED) {
log_info("Timing exceeds window: H=%d, V=%d, Lines=%d, VSync=%d", hsync_period * 1000 / cpuspeed, (int)((double)vsync_period * 1000 / cpuspeed), (int) (((double)vsync_period/hsync_period) + 0.5), (result & RET_VSYNC_POLARITY_CHANGED) ? 1 : 0);
}

Wyświetl plik

@ -1,21 +1,21 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
* This file is part of the 86Box distribution.
*
* IBM CGA composite filter, borrowed from reenigne's DOSBox
* patch and ported to C.
* IBM CGA composite filter, borrowed from reenigne's DOSBox
* patch and ported to C.
*
* modified for RGBtoHDMI
*
* Authors: reenigne,
* Miran Grca, <mgrca8@gmail.com>
*
* Authors: reenigne,
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2015-2019 reenigne.
* Copyright 2015-2019 Miran Grca.
* Copyright 2015-2019 reenigne.
* Copyright 2015-2019 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
@ -25,9 +25,10 @@
#include <math.h>
#include <stdbool.h>
#include "defs.h"
int CGA_Composite_Table[1024];
#include "osd.h"
#include "rgb_to_fb.h"
#include "vid_cga_comp.h"
#include "rgb_to_hdmi.h"
static double brightness = 0;
@ -35,6 +36,7 @@ static double contrast = 100;
static double saturation = 100;
static double sharpness = 0;
static double hue_offset = 0;
static int ntsc_pixel_phase = 0;
/* New algorithm by reenigne
Works in all CGA modes/color settings and can simulate older and newer CGA revisions */
@ -42,25 +44,25 @@ static double hue_offset = 0;
static const double tau = 6.28318531; /* == 2*pi */
static unsigned char chroma_multiplexer[256] = {
2, 2, 2, 2, 114,174, 4, 3, 2, 1,133,135, 2,113,150, 4,
133, 2, 1, 99, 151,152, 2, 1, 3, 2, 96,136, 151,152,151,152,
2, 56, 62, 4, 111,250,118, 4, 0, 51,207,137, 1,171,209, 5,
140, 50, 54,100, 133,202, 57, 4, 2, 50,153,149, 128,198,198,135,
32, 1, 36, 81, 147,158, 1, 42, 33, 1,210,254, 34,109,169, 77,
177, 2, 0,165, 189,154, 3, 44, 33, 0, 91,197, 178,142,144,192,
4, 2, 61, 67, 117,151,112, 83, 4, 0,249,255, 3,107,249,117,
147, 1, 50,162, 143,141, 52, 54, 3, 0,145,206, 124,123,192,193,
72, 78, 2, 0, 159,208, 4, 0, 53, 58,164,159, 37,159,171, 1,
248,117, 4, 98, 212,218, 5, 2, 54, 59, 93,121, 176,181,134,130,
1, 61, 31, 0, 160,255, 34, 1, 1, 58,197,166, 0,177,194, 2,
162,111, 34, 96, 205,253, 32, 1, 1, 57,123,125, 119,188,150,112,
78, 4, 0, 75, 166,180, 20, 38, 78, 1,143,246, 42,113,156, 37,
252, 4, 1,188, 175,129, 1, 37, 118, 4, 88,249, 202,150,145,200,
61, 59, 60, 60, 228,252,117, 77, 60, 58,248,251, 81,212,254,107,
198, 59, 58,169, 250,251, 81, 80, 100, 58,154,250, 251,252,252,252};
2, 2, 2, 2, 114,174, 4, 3, 2, 1,133,135, 2,113,150, 4,
133, 2, 1, 99, 151,152, 2, 1, 3, 2, 96,136, 151,152,151,152,
2, 56, 62, 4, 111,250,118, 4, 0, 51,207,137, 1,171,209, 5,
140, 50, 54,100, 133,202, 57, 4, 2, 50,153,149, 128,198,198,135,
32, 1, 36, 81, 147,158, 1, 42, 33, 1,210,254, 34,109,169, 77,
177, 2, 0,165, 189,154, 3, 44, 33, 0, 91,197, 178,142,144,192,
4, 2, 61, 67, 117,151,112, 83, 4, 0,249,255, 3,107,249,117,
147, 1, 50,162, 143,141, 52, 54, 3, 0,145,206, 124,123,192,193,
72, 78, 2, 0, 159,208, 4, 0, 53, 58,164,159, 37,159,171, 1,
248,117, 4, 98, 212,218, 5, 2, 54, 59, 93,121, 176,181,134,130,
1, 61, 31, 0, 160,255, 34, 1, 1, 58,197,166, 0,177,194, 2,
162,111, 34, 96, 205,253, 32, 1, 1, 57,123,125, 119,188,150,112,
78, 4, 0, 75, 166,180, 20, 38, 78, 1,143,246, 42,113,156, 37,
252, 4, 1,188, 175,129, 1, 37, 118, 4, 88,249, 202,150,145,200,
61, 59, 60, 60, 228,252,117, 77, 60, 58,248,251, 81,212,254,107,
198, 59, 58,169, 250,251, 81, 80, 100, 58,154,250, 251,252,252,252};
static double intensity[4] = {
77.175381, 88.654656, 166.564623, 174.228438};
77.175381, 88.654656, 166.564623, 174.228438};
#define NEW_CGA(c,i,r,g,b) (((c)/0.72)*0.29 + ((i)/0.28)*0.32 + ((r)/0.28)*0.1 + ((g)/0.28)*0.22 + ((b)/0.28)*0.07)
@ -70,18 +72,18 @@ double mode_hue;
double min_v;
double max_v;
int video_ri, video_rq, video_gi, video_gq, video_bi, video_bq;
int video_sharpness;
int tandy_mode_control = 0;
static bool new_cga = 0;
static bool new_cga;
void update_cga16_color(uint8_t cgamode) {
int x;
double c, i, v;
double q, a, s, r;
double iq_adjust_i, iq_adjust_q;
double i0, i3, mode_saturation;
static int cgamode = 0;
void update_cga16_color() {
int x;
double c, i, v;
double q, a, s, r;
double iq_adjust_i, iq_adjust_q;
double i0, i3, mode_saturation;
static const double ri = 0.9563;
static const double rq = 0.6210;
@ -90,6 +92,28 @@ void update_cga16_color(uint8_t cgamode) {
static const double bi = -1.1069;
static const double bq = 1.7046;
brightness = get_brightness() - 100;
contrast = get_contrast();
saturation = get_saturation();
hue_offset = get_tint();
ntsc_pixel_phase = ((get_ntscphase() ^ 3) + 1) & 3; //reorder to match existing artifact code
switch(get_ntscfringe()) {
default:
case 0:
sharpness = 0;
break;
case 1:
sharpness = 50;
break;
case 2:
sharpness = 0;
break;
}
new_cga = 0;
if (!new_cga) {
min_v = chroma_multiplexer[0] + intensity[0];
max_v = chroma_multiplexer[255] + intensity[3];
@ -155,8 +179,8 @@ void update_cga16_color(uint8_t cgamode) {
}
static Bit8u byte_clamp(int v) {
v >>= 13;
return v < 0 ? 0 : (v > 255 ? 255 : v);
v >>= (13 + 4);
return v < 0 ? 0 : (v > 15 ? 15 : v);
}
/* 2048x1536 is the maximum we can possibly support. */
@ -166,21 +190,20 @@ static int temp[SCALER_MAXWIDTH + 10]={0};
static int atemp[SCALER_MAXWIDTH + 2]={0};
static int btemp[SCALER_MAXWIDTH + 2]={0};
Bit32u * Composite_Process(uint8_t cgamode, Bit32u blocks, Bit32u *TempLine)
void Composite_Process(Bit32u blocks, Bit8u *rgbi, int render)
{
Bit8u border = 0;
int x;
Bit32u x2;
int x;
Bit32u x2;
int w = blocks*8;
int *o;
int *i;
int *ap, *bp;
int w = blocks*4;
int *o;
Bit32u *rgbi;
int *b;
int *i;
Bit32u* srgb;
int *ap, *bp;
uint32_t temp_srgb;
uint32_t srgb0;
uint32_t srgb1;
uint32_t srgb2;
uint32_t srgb3;
#define COMPOSITE_CONVERT(I, Q) do { \
i[1] = (i[1]<<3) - ap[1]; \
@ -195,150 +218,125 @@ Bit32u * Composite_Process(uint8_t cgamode, Bit32u blocks, Bit32u *TempLine)
++i; \
++ap; \
++bp; \
*srgb = (byte_clamp(rr)<<16) | (byte_clamp(gg)<<8) | byte_clamp(bb); \
++srgb; \
} while (0)
#define OUT(v) do { *o = (v); ++o; } while (0)
/* Simulate CGA composite output */
o = temp;
rgbi = TempLine;
b = &CGA_Composite_Table[border*68];
for (x = 0; x < 4; ++x)
OUT(b[(x+3)&3]);
OUT(CGA_Composite_Table[(border<<6) | ((*rgbi & 0x0f)<<2) | 3]);
for (x = 0; x < w-1; ++x) {
OUT(CGA_Composite_Table[((rgbi[0] & 0x0f)<<6) | ((rgbi[1] & 0x0f)<<2) | (x&3)]);
for (x = 0; x < w; ++x) {
OUT(CGA_Composite_Table[(((Bit32u)rgbi[0] & 0x0f)<<6) | (((Bit32u)rgbi[1] & 0x0f)<<2) | ((x + ntsc_pixel_phase) & 3)]);
++rgbi;
}
OUT(CGA_Composite_Table[((*rgbi & 0x0f)<<6) | (border<<2) | 3]);
for (x = 0; x < 5; ++x)
OUT(b[x&3]);
if ((cgamode & 4) != 0) {
/* Decode */
i = temp + 5;
srgb = (Bit32u *)TempLine;
for (x2 = 0; x2 < blocks*4; ++x2) {
int c = (i[0]+i[0])<<3;
int d = (i[-1]+i[1])<<3;
int y = ((c+d)<<8) + video_sharpness*(c-d);
++i;
*srgb = byte_clamp(y)*0x10101;
++srgb;
}
/* Store chroma */
i = temp + 4;
ap = atemp + 1;
bp = btemp + 1;
for (x = -1; x < w + 1; ++x) {
ap[x] = i[-4]-((i[-2]-i[0]+i[2])<<1)+i[4];
bp[x] = (i[-3]-i[-1]+i[1]-i[3])<<1;
++i;
}
else {
/* Store chroma */
i = temp + 4;
ap = atemp + 1;
bp = btemp + 1;
for (x = -1; x < w + 1; ++x) {
ap[x] = i[-4]-((i[-2]-i[0]+i[2])<<1)+i[4];
bp[x] = (i[-3]-i[-1]+i[1]-i[3])<<1;
++i;
}
/* Decode */
i = temp + 5;
i[-1] = (i[-1]<<3) - ap[-1];
i[0] = (i[0]<<3) - ap[0];
srgb = (Bit32u *)TempLine;
for (x2 = 0; x2 < blocks; ++x2) {
int y,a,b,c,d,rr,gg,bb;
COMPOSITE_CONVERT(a, b);
COMPOSITE_CONVERT(-b, a);
COMPOSITE_CONVERT(-a, -b);
COMPOSITE_CONVERT(b, -a);
}
/* Decode */
i = temp + 5;
i[-1] = (i[-1]<<3) - ap[-1];
i[0] = (i[0]<<3) - ap[0];
for (x2 = 0; x2 < blocks - 1; ++x2) {
int y,a,b,c,d,rr,gg,bb;
switch (ntsc_pixel_phase) {
default:
case 0:
COMPOSITE_CONVERT(a, b);
temp_srgb = (byte_clamp(rr)<<8) | (byte_clamp(gg)<<4) | byte_clamp(bb);
COMPOSITE_CONVERT(-b, a);
srgb0 = temp_srgb | (byte_clamp(rr)<<24) | (byte_clamp(gg)<<20) | byte_clamp(bb)<<16;
COMPOSITE_CONVERT(-a, -b);
temp_srgb = (byte_clamp(rr)<<8) | (byte_clamp(gg)<<4) | byte_clamp(bb);
COMPOSITE_CONVERT(b, -a);
srgb1 = temp_srgb | (byte_clamp(rr)<<24) | (byte_clamp(gg)<<20) | byte_clamp(bb)<<16;
COMPOSITE_CONVERT(a, b);
temp_srgb = (byte_clamp(rr)<<8) | (byte_clamp(gg)<<4) | byte_clamp(bb);
COMPOSITE_CONVERT(-b, a);
srgb2 = temp_srgb | (byte_clamp(rr)<<24) | (byte_clamp(gg)<<20) | byte_clamp(bb)<<16;
COMPOSITE_CONVERT(-a, -b);
temp_srgb = (byte_clamp(rr)<<8) | (byte_clamp(gg)<<4) | byte_clamp(bb);
COMPOSITE_CONVERT(b, -a);
srgb3 = temp_srgb | (byte_clamp(rr)<<24) | (byte_clamp(gg)<<20) | byte_clamp(bb)<<16;
break;
case 1:
COMPOSITE_CONVERT(-b, a);
temp_srgb = (byte_clamp(rr)<<8) | (byte_clamp(gg)<<4) | byte_clamp(bb);
COMPOSITE_CONVERT(-a, -b);
srgb0 = temp_srgb | (byte_clamp(rr)<<24) | (byte_clamp(gg)<<20) | byte_clamp(bb)<<16;
COMPOSITE_CONVERT(b, -a);
temp_srgb = (byte_clamp(rr)<<8) | (byte_clamp(gg)<<4) | byte_clamp(bb);
COMPOSITE_CONVERT(a, b);
srgb1 = temp_srgb | (byte_clamp(rr)<<24) | (byte_clamp(gg)<<20) | byte_clamp(bb)<<16;
COMPOSITE_CONVERT(-b, a);
temp_srgb = (byte_clamp(rr)<<8) | (byte_clamp(gg)<<4) | byte_clamp(bb);
COMPOSITE_CONVERT(-a, -b);
srgb2 = temp_srgb | (byte_clamp(rr)<<24) | (byte_clamp(gg)<<20) | byte_clamp(bb)<<16;
COMPOSITE_CONVERT(b, -a);
temp_srgb = (byte_clamp(rr)<<8) | (byte_clamp(gg)<<4) | byte_clamp(bb);
COMPOSITE_CONVERT(a, b);
srgb3 = temp_srgb | (byte_clamp(rr)<<24) | (byte_clamp(gg)<<20) | byte_clamp(bb)<<16;
break;
case 2:
COMPOSITE_CONVERT(-a, -b);
temp_srgb = (byte_clamp(rr)<<8) | (byte_clamp(gg)<<4) | byte_clamp(bb);
COMPOSITE_CONVERT(b, -a);
srgb0 = temp_srgb | (byte_clamp(rr)<<24) | (byte_clamp(gg)<<20) | byte_clamp(bb)<<16;
COMPOSITE_CONVERT(a, b);
temp_srgb = (byte_clamp(rr)<<8) | (byte_clamp(gg)<<4) | byte_clamp(bb);
COMPOSITE_CONVERT(-b, a);
srgb1 = temp_srgb | (byte_clamp(rr)<<24) | (byte_clamp(gg)<<20) | byte_clamp(bb)<<16;
COMPOSITE_CONVERT(-a, -b);
temp_srgb = (byte_clamp(rr)<<8) | (byte_clamp(gg)<<4) | byte_clamp(bb);
COMPOSITE_CONVERT(b, -a);
srgb2 = temp_srgb | (byte_clamp(rr)<<24) | (byte_clamp(gg)<<20) | byte_clamp(bb)<<16;
COMPOSITE_CONVERT(a, b);
temp_srgb = (byte_clamp(rr)<<8) | (byte_clamp(gg)<<4) | byte_clamp(bb);
COMPOSITE_CONVERT(-b, a);
srgb3 = temp_srgb | (byte_clamp(rr)<<24) | (byte_clamp(gg)<<20) | byte_clamp(bb)<<16;
break;
case 3:
COMPOSITE_CONVERT(b, -a);
temp_srgb = (byte_clamp(rr)<<8) | (byte_clamp(gg)<<4) | byte_clamp(bb);
COMPOSITE_CONVERT(a, b);
srgb0 = temp_srgb | (byte_clamp(rr)<<24) | (byte_clamp(gg)<<20) | byte_clamp(bb)<<16;
COMPOSITE_CONVERT(-b, a);
temp_srgb = (byte_clamp(rr)<<8) | (byte_clamp(gg)<<4) | byte_clamp(bb);
COMPOSITE_CONVERT(-a, -b);
srgb1 = temp_srgb | (byte_clamp(rr)<<24) | (byte_clamp(gg)<<20) | byte_clamp(bb)<<16;
COMPOSITE_CONVERT(b, -a);
temp_srgb = (byte_clamp(rr)<<8) | (byte_clamp(gg)<<4) | byte_clamp(bb);
COMPOSITE_CONVERT(a, b);
srgb2 = temp_srgb | (byte_clamp(rr)<<24) | (byte_clamp(gg)<<20) | byte_clamp(bb)<<16;
COMPOSITE_CONVERT(-b, a);
temp_srgb = (byte_clamp(rr)<<8) | (byte_clamp(gg)<<4) | byte_clamp(bb);
COMPOSITE_CONVERT(-a, -b);
srgb3 = temp_srgb | (byte_clamp(rr)<<24) | (byte_clamp(gg)<<20) | byte_clamp(bb)<<16;
break;
}
if (render)
cga_render_words(srgb0, srgb1, srgb2, srgb3); //renders 8 pixels at a time to the uncached screen using stmia for speed
}
#undef COMPOSITE_CONVERT
#undef OUT
return TempLine;
}
void IncreaseHue(uint8_t cgamode)
{
hue_offset += 5.0;
update_cga16_color(cgamode);
void Test_Composite_Process(Bit32u blocks, Bit8u *rgbi, int render) {
Composite_Process(blocks, rgbi, render);
}
void DecreaseHue(uint8_t cgamode)
{
hue_offset -= 5.0;
update_cga16_color(cgamode);
}
void IncreaseSaturation(uint8_t cgamode)
{
saturation += 5;
update_cga16_color(cgamode);
}
void DecreaseSaturation(uint8_t cgamode)
{
saturation -= 5;
update_cga16_color(cgamode);
}
void IncreaseContrast(uint8_t cgamode)
{
contrast += 5;
update_cga16_color(cgamode);
}
void DecreaseContrast(uint8_t cgamode)
{
contrast -= 5;
update_cga16_color(cgamode);
}
void IncreaseBrightness(uint8_t cgamode)
{
brightness += 5;
update_cga16_color(cgamode);
}
void DecreaseBrightness(uint8_t cgamode)
{
brightness -= 5;
update_cga16_color(cgamode);
}
void IncreaseSharpness(uint8_t cgamode)
{
sharpness += 10;
update_cga16_color(cgamode);
}
void DecreaseSharpness(uint8_t cgamode)
{
sharpness -= 10;
update_cga16_color(cgamode);
}
void cga_comp_init(int revision)
{
new_cga = revision;
/* Making sure this gets reset after reset. */
brightness = 0;
contrast = 100;
saturation = 100;
sharpness = 0;
hue_offset = 0;
update_cga16_color(0);
}

Wyświetl plik

@ -1,3 +1,7 @@
void update_cga16_color(uint8_t cgamode);
Bit32u * Composite_Process(uint8_t cgamode, Bit32u blocks, Bit32u *TempLine);
void cga_comp_init(int revision);
int CGA_Composite_Table[1024];
int video_sharpness;
int video_ri, video_rq, video_gi, video_gq, video_bi, video_bq;
void update_cga16_color();
void Composite_Process(Bit32u blocks, Bit8u *rgbi, int render);
void Test_Composite_Process(Bit32u blocks, Bit8u *rgbi, int render);