January 30, 2023 Beta Build

Added machine types, character rom fixes, render code consolidation.
DPMS Sleep mode when the RP2040 is powered separately from the Apple.
This commit is contained in:
David Kuder 2023-01-31 19:32:47 -05:00
parent 564ebb545a
commit 5cb0c6dab3
21 changed files with 876 additions and 396 deletions

View File

@ -52,6 +52,9 @@ void parse_config(uint8_t *buffer) {
} else if(!strcmp("IIGS", buffer+2)) {
cfg_machine = MACHINE_IIGS;
soft_switches |= SOFTSW_IIE_REGS | SOFTSW_IIGS_REGS;
} else if(!strcmp("PRAVETZ", buffer+2)) {
cfg_machine = MACHINE_PRAVETZ;
soft_switches &= ~(SOFTSW_IIE_REGS | SOFTSW_IIGS_REGS);
}
} else if(!memcmp("S=", buffer, 2)) {
if(!strcmp("USB", buffer+2)) {
@ -313,7 +316,31 @@ void config_handler() {
config_cmdbuf[7] = 0xff;
if(!memcmp("H=", (uint8_t*)config_cmdbuf, 2)) {
parse_config((uint8_t*)config_cmdbuf);
if(!strcmp("II", config_cmdbuf+2)) {
current_machine = MACHINE_II;
soft_switches &= ~(SOFTSW_IIE_REGS | SOFTSW_IIGS_REGS);
} else if(!strcmp("IIE", config_cmdbuf+2)) {
current_machine = MACHINE_IIE;
soft_switches &= ~SOFTSW_IIGS_REGS;
soft_switches |= SOFTSW_IIE_REGS;
} else if(!strcmp("IIGS", config_cmdbuf+2)) {
current_machine = MACHINE_IIGS;
soft_switches |= SOFTSW_IIE_REGS | SOFTSW_IIGS_REGS;
#if 0
} else if(!strcmp("B108", config_cmdbuf+2)) {
current_machine = MACHINE_BASIS;
soft_switches &= ~(SOFTSW_IIE_REGS | SOFTSW_IIGS_REGS);
} else if(!strcmp("P", config_cmdbuf+2)) {
current_machine = MACHINE_PRAVETZ;
soft_switches &= ~(SOFTSW_IIE_REGS | SOFTSW_IIGS_REGS);
} else if(!strcmp("A7", config_cmdbuf+2)) {
current_machine = MACHINE_AGAT7;
soft_switches &= ~(SOFTSW_IIE_REGS | SOFTSW_IIGS_REGS);
} else if(!strcmp("A9", config_cmdbuf+2)) {
current_machine = MACHINE_AGAT9;
soft_switches &= ~(SOFTSW_IIE_REGS | SOFTSW_IIGS_REGS);
#endif
}
} else if(!memcmp("UF", (uint8_t*)config_cmdbuf, 2)) {
upload_font(config_cmdbuf[2]);
} else if(!memcmp("DF", (uint8_t*)config_cmdbuf, 2)) {

View File

@ -63,6 +63,9 @@ typedef enum {
MACHINE_II = 0,
MACHINE_IIE = 1,
MACHINE_IIGS = 2,
MACHINE_PRAVETZ = 6,
MACHINE_AGAT7 = 7,
MACHINE_AGAT9 = 9,
MACHINE_AUTO = 0xff
} compat_t;

View File

@ -24,6 +24,8 @@ static void __time_critical_func(core1_loop)() {
pio_sm_put_blocking(CONFIG_ABUS_PIO, ABUS_DEVICE_READ_SM, apple_memory[address]);
}
}
busactive = 1;
if(CARD_SELECT) {
if(CARD_DEVSEL) {
@ -58,6 +60,31 @@ static void __time_critical_func(core1_loop)() {
parallel_businterface(address, value);
break;
}
if(current_machine == MACHINE_AUTO) {
if((apple_memory[0x0417] == 0xE7) && (apple_memory[0x416] == 0xC9)) { // Apple IIgs
current_machine = MACHINE_IIGS;
soft_switches &= ~SOFTSW_IIE_REGS;
soft_switches |= SOFTSW_IIGS_REGS;
} else if((apple_memory[0x0417] == 0xE5) && (apple_memory[0x416] == 0xAF)) { // Apple //e Enhanced
current_machine = MACHINE_IIE;
soft_switches |= SOFTSW_IIE_REGS;
soft_switches &= ~SOFTSW_IIGS_REGS;
} else if((apple_memory[0x0415] == 0xDD) && (apple_memory[0x413] == 0xE5)) { // Apple //e Unenhanced
current_machine = MACHINE_IIE;
soft_switches |= SOFTSW_IIE_REGS;
soft_switches &= ~SOFTSW_IIGS_REGS;
} else if(apple_memory[0x0410] == 0xD0) { // Apple II/Plus/J-Plus with Autostart
current_machine = MACHINE_II;
soft_switches &= ~(SOFTSW_IIE_REGS | SOFTSW_IIGS_REGS);
} else if((apple_memory[0x07D0] == 0xAA) && (apple_memory[0x07D1] == 0x60)) { // Apple II without Autostart
current_machine = MACHINE_II;
soft_switches &= ~(SOFTSW_IIE_REGS | SOFTSW_IIGS_REGS);
} else if(apple_memory[0x0410] == 0xF2) { // Pravetz!
current_machine = MACHINE_PRAVETZ;
soft_switches &= ~(SOFTSW_IIE_REGS | SOFTSW_IIGS_REGS);
}
}
}
}
@ -94,10 +121,15 @@ int main() {
abus_init();
memcpy(config_errbuf, "V2ANALOG", 8);
memset(config_cmdbuf, 0xFF, 8);
multicore_launch_core1(core1_loop);
memcpy((uint8_t*)apple_memory+0xC1F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2ANALOG", 16);
memcpy((uint8_t*)apple_memory+0xC2F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2ANALOG", 16);
memcpy((uint8_t*)apple_memory+0xC3F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2ANALOG", 16);
memcpy((uint8_t*)apple_memory+0xC4F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2ANALOG", 16);
memcpy((uint8_t*)apple_memory+0xC5F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2ANALOG", 16);
memcpy((uint8_t*)apple_memory+0xC6F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2ANALOG", 16);
memcpy((uint8_t*)apple_memory+0xC7F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2ANALOG", 16);
// Sensible defaults if there is no config / fs
default_config();

View File

@ -7,7 +7,6 @@
volatile uint8_t *videx_page = videx_memory;
uint32_t a2_first_write = 0;
static inline void __time_critical_func(videx_crtc_addr)(uint32_t value) {
}
@ -150,24 +149,6 @@ void __time_critical_func(vga_businterface)(uint32_t address, uint32_t value) {
// Shadow parts of the Apple's memory by observing the bus write cycles
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0) {
if(current_machine == MACHINE_AUTO) {
a2_first_write = (address << 16) | (value & 0x3FF);
if(a2_first_write == 0xC0330100) { // Apple IIgs ROM03 Clock Access
current_machine = MACHINE_IIGS;
soft_switches &= ~SOFTSW_IIE_REGS;
soft_switches |= SOFTSW_IIGS_REGS;
} else if(a2_first_write == 0x01F901FB) { // Apple II Plus
current_machine = MACHINE_II;
soft_switches &= ~(SOFTSW_IIE_REGS | SOFTSW_IIGS_REGS);
} else if(a2_first_write == 0x01F5018B) { // Apple IIe Platinum
current_machine = MACHINE_IIE;
soft_switches |= SOFTSW_IIE_REGS;
soft_switches &= ~SOFTSW_IIGS_REGS;
} else {
a2_first_write = 0;
}
}
// Mirror Video Memory from MAIN & AUX banks
if(soft_switches & SOFTSW_LINEARIZE) {
if((address >= 0x2000) && (address < 0xC000)) {

View File

@ -26,7 +26,7 @@ const uint8_t default_character_rom[2048] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
0x00, 0x1c, 0x22, 0x26, 0x2a, 0x32, 0x22, 0x1c, 0x00, 0x08, 0x18, 0x08, 0x08, 0x08, 0x08, 0x1c,
0x00, 0x1c, 0x22, 0x02, 0x0c, 0x10, 0x20, 0x3e, 0x00, 0x3e, 0x02, 0x04, 0x0c, 0x02, 0x22, 0x1e,
0x00, 0x1c, 0x22, 0x02, 0x0c, 0x10, 0x20, 0x3e, 0x00, 0x3e, 0x02, 0x04, 0x0c, 0x02, 0x22, 0x1c,
0x00, 0x04, 0x0c, 0x14, 0x24, 0x3e, 0x04, 0x04, 0x00, 0x3e, 0x20, 0x3c, 0x02, 0x02, 0x22, 0x1c,
0x00, 0x0e, 0x10, 0x20, 0x3c, 0x22, 0x22, 0x1c, 0x00, 0x3e, 0x02, 0x04, 0x08, 0x10, 0x10, 0x10,
0x00, 0x1c, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x1c, 0x00, 0x1c, 0x22, 0x22, 0x1e, 0x02, 0x04, 0x38,
@ -58,7 +58,7 @@ const uint8_t default_character_rom[2048] = {
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x77, 0x77, 0x6f, 0x7f, 0x7f, 0x7f, 0x7f, 0x41, 0x7f, 0x7f, 0x7f,
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x77, 0x7f, 0x7f, 0x7d, 0x7b, 0x77, 0x6f, 0x5f, 0x7f,
0x7f, 0x63, 0x5d, 0x59, 0x55, 0x4d, 0x5d, 0x63, 0x7f, 0x77, 0x67, 0x77, 0x77, 0x77, 0x77, 0x63,
0x7f, 0x63, 0x5d, 0x7d, 0x73, 0x6f, 0x5f, 0x41, 0x7f, 0x41, 0x7d, 0x7b, 0x73, 0x7d, 0x5d, 0x61,
0x7f, 0x63, 0x5d, 0x7d, 0x73, 0x6f, 0x5f, 0x41, 0x7f, 0x41, 0x7d, 0x7b, 0x73, 0x7d, 0x5d, 0x63,
0x7f, 0x7b, 0x73, 0x6b, 0x5b, 0x41, 0x7b, 0x7b, 0x7f, 0x41, 0x5f, 0x43, 0x7d, 0x7d, 0x5d, 0x63,
0x7f, 0x71, 0x6f, 0x5f, 0x43, 0x5d, 0x5d, 0x63, 0x7f, 0x41, 0x7d, 0x7b, 0x77, 0x6f, 0x6f, 0x6f,
0x7f, 0x63, 0x5d, 0x5d, 0x63, 0x5d, 0x5d, 0x63, 0x7f, 0x63, 0x5d, 0x5d, 0x61, 0x7d, 0x7b, 0x47,
@ -90,7 +90,7 @@ const uint8_t default_character_rom[2048] = {
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x77, 0x77, 0x6f, 0x7f, 0x7f, 0x7f, 0x7f, 0x41, 0x7f, 0x7f, 0x7f,
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x77, 0x7f, 0x7f, 0x7d, 0x7b, 0x77, 0x6f, 0x5f, 0x7f,
0x7f, 0x63, 0x5d, 0x59, 0x55, 0x4d, 0x5d, 0x63, 0x7f, 0x77, 0x67, 0x77, 0x77, 0x77, 0x77, 0x63,
0x7f, 0x63, 0x5d, 0x7d, 0x73, 0x6f, 0x5f, 0x41, 0x7f, 0x41, 0x7d, 0x7b, 0x73, 0x7d, 0x5d, 0x61,
0x7f, 0x63, 0x5d, 0x7d, 0x73, 0x6f, 0x5f, 0x41, 0x7f, 0x41, 0x7d, 0x7b, 0x73, 0x7d, 0x5d, 0x63,
0x7f, 0x7b, 0x73, 0x6b, 0x5b, 0x41, 0x7b, 0x7b, 0x7f, 0x41, 0x5f, 0x43, 0x7d, 0x7d, 0x5d, 0x63,
0x7f, 0x71, 0x6f, 0x5f, 0x43, 0x5d, 0x5d, 0x63, 0x7f, 0x41, 0x7d, 0x7b, 0x77, 0x6f, 0x6f, 0x6f,
0x7f, 0x63, 0x5d, 0x5d, 0x63, 0x5d, 0x5d, 0x63, 0x7f, 0x63, 0x5d, 0x5d, 0x61, 0x7d, 0x7b, 0x47,
@ -122,7 +122,7 @@ const uint8_t default_character_rom[2048] = {
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x77, 0x77, 0x6f, 0x7f, 0x7f, 0x7f, 0x7f, 0x41, 0x7f, 0x7f, 0x7f,
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x77, 0x7f, 0x7f, 0x7d, 0x7b, 0x77, 0x6f, 0x5f, 0x7f,
0x7f, 0x63, 0x5d, 0x59, 0x55, 0x4d, 0x5d, 0x63, 0x7f, 0x77, 0x67, 0x77, 0x77, 0x77, 0x77, 0x63,
0x7f, 0x63, 0x5d, 0x7d, 0x73, 0x6f, 0x5f, 0x41, 0x7f, 0x41, 0x7d, 0x7b, 0x73, 0x7d, 0x5d, 0x61,
0x7f, 0x63, 0x5d, 0x7d, 0x73, 0x6f, 0x5f, 0x41, 0x7f, 0x41, 0x7d, 0x7b, 0x73, 0x7d, 0x5d, 0x63,
0x7f, 0x7b, 0x73, 0x6b, 0x5b, 0x41, 0x7b, 0x7b, 0x7f, 0x41, 0x5f, 0x43, 0x7d, 0x7d, 0x5d, 0x63,
0x7f, 0x71, 0x6f, 0x5f, 0x43, 0x5d, 0x5d, 0x63, 0x7f, 0x41, 0x7d, 0x7b, 0x77, 0x6f, 0x6f, 0x6f,
0x7f, 0x63, 0x5d, 0x5d, 0x63, 0x5d, 0x5d, 0x63, 0x7f, 0x63, 0x5d, 0x5d, 0x61, 0x7d, 0x7b, 0x47,
@ -393,3 +393,395 @@ const uint8_t appleiigs_character_rom[2048] = {
0x65, 0x53, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x55, 0x6b, 0x55, 0x6b, 0x55, 0x7f, 0x7f
};
const uint8_t pravetz_character_rom[2048] = {
0x00, 0x1c, 0x22, 0x2a, 0x2e, 0x2c, 0x20, 0x1e, 0x00, 0x08, 0x14, 0x22, 0x22, 0x3e, 0x22, 0x22,
0x00, 0x3c, 0x22, 0x22, 0x3c, 0x22, 0x22, 0x3c, 0x00, 0x1c, 0x22, 0x20, 0x20, 0x20, 0x22, 0x1c,
0x00, 0x3c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x3c, 0x00, 0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x3e,
0x00, 0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x20, 0x00, 0x1e, 0x20, 0x20, 0x20, 0x26, 0x22, 0x1e,
0x00, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x00, 0x1c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c,
0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x22, 0x1c, 0x00, 0x22, 0x24, 0x28, 0x30, 0x28, 0x24, 0x22,
0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3e, 0x00, 0x22, 0x36, 0x2a, 0x2a, 0x22, 0x22, 0x22,
0x00, 0x22, 0x22, 0x32, 0x2a, 0x26, 0x22, 0x22, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c,
0x00, 0x3c, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x20, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x2a, 0x24, 0x1a,
0x00, 0x3c, 0x22, 0x22, 0x3c, 0x28, 0x24, 0x22, 0x00, 0x1c, 0x22, 0x20, 0x1c, 0x02, 0x22, 0x1c,
0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c,
0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00, 0x22, 0x22, 0x22, 0x2a, 0x2a, 0x36, 0x22,
0x00, 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08,
0x00, 0x3e, 0x02, 0x04, 0x08, 0x10, 0x20, 0x3e, 0x00, 0x3e, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3e,
0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x3e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3e,
0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08,
0x00, 0x14, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x3e, 0x14, 0x3e, 0x14, 0x14,
0x00, 0x08, 0x1e, 0x28, 0x1c, 0x0a, 0x3c, 0x08, 0x00, 0x30, 0x32, 0x04, 0x08, 0x10, 0x26, 0x06,
0x00, 0x10, 0x28, 0x28, 0x10, 0x2a, 0x24, 0x1a, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x08, 0x10, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, 0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08,
0x00, 0x08, 0x2a, 0x1c, 0x08, 0x1c, 0x2a, 0x08, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
0x00, 0x1c, 0x22, 0x26, 0x2a, 0x32, 0x22, 0x1c, 0x00, 0x08, 0x18, 0x08, 0x08, 0x08, 0x08, 0x1c,
0x00, 0x1c, 0x22, 0x02, 0x0c, 0x10, 0x20, 0x3e, 0x00, 0x3e, 0x02, 0x04, 0x0c, 0x02, 0x22, 0x1c,
0x00, 0x04, 0x0c, 0x14, 0x24, 0x3e, 0x04, 0x04, 0x00, 0x3e, 0x20, 0x3c, 0x02, 0x02, 0x22, 0x1c,
0x00, 0x0e, 0x10, 0x20, 0x3c, 0x22, 0x22, 0x1c, 0x00, 0x3e, 0x02, 0x04, 0x08, 0x10, 0x10, 0x10,
0x00, 0x1c, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x1c, 0x00, 0x1c, 0x22, 0x22, 0x1e, 0x02, 0x04, 0x38,
0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x10,
0x00, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00,
0x00, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00, 0x1c, 0x22, 0x04, 0x08, 0x08, 0x00, 0x08,
0x00, 0x1c, 0x22, 0x2a, 0x2e, 0x2c, 0x20, 0x1e, 0x00, 0x08, 0x14, 0x22, 0x22, 0x3e, 0x22, 0x22,
0x00, 0x3c, 0x22, 0x22, 0x3c, 0x22, 0x22, 0x3c, 0x00, 0x1c, 0x22, 0x20, 0x20, 0x20, 0x22, 0x1c,
0x00, 0x3c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x3c, 0x00, 0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x3e,
0x00, 0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x20, 0x00, 0x1e, 0x20, 0x20, 0x20, 0x26, 0x22, 0x1e,
0x00, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x00, 0x1c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c,
0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x22, 0x1c, 0x00, 0x22, 0x24, 0x28, 0x30, 0x28, 0x24, 0x22,
0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3e, 0x00, 0x22, 0x36, 0x2a, 0x2a, 0x22, 0x22, 0x22,
0x00, 0x22, 0x22, 0x32, 0x2a, 0x26, 0x22, 0x22, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c,
0x00, 0x3c, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x20, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x2a, 0x24, 0x1a,
0x00, 0x3c, 0x22, 0x22, 0x3c, 0x28, 0x24, 0x22, 0x00, 0x1c, 0x22, 0x20, 0x1c, 0x02, 0x22, 0x1c,
0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c,
0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00, 0x22, 0x22, 0x22, 0x2a, 0x2a, 0x36, 0x22,
0x00, 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08,
0x00, 0x3e, 0x02, 0x04, 0x08, 0x10, 0x20, 0x3e, 0x00, 0x3e, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3e,
0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x3e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3e,
0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08,
0x00, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x3e, 0x14, 0x3e, 0x14, 0x14,
0x00, 0x08, 0x1e, 0x28, 0x1c, 0x0a, 0x3c, 0x08, 0x00, 0x30, 0x32, 0x04, 0x08, 0x10, 0x26, 0x06,
0x00, 0x10, 0x28, 0x28, 0x10, 0x2a, 0x24, 0x1a, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x08, 0x10, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, 0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08,
0x00, 0x08, 0x2a, 0x1c, 0x08, 0x1c, 0x2a, 0x08, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
0x00, 0x1c, 0x22, 0x26, 0x2a, 0x32, 0x22, 0x1c, 0x00, 0x08, 0x18, 0x08, 0x08, 0x08, 0x08, 0x1c,
0x00, 0x1c, 0x22, 0x02, 0x0c, 0x10, 0x20, 0x3e, 0x00, 0x3e, 0x02, 0x04, 0x0c, 0x02, 0x22, 0x1c,
0x00, 0x04, 0x0c, 0x14, 0x24, 0x3e, 0x04, 0x04, 0x00, 0x3e, 0x20, 0x3c, 0x02, 0x02, 0x22, 0x1c,
0x00, 0x0e, 0x10, 0x20, 0x3c, 0x22, 0x22, 0x1c, 0x00, 0x3e, 0x02, 0x04, 0x08, 0x10, 0x10, 0x10,
0x00, 0x1c, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x1c, 0x00, 0x1c, 0x22, 0x22, 0x1e, 0x02, 0x04, 0x38,
0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x10,
0x00, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00,
0x00, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00, 0x1c, 0x22, 0x04, 0x08, 0x08, 0x00, 0x08,
0x00, 0x1c, 0x22, 0x2a, 0x2e, 0x2c, 0x20, 0x1e, 0x00, 0x08, 0x14, 0x22, 0x22, 0x3e, 0x22, 0x22,
0x00, 0x3c, 0x22, 0x22, 0x3c, 0x22, 0x22, 0x3c, 0x00, 0x1c, 0x22, 0x20, 0x20, 0x20, 0x22, 0x1c,
0x00, 0x3c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x3c, 0x00, 0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x3e,
0x00, 0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x20, 0x00, 0x1e, 0x20, 0x20, 0x20, 0x26, 0x22, 0x1e,
0x00, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x00, 0x1c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c,
0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x22, 0x1c, 0x00, 0x22, 0x24, 0x28, 0x30, 0x28, 0x24, 0x22,
0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3e, 0x00, 0x22, 0x36, 0x2a, 0x2a, 0x22, 0x22, 0x22,
0x00, 0x22, 0x22, 0x32, 0x2a, 0x26, 0x22, 0x22, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c,
0x00, 0x3c, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x20, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x2a, 0x24, 0x1a,
0x00, 0x3c, 0x22, 0x22, 0x3c, 0x28, 0x24, 0x22, 0x00, 0x1c, 0x22, 0x20, 0x1c, 0x02, 0x22, 0x1c,
0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c,
0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00, 0x22, 0x22, 0x22, 0x2a, 0x2a, 0x36, 0x22,
0x00, 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08,
0x00, 0x3e, 0x02, 0x04, 0x08, 0x10, 0x20, 0x3e, 0x00, 0x3e, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3e,
0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x3e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3e,
0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08,
0x00, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x3e, 0x14, 0x3e, 0x14, 0x14,
0x00, 0x08, 0x1e, 0x28, 0x1c, 0x0a, 0x3c, 0x08, 0x00, 0x30, 0x32, 0x04, 0x08, 0x10, 0x26, 0x06,
0x00, 0x10, 0x28, 0x28, 0x10, 0x2a, 0x24, 0x1a, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x08, 0x10, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, 0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08,
0x00, 0x08, 0x2a, 0x1c, 0x08, 0x1c, 0x2a, 0x08, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
0x00, 0x1c, 0x22, 0x26, 0x2a, 0x32, 0x22, 0x1c, 0x00, 0x08, 0x18, 0x08, 0x08, 0x08, 0x08, 0x1c,
0x00, 0x1c, 0x22, 0x02, 0x0c, 0x10, 0x20, 0x3e, 0x00, 0x3e, 0x02, 0x04, 0x0c, 0x02, 0x22, 0x1c,
0x00, 0x04, 0x0c, 0x14, 0x24, 0x3e, 0x04, 0x04, 0x00, 0x3e, 0x20, 0x3c, 0x02, 0x02, 0x22, 0x1c,
0x00, 0x0e, 0x10, 0x20, 0x3c, 0x22, 0x22, 0x1c, 0x00, 0x3e, 0x02, 0x04, 0x08, 0x10, 0x10, 0x10,
0x00, 0x1c, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x1c, 0x00, 0x1c, 0x22, 0x22, 0x1e, 0x02, 0x04, 0x38,
0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x10,
0x00, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00,
0x00, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00, 0x1c, 0x22, 0x04, 0x08, 0x08, 0x00, 0x08,
0x00, 0x24, 0x2a, 0x2a, 0x3a, 0x2a, 0x2a, 0x24, 0x00, 0x08, 0x14, 0x22, 0x22, 0x3e, 0x22, 0x22,
0x00, 0x3c, 0x22, 0x22, 0x3c, 0x22, 0x22, 0x3c, 0x00, 0x1c, 0x22, 0x20, 0x20, 0x20, 0x22, 0x1c,
0x00, 0x3c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x3c, 0x00, 0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x3e,
0x00, 0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x20, 0x00, 0x1e, 0x20, 0x20, 0x20, 0x26, 0x22, 0x1e,
0x00, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x00, 0x1c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c,
0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x22, 0x1c, 0x00, 0x22, 0x24, 0x28, 0x30, 0x28, 0x24, 0x22,
0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3e, 0x00, 0x22, 0x36, 0x2a, 0x2a, 0x22, 0x22, 0x22,
0x00, 0x22, 0x22, 0x32, 0x2a, 0x26, 0x22, 0x22, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c,
0x00, 0x3c, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x20, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x2a, 0x24, 0x1a,
0x00, 0x3c, 0x22, 0x22, 0x3c, 0x28, 0x24, 0x22, 0x00, 0x1c, 0x22, 0x20, 0x1c, 0x02, 0x22, 0x1c,
0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c,
0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00, 0x22, 0x22, 0x22, 0x2a, 0x2a, 0x36, 0x22,
0x00, 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08,
0x00, 0x3e, 0x02, 0x04, 0x08, 0x10, 0x20, 0x3e, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x3e, 0x00,
0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x3e, 0x02,
0x00, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
0x00, 0x1c, 0x22, 0x2a, 0x2e, 0x2c, 0x20, 0x1e, 0x00, 0x08, 0x14, 0x22, 0x22, 0x3e, 0x22, 0x22,
0x00, 0x3c, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x3c, 0x00, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3e, 0x02,
0x00, 0x0c, 0x12, 0x12, 0x12, 0x12, 0x3e, 0x22, 0x00, 0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x3e,
0x00, 0x08, 0x1c, 0x2a, 0x2a, 0x2a, 0x1c, 0x08, 0x00, 0x3e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x22, 0x22, 0x26, 0x2a, 0x32, 0x22, 0x22,
0x00, 0x2a, 0x22, 0x26, 0x2a, 0x32, 0x22, 0x22, 0x00, 0x22, 0x24, 0x28, 0x30, 0x28, 0x24, 0x22,
0x00, 0x0e, 0x12, 0x12, 0x12, 0x12, 0x12, 0x22, 0x00, 0x22, 0x36, 0x2a, 0x2a, 0x22, 0x22, 0x22,
0x00, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c,
0x00, 0x3e, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x0a, 0x12, 0x22,
0x00, 0x3c, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x20, 0x00, 0x1c, 0x22, 0x20, 0x20, 0x20, 0x22, 0x1c,
0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x02, 0x3c,
0x00, 0x2a, 0x2a, 0x1c, 0x1c, 0x2a, 0x2a, 0x2a, 0x00, 0x3c, 0x22, 0x22, 0x3c, 0x22, 0x22, 0x3c,
0x00, 0x20, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x3c, 0x00, 0x30, 0x10, 0x10, 0x1c, 0x12, 0x12, 0x1c,
0x00, 0x3c, 0x02, 0x02, 0x1c, 0x02, 0x02, 0x3c, 0x00, 0x3e, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3e,
0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x3e, 0x02, 0x00, 0x3e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3e,
0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e
};
const uint8_t agat7_character_rom[2048] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x1e, 0x2a, 0x2a, 0x1a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x04, 0x7e, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x3e, 0x00, 0x08, 0x1c, 0x08, 0x08, 0x1c, 0x08, 0x3e, 0x00,
0x00, 0x08, 0x1c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x08, 0x00,
0x00, 0x00, 0x04, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3e, 0x00,
0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00,
0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x3e, 0x14, 0x3e, 0x14, 0x14, 0x00,
0x22, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x22, 0x00, 0x30, 0x32, 0x04, 0x08, 0x10, 0x26, 0x06, 0x00,
0x10, 0x28, 0x28, 0x10, 0x2a, 0x24, 0x1a, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x08, 0x10, 0x10, 0x10, 0x08, 0x04, 0x00, 0x10, 0x08, 0x04, 0x04, 0x04, 0x08, 0x10, 0x00,
0x08, 0x2a, 0x1c, 0x08, 0x1c, 0x2a, 0x08, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00,
0x1c, 0x22, 0x26, 0x2a, 0x32, 0x22, 0x1c, 0x00, 0x08, 0x18, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00,
0x1c, 0x22, 0x02, 0x04, 0x08, 0x10, 0x3e, 0x00, 0x3e, 0x02, 0x04, 0x0c, 0x02, 0x22, 0x1c, 0x00,
0x04, 0x0c, 0x14, 0x24, 0x3e, 0x04, 0x04, 0x00, 0x3e, 0x20, 0x3c, 0x02, 0x02, 0x22, 0x1c, 0x00,
0x0e, 0x10, 0x20, 0x3c, 0x22, 0x22, 0x1c, 0x00, 0x3e, 0x02, 0x04, 0x08, 0x10, 0x10, 0x10, 0x00,
0x1c, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x1c, 0x00, 0x1c, 0x22, 0x22, 0x1e, 0x02, 0x04, 0x38, 0x00,
0x00, 0x00, 0x0c, 0x0c, 0x00, 0x0c, 0x0c, 0x00, 0x0c, 0x0c, 0x00, 0x0c, 0x0c, 0x04, 0x08, 0x00,
0x02, 0x04, 0x08, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00, 0x00,
0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00, 0x1c, 0x22, 0x04, 0x08, 0x08, 0x00, 0x08, 0x00,
0x1c, 0x22, 0x2e, 0x2a, 0x2e, 0x20, 0x1e, 0x00, 0x08, 0x14, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x00,
0x3c, 0x22, 0x22, 0x3c, 0x22, 0x22, 0x3c, 0x00, 0x1c, 0x22, 0x20, 0x20, 0x20, 0x22, 0x1c, 0x00,
0x3c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x3c, 0x00, 0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x3e, 0x00,
0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x20, 0x00, 0x1e, 0x20, 0x20, 0x20, 0x26, 0x22, 0x1e, 0x00,
0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x00, 0x1c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00,
0x02, 0x02, 0x02, 0x02, 0x02, 0x22, 0x1c, 0x00, 0x22, 0x24, 0x28, 0x30, 0x28, 0x24, 0x22, 0x00,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3e, 0x00, 0x22, 0x36, 0x2a, 0x2a, 0x22, 0x22, 0x22, 0x00,
0x22, 0x22, 0x32, 0x2a, 0x26, 0x22, 0x22, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00,
0x3c, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x20, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x2a, 0x24, 0x1a, 0x00,
0x3c, 0x22, 0x22, 0x3c, 0x28, 0x24, 0x22, 0x00, 0x1c, 0x22, 0x20, 0x1c, 0x02, 0x22, 0x1c, 0x00,
0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00,
0x22, 0x22, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00, 0x22, 0x22, 0x22, 0x2a, 0x2a, 0x36, 0x22, 0x00,
0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00,
0x3e, 0x02, 0x04, 0x08, 0x10, 0x20, 0x3e, 0x00, 0x3e, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3e, 0x00,
0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x3e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3e, 0x00,
0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0x2e, 0x2a, 0x2a, 0x3a, 0x2a, 0x2a, 0x2e, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x00,
0x3e, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x3c, 0x00, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3e, 0x02,
0x0e, 0x12, 0x12, 0x12, 0x12, 0x12, 0x3f, 0x21, 0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x3e, 0x00,
0x1c, 0x2a, 0x2a, 0x2a, 0x1c, 0x08, 0x08, 0x00, 0x3e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,
0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x22, 0x22, 0x22, 0x26, 0x2a, 0x32, 0x22, 0x00,
0x2a, 0x2a, 0x22, 0x26, 0x2a, 0x32, 0x22, 0x00, 0x22, 0x24, 0x28, 0x30, 0x28, 0x24, 0x22, 0x00,
0x06, 0x0a, 0x12, 0x12, 0x12, 0x12, 0x22, 0x00, 0x22, 0x36, 0x2a, 0x2a, 0x22, 0x22, 0x22, 0x00,
0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00,
0x3e, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x0a, 0x12, 0x22, 0x00,
0x3c, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x20, 0x00, 0x1c, 0x22, 0x20, 0x20, 0x20, 0x22, 0x1c, 0x00,
0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x22, 0x1c, 0x00,
0x2a, 0x2a, 0x2a, 0x1c, 0x2a, 0x2a, 0x2a, 0x00, 0x3c, 0x22, 0x22, 0x3c, 0x22, 0x22, 0x3c, 0x00,
0x20, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x3c, 0x00, 0x22, 0x22, 0x22, 0x3a, 0x2a, 0x2a, 0x3a, 0x00,
0x1c, 0x22, 0x02, 0x0c, 0x02, 0x22, 0x1c, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x3e, 0x00,
0x3c, 0x02, 0x02, 0x1e, 0x02, 0x02, 0x3c, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x3e, 0x02,
0x22, 0x22, 0x22, 0x1e, 0x02, 0x02, 0x02, 0x00, 0x30, 0x10, 0x10, 0x1c, 0x12, 0x12, 0x1c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x1e, 0x2a, 0x2a, 0x1a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x04, 0x7e, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x3e, 0x00, 0x08, 0x1c, 0x08, 0x08, 0x1c, 0x08, 0x3e, 0x00,
0x00, 0x08, 0x1c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x08, 0x00,
0x00, 0x00, 0x04, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3e, 0x00,
0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00,
0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x3e, 0x14, 0x3e, 0x14, 0x14, 0x00,
0x22, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x22, 0x00, 0x30, 0x32, 0x04, 0x08, 0x10, 0x26, 0x06, 0x00,
0x10, 0x28, 0x28, 0x10, 0x2a, 0x24, 0x1a, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x08, 0x10, 0x10, 0x10, 0x08, 0x04, 0x00, 0x10, 0x08, 0x04, 0x04, 0x04, 0x08, 0x10, 0x00,
0x08, 0x2a, 0x1c, 0x08, 0x1c, 0x2a, 0x08, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00,
0x1c, 0x22, 0x26, 0x2a, 0x32, 0x22, 0x1c, 0x00, 0x08, 0x18, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00,
0x1c, 0x22, 0x02, 0x04, 0x08, 0x10, 0x3e, 0x00, 0x3e, 0x02, 0x04, 0x0c, 0x02, 0x22, 0x1c, 0x00,
0x04, 0x0c, 0x14, 0x24, 0x3e, 0x04, 0x04, 0x00, 0x3e, 0x20, 0x3c, 0x02, 0x02, 0x22, 0x1c, 0x00,
0x0e, 0x10, 0x20, 0x3c, 0x22, 0x22, 0x1c, 0x00, 0x3e, 0x02, 0x04, 0x08, 0x10, 0x10, 0x10, 0x00,
0x1c, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x1c, 0x00, 0x1c, 0x22, 0x22, 0x1e, 0x02, 0x04, 0x38, 0x00,
0x00, 0x00, 0x0c, 0x0c, 0x00, 0x0c, 0x0c, 0x00, 0x0c, 0x0c, 0x00, 0x0c, 0x0c, 0x04, 0x08, 0x00,
0x02, 0x04, 0x08, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00, 0x00,
0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00, 0x1c, 0x22, 0x04, 0x08, 0x08, 0x00, 0x08, 0x00,
0x1c, 0x22, 0x2e, 0x2a, 0x2e, 0x20, 0x1e, 0x00, 0x08, 0x14, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x00,
0x3c, 0x22, 0x22, 0x3c, 0x22, 0x22, 0x3c, 0x00, 0x1c, 0x22, 0x20, 0x20, 0x20, 0x22, 0x1c, 0x00,
0x3c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x3c, 0x00, 0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x3e, 0x00,
0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x20, 0x00, 0x1e, 0x20, 0x20, 0x20, 0x26, 0x22, 0x1e, 0x00,
0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x00, 0x1c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00,
0x02, 0x02, 0x02, 0x02, 0x02, 0x22, 0x1c, 0x00, 0x22, 0x24, 0x28, 0x30, 0x28, 0x24, 0x22, 0x00,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3e, 0x00, 0x22, 0x36, 0x2a, 0x2a, 0x22, 0x22, 0x22, 0x00,
0x22, 0x22, 0x32, 0x2a, 0x26, 0x22, 0x22, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00,
0x3c, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x20, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x2a, 0x24, 0x1a, 0x00,
0x3c, 0x22, 0x22, 0x3c, 0x28, 0x24, 0x22, 0x00, 0x1c, 0x22, 0x20, 0x1c, 0x02, 0x22, 0x1c, 0x00,
0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00,
0x22, 0x22, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00, 0x22, 0x22, 0x22, 0x2a, 0x2a, 0x36, 0x22, 0x00,
0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00,
0x3e, 0x02, 0x04, 0x08, 0x10, 0x20, 0x3e, 0x00, 0x3e, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3e, 0x00,
0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x3e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3e, 0x00,
0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0x2e, 0x2a, 0x2a, 0x3a, 0x2a, 0x2a, 0x2e, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x00,
0x3e, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x3c, 0x00, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3e, 0x02,
0x0e, 0x12, 0x12, 0x12, 0x12, 0x12, 0x3f, 0x21, 0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x3e, 0x00,
0x1c, 0x2a, 0x2a, 0x2a, 0x1c, 0x08, 0x08, 0x00, 0x3e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,
0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x22, 0x22, 0x22, 0x26, 0x2a, 0x32, 0x22, 0x00,
0x2a, 0x2a, 0x22, 0x26, 0x2a, 0x32, 0x22, 0x00, 0x22, 0x24, 0x28, 0x30, 0x28, 0x24, 0x22, 0x00,
0x06, 0x0a, 0x12, 0x12, 0x12, 0x12, 0x22, 0x00, 0x22, 0x36, 0x2a, 0x2a, 0x22, 0x22, 0x22, 0x00,
0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00,
0x3e, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x0a, 0x12, 0x22, 0x00,
0x3c, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x20, 0x00, 0x1c, 0x22, 0x20, 0x20, 0x20, 0x22, 0x1c, 0x00,
0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x22, 0x1c, 0x00,
0x2a, 0x2a, 0x2a, 0x1c, 0x2a, 0x2a, 0x2a, 0x00, 0x3c, 0x22, 0x22, 0x3c, 0x22, 0x22, 0x3c, 0x00,
0x20, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x3c, 0x00, 0x22, 0x22, 0x22, 0x3a, 0x2a, 0x2a, 0x3a, 0x00,
0x1c, 0x22, 0x02, 0x0c, 0x02, 0x22, 0x1c, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x3e, 0x00,
0x3c, 0x02, 0x02, 0x1e, 0x02, 0x02, 0x3c, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x3e, 0x02,
0x22, 0x22, 0x22, 0x1e, 0x02, 0x02, 0x02, 0x00, 0x30, 0x10, 0x10, 0x1c, 0x12, 0x12, 0x1c, 0x00
};
const uint8_t agat9_character_rom[2048] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x00, 0x00, 0x1e, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00,
0x22, 0x22, 0x3e, 0x22, 0x22, 0x14, 0x08, 0x00, 0x1e, 0x02, 0x02, 0x0e, 0x02, 0x02, 0x1e, 0x00,
0x00, 0x08, 0x10, 0x3e, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x0c, 0x08, 0x08,
0x00, 0x00, 0x00, 0xe0, 0x30, 0x18, 0x08, 0x08, 0x08, 0x18, 0x30, 0xe0, 0x00, 0x00, 0x00, 0x00,
0x08, 0x0c, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x08, 0x08, 0x2a, 0x1c, 0x08, 0x3e, 0x00,
0x00, 0x20, 0x12, 0x0a, 0x06, 0x1e, 0x00, 0x00, 0x14, 0x00, 0x1c, 0x22, 0x3e, 0x20, 0x1e, 0x00,
0x00, 0x00, 0x00, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0xff, 0x08, 0x08, 0x08, 0x08,
0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x04, 0xfe, 0x04, 0x08, 0x00, 0x00,
0x00, 0x1e, 0x06, 0x0a, 0x12, 0x20, 0x00, 0x00, 0x00, 0x02, 0x24, 0x28, 0x30, 0x3c, 0x00, 0x00,
0x00, 0x3c, 0x30, 0x28, 0x24, 0x02, 0x00, 0x00, 0x08, 0x1c, 0x2a, 0x08, 0x08, 0x08, 0x08, 0x00,
0x08, 0x08, 0x08, 0x08, 0x2a, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
0x08, 0x08, 0x08, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x00, 0x00, 0x00, 0x00,
0x08, 0x08, 0x08, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1a, 0x24, 0x24, 0x1a, 0x00, 0x00,
0x00, 0x38, 0x24, 0x2c, 0x22, 0x2c, 0x20, 0x20, 0x00, 0x22, 0x14, 0x08, 0x14, 0x14, 0x14, 0x08,
0x00, 0x0c, 0x12, 0x08, 0x12, 0x0c, 0x00, 0x00, 0x20, 0x10, 0x08, 0x14, 0x22, 0x22, 0x00, 0x00,
0x00, 0x24, 0x24, 0x24, 0x34, 0x2a, 0x20, 0x20, 0x00, 0x3e, 0x14, 0x14, 0x14, 0x24, 0x00, 0x00,
0x00, 0x0c, 0x12, 0x12, 0x1c, 0x10, 0x10, 0x20, 0x00, 0x1e, 0x28, 0x08, 0x08, 0x04, 0x00, 0x00,
0x00, 0x24, 0x2a, 0x2a, 0x2a, 0x1c, 0x08, 0x08, 0x00, 0x22, 0x2a, 0x2a, 0x2a, 0x1c, 0x08, 0x08,
0x00, 0x14, 0x22, 0x22, 0x2a, 0x14, 0x00, 0x00, 0x3e, 0x20, 0x10, 0x08, 0x10, 0x20, 0x3e, 0x00,
0x00, 0x02, 0x06, 0x0a, 0x12, 0x22, 0x3e, 0x00, 0x00, 0x08, 0x00, 0x3e, 0x00, 0x08, 0x00, 0x00,
0x18, 0x24, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x10, 0x30, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00,
0x18, 0x24, 0x08, 0x10, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x24, 0x08, 0x24, 0x18, 0x00, 0x00, 0x00,
0x0c, 0x14, 0x24, 0x3c, 0x04, 0x00, 0x00, 0x00, 0x3c, 0x20, 0x38, 0x04, 0x38, 0x00, 0x00, 0x00,
0x1c, 0x20, 0x38, 0x24, 0x18, 0x00, 0x00, 0x00, 0x3c, 0x04, 0x08, 0x10, 0x10, 0x00, 0x00, 0x00,
0x18, 0x24, 0x18, 0x24, 0x18, 0x00, 0x00, 0x00, 0x18, 0x24, 0x1c, 0x04, 0x38, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00,
0x04, 0x08, 0x10, 0x08, 0x04, 0x10, 0x08, 0x04, 0x00, 0x04, 0x3e, 0x08, 0x3e, 0x10, 0x00, 0x00,
0x10, 0x08, 0x04, 0x08, 0x10, 0x04, 0x08, 0x10, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x00, 0x3e, 0x00,
0x1e, 0x10, 0x3e, 0x22, 0x3e, 0x04, 0x3c, 0x00, 0x00, 0x00, 0x1c, 0x24, 0x24, 0x24, 0x1a, 0x00,
0x20, 0x20, 0x2c, 0x32, 0x22, 0x22, 0x3c, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x20, 0x20, 0x1e, 0x00,
0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x1e, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x14, 0x18, 0x0e, 0x00,
0x0c, 0x12, 0x10, 0x3c, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x02, 0x1c,
0x20, 0x20, 0x3c, 0x22, 0x22, 0x22, 0x22, 0x00, 0x08, 0x00, 0x08, 0x08, 0x08, 0x08, 0x0c, 0x00,
0x04, 0x00, 0x0c, 0x04, 0x04, 0x04, 0x24, 0x18, 0x20, 0x20, 0x22, 0x24, 0x38, 0x24, 0x22, 0x00,
0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x34, 0x2a, 0x2a, 0x2a, 0x2a, 0x00,
0x00, 0x00, 0x2c, 0x32, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00,
0x00, 0x00, 0x3c, 0x22, 0x22, 0x32, 0x2c, 0x20, 0x00, 0x00, 0x1e, 0x22, 0x22, 0x26, 0x1a, 0x02,
0x00, 0x00, 0x2c, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x1e, 0x20, 0x1c, 0x02, 0x3c, 0x00,
0x10, 0x10, 0x3c, 0x10, 0x10, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x26, 0x1a, 0x00,
0x00, 0x00, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00, 0x00, 0x00, 0x22, 0x2a, 0x2a, 0x2a, 0x14, 0x00,
0x00, 0x00, 0x36, 0x08, 0x08, 0x2a, 0x14, 0x00, 0x00, 0x00, 0x22, 0x22, 0x14, 0x08, 0x10, 0x20,
0x00, 0x00, 0x3e, 0x04, 0x08, 0x10, 0x3e, 0x00, 0x0e, 0x18, 0x18, 0x30, 0x18, 0x18, 0x0e, 0x00,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x0c, 0x0c, 0x06, 0x0c, 0x0c, 0x38, 0x00,
0x00, 0x10, 0x2a, 0x04, 0x00, 0x3e, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x26, 0x29, 0x39, 0x29, 0x26, 0x00, 0x00, 0x00, 0x18, 0x04, 0x1c, 0x24, 0x1a, 0x00,
0x02, 0x1c, 0x20, 0x2c, 0x32, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x3f, 0x01,
0x1c, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x3e, 0x20, 0x1e, 0x00,
0x00, 0x08, 0x1c, 0x2a, 0x2a, 0x2a, 0x1c, 0x08, 0x00, 0x00, 0x3c, 0x24, 0x20, 0x20, 0x20, 0x00,
0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x22, 0x26, 0x2a, 0x32, 0x22, 0x00,
0x00, 0x08, 0x22, 0x26, 0x2a, 0x32, 0x22, 0x00, 0x00, 0x00, 0x22, 0x24, 0x38, 0x24, 0x22, 0x00,
0x00, 0x00, 0x06, 0x0a, 0x12, 0x12, 0x22, 0x00, 0x00, 0x00, 0x22, 0x36, 0x2a, 0x22, 0x22, 0x00,
0x00, 0x00, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x24, 0x18, 0x00,
0x00, 0x00, 0x3e, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x1e, 0x0a, 0x32, 0x00,
0x00, 0x00, 0x3c, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x00, 0x00, 0x1e, 0x20, 0x20, 0x20, 0x1e, 0x00,
0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x1c,
0x00, 0x00, 0x2a, 0x2a, 0x1c, 0x2a, 0x2a, 0x00, 0x10, 0x28, 0x28, 0x2c, 0x32, 0x22, 0x3c, 0x00,
0x00, 0x00, 0x20, 0x2c, 0x32, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x21, 0x29, 0x35, 0x25, 0x19, 0x00,
0x00, 0x00, 0x1c, 0x22, 0x0c, 0x02, 0x3c, 0x00, 0x00, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x3e, 0x00,
0x00, 0x00, 0x3c, 0x02, 0x1e, 0x02, 0x3c, 0x00, 0x00, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x3f, 0x01,
0x00, 0x00, 0x22, 0x22, 0x3e, 0x02, 0x02, 0x00, 0x00, 0x00, 0x30, 0x14, 0x1a, 0x12, 0x0c, 0x00,
0x1c, 0x22, 0x2a, 0x2e, 0x2c, 0x20, 0x1e, 0x00, 0x07, 0x0a, 0x12, 0x12, 0x1e, 0x12, 0x33, 0x00,
0x3c, 0x12, 0x12, 0x1c, 0x12, 0x12, 0x3c, 0x00, 0x1e, 0x22, 0x20, 0x20, 0x20, 0x22, 0x1e, 0x00,
0x3c, 0x12, 0x12, 0x12, 0x12, 0x12, 0x3c, 0x00, 0x3e, 0x10, 0x10, 0x1c, 0x10, 0x10, 0x3e, 0x00,
0x3e, 0x12, 0x10, 0x18, 0x10, 0x10, 0x38, 0x00, 0x1c, 0x22, 0x20, 0x20, 0x2e, 0x22, 0x1c, 0x00,
0x33, 0x12, 0x12, 0x1e, 0x12, 0x12, 0x33, 0x00, 0x1c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00,
0x0e, 0x04, 0x04, 0x04, 0x04, 0x24, 0x18, 0x00, 0x31, 0x12, 0x14, 0x18, 0x14, 0x12, 0x31, 0x00,
0x38, 0x10, 0x10, 0x10, 0x10, 0x12, 0x3e, 0x00, 0x11, 0x1b, 0x15, 0x15, 0x11, 0x11, 0x31, 0x00,
0x22, 0x22, 0x32, 0x2a, 0x26, 0x22, 0x22, 0x00, 0x0c, 0x12, 0x21, 0x21, 0x21, 0x12, 0x0c, 0x00,
0x3e, 0x11, 0x11, 0x1e, 0x10, 0x10, 0x38, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x2a, 0x24, 0x1a, 0x00,
0x3e, 0x11, 0x11, 0x1e, 0x14, 0x12, 0x31, 0x00, 0x1c, 0x22, 0x20, 0x1c, 0x02, 0x22, 0x1c, 0x00,
0x3e, 0x2a, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00,
0x22, 0x22, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00, 0x22, 0x22, 0x22, 0x2a, 0x2a, 0x36, 0x22, 0x00,
0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00,
0x3e, 0x22, 0x04, 0x08, 0x10, 0x22, 0x3e, 0x00, 0x1e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1e, 0x00,
0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00,
0x00, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x3e, 0x20, 0x3c, 0x20, 0x3e, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00,
0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x3e, 0x14, 0x3e, 0x14, 0x14, 0x00,
0x22, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x22, 0x00, 0x30, 0x32, 0x04, 0x08, 0x10, 0x26, 0x06, 0x00,
0x10, 0x28, 0x28, 0x10, 0x2a, 0x24, 0x1a, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x10, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, 0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08, 0x00,
0x08, 0x2a, 0x1c, 0x08, 0x1c, 0x2a, 0x08, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00,
0x1c, 0x22, 0x26, 0x2a, 0x32, 0x22, 0x1c, 0x00, 0x08, 0x18, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00,
0x1c, 0x22, 0x02, 0x0c, 0x10, 0x20, 0x3e, 0x00, 0x3e, 0x02, 0x04, 0x0c, 0x02, 0x22, 0x1c, 0x00,
0x04, 0x0c, 0x14, 0x24, 0x3e, 0x04, 0x04, 0x00, 0x3e, 0x20, 0x3c, 0x02, 0x02, 0x22, 0x1c, 0x00,
0x0e, 0x10, 0x20, 0x3c, 0x22, 0x22, 0x1c, 0x00, 0x3e, 0x02, 0x04, 0x08, 0x10, 0x10, 0x10, 0x00,
0x1c, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x1c, 0x00, 0x1c, 0x22, 0x22, 0x1e, 0x02, 0x04, 0x38, 0x00,
0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x08, 0x10,
0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00, 0x00,
0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00, 0x1c, 0x22, 0x04, 0x08, 0x08, 0x00, 0x08, 0x00,
0x1c, 0x22, 0x2a, 0x2e, 0x2c, 0x20, 0x1e, 0x00, 0x07, 0x0a, 0x12, 0x12, 0x1e, 0x12, 0x33, 0x00,
0x3c, 0x12, 0x12, 0x1c, 0x12, 0x12, 0x3c, 0x00, 0x1e, 0x22, 0x20, 0x20, 0x20, 0x22, 0x1e, 0x00,
0x3c, 0x12, 0x12, 0x12, 0x12, 0x12, 0x3c, 0x00, 0x3e, 0x10, 0x10, 0x1c, 0x10, 0x10, 0x3e, 0x00,
0x3e, 0x12, 0x10, 0x18, 0x10, 0x10, 0x38, 0x00, 0x1c, 0x22, 0x20, 0x20, 0x2e, 0x22, 0x1c, 0x00,
0x33, 0x12, 0x12, 0x1e, 0x12, 0x12, 0x33, 0x00, 0x1c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00,
0x0e, 0x04, 0x04, 0x04, 0x04, 0x24, 0x18, 0x00, 0x31, 0x12, 0x14, 0x18, 0x14, 0x12, 0x31, 0x00,
0x38, 0x10, 0x10, 0x10, 0x10, 0x12, 0x3e, 0x00, 0x11, 0x1b, 0x15, 0x15, 0x11, 0x11, 0x31, 0x00,
0x22, 0x22, 0x32, 0x2a, 0x26, 0x22, 0x22, 0x00, 0x0c, 0x12, 0x21, 0x21, 0x21, 0x12, 0x0c, 0x00,
0x3e, 0x11, 0x11, 0x1e, 0x10, 0x10, 0x38, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x2a, 0x24, 0x1a, 0x00,
0x3e, 0x11, 0x11, 0x1e, 0x14, 0x12, 0x31, 0x00, 0x1c, 0x22, 0x20, 0x1c, 0x02, 0x22, 0x1c, 0x00,
0x3e, 0x2a, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00,
0x22, 0x22, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00, 0x22, 0x22, 0x22, 0x2a, 0x2a, 0x36, 0x22, 0x00,
0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00,
0x3e, 0x22, 0x04, 0x08, 0x10, 0x22, 0x3e, 0x00, 0x1e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1e, 0x00,
0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00,
0x00, 0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
0x26, 0x29, 0x29, 0x39, 0x29, 0x29, 0x26, 0x00, 0x08, 0x14, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x00,
0x3e, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x3c, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x3f, 0x01,
0x0e, 0x12, 0x12, 0x12, 0x12, 0x12, 0x3f, 0x21, 0x3e, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x3e, 0x00,
0x1c, 0x2a, 0x2a, 0x2a, 0x2a, 0x1c, 0x08, 0x00, 0x3e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,
0x22, 0x36, 0x1c, 0x08, 0x1c, 0x36, 0x22, 0x00, 0x22, 0x22, 0x26, 0x2a, 0x32, 0x22, 0x22, 0x00,
0x2d, 0x21, 0x23, 0x25, 0x29, 0x31, 0x21, 0x00, 0x22, 0x24, 0x28, 0x30, 0x28, 0x24, 0x22, 0x00,
0x0e, 0x12, 0x12, 0x12, 0x12, 0x12, 0x22, 0x00, 0x22, 0x36, 0x2a, 0x2a, 0x22, 0x22, 0x22, 0x00,
0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00,
0x3e, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x0a, 0x12, 0x22, 0x00,
0x3c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x00, 0x1c, 0x22, 0x20, 0x20, 0x20, 0x22, 0x1c, 0x00,
0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x22, 0x1c, 0x00,
0x2a, 0x2a, 0x2a, 0x1c, 0x2a, 0x2a, 0x2a, 0x00, 0x3c, 0x22, 0x22, 0x3c, 0x22, 0x22, 0x3c, 0x00,
0x20, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x3c, 0x00, 0x21, 0x21, 0x21, 0x39, 0x25, 0x25, 0x39, 0x00,
0x1c, 0x22, 0x02, 0x0c, 0x02, 0x22, 0x1c, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x3e, 0x00,
0x3c, 0x02, 0x02, 0x1e, 0x02, 0x02, 0x3c, 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x3f, 0x01,
0x22, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x02, 0x00, 0x30, 0x10, 0x10, 0x1c, 0x12, 0x12, 0x1c, 0x00
};

View File

@ -5,3 +5,6 @@
extern const uint8_t default_character_rom[2048];
extern const uint8_t appleiie_character_rom[2048];
extern const uint8_t appleiigs_character_rom[2048];
extern const uint8_t pravetz_character_rom[2048];
extern const uint8_t agat7_character_rom[2048];
extern const uint8_t agat9_character_rom[2048];

View File

@ -202,7 +202,7 @@ static uint32_t hires_color_patterns[2*256] = {
/* 0b11000100 */ _PIXELS(0x012, 0x010),
/* 0b11000101 */ _PIXELS(0x012, 0x051),
/* 0b11000110 */ _PIXELS(0x02b, 0x031),
/* 0b11000111 */ _PIXELS(0x02b, 0x130),
/* 0b11000111 */ _PIXELS(0x000, 0x000), //_PIXELS(0x02b, 0x130),
/* 0b11001000 */ _PIXELS(0x00d, 0x005),
/* 0b11001001 */ _PIXELS(0x00d, 0x10f),
/* 0b11001010 */ _PIXELS(0x0e5, 0x124),
@ -230,11 +230,11 @@ static uint32_t hires_color_patterns[2*256] = {
/* 0b11100000 */ _PIXELS(0x000, 0x000),
/* 0b11100001 */ _PIXELS(0x000, 0x000),
/* 0b11100010 */ _PIXELS(0x099, 0x048),
/* 0b11100011 */ _PIXELS(0x099, 0x150),
/* 0b11100011 */ _PIXELS(0x000, 0x000), //_PIXELS(0x099, 0x150),
/* 0b11100100 */ _PIXELS(0x059, 0x010),
/* 0b11100101 */ _PIXELS(0x059, 0x052),
/* 0b11100110 */ _PIXELS(0x072, 0x031),
/* 0b11100111 */ _PIXELS(0x072, 0x130),
/* 0b11100111 */ _PIXELS(0x000, 0x000), //_PIXELS(0x072, 0x130),
/* 0b11101000 */ _PIXELS(0x055, 0x00d),
/* 0b11101001 */ _PIXELS(0x055, 0x10e),
/* 0b11101010 */ _PIXELS(0x12c, 0x124),
@ -460,7 +460,7 @@ static uint32_t hires_color_patterns[2*256] = {
/* 0b11000100 */ _PIXELS(0x0c3, 0x0c3),
/* 0b11000101 */ _PIXELS(0x0c3, 0x08a),
/* 0b11000110 */ _PIXELS(0x10e, 0x14f),
/* 0b11000111 */ _PIXELS(0x10e, 0x0d7),
/* 0b11000111 */ _PIXELS(0x000, 0x000), //_PIXELS(0x10e, 0x0d7),
/* 0b11001000 */ _PIXELS(0x1d0, 0x1d0),
/* 0b11001001 */ _PIXELS(0x1d0, 0x1a8),
/* 0b11001010 */ _PIXELS(0x1dd, 0x1de),
@ -488,11 +488,11 @@ static uint32_t hires_color_patterns[2*256] = {
/* 0b11100000 */ _PIXELS(0x000, 0x000),
/* 0b11100001 */ _PIXELS(0x000, 0x000),
/* 0b11100010 */ _PIXELS(0x14f, 0x14f),
/* 0b11100011 */ _PIXELS(0x14f, 0x0d7),
/* 0b11100011 */ _PIXELS(0x000, 0x000), //_PIXELS(0x14f, 0x0d7),
/* 0b11100100 */ _PIXELS(0x14f, 0x14f),
/* 0b11100101 */ _PIXELS(0x14f, 0x0d7),
/* 0b11100110 */ _PIXELS(0x14f, 0x14f),
/* 0b11100111 */ _PIXELS(0x14f, 0x0d7),
/* 0b11100111 */ _PIXELS(0x000, 0x000), //_PIXELS(0x14f, 0x0d7),
/* 0b11101000 */ _PIXELS(0x1df, 0x1df),
/* 0b11101001 */ _PIXELS(0x1df, 0x1f7),
/* 0b11101010 */ _PIXELS(0x1df, 0x1df),

View File

@ -22,6 +22,9 @@ void switch_font() {
case MACHINE_II:
memcpy(character_rom, default_character_rom, 2048);
break;
case MACHINE_PRAVETZ:
memcpy(character_rom, pravetz_character_rom, 2048);
break;
case MACHINE_IIE:
memcpy(character_rom, appleiie_character_rom, 2048);
break;
@ -51,6 +54,53 @@ void load_font() {
return;
}
uint16_t status_timeout = 900;
uint8_t status_line[81];
void 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 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 render_init() {
int i;
@ -63,11 +113,14 @@ void render_init() {
terminal_tbcolor = 0xf0;
terminal_border = 0x00;
memcpy(videx_character_rom, appleiie_character_rom, 2048);
memset(status_line, 0, sizeof(status_line));
render_test_init();
}
// Blank screen
void __time_critical_func(render_blank)() {
// Skip 48 lines to center vertically
void __time_critical_func(render_border)(uint count) {
struct vga_scanline *sl = vga_prepare_scanline();
uint sl_pos = 0;
@ -77,7 +130,7 @@ void __time_critical_func(render_blank)() {
}
sl->length = sl_pos;
sl->repeat_count = 479;
sl->repeat_count = count - 1;
vga_submit_scanline(sl);
}
@ -87,25 +140,29 @@ uint32_t testdone = 0;
void __noinline __time_critical_func(render_loop)() {
while(current_mode == MODE_VGACARD) {
config_handler();
#if 0
if((busactive == 0) && (screentimeout > (30 * 60))) {
render_blank();
} else if((busactive == 0) && (screentimeout > (15 * 60))) {
render_testpattern();
screentimeout++;
} else if((busactive == 0) && (screentimeout == 15 * 60)) {
render_test_sleep();
render_testpattern();
screentimeout++;
if((busactive == 0) && (screentimeout > (15 * 60))) {
vga_prepare_frame();
render_border(480);
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(!userfont && (machinefont != current_machine)) {
switch_font();
@ -132,6 +189,16 @@ void __noinline __time_critical_func(render_loop)() {
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) {
@ -165,7 +232,9 @@ void __noinline __time_critical_func(render_loop)() {
render_text();
break;
}
render_border(48);
}
// }
}
}
}

View File

@ -7,6 +7,10 @@
extern uint16_t lores_palette[16];
extern uint16_t text_fore, text_back, text_border;
extern uint8_t status_line[81];
extern void update_status_left(const char *str);
extern void update_status_right(const char *str);
extern void render_init();
extern void render_loop();
@ -20,11 +24,12 @@ extern void update_text_flasher();
extern void render_text();
extern void render_text40_line(bool p2, unsigned int line);
extern void render_text80_line(bool p2, unsigned int line);
extern void render_status_line();
extern void render_videx();
extern void render_videx_line(unsigned int line);
extern void render_border();
extern void render_border(uint count);
extern void render_lores();
extern void render_mixed_lores();

View File

@ -3,48 +3,32 @@
#include "render.h"
#include "vgaout.h"
//#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];
static void render_dgr_line(bool p2, uint line);
void __time_critical_func(render_dgr)() {
vga_prepare_frame();
render_border();
bool p2 = !(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2);
for(uint line=0; line < 24; line++) {
render_dgr_line(p2, line);
render_dgr_line(PAGE2SEL, line);
}
render_border();
}
void __time_critical_func(render_mixed_dgr)() {
vga_prepare_frame();
render_border();
bool p2 = !(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2);
for(uint line=0; line < 20; line++) {
render_dgr_line(p2, line);
render_dgr_line(PAGE2SEL, line);
}
if(soft_switches & SOFTSW_80COL) {
for(uint line=20; line < 24; line++) {
render_text80_line(p2, line);
}
} else {
for(uint line=20; line < 24; line++) {
render_text40_line(p2, line);
for(uint line=20; line < 24; line++) {
if(soft_switches & SOFTSW_80COL) {
render_text80_line(PAGE2SEL, line);
} else {
render_text40_line(PAGE2SEL, line);
}
}
render_border();
}

View File

@ -33,48 +33,34 @@ uint16_t dhgr_palette[16] = {
};
#undef _RGB333
//#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)() {
vga_prepare_frame();
render_border();
bool p2 = !(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2);
for(uint line=0; line < 192; line++) {
render_dhgr_line(p2, line);
render_dhgr_line(PAGE2SEL, line);
}
render_border();
}
void __time_critical_func(render_mixed_dhgr)() {
vga_prepare_frame();
render_border();
bool p2 = !(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2);
for(uint line=0; line < 160; line++) {
render_dhgr_line(p2, line);
render_dhgr_line(PAGE2SEL, line);
}
if(soft_switches & SOFTSW_80COL) {
for(uint line=20; line < 24; line++) {
render_text80_line(p2, line);
}
} else {
for(uint line=20; line < 24; line++) {
render_text40_line(p2, line);
for(uint line=20; line < 24; line++) {
if(soft_switches & SOFTSW_80COL) {
render_text80_line(PAGE2SEL, line);
} else {
render_text40_line(PAGE2SEL, line);
}
}
render_border();
}

View File

@ -5,6 +5,8 @@
#include "render.h"
#include "vgaout.h"
//#define PAGE2SEL (!(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2))
#define PAGE2SEL ((soft_switches & (SOFTSW_80STORE | SOFTSW_PAGE_2)) == SOFTSW_PAGE_2)
static void render_hires_line(bool p2, uint line);
@ -14,42 +16,24 @@ static uint hires_line_to_mem_offset(uint line) {
void __time_critical_func(render_hires)() {
vga_prepare_frame();
render_border();
bool p2 = !(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2);
for(uint line=0; line < 192; line++) {
render_hires_line(p2, line);
render_hires_line(PAGE2SEL, line);
}
render_border();
}
void __time_critical_func(render_mixed_hires)() {
vga_prepare_frame();
render_border();
bool p2 = !(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2);
for(uint line=0; line < 160; line++) {
render_hires_line(p2, line);
render_hires_line(PAGE2SEL, line);
}
if(soft_switches & SOFTSW_80COL) {
for(uint line=20; line < 24; line++) {
render_text80_line(p2, line);
}
} else {
for(uint line=20; line < 24; line++) {
render_text40_line(p2, line);
for(uint line=20; line < 24; line++) {
if(soft_switches & SOFTSW_80COL) {
render_text80_line(PAGE2SEL, line);
} else {
render_text40_line(PAGE2SEL, line);
}
}
render_border();
}

View File

@ -33,44 +33,28 @@ uint16_t lores_palette[16] = {
static void render_lores_line(bool p2, uint line);
//#define PAGE2SEL (!(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2))
#define PAGE2SEL ((soft_switches & (SOFTSW_80STORE | SOFTSW_PAGE_2)) == SOFTSW_PAGE_2)
void __time_critical_func(render_lores)() {
vga_prepare_frame();
render_border();
bool p2 = !(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2);
for(uint line=0; line < 24; line++) {
render_lores_line(p2, line);
render_lores_line(PAGE2SEL, line);
}
render_border();
}
void __time_critical_func(render_mixed_lores)() {
vga_prepare_frame();
render_border();
bool p2 = !(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2);
for(uint line=0; line < 20; line++) {
render_lores_line(p2, line);
render_lores_line(PAGE2SEL, line);
}
if(soft_switches & SOFTSW_80COL) {
for(uint line=20; line < 24; line++) {
render_text80_line(p2, line);
}
} else {
for(uint line=20; line < 24; line++) {
render_text40_line(p2, line);
for(uint line=20; line < 24; line++) {
if(soft_switches & SOFTSW_80COL) {
render_text80_line(PAGE2SEL, line);
} else {
render_text40_line(PAGE2SEL, line);
}
}
render_border();
}

View File

@ -13,31 +13,16 @@ static uint16_t __time_critical_func(rgb444_to_rgb333)(uint16_t a) {
return ((a & 0xe00) >> 3) | ((a & 0xe0) >> 2) | ((a & 0xe) >> 1);
}
// Skip 40 lines to center vertically
void __time_critical_func(render_shr_border)() {
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 = 39;
vga_submit_scanline(sl);
}
void __time_critical_func(render_shr)() {
vga_prepare_frame();
render_shr_border();
render_border(40);
for(uint line=0; line < 200; line++) {
render_shr_line(line);
}
render_shr_border();
render_border(40);
}
static void __time_critical_func(render_shr_line)(uint16_t line) {

View File

@ -12,57 +12,45 @@
#define _PIXPAIR(p1, p2) ((uint32_t)(p1) | (((uint32_t)p2) << 16))
char error_message[16*24+1];
void render_test_sleep() {
memcpy(error_message + 208, " APPLE II BUS ", 16);
memcpy(error_message + 224, " ACTIVITY ", 16);
memcpy(error_message + 240, " NOT DETECTED ", 16);
memcpy(error_message + 272, "SCREEN BLANKING ", 16);
memcpy(error_message + 288, " IN 15 SECONDS ", 16);
memcpy(error_message + 304, " ", 16);
}
char error_message[32*24+1];
void render_test_init() {
memset(error_message, ' ', 16*24);
memcpy(error_message + 0, "HW: ANALOG-REV-1", 16);
memcpy(error_message + 16, "FW: 23-01-19-131", 16);
memset(error_message, ' ', 32*24);
memcpy(error_message + 0, "HW: Analog-Rev-1 ", 32);
memcpy(error_message + 32, "FW: 23-01-29-145 ", 32);
memcpy(error_message + 64, " COPYRIGHT (C) ", 16);
memcpy(error_message + 80, " DAVID KUDER ", 16);
memcpy(error_message + 128, " Copyright (C) 2022-2023 ", 32);
memcpy(error_message + 160, " David Kuder ", 32);
memcpy(error_message + 128, " BASED ON ", 16);
memcpy(error_message + 144, " APPLEII-VGA BY ", 16);
memcpy(error_message + 160, " MARK AIKENS ", 16);
memcpy(error_message + 256, " based on ", 32);
memcpy(error_message + 288, " AppleII-VGA by Mark Aikens ", 32);
memcpy(error_message + 208, " APPLE II BUS ", 16);
memcpy(error_message + 224, " ACTIVITY ", 16);
memcpy(error_message + 240, " NOT DETECTED ", 16);
memcpy(error_message + 416, " no Apple II bus activity ", 32);
memcpy(error_message + 272, "TURN OFF POWER &", 16);
memcpy(error_message + 288, "CHECK FOR PROPER", 16);
memcpy(error_message + 304, " CARD INSERTION ", 16);
memcpy(error_message + 544, " Turn off power & check ", 32);
memcpy(error_message + 576, " for proper card insertion. ", 32);
#ifdef RASPBERRYPI_PICO_W
memcpy(error_message + 352, " SERIAL NUMBER: ", 16);
memcpy(error_message + 704, " serial number: ", 32);
// Get Pico's Flash Serial Number (Board ID) and terminating null.
pico_get_unique_board_id_string(error_message + 368, 17);
memcpy(error_message + 736, " ", 8);
pico_get_unique_board_id_string(error_message + 744, 17);
memcpy(error_message + 760, " ", 8);
#else
memcpy(error_message + 368, " V2-ANALOG-LC ", 16);
memcpy(error_message + 736, " V2-Analog-LC ", 32);
#endif
}
// Clear the error message, in case the user sets 0x20 in terminal switches
// to show the about screen.
void render_about_init() {
memset(error_message + 208, ' ', 48);
memset(error_message + 272, ' ', 48);
memset(error_message + 416, ' ', 32);
memset(error_message + 544, ' ', 64);
}
static inline uint_fast8_t __time_critical_func(char_text_bits)(uint_fast8_t ch, uint_fast8_t glyph_line) {
uint_fast8_t bits = character_rom[((uint_fast16_t)(ch & 0x7f) << 3) | glyph_line | 0x400];
static inline uint_fast8_t __time_critical_func(char_test_bits)(uint_fast8_t ch, uint_fast8_t glyph_line) {
uint_fast8_t bits = videx_character_rom[((uint_fast16_t)(ch & 0x7f) << 3) | glyph_line | 0x400];
return bits & 0x7f;
}
@ -70,184 +58,249 @@ void __noinline __time_critical_func(render_testpattern)() {
vga_prepare_frame();
for(uint line=0; line < VGA_HEIGHT;) {
struct vga_scanline *sl = vga_prepare_scanline();
uint sl_pos = 0;
if(line == 19) {
render_status_line();
line += 16;
} else {
struct vga_scanline *sl = vga_prepare_scanline();
uint sl_pos = 0;
if((line == 0) || (line == VGA_HEIGHT-1) || (line == 36) || (line == VGA_HEIGHT-36-1)) {
for(; sl_pos < VGA_WIDTH/8; sl_pos++) {
sl->data[sl_pos] = _PIXPAIR(0x1ff | THEN_EXTEND_3, 0x1ff | THEN_EXTEND_3);
}
sl->length = sl_pos;
} else if((line == 1) || (line == VGA_HEIGHT-36)) {
for(uint i=0; i < VGA_WIDTH/4; i++, sl_pos++) {
sl->data[sl_pos] = _PIXPAIR(0x1ff, 0);
}
for(uint i=0; i < VGA_WIDTH/4; i++, sl_pos++) {
sl->data[sl_pos] = _PIXPAIR(0, 0x1ff);
}
if((line == 0) || (line == VGA_HEIGHT-1) || (line == 36) || (line == VGA_HEIGHT-36-1)) {
for(; sl_pos < VGA_WIDTH/8; sl_pos++) {
sl->data[sl_pos] = _PIXPAIR(0x1ff | THEN_EXTEND_3, 0x1ff | THEN_EXTEND_3);
}
sl->length = sl_pos;
} else if(line == 1) {
for(uint i=0; i < VGA_WIDTH/4; i++, sl_pos++) {
sl->data[sl_pos] = _PIXPAIR(0x1ff, 0);
}
for(uint i=0; i < VGA_WIDTH/4; i++, sl_pos++) {
sl->data[sl_pos] = _PIXPAIR(0, 0x1ff);
}
sl->length = sl_pos;
sl->repeat_count = 34;
} else if((line >= 48) && (line < 48+128)) {
sl->data[sl_pos++] = _PIXPAIR(0x1ff, 0 | THEN_EXTEND_6); // 8px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
sl->length = sl_pos;
sl->repeat_count = 16;
} else if(line == VGA_HEIGHT-36) {
for(uint i=0; i < VGA_WIDTH/4; i++, sl_pos++) {
sl->data[sl_pos] = _PIXPAIR(0x1ff, 0);
}
for(uint i=0; i < VGA_WIDTH/4; i++, sl_pos++) {
sl->data[sl_pos] = _PIXPAIR(0, 0x1ff);
}
const uint z = (line - 48);
sl->length = sl_pos;
sl->repeat_count = 34;
} else if((line >= 48) && (line < 48+128)) {
sl->data[sl_pos++] = _PIXPAIR(0x1ff, 0 | THEN_EXTEND_6); // 8px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
if((z & 0xf) < 14) {
const uint g = z / 16;
for(uint b=0; b < 3; b++) {
for(uint r=0; r < 8; r++) {
const uint rgb = (r << 6) | (g << 3) | b;
sl->data[sl_pos++] = _PIXPAIR(0, rgb | THEN_EXTEND_6); // 8px
sl->data[sl_pos++] = _PIXPAIR(rgb | THEN_EXTEND_6, 0); // 8px
const uint z = (line - 48);
if((z & 0xf) < 14) {
const uint g = z / 16;
for(uint b=0; b < 3; b++) {
for(uint r=0; r < 8; r++) {
const uint rgb = (r << 6) | (g << 3) | b;
sl->data[sl_pos++] = _PIXPAIR(0, rgb | THEN_EXTEND_6); // 8px
sl->data[sl_pos++] = _PIXPAIR(rgb | THEN_EXTEND_6, 0); // 8px
}
}
} else {
for(uint i=0; i < 24; i++) {
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_7, 0 | THEN_EXTEND_7); // 400px
}
}
} else {
for(uint i=0; i < 24; i++) {
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_7, 0 | THEN_EXTEND_7); // 400px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_3, 0 | THEN_EXTEND_3); // 8px
const uint w = (line - 48) << 1;
for(uint i=0; i < 32; i+=2) {
uint32_t bits_a = char_test_bits(error_message[(w & 0x3E0) | i], (w>>2) & 0x7);
uint32_t bits_b = char_test_bits(error_message[(w & 0x3E0) | (i+1)], (w>>2) & 0x7);
uint32_t bits = (bits_a << 7) | bits_b;
for(uint j=0; j < 7; j++) {
uint32_t pixeldata = (bits & 0x2000) ? (0) : (0x1ff);
pixeldata |= (bits & 0x1000) ? ((0) << 16) : ((0x1ff) << 16);
bits <<= 2;
sl->data[sl_pos++] = pixeldata;
}
}
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_3, 0 | THEN_EXTEND_3); // 8px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_6, 0x1ff); // 8px
const uint w = (line - 48);
for(uint i=0; i < 16; i+=2) {
uint32_t bits_a = char_text_bits(error_message[(w & 0x1f0) | i], (w/2) & 0x7);
uint32_t bits_b = char_text_bits(error_message[(w & 0x1f0) | (i+1)], (w/2) & 0x7);
uint32_t bits = (bits_a << 7) | bits_b;
for(uint j=0; j < 7; j++) {
uint32_t pixeldata = (bits & 0x2000) ? (0|THEN_EXTEND_1) : (0x1ff | THEN_EXTEND_1);
pixeldata |= (bits & 0x1000) ? ((0|THEN_EXTEND_1) << 16) : ((0x1ff | THEN_EXTEND_1) << 16);
bits <<= 2;
sl->data[sl_pos++] = pixeldata;
}
}
sl->repeat_count = 1;
sl->length = sl_pos;
} else if((line >= 176) && (line < 176+128)) {
sl->data[sl_pos++] = _PIXPAIR(0x1ff, 0 | THEN_EXTEND_6); // 8px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_6, 0x1ff); // 8px
sl->repeat_count = 1;
sl->length = sl_pos;
} else if((line >= 176) && (line < 176+128)) {
sl->data[sl_pos++] = _PIXPAIR(0x1ff, 0 | THEN_EXTEND_6); // 8px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
const uint z = (line - 176);
const uint g = z / 16;
// center-left square
if((z & 0xf) < 14) {
uint b = 3;
for(uint r=0; r < 8; r++) {
const uint rgb = (r << 6) | (g << 3) | b;
sl->data[sl_pos++] = _PIXPAIR(0, rgb | THEN_EXTEND_6);
sl->data[sl_pos++] = _PIXPAIR(rgb | THEN_EXTEND_6, 0);
}
} else {
for(uint i=0; i < 8; i++) {
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_7, 0 | THEN_EXTEND_7);
}
}
// center square (logo)
for(uint i=0; i < 32; i++) {
uint color1 = lores_palette[PicoPalLogo[((z & 0x7e) << 4) | i] >> 4];
uint color2 = lores_palette[PicoPalLogo[((z & 0x7e) << 4) | i] & 0xf];
sl->data[sl_pos++] = _PIXPAIR(color1 | THEN_EXTEND_1, color2 | THEN_EXTEND_1);
}
// center-right square
if((z & 0xf) < 14) {
uint b = 4;
for(uint r=0; r < 8; r++) {
const uint rgb = (r << 6) | (g << 3) | b;
sl->data[sl_pos++] = _PIXPAIR(0, rgb | THEN_EXTEND_6);
sl->data[sl_pos++] = _PIXPAIR(rgb | THEN_EXTEND_6, 0);
}
} else {
for(uint i=0; i < 8; i++) {
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_7, 0 | THEN_EXTEND_7);
}
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_3, 0 | THEN_EXTEND_3); // 8px
const uint w = (line - 48);
for(uint i=0; i < 16; i+=2) {
uint32_t bits_a = char_text_bits(error_message[(w & 0x1f0) | i], (w/2) & 0x7);
uint32_t bits_b = char_text_bits(error_message[(w & 0x1f0) | (i+1)], (w/2) & 0x7);
uint32_t bits = (bits_a << 7) | bits_b;
for(uint j=0; j < 7; j++) {
uint32_t pixeldata = (bits & 0x2000) ? (0|THEN_EXTEND_1) : (0x1ff | THEN_EXTEND_1);
pixeldata |= (bits & 0x1000) ? ((0|THEN_EXTEND_1) << 16) : ((0x1ff | THEN_EXTEND_1) << 16);
bits <<= 2;
sl->data[sl_pos++] = pixeldata;
}
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_6, 0x1ff); // 8px
sl->repeat_count = 1;
sl->length = sl_pos;
} else if((line >= 304) && (line < 304+128)) {
sl->data[sl_pos++] = _PIXPAIR(0x1ff, 0 | THEN_EXTEND_6); // 8px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
const uint z = (line - 304);
if((z & 0xf) < 14) {
const uint z = (line - 176);
const uint g = z / 16;
for(uint b=5; b < 8; b++) {
// center-left square
if((z & 0xf) < 14) {
uint b = 3;
for(uint r=0; r < 8; r++) {
const uint rgb = (r << 6) | (g << 3) | b;
sl->data[sl_pos++] = _PIXPAIR(0, rgb | THEN_EXTEND_6);
sl->data[sl_pos++] = _PIXPAIR(rgb | THEN_EXTEND_6, 0);
}
} else {
for(uint i=0; i < 8; i++) {
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_7, 0 | THEN_EXTEND_7);
}
}
// center square (logo)
for(uint i=0; i < 32; i++) {
uint color1 = lores_palette[PicoPalLogo[((z & 0x7e) << 4) | i] >> 4];
uint color2 = lores_palette[PicoPalLogo[((z & 0x7e) << 4) | i] & 0xf];
sl->data[sl_pos++] = _PIXPAIR(color1 | THEN_EXTEND_1, color2 | THEN_EXTEND_1);
}
// center-right square
if((z & 0xf) < 14) {
uint b = 4;
for(uint r=0; r < 8; r++) {
const uint rgb = (r << 6) | (g << 3) | b;
sl->data[sl_pos++] = _PIXPAIR(0, rgb | THEN_EXTEND_6);
sl->data[sl_pos++] = _PIXPAIR(rgb | THEN_EXTEND_6, 0);
}
} else {
for(uint i=0; i < 8; i++) {
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_7, 0 | THEN_EXTEND_7);
}
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_3, 0 | THEN_EXTEND_3); // 8px
const uint w = (line - 48) << 1;
for(uint i=0; i < 32; i+=2) {
uint32_t bits_a = char_test_bits(error_message[(w & 0x3E0) | i], (w>>2) & 0x7);
uint32_t bits_b = char_test_bits(error_message[(w & 0x3E0) | (i+1)], (w>>2) & 0x7);
uint32_t bits = (bits_a << 7) | bits_b;
for(uint j=0; j < 7; j++) {
uint32_t pixeldata = (bits & 0x2000) ? (0) : (0x1ff);
pixeldata |= (bits & 0x1000) ? ((0) << 16) : ((0x1ff) << 16);
bits <<= 2;
sl->data[sl_pos++] = pixeldata;
}
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_6, 0x1ff); // 8px
sl->repeat_count = 1;
sl->length = sl_pos;
} else if((line >= 304) && (line < 304+128)) {
sl->data[sl_pos++] = _PIXPAIR(0x1ff, 0 | THEN_EXTEND_6); // 8px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
const uint z = (line - 304);
if((z & 0xf) < 14) {
const uint g = z / 16;
for(uint b=5; b < 8; b++) {
for(uint r=0; r < 8; r++) {
const uint rgb = (r << 6) | (g << 3) | b;
sl->data[sl_pos++] = _PIXPAIR(0, rgb | THEN_EXTEND_6);
sl->data[sl_pos++] = _PIXPAIR(rgb | THEN_EXTEND_6, 0);
}
}
} else {
for(uint i=0; i < 24; i++) {
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_7, 0 | THEN_EXTEND_7); // 400px
}
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_3, 0 | THEN_EXTEND_3); // 8px
const uint w = (line - 48) << 1;
for(uint i=0; i < 32; i+=2) {
uint32_t bits_a = char_test_bits(error_message[(w & 0x3E0) | i], (w>>2) & 0x7);
uint32_t bits_b = char_test_bits(error_message[(w & 0x3E0) | (i+1)], (w>>2) & 0x7);
uint32_t bits = (bits_a << 7) | bits_b;
for(uint j=0; j < 7; j++) {
uint32_t pixeldata = (bits & 0x2000) ? (0) : (0x1ff);
pixeldata |= (bits & 0x1000) ? ((0) << 16) : ((0x1ff) << 16);
bits <<= 2;
sl->data[sl_pos++] = pixeldata;
}
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_6, 0x1ff); // 8px
sl->repeat_count = 1;
sl->length = sl_pos;
} else if(line < VGA_HEIGHT) {
// black w/ white border
sl->data[sl_pos++] = _PIXPAIR(0x1ff, 0 | THEN_EXTEND_6);
for(uint i=0; i < 39; i++) {
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_7, 0 | THEN_EXTEND_7);
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_6, 0x1ff);
sl->length = sl_pos;
} else {
for(uint i=0; i < 24; i++) {
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_7, 0 | THEN_EXTEND_7); // 400px
}
sl->data[sl_pos++] = _PIXPAIR(0, 0);
sl->length = sl_pos;
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_3, 0 | THEN_EXTEND_3); // 8px
line += sl->repeat_count + 1;
vga_submit_scanline(sl);
}
}
}
const uint w = (line - 48);
for(uint i=0; i < 16; i+=2) {
uint32_t bits_a = char_text_bits(error_message[(w & 0x1f0) | i], (w/2) & 0x7);
uint32_t bits_b = char_text_bits(error_message[(w & 0x1f0) | (i+1)], (w/2) & 0x7);
uint32_t bits = (bits_a << 7) | bits_b;
for(uint j=0; j < 7; j++) {
uint32_t pixeldata = (bits & 0x2000) ? (0|THEN_EXTEND_1) : (0x1ff | THEN_EXTEND_1);
pixeldata |= (bits & 0x1000) ? ((0|THEN_EXTEND_1) << 16) : ((0x1ff | THEN_EXTEND_1) << 16);
bits <<= 2;
sl->data[sl_pos++] = pixeldata;
}
void __time_critical_func(render_status_line)() {
for(uint glyph_line=0; glyph_line < 8; glyph_line++) {
struct vga_scanline *sl = vga_prepare_scanline();
uint8_t *line_buf = status_line;
uint32_t bits;
uint sl_pos = 0;
// 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
for(uint col=0; col < 40; ) {
// Grab 14 pixels from the next two characters
if(*line_buf != 0) {
bits = char_test_bits(*line_buf++, glyph_line) << 7;
} else {
bits = 0x7f << 7;
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_6, 0x1ff); // 8px
sl->repeat_count = 1;
sl->length = sl_pos;
} else if(line < VGA_HEIGHT) {
// black w/ white border
sl->data[sl_pos++] = _PIXPAIR(0x1ff, 0 | THEN_EXTEND_6);
for(uint i=0; i < 39; i++) {
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_7, 0 | THEN_EXTEND_7);
if(*line_buf != 0) {
bits |= char_test_bits(*line_buf++, glyph_line);
} else {
bits |= 0x7f;
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_6, 0x1ff);
col++;
sl->length = sl_pos;
} else {
sl->data[sl_pos++] = _PIXPAIR(0, 0);
// Translate each pair of bits into a pair of pixels
for(int i=0; i < 7; i++) {
uint32_t pixeldata = (bits & 0x2000) ? (0x000) : (0x1ff);
pixeldata |= (bits & 0x1000) ?
((uint32_t)0x000) << 16 :
((uint32_t)0x1ff) << 16;
bits <<= 2;
sl->length = sl_pos;
sl->data[sl_pos] = pixeldata;
sl_pos++;
}
}
line += sl->repeat_count + 1;
// Pad 40 pixels on the right 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);
}
}

View File

@ -4,6 +4,8 @@
#include "character_rom.h"
#include "vgaout.h"
//#define PAGE2SEL (!(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2))
#define PAGE2SEL ((soft_switches & (SOFTSW_80STORE | SOFTSW_PAGE_2)) == SOFTSW_PAGE_2)
uint_fast32_t text_flasher_mask = 0;
static uint64_t next_flash_tick = 0;
@ -12,7 +14,18 @@ void update_text_flasher() {
uint64_t now = time_us_64();
if(now > next_flash_tick) {
text_flasher_mask ^= 0x7f;
next_flash_tick = now + 250000u;
switch(current_machine) {
default:
case MACHINE_II:
case MACHINE_PRAVETZ:
next_flash_tick = now + 125000u;
break;
case MACHINE_IIE:
case MACHINE_IIGS:
next_flash_tick = now + 250000u;
break;
}
}
}
@ -34,40 +47,14 @@ static inline uint_fast8_t __time_critical_func(char_text_bits)(uint_fast8_t ch,
return bits;
}
// Skip 48 lines to center vertically
void __time_critical_func(render_border)() {
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 = 47;
vga_submit_scanline(sl);
}
void __time_critical_func(render_text)() {
vga_prepare_frame();
render_border();
bool p2 = !(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2);
if(soft_switches & SOFTSW_80COL) {
for(uint line=0; line < 24; line++) {
render_text80_line(p2, line);
}
} else {
for(uint line=0; line < 24; line++) {
render_text40_line(p2, line);
for(uint line=0; line < 24; line++) {
if(soft_switches & SOFTSW_80COL) {
render_text80_line(PAGE2SEL, line);
} else {
render_text40_line(PAGE2SEL, line);
}
}
render_border();
}
void __time_critical_func(render_text40_line)(bool p2, unsigned int line) {
@ -116,7 +103,6 @@ void __time_critical_func(render_text40_line)(bool p2, unsigned int line) {
}
}
void __time_critical_func(render_text80_line)(bool p2, unsigned int line) {
const uint8_t *page_a = (const uint8_t *)(p2 ? text_p2 : text_p1);
const uint8_t *page_b = (const uint8_t *)(p2 ? text_p4 : text_p3);
@ -133,7 +119,7 @@ void __time_critical_func(render_text80_line)(bool p2, unsigned int line) {
sl->data[sl_pos++] = (text_border|THEN_EXTEND_3) | ((text_border|THEN_EXTEND_3) << 16); // 8 pixels per word
for(uint col=0; col < 40; ) {
// Grab 14 pixels from the next four characters
// Grab 14 pixels from the next two characters
uint32_t bits_a = char_text_bits(line_buf_a[col], glyph_line);
uint32_t bits_b = char_text_bits(line_buf_b[col], glyph_line);
col++;
@ -163,3 +149,4 @@ void __time_critical_func(render_text80_line)(bool p2, unsigned int line) {
vga_submit_scanline(sl);
}
}

View File

@ -5,7 +5,7 @@
#include "vgaout.h"
static inline uint_fast8_t __time_critical_func(char_terminal_bits)(uint_fast8_t ch, uint_fast8_t glyph_line) {
uint_fast8_t bits = character_rom[((uint_fast16_t)ch << 3) | glyph_line];
uint_fast8_t bits = videx_character_rom[((uint_fast16_t)ch << 3) | glyph_line];
if(ch & 0x80) {
// normal character
return bits & 0x7f;
@ -22,15 +22,9 @@ static inline uint_fast8_t __time_critical_func(char_terminal_bits)(uint_fast8_t
void __time_critical_func(render_videx)() {
vga_prepare_frame();
render_border();
for(int line=0; line < 24; line++) {
render_videx_line(line);
}
render_border();
}
@ -79,3 +73,4 @@ void __time_critical_func(render_videx_line)(unsigned int line) {
vga_submit_scanline(sl);
}
}

View File

@ -5,7 +5,8 @@
volatile uint32_t soft_switches = 0;
// The currently programmed character generator ROM for text mode
uint8_t character_rom[4096];
uint8_t character_rom[2048];
uint8_t videx_character_rom[2048];
volatile uint8_t videx_crtc_reg;

View File

@ -7,8 +7,8 @@
#define hires_memory hgr_p1
#define videx_memory (private_memory+0xF000)
extern uint8_t character_rom[4096];
extern uint8_t terminal_rom[2048];
extern uint8_t character_rom[2048];
extern uint8_t videx_character_rom[2048];
extern volatile uint8_t videx_crtc_reg;
extern volatile uint8_t videx_addr;

View File

@ -181,7 +181,14 @@ void vga_init() {
pio_enable_sm_mask_in_sync(CONFIG_VGA_PIO, (1 << VGA_HSYNC_SM) | (1 << VGA_VSYNC_SM) | (1 << VGA_DATA_SM));
}
void vga_dpms_sleep() {
pio_set_sm_mask_enabled(CONFIG_VGA_PIO, (1 << VGA_HSYNC_SM) | (1 << VGA_VSYNC_SM) | (1 << VGA_DATA_SM), false);
}
void vga_dpms_wake() {
pio_enable_sm_mask_in_sync(CONFIG_VGA_PIO, (1 << VGA_HSYNC_SM) | (1 << VGA_VSYNC_SM) | (1 << VGA_DATA_SM));
}
void vga_deinit() {
// Disable DMA IRQ
irq_set_enabled(DMA_IRQ_0, false);

View File

@ -31,8 +31,10 @@ struct vga_scanline {
uint32_t data[(VGA_WIDTH/2)+8];
};
void vga_prepare_frame();
struct vga_scanline *vga_prepare_scanline();
void vga_submit_scanline(struct vga_scanline *scanline);
void vga_dpms_sleep();
void vga_dpms_wake();