| /* |
| * $Id: type340.c,v 1.5 2004/01/24 20:52:16 phil Exp $ |
| * Simulator Independent DEC Type 340 Graphic Display Processor Simulation |
| * Phil Budne <phil@ultimate.com> |
| * September 20, 2003 |
| * from vt11.c |
| * |
| * Information from DECUS 7-13 |
| * http://www.spies.com/~aek/pdf/dec/pdp7/7-13_340displayProgMan.pdf |
| */ |
| |
| /* |
| * Copyright (c) 2003-2004, Philip L. Budne |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included in |
| * all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
| * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| * |
| * Except as contained in this notice, the name of the author shall |
| * not be used in advertising or otherwise to promote the sale, use or |
| * other dealings in this Software without prior written authorization |
| * from the authors. |
| */ |
| |
| #include "display.h" /* XY plot interface */ |
| |
| /* |
| * The Type 340 was used on the PDP-{4,6,7,9,10} |
| * and used 18-bit words, with bits numbered 0 thru 17 |
| * (most significant to least) |
| */ |
| |
| #define BITMASK(N) (1<<(17-(N))) |
| |
| /* mask for a field */ |
| #define FIELDMASK(START,END) ((1<<((END)-(START)+1))-1) |
| |
| /* extract a field */ |
| #define GETFIELD(W,START,END) (((W)>>(17-(END)))&FIELDMASK(START,END)) |
| |
| /* extract a 1-bit field */ |
| #define TESTBIT(W,B) (((W) & BITMASK(B)) != 0) |
| |
| #ifdef DEBUG_TY340 |
| #define DEBUGF(X) printf X |
| #else |
| #define DEBUGF(X) |
| #endif |
| |
| typedef long ty340word; |
| |
| static ty340word DAC; /* Display Address Counter */ |
| static unsigned char shift; /* 1 bit */ |
| static enum mode mode; /* 3 bits */ |
| static int scale; /* 2 bits */ |
| |
| enum mode { PARAM=0, POINT, SLAVE, CHAR, VECTOR, VCONT, INCR, SUBR }; |
| |
| enum jump_type { DJP=2, DJS=3, DDS=1 }; |
| static ty340word ASR; /* Address Save Register */ |
| static unsigned char save_ff; /* "save" flip-flop */ |
| |
| static unsigned char intensity; /* 3 bits */ |
| static unsigned char lp_ena; /* 1 bit */ |
| |
| /* kept signed for raster violation checking */ |
| static short xpos, ypos; /* 10 bits, signed */ |
| static unsigned char sequence; /* 2 bits */ |
| |
| /* XXX make defines public for 340_cycle return */ |
| #define STOPPED 01 |
| #define LPHIT 02 |
| #define VEDGE 04 |
| #define HEDGE 010 |
| static unsigned char status = STOPPED; |
| |
| /* |
| * callbacks into PDP-6/10 simulator |
| */ |
| extern ty340word ty340_fetch(ty340word); |
| extern void ty340_store(ty340word, ty340word); |
| extern void ty340_stop_int(void); |
| extern void ty340_lp_int(void); |
| |
| void |
| ty340_set_dac(ty340word addr) |
| { |
| DAC = addr; |
| mode = 0; |
| DEBUGF(("set DAC %06\r\n", DAC)); |
| status = 0; /* XXX just clear stopped? */ |
| /* XXX clear other stuff? save_ff? */ |
| } |
| |
| void |
| ty340_reset(void) |
| { |
| /* XXX call display layer? destroy window? */ |
| xpos = ypos = 0; |
| status = STOPPED; |
| } |
| |
| static int |
| point(int x, int y, int seq) |
| { |
| int i; |
| |
| /* XXX apply scale? */ |
| |
| i = DISPLAY_INT_MAX-7+intensity; |
| if (i <= 0) |
| i = 1; |
| |
| if (x < 0 || x > 1023) { |
| status |= VEDGE; |
| return 0; |
| } |
| if (y < 0 || y > 1023) { |
| status |= HEDGE; |
| return 0; |
| } |
| |
| if (display_point(x, y, i, 0)) { |
| if (lp_ena) { |
| /* XXX save location? */ |
| status |= LPHIT; |
| sequence = seq; |
| } |
| } |
| } |
| |
| /* |
| * two-step algorithm, developed by Xiaolin Wu |
| * from http://graphics.lcs.mit.edu/~mcmillan/comp136/Lecture6/Lines.html |
| */ |
| |
| /* |
| * The two-step algorithm takes the interesting approach of treating |
| * line drawing as a automaton, or finite state machine. If one looks |
| * at the possible configurations for the next two pixels of a line, |
| * it is easy to see that only a finite set of possibilities exist. |
| * The two-step algorithm shown here also exploits the symmetry of |
| * line-drawing by simultaneously drawn from both ends towards the |
| * midpoint. |
| */ |
| |
| static void |
| lineTwoStep(int x0, int y0, int x1, int y1) |
| { |
| int dy = y1 - y0; |
| int dx = x1 - x0; |
| int stepx, stepy; |
| |
| if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; } |
| if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; } |
| |
| lpoint(x0,y0); |
| if (dx == 0 && dy == 0) /* following algorithm won't work */ |
| return; /* just the one dot */ |
| lpoint(x1, y1); |
| if (dx > dy) { |
| int length = (dx - 1) >> 2; |
| int extras = (dx - 1) & 3; |
| int incr2 = (dy << 2) - (dx << 1); |
| if (incr2 < 0) { |
| int c = dy << 1; |
| int incr1 = c << 1; |
| int d = incr1 - dx; |
| int i; |
| |
| for (i = 0; i < length; i++) { |
| x0 += stepx; |
| x1 -= stepx; |
| if (d < 0) { /* Pattern: */ |
| lpoint(x0, y0); |
| lpoint(x0 += stepx, y0); /* x o o */ |
| lpoint(x1, y1); |
| lpoint(x1 -= stepx, y1); |
| d += incr1; |
| } |
| else { |
| if (d < c) { /* Pattern: */ |
| lpoint(x0, y0); /* o */ |
| lpoint(x0 += stepx, y0 += stepy); /* x o */ |
| lpoint(x1, y1); |
| lpoint(x1 -= stepx, y1 -= stepy); |
| } else { |
| lpoint(x0, y0 += stepy); /* Pattern: */ |
| lpoint(x0 += stepx, y0); /* o o */ |
| lpoint(x1, y1 -= stepy); /* x */ |
| lpoint(x1 -= stepx, y1); |
| } |
| d += incr2; |
| } |
| } |
| if (extras > 0) { |
| if (d < 0) { |
| lpoint(x0 += stepx, y0); |
| if (extras > 1) lpoint(x0 += stepx, y0); |
| if (extras > 2) lpoint(x1 -= stepx, y1); |
| } else |
| if (d < c) { |
| lpoint(x0 += stepx, y0); |
| if (extras > 1) lpoint(x0 += stepx, y0 += stepy); |
| if (extras > 2) lpoint(x1 -= stepx, y1); |
| } else { |
| lpoint(x0 += stepx, y0 += stepy); |
| if (extras > 1) lpoint(x0 += stepx, y0); |
| if (extras > 2) lpoint(x1 -= stepx, y1 -= stepy); |
| } |
| } |
| } else { |
| int c = (dy - dx) << 1; |
| int incr1 = c << 1; |
| int d = incr1 + dx; |
| int i; |
| for (i = 0; i < length; i++) { |
| x0 += stepx; |
| x1 -= stepx; |
| if (d > 0) { |
| lpoint(x0, y0 += stepy); /* Pattern: */ |
| lpoint(x0 += stepx, y0 += stepy); /* o */ |
| lpoint(x1, y1 -= stepy); /* o */ |
| lpoint(x1 -= stepx, y1 -= stepy); /* x */ |
| d += incr1; |
| } else { |
| if (d < c) { |
| lpoint(x0, y0); /* Pattern: */ |
| lpoint(x0 += stepx, y0 += stepy); /* o */ |
| lpoint(x1, y1); /* x o */ |
| lpoint(x1 -= stepx, y1 -= stepy); |
| } else { |
| lpoint(x0, y0 += stepy); /* Pattern: */ |
| lpoint(x0 += stepx, y0); /* o o */ |
| lpoint(x1, y1 -= stepy); /* x */ |
| lpoint(x1 -= stepx, y1); |
| } |
| d += incr2; |
| } |
| } |
| if (extras > 0) { |
| if (d > 0) { |
| lpoint(x0 += stepx, y0 += stepy); |
| if (extras > 1) lpoint(x0 += stepx, y0 += stepy); |
| if (extras > 2) lpoint(x1 -= stepx, y1 -= stepy); |
| } else if (d < c) { |
| lpoint(x0 += stepx, y0); |
| if (extras > 1) lpoint(x0 += stepx, y0 += stepy); |
| if (extras > 2) lpoint(x1 -= stepx, y1); |
| } else { |
| lpoint(x0 += stepx, y0 += stepy); |
| if (extras > 1) lpoint(x0 += stepx, y0); |
| if (extras > 2) { |
| if (d > c) |
| lpoint(x1 -= stepx, y1 -= stepy); |
| else |
| lpoint(x1 -= stepx, y1); |
| } |
| } |
| } |
| } |
| } else { |
| int length = (dy - 1) >> 2; |
| int extras = (dy - 1) & 3; |
| int incr2 = (dx << 2) - (dy << 1); |
| if (incr2 < 0) { |
| int c = dx << 1; |
| int incr1 = c << 1; |
| int d = incr1 - dy; |
| int i; |
| for (i = 0; i < length; i++) { |
| y0 += stepy; |
| y1 -= stepy; |
| if (d < 0) { |
| lpoint(x0, y0); |
| lpoint(x0, y0 += stepy); |
| lpoint(x1, y1); |
| lpoint(x1, y1 -= stepy); |
| d += incr1; |
| } else { |
| if (d < c) { |
| lpoint(x0, y0); |
| lpoint(x0 += stepx, y0 += stepy); |
| lpoint(x1, y1); |
| lpoint(x1 -= stepx, y1 -= stepy); |
| } else { |
| lpoint(x0 += stepx, y0); |
| lpoint(x0, y0 += stepy); |
| lpoint(x1 -= stepx, y1); |
| lpoint(x1, y1 -= stepy); |
| } |
| d += incr2; |
| } |
| } |
| if (extras > 0) { |
| if (d < 0) { |
| lpoint(x0, y0 += stepy); |
| if (extras > 1) lpoint(x0, y0 += stepy); |
| if (extras > 2) lpoint(x1, y1 -= stepy); |
| } else |
| if (d < c) { |
| lpoint(x0, y0 += stepy); |
| if (extras > 1) lpoint(x0 += stepx, y0 += stepy); |
| if (extras > 2) lpoint(x1, y1 -= stepy); |
| } else { |
| lpoint(x0 += stepx, y0 += stepy); |
| if (extras > 1) lpoint(x0, y0 += stepy); |
| if (extras > 2) lpoint(x1 -= stepx, y1 -= stepy); |
| } |
| } |
| } else { |
| int c = (dx - dy) << 1; |
| int incr1 = c << 1; |
| int d = incr1 + dy; |
| int i; |
| for (i = 0; i < length; i++) { |
| y0 += stepy; |
| y1 -= stepy; |
| if (d > 0) { |
| lpoint(x0 += stepx, y0); |
| lpoint(x0 += stepx, y0 += stepy); |
| lpoint(x1 -= stepy, y1); |
| lpoint(x1 -= stepx, y1 -= stepy); |
| d += incr1; |
| } else { |
| if (d < c) { |
| lpoint(x0, y0); |
| lpoint(x0 += stepx, y0 += stepy); |
| lpoint(x1, y1); |
| lpoint(x1 -= stepx, y1 -= stepy); |
| } else { |
| lpoint(x0 += stepx, y0); |
| lpoint(x0, y0 += stepy); |
| lpoint(x1 -= stepx, y1); |
| lpoint(x1, y1 -= stepy); |
| } |
| d += incr2; |
| } |
| } |
| if (extras > 0) { |
| if (d > 0) { |
| lpoint(x0 += stepx, y0 += stepy); |
| if (extras > 1) lpoint(x0 += stepx, y0 += stepy); |
| if (extras > 2) lpoint(x1 -= stepx, y1 -= stepy); |
| } else if (d < c) { |
| lpoint(x0, y0 += stepy); |
| if (extras > 1) lpoint(x0 += stepx, y0 += stepy); |
| if (extras > 2) lpoint(x1, y1 -= stepy); |
| } else { |
| lpoint(x0 += stepx, y0 += stepy); |
| if (extras > 1) lpoint(x0, y0 += stepy); |
| if (extras > 2) { |
| if (d > c) |
| lpoint(x1 -= stepx, y1 -= stepy); |
| else |
| lpoint(x1, y1 -= stepy); |
| } |
| } |
| } |
| } |
| } |
| } /* lineTwoStep */ |
| |
| static int |
| vector(int i, int sx, int dx, int sy, int dy) |
| { |
| int x0, y0, x1, y1; |
| |
| x0 = xpos; |
| y0 = ypos; |
| |
| if (sx) { |
| x1 = x0 - dx; |
| if (x1 < 0) /* XXX TEMP? */ |
| x1 = 0; |
| } |
| else { |
| x1 = x0 + dx; |
| if (x1 > 1023) /* XXX TEMP? */ |
| x1 = 1023; |
| } |
| |
| if (sy) { |
| y1 = y0 - dy; |
| if (y1 < 0) /* XXX TEMP? */ |
| y1 = 0; |
| } |
| else { |
| y1 = y0 + dy; /* XXX TEMP? */ |
| if (y1 > 1023) |
| y1 = 1023; |
| } |
| |
| DEBUGF(("vector i%d (%d,%d) to (%d,%d)\r\n", i, x0, y0, x1, y1)); |
| if (i) |
| lineTwoStep(x0, y0, x1, y1); |
| |
| xpos = x1; |
| ypos = y1; |
| return 0; |
| } |
| |
| /* return true on raster violation */ |
| int |
| ipoint(int i, int n, unsigned char byte) |
| { |
| if (byte & 010) { /* left/right */ |
| if (byte & 04) { |
| if (xpos == 0) { |
| status |= VEDGE; |
| return 1; |
| } |
| xpos--; |
| } |
| else { |
| if (xpos == 1023) { |
| status |= VEDGE; |
| return 1; |
| } |
| xpos++; |
| } |
| } |
| if (byte & 02) { /* up/down */ |
| if (byte & 04) { |
| if (ypos == 0) { |
| status |= HEDGE; |
| return 1; |
| } |
| ypos--; |
| } |
| else { |
| if (ypos == 1023) { |
| status |= HEDGE; |
| return 1; |
| } |
| ypos++; |
| } |
| } |
| if (i) |
| point(xpos, ypos, n); |
| |
| return 0; |
| } |
| |
| /* |
| * 342 character generator - first 64 characters (from manual) |
| */ |
| static const unsigned char chars[64][5] = { |
| { 0070, 0124, 0154, 0124, 0070 }, /* 00 */ |
| { 0174, 0240, 0240, 0240, 0174 }, /* 01 A */ |
| { 0376, 0222, 0222, 0222, 0154 }, /* 02 B */ |
| { 0174, 0202, 0202, 0202, 0104 }, /* 03 C */ |
| { 0376, 0202, 0202, 0202, 0174 }, /* 04 D */ |
| { 0376, 0222, 0222, 0222, 0222 }, /* 05 E */ |
| { 0376, 0220, 0220, 0220, 0220 }, /* 06 F */ |
| { 0174, 0202, 0222, 0222, 0134 }, /* 07 G */ |
| { 0376, 0020, 0020, 0020, 0376 }, /* 10 H */ |
| { 0000, 0202, 0376, 0202, 0000 }, /* 11 I */ |
| { 0004, 0002, 0002, 0002, 0374 }, /* 12 J */ |
| { 0376, 0020, 0050, 0104, 0202 }, /* 13 K */ |
| { 0376, 0002, 0002, 0002, 0002 }, /* 14 K */ |
| { 0374, 0100, 0040, 0100, 0374 }, /* 15 M */ |
| { 0376, 0100, 0040, 0020, 0376 }, /* 16 N */ |
| { 0174, 0202, 0202, 0202, 0174 }, /* 17 O */ |
| { 0376, 0220, 0220, 0220, 0140 }, /* 20 P */ |
| { 0174, 0202, 0212, 0206, 0176 }, /* 21 Q */ |
| { 0376, 0220, 0230, 0224, 0142 }, /* 22 R */ |
| { 0144, 0222, 0222, 0222, 0114 }, /* 23 S */ |
| { 0200, 0200, 0376, 0200, 0200 }, /* 24 T */ |
| { 0374, 0002, 0002, 0002, 0374 }, /* 25 U */ |
| { 0370, 0004, 0002, 0004, 0370 }, /* 26 V */ |
| { 0376, 0004, 0010, 0004, 0376 }, /* 27 W */ |
| { 0202, 0104, 0070, 0104, 0202 }, /* 30 X */ |
| { 0200, 0100, 0076, 0100, 0200 }, /* 31 Y */ |
| { 0226, 0232, 0222, 0262, 0322 }, /* 32 Z */ |
| { 0000, 0000, 0000, 0000, 0000 }, /* 33 LF */ |
| { 0000, 0000, 0000, 0000, 0000 }, /* 34 CR */ |
| { 0000, 0000, 0000, 0000, 0000 }, /* 35 HORIZ */ |
| { 0000, 0000, 0000, 0000, 0000 }, /* 36 VERT */ |
| { 0000, 0000, 0000, 0000, 0000 }, /* 37 ESC */ |
| { 0000, 0000, 0000, 0000, 0000 }, /* 40 space */ |
| { 0000, 0000, 0372, 0000, 0000 }, /* 41 ! */ |
| { 0000, 0340, 0000, 0340, 0000 }, /* 42 " */ |
| { 0050, 0376, 0050, 0376, 0050 }, /* 43 # */ |
| { 0144, 0222, 0376, 0222, 0114 }, /* 44 $ */ |
| { 0306, 0310, 0220, 0246, 0306 }, /* 45 % */ |
| { 0154, 0222, 0156, 0004, 0012 }, /* 46 & */ |
| { 0000, 0000, 0300, 0340, 0000 }, /* 47 ' */ |
| { 0070, 0104, 0202, 0000, 0000 }, /* 50 ( */ |
| { 0000, 0000, 0202, 0104, 0070 }, /* 51 ) */ |
| { 0124, 0070, 0174, 0070, 0124 }, /* 52 * */ |
| { 0020, 0020, 0174, 0020, 0020 }, /* 53 + */ |
| { 0000, 0014, 0016, 0000, 0000 }, /* 54 , */ |
| { 0020, 0020, 0020, 0020, 0020 }, /* 55 - */ |
| { 0000, 0006, 0006, 0000, 0000 }, /* 56 . */ |
| { 0004, 0010, 0020, 0040, 0100 }, /* 57 / */ |
| { 0174, 0212, 0222, 0242, 0174 }, /* 60 0 */ |
| { 0000, 0102, 0376, 0002, 0000 }, /* 61 1 */ |
| { 0116, 0222, 0222, 0222, 0142 }, /* 62 2 */ |
| { 0104, 0202, 0222, 0222, 0154 }, /* 63 3 */ |
| { 0020, 0060, 0120, 0376, 0020 }, /* 64 4 */ |
| { 0344, 0222, 0222, 0222, 0214 }, /* 65 5 */ |
| { 0174, 0222, 0222, 0222, 0114 }, /* 66 6 */ |
| { 0306, 0210, 0220, 0240, 0300 }, /* 67 7 */ |
| { 0154, 0222, 0222, 0222, 0154 }, /* 70 8 */ |
| { 0144, 0222, 0222, 0222, 0174 }, /* 71 9 */ |
| { 0000, 0066, 0066, 0000, 0000 }, /* 72 : */ |
| { 0000, 0154, 0156, 0000, 0000 }, /* 73 ; */ |
| { 0020, 0050, 0104, 0202, 0000 }, /* 74 < */ |
| { 0050, 0050, 0050, 0050, 0050 }, /* 75 = */ |
| { 0000, 0202, 0104, 0050, 0020 }, /* 76 > */ |
| { 0100, 0200, 0236, 0220, 0140 } /* 77 ? */ |
| }; |
| |
| /* |
| * type 342 Character/Symbol generator for type 340 display |
| * return true if ESCaped |
| */ |
| static int |
| character(int n, char c) |
| { |
| int x, y; |
| |
| switch (c) { |
| case 033: /* LF */ |
| if (ypos < 12) { |
| status |= HEDGE; |
| ypos = 0; |
| } |
| else |
| ypos -= 12; /* XXX scale? */ |
| |
| return 0; |
| case 034: /* CR */ |
| xpos = 0; |
| return 0; |
| case 035: /* shift in */ |
| shift = 1; |
| return 0; |
| case 036: /* shift out */ |
| shift = 0; |
| return 0; |
| case 037: /* escape */ |
| sequence = n; |
| return 1; |
| } |
| /* XXX plot character from character set selected by "shift" |
| * (offset index by 64?) |
| */ |
| for (x = 0; x < 5; x++) { |
| for (y = 0; y < 7; y++) { |
| if (chars[c][x] & (1<<y)) { |
| /* XXX check for raster violation? */ |
| point(xpos+x, ypos+y, n); /* XXX scale? */ |
| } |
| } |
| } |
| xpos += 7; /* XXX scale? */ |
| if (xpos > 1023) { |
| xpos = 1023; |
| status |= VEDGE; |
| } |
| return 0; |
| } |
| |
| int |
| ty340_cycle(int us, int slowdown) |
| { |
| ty340word inst, addr; |
| int i, escape, stopped; |
| |
| if (status & STOPPED) |
| return 0; /* XXX age display? */ |
| |
| inst = ty340_fetch(DAC); |
| DEBUGF(("%06o: %06o\r\n", DAC, inst)); |
| DAC++; |
| |
| escape = 0; |
| switch (mode) { |
| case PARAM: |
| mode = GETFIELD(inst, 2, 4); |
| |
| if (TESTBIT(inst, 5)) { /* load l.p. enable */ |
| lp_ena = TESTBIT(inst,6); |
| DEBUGF(("lp_ena %d\r\n", lp_ena)); |
| } |
| |
| if (TESTBIT(inst, 7)) { |
| status |= STOPPED; |
| if (TESTBIT(inst, 8)) |
| ty340_stop_int(); /* set stop_int_end? */ |
| } |
| |
| if (TESTBIT(inst, 11)) |
| scale = GETFIELD(inst, 12, 13); |
| |
| if (TESTBIT(inst, 14)) |
| intensity = GETFIELD(inst, 15, 17); |
| |
| break; |
| |
| case POINT: |
| mode = GETFIELD(inst, 2, 4); |
| |
| if (TESTBIT(inst, 5)) /* load l.p. enable */ |
| lp_ena = TESTBIT(inst,6); |
| |
| if (TESTBIT(inst, 1)) |
| ypos = GETFIELD(inst, 8, 17); |
| else |
| xpos = GETFIELD(inst, 8, 17); |
| |
| if (TESTBIT(inst, 7)) |
| point(xpos, ypos, 0); |
| break; |
| |
| case SLAVE: |
| mode = GETFIELD(inst, 2, 4); |
| break; |
| |
| case CHAR: |
| escape = (character(0, GETFIELD(inst, 0, 5)) || |
| character(1, GETFIELD(inst, 6, 11)) || |
| character(2, GETFIELD(inst, 12, 17))); |
| break; |
| |
| case VECTOR: |
| escape = TESTBIT(inst, 0); |
| if (vector(TESTBIT(inst, 1), |
| TESTBIT(inst, 2), GETFIELD(inst, 3, 9), |
| TESTBIT(inst, 10), GETFIELD(inst, 11, 17))) { |
| /* XXX interrupt? */ |
| } |
| break; |
| case VCONT: |
| escape = TESTBIT(inst, 0); |
| if (vector(TESTBIT(inst, 1), |
| TESTBIT(inst, 2), GETFIELD(inst, 3, 9), |
| TESTBIT(inst, 10), GETFIELD(inst, 11, 17))) { |
| /* XXX set escape? */ |
| mode = PARAM; /* raster violation */ |
| } |
| break; |
| |
| case INCR: |
| escape = TESTBIT(inst, 0); /* escape bit */ |
| i = TESTBIT(inst, 1); |
| |
| if (ipoint(i, 0, GETFIELD(inst, 2, 5)) || |
| ipoint(i, 1, GETFIELD(inst, 6, 9)) || |
| ipoint(i, 2, GETFIELD(inst, 10, 13)) || |
| ipoint(i, 3, GETFIELD(inst, 14, 17))) |
| /* XXX set escape? */ |
| mode = PARAM; /* raster violation */ |
| break; |
| |
| case SUBR: |
| /* type 347 Display Subroutine Option? */ |
| |
| mode = GETFIELD(inst, 2, 4); |
| /* XXX take high bits of current DAC? */ |
| addr = GETFIELD(inst, 5, 17); |
| |
| switch (GETFIELD(inst, 0, 1)) { |
| case DJS: /* display jump and save */ |
| ASR = DAC; |
| save_ff = 1; /* set "save" flip-flop */ |
| /* FALL */ |
| case DJP: /* display jump */ |
| DAC = addr; |
| break; |
| case DDS: /* display deposit save register */ |
| ty340_deposit(addr, (DJP<<16) | ASR); |
| save_ff = 0; /* ?? */ |
| break; |
| default: |
| /* XXX ??? */ |
| break; |
| } |
| break; |
| } |
| |
| if (escape) { |
| mode = PARAM; |
| if (save_ff) { |
| /* return from subroutine */ |
| DAC = ASR; |
| save_ff = 0; |
| } |
| } |
| return status; |
| } /* ty340_cycle */ |