int cursor_x, cursor_y;
int saved_x, saved_y;
int unicruds; char unicrud[7];
- unsigned char mode;
+ uint16_t mode;
Bool fast_p;
};
}
static void
-at_ascii_printc (analogterm_state_t *st, unsigned char c, unsigned char m,
+at_ascii_printc (analogterm_state_t *st, unsigned char c, uint16_t m,
Bool scroll_p)
{
state->mode &= ~TMODE_BOLD;
break;
case 4:
- case 21: /* FALLTHROUGH (doubly underline) */
state->mode |= TMODE_UNDERLINE;
break;
case 5:
case 7: /* FALLTHROUGH */
state->mode |= TMODE_INVERSE;
break;
- case 8: /* XXX Invisible, not yet implemented. */
+ case 8: /* Invisible */
+ state->mode |= TMODE_INVISIBLE;
break;
- case 9: /* XXX Striked, not yet implemented. */
+ case 9:
+ state->mode |= TMODE_STRIKE;
+ break;
+ case 21:
+ state->mode |= TMODE_DUNDERLINE;
break;
/* XXX Enable colors, converted to other attributes */
/* Foreground color */
state->mode &= ~(TMODE_BOLD | TMODE_DIM);
break;
case 24:
- state->mode &= ~TMODE_UNDERLINE;
+ state->mode &= ~(TMODE_UNDERLINE | TMODE_DUNDERLINE);
break;
case 25:
state->mode &= ~TMODE_BLINK;
case 27: /* FALLTHROUGH */
state->mode &= ~TMODE_INVERSE;
break;
- case 28: /* XXX Visible, not yet implemented. */
+ case 28: /* Visible, not yet implemented. */
+ state->mode &= ~TMODE_INVISIBLE;
break;
- case 29: /* XXX Not striked, not yet implemented. */
+ case 29:
+ state->mode &= ~TMODE_STRIKE;
break;
case 39: /* Default fg color */
state->mode &= ~TMODE_FGCOLOR;
/*
* Interestingly, in this case both dhc1 and dch with 0 are
* considered equivalent. dch <n> > 1 delete more than 1.
- * XXX Could use at_move() and at_clear().
*/
many = (state->csiparam[0] > 1 ? state->csiparam[0] : 1);
if (many >= cols - st->cursx) {
/* Clear rest of line in this case, like K */
many = cols - st->cursx;
- (void)memset(&st->textlines_char[st->cursy][st->cursx], ' ',
- many);
- (void)memset(&st->textlines_mode[st->cursy][st->cursx],
- state->mode & TMODE_BGCOLOR, many);
+ at_clear(st, st->cursx, st->cursy, many);
} else {
- unsigned char *cptr;
-
/* Move n chars from right to left */
- cptr = &st->textlines_char[st->cursy][st->cursx];
- (void)memmove(cptr, &cptr[many], cols - st->cursx - many);
- cptr = &st->textlines_mode[st->cursy][st->cursx];
- (void)memmove(cptr, &cptr[many], cols - st->cursx - many);
+ at_move(st, st->cursx, st->cursy, st->cursx + many, st->cursy,
+ cols - st->cursx - many);
/* Fill hole at right with emptyness */
- /* XXX Make sure this is the correct implementation */
- cptr = &st->textlines_char[st->cursy][cols];
- (void)memset(&cptr[-many], ' ', many);
- cptr = &st->textlines_mode[st->cursy][cols];
- (void)memset(&cptr[-many], state->mode & TMODE_BGCOLOR, many);
+ at_clear(st, cols - many, st->cursy, many);
}
state->escstate = 0;
break;
(void)memmove(&st->textlines_char[dy][dx],
&st->textlines_char[sy][sx], len);
(void)memmove(&st->textlines_mode[dy][dx],
- &st->textlines_mode[sy][sx], len);
+ &st->textlines_mode[sy][sx], len * sizeof(uint16_t));
}
void
at_clear(analogterm_state_t *st, int x, int y, int len)
{
+ int f, t;
+ uint16_t *mptr, *tptr;
(void)memset(&st->textlines_char[y][x], ' ', len);
- (void)memset(&st->textlines_mode[y][x], st->mode & TMODE_BGCOLOR, len);
+ for (mptr = &st->textlines_mode[y][x], tptr = &mptr[len];
+ mptr < tptr; mptr++)
+ *mptr = st->mode & TMODE_BGCOLOR;
}
/*
at_insert(analogterm_state_t *st, int many)
{
unsigned char *cptr;
+ uint16_t *mptr, *tptr;
int s;
if (many < 1)
return;
- /* Disable cursor */
- /*st->textlines_mode[st->cursy][st->cursx] &= ~TMODE_BLINK;*/
-
if (many > 80 - st->cursx)
many = 80 - st->cursx;
s = 80 - st->cursx - many;
+
cptr = &st->textlines_char[st->cursy][st->cursx];
(void)memmove(&cptr[many], cptr, s);
(void)memset(cptr, ' ', many);
- cptr = &st->textlines_mode[st->cursy][st->cursx];
- (void)memmove(&cptr[many], cptr, s);
- (void)memset(cptr, st->mode & TMODE_BGCOLOR, many);
- /* Restore cursor, may not always be necessary */
- /*st->textlines_mode[st->cursy][st->cursx] |= TMODE_BLINK;*/
+ mptr = &st->textlines_mode[st->cursy][st->cursx];
+ (void)memmove(&mptr[many], mptr, s * sizeof(uint16_t));
+ for (tptr = &mptr[many]; mptr < tptr; mptr++)
+ *mptr = st->mode & TMODE_BGCOLOR;
}
static signed char cursorstate = 127;
}*/
/* Block cursor, a bit bizarre for now :) */
- /* XXX This memory design is very inefficient */
- /* XXX Should probably use a well defined range instead of cycling
- * completely. */
+ /*
+ * XXX
+ * - This memory design is very inefficient
+ * - Should probably use a well-defined range instead of full cycle
+ * - Blinking speed should rely in a configurable timer
+ */
for (y = 0; y < 8; y++) {
pp = &sim->inp->signal[(ANALOGTV_TOP+3) + (8 * st->cursy) + y]
[(ANALOGTV_PIC_START+100) + (7 * st->cursx)];
if (offset == 0)
return;
- /* Disable cursor */
- /*st->textlines_mode[st->cursy][st->cursx] &= ~TMODE_BLINK;*/
-
/* Only one line to clear */
if (st->scroll_top == st->scroll_bottom) {
at_clear(st, 0, st->cursy, 80);
- /*goto done;*/
return;
}
+
/* Nothing to move, clear whole scrolling region */
if (abs(offset) > st->scroll_bottom - st->scroll_top) {
for (y = st->scroll_top; y < st->scroll_bottom; y++)
at_clear(st, 0, y, 80);
- /*goto done;*/
return;
}
for (y = st->scroll_top; offset > 0; offset--, y++)
at_clear(st, 0, y, 80);
}
-
-/*done:*/
- /* Restore cursor, may not always be necessary */
- /*st->textlines_mode[st->cursy][st->cursx] |= TMODE_BLINK;*/
}
void
at_scroll_range(st, -1);
}
+/* XXX Mode could use a state structure */
static void
-at_printc_1(analogterm_state_t *st, char c, unsigned char m, int scroll_p)
+at_printc_1(analogterm_state_t *st, char c, uint16_t m, int scroll_p)
{
- /*st->textlines_mode[st->cursy][st->cursx] &= ~TMODE_BLINK;*/ /* turn off blink */
+
at_resetcursor();
if (c == '\n') /* ^J == NL */
st->cursx=0;
}
}
-
- /*st->textlines_mode[st->cursy][st->cursx] |= TMODE_BLINK;*/ /* turn on blink */
}
void
-at_printc(analogterm_state_t *st, char c, unsigned char m)
+at_printc(analogterm_state_t *st, char c, uint16_t m)
{
at_printc_1(st, c, m, 1);
}
void
-at_printc_noscroll(analogterm_state_t *st, char c, unsigned char m)
+at_printc_noscroll(analogterm_state_t *st, char c, uint16_t m)
{
at_printc_1(st, c, m, 0);
}
void
-at_prints(analogterm_state_t *st, char *s, unsigned char m)
+at_prints(analogterm_state_t *st, char *s, uint16_t m)
{
while (*s) at_printc(st, *s++, m);
}
{
if (r > 24) r = 24;
if (c > 79) c = 79;
- /*st->textlines_mode[st->cursy][st->cursx] &= ~TMODE_BLINK;*/ /* turn off blink */
- st->cursy=r;
- st->cursx=c;
- /*st->textlines_mode[st->cursy][st->cursx] |= TMODE_BLINK;*/ /* turn on blink */
+
+ st->cursy = r;
+ st->cursx = c;
+
at_resetcursor();
}
void
at_cls(analogterm_state_t *st)
{
- int i;
-
- for (i=0; i<25; i++) {
- memset(st->textlines_char[i], ' ', 80);
- memset(st->textlines_mode[i], st->mode & TMODE_BGCOLOR, 80);
+ int y;
+ uint16_t *mptr, *tptr;
+
+ for (y = 0; y < 25; y++) {
+ memset(st->textlines_char[y], ' ', 80);
+ for (mptr = st->textlines_mode[y], tptr = &mptr[80];
+ mptr < tptr; mptr++)
+ *mptr = st->mode & TMODE_BGCOLOR;
}
}
reasonable. (I soldered a resistor in mine to make it blink faster.) */
i=st->blink;
st->blink=((int)blinkphase)&1;
+
+#if 0
if (st->blink!=i && !(st->gr_mode&A2_GR_FULL)) {
int downcounter=0;
/* For every row with blinking text, set the changed flag. This basically
int row, col;
for (row=(st->gr_mode ? 20 : 0); row<25; row++) {
for (col=0; col<80; col++) {
- int c = st->textlines_mode[row][col];
- if ((c & TMODE_BLINK) != 0) {
+ uint16_t m = st->textlines_mode[row][col];
+ if ((m & TMODE_BLINK) != 0) {
downcounter=4;
break;
}
}
}
}
+#endif
if (sim->curtime >= sim->delay)
sim->stepno = A2CONTROLLER_DONE;
signed char *pp;
int col;
int lastrow = row == textrow * 8 + 7;
+ int midrow = row == textrow * 8 + 3;
/* First we generate the pattern that the video circuitry shifts out
of memory. It has a 14.something MHz dot clock, equal to 4 times
pp=&sim->inp->signal[row+ANALOGTV_TOP+/*4*/3][ANALOGTV_PIC_START+100];
for (col=0; col<80; col++) {
int rev, level, olevel, iblink;
- int c = st->textlines_char[textrow][col] & 0xff;
- unsigned char m = st->textlines_mode[textrow][col] & 0xff;
- XImage *im = sim->text_im[m & TMODE_GFX ? 1 : 0];
+ int c = st->textlines_char[textrow][col] & 0xff; /* XXX */
+ uint16_t m = st->textlines_mode[textrow][col];
+ XImage *im = sim->text_im[(m & TMODE_GFX) != 0 ? 1 : 0];
rev = ((m & (TMODE_INVERSE | TMODE_BGCOLOR)) != 0);
if (c < 32 || c > 126)
c = 32;
- pix = XGetPixel(im, (c - 32) * 7 + i, row % 8);
- if ((m & TMODE_UNDERLINE) != 0 && lastrow)
+ if ((m & TMODE_INVISIBLE) != 0)
+ pix = 0;
+ else
+ pix = XGetPixel(im, (c - 32) * 7 + i, row % 8);
+
+ if (lastrow &&
+ (m & (TMODE_UNDERLINE | TMODE_DUNDERLINE)) != 0) {
+ pix = 1;
+ if ((m & TMODE_DUNDERLINE) != 0)
+ level = olevel = TMODE_BOLD_LEVEL;
+ } else if (midrow && (m & TMODE_STRIKE) != 0)
pix = 1;
+
if (iblink) {
if (!pix)
pix = olevel;
return 1;
}
-
#include "analogtv.h"
-#define TMODE_INVERSE (1 << 0)
-#define TMODE_BLINK (1 << 1)
-#define TMODE_BOLD (1 << 2)
-#define TMODE_UNDERLINE (1 << 3)
-#define TMODE_DIM (1 << 4)
-#define TMODE_GFX (1 << 5)
-/* We implement these with inverse and dim */
-#define TMODE_FGCOLOR (1 << 6)
-#define TMODE_BGCOLOR (1 << 7)
+/* Text attributes */
+
+#define TMODE_BOLD (1L << 0)
+#define TMODE_DIM (1L << 1)
+#define TMODE_ITALIC (1L << 2)
+#define TMODE_UNDERLINE (1L << 3)
+#define TMODE_BLINK (1L << 4)
+#define TMODE_INVERSE (1L << 5)
+#define TMODE_INVISIBLE (1L << 6)
+#define TMODE_STRIKE (1L << 7)
+#define TMODE_DUNDERLINE (1L << 8)
+#define TMODE_GFX (1L << 9)
+/* We implement these pseudocolors with attributes */
+#define TMODE_FGCOLOR (1L << 10)
+#define TMODE_BGCOLOR (1L << 11)
#define TMODE_NORMAL_LEVEL (ANALOGTV_WHITE_LEVEL - 35)
#define TMODE_BOLD_LEVEL (ANALOGTV_WHITE_LEVEL + 25)
typedef struct analogterm_state {
unsigned char hireslines[192][80];
unsigned char textlines_char[25][80]; /* XXX Use definition/macro */
- unsigned char textlines_mode[25][80];
+ uint16_t textlines_mode[25][80];
int gr_text;
enum {
A2_GR_FULL=1,
} gr_mode;
int cursx;
int cursy;
- int mode;
+ uint16_t mode;
int blink; /* XXX Still needed? */
int scroll_top, scroll_bottom;
int lastchar;
int len, char type);
void at_scroll_range(analogterm_state_t *st, int offset);
void at_scroll(analogterm_state_t *st);
-void at_printc(analogterm_state_t *st, char c, unsigned char m);
-void at_printc_noscroll(analogterm_state_t *st, char c, unsigned char m);
-void at_prints(analogterm_state_t *st, char *s, unsigned char m);
+void at_printc(analogterm_state_t *st, char c, uint16_t m);
+void at_printc_noscroll(analogterm_state_t *st, char c, uint16_t m);
+void at_prints(analogterm_state_t *st, char *s, uint16_t m);
void at_goto(analogterm_state_t *st, int r, int c);
void at_cls(analogterm_state_t *st);
void at_clear_hgr(analogterm_state_t *st);