analog/v2-analog-rev1/vga/render_dhgr.c
David Kuder 0835003caa Build 0159
Progress on PCPI mode bug fixes. PCPI mode is now working again, but the config interface is still broken enough to prevent the use of the config utility while in this mode.. Sending the FORMAT command from the monitor rom returns the card to defaults.
Replace n with the slot number the card is installed in:

]CALL -151
*CnF0:46 4F 52 4D 41 54 00 00

Correction of mousetext / inverse / flashing handling on IIe
see https://github.com/V2RetroComputing/analog/issues/3

Monochrome mode & color palettes are now implemented.
$C0n1: Monochrome mode & palette
  $80: B&W
  $90: Inverse
  $A0: Amber
  $B0: Inverse Amber
  $C0: Green
  $D0: Inverse Green
  $E0: Commodore 64 Theme
  $F0: Use IIgs palette
$C0n2: Mirror of IIgs TBCOLOR register
$C0n3: Mirror of IIgs BORDER register
2023-03-02 11:09:48 -05:00

148 lines
5.4 KiB
C

#include <pico/stdlib.h>
#include "hires_color_patterns.h"
#include "hires_dot_patterns.h"
#include "vgabuf.h"
#include "render.h"
#include "vgaout.h"
static void render_dhgr_line(bool p2, uint line);
uint16_t dhgr_palette[16] = {
_RGB333(0x00,0x00,0x00), // black 0000
_RGB333(0x00,0x00,0xb4), // d.blue 1000
_RGB333(0x00,0x90,0x00), // d.green 0100
_RGB333(0x00,0x6c,0xd8), // h.blue 1100
_RGB333(0x6c,0x6c,0x00), // brown 0010
_RGB333(0x90,0x90,0x90), // l.gray 1010
_RGB333(0x00,0xd8,0x24), // h.green 0110
_RGB333(0x90,0xfc,0x90), // aqua 1110
_RGB333(0xd8,0x00,0x6c), // magenta 0001
_RGB333(0xb4,0x24,0xfc), // h.violet 1001
_RGB333(0x48,0x48,0x48), // d.gray 0101
_RGB333(0x6c,0x6c,0xff), // l.blue 1101
_RGB333(0xfc,0x6c,0x24), // h.orange 0011
_RGB333(0xff,0xd8,0xff), // pink 1011
_RGB333(0xd8,0xd8,0x00), // yellow 0111
_RGB333(0xff,0xff,0xff), // white 1111
};
//#define PAGE2SEL (!(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2))
#define PAGE2SEL ((soft_switches & (SOFTSW_80STORE | SOFTSW_PAGE_2)) == SOFTSW_PAGE_2)
static uint dhgr_line_to_mem_offset(uint line) {
return ((line & 0x07) << 10) | ((line & 0x38) << 4) | (((line & 0xc0) >> 6) * 40);
}
void __time_critical_func(render_dhgr)() {
for(uint line=0; line < 192; line++) {
render_dhgr_line(PAGE2SEL, line);
}
}
void __time_critical_func(render_mixed_dhgr)() {
for(uint line=0; line < 160; line++) {
render_dhgr_line(PAGE2SEL, line);
}
for(uint line=20; line < 24; line++) {
if(soft_switches & SOFTSW_80COL) {
render_text80_line(PAGE2SEL, line);
} else {
render_text40_line(PAGE2SEL, line);
}
}
}
static void __time_critical_func(render_dhgr_line)(bool p2, uint line) {
struct vga_scanline *sl = vga_prepare_scanline();
uint sl_pos = 0;
uint i;
const uint8_t *line_mema = (const uint8_t *)((p2 ? hgr_p2 : hgr_p1) + dhgr_line_to_mem_offset(line));
const uint8_t *line_memb = (const uint8_t *)((p2 ? hgr_p4 : hgr_p3) + dhgr_line_to_mem_offset(line));
// Pad 40 pixels on the left to center horizontally
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_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); // 8 pixels per word
// DHGR is weird. Nuff said.
uint32_t dots = 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) {
// Consume 6 pixels (24 subpixel bits)
for(j = 0; j < 12; 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 6 pixels (24 subpixel bits)
for(j = 0; j < 3; 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;
}
}
// 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) {
// 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;
}
}
}
// Pad 40 pixels on the left to center horizontally
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_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); // 8 pixels per word
sl->length = sl_pos;
sl->repeat_count = 1;
vga_submit_scanline(sl);
}