From 2d3982b994fbd07334a88d2791d1eb35d62f431c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A8Rene=20Richarz?= <¨rene.richarz@bluewin.ch¨> Date: Sat, 13 Apr 2019 12:19:45 +0200 Subject: [PATCH] full implementation of Tektronix 4014 decoder --- README.md | 3 +- ards.c | 2 +- main.c | 6 +- tek4010 | Bin 35344 -> 39548 bytes tek4010.c | 243 ++++++++++++++++++++++++++++++--------------------- tube.c | 20 +++-- tube.h | 5 +- versions.txt | 7 +- 8 files changed, 167 insertions(+), 119 deletions(-) diff --git a/README.md b/README.md index 62ed8f3..eb3c528 100644 --- a/README.md +++ b/README.md @@ -263,7 +263,7 @@ module. If called with the -full option, the tek4010 emulator creates creates a full screen window, and uses the full 4K resolution of the 4014 with enhanced graphics module installed, scaled down to the actual window size. -Use control-q close the tek4010 window. This option is experimental. +Use control-q to close the tek4010 window. This option is experimental. **Compiling the tek4010 project** @@ -274,6 +274,7 @@ If you want to compile the project, you need to install "libgtk-3-dev": There is a make file in the repo. **Version** + See [versions.txt](versions.txt) diff --git a/ards.c b/ards.c index c1ba131..0b52dca 100755 --- a/ards.c +++ b/ards.c @@ -80,7 +80,7 @@ void ards_draw(cairo_t *cr, cairo_t *cr2, int first) tube_clearSecond(cr2); // clear persistent surface, if necessary - if (globaltube_clearPersistent) { + if (tube_doClearPersistent) { tube_clearPersistent(cr,cr2); } diff --git a/main.c b/main.c index 871bae6..770739a 100644 --- a/main.c +++ b/main.c @@ -58,7 +58,7 @@ extern int argARDS; int windowWidth; int windowHeight; -int globaltube_clearPersistent; +extern int tube_doClearPersistent; static void do_drawing(cairo_t *, GtkWidget *); @@ -131,7 +131,7 @@ static void on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_da (event->keyval == 0xFF55) || // "page up" key (event->keyval == 0xFF56)) // "page down" key { - globaltube_clearPersistent = 1; + tube_doClearPersistent = 1; gtk_widget_queue_draw(widget); return; } @@ -142,7 +142,7 @@ static void on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_da else if (event->state & GDK_CONTROL_MASK) { if ((event->keyval == 0xFF51) || // "left arrow" key (event->keyval == 0xFF52)) { // "up arrow" key - globaltube_clearPersistent = 1; + tube_doClearPersistent = 1; gtk_widget_queue_draw(widget); return; } diff --git a/tek4010 b/tek4010 index 3bbaf2e3c70ee3cac07cff7e53a55a0e3ee31d5c..dc8b1a104ed308c77629bfd34da1c7421a4661da 100755 GIT binary patch delta 13719 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 delta 13008 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 (windowHeight - vDotsPerChar)) tube_y0 = windowHeight - vDotsPerChar; } -void tek4010_escapeCodeHandler(cairo_t *cr, cairo_t *cr2, int ch) -// handle escape sequencies +void tek4010_bell() +{ + // bell function, delay 0.1 sec + tube_u100ResetSeconds(1); + usleep(50000); + showCursor=0; + todo = 0; +} + +void tek4010_escapeCodeHandler(cairo_t *cr, cairo_t *cr2, int ch) +// handle escape sequencies, see 4014 user manual, table page G-1 +// codes identical for all modes are handled elsewhere { - if (DEBUG) printf("Escape mode, ch=%02X\n",ch); switch (ch) { - case 0: break; + case 0: break; // ignore filler 0 + case 5: // ENQ: ask for status and position // not yet implemented, needs to send 7 bytes - printf("ENQ not implemented\n"); - break; - case 12: - if (DEBUG) printf("Form feed, clear screen\n"); + printf("ENQ not supported, ignored\n"); + mode = 0; break; + case 6: break; + + case 8: // backspace during ESC + tube_x0 -= hDotsPerChar; + tek4010_checkLimits(); + mode = 0; break; + case 9: // tab during ESC + if (argTab1) + tube_x0 += hDotsPerChar; + else + tube_x0 = tube_x0 - (tube_x0 % (8 * hDotsPerChar)) + 8 * hDotsPerChar; + tek4010_checkLimits(); + mode = 0; break; + + case 11:// VT during ESC, move one line up + tube_y0 += vDotsPerChar; + tek4010_checkLimits(); + mode = 0; break; + case 12:// FF during ESC tube_changeCharacterSize(cr, cr2, 74, 35, (int) (18.0 * efactor)); tube_clearPersistent(cr,cr2); - mode = 0; - break; - case '[': - // a second escape code follows, do not reset mode - break; - + mode = 0; break; + case 13:mode = 0; break; case 14: // SO activate alternative char set, not implemented - case 15: // SI deactivate alternative char set - mode = 0; + case 15: // SI deactivate alternative char set, not implemented break; - + case 23: system("scrot --focussed"); mode= 0; break; - - case 28: // file separator >> point plot mode - mode = 5; - plotPointMode= 1; + + case 26: // sub + printf("GIN mode not supported, ignored\n"); + mode = 50; break; - case 29: // group separator >> graphics mode - mode = 1; - plotPointMode = 0; + // modes 27 and 29 - 31 are identical in all modes + case 28: // record sepatator + printf("Special point plot mode not supported, ignored\n"); + mode = 50; break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': printf("esc %c\n", ch); mode = 31; break; + case '8': tube_changeCharacterSize(cr, cr2, 74, 35, (int)(efactor * 18)); break; case '9': tube_changeCharacterSize(cr, cr2, 81, 38, (int)(efactor * 16)); break; case ':': tube_changeCharacterSize(cr, cr2, 121, 58, (int)(efactor * 11)); break; case ';': tube_changeCharacterSize(cr, cr2, 133, 64, (int)(efactor * 10)); break; - case ']': printf("esc %c\n", ch); break; - case 'm': mode = 0; break; + case '[': // a second escape code follows, do not reset mode + break; + + // normal mode case '`': ltype = SOLID; writeThroughMode = 0; mode = 0; break; case 'a': ltype = DOTTED; writeThroughMode = 0; mode = 0; break; case 'b': ltype = DOTDASH; writeThroughMode = 0; mode = 0; break; case 'c': ltype = SHORTDASH;writeThroughMode = 0; mode = 0; break; case 'd': ltype = LONGDASH; writeThroughMode = 0; mode = 0; break; case 'e': ltype = SOLID; writeThroughMode = 0; mode = 0; break; - case 'f': ltype = SOLID; writeThroughMode = 0; mode = 0; break; - case 'h': ltype = SOLID; writeThroughMode = 0; mode = 0; break; - + case 'f': ltype = SOLID; writeThroughMode = 0; mode = 0; break; + case 'g': ltype = SOLID; writeThroughMode = 0; mode = 0; break; + + // defocussed mode + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': printf("Defocussed mode ESC %c not supported, ignored\n", ch); mode = 101; break; + + // write-trough mode case 'p': ltype = SOLID; writeThroughMode = 1; mode = 101; showCursor = 0; break; case 'q': ltype = DOTTED; writeThroughMode = 1; mode = 101; showCursor = 0; break; case 'r': ltype = DOTDASH; writeThroughMode = 1; mode = 101; showCursor = 0; break; @@ -162,21 +190,28 @@ void tek4010_escapeCodeHandler(cairo_t *cr, cairo_t *cr2, int ch) case 'w': ltype = SOLID; writeThroughMode = 1; mode = 101; showCursor = 0; break; default: - printf("Escape code %02X not implemented, mode = %d\n",ch, savemode); + printf("ESC %d not supported, ignored\n",ch); mode = 0; break; } } - -int tek4010_checkExitFromGraphics(int ch) -// test for exit from graphics character +int tek4010_checkReturnToAlpha(int ch) +// test for return to alpha character set +// see 4014 manual, page F-10, note 1 { if ((ch==31) || (ch==13) || (ch==27) || (ch==12)) { + if (DEBUG && mode) printf("Going to alpha mode\n"); mode = 0; - if (DEBUG) printf("Leaving graphics mode\n"); showCursor = 0; - if (ch == 12) globaltube_clearPersistent = 1; + if (ch == 12) { + tube_doClearPersistent = 1; + todo = 0; + } + if (ch == 27) { + mode = 30; + todo = 0; + } plotPointMode = 0; return 1; } @@ -223,7 +258,7 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int first) tube_clearSecond(cr2); // clear persistent surface, if necessary - if (globaltube_clearPersistent) { + if (tube_doClearPersistent) { tube_clearPersistent(cr,cr2); tube_changeCharacterSize(cr, cr2, 74, 35, (int) (18.0 * efactor)); } @@ -256,35 +291,62 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int first) if ((ch>0x20)&&(ch<=0x7E)) printf(" (%c)",ch); printf("\n"); } + + if (tek4010_checkReturnToAlpha(ch)) { + todo = todo - 4; + goto endDo; + } + + // the following chars are identical in all modes (with exception: 13,28) + // see 4014 user manual, table on page G1 ff - if (mode == 31) { - printf("ANSI escape mode 31, ch=%02x\n",ch); - if ((ch>='0') && (ch<='9')) { savemode = mode; mode = 30; } + switch (ch) { + case 7: tek4010_bell(); + goto endDo; + case 10: // new line + tube_y0 -= vDotsPerChar; + if (!argRaw) tube_x0 = leftmargin; + tek4010_checkLimits(); + goto endDo; + case 13: // return + if (mode != 30) { // special handling in ESC mode + mode = 0; tube_x0 = leftmargin; + goto endDo; + } + break; + case 27: // escape code, all modes + savemode = mode; + mode = 30; + goto endDo; + case 28: // file separator >> point plot mode + if (mode != 30) { // special handling in ESC mode + mode = 5; + plotPointMode= 1; + goto endDo; + } + break; + case 29: // group separator >> graphics mode + mode = 1; + plotPointMode = 0; + goto endDo; + case 30: // record separator >> incremental mode + printf("Special point plot mode not supported, ignored\n"); + mode = 40; + goto endDo; + case 31: // US, normal mode + mode = 0; + goto endDo; } - if (ch == 27) { // escape code - savemode = mode; - mode = 30; return; - } - if (ch == 30) { - printf("Incremental plot mode not implemented\n"); - mode = 40; return; - } + // handle skipping coordinate bytes + // this cannot be done in switch(mode) below, because multiple bytes + // can be skipped and the current byte must be executed after a mode change int tag = (ch >> 5) & 3; if ((mode >= 1) && (mode <= 8)) { - if (tek4010_checkExitFromGraphics(ch)) { - todo = todo - 4; - goto endDo; - } - - // handle skipped coordinate bytes - // this cannot be done in switch(mode) below, because multiple bytes - // can be switched and the current byte must be executed after a mode change - if ((mode == 5) && (ch == 29)) { if (DEBUG) printf("group separator, go from mode 5 to mode 1\n"); mode = 1; @@ -293,10 +355,10 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int first) if (DEBUG) { if (mode & 1) - printf("mode=%d,tag=%d-H-val=%d,", + printf(" mode=%d,tag=%d-H-val=%d,", mode,tag, 32 * (ch & 31)); else - printf("mode=%d,tag=%d-L-val=%d,", + printf(" mode=%d,tag=%d-L-val=%d,", mode,tag, ch & 31); printf("xh=%d,xl=%d,yh=%d,yl=%d\n",xh,xl,yh,yl); } @@ -340,6 +402,9 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int first) } } + + + // handling anything specific to a mode switch (mode) { case 1: plotPointMode = 0; // normal graphics mode, starting coordinates @@ -425,22 +490,19 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int first) tek4010_escapeCodeHandler(cr, cr2, ch); break; case 40: // incremental plot mode, not implemented - if (ch == 31) mode = 0; // leave this mode + tek4010_checkReturnToAlpha(ch); // check for exit break; + case 50: // incremental plot mode, not implemented + tek4010_checkReturnToAlpha(ch); // check for exit + break; case 101: if (DEBUG) printf("Ignore until group separator, ch = %02x\n", ch); if (ch == 29) mode = 1; break; - default: + case 0: // handle ALPHA mode; 4014 user manual, table page G-1 + // some characters are indentical for all modes and handled elsewhere switch (ch) { case 0: break; - case 7: // bell function, delay 0.1 sec - // cannot delay if bright spot is on, needs to be turned off first - tube_u100ResetSeconds(1); - usleep(50000); - showCursor=0; - todo = 0; - break; case 8: // backspace tube_x0 -= hDotsPerChar; tek4010_checkLimits(); @@ -452,43 +514,24 @@ void tek4010_draw(cairo_t *cr, cairo_t *cr2, int first) tube_x0 = tube_x0 - (tube_x0 % (8 * hDotsPerChar)) + 8 * hDotsPerChar; tek4010_checkLimits(); break; - case 10: // new line - tube_y0 -= vDotsPerChar; - if (!argRaw) tube_x0 = leftmargin; - tek4010_checkLimits(); - break; case 11: // VT, move one line up tube_y0 += vDotsPerChar; tek4010_checkLimits(); break; - case 13: // return - mode = 0; tube_x0 = leftmargin; - break; case 23: // ctrl-w screen dump system("scrot --focussed"); break; - case 28: // file separator >> point plot mode - mode = 5; - plotPointMode= 1; - break; - case 29: // group separator - mode = 1; - break; - case 30: // record separator - mode = 40; - break; - case 31: // US, leave graphics mode - mode = 0; - break; + default: if ((ch >= 32) && (ch <127)) { // printable character tek4010_checkLimits(); - tube_drawCharacter(cr,cr2, ch); - + tube_drawCharacter(cr,cr2, ch); todo-= 2; } break; } - break; + break; + default: printf("Illegal mode - this is a tek4010decoder error and should not happen\n"); + break; } endDo:; } diff --git a/tube.c b/tube.c index 44b8dc0..1b6108c 100755 --- a/tube.c +++ b/tube.c @@ -51,7 +51,6 @@ #include "tube.h" extern void gtk_main_quit(); -extern int globaltube_clearPersistent; extern int windowWidth; extern int windowHeight; extern char *windowName; @@ -75,6 +74,7 @@ double dashset[] = {2,6,2,2,6,3,3,3,6,6}; int plotPointMode = 0; // plot point mode int writeThroughMode = 0; // write through mode +int tube_doClearPersistent; int tube_x0, tube_x2,tube_y0, tube_y2; @@ -162,7 +162,6 @@ int tube_getInputChar() if (t < charResetCount * characterInterval) return -1; // there is time to refresh the screen int c = getc(getData) & 0x7F; - if (DEBUG) printf(">>%02X<<",c); charCount++; charResetCount++; lastTime = t; @@ -259,7 +258,7 @@ void tube_init(int argc, char* argv[]) if (DEBUG) printf("character_interval = %0.1f msec\n",(double)characterInterval/10.0); - globaltube_clearPersistent = 1; + tube_doClearPersistent = 1; // create pipes for communication between parent and child if (pipe(getDataPipe) == -1) { @@ -403,7 +402,7 @@ void tube_clearPersistent(cairo_t *cr, cairo_t *cr2) { cairo_set_source_rgb(cr, BLACK_COLOR); cairo_paint(cr); - globaltube_clearPersistent = 0; + tube_doClearPersistent = 0; tube_x0 = 0; tube_y0 = windowHeight - vDotsPerChar; tube_x2 = tube_x0; @@ -470,19 +469,19 @@ void tube_drawCharacter(cairo_t *cr, cairo_t *cr2, char ch) if (writeThroughMode) { // draw the write-through character cairo_set_source_rgb(cr2, 0, WRITE_TROUGH_INTENSITY, 0); - cairo_move_to(cr2, tube_x0 + eoffx, windowHeight - tube_y0 + 4); + cairo_move_to(cr2, tube_x0 + eoffx, windowHeight - tube_y0); cairo_show_text(cr2, s); } else { // draw the character cairo_set_source_rgb(cr, 0, NORMAL_INTENSITY, 0); - cairo_move_to(cr, tube_x0 + eoffx, windowHeight - tube_y0 + 4); + cairo_move_to(cr, tube_x0 + eoffx, windowHeight - tube_y0); cairo_show_text(cr, s); // draw the bright spot cairo_set_source_rgb(cr2, BRIGHT_SPOT_COLOR); - cairo_move_to(cr2, tube_x0 + eoffx, windowHeight - tube_y0 + 4); + cairo_move_to(cr2, tube_x0 + eoffx, windowHeight - tube_y0); cairo_show_text(cr2, s); } @@ -531,8 +530,11 @@ void tube_drawPoint(cairo_t *cr, cairo_t *cr2) void tube_drawVector(cairo_t *cr, cairo_t *cr2) { - if (DEBUG) printf("******************************************** Drawing to (%d,%d)\n",tube_x2,tube_y2); - + if (DEBUG) { + printf("********************************************"); + printf("Drawing from (%d,%d) to (%d,%d), writethrough = %d\n", + tube_x0, tube_y0, tube_x2, tube_y2, writeThroughMode); + } tube_emulateDeflectionTime(); if ((tube_x2 == tube_x0) && (tube_y2 == tube_y0)) tube_x0++; // cairo cannot draw a dot diff --git a/tube.h b/tube.h index acc69b1..3329f46 100644 --- a/tube.h +++ b/tube.h @@ -3,7 +3,7 @@ enum LineType {SOLID,DOTTED,DOTDASH,SHORTDASH,LONGDASH}; extern enum LineType ltype; -extern int globaltube_clearPersistent; +extern int tube_doClearPersistent; extern int windowWidth; extern int windowHeight; @@ -21,7 +21,7 @@ extern int showCursor; // set of cursor is shown (not set in gra extern int isBrightSpot; // set if there is currently a bright spot on the screen extern int plotPointMode; -int writeThroughMode; +extern int writeThroughMode; extern double efactor; extern int eoffx; @@ -33,7 +33,6 @@ extern long tube_u100ResetSeconds(int reset); extern void tube_doCursor(cairo_t *cr2); extern void tube_clearPersistent(cairo_t *cr, cairo_t *cr2); extern void tube_clearSecond(cairo_t *cr2); -extern void tube_clearPersistent(cairo_t *cr, cairo_t *cr2); extern int tube_isInput(); extern int tube_getInputChar(); extern void tube_emulateDeflectionTime(); diff --git a/versions.txt b/versions.txt index 9d64b04..3ad2b06 100644 --- a/versions.txt +++ b/versions.txt @@ -2,11 +2,14 @@ Next version t.b.b ================== New features - variable character size, set with ESC sequencies, reset if screen is cleared - +Bug fixes +- vertical position of characters corrected +- full implementation of Tektronix 4014 decoder +Appearance: Version 1.1 April 12, 2019 ========================== -Phase: Fist offical release +Phase: First offical release Version 1.0.3 April 11, 2019 ============================