mirror of
https://github.com/V2RetroComputing/analog-firmware.git
synced 2024-11-15 21:10:03 +00:00
264 lines
8.0 KiB
C
264 lines
8.0 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;
|
|
|
|
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_FONT_APPLE_IIE, 4096);
|
|
memset(status_line, 0, sizeof(status_line));
|
|
|
|
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); // 8 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 == 5) {
|
|
update_status_right("Going to sleep...");
|
|
}
|
|
} else {
|
|
if(screentimeout >= 5) {
|
|
// 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;
|
|
}
|
|
|
|
if(internal_flags & IFLAGS_TEST) {
|
|
render_testpattern();
|
|
// Automatically dismiss the test pattern when the Apple II is seen.
|
|
if(((soft_switches & SOFTSW_MODE_MASK) != 0) && (testdone == 0)) {
|
|
internal_flags &= ~IFLAGS_TEST;
|
|
testdone = 1;
|
|
render_about_init();
|
|
}
|
|
} else if(soft_switches & SOFTSW_TERMINAL) {
|
|
render_terminal();
|
|
#if defined(ANALOG_GS) || defined(OVERCLOCKED)
|
|
} else if(soft_switches & SOFTSW_SHR) {
|
|
render_shr();
|
|
#endif
|
|
} else {
|
|
vga_prepare_frame();
|
|
|
|
render_border(24);
|
|
if(status_line[0] != 0) {
|
|
render_status_line();
|
|
render_border(16);
|
|
} 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
|
|
}
|
|
}
|