Color Artifact Changes

This changeset improves the horizontal resolution of the color DHGR rendering and fixes double-lores rendering.  HGR rendering has been rewritten to match the new DHGR rendering.  DHGR, HGR and DGR modes now have a horizontal stippling effect applied.

The DHGR & HGR changes can be reverted at runtime with bit 3 of the $C0n1 register.
This commit is contained in:
David Kuder 2023-04-25 01:55:14 -04:00
parent d46ae93e6a
commit dfd848713b
7 changed files with 337 additions and 114 deletions

View File

@ -105,6 +105,7 @@ extern volatile uint32_t internal_flags;
#define SOFTSW_SHADOW_IO 0x04000000
// V2 Analog specific softswitches
#define IFLAGS_OLDCOLOR 0x08000000
#define SOFTSW_TERMINAL 0x10000000
#define IFLAGS_TEST 0x20000000
#define IFLAGS_IIE_REGS 0x40000000

View File

@ -213,6 +213,11 @@ void __time_critical_func(vga_businterface)(uint32_t address, uint32_t value) {
switch(address & 0x0F) {
case 0x01:
mono_palette = (value >> 4) & 0xF;
if(value & 0x8) {
internal_flags |= IFLAGS_OLDCOLOR;
} else {
internal_flags &= ~IFLAGS_OLDCOLOR;
}
apple_memory[address] = value;
break;
case 0x02:

View File

@ -39,3 +39,70 @@ static uint16_t DELAYED_COPY_DATA(hires_dot_patterns)[256] = {
0x001f,0x181f,0x061f,0x1e1f,0x019f,0x199f,0x079f,0x1f9f,
0x007f,0x187f,0x067f,0x1e7f,0x01ff,0x19ff,0x07ff,0x1fff,
};
static uint16_t DELAYED_COPY_DATA(hires_dot_patterns2)[512] = {
0b0000000000000000,0b0000000000000011,0b0000000000001100,0b0000000000001111,0b0000000000110000,0b0000000000110011,0b0000000000111100,0b0000000000111111,
0b0000000011000000,0b0000000011000011,0b0000000011001100,0b0000000011001111,0b0000000011110000,0b0000000011110011,0b0000000011111100,0b0000000011111111,
0b0000001100000000,0b0000001100000011,0b0000001100001100,0b0000001100001111,0b0000001100110000,0b0000001100110011,0b0000001100111100,0b0000001100111111,
0b0000001111000000,0b0000001111000011,0b0000001111001100,0b0000001111001111,0b0000001111110000,0b0000001111110011,0b0000001111111100,0b0000001111111111,
0b0000110000000000,0b0000110000000011,0b0000110000001100,0b0000110000001111,0b0000110000110000,0b0000110000110011,0b0000110000111100,0b0000110000111111,
0b0000110011000000,0b0000110011000011,0b0000110011001100,0b0000110011001111,0b0000110011110000,0b0000110011110011,0b0000110011111100,0b0000110011111111,
0b0000111100000000,0b0000111100000011,0b0000111100001100,0b0000111100001111,0b0000111100110000,0b0000111100110011,0b0000111100111100,0b0000111100111111,
0b0000111111000000,0b0000111111000011,0b0000111111001100,0b0000111111001111,0b0000111111110000,0b0000111111110011,0b0000111111111100,0b0000111111111111,
0b0011000000000000,0b0011000000000011,0b0011000000001100,0b0011000000001111,0b0011000000110000,0b0011000000110011,0b0011000000111100,0b0011000000111111,
0b0011000011000000,0b0011000011000011,0b0011000011001100,0b0011000011001111,0b0011000011110000,0b0011000011110011,0b0011000011111100,0b0011000011111111,
0b0011001100000000,0b0011001100000011,0b0011001100001100,0b0011001100001111,0b0011001100110000,0b0011001100110011,0b0011001100111100,0b0011001100111111,
0b0011001111000000,0b0011001111000011,0b0011001111001100,0b0011001111001111,0b0011001111110000,0b0011001111110011,0b0011001111111100,0b0011001111111111,
0b0011110000000000,0b0011110000000011,0b0011110000001100,0b0011110000001111,0b0011110000110000,0b0011110000110011,0b0011110000111100,0b0011110000111111,
0b0011110011000000,0b0011110011000011,0b0011110011001100,0b0011110011001111,0b0011110011110000,0b0011110011110011,0b0011110011111100,0b0011110011111111,
0b0011111100000000,0b0011111100000011,0b0011111100001100,0b0011111100001111,0b0011111100110000,0b0011111100110011,0b0011111100111100,0b0011111100111111,
0b0011111111000000,0b0011111111000011,0b0011111111001100,0b0011111111001111,0b0011111111110000,0b0011111111110011,0b0011111111111100,0b0011111111111111,
0b0000000000000000,0b0000000000000110,0b0000000000011000,0b0000000000011110,0b0000000001100000,0b0000000001100110,0b0000000001111000,0b0000000001111110,
0b0000000110000000,0b0000000110000110,0b0000000110011000,0b0000000110011110,0b0000000111100000,0b0000000111100110,0b0000000111111000,0b0000000111111110,
0b0000011000000000,0b0000011000000110,0b0000011000011000,0b0000011000011110,0b0000011001100000,0b0000011001100110,0b0000011001111000,0b0000011001111110,
0b0000011110000000,0b0000011110000110,0b0000011110011000,0b0000011110011110,0b0000011111100000,0b0000011111100110,0b0000011111111000,0b0000011111111110,
0b0001100000000000,0b0001100000000110,0b0001100000011000,0b0001100000011110,0b0001100001100000,0b0001100001100110,0b0001100001111000,0b0001100001111110,
0b0001100110000000,0b0001100110000110,0b0001100110011000,0b0001100110011110,0b0001100111100000,0b0001100111100110,0b0001100111111000,0b0001100111111110,
0b0001111000000000,0b0001111000000110,0b0001111000011000,0b0001111000011110,0b0001111001100000,0b0001111001100110,0b0001111001111000,0b0001111001111110,
0b0001111110000000,0b0001111110000110,0b0001111110011000,0b0001111110011110,0b0001111111100000,0b0001111111100110,0b0001111111111000,0b0001111111111110,
0b0110000000000000,0b0110000000000110,0b0110000000011000,0b0110000000011110,0b0110000001100000,0b0110000001100110,0b0110000001111000,0b0110000001111110,
0b0110000110000000,0b0110000110000110,0b0110000110011000,0b0110000110011110,0b0110000111100000,0b0110000111100110,0b0110000111111000,0b0110000111111110,
0b0110011000000000,0b0110011000000110,0b0110011000011000,0b0110011000011110,0b0110011001100000,0b0110011001100110,0b0110011001111000,0b0110011001111110,
0b0110011110000000,0b0110011110000110,0b0110011110011000,0b0110011110011110,0b0110011111100000,0b0110011111100110,0b0110011111111000,0b0110011111111110,
0b0111100000000000,0b0111100000000110,0b0111100000011000,0b0111100000011110,0b0111100001100000,0b0111100001100110,0b0111100001111000,0b0111100001111110,
0b0111100110000000,0b0111100110000110,0b0111100110011000,0b0111100110011110,0b0111100111100000,0b0111100111100110,0b0111100111111000,0b0111100111111110,
0b0111111000000000,0b0111111000000110,0b0111111000011000,0b0111111000011110,0b0111111001100000,0b0111111001100110,0b0111111001111000,0b0111111001111110,
0b0111111110000000,0b0111111110000110,0b0111111110011000,0b0111111110011110,0b0111111111100000,0b0111111111100110,0b0111111111111000,0b0111111111111110,
0b0000000000000000,0b0000000000000011,0b0000000000001100,0b0000000000001111,0b0000000000110000,0b0000000000110011,0b0000000000111100,0b0000000000111111,
0b0000000011000000,0b0000000011000011,0b0000000011001100,0b0000000011001111,0b0000000011110000,0b0000000011110011,0b0000000011111100,0b0000000011111111,
0b0000001100000000,0b0000001100000011,0b0000001100001100,0b0000001100001111,0b0000001100110000,0b0000001100110011,0b0000001100111100,0b0000001100111111,
0b0000001111000000,0b0000001111000011,0b0000001111001100,0b0000001111001111,0b0000001111110000,0b0000001111110011,0b0000001111111100,0b0000001111111111,
0b0000110000000000,0b0000110000000011,0b0000110000001100,0b0000110000001111,0b0000110000110000,0b0000110000110011,0b0000110000111100,0b0000110000111111,
0b0000110011000000,0b0000110011000011,0b0000110011001100,0b0000110011001111,0b0000110011110000,0b0000110011110011,0b0000110011111100,0b0000110011111111,
0b0000111100000000,0b0000111100000011,0b0000111100001100,0b0000111100001111,0b0000111100110000,0b0000111100110011,0b0000111100111100,0b0000111100111111,
0b0000111111000000,0b0000111111000011,0b0000111111001100,0b0000111111001111,0b0000111111110000,0b0000111111110011,0b0000111111111100,0b0000111111111111,
0b0011000000000000,0b0011000000000011,0b0011000000001100,0b0011000000001111,0b0011000000110000,0b0011000000110011,0b0011000000111100,0b0011000000111111,
0b0011000011000000,0b0011000011000011,0b0011000011001100,0b0011000011001111,0b0011000011110000,0b0011000011110011,0b0011000011111100,0b0011000011111111,
0b0011001100000000,0b0011001100000011,0b0011001100001100,0b0011001100001111,0b0011001100110000,0b0011001100110011,0b0011001100111100,0b0011001100111111,
0b0011001111000000,0b0011001111000011,0b0011001111001100,0b0011001111001111,0b0011001111110000,0b0011001111110011,0b0011001111111100,0b0011001111111111,
0b0011110000000000,0b0011110000000011,0b0011110000001100,0b0011110000001111,0b0011110000110000,0b0011110000110011,0b0011110000111100,0b0011110000111111,
0b0011110011000000,0b0011110011000011,0b0011110011001100,0b0011110011001111,0b0011110011110000,0b0011110011110011,0b0011110011111100,0b0011110011111111,
0b0011111100000000,0b0011111100000011,0b0011111100001100,0b0011111100001111,0b0011111100110000,0b0011111100110011,0b0011111100111100,0b0011111100111111,
0b0011111111000000,0b0011111111000011,0b0011111111001100,0b0011111111001111,0b0011111111110000,0b0011111111110011,0b0011111111111100,0b0011111111111111,
0b0000000000000001,0b0000000000000111,0b0000000000011001,0b0000000000011111,0b0000000001100001,0b0000000001100111,0b0000000001111001,0b0000000001111111,
0b0000000110000001,0b0000000110000111,0b0000000110011001,0b0000000110011111,0b0000000111100001,0b0000000111100111,0b0000000111111001,0b0000000111111111,
0b0000011000000001,0b0000011000000111,0b0000011000011001,0b0000011000011111,0b0000011001100001,0b0000011001100111,0b0000011001111001,0b0000011001111111,
0b0000011110000001,0b0000011110000111,0b0000011110011001,0b0000011110011111,0b0000011111100001,0b0000011111100111,0b0000011111111001,0b0000011111111111,
0b0001100000000001,0b0001100000000111,0b0001100000011001,0b0001100000011111,0b0001100001100001,0b0001100001100111,0b0001100001111001,0b0001100001111111,
0b0001100110000001,0b0001100110000111,0b0001100110011001,0b0001100110011111,0b0001100111100001,0b0001100111100111,0b0001100111111001,0b0001100111111111,
0b0001111000000001,0b0001111000000111,0b0001111000011001,0b0001111000011111,0b0001111001100001,0b0001111001100111,0b0001111001111001,0b0001111001111111,
0b0001111110000001,0b0001111110000111,0b0001111110011001,0b0001111110011111,0b0001111111100001,0b0001111111100111,0b0001111111111001,0b0001111111111111,
0b0110000000000001,0b0110000000000111,0b0110000000011001,0b0110000000011111,0b0110000001100001,0b0110000001100111,0b0110000001111001,0b0110000001111111,
0b0110000110000001,0b0110000110000111,0b0110000110011001,0b0110000110011111,0b0110000111100001,0b0110000111100111,0b0110000111111001,0b0110000111111111,
0b0110011000000001,0b0110011000000111,0b0110011000011001,0b0110011000011111,0b0110011001100001,0b0110011001100111,0b0110011001111001,0b0110011001111111,
0b0110011110000001,0b0110011110000111,0b0110011110011001,0b0110011110011111,0b0110011111100001,0b0110011111100111,0b0110011111111001,0b0110011111111111,
0b0111100000000001,0b0111100000000111,0b0111100000011001,0b0111100000011111,0b0111100001100001,0b0111100001100111,0b0111100001111001,0b0111100001111111,
0b0111100110000001,0b0111100110000111,0b0111100110011001,0b0111100110011111,0b0111100111100001,0b0111100111100111,0b0111100111111001,0b0111100111111111,
0b0111111000000001,0b0111111000000111,0b0111111000011001,0b0111111000011111,0b0111111001100001,0b0111111001100111,0b0111111001111001,0b0111111001111111,
0b0111111110000001,0b0111111110000111,0b0111111110011001,0b0111111110011111,0b0111111111100001,0b0111111111100111,0b0111111111111001,0b0111111111111111,
};

View File

@ -57,12 +57,14 @@ extern void vga_deinit();
(((((uint)(g) * 256 / 18) + 256) / 256) << 4) | \
((((uint)(b) * 256 / 18) + 256) / 256) \
)
#define _RGBHALF 0x777
#else
#define _RGB(r, g, b) ( \
(((((uint)(r) * 256 / 36) + 128) / 256) << 6) | \
(((((uint)(g) * 256 / 36) + 128) / 256) << 3) | \
((((uint)(b) * 256 / 36) + 128) / 256) \
)
#define _RGBHALF 0x0DB
#endif
#define RGB_BLACK _RGB(0x00,0x00,0x00)

View File

@ -7,8 +7,14 @@
//#define PAGE2SEL (!(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2))
#define PAGE2SEL ((soft_switches & (SOFTSW_80STORE | SOFTSW_PAGE_2)) == SOFTSW_PAGE_2)
extern uint16_t lores_palette[16];
extern uint16_t lores_dot_pattern[16];
extern uint16_t dhgr_palette[16];
uint8_t DELAYED_COPY_DATA(dgr_dot_pattern)[32] = {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x08, 0x19, 0x2A, 0x3B, 0x4C, 0x5D, 0x6E, 0x7F,
0x00, 0x44, 0x08, 0x4C, 0x11, 0x55, 0x19, 0x5D,
0x22, 0x66, 0x2A, 0x6E, 0x33, 0x77, 0x3B, 0x7F,
};
static void render_dgr_line(bool p2, uint line);
@ -40,7 +46,9 @@ static void DELAYED_COPY_CODE(render_dgr_line)(bool p2, uint line) {
struct vga_scanline *sl2 = vga_prepare_scanline();
uint sl_pos = 0;
uint i, j;
uint32_t color1, color2, color3, color4;
uint32_t color1, color2;
uint_fast8_t dotc = 0;
uint32_t pixeldata;
const uint8_t *line_bufa = (const uint8_t *)((p2 ? text_p2 : text_p1) + ((line & 0x7) << 7) + (((line >> 3) & 0x3) * 40));
const uint8_t *line_bufb = (const uint8_t *)((p2 ? text_p4 : text_p3) + ((line & 0x7) << 7) + (((line >> 3) & 0x3) * 40));
@ -56,42 +64,105 @@ static void DELAYED_COPY_CODE(render_dgr_line)(bool p2, uint line) {
sl2->data[sl_pos] = (text_border|THEN_EXTEND_3) | ((text_border|THEN_EXTEND_3) << 16); // 8 pixels per word
sl_pos++;
i = 0;
if((soft_switches & SOFTSW_MONOCHROME) || (mono_palette & 0x8)) {
for(i = 0; i < 40; i++) {
color1 = lores_dot_pattern[line_bufb[i] & 0xf] << 21;
color2 = lores_dot_pattern[(line_bufb[i] >> 4) & 0xf] << 21;
color1 |= lores_dot_pattern[line_bufa[i] & 0xf] << 7;
color2 |= lores_dot_pattern[(line_bufa[i] >> 4) & 0xf] << 7;
while(i < 40) {
while((dotc <= 18) && (i < 40)) {
color1 |= dgr_dot_pattern[((i & 1) << 4) | (line_bufb[i] & 0xf)] << dotc;
color2 |= dgr_dot_pattern[((i & 1) << 4) | ((line_bufb[i] >> 4) & 0xf)] << dotc;
dotc += 7;
color1 |= dgr_dot_pattern[((i & 1) << 4) | (line_bufa[i] & 0xf)] << dotc;
color2 |= dgr_dot_pattern[((i & 1) << 4) | ((line_bufa[i] >> 4) & 0xf)] << dotc;
dotc += 7;
i++;
}
for(j = 0; j < 7; j++) {
uint32_t pixeldata;
pixeldata = (color1 & 0x8000000) ? (text_fore) : (text_back);
pixeldata |= (color1 & 0x4000000) ? ((text_fore) << 16) : ((text_back) << 16);
color1 <<= 2;
// Consume pixels
while(dotc >= 2) {
pixeldata = ((color1 & 1) ? (text_fore) : (text_back));
pixeldata |= (((color1 & 2) ? (text_fore) : (text_back))) << 16;
sl1->data[sl_pos] = pixeldata;
pixeldata = (color2 & 0x8000000) ? (text_fore) : (text_back);
pixeldata |= (color2 & 0x4000000) ? ((text_fore) << 16) : ((text_back) << 16);
pixeldata = ((color2 & 1) ? (text_fore) : (text_back));
pixeldata |= (((color2 & 2) ? (text_fore) : (text_back))) << 16;
sl2->data[sl_pos] = pixeldata;
color2 <<= 2;
color1 >>= 2;
color2 >>= 2;
sl_pos++;
dotc -= 2;
}
}
} else {
for(i=0; i < 40; i++) {
color1 = lores_palette[line_bufb[i] & 0xf];
color2 = lores_palette[(line_bufb[i] >> 4) & 0xf];
color3 = lores_palette[line_bufa[i] & 0xf];
color4 = lores_palette[(line_bufa[i] >> 4) & 0xf];
// Preload the first 14 subpixels
color1 = dgr_dot_pattern[line_bufb[i] & 0xf] << dotc;
color2 = dgr_dot_pattern[(line_bufb[i] >> 4) & 0xf] << dotc;
dotc += 7;
color1 |= dgr_dot_pattern[(line_bufa[i] & 0xf)] << dotc;
color2 |= dgr_dot_pattern[((line_bufa[i] >> 4) & 0xf)] << dotc;
dotc += 7;
i++;
// Each double lores pixel is 7 double hires pixels, or 7 VGA pixels wide
sl1->data[sl_pos] = (color1|THEN_EXTEND_6) | ((color3|THEN_EXTEND_6) << 16);
sl2->data[sl_pos] = (color2|THEN_EXTEND_6) | ((color4|THEN_EXTEND_6) << 16);
sl_pos++;
// First two pixels
pixeldata = dhgr_palette[0];
pixeldata |= ((dhgr_palette[color1 & 0xf] >> 1) & _RGBHALF) << 16;
sl1->data[sl_pos] = pixeldata;
pixeldata = dhgr_palette[0];
pixeldata |= ((dhgr_palette[color1 & 0xf] >> 1) & _RGBHALF) << 16;
sl2->data[sl_pos] = pixeldata;
sl_pos++;
while(i < 40) {
// Load in as many subpixels as possible
while((dotc <= 18) && (i < 40)) {
color1 |= dgr_dot_pattern[((i & 1) << 4) | (line_bufb[i] & 0xf)] << dotc;
color2 |= dgr_dot_pattern[((i & 1) << 4) | ((line_bufb[i] >> 4) & 0xf)] << dotc;
dotc += 7;
color1 |= dgr_dot_pattern[((i & 1) << 4) | (line_bufa[i] & 0xf)] << dotc;
color2 |= dgr_dot_pattern[((i & 1) << 4) | ((line_bufa[i] >> 4) & 0xf)] << dotc;
dotc += 7;
i++;
}
// Consume pixels
while(dotc >= 8) {
pixeldata = (dhgr_palette[color1 & 0xf]);
pixeldata |= ((dhgr_palette[color1 & 0xf] >> 1) & _RGBHALF) << 16;
sl1->data[sl_pos] = pixeldata;
pixeldata = (dhgr_palette[color2 & 0xf]);
pixeldata |= ((dhgr_palette[color2 & 0xf] >> 1) & _RGBHALF) << 16;
sl2->data[sl_pos] = pixeldata;
sl_pos++;
pixeldata = (dhgr_palette[(color1 & 0xc) | ((color1 & 0x30) >> 4)]);
pixeldata |= ((dhgr_palette[(color1 & 0xf0) >> 4] >> 1) & _RGBHALF) << 16;
sl1->data[sl_pos] = pixeldata;
pixeldata = (dhgr_palette[(color2 & 0xc) | ((color2 & 0x30) >> 4)]);
pixeldata |= ((dhgr_palette[(color2 & 0xf0) >> 4] >> 1) & _RGBHALF) << 16;
sl2->data[sl_pos] = pixeldata;
sl_pos++;
color1 >>= 4;
color2 >>= 4;
dotc -= 4;
}
}
// Last two pixels
pixeldata = (dhgr_palette[color1 & 0xf]);
pixeldata |= ((dhgr_palette[color1 & 0xf] >> 1) & _RGBHALF) << 16;
sl1->data[sl_pos] = pixeldata;
pixeldata = (dhgr_palette[color2 & 0xf]);
pixeldata |= ((dhgr_palette[color2 & 0xf] >> 1) & _RGBHALF) << 16;
sl2->data[sl_pos] = pixeldata;
sl_pos++;
}
// Pad 40 pixels on the right to center horizontally

View File

@ -61,67 +61,92 @@ static void DELAYED_COPY_CODE(render_dhgr_line)(bool p2, uint line) {
// DHGR is weird. Nuff said.
uint32_t dots = 0;
uint_fast8_t dotc = 0;
uint32_t pixeldata;
int j;
i = 0;
while(i < 40) {
// Load in the next 28 subpixels
dots = (line_memb[i] & 0x7f) << 0;
dots |= (line_mema[i] & 0x7f) << 7;
i++;
dots |= (line_memb[i] & 0x7f) << 14;
dots |= (line_mema[i] & 0x7f) << 21;
i++;
if((soft_switches & SOFTSW_MONOCHROME) || (mono_palette & 0x8)) {
while(i < 40) {
// Load in as many subpixels as possible
while((dotc < 28) && (i < 40)) {
dots |= (line_memb[i] & 0x7f) << dotc;
dotc += 7;
dots |= (line_mema[i] & 0x7f) << dotc;
dotc += 7;
i++;
}
if((soft_switches & SOFTSW_MONOCHROME) || (mono_palette & 0x8)) {
// Consume 6 pixels (24 subpixel bits)
for(j = 0; j < 12; j++) {
// Consume pixels
while(dotc) {
pixeldata = ((dots & 1) ? (text_fore) : (text_back));
dots >>= 1;
pixeldata |= (((dots & 1) ? (text_fore) : (text_back))) << 16;
dots >>= 1;
sl->data[sl_pos++] = pixeldata;
dotc -= 2;
}
} else {
// Consume 6 pixels (24 subpixel bits)
for(j = 0; j < 3; j++) {
}
} else if(internal_flags & IFLAGS_OLDCOLOR) {
while(i < 40) {
// Load in as many subpixels as possible
while((dotc <= 18) && (i < 40)) {
dots |= (line_memb[i] & 0x7f) << dotc;
dotc += 7;
dots |= (line_mema[i] & 0x7f) << dotc;
dotc += 7;
i++;
}
// Consume pixels
while(dotc >= 8) {
pixeldata = (dhgr_palette[dots & 0xf] | THEN_EXTEND_3);
dots >>= 4;
pixeldata |= (dhgr_palette[dots & 0xf] | THEN_EXTEND_3) << 16;
dots >>= 4;
sl->data[sl_pos++] = pixeldata;
dotc -= 8;
}
}
} else {
// Preload the first 14 subpixels
dots |= (line_memb[i] & 0x7f) << dotc;
dotc += 7;
dots |= (line_mema[i] & 0x7f) << dotc;
dotc += 7;
i++;
// First two pixels
pixeldata = dhgr_palette[0];
pixeldata |= ((dhgr_palette[dots & 0xf] >> 1) & _RGBHALF) << 16;
sl->data[sl_pos++] = pixeldata;
while(i < 40) {
// Load in as many subpixels as possible
while((dotc <= 18) && (i < 40)) {
dots |= (line_memb[i] & 0x7f) << dotc;
dotc += 7;
dots |= (line_mema[i] & 0x7f) << dotc;
dotc += 7;
i++;
}
// Consume pixels
while(dotc >= 8) {
pixeldata = (dhgr_palette[dots & 0xf]);
pixeldata |= ((dhgr_palette[dots & 0xf] >> 1) & _RGBHALF) << 16;
sl->data[sl_pos++] = pixeldata;
pixeldata = (dhgr_palette[(dots & 0xc) | ((dots & 0x30) >> 4)]);
pixeldata |= ((dhgr_palette[(dots & 0xf0) >> 4] >> 1) & _RGBHALF) << 16;
sl->data[sl_pos++] = pixeldata;
dots >>= 4;
dotc -= 4;
}
}
// 4 subpixels roll over to the next block
// Load in the next 28 subpixels
dots |= (line_memb[i] & 0x7f) << 4;
dots |= (line_mema[i] & 0x7f) << 11;
i++;
dots |= (line_memb[i] & 0x7f) << 18;
dots |= (line_mema[i] & 0x7f) << 25;
i++;
if((soft_switches & SOFTSW_MONOCHROME) || (mono_palette & 0x8)) {
// Consume 8 pixels (32 subpixel bits)
for(j = 0; j < 16; j++) {
pixeldata = ((dots & 1) ? (text_fore) : (text_back));
dots >>= 1;
pixeldata |= (((dots & 1) ? (text_fore) : (text_back))) << 16;
dots >>= 1;
sl->data[sl_pos++] = pixeldata;
}
} else {
// Consume 8 pixels (32 subpixel bits)
for(j = 0; j < 4; j++) {
pixeldata = (dhgr_palette[dots & 0xf] | THEN_EXTEND_3);
dots >>= 4;
pixeldata |= (dhgr_palette[dots & 0xf] | THEN_EXTEND_3) << 16;
dots >>= 4;
sl->data[sl_pos++] = pixeldata;
}
}
// Last two pixels
pixeldata = (dhgr_palette[dots & 0xf]);
pixeldata |= ((dhgr_palette[dots & 0xf] >> 1) & _RGBHALF) << 16;
sl->data[sl_pos++] = pixeldata;
}
// Pad 40 pixels on the right to center horizontally

View File

@ -10,6 +10,7 @@
#define PAGE2SEL ((soft_switches & (SOFTSW_80STORE | SOFTSW_PAGE_2)) == SOFTSW_PAGE_2)
static void render_hires_line(bool p2, uint line);
extern uint16_t dhgr_palette[16];
static inline uint hires_line_to_mem_offset(uint line) {
return ((line & 0x07) << 10) | ((line & 0x38) << 4) | (((line & 0xc0) >> 6) * 40);
@ -37,7 +38,6 @@ void DELAYED_COPY_CODE(render_mixed_hires)() {
}
}
static void DELAYED_COPY_CODE(render_hires_line)(bool p2, uint line) {
struct vga_scanline *sl = vga_prepare_scanline();
uint sl_pos = 0;
@ -49,52 +49,66 @@ static void DELAYED_COPY_CODE(render_hires_line)(bool p2, uint line) {
sl->data[sl_pos++] = (text_border|THEN_EXTEND_7) | ((text_border|THEN_EXTEND_7) << 16); // 16 pixels per word
sl->data[sl_pos++] = (text_border|THEN_EXTEND_3) | ((text_border|THEN_EXTEND_3) << 16); // 16 pixels per word
// Each hires byte contains 7 pixels which may be shifted right 1/2 a pixel. That is
// represented here by 14 'dots' to precisely describe the half-pixel positioning.
//
// For each pixel, inspect a window of 8 dots around the pixel to determine the
// precise dot locations and colors.
//
// Dots would be scanned out to the CRT from MSB to LSB (left to right here):
//
// previous | next
// dots | dots
// +-------------------+--------------------------------------------------+
// dots: | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | ... | 14 | 13 | 12 | ...
// | | | |
// \______________|_________|______________/
// | |
// \_________/
// current
// pixel
uint32_t lastmsb = 0;
uint32_t dots = 0;
uint oddness = 0;
uint i, j;
uint_fast8_t dotc = 0;
uint32_t pixeldata;
uint i;
// Load in the first 14 dots
dots |= (uint32_t)hires_dot_patterns[line_mem[0]] << 15;
for(i=1; i < 41; i++) {
// Load in the next 14 dots
uint b = (i < 40) ? line_mem[i] : 0;
if(b & 0x80) {
// Extend the last bit from the previous byte
dots |= (dots & (1u << 15)) >> 1;
}
dots |= (uint32_t)hires_dot_patterns[b] << 1;
if((soft_switches & SOFTSW_MONOCHROME) || (mono_palette & 0x8)) {
// Consume 14 dots
for(j = 0; j < 7; j++) {
uint32_t pixeldata = (dots & 0x40000000) ? (text_fore) : (text_back);
pixeldata |= (dots & 0x20000000) ?
((text_fore) << 16) :
((text_back) << 16);
dots <<= 2;
sl->data[sl_pos] = pixeldata;
sl_pos++;
if((soft_switches & SOFTSW_MONOCHROME) || (mono_palette & 0x8)) {
while(i < 40) {
// Load in as many subpixels as possible
while((dotc < 18) && (i < 40)) {
dots |= (hires_dot_patterns2[lastmsb | line_mem[i]]) << dotc;
lastmsb = (dotc>0) ? ((line_mem[i] & 0x40)<<2) : 0;
i++;
dotc += 14;
}
} else {
// Consume pixels
while(dotc) {
pixeldata = ((dots & 1) ? (text_fore) : (text_back));
dots >>= 1;
pixeldata |= (((dots & 1) ? (text_fore) : (text_back))) << 16;
dots >>= 1;
sl->data[sl_pos++] = pixeldata;
dotc -= 2;
}
}
} else if(internal_flags & IFLAGS_OLDCOLOR) {
// Each hires byte contains 7 pixels which may be shifted right 1/2 a pixel. That is
// represented here by 14 'dots' to precisely describe the half-pixel positioning.
//
// For each pixel, inspect a window of 8 dots around the pixel to determine the
// precise dot locations and colors.
//
// Dots would be scanned out to the CRT from MSB to LSB (left to right here):
//
// previous | next
// dots | dots
// +-------------------+--------------------------------------------------+
// dots: | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | ... | 14 | 13 | 12 | ...
// | | | |
// \______________|_________|______________/
// | |
// \_________/
// current
// pixel
uint oddness = 0;
uint j;
// Load in the first 14 dots
dots |= (uint32_t)hires_dot_patterns[line_mem[0]] << 15;
for(i=1; i < 41; i++) {
// Load in the next 14 dots
uint b = (i < 40) ? line_mem[i] : 0;
if(b & 0x80) {
// Extend the last bit from the previous byte
dots |= (dots & (1u << 15)) >> 1;
}
dots |= (uint32_t)hires_dot_patterns[b] << 1;
// Consume 14 dots
for(uint j=0; j < 7; j++) {
uint dot_pattern = oddness | ((dots >> 24) & 0xff);
@ -104,6 +118,44 @@ static void DELAYED_COPY_CODE(render_hires_line)(bool p2, uint line) {
oddness ^= 0x100;
}
}
} else {
// Preload the first 14 subpixels
dots = (hires_dot_patterns2[line_mem[i]]);
lastmsb = (dotc>0) ? ((line_mem[i] & 0x40)<<2) : 0;
i++;
dotc = 14;
// First two pixels
pixeldata = lores_palette[0];
pixeldata |= ((lores_palette[dots & 0xf] >> 1) & _RGBHALF) << 16;
sl->data[sl_pos++] = pixeldata;
while(i < 40) {
// Load in as many subpixels as possible
if((dotc < 18) && (i < 40)) {
dots |= (hires_dot_patterns2[lastmsb | line_mem[i]]) << dotc;
lastmsb = (dotc>0) ? ((line_mem[i] & 0x40)<<2) : 0;
i++;
dotc += 14;
}
// Consume pixels
while(dotc >= 8) {
pixeldata = (lores_palette[dots & 0xf]);
pixeldata |= ((lores_palette[dots & 0xf] >> 1) & _RGBHALF) << 16;
sl->data[sl_pos++] = pixeldata;
pixeldata = (lores_palette[(dots & 0xc) | ((dots & 0x30) >> 4)]);
pixeldata |= ((lores_palette[(dots & 0xf0) >> 4] >> 1) & _RGBHALF) << 16;
sl->data[sl_pos++] = pixeldata;
dots >>= 4;
dotc -= 4;
}
}
// Last two pixels
pixeldata = (lores_palette[dots & 0xf]);
pixeldata |= ((lores_palette[dots & 0xf] >> 1) & _RGBHALF) << 16;
sl->data[sl_pos++] = pixeldata;
}
// Pad 40 pixels on the right to center horizontally