diff --git a/src/conio/cterm.c b/src/conio/cterm.c
index f35a4231a65ce238f40b4bbba34f88fc96bca75b..cb0420c459c43cd9379f4c776268bf0601f88b5e 100644
--- a/src/conio/cterm.c
+++ b/src/conio/cterm.c
@@ -45,6 +45,13 @@
 	#include <xpsem.h>
 #endif
 #include <threadwrap.h>
+#if !(defined __BORLANDC__ || defined _MSC_VER)
+ #include <stdbool.h>
+#else
+ #define bool int
+ enum { false, true };
+#endif
+
 
 #include "ciolib.h"
 
@@ -962,7 +969,7 @@ void CIOLIBCALL cterm_clearscreen(struct cterminal *cterm, char attr)
 		    cterm->scrollback + (cterm->backpos - cterm->height) * cterm->width);
 	}
 	CLRSCR();
-	if(cterm->origin_mode)
+	if(cterm->extattr & CTERM_EXTATTR_ORIGINMODE)
 		GOTOXY(1,cterm->top_margin);
 	else
 		GOTOXY(1,1);
@@ -1440,10 +1447,10 @@ static void parse_sixel_string(struct cterminal *cterm, bool finish)
 						setpixels(cterm->sx_left, cterm->sx_y, cterm->sx_row_max_x, cterm->sx_y + 6 * cterm->sx_iv - 1, cterm->sx_left, 0, cterm->sx_pixels, cterm->sx_mask);
 						cterm->sx_row_max_x = 0;
 
-						if(cterm->origin_mode)
+						if(cterm->extattr & CTERM_EXTATTR_ORIGINMODE)
 							max_row = cterm->bottom_margin - cterm->top_margin + 1;
 
-						if ((!cterm->sx_scroll_mode) && (((cterm->sx_y + 6 * cterm->sx_iv) + 6*cterm->sx_iv - 1) >= (cterm->y + max_row - 1) * vparams[vmode].charheight)) {
+						if ((!(cterm->extattr & CTERM_EXTATTR_SXSCROLL)) && (((cterm->sx_y + 6 * cterm->sx_iv) + 6*cterm->sx_iv - 1) >= (cterm->y + max_row - 1) * vparams[vmode].charheight)) {
 							p++;
 							break;
 						}
@@ -1500,7 +1507,7 @@ all_done:
 		free(px.pixels);
 	}
 
-	if (cterm->sx_scroll_mode) {
+	if (cterm->extattr & CTERM_EXTATTR_SXSCROLL) {
 		if (vmode != -1) {
 			cterm->sx_x = cterm->sx_x / vparams[vmode].charwidth + 1;
 			cterm->sx_x -= (cterm->x - 1);
@@ -1523,12 +1530,41 @@ all_done:
 	FREE_AND_NULL(cterm->sx_mask);
 }
 
-static void parse_extended_colour(struct esc_seq *seq, int *i, uint32_t *co)
+static void save_extended_colour_seq(struct cterminal *cterm, int fg, struct esc_seq *seq, int seqoff, int count)
+{
+	char **str = fg ? &cterm->fg_tc_str : &cterm->bg_tc_str;
+
+	if (*str)
+		FREE_AND_NULL(*str);
+
+	switch (count) {
+		case 1:
+			*str = asprintf("%s", seq->param[seqoff]);
+			break;
+		case 2:
+			*str = asprintf("%s;%s", seq->param[seqoff], seq->param[seqoff+1]);
+			break;
+		case 3:
+			*str = asprintf("%s;%s;%s", seq->param[seqoff], seq->param[seqoff+1], seq->param[seqoff+2]);
+			break;
+		case 5:
+			*str = asprintf("%s;%s;%s;%s;%s", seq->param[seqoff], seq->param[seqoff+1], seq->param[seqoff+2], seq->param[seqoff+3], seq->param[seqoff+4]);
+			break;
+	}
+}
+
+static void parse_extended_colour(struct esc_seq *seq, int *i, struct cterminal *cterm, int fg)
 {
 	struct sub_params sub = {0};
 	uint32_t nc;
+	uint32_t *co;
 
-	if (seq == NULL || co == NULL || i == NULL)
+	if (fg)
+		FREE_AND_NULL(cterm->fg_tc_str);
+	else
+		FREE_AND_NULL(cterm->bg_tc_str);
+	co = fg ? (&cterm->fg_color) : (&cterm->bg_color);
+	if (seq == NULL || cterm == NULL || i == NULL)
 		return;
 	if (*i>=seq->param_count)
 		return;
@@ -1538,18 +1574,22 @@ static void parse_extended_colour(struct esc_seq *seq, int *i, uint32_t *co)
 		// CSI 38 : 2 : Z? : R : G : B m variant
 
 		if (parse_sub_parameters(&sub, seq, *i)) {
-			if (sub.param_count == 3 && sub.param_int[1] == 5)
+			if (sub.param_count == 3 && sub.param_int[1] == 5) {
 				*co = sub.param_int[2];
+				save_extended_colour_seq(cterm, fg, seq, *i, 1);
+			}
 			else if (sub.param_int[1] == 2) {
 				if (sub.param_count == 5) {
 					nc = map_rgb(sub.param_int[2]<<8, sub.param_int[3]<<8, sub.param_int[4]<<8);
 					if (nc != UINT32_MAX)
 						*co = nc;
+					save_extended_colour_seq(cterm, fg, seq, *i, 1);
 				}
 				else if (sub.param_count > 5) {
 					nc = map_rgb(sub.param_int[3]<<8, sub.param_int[4]<<8, sub.param_int[5]<<8);
 					if (nc != UINT32_MAX)
 						*co = nc;
+					save_extended_colour_seq(cterm, fg, seq, *i, 1);
 				}
 			}
 		}
@@ -1560,12 +1600,14 @@ static void parse_extended_colour(struct esc_seq *seq, int *i, uint32_t *co)
 			if (sub.param_count == 2)
 				*co = sub.param_int[1];
 			(*i)++;
+			save_extended_colour_seq(cterm, fg, seq, *i, 2);
 		}
 	}
 	else if ((*i)+2 < seq->param_count && seq->param_int[(*i)+1] == 5) {
 		// CSI 38 ; 5 ; X m variant
 		*co = seq->param_int[(*i)+2] + 16;
 		*i+=2;
+		save_extended_colour_seq(cterm, fg, seq, *i, 3);
 	}
 	else if ((*i)+1 < seq->param_count && seq->param_int[(*i)+1] == 2 && seq->param[(*i)+1][1] == ':') {
 		// CSI 38 ; 2 : Z? : R : G : B m variant
@@ -1577,6 +1619,7 @@ static void parse_extended_colour(struct esc_seq *seq, int *i, uint32_t *co)
 				nc = map_rgb(sub.param_int[1]<<8, sub.param_int[2]<<8, sub.param_int[3]<<8);
 			if (nc != UINT32_MAX)
 				*co = nc;
+			save_extended_colour_seq(cterm, fg, seq, *i, 2);
 		}
 	}
 	else if ((*i)+4 < seq->param_count && seq->param_int[(*i)+1] == 2) {
@@ -1585,6 +1628,7 @@ static void parse_extended_colour(struct esc_seq *seq, int *i, uint32_t *co)
 		if (nc != UINT32_MAX)
 			*co = nc;
 		*i += 4;
+		save_extended_colour_seq(cterm, fg, seq, *i, 5);
 	}
 	free_sub_parameters(&sub);
 }
@@ -1679,15 +1723,15 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 						if (seq->param_str[0] == '?' && parse_parameters(seq)) {
 							attr2palette(cterm->attr, &oldfg, &oldbg);
 							updfg = (oldfg == cterm->fg_color);
-							updbg = (oldfg == cterm->bg_color);
+							updbg = (oldbg == cterm->bg_color);
 							for (i=0; i<seq->param_count; i++) {
 								switch(seq->param_int[i]) {
 									case 6:
-										cterm->origin_mode=true;
+										cterm->extattr |= CTERM_EXTATTR_ORIGINMODE;
 										GOTOXY(1,cterm->top_margin);
 										break;
 									case 7:
-										cterm->autowrap=true;
+										cterm->extattr |= CTERM_EXTATTR_AUTOWRAP;
 										break;
 									case 25:
 										cterm->cursor=_NORMALCURSOR;
@@ -1719,12 +1763,17 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 										SETVIDEOFLAGS(flags);
 										break;
 									case 80:
-										cterm->sx_scroll_mode = 1;
+										cterm->extattr |= CTERM_EXTATTR_SXSCROLL;
 										break;
 								}
 							}
-							if (updfg || updbg)
+							if (updfg || updbg) {
 								attr2palette(cterm->attr, updfg ? &cterm->fg_color : NULL, updbg ? &cterm->bg_color : NULL);
+								if (updfg)
+									FREE_AND_NULL(cterm->fg_tc_str);
+								if (updbg)
+									FREE_AND_NULL(cterm->bg_tc_str);
+							}
 						}
 						else if(!strcmp(seq->param_str,"=255"))
 							cterm->doorway_mode=1;
@@ -1733,15 +1782,15 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 						if (seq->param_str[0] == '?' && parse_parameters(seq)) {
 							attr2palette(cterm->attr, &oldfg, &oldbg);
 							updfg = (oldfg == cterm->fg_color);
-							updbg = (oldfg == cterm->bg_color);
+							updbg = (oldbg == cterm->bg_color);
 							for (i=0; i<seq->param_count; i++) {
 								switch(seq->param_int[i]) {
 									case 6:
-										cterm->origin_mode=false;
+										cterm->extattr &= ~CTERM_EXTATTR_ORIGINMODE;
 										GOTOXY(1,1);
 										break;
 									case 7:
-										cterm->autowrap=false;
+										cterm->extattr &= ~(CTERM_EXTATTR_AUTOWRAP);
 										break;
 									case 25:
 										cterm->cursor=_NOCURSOR;
@@ -1773,12 +1822,17 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 										SETVIDEOFLAGS(flags);
 										break;
 									case 80:
-										cterm->sx_scroll_mode = 0;
+										cterm->extattr &= ~CTERM_EXTATTR_SXSCROLL;
 										break;
 								}
 							}
-							if (updfg || updbg)
+							if (updfg || updbg) {
 								attr2palette(cterm->attr, updfg ? &cterm->fg_color : NULL, updbg ? &cterm->bg_color : NULL);
+								if (updfg)
+									FREE_AND_NULL(cterm->fg_tc_str);
+								if (updbg)
+									FREE_AND_NULL(cterm->bg_tc_str);
+							}
 						}
 						else if(!strcmp(seq->param_str,"=255"))
 							cterm->doorway_mode=0;
@@ -1807,9 +1861,9 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 								case 2:
 									vidflags = GETVIDEOFLAGS();
 									strcpy(tmp, "\x1b[=2");
-									if(cterm->origin_mode)
-									strcat(tmp, ";6");
-									if(cterm->autowrap)
+									if(cterm->extattr & CTERM_EXTATTR_ORIGINMODE)
+										strcat(tmp, ";6");
+									if (cterm->extattr & CTERM_EXTATTR_AUTOWRAP);
 										strcat(tmp, ";7");
 									if(cterm->cursor == _NORMALCURSOR)
 										strcat(tmp, ";25");
@@ -1823,7 +1877,7 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 										strcat(tmp, ";34");
 									if(vidflags & CIOLIB_VIDEO_NOBLINK)
 										strcat(tmp, ";35");
-									if (cterm->sx_scroll_mode)
+									if (cterm->extattr & CTERM_EXTATTR_SXSCROLL)
 										strcat(tmp, ";80");
 									if (strlen(tmp) == 4) {	// Nothing set
 										strcat(tmp, ";");
@@ -1854,15 +1908,15 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 								/* All the save stuff... */
 								cterm->saved_mode_mask |= (CTERM_SAVEMODE_AUTOWRAP|CTERM_SAVEMODE_CURSOR|CTERM_SAVEMODE_ALTCHARS|CTERM_SAVEMODE_NOBRIGHT|CTERM_SAVEMODE_BGBRIGHT|CTERM_SAVEMODE_ORIGIN|CTERM_SAVEMODE_SIXEL_SCROLL);
 								cterm->saved_mode &= ~(CTERM_SAVEMODE_AUTOWRAP|CTERM_SAVEMODE_CURSOR|CTERM_SAVEMODE_ALTCHARS|CTERM_SAVEMODE_NOBRIGHT|CTERM_SAVEMODE_BGBRIGHT|CTERM_SAVEMODE_ORIGIN|CTERM_SAVEMODE_SIXEL_SCROLL);
-								cterm->saved_mode |= (cterm->autowrap)?CTERM_SAVEMODE_AUTOWRAP:0;
+								cterm->saved_mode |= (cterm->extattr & CTERM_EXTATTR_AUTOWRAP)?CTERM_SAVEMODE_AUTOWRAP:0;
 								cterm->saved_mode |= (cterm->cursor==_NORMALCURSOR)?CTERM_SAVEMODE_CURSOR:0;
 								cterm->saved_mode |= (flags & CIOLIB_VIDEO_ALTCHARS)?CTERM_SAVEMODE_ALTCHARS:0;
 								cterm->saved_mode |= (flags & CIOLIB_VIDEO_NOBRIGHT)?CTERM_SAVEMODE_NOBRIGHT:0;
 								cterm->saved_mode |= (flags & CIOLIB_VIDEO_BGBRIGHT)?CTERM_SAVEMODE_BGBRIGHT:0;
 								cterm->saved_mode |= (flags & CIOLIB_VIDEO_BLINKALTCHARS)?CTERM_SAVEMODE_BLINKALTCHARS:0;
 								cterm->saved_mode |= (flags & CIOLIB_VIDEO_NOBLINK)?CTERM_SAVEMODE_NOBLINK:0;
-								cterm->saved_mode |= (cterm->origin_mode)?CTERM_SAVEMODE_ORIGIN:0;
-								cterm->saved_mode |= (cterm->sx_scroll_mode)?CTERM_SAVEMODE_SIXEL_SCROLL:0;
+								cterm->saved_mode |= (cterm->extattr & CTERM_EXTATTR_ORIGINMODE)?CTERM_SAVEMODE_ORIGIN:0;
+								cterm->saved_mode |= (cterm->extattr & CTERM_EXTATTR_SXSCROLL)?CTERM_SAVEMODE_SIXEL_SCROLL:0;
 								break;
 							}
 							else {
@@ -1871,12 +1925,12 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 										case 6:
 											cterm->saved_mode_mask |= CTERM_SAVEMODE_ORIGIN;
 											cterm->saved_mode &= ~(CTERM_SAVEMODE_AUTOWRAP|CTERM_SAVEMODE_CURSOR|CTERM_SAVEMODE_ALTCHARS|CTERM_SAVEMODE_NOBRIGHT|CTERM_SAVEMODE_BGBRIGHT|CTERM_SAVEMODE_ORIGIN);
-											cterm->saved_mode |= cterm->origin_mode?CTERM_SAVEMODE_ORIGIN:0;
+											cterm->saved_mode |= (cterm->extattr & CTERM_EXTATTR_ORIGINMODE)?CTERM_SAVEMODE_ORIGIN:0;
 											break;
 										case 7:
 											cterm->saved_mode_mask |= CTERM_SAVEMODE_AUTOWRAP;
 											cterm->saved_mode &= ~(CTERM_SAVEMODE_AUTOWRAP|CTERM_SAVEMODE_CURSOR|CTERM_SAVEMODE_ALTCHARS|CTERM_SAVEMODE_NOBRIGHT|CTERM_SAVEMODE_BGBRIGHT);
-											cterm->saved_mode |= cterm->autowrap?CTERM_SAVEMODE_AUTOWRAP:0;
+											cterm->saved_mode |= (cterm->extattr & CTERM_EXTATTR_AUTOWRAP)?CTERM_SAVEMODE_AUTOWRAP:0;
 											break;
 										case 25:
 											cterm->saved_mode_mask |= CTERM_SAVEMODE_CURSOR;
@@ -1911,7 +1965,7 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 										case 80:
 											cterm->saved_mode_mask |= CTERM_SAVEMODE_SIXEL_SCROLL;
 											cterm->saved_mode &= ~(CTERM_SAVEMODE_SIXEL_SCROLL);
-											cterm->saved_mode |= (cterm->sx_scroll_mode)?CTERM_SAVEMODE_SIXEL_SCROLL:0;
+											cterm->saved_mode |= (cterm->extattr & CTERM_EXTATTR_SXSCROLL)?CTERM_SAVEMODE_SIXEL_SCROLL:0;
 											break;
 									}
 								}
@@ -1924,15 +1978,27 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 							flags = GETVIDEOFLAGS();
 							attr2palette(cterm->attr, &oldfg, &oldbg);
 							updfg = (oldfg == cterm->fg_color);
-							updbg = (oldfg == cterm->bg_color);
+							updbg = (oldbg == cterm->bg_color);
 							if(seq->param_count == 0) {
 								/* All the save stuff... */
-								if(cterm->saved_mode_mask & CTERM_SAVEMODE_ORIGIN)
-									cterm->origin_mode=(cterm->saved_mode & CTERM_SAVEMODE_ORIGIN) ? true : false;
-								if(cterm->saved_mode_mask & CTERM_SAVEMODE_AUTOWRAP)
-									cterm->autowrap=(cterm->saved_mode & CTERM_SAVEMODE_AUTOWRAP) ? true : false;
-								if(cterm->saved_mode_mask & CTERM_SAVEMODE_SIXEL_SCROLL)
-									cterm->sx_scroll_mode=(cterm->saved_mode & CTERM_SAVEMODE_SIXEL_SCROLL) ? true : false;
+								if(cterm->saved_mode_mask & CTERM_SAVEMODE_ORIGIN) {
+									if (cterm->saved_mode & CTERM_SAVEMODE_ORIGIN)
+										cterm->extattr |= CTERM_EXTATTR_ORIGINMODE;
+									else
+										cterm->extattr &= ~CTERM_EXTATTR_ORIGINMODE;
+								}
+								if(cterm->saved_mode_mask & CTERM_SAVEMODE_AUTOWRAP) {
+									if (cterm->saved_mode & CTERM_SAVEMODE_AUTOWRAP)
+										cterm->extattr |= CTERM_EXTATTR_AUTOWRAP;
+									else
+										cterm->extattr &= ~CTERM_EXTATTR_AUTOWRAP;
+								}
+	 							if(cterm->saved_mode_mask & CTERM_SAVEMODE_SIXEL_SCROLL) {
+									if (cterm->saved_mode & CTERM_SAVEMODE_SIXEL_SCROLL)
+										cterm->extattr |= CTERM_EXTATTR_SXSCROLL;
+									else
+										cterm->extattr &= ~CTERM_EXTATTR_SXSCROLL;
+								}
 								if(cterm->saved_mode_mask & CTERM_SAVEMODE_CURSOR) {
 									cterm->cursor = (cterm->saved_mode & CTERM_SAVEMODE_CURSOR) ? _NORMALCURSOR : _NOCURSOR;
 									SETCURSORTYPE(cterm->cursor);
@@ -1974,12 +2040,20 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 								for (i=0; i<seq->param_count; i++) {
 									switch(seq->param_int[i]) {
 										case 6:
-											if(cterm->saved_mode_mask & CTERM_SAVEMODE_ORIGIN)
-												cterm->origin_mode=(cterm->saved_mode & CTERM_SAVEMODE_ORIGIN) ? true : false;
+											if(cterm->saved_mode_mask & CTERM_SAVEMODE_ORIGIN) {
+												if (cterm->saved_mode & CTERM_SAVEMODE_ORIGIN)
+													cterm->extattr |= CTERM_EXTATTR_ORIGINMODE;
+												else
+													cterm->extattr &= ~CTERM_EXTATTR_ORIGINMODE;
+											}
 											break;
 										case 7:
-											if(cterm->saved_mode_mask & CTERM_SAVEMODE_AUTOWRAP)
-												cterm->autowrap=(cterm->saved_mode & CTERM_SAVEMODE_AUTOWRAP) ? true : false;
+											if(cterm->saved_mode_mask & CTERM_SAVEMODE_AUTOWRAP) {
+												if (cterm->saved_mode & CTERM_SAVEMODE_AUTOWRAP)
+													cterm->extattr |= CTERM_EXTATTR_AUTOWRAP;
+												else
+													cterm->extattr &= ~CTERM_EXTATTR_AUTOWRAP;
+											}
 											break;
 										case 25:
 											if(cterm->saved_mode_mask & CTERM_SAVEMODE_CURSOR) {
@@ -2033,14 +2107,23 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 											}
 											break;
 										case 80:
-											if(cterm->saved_mode_mask & CTERM_SAVEMODE_SIXEL_SCROLL)
-												cterm->sx_scroll_mode=(cterm->saved_mode & CTERM_SAVEMODE_SIXEL_SCROLL) ? true : false;
+											if(cterm->saved_mode_mask & CTERM_SAVEMODE_SIXEL_SCROLL) {
+												if (cterm->saved_mode & CTERM_SAVEMODE_SIXEL_SCROLL)
+													cterm->extattr |= CTERM_EXTATTR_SXSCROLL;
+												else
+													cterm->extattr &= ~CTERM_EXTATTR_SXSCROLL;
+											}
 											break;
 									}
 								}
 							}
-							if (updfg || updbg)
+							if (updfg || updbg) {
 								attr2palette(cterm->attr, updfg ? &cterm->fg_color : NULL, updbg ? &cterm->bg_color : NULL);
+								if (updfg)
+									FREE_AND_NULL(cterm->fg_tc_str);
+								if (updbg)
+									FREE_AND_NULL(cterm->bg_tc_str);
+							}
 						}
 						break;
 					case '{':
@@ -2230,7 +2313,7 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 						seq_default(seq, 0, 1);
 						seq_default(seq, 1, 1);
 						max_row = cterm->height;
-						if(cterm->origin_mode)
+						if(cterm->extattr & CTERM_EXTATTR_ORIGINMODE)
 							max_row = cterm->bottom_margin - cterm->top_margin + 1;
 						row=seq->param_int[0];
 						col=seq->param_int[1];
@@ -2240,7 +2323,7 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 							col=1;
 						if(row>max_row)
 							row=max_row;
-						if(cterm->origin_mode)
+						if(cterm->extattr & CTERM_EXTATTR_ORIGINMODE)
 							row += cterm->top_margin - 1;
 						if(col>cterm->width)
 							col=cterm->width;
@@ -2364,7 +2447,7 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 					case 'U':	/* Next Page */
 						GETTEXTINFO(&ti);
 						cterm_clearscreen(cterm, ti.normattr);
-						if(cterm->origin_mode)
+						if(cterm->extattr & CTERM_EXTATTR_ORIGINMODE)
 							GOTOXY(1,cterm->top_margin);
 						else
 							GOTOXY(1,1);
@@ -2456,46 +2539,62 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 								case 0:
 									cterm->attr=ti.normattr;
 									attr2palette(cterm->attr, &cterm->fg_color, &cterm->bg_color);
+									FREE_AND_NULL(cterm->fg_tc_str);
+									FREE_AND_NULL(cterm->bg_tc_str);
 									break;
 								case 1:
 									cterm->attr|=8;
-									if (!(flags & CIOLIB_VIDEO_NOBRIGHT))
+									if (!(flags & CIOLIB_VIDEO_NOBRIGHT)) {
 										attr2palette(cterm->attr, &cterm->fg_color, NULL);
+										FREE_AND_NULL(cterm->fg_tc_str);
+									}
 									break;
 								case 2:
 									cterm->attr&=247;
-									if (!(flags & CIOLIB_VIDEO_NOBRIGHT))
+									if (!(flags & CIOLIB_VIDEO_NOBRIGHT)) {
 										attr2palette(cterm->attr, &cterm->fg_color, NULL);
+										FREE_AND_NULL(cterm->fg_tc_str);
+									}
 									break;
 								case 4:	/* Underscore */
 									break;
 								case 5:
 								case 6:
 									cterm->attr|=128;
-									if (flags & CIOLIB_VIDEO_BGBRIGHT)
+									if (flags & CIOLIB_VIDEO_BGBRIGHT) {
 										attr2palette(cterm->attr, NULL, &cterm->bg_color);
+										FREE_AND_NULL(cterm->bg_tc_str);
+									}
 									break;
 								case 7:
 									j=cterm->attr&112;
 									cterm->attr = (cterm->attr << 4) & 0x70;
 									cterm->attr |= j>>4;
 									attr2palette(cterm->attr, &cterm->fg_color, &cterm->bg_color);
+									FREE_AND_NULL(cterm->fg_tc_str);
+									FREE_AND_NULL(cterm->bg_tc_str);
 									break;
 								case 8:
 									j=cterm->attr&112;
 									cterm->attr&=112;
 									cterm->attr |= j>>4;
 									attr2palette(cterm->attr, &cterm->fg_color, &cterm->bg_color);
+									FREE_AND_NULL(cterm->fg_tc_str);
+									FREE_AND_NULL(cterm->bg_tc_str);
 									break;
 								case 22:
 									cterm->attr &= 0xf7;
-									if (!(flags & CIOLIB_VIDEO_NOBRIGHT))
+									if (!(flags & CIOLIB_VIDEO_NOBRIGHT)) {
 										attr2palette(cterm->attr, &cterm->fg_color, NULL);
+										FREE_AND_NULL(cterm->fg_tc_str);
+									}
 									break;
 								case 25:
 									cterm->attr &= 0x7f;
-									if (flags & CIOLIB_VIDEO_BGBRIGHT)
+									if (flags & CIOLIB_VIDEO_BGBRIGHT) {
 										attr2palette(cterm->attr, NULL, &cterm->bg_color);
+										FREE_AND_NULL(cterm->bg_tc_str);
+									}
 									break;
 								case 27:
 									i=cterm->attr&7;
@@ -2504,92 +2603,110 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 									cterm->attr |= j>>4;
 									cterm->attr |= i<<4;
 									attr2palette(cterm->attr, &cterm->fg_color, &cterm->bg_color);
+									FREE_AND_NULL(cterm->fg_tc_str);
+									FREE_AND_NULL(cterm->bg_tc_str);
 									break;
 								case 30:
 									cterm->attr&=248;
 									attr2palette(cterm->attr, &cterm->fg_color, NULL);
+									FREE_AND_NULL(cterm->fg_tc_str);
 									break;
 								case 31:
 									cterm->attr&=248;
 									cterm->attr|=4;
 									attr2palette(cterm->attr, &cterm->fg_color, NULL);
+									FREE_AND_NULL(cterm->fg_tc_str);
 									break;
 								case 32:
 									cterm->attr&=248;
 									cterm->attr|=2;
 									attr2palette(cterm->attr, &cterm->fg_color, NULL);
+									FREE_AND_NULL(cterm->fg_tc_str);
 									break;
 								case 33:
 									cterm->attr&=248;
 									cterm->attr|=6;
 									attr2palette(cterm->attr, &cterm->fg_color, NULL);
+									FREE_AND_NULL(cterm->fg_tc_str);
 									break;
 								case 34:
 									cterm->attr&=248;
 									cterm->attr|=1;
 									attr2palette(cterm->attr, &cterm->fg_color, NULL);
+									FREE_AND_NULL(cterm->fg_tc_str);
 									break;
 								case 35:
 									cterm->attr&=248;
 									cterm->attr|=5;
 									attr2palette(cterm->attr, &cterm->fg_color, NULL);
+									FREE_AND_NULL(cterm->fg_tc_str);
 									break;
 								case 36:
 									cterm->attr&=248;
 									cterm->attr|=3;
 									attr2palette(cterm->attr, &cterm->fg_color, NULL);
+									FREE_AND_NULL(cterm->fg_tc_str);
 									break;
 								case 38:
-									parse_extended_colour(seq, &i, &cterm->fg_color);
+									parse_extended_colour(seq, &i, cterm, 1);
 									break;
 								case 37:
 								case 39:
 									cterm->attr&=248;
 									cterm->attr|=7;
 									attr2palette(cterm->attr, &cterm->fg_color, NULL);
+									FREE_AND_NULL(cterm->fg_tc_str);
 									break;
 								case 49:
 								case 40:
 									cterm->attr&=143;
 									attr2palette(cterm->attr, NULL, &cterm->bg_color);
+									FREE_AND_NULL(cterm->bg_tc_str);
 									break;
 								case 41:
 									cterm->attr&=143;
 									cterm->attr|=4<<4;
 									attr2palette(cterm->attr, NULL, &cterm->bg_color);
+									FREE_AND_NULL(cterm->bg_tc_str);
 									break;
 								case 42:
 									cterm->attr&=143;
 									cterm->attr|=2<<4;
 									attr2palette(cterm->attr, NULL, &cterm->bg_color);
+									FREE_AND_NULL(cterm->bg_tc_str);
 									break;
 								case 43:
 									cterm->attr&=143;
 									cterm->attr|=6<<4;
 									attr2palette(cterm->attr, NULL, &cterm->bg_color);
+									FREE_AND_NULL(cterm->bg_tc_str);
 									break;
 								case 44:
 									cterm->attr&=143;
 									cterm->attr|=1<<4;
 									attr2palette(cterm->attr, NULL, &cterm->bg_color);
+									FREE_AND_NULL(cterm->bg_tc_str);
 									break;
 								case 45:
 									cterm->attr&=143;
 									cterm->attr|=5<<4;
 									attr2palette(cterm->attr, NULL, &cterm->bg_color);
+									FREE_AND_NULL(cterm->bg_tc_str);
 									break;
 								case 46:
 									cterm->attr&=143;
 									cterm->attr|=3<<4;
 									attr2palette(cterm->attr, NULL, &cterm->bg_color);
+									FREE_AND_NULL(cterm->bg_tc_str);
 									break;
 								case 47:
 									cterm->attr&=143;
 									cterm->attr|=7<<4;
 									attr2palette(cterm->attr, NULL, &cterm->bg_color);
+									FREE_AND_NULL(cterm->bg_tc_str);
 									break;
 								case 48:
-									parse_extended_colour(seq, &i, &cterm->bg_color);
+									parse_extended_colour(seq, &i, cterm, 0);
 									break;
 							}
 						}
@@ -2609,7 +2726,7 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 							case 6:
 								if(retbuf!=NULL) {
 									row = WHEREY();
-									if(cterm->origin_mode)
+									if(cterm->extattr & CTERM_EXTATTR_ORIGINMODE)
 										row = row - cterm->top_margin + 1;
 									sprintf(tmp,"\x1b[%d;%dR",row,WHEREX());
 									if(strlen(retbuf)+strlen(tmp) < retsize)
@@ -2619,7 +2736,7 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 							case 255:
 								if(retbuf!=NULL) {
 									row = cterm->height;
-									if(cterm->origin_mode)
+									if(cterm->extattr & CTERM_EXTATTR_ORIGINMODE)
 										row = (cterm->bottom_margin - cterm->top_margin) + 1;
 									sprintf(tmp,"\x1b[%d;%dR",row,cterm->width);
 									if(strlen(retbuf)+strlen(tmp) < retsize)
@@ -2671,7 +2788,7 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 					case 'u':
 						if(cterm->save_ypos>0 && cterm->save_ypos<=cterm->height
 								&& cterm->save_xpos>0 && cterm->save_xpos<=cterm->width) {
-							if(cterm->origin_mode && (cterm->save_ypos < cterm->top_margin || cterm->save_ypos > cterm->bottom_margin))
+							if((cterm->extattr & CTERM_EXTATTR_ORIGINMODE) && (cterm->save_ypos < cterm->top_margin || cterm->save_ypos > cterm->bottom_margin))
 								break;
 							GOTOXY(cterm->save_xpos,cterm->save_ypos);
 						}
@@ -2769,6 +2886,22 @@ static void do_ansi(struct cterminal *cterm, char *retbuf, size_t retsize, int *
 									}
 								}
 							}
+							else if (strncmp(cterm->strbuf, "$q", 2) == 0) {
+								// DECRQSS - VT-420
+								switch (cterm->strbuf[2]) {
+									case 'm':
+										if (cterm->strbuf[3] == 0) {
+										}
+										break;
+									default:
+										// TODO: Send error response.
+										if(retbuf!=NULL) {
+											strcpy(tmp,"\x1b[0n");
+											if(strlen(retbuf)+7 < retsize)
+												strcat(retbuf, "\x1bP1$r\x1b_");
+										}
+								}
+							}
 						}
 						cterm->sixel = SIXEL_INACTIVE;
 						break;
@@ -2904,11 +3037,9 @@ struct cterminal* CIOLIBCALL cterm_init(int height, int width, int xpos, int ypo
 	cterm->logfile=NULL;
 	cterm->emulation=emulation;
 	cterm->cursor=_NORMALCURSOR;
-	cterm->autowrap=true;
-	cterm->origin_mode=false;
+	cterm->extattr = CTERM_EXTATTR_AUTOWRAP | CTERM_EXTATTR_SXSCROLL;
 	cterm->fg_color = UINT32_MAX;
 	cterm->bg_color = UINT32_MAX;
-	cterm->sx_scroll_mode = true;
 	if(cterm->scrollback!=NULL)
 		memset(cterm->scrollback,0,cterm->width*2*cterm->backlines);
 	strcpy(cterm->DA,"\x1b[=67;84;101;114;109;");
@@ -2979,6 +3110,8 @@ void CIOLIBCALL cterm_start(struct cterminal *cterm)
 		GETTEXTINFO(&ti);
 		cterm->attr=ti.normattr;
 		attr2palette(cterm->attr, &cterm->fg_color, &cterm->bg_color);
+		FREE_AND_NULL(cterm->fg_tc_str);
+		FREE_AND_NULL(cterm->bg_tc_str);
 		cterm->fg_color += 16;
 		cterm->bg_color += 16;
 		TEXTATTR(cterm->attr);
@@ -3052,7 +3185,7 @@ static void ctputs(struct cterminal *cterm, char *buf)
 				GOTOXY(cx,cy);
 				break;
 			default:
-				if(cx==cterm->width && (!cterm->autowrap)) {
+				if(cx==cterm->width && (!(cterm->extattr & CTERM_EXTATTR_AUTOWRAP))) {
 					char ch;
 					ch=*(p+1);
 					*(p+1)=0;
@@ -3125,7 +3258,7 @@ static void parse_sixel_intro(struct cterminal *cterm)
 			return;
 		}
 		attr2palette(ti.attribute, &cterm->sx_fg, &cterm->sx_bg);
-		if (cterm->sx_scroll_mode) {
+		if (cterm->extattr & CTERM_EXTATTR_SXSCROLL) {
 			cterm->sx_x = cterm->sx_left = (cterm->x + WHEREX() - 2) * vparams[vmode].charwidth;
 			cterm->sx_y = (cterm->y + WHEREY() - 2) * vparams[vmode].charheight;
 		}
@@ -3757,6 +3890,8 @@ CIOLIBEXPORT char* CIOLIBCALL cterm_write(struct cterminal * cterm, const void *
 								}
 								TEXTATTR(cterm->attr);
 								attr2palette(cterm->attr, &cterm->fg_color, &cterm->bg_color);
+								FREE_AND_NULL(cterm->fg_tc_str);
+								FREE_AND_NULL(cterm->bg_tc_str);
 								break;
 
 							/* Movement */
@@ -3962,7 +4097,7 @@ CIOLIBEXPORT char* CIOLIBCALL cterm_write(struct cterminal * cterm, const void *
 									if(cterm->log==CTERM_LOG_ASCII && cterm->logfile != NULL)
 										fputs("\x0c", cterm->logfile);
 									cterm_clearscreen(cterm, (char)cterm->attr);
-									if(cterm->origin_mode)
+									if(cterm->extattr & CTERM_EXTATTR_ORIGINMODE)
 										GOTOXY(1,cterm->top_margin);
 									else
 										GOTOXY(1,1);
diff --git a/src/conio/cterm.h b/src/conio/cterm.h
index e68f4c01de12bbe1491595c519a859f389f66beb..c22613e959eefa6451ac421dadd55237f22da53d 100644
--- a/src/conio/cterm.h
+++ b/src/conio/cterm.h
@@ -35,12 +35,6 @@
 #define _CTERM_H_
 
 #include <stdio.h>	/* FILE* */
-#if !(defined __BORLANDC__ || defined _MSC_VER)
-#include <stdbool.h>
-#else
-#define bool int
-enum { false, true };
-#endif
 #include <link_list.h>
 #include <semwrap.h>
 #include "ciolib.h"
@@ -91,8 +85,6 @@ struct cterminal {
 	struct vmem_cell	*scrollback;
 	int					backlines;		// Number of lines in scrollback
 	char				DA[1024];		// Device Attributes
-	bool				autowrap;
-	bool				origin_mode;
 #define	CTERM_SAVEMODE_AUTOWRAP			0x001
 #define CTERM_SAVEMODE_CURSOR			0x002
 #define	CTERM_SAVEMODE_ALTCHARS			0x004
@@ -111,6 +103,10 @@ struct cterminal {
 	unsigned char		attr;			// Current attribute
 	uint32_t			fg_color;
 	uint32_t			bg_color;
+	unsigned int		extattr;		// Extended attributes
+#define CTERM_EXTATTR_AUTOWRAP		0x0001
+#define CTERM_EXTATTR_ORIGINMODE	0x0002
+#define CTERM_EXTATTR_SXSCROLL		0x0004
 	int					save_xpos;		// Saved position (for later restore)
 	int					save_ypos;
 	int					sequence;		// An escape sequence is being parsed
@@ -148,6 +144,8 @@ struct cterminal {
 	int					doorway_mode;
 	int					doorway_char;	// Indicates next char is a "doorway" mode char
 	int					cursor;			// Current cursor mode (Normal or None)
+	char				*fg_tc_str;
+	char				*bg_tc_str;
 
 	/* Sixel state */
 	int					sixel;			// Sixel status
@@ -165,7 +163,6 @@ struct cterminal {
 										   Raster Attributes are ignore if this is true. */
 	int					sx_first_pass;	// First pass through a line
 	int					sx_hold_update;	// hold_update value to restore on completion
-	bool				sx_scroll_mode;	// Sixel scrolling mode
 	int					sx_start_x;		// Starting X position
 	int					sx_start_y;		// Starting Y position
 	int					sx_row_max_x;	// Max right size of this sixel line
diff --git a/src/conio/cterm.txt b/src/conio/cterm.txt
index 5c4c3a622c4ec3d7a98bba43e29392c3c8d8f012..b0969a34dfea05cd00a8a96e53c6eb6dddf3d7c1 100644
--- a/src/conio/cterm.txt
+++ b/src/conio/cterm.txt
@@ -613,46 +613,53 @@ CSI Ps... m
 	Sets or clears one or more text attributes.  Unlimited parameters are
 	supported and are applied in received order.  The following are
 	supported:
-	                                        Blink Bold FG BG (Modified)
-	0 -  Default attribute, white on black     X    X  X  X
-	1 -  Bright Intensity                           X
-	2 -  Dim intensity                              X
-	5 -  Blink (By definition, slow blink)     X
-	6 -  Blink (By definition, fast blink)     X
+	                                        Blink Bold FG BG TF TB (Modified)
+	0 -  Default attribute, white on black     X    X  X  X  X  X
+	1 -  Bright Intensity                           X        X
+	2 -  Dim intensity                              X        X
+	5 -  Blink (By definition, slow blink)     X                X
+	6 -  Blink (By definition, fast blink)     X                X
 	     NOTE: Both blinks are the same speed.
-	7 -  Negative Image - Reverses FG and BG           X  X
-	8 -  Concealed characters, sets the                X
+	7 -  Negative Image - Reverses FG and BG           X  X  X  X
+	8 -  Concealed characters, sets the                X     X  X
 	     foreground colour to the background
 	     colour.
-	22 - Normal intensity                           X
-	25 - Steady (Not blinking)                 X
-	27 - Positive Image - Reverses FG and BG           X  X
+	22 - Normal intensity                           X        X
+	25 - Steady (Not blinking)                 X                X
+	27 - Positive Image - Reverses FG and BG           X  X  X  X
 	     NOTE: This should be a separate
 	           attribute than 7 but this
 	           implementation makes them equal
-	30 - Black foreground                              X
-	31 - Red foreground                                X
-	32 - Green foreground                              X
-	33 - Yellow foreground                             X
-	34 - Blue foreground                               X
-	35 - Magenta foreground                            X
-	36 - Cyan foreground                               X
-	37 - White foreground                              X
-	38 - Extended Foreground (see notes)               X
-	39 - Default foreground (same as white)	           X
-	40 - Black background                                 X
-	41 - Red background                                   X
-	42 - Green background                                 X
-	43 - Yellow background                                X
-	44 - Blue background                                  X
-	45 - Magenta background                               X
-	46 - Cyan background                                  X
-	47 - White background                                 X
-	48 - Extended Background (see notes)                  X
-	49 - Default background (same as black)               X
+	30 - Black foreground                              X     X
+	31 - Red foreground                                X     X
+	32 - Green foreground                              X     X
+	33 - Yellow foreground                             X     X
+	34 - Blue foreground                               X     X
+	35 - Magenta foreground                            X     X
+	36 - Cyan foreground                               X     X
+	37 - White foreground                              X     X
+	38 - Extended Foreground (see notes)                     X
+	39 - Default foreground (same as white)	           X     X
+	40 - Black background                                 X     X
+	41 - Red background                                   X     X
+	42 - Green background                                 X     X
+	43 - Yellow background                                X     X
+	44 - Blue background                                  X     X
+	45 - Magenta background                               X     X
+	46 - Cyan background                                  X     X
+	47 - White background                                 X     X
+	48 - Extended Background (see notes)                        X
+	49 - Default background (same as black)               X     X
 
 	All others are ignored.
 
+	Blink indicates the blink bit.
+	Bold indicates the bold bit.
+	FG indicates the foreground colour.
+	BG indicates the background colour.
+	TF indicates that the Tru Colour foreground is changed.
+	TB indicates that the Tru Colour background is changed.
+
 	NOTE: For 38 and 48, two additional formats are supported, a palette
 	selection and a direct colour selection.