mirror of
https://github.com/V2RetroComputing/analog-firmware.git
synced 2024-09-26 14:55:04 +00:00
dd9fa40678
May need to make this on consistent bus activity. The card was remaining in the test pattern if reset and no soft switches were toggled afterward.
271 lines
8.2 KiB
C
271 lines
8.2 KiB
C
#include <string.h>
|
|
#include <pico/stdlib.h>
|
|
#include <hardware/timer.h>
|
|
#include "common/config.h"
|
|
#include "common/flash.h"
|
|
#include "common/dmacopy.h"
|
|
#include "vga/vgabuf.h"
|
|
#include "vga/render.h"
|
|
#include "vga/vgaout.h"
|
|
|
|
uint16_t text_fore;
|
|
uint16_t text_back;
|
|
uint16_t text_border;
|
|
|
|
compat_t machinefont = MACHINE_INVALID;
|
|
bool userfont = false;
|
|
bool mono_rendering = false;
|
|
|
|
uint16_t DELAYED_COPY_DATA(mono_colors)[14] = {
|
|
_RGB(0x00, 0x00, 0x00), _RGB(0xFF, 0xFF, 0xFF), // White Normal
|
|
_RGB(0xFF, 0xFF, 0xFF), _RGB(0x00, 0x00, 0x00), // White Inverse
|
|
_RGB(0x00, 0x00, 0x00), _RGB(0xFE, 0x7F, 0x00), // Amber Normal
|
|
_RGB(0xFE, 0x7F, 0x00), _RGB(0x00, 0x00, 0x00), // Amber Inverse
|
|
_RGB(0x00, 0x00, 0x00), _RGB(0x00, 0xBF, 0x00), // Green Normal
|
|
_RGB(0x00, 0xBF, 0x00), _RGB(0x00, 0x00, 0x00), // Green Inverse
|
|
_RGB(0x35, 0x28, 0x79), _RGB(0x6C, 0x5E, 0xB5), // Commodore
|
|
};
|
|
|
|
// Initialize the character generator ROM
|
|
static void DELAYED_COPY_CODE(switch_font)() {
|
|
if(romx_changed) {
|
|
memcpy32(character_rom, (void*)FLASH_FONT(romx_textbank), 4096);
|
|
} else if(userfont) {
|
|
return;
|
|
} else if(current_machine != machinefont) {
|
|
switch(current_machine) {
|
|
default:
|
|
case MACHINE_II:
|
|
memcpy32(character_rom, (void*)FLASH_FONT_APPLE_II, 4096);
|
|
break;
|
|
case MACHINE_IIE:
|
|
memcpy32(character_rom, (void*)FLASH_FONT_APPLE_IIE, 4096);
|
|
break;
|
|
case MACHINE_IIGS:
|
|
memcpy32(character_rom, (void*)FLASH_FONT_APPLE_IIGS, 4096);
|
|
break;
|
|
case MACHINE_PRAVETZ:
|
|
memcpy32(character_rom, (void*)FLASH_FONT_PRAVETZ, 4096);
|
|
break;
|
|
}
|
|
machinefont = current_machine;
|
|
}
|
|
}
|
|
|
|
uint16_t status_timeout = 900;
|
|
uint8_t status_line[81];
|
|
|
|
void DELAYED_COPY_CODE(update_status_right)(const char *str) {
|
|
uint i, len;
|
|
|
|
if(str != NULL) {
|
|
len = strlen(str);
|
|
} else {
|
|
len = 0;
|
|
}
|
|
|
|
if(len < 80) {
|
|
memset(status_line, ' ', 80 - len);
|
|
} else {
|
|
len = 80;
|
|
}
|
|
|
|
for(i = 0; i < len; i++) {
|
|
status_line[(80-len) + i] = str[i];
|
|
}
|
|
|
|
status_timeout = 900;
|
|
}
|
|
|
|
void DELAYED_COPY_CODE(update_status_left)(const char *str) {
|
|
uint i, len;
|
|
|
|
if(str != NULL) {
|
|
len = strlen(str);
|
|
} else {
|
|
len = 0;
|
|
}
|
|
|
|
if(len < 80) {
|
|
memset(status_line + len, ' ', 80 - len);
|
|
} else {
|
|
len = 80;
|
|
}
|
|
|
|
for(i = 0; i < len; i++) {
|
|
status_line[i] = str[i];
|
|
}
|
|
|
|
status_timeout = 900;
|
|
}
|
|
|
|
void DELAYED_COPY_CODE(render_init)() {
|
|
int i;
|
|
|
|
switch_font();
|
|
|
|
if((soft_switches & SOFTSW_MODE_MASK) == 0)
|
|
internal_flags |= IFLAGS_TEST;
|
|
|
|
apple_tbcolor = 0xf0;
|
|
apple_border = 0x00;
|
|
|
|
terminal_tbcolor = 0xf0;
|
|
terminal_border = 0x00;
|
|
|
|
memcpy(terminal_character_rom, (void*)FLASH_VIDEX_BASE, 4096);
|
|
memset(status_line, 0, sizeof(status_line));
|
|
|
|
terminal_clear_screen();
|
|
|
|
render_test_init();
|
|
}
|
|
|
|
// Skip lines to center vertically or blank the screen
|
|
void DELAYED_COPY_CODE(render_border)(uint count) {
|
|
struct vga_scanline *sl = vga_prepare_scanline();
|
|
uint sl_pos = 0;
|
|
|
|
while(sl_pos < VGA_WIDTH/16) {
|
|
sl->data[sl_pos] = (text_border|THEN_EXTEND_7) | ((text_border|THEN_EXTEND_7) << 16); // 16 pixels per word
|
|
sl_pos++;
|
|
}
|
|
|
|
sl->length = sl_pos;
|
|
sl->repeat_count = count - 1;
|
|
vga_submit_scanline(sl);
|
|
}
|
|
|
|
uint32_t screentimeout = 0;
|
|
uint32_t testdone = 0;
|
|
|
|
void DELAYED_COPY_CODE(render_loop)() {
|
|
for(;;) {
|
|
config_handler();
|
|
|
|
#if 0
|
|
if((busactive == 0) && (screentimeout > (15 * 60))) {
|
|
vga_prepare_frame();
|
|
render_border(VGA_HEIGHT);
|
|
memset(status_line, 0, sizeof(status_line));
|
|
status_timeout = 0;
|
|
vga_dpms_sleep();
|
|
while(busactive == 0);
|
|
vga_dpms_wake();
|
|
} else {
|
|
if(busactive == 0) {
|
|
screentimeout++;
|
|
if(screentimeout == 30) {
|
|
update_status_right("Going to sleep...");
|
|
}
|
|
} else {
|
|
if(screentimeout >= 30) {
|
|
// Clear the sleep mode message
|
|
memset(status_line, 0, sizeof(status_line));
|
|
status_timeout = 0;
|
|
}
|
|
screentimeout = 0;
|
|
}
|
|
busactive = 0;
|
|
#endif
|
|
|
|
if(romx_changed || (machinefont != current_machine)) {
|
|
switch_font();
|
|
romx_changed = 0;
|
|
machinefont = current_machine;
|
|
}
|
|
|
|
update_text_flasher();
|
|
|
|
if(!(mono_palette & 0x8)) {
|
|
if((current_machine == MACHINE_IIGS) && !(soft_switches & SOFTSW_MONOCHROME)) {
|
|
text_fore = lores_palette[APPLE_FORE];
|
|
text_back = lores_palette[APPLE_BACK];
|
|
text_border = lores_palette[APPLE_BORDER];
|
|
} else {
|
|
text_fore = mono_colors[1];
|
|
text_back = mono_colors[0];
|
|
text_border = mono_colors[0];
|
|
}
|
|
} else if(mono_palette == 0xF) {
|
|
text_fore = lores_palette[TERMINAL_FORE];
|
|
text_back = lores_palette[TERMINAL_BACK];
|
|
text_border = lores_palette[TERMINAL_BORDER];
|
|
} else {
|
|
int palette = mono_palette & 0x7;
|
|
text_fore = mono_colors[palette*2+1];
|
|
text_back = mono_colors[palette*2];
|
|
text_border = (palette == 0x6) ? text_fore : text_back;
|
|
}
|
|
|
|
mono_rendering = ((soft_switches & SOFTSW_MONOCHROME) || (mono_palette & 0x8));
|
|
|
|
if(internal_flags & IFLAGS_TEST) {
|
|
render_testpattern();
|
|
// Assume the RP2040 has been hard reset and try to default to text display
|
|
if(busactive && (testdone == 0)) { // was ((soft_switches & SOFTSW_MODE_MASK) != 0)
|
|
soft_switches |= SOFTSW_TEXT_MODE;
|
|
internal_flags &= ~IFLAGS_TEST;
|
|
testdone = 1;
|
|
render_about_init();
|
|
}
|
|
#if defined(ANALOG_GS)
|
|
} else if(soft_switches & SOFTSW_SHR) {
|
|
vga_prepare_frame();
|
|
render_shr();
|
|
#endif
|
|
} else if(internal_flags & IFLAGS_TERMINAL) {
|
|
vga_prepare_frame();
|
|
render_terminal();
|
|
} else {
|
|
vga_prepare_frame();
|
|
|
|
render_border(16);
|
|
if(status_line[0] != 0) {
|
|
render_status_line();
|
|
} else {
|
|
render_border(32);
|
|
}
|
|
|
|
switch(soft_switches & SOFTSW_MODE_MASK) {
|
|
case 0:
|
|
if(soft_switches & SOFTSW_DGR) {
|
|
render_dgr();
|
|
} else {
|
|
render_lores();
|
|
}
|
|
break;
|
|
case SOFTSW_MIX_MODE:
|
|
if((soft_switches & (SOFTSW_80COL | SOFTSW_DGR)) == (SOFTSW_80COL | SOFTSW_DGR)) {
|
|
render_mixed_dgr();
|
|
} else {
|
|
render_mixed_lores();
|
|
}
|
|
break;
|
|
case SOFTSW_HIRES_MODE:
|
|
if(soft_switches & SOFTSW_DGR) {
|
|
render_dhgr();
|
|
} else {
|
|
render_hires();
|
|
}
|
|
break;
|
|
case SOFTSW_HIRES_MODE|SOFTSW_MIX_MODE:
|
|
if((soft_switches & (SOFTSW_80COL | SOFTSW_DGR)) == (SOFTSW_80COL | SOFTSW_DGR)) {
|
|
render_mixed_dhgr();
|
|
} else {
|
|
render_mixed_hires();
|
|
}
|
|
break;
|
|
default:
|
|
render_text();
|
|
break;
|
|
}
|
|
|
|
render_border(48);
|
|
}
|
|
#if 0
|
|
}
|
|
#endif
|
|
}
|
|
}
|