Video 7 support
This commit is contained in:
parent
d5e001f2c1
commit
e94cfac000
|
@ -55,3 +55,6 @@
|
|||
|
||||
#define CFGTOKEN_TBCOLOR 0x00005456 // "VT\xXX\x00" Custom default TBCOLOR
|
||||
#define CFGTOKEN_BORDER 0x00004256 // "VB\xXX\x00" Custom default BORDER
|
||||
|
||||
#define CFGTOKEN_VIDEO7 0x00003756 // "V7\xXX\x00" Video 7 Enable / Disable
|
||||
#define CFGTOKEN_RGBCOLOR 0x00005043 // "CP\xXX\x04" RGB Palette Entry Override
|
||||
|
|
|
@ -15,8 +15,10 @@ extern volatile uint8_t romx_changed;
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef ANALOG_GS
|
||||
volatile compat_t cfg_machine = MACHINE_AUTO;
|
||||
volatile compat_t current_machine = MACHINE_AUTO;
|
||||
#endif
|
||||
|
||||
#ifdef FUNCTION_Z80
|
||||
volatile usbmux_t usbmux;
|
||||
|
@ -68,21 +70,29 @@ bool DELAYED_COPY_CODE(parse_config)(uint32_t address) {
|
|||
switch(config[i] & 0x0000FFFF) {
|
||||
case CFGTOKEN_HOST_AUTO:
|
||||
cfg_machine = MACHINE_AUTO;
|
||||
internal_flags |= (IFLAGS_IIE_REGS | IFLAGS_IIGS_REGS);
|
||||
break;
|
||||
case CFGTOKEN_HOST_II:
|
||||
cfg_machine = MACHINE_II;
|
||||
internal_flags &= ~(IFLAGS_IIE_REGS | IFLAGS_IIGS_REGS);
|
||||
break;
|
||||
case CFGTOKEN_HOST_IIE:
|
||||
cfg_machine = MACHINE_IIE;
|
||||
internal_flags |= IFLAGS_IIE_REGS;
|
||||
internal_flags &= ~IFLAGS_IIGS_REGS;
|
||||
break;
|
||||
case CFGTOKEN_HOST_IIGS:
|
||||
cfg_machine = MACHINE_IIGS;
|
||||
internal_flags &= ~IFLAGS_IIE_REGS;
|
||||
internal_flags |= IFLAGS_IIGS_REGS;
|
||||
break;
|
||||
case CFGTOKEN_HOST_PRAVETZ:
|
||||
cfg_machine = MACHINE_PRAVETZ;
|
||||
internal_flags &= ~(IFLAGS_IIE_REGS | IFLAGS_IIGS_REGS);
|
||||
break;
|
||||
case CFGTOKEN_HOST_BASIS:
|
||||
cfg_machine = MACHINE_BASIS;
|
||||
internal_flags &= ~(IFLAGS_IIE_REGS | IFLAGS_IIGS_REGS);
|
||||
break;
|
||||
#ifdef FUNCTION_VGA
|
||||
case CFGTOKEN_FONT_00:
|
||||
|
@ -98,6 +108,17 @@ bool DELAYED_COPY_CODE(parse_config)(uint32_t address) {
|
|||
case CFGTOKEN_BORDER:
|
||||
terminal_border = (config[i] >> 16) & 0xF;
|
||||
break;
|
||||
case CFGTOKEN_RGBCOLOR:
|
||||
lores_palette[(config[i] >> 16) & 0xF] = config[i+1];
|
||||
dhgr_palette[((config[i] >> 17) & 0x7) | ((config[i] >> 13) & 0x8)] = config[i+1];
|
||||
break;
|
||||
case CFGTOKEN_VIDEO7:
|
||||
if((config[i] >> 16) & 1) {
|
||||
internal_flags |= IFLAGS_VIDEO7;
|
||||
} else {
|
||||
internal_flags &= ~IFLAGS_VIDEO7;
|
||||
}
|
||||
break;
|
||||
#elif defined(FUNCTION_Z80)
|
||||
case CFGTOKEN_MUX_LOOP:
|
||||
serialmux[(config[i] >> 16) & 1] = SERIAL_LOOP;
|
||||
|
@ -172,7 +193,17 @@ void DELAYED_COPY_CODE(default_config)() {
|
|||
strcpy((char*)wifi_ssid, "V2RetroNet");
|
||||
strcpy((char*)wifi_psk, "Analog");
|
||||
#endif
|
||||
#ifdef ANALOG_GS
|
||||
cfg_machine = MACHINE_IIGS;
|
||||
current_machine = MACHINE_IIGS;
|
||||
internal_flags &= ~IFLAGS_IIE_REGS;
|
||||
internal_flags |= IFLAGS_IIGS_REGS;
|
||||
#else
|
||||
cfg_machine = MACHINE_AUTO;
|
||||
current_machine = MACHINE_AUTO;
|
||||
internal_flags |= (IFLAGS_IIE_REGS | IFLAGS_IIGS_REGS);
|
||||
#endif
|
||||
internal_flags |= IFLAGS_VIDEO7;
|
||||
}
|
||||
|
||||
int DELAYED_COPY_CODE(make_config)(uint32_t rev) {
|
||||
|
@ -277,6 +308,13 @@ int DELAYED_COPY_CODE(make_config)(uint32_t rev) {
|
|||
config_temp[i++] = CFGTOKEN_MONO_00 | ((mono_palette & 0xF) << 20);
|
||||
config_temp[i++] = CFGTOKEN_TBCOLOR | ((terminal_tbcolor & 0xFF) << 16);
|
||||
config_temp[i++] = CFGTOKEN_BORDER | ((terminal_border & 0xF) << 16);
|
||||
|
||||
config_temp[i++] = CFGTOKEN_VIDEO7 | ((internal_flags & IFLAGS_VIDEO7) ? (1ul<<16) : 0);
|
||||
|
||||
for(uint32_t j = 0; j < 16; j++) {
|
||||
config_temp[i++] = CFGTOKEN_RGBCOLOR | (j << 16);
|
||||
config_temp[i++] = lores_palette[j];
|
||||
}
|
||||
#endif
|
||||
config_temp[i++] = NEWCONFIG_EOF_MARKER;
|
||||
|
||||
|
@ -320,12 +358,14 @@ uint8_t DELAYED_COPY_CODE(get_config_rev)(uint32_t address) {
|
|||
// Every time we write the config we overwrite the older slot,
|
||||
// ensuring we don't leave the user without a configuration.
|
||||
// We increment the revision number each time, wrapping back to 0x00 from 0xFF.
|
||||
#if 0
|
||||
bool DELAYED_COPY_CODE(is_primary_config_newer)() {
|
||||
uint8_t a=get_config_rev(FLASH_CONFIG_PRIMARY);
|
||||
uint8_t b=get_config_rev(FLASH_CONFIG_SECONDARY);
|
||||
|
||||
return ((int8_t)(a-b)) >= 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool DELAYED_COPY_CODE(read_config)() {
|
||||
if(is_config_valid(FLASH_CONFIG_ONETIME)) {
|
||||
|
@ -334,6 +374,13 @@ bool DELAYED_COPY_CODE(read_config)() {
|
|||
if(parse_config(FLASH_CONFIG_ONETIME))
|
||||
return true;
|
||||
}
|
||||
|
||||
if(is_config_valid(FLASH_CONFIG_PRIMARY)) {
|
||||
if(parse_config(FLASH_CONFIG_PRIMARY))
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if(is_config_valid(FLASH_CONFIG_PRIMARY)) {
|
||||
if(!is_config_valid(FLASH_CONFIG_SECONDARY) || (is_primary_config_newer())) {
|
||||
if(parse_config(FLASH_CONFIG_PRIMARY))
|
||||
|
@ -344,6 +391,7 @@ bool DELAYED_COPY_CODE(read_config)() {
|
|||
if(parse_config(FLASH_CONFIG_SECONDARY))
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
default_config();
|
||||
return false;
|
||||
|
@ -359,6 +407,10 @@ bool DELAYED_COPY_CODE(write_config)(bool onetime) {
|
|||
vga_dpms_sleep();
|
||||
#endif
|
||||
|
||||
write_secondary = false;
|
||||
rev = get_config_rev(FLASH_CONFIG_PRIMARY);
|
||||
|
||||
#if 0
|
||||
if(is_config_valid(FLASH_CONFIG_PRIMARY) && is_config_valid(FLASH_CONFIG_SECONDARY)) {
|
||||
write_secondary = is_primary_config_newer();
|
||||
rev = write_secondary ? get_config_rev(FLASH_CONFIG_PRIMARY) : get_config_rev(FLASH_CONFIG_SECONDARY);
|
||||
|
@ -369,9 +421,9 @@ bool DELAYED_COPY_CODE(write_config)(bool onetime) {
|
|||
write_secondary = false;
|
||||
rev = get_config_rev(FLASH_CONFIG_SECONDARY);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(make_config(rev + 1) <= CONFIG_SIZE) {
|
||||
|
||||
if(onetime) {
|
||||
flash_range_erase((FLASH_CONFIG_ONETIME-XIP_BASE), CONFIG_SIZE);
|
||||
flash_range_program((FLASH_CONFIG_ONETIME-XIP_BASE), (const uint8_t *)config_temp, CONFIG_SIZE);
|
||||
|
@ -401,6 +453,7 @@ uint8_t DELAYED_COPY_CODE(get_config_block)() {
|
|||
last_config_block = (FLASH_CONFIG_PRIMARY-XIP_BASE) / 4096;
|
||||
next_config_block = last_config_block;
|
||||
|
||||
#if 0
|
||||
if(is_config_valid(FLASH_CONFIG_PRIMARY)) {
|
||||
if(!is_config_valid(FLASH_CONFIG_SECONDARY) || (is_primary_config_newer())) {
|
||||
last_config_block = (FLASH_CONFIG_PRIMARY-XIP_BASE) / 4096;
|
||||
|
@ -413,6 +466,7 @@ uint8_t DELAYED_COPY_CODE(get_config_block)() {
|
|||
last_config_block = (FLASH_CONFIG_SECONDARY-XIP_BASE) / 4096;
|
||||
next_config_block = (FLASH_CONFIG_PRIMARY-XIP_BASE) / 4096;
|
||||
}
|
||||
#endif
|
||||
|
||||
config_rpybuf[5] = (next_config_block >> 8) & 0xFF;
|
||||
config_rpybuf[4] = (next_config_block >> 0) & 0xFF;
|
||||
|
@ -574,6 +628,31 @@ void DELAYED_COPY_CODE(config_handler)() {
|
|||
config_rpybuf[0] = REPLY_BUSY;
|
||||
|
||||
switch(config_cmdbuf[0]) {
|
||||
case 'P':
|
||||
switch(config_cmdbuf[1]) {
|
||||
default:
|
||||
retval = REPLY_ECMD;
|
||||
break;
|
||||
#ifdef FUNCTION_VGA
|
||||
case 'r':
|
||||
memcpy((void *)cfbuf, lores_palette, 16*2);
|
||||
cfptr = 0;
|
||||
retval = REPLY_OK;
|
||||
break;
|
||||
case 'T':
|
||||
for(uint j = 0; j < 16; j++) {
|
||||
#ifdef ANALOG_GS
|
||||
lores_palette[j] = ((uint16_t *)cfbuf)[j] & 0xFFF;
|
||||
#else
|
||||
lores_palette[j] = ((uint16_t *)cfbuf)[j] & 0x1FF;
|
||||
#endif
|
||||
}
|
||||
cfptr = 0;
|
||||
retval = REPLY_OK;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
switch(config_cmdbuf[1]) {
|
||||
default:
|
||||
|
|
|
@ -46,25 +46,25 @@ static void __noinline __time_critical_func(core1_loop)() {
|
|||
// Config memory in card slot-rom address space
|
||||
if(ACCESS_WRITE) {
|
||||
if((address & 0xFF) == 0xEC) {
|
||||
apple_memory[address] = value;
|
||||
cfptr = (cfptr & 0x0F00) | value;
|
||||
apple_memory[address] = (value & 0xff);
|
||||
cfptr = (cfptr & 0x0F00) | (value & 0xff);
|
||||
apple_memory[address+2] = cfbuf[cfptr]; // $CnEE
|
||||
apple_memory[address+3] = cfbuf[cfptr]; // $CnEF
|
||||
}
|
||||
if((address & 0xFF) == 0xED) {
|
||||
apple_memory[address] = value & 0x0F;
|
||||
apple_memory[address] = (value & 0x0F);
|
||||
cfptr = ((cfptr & 0xFF) | (((uint16_t)value) << 8)) & 0xFFF;
|
||||
apple_memory[address+1] = cfbuf[cfptr]; // $CnEE
|
||||
apple_memory[address+2] = cfbuf[cfptr]; // $CnEF
|
||||
}
|
||||
if((address & 0xFF) == 0xEF) {
|
||||
cfbuf[cfptr] = value;
|
||||
cfbuf[cfptr] = (value & 0xff);
|
||||
cfptr = (cfptr + 1) & 0x0FFF;
|
||||
apple_memory[address-1] = cfbuf[cfptr]; // $CnEE
|
||||
apple_memory[address] = cfbuf[cfptr]; // $CnEF
|
||||
}
|
||||
if((address & 0xFF) >= 0xF0) {
|
||||
apple_memory[address] = value;
|
||||
apple_memory[address] = (value & 0xff);
|
||||
}
|
||||
} else if((address & 0xFF) == 0xEE) {
|
||||
cfptr = (cfptr + 1) & 0x0FFF;
|
||||
|
@ -76,7 +76,12 @@ static void __noinline __time_critical_func(core1_loop)() {
|
|||
}
|
||||
#ifdef FUNCTION_VGA
|
||||
} else if(current_machine == MACHINE_AUTO) {
|
||||
if((apple_memory[0x404] == 0xE5) && (apple_memory[0x0403] == 0xD8)) { // ROMXe
|
||||
if(value & 0x08000000) {
|
||||
// Hardware jumpered for IIGS mode.
|
||||
current_machine = MACHINE_IIGS;
|
||||
internal_flags &= ~IFLAGS_IIE_REGS;
|
||||
internal_flags |= IFLAGS_IIGS_REGS;
|
||||
} else if((apple_memory[0x404] == 0xE5) && (apple_memory[0x0403] == 0xD8)) { // ROMXe
|
||||
current_machine = MACHINE_IIE;
|
||||
internal_flags |= IFLAGS_IIE_REGS;
|
||||
internal_flags &= ~IFLAGS_IIGS_REGS;
|
||||
|
@ -108,25 +113,27 @@ static void __noinline __time_critical_func(core1_loop)() {
|
|||
#endif
|
||||
} else switch(reset_state) {
|
||||
case 0:
|
||||
if((value & 0x3FFFF00) == ((0xFFFC << 10) | 0x300))
|
||||
if((value & 0x7FFFF00) == ((0xFFFC << 10) | 0x300))
|
||||
reset_state++;
|
||||
break;
|
||||
case 1:
|
||||
if((value & 0x3FFFF00) == ((0xFFFD << 10) | 0x300))
|
||||
if((value & 0x7FFFF00) == ((0xFFFD << 10) | 0x300))
|
||||
reset_state++;
|
||||
else
|
||||
reset_state=0;
|
||||
break;
|
||||
case 2:
|
||||
if((value & 0x3FFFF00) == ((0xFA62 << 10) | 0x300))
|
||||
if((value & 0x7FFFF00) == ((0xFA62 << 10) | 0x300))
|
||||
reset_state++;
|
||||
else
|
||||
reset_state=0;
|
||||
break;
|
||||
case 3:
|
||||
#ifdef FUNCTION_VGA
|
||||
soft_switches = SOFTSW_TEXT_MODE;
|
||||
soft_switches |= SOFTSW_TEXT_MODE;
|
||||
soft_switches &= ~SOFTSW_80COL;
|
||||
soft_switches &= ~SOFTSW_DGR;
|
||||
internal_flags &= ~(IFLAGS_TERMINAL | IFLAGS_TEST | IFLAGS_V7_MODE3);
|
||||
#endif
|
||||
default:
|
||||
reset_state = 0;
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
volatile uint8_t *terminal_page = terminal_memory;
|
||||
|
||||
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((address < 0xC000) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
||||
// Apple IIgs: CARD_SELECT is pulled low by our CPLD when M2B0 is active and addr < $C000
|
||||
#ifdef ANALOG_GS
|
||||
if(CARD_SELECT) {
|
||||
// Apple IIgs: Bit 27 is GS jumper closed, Bit 26 is M2B0
|
||||
if(value & 0x4000000) {
|
||||
if(ACCESS_WRITE) {
|
||||
private_memory[address] = value & 0xff;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Shadow parts of the Apple's memory by observing the bus write cycles
|
||||
|
@ -156,6 +156,11 @@ void __time_critical_func(vga_businterface)(uint32_t address, uint32_t value) {
|
|||
}
|
||||
break;
|
||||
case 0x5f:
|
||||
// Video 7 shift register
|
||||
if(!soft_switches & SOFTSW_DGR) {
|
||||
internal_flags = (internal_flags & 0xfffffffc) | ((internal_flags & 0x1) << 1) | ((soft_switches & SOFTSW_80COL) ? 1 : 0);
|
||||
}
|
||||
|
||||
if(internal_flags & (IFLAGS_IIGS_REGS | IFLAGS_IIE_REGS)) {
|
||||
soft_switches &= ~SOFTSW_DGR;
|
||||
}
|
||||
|
@ -239,11 +244,16 @@ void __time_critical_func(vga_businterface)(uint32_t address, uint32_t value) {
|
|||
switch(address & 0x0F) {
|
||||
case 0x01:
|
||||
mono_palette = (value >> 4) & 0xF;
|
||||
if(value & 0x8) {
|
||||
if(value & 8) {
|
||||
internal_flags |= IFLAGS_OLDCOLOR;
|
||||
} else {
|
||||
internal_flags &= ~IFLAGS_OLDCOLOR;
|
||||
}
|
||||
if(value & 4) {
|
||||
internal_flags |= IFLAGS_VIDEO7;
|
||||
} else {
|
||||
internal_flags &= ~IFLAGS_VIDEO7;
|
||||
}
|
||||
apple_memory[address] = value;
|
||||
break;
|
||||
case 0x02:
|
||||
|
@ -255,10 +265,10 @@ void __time_critical_func(vga_businterface)(uint32_t address, uint32_t value) {
|
|||
apple_memory[address] = terminal_border;
|
||||
break;
|
||||
case 0x08:
|
||||
soft_switches &= ~SOFTSW_TERMINAL;
|
||||
internal_flags &= ~IFLAGS_TERMINAL;
|
||||
break;
|
||||
case 0x09:
|
||||
soft_switches |= SOFTSW_TERMINAL;
|
||||
internal_flags |= IFLAGS_TERMINAL;
|
||||
break;
|
||||
case 0x0A:
|
||||
terminal_fifo[terminal_fifo_wrptr++] = (value & 0xFF);
|
||||
|
|
|
@ -213,7 +213,7 @@ void DELAYED_COPY_CODE(render_loop)() {
|
|||
vga_prepare_frame();
|
||||
render_shr();
|
||||
#endif
|
||||
} else if(soft_switches & SOFTSW_TERMINAL) {
|
||||
} else if(internal_flags & IFLAGS_TERMINAL) {
|
||||
vga_prepare_frame();
|
||||
render_terminal();
|
||||
} else {
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#define RENDER_TEST_PATTERN
|
||||
|
||||
extern uint16_t lores_palette[16];
|
||||
extern uint16_t dhgr_palette[16];
|
||||
|
||||
extern uint16_t text_fore, text_back, text_border;
|
||||
extern uint8_t status_line[81];
|
||||
extern bool mono_rendering;
|
||||
|
@ -25,8 +27,11 @@ extern void render_test_sleep();
|
|||
|
||||
extern void update_text_flasher();
|
||||
extern void render_text();
|
||||
extern void render_mixed_text();
|
||||
extern void render_text40_line(bool p2, unsigned int line);
|
||||
extern void render_text80_line(bool p2, unsigned int line);
|
||||
extern void render_color_text40_line(unsigned int line);
|
||||
extern void render_color_text80_line(unsigned int line);
|
||||
extern void render_status_line();
|
||||
|
||||
extern void render_terminal();
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
uint8_t terminal_jsoffset = 0;
|
||||
uint8_t terminal_ssoffset = 0;
|
||||
bool terminal_inverse = 0;
|
||||
bool terminal_esc = 0;
|
||||
bool terminal_esc_crz = 0;
|
||||
int terminal_esc_pos = 0;
|
||||
|
@ -26,15 +27,19 @@ static inline uint_fast8_t char_terminal_bits(uint_fast8_t ch, uint_fast8_t glyp
|
|||
return (bits & 0x7f);
|
||||
}
|
||||
|
||||
static void DELAYED_COPY_CODE(terminal_scroll)() {
|
||||
// Clear the next text buffer line (using dma if possible)
|
||||
memset((void*)(terminal_memory+(((terminal_height+terminal_jsoffset) * 128) & 0xFFF)), ' ', 128);
|
||||
|
||||
// Smooth scroll then increment jsoffset
|
||||
terminal_ssoffset = 1;
|
||||
}
|
||||
|
||||
static void DELAYED_COPY_CODE(terminal_linefeed)() {
|
||||
if(terminal_row < (terminal_height-1)) {
|
||||
terminal_row++;
|
||||
} else {
|
||||
// Clear the next text buffer line (using dma if possible)
|
||||
memset((void*)(terminal_memory+(((terminal_row+1+terminal_jsoffset) * 128) & 0xFFF)), ' ', 128);
|
||||
|
||||
// Smooth scroll then increment jsoffset
|
||||
terminal_ssoffset = 1;
|
||||
terminal_scroll();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,7 +94,7 @@ void DELAYED_COPY_CODE(terminal_process_input)() {
|
|||
terminal_clear_screen();
|
||||
break;
|
||||
case '1':
|
||||
soft_switches &= ~SOFTSW_TERMINAL;
|
||||
internal_flags &= ~IFLAGS_TERMINAL;
|
||||
break;
|
||||
case '2':
|
||||
terminal_charset = 0;
|
||||
|
@ -104,17 +109,30 @@ void DELAYED_COPY_CODE(terminal_process_input)() {
|
|||
}
|
||||
terminal_esc_crz = false;
|
||||
} else if(terminal_esc) {
|
||||
terminal_esc = false;
|
||||
switch(ch) {
|
||||
case 'K':
|
||||
case '>':
|
||||
terminal_esc = true;
|
||||
case 'A':
|
||||
terminal_advance_cursor();
|
||||
break;
|
||||
case 'J':
|
||||
case '<':
|
||||
terminal_esc = true;
|
||||
case 'B':
|
||||
if(terminal_col > 0)
|
||||
terminal_col--;
|
||||
break;
|
||||
case 'M':
|
||||
case 'v':
|
||||
terminal_esc = true;
|
||||
case 'C':
|
||||
terminal_linefeed();
|
||||
break;
|
||||
case 'I':
|
||||
case '^':
|
||||
terminal_esc = true;
|
||||
case 'D': // Reverse Linefeed
|
||||
if(terminal_row > 0)
|
||||
terminal_row--;
|
||||
|
@ -128,14 +146,25 @@ void DELAYED_COPY_CODE(terminal_process_input)() {
|
|||
case '@': // Clear screen
|
||||
terminal_clear_screen();
|
||||
break;
|
||||
case '4':
|
||||
internal_flags &= ~IFLAGS_TERMINAL;
|
||||
break;
|
||||
case '8':
|
||||
internal_flags |= IFLAGS_TERMINAL;
|
||||
break;
|
||||
default:
|
||||
terminal_memory[(((terminal_row+terminal_jsoffset) * 128) + terminal_col) & 0xFFF] = ch;
|
||||
terminal_advance_cursor();
|
||||
break;
|
||||
}
|
||||
terminal_esc = false;
|
||||
} else
|
||||
switch(ch) {
|
||||
case 0x07:
|
||||
break;
|
||||
case 0x08:
|
||||
if(terminal_col > 0)
|
||||
terminal_col--;
|
||||
break;
|
||||
case 0x0A: // Line Feed
|
||||
terminal_linefeed();
|
||||
break;
|
||||
|
@ -148,10 +177,25 @@ void DELAYED_COPY_CODE(terminal_process_input)() {
|
|||
case 0x0D: // Ctrl-M: Carriage Return
|
||||
terminal_col = 0;
|
||||
break;
|
||||
case 0x0E: // Normal Text
|
||||
terminal_inverse = false;
|
||||
break;
|
||||
case 0x0F: // Inverse Text
|
||||
terminal_inverse = true;
|
||||
break;
|
||||
case 0x11:
|
||||
internal_flags &= ~IFLAGS_TERMINAL;
|
||||
break;
|
||||
case 0x12:
|
||||
internal_flags |= IFLAGS_TERMINAL;
|
||||
break;
|
||||
case 0x13: // Ctrl-S: Xon/Xoff (unimplemented)
|
||||
break;
|
||||
case 0x15: // Ctrl-U: Copy (unimplemented)
|
||||
break;
|
||||
case 0x17: // Ctrl-W: Scroll one line without moving cursor
|
||||
terminal_scroll();
|
||||
break;
|
||||
case 0x19: // Ctrl-Y: Home Cursor
|
||||
terminal_row = 0;
|
||||
terminal_col = 0;
|
||||
|
@ -176,7 +220,7 @@ void DELAYED_COPY_CODE(terminal_process_input)() {
|
|||
terminal_row--;
|
||||
break;
|
||||
default:
|
||||
terminal_memory[(((terminal_row+terminal_jsoffset) * 128) + terminal_col) & 0xFFF] = ch;
|
||||
terminal_memory[(((terminal_row+terminal_jsoffset) * 128) + terminal_col) & 0xFFF] = ch ^ (terminal_inverse ? 0x80 : 0x00);
|
||||
terminal_advance_cursor();
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -30,13 +30,7 @@ void DELAYED_COPY_CODE(render_mixed_dgr)() {
|
|||
render_dgr_line(PAGE2SEL, line);
|
||||
}
|
||||
|
||||
for(uint line=20; line < 24; line++) {
|
||||
if(soft_switches & SOFTSW_80COL) {
|
||||
render_text80_line(PAGE2SEL, line);
|
||||
} else {
|
||||
render_text40_line(PAGE2SEL, line);
|
||||
}
|
||||
}
|
||||
render_mixed_text();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,27 +25,25 @@ static inline uint dhgr_line_to_mem_offset(uint line) {
|
|||
|
||||
|
||||
void DELAYED_COPY_CODE(render_dhgr)() {
|
||||
if((internal_flags & IFLAGS_VIDEO7) && (internal_flags & IFLAGS_V7_MODE3 == IFLAGS_V7_MODE3)) {
|
||||
mono_rendering = true;
|
||||
}
|
||||
for(uint line=0; line < 192; line++) {
|
||||
render_dhgr_line(PAGE2SEL, line);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DELAYED_COPY_CODE(render_mixed_dhgr)() {
|
||||
if((internal_flags & IFLAGS_VIDEO7) && (internal_flags & IFLAGS_V7_MODE3 == IFLAGS_V7_MODE3)) {
|
||||
mono_rendering = true;
|
||||
}
|
||||
for(uint line=0; line < 160; line++) {
|
||||
render_dhgr_line(PAGE2SEL, line);
|
||||
}
|
||||
|
||||
for(uint line=20; line < 24; line++) {
|
||||
if(soft_switches & SOFTSW_80COL) {
|
||||
render_text80_line(PAGE2SEL, line);
|
||||
} else {
|
||||
render_text40_line(PAGE2SEL, line);
|
||||
}
|
||||
}
|
||||
render_mixed_text();
|
||||
}
|
||||
|
||||
|
||||
static void DELAYED_COPY_CODE(render_dhgr_line)(bool p2, uint line) {
|
||||
struct vga_scanline *sl = vga_prepare_scanline();
|
||||
uint sl_pos = 0;
|
||||
|
@ -54,10 +52,17 @@ static void DELAYED_COPY_CODE(render_dhgr_line)(bool p2, uint line) {
|
|||
const uint8_t *line_mema = (const uint8_t *)((p2 ? hgr_p2 : hgr_p1) + dhgr_line_to_mem_offset(line));
|
||||
const uint8_t *line_memb = (const uint8_t *)((p2 ? hgr_p4 : hgr_p3) + dhgr_line_to_mem_offset(line));
|
||||
|
||||
// Pad 40 pixels on the left to center horizontally
|
||||
sl->data[sl_pos++] = (text_border|THEN_EXTEND_7) | ((text_border|THEN_EXTEND_7) << 16); // 16 pixels per word
|
||||
sl->data[sl_pos++] = (text_border|THEN_EXTEND_7) | ((text_border|THEN_EXTEND_7) << 16); // 16 pixels per word
|
||||
sl->data[sl_pos++] = (text_border|THEN_EXTEND_3) | ((text_border|THEN_EXTEND_3) << 16); // 16 pixels per word
|
||||
if((internal_flags & IFLAGS_VIDEO7) && ((internal_flags & IFLAGS_V7_MODE3) == IFLAGS_V7_MODE1)) {
|
||||
// Pad 30 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_3) | ((text_border|THEN_EXTEND_7) << 16); // 12 pixels per word
|
||||
sl->data[sl_pos++] = (text_border) | ((text_border) << 16); // 2 pixels per word
|
||||
} else {
|
||||
// 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); // 16 pixels per word
|
||||
}
|
||||
|
||||
// DHGR is weird. Nuff said.
|
||||
uint32_t dots = 0;
|
||||
|
@ -86,6 +91,27 @@ static void DELAYED_COPY_CODE(render_dhgr_line)(bool p2, uint line) {
|
|||
dotc -= 2;
|
||||
}
|
||||
}
|
||||
} else if((internal_flags & IFLAGS_VIDEO7) && ((internal_flags & IFLAGS_V7_MODE3) == IFLAGS_V7_MODE1)) {
|
||||
while(i < 40) {
|
||||
// Load in as many subpixels as possible
|
||||
while((dotc <= 18) && (i < 40)) {
|
||||
dots |= (line_memb[i] & 0xff) << dotc;
|
||||
dotc += 8;
|
||||
dots |= (line_mema[i] & 0xff) << dotc;
|
||||
dotc += 8;
|
||||
i++;
|
||||
}
|
||||
|
||||
// Consume pixels
|
||||
while(dotc >= 8) {
|
||||
pixeldata = (dhgr_palette[dots & 0xf] | THEN_EXTEND_3);
|
||||
dots >>= 4;
|
||||
pixeldata |= (dhgr_palette[dots & 0xf] | THEN_EXTEND_3) << 16;
|
||||
dots >>= 4;
|
||||
sl->data[sl_pos++] = pixeldata;
|
||||
dotc -= 8;
|
||||
}
|
||||
}
|
||||
} else if(internal_flags & IFLAGS_OLDCOLOR) {
|
||||
while(i < 40) {
|
||||
// Load in as many subpixels as possible
|
||||
|
@ -149,10 +175,17 @@ static void DELAYED_COPY_CODE(render_dhgr_line)(bool p2, uint line) {
|
|||
sl->data[sl_pos++] = pixeldata;
|
||||
}
|
||||
|
||||
// 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); // 16 pixels per word
|
||||
if((internal_flags & IFLAGS_VIDEO7) && ((internal_flags & IFLAGS_V7_MODE3) == IFLAGS_V7_MODE1)) {
|
||||
// Pad 30 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_3) | ((text_border|THEN_EXTEND_7) << 16); // 12 pixels per word
|
||||
sl->data[sl_pos++] = (text_border) | ((text_border) << 16); // 2 pixels per word
|
||||
} else {
|
||||
// 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); // 16 pixels per word
|
||||
}
|
||||
|
||||
sl->length = sl_pos;
|
||||
sl->repeat_count = 1;
|
||||
|
|
|
@ -29,13 +29,7 @@ void DELAYED_COPY_CODE(render_mixed_hires)() {
|
|||
render_hires_line(PAGE2SEL, line);
|
||||
}
|
||||
|
||||
for(uint line=20; line < 24; line++) {
|
||||
if(soft_switches & SOFTSW_80COL) {
|
||||
render_text80_line(PAGE2SEL, line);
|
||||
} else {
|
||||
render_text40_line(PAGE2SEL, line);
|
||||
}
|
||||
}
|
||||
render_mixed_text();
|
||||
}
|
||||
|
||||
static void DELAYED_COPY_CODE(render_hires_line)(bool p2, uint line) {
|
||||
|
|
|
@ -48,13 +48,7 @@ void DELAYED_COPY_CODE(render_mixed_lores)() {
|
|||
render_lores_line(PAGE2SEL, line);
|
||||
}
|
||||
|
||||
for(uint line=20; line < 24; line++) {
|
||||
if(soft_switches & SOFTSW_80COL) {
|
||||
render_text80_line(PAGE2SEL, line);
|
||||
} else {
|
||||
render_text40_line(PAGE2SEL, line);
|
||||
}
|
||||
}
|
||||
render_mixed_text();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "vga/render.h"
|
||||
#include "vga/vgaout.h"
|
||||
|
||||
extern uint16_t lores_palette[16];
|
||||
|
||||
//#define PAGE2SEL (!(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2))
|
||||
#define PAGE2SEL ((soft_switches & (SOFTSW_80STORE | SOFTSW_PAGE_2)) == SOFTSW_PAGE_2)
|
||||
|
||||
|
@ -48,11 +50,53 @@ static inline uint_fast8_t char_text_bits(uint_fast8_t ch, uint_fast8_t glyph_li
|
|||
}
|
||||
|
||||
void DELAYED_COPY_CODE(render_text)() {
|
||||
for(uint line=0; line < 24; line++) {
|
||||
uint line;
|
||||
|
||||
if((internal_flags & IFLAGS_VIDEO7) && !(soft_switches & SOFTSW_DGR)) {
|
||||
if(soft_switches & SOFTSW_80COL) {
|
||||
render_text80_line(PAGE2SEL, line);
|
||||
for(line=0; line < 24; line++) {
|
||||
render_color_text80_line(line);
|
||||
}
|
||||
} else {
|
||||
render_text40_line(PAGE2SEL, line);
|
||||
for(line=0; line < 24; line++) {
|
||||
render_color_text40_line(line);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(soft_switches & SOFTSW_80COL) {
|
||||
for(line=0; line < 24; line++) {
|
||||
render_text80_line(PAGE2SEL, line);
|
||||
}
|
||||
} else {
|
||||
for(line=0; line < 24; line++) {
|
||||
render_text40_line(PAGE2SEL, line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DELAYED_COPY_CODE(render_mixed_text)() {
|
||||
uint line;
|
||||
|
||||
if((internal_flags & IFLAGS_VIDEO7) && !(soft_switches & SOFTSW_DGR)) {
|
||||
if(soft_switches & SOFTSW_80COL) {
|
||||
for(line=20; line < 24; line++) {
|
||||
render_color_text80_line(line);
|
||||
}
|
||||
} else {
|
||||
for(line=20; line < 24; line++) {
|
||||
render_color_text40_line(line);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(soft_switches & SOFTSW_80COL) {
|
||||
for(line=20; line < 24; line++) {
|
||||
render_text80_line(PAGE2SEL, line);
|
||||
}
|
||||
} else {
|
||||
for(line=20; line < 24; line++) {
|
||||
render_text40_line(PAGE2SEL, line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -150,3 +194,146 @@ void DELAYED_COPY_CODE(render_text80_line)(bool p2, unsigned int line) {
|
|||
}
|
||||
}
|
||||
|
||||
void DELAYED_COPY_CODE(render_color_text40_line)(unsigned int line) {
|
||||
const uint8_t *line_buf = (const uint8_t *)(text_p1 + ((line & 0x7) << 7) + (((line >> 3) & 0x3) * 40));
|
||||
const uint8_t *color_buf = (const uint8_t *)(text_p3 + ((line & 0x7) << 7) + (((line >> 3) & 0x3) * 40));
|
||||
|
||||
for(uint glyph_line=0; glyph_line < 8; glyph_line++) {
|
||||
struct vga_scanline *sl = vga_prepare_scanline();
|
||||
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
|
||||
uint32_t bits_a = char_text_bits(line_buf[col], glyph_line);
|
||||
uint16_t color1 = lores_palette[(color_buf[col] >> 4) & 0xf];
|
||||
uint16_t color2 = lores_palette[color_buf[col] & 0xf];
|
||||
col++;
|
||||
uint32_t bits_b = char_text_bits(line_buf[col], glyph_line);
|
||||
uint16_t color3 = lores_palette[(color_buf[col] >> 4) & 0xf];
|
||||
uint16_t color4 = lores_palette[color_buf[col] & 0xf];
|
||||
col++;
|
||||
|
||||
uint32_t bits = (bits_a << 7) | bits_b;
|
||||
uint32_t pixeldata;
|
||||
|
||||
// Translate each pair of bits into a pair of pixels
|
||||
for(int i=0; i < 3; i++) {
|
||||
pixeldata = (bits & 0x2000) ? (color2|THEN_EXTEND_1) : (color1|THEN_EXTEND_1);
|
||||
pixeldata |= (bits & 0x1000) ?
|
||||
(uint32_t)(color2|THEN_EXTEND_1) << 16 :
|
||||
(uint32_t)(color1|THEN_EXTEND_1) << 16;
|
||||
bits <<= 2;
|
||||
|
||||
sl->data[sl_pos] = pixeldata;
|
||||
sl_pos++;
|
||||
}
|
||||
|
||||
pixeldata = (bits & 0x2000) ? (color2|THEN_EXTEND_1) : (color1|THEN_EXTEND_1);
|
||||
pixeldata |= (bits & 0x1000) ?
|
||||
(uint32_t)(color4|THEN_EXTEND_1) << 16 :
|
||||
(uint32_t)(color3|THEN_EXTEND_1) << 16;
|
||||
bits <<= 2;
|
||||
|
||||
sl->data[sl_pos] = pixeldata;
|
||||
sl_pos++;
|
||||
|
||||
for(int i=4; i < 7; i++) {
|
||||
pixeldata = (bits & 0x2000) ? (color4|THEN_EXTEND_1) : (color3|THEN_EXTEND_1);
|
||||
pixeldata |= (bits & 0x1000) ?
|
||||
(uint32_t)(color4|THEN_EXTEND_1) << 16 :
|
||||
(uint32_t)(color3|THEN_EXTEND_1) << 16;
|
||||
bits <<= 2;
|
||||
|
||||
sl->data[sl_pos] = pixeldata;
|
||||
sl_pos++;
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
void DELAYED_COPY_CODE(render_color_text80_line)(unsigned int line) {
|
||||
const uint8_t *line_buf_a = (const uint8_t *)(text_p1 + ((line & 0x7) << 7) + (((line >> 3) & 0x3) * 40));
|
||||
const uint8_t *line_buf_b = (const uint8_t *)(text_p3 + ((line & 0x7) << 7) + (((line >> 3) & 0x3) * 40));
|
||||
const uint8_t *color_buf_a = (const uint8_t *)(text_p2 + ((line & 0x7) << 7) + (((line >> 3) & 0x3) * 40));
|
||||
const uint8_t *color_buf_b = (const uint8_t *)(text_p4 + ((line & 0x7) << 7) + (((line >> 3) & 0x3) * 40));
|
||||
|
||||
for(uint glyph_line=0; glyph_line < 8; glyph_line++) {
|
||||
struct vga_scanline *sl = vga_prepare_scanline();
|
||||
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
|
||||
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);
|
||||
uint16_t color1 = lores_palette[color_buf_a[col] >> 4];
|
||||
uint16_t color2 = lores_palette[color_buf_a[col] & 0xF];
|
||||
uint16_t color3 = lores_palette[color_buf_b[col] >> 4];
|
||||
uint16_t color4 = lores_palette[color_buf_b[col] & 0xF];
|
||||
col++;
|
||||
|
||||
uint32_t bits = (bits_b << 7) | bits_a;
|
||||
uint32_t pixeldata;
|
||||
|
||||
// Translate each pair of bits into a pair of pixels
|
||||
for(int i=0; i < 3; i++) {
|
||||
pixeldata = (bits & 0x2000) ? (color2) : (color1);
|
||||
pixeldata |= (bits & 0x1000) ?
|
||||
(uint32_t)(color2) << 16 :
|
||||
(uint32_t)(color1) << 16;
|
||||
bits <<= 2;
|
||||
|
||||
sl->data[sl_pos] = pixeldata;
|
||||
sl_pos++;
|
||||
}
|
||||
|
||||
pixeldata = (bits & 0x2000) ? (color2) : (color1);
|
||||
pixeldata |= (bits & 0x1000) ?
|
||||
(uint32_t)(color4) << 16 :
|
||||
(uint32_t)(color3) << 16;
|
||||
bits <<= 2;
|
||||
|
||||
sl->data[sl_pos] = pixeldata;
|
||||
sl_pos++;
|
||||
|
||||
for(int i=4; i < 7; i++) {
|
||||
pixeldata = (bits & 0x2000) ? (color4) : (color3);
|
||||
pixeldata |= (bits & 0x1000) ?
|
||||
(uint32_t)(color4) << 16 :
|
||||
(uint32_t)(color3) << 16;
|
||||
bits <<= 2;
|
||||
|
||||
sl->data[sl_pos] = pixeldata;
|
||||
sl_pos++;
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue