diff --git a/PDP10/ka10_dd.c b/PDP10/ka10_dd.c new file mode 100644 index 0000000..026f841 --- /dev/null +++ b/PDP10/ka10_dd.c @@ -0,0 +1,756 @@ +/* ka10_dd.c: Data Disc 6600 Television Display System, with + PDP-10 interface and video switch made at Stanford AI lab. + + Copyright (c) 2022-2023, Lars Brinkhoff + + 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 + LARS BRINKHOFF 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 Lars Brinkhoff shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Lars Brinkhoff. +*/ + +#include "kx10_defs.h" +#ifndef NUM_DEVS_DD +#define NUM_DEVS_DD 0 +#endif + +#if NUM_DEVS_DD > 0 +#include "sim_video.h" + +#define DD_DEVNUM 0510 +#define VDS_DEVNUM 0340 + +#define DD_WIDTH 512 /* Display width. */ +#define DD_HEIGHT 480 /* Display height. */ +#define DD_PIXELS (DD_WIDTH * DD_HEIGHT) /* Total number of pixels. */ +#define DD_CHANNELS 32 /* Data Disc channels. */ +#define DD_COLUMNS 85 +#define FONT_WIDTH 6 +#define FONT_HEIGHT 12 +#define MARGIN 2 +#define VDS_OUTPUTS 64 /* Video switch outputs. */ +#define III_DISPLAYS 6 + +#define STATUS u3 +#define MA u4 /* Current memory address. */ +#define PIA u5 +#define COLUMN u6 +#define LINE us9 +#define CHANNEL us10 + +/* CONI/O Bits */ +#define DD_HALT 000000010 /* CONI: Halted. */ +#define DD_RESET 000000010 /* CONO: Reset. */ +#define DD_INT 000000020 /* CONI: Interrupting. */ +#define DD_FORCE 000000020 /* CONO: Force field. */ +#define DD_FIELD 000000040 /* CONI: Field. */ +#define DD_HALT_ENA 000000100 /* CONI: Halt interrupt enabled. */ +#define DD_DDGO 000000100 /* CONO: Go. */ +#define DD_LATE 000000200 /* CONI: Late. */ +#define DD_SPGO 000000200 /* CONO */ +#define DD_LATE_ENA 000000400 /* Late interrupt enabled. */ +#define DD_USER 000001000 /* User mode. */ +#define DD_NXM 000002000 /* CONI: Accessed non existing memory. */ + +/* Function codes. */ +#define FC_GRAPHICS 001 /* Graphics mode. */ +#define FC_WRITE 002 /* Write to disc. */ +#define FC_DARK 004 /* Dark background. */ +#define FC_DOUBLE_W 010 /* Double width. */ +#define FC_ERASE 010 /* Erase graphics. */ +#define FC_ADDITIVE 020 /* Additive graphics. */ +#define FC_SINGLE_H 040 /* Single height. */ + +/* There are 64 displays, fed from the video switch. */ +static uint32 vds_surface[VDS_OUTPUTS][DD_PIXELS]; +static uint32 vds_palette[VDS_OUTPUTS][2]; +static VID_DISPLAY *vds_vptr[VDS_OUTPUTS]; + +/* There are 32 channels on the Data Disc. */ +static uint8 dd_channel[DD_CHANNELS][DD_PIXELS]; +static uint8 dd_changed[DD_CHANNELS]; +static int dd_windows = 1; + +static uint8 dd_function_code = 0; +static uint16 dd_line_buffer[DD_COLUMNS + 1]; +static int dd_line_buffer_address = 0; +static int dd_line_buffer_written = 0; +#define WRITTEN 0400 + +uint32 vds_channel; /* Currently selected video outputs. */ +uint8 vds_changed[VDS_OUTPUTS]; +uint32 vds_selection[VDS_OUTPUTS]; /* Data Disc channels. */ +uint32 vds_sync_inhibit[VDS_OUTPUTS]; +uint32 vds_analog[VDS_OUTPUTS]; /* Analog channel. */ + +#include "ka10_dd_font.h" + +static t_stat dd_set_windows (UNIT *uptr, int32 val, CONST char *cptr, void *desc) ; +static t_stat dd_show_windows (FILE *st, UNIT *uptr, int32 val, CONST void *desc); +static void dd_chargen (char c, int column); +static void dd_graphics (uint8 data, int column); +static t_stat dd_devio(uint32 dev, uint64 *data); +static t_stat vds_devio(uint32 dev, uint64 *data); +static t_stat dd_svc(UNIT *uptr); +static t_stat vds_svc(UNIT *uptr); +static t_stat dd_reset(DEVICE *dptr); +static t_stat vds_reset(DEVICE *dptr); +static t_stat dd_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); +static t_stat vds_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); +static const char *dd_description (DEVICE *dptr); +static const char *vds_description (DEVICE *dptr); + +DIB dd_dib = { DD_DEVNUM, 1, dd_devio, NULL}; + +UNIT dd_unit = { + UDATA (&dd_svc, UNIT_IDLE, 0) +}; + +MTAB dd_mod[] = { + { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "WINDOWS", "WINDOWS", + &dd_set_windows, &dd_show_windows, NULL}, + { 0 } + }; + +DEVICE dd_dev = { + "DD", &dd_unit, NULL, dd_mod, + 1, 10, 31, 1, 8, 8, + NULL, NULL, dd_reset, + NULL, NULL, NULL, &dd_dib, DEV_DEBUG | DEV_DISABLE | DEV_DIS | DEV_DISPLAY, 0, dev_debug, + NULL, NULL, &dd_help, NULL, NULL, &dd_description + }; + +UNIT vds_unit = { + UDATA (&vds_svc, UNIT_IDLE, 0) +}; + +DIB vds_dib = { VDS_DEVNUM, 1, vds_devio, NULL}; + +DEVICE vds_dev = { + "VDS", &vds_unit, NULL, NULL, + 1, 10, 31, 1, 8, 8, + NULL, NULL, vds_reset, + NULL, NULL, NULL, &vds_dib, DEV_DEBUG | DEV_DISABLE | DEV_DIS | DEV_DISPLAY, 0, dev_debug, + NULL, NULL, &vds_help, NULL, NULL, &vds_description + }; + +static void unimplemented (const char *text) +{ + fprintf (stderr, "\r\n[UNIMPLEMENTED: %s]\r\n", text); +} + +static void +dd_hang (const char *msg) +{ + sim_debug(DEBUG_CMD, &dd_dev, "HANG: %s\n", msg); + dd_unit.STATUS |= DD_HALT; +} + +static void +dd_halt (const char *msg) +{ + sim_debug(DEBUG_CMD, &dd_dev, "HALT: %s\n", msg); + dd_unit.STATUS |= DD_HALT; +} + +static void +dd_execute (const char *msg) +{ + int i; + sim_debug(DEBUG_CMD, &dd_dev, "%s; %s mode\n", + msg, (dd_function_code & FC_GRAPHICS) ? "graphics" : "text"); + if (dd_unit.LINE >= DD_HEIGHT) + return; + + if (dd_function_code & FC_GRAPHICS) { + for (i = 1; i <= 64; i++) { + if (dd_line_buffer[i] & WRITTEN) + dd_graphics (dd_line_buffer[i] & 0377, i - 1); + } + } else { + for (i = 1; i <= DD_COLUMNS; i++) { + if (dd_line_buffer[i] & WRITTEN) + dd_chargen (dd_line_buffer[i] & 0177, i - 1); + } + } + + memset (dd_line_buffer, 0, sizeof dd_line_buffer); + dd_line_buffer_address = 1; + dd_line_buffer_written = 0; +} + +static t_stat +dd_devio(uint32 dev, uint64 *data) { + UNIT *uptr = &dd_unit; + switch(dev & 3) { + case CONI: + *data = uptr->PIA | uptr->STATUS; + sim_debug (DEBUG_CONI, &dd_dev, "%06llo (%6o)\n", *data, PC); + break; + case CONO: + sim_debug (DEBUG_CONO, &dd_dev, "%06llo (%6o)\n", *data, PC); + uptr->STATUS &= ~DD_HALT; + clr_interrupt (DD_DEVNUM); + uptr->PIA = (uint32)(*data & 7); + if (*data & DD_RESET) { + sim_debug(DEBUG_DETAIL, &dd_dev, "Reset.\n"); + uptr->PIA = 0; + uptr->STATUS = 0; + uptr->COLUMN = dd_line_buffer_address = 1; + uptr->LINE = 0; + dd_function_code = 0; + sim_cancel (uptr); + } + if (*data & DD_FORCE) { + sim_debug(DEBUG_DETAIL, &dd_dev, "Force field.\n"); + } + if (*data & 040) { + sim_debug(DEBUG_DETAIL, &dd_dev, "Halt interrupt enabled.\n"); + uptr->STATUS |= DD_HALT_ENA; + } + if (*data & DD_DDGO) { + sim_debug(DEBUG_DETAIL, &dd_dev, "Go.\n"); + } + if (*data & DD_SPGO) { + sim_debug(DEBUG_DETAIL, &dd_dev, "SPGO\n"); + } + if (*data & DD_LATE_ENA) { + sim_debug(DEBUG_DETAIL, &dd_dev, "Late interrupt enabled.\n"); + uptr->STATUS |= DD_LATE_ENA; + } + if (*data & DD_USER) { + sim_debug(DEBUG_DETAIL, &dd_dev, "User mode.\n"); + uptr->STATUS |= DD_USER; + } + break; + case DATAI: + *data = 0; + sim_debug(DEBUG_DATAIO, &dd_dev, "DATAI (%6o)\n", PC); + break; + case DATAO: + uptr->MA = *data & 0777777; + sim_debug(DEBUG_DATAIO, &dd_dev, "DATAO %06o (%6o)\n", uptr->MA, PC); + if (uptr->STATUS & DD_DDGO) + sim_activate (uptr, 1); + break; + } + return SCPE_OK; +} + +static void +dd_pixel (int x, int y, uint8 pixel) +{ + if (x >= DD_WIDTH) + return; + if (y >= DD_HEIGHT) + return; + pixel &= 1; + if (!(dd_function_code & FC_DARK)) + pixel ^= 1; + if (dd_function_code & FC_ADDITIVE) + dd_channel[dd_unit.CHANNEL][DD_WIDTH * y + x] |= pixel; + else + dd_channel[dd_unit.CHANNEL][DD_WIDTH * y + x] = pixel; + dd_changed[dd_unit.CHANNEL] = 1; +} + +static void +dd_chargen (char c, int column) +{ + int i, j; + uint8 pixels; + int line = dd_unit.LINE; + int field = line & 1; + + if (line >= DD_HEIGHT || column >= DD_COLUMNS) + return; + + sim_debug (DEBUG_DETAIL, &dd_dev, "CHARGEN %03o %d@(%d,%d)\n", + c, dd_unit.CHANNEL, column, dd_unit.LINE); + + for (i = 0; i < FONT_HEIGHT-1; i += 2, line += 2) { + pixels = font[c][i + field]; + for (j = 0; j < FONT_WIDTH-1; j++) { + dd_pixel (6 * column + j, line, pixels >> 4); + pixels <<= 1; + } + } +} + +static void +dd_byte (uint8 data) +{ + int max = (dd_function_code & FC_GRAPHICS) ? 64 : DD_COLUMNS; + if (dd_line_buffer_address <= max) { + sim_debug(DEBUG_DETAIL, &dd_dev, "Buffer[%d] %03o\n", + dd_line_buffer_address, data); + dd_line_buffer[dd_line_buffer_address] = data | WRITTEN; + } + dd_line_buffer_address++; + dd_line_buffer_address &= 0177; +} + +static void +dd_text (uint64 insn) +{ + int rubout = 0; + char text[6]; + int i; + + text[0] = (insn >> 29) & 0177; + text[1] = (insn >> 22) & 0177; + text[2] = (insn >> 15) & 0177; + text[3] = (insn >> 8) & 0177; + text[4] = (insn >> 1) & 0177; + text[5] = 0; + + sim_debug(DEBUG_CMD, &dd_dev, "TEXT \"%s\" to %d@(%d,%d)\n", + text, dd_unit.CHANNEL, dd_unit.COLUMN, dd_unit.LINE); + + for (i = 0; i < 5; i++) { + switch (text[i]) { + case 000: + case 0177: + sim_debug (DEBUG_DETAIL, &dd_dev, "CHAR %03o ignored\n", text[i]); + break; + case 012: + if (rubout) + goto print; + if (dd_line_buffer_written) { + sim_debug (DEBUG_DETAIL, &dd_dev, "LF clear rest of line\n"); + while (dd_line_buffer_address <= DD_COLUMNS) + dd_byte (040); + dd_execute ("LF execute"); + } + dd_unit.LINE += FONT_HEIGHT; + if (!(dd_function_code & FC_SINGLE_H)) + dd_unit.LINE += FONT_HEIGHT; + dd_unit.LINE &= 0777; + sim_debug (DEBUG_DETAIL, &dd_dev, "CHAR 012 LF -> (%d,%d)\n", + dd_unit.COLUMN, dd_unit.LINE); + break; + case 015: + if (rubout) + goto print; + if (dd_line_buffer_written) { + sim_debug (DEBUG_DETAIL, &dd_dev, "CR clear rest of line\n"); + while (dd_line_buffer_address <= DD_COLUMNS) + dd_byte (040); + dd_execute ("CR execute"); + } + dd_unit.COLUMN = dd_line_buffer_address = MARGIN; + sim_debug (DEBUG_DETAIL, &dd_dev, "CHAR 015 CR -> (%d,%d)\n", + dd_unit.COLUMN, dd_unit.LINE); + break; + case 010: + case 011: + if (!rubout) + break; + /* Fall through. */ + default: + print: + { + char ch[2]; + memset (ch, 0, 2); + if (text[i] > 040 && text[i] < 0177) + ch[0] = text[i]; + sim_debug (DEBUG_DETAIL, &dd_dev, "CHAR %03o %s (%d,%d)\n", + text[i], ch, dd_line_buffer_address, dd_unit.LINE); + } + dd_byte (text[i]); + dd_line_buffer_written = 1; + dd_unit.COLUMN++; + dd_unit.COLUMN &= 0177; + break; + } + rubout = (text[i] == 0177); + } +} + +static void +dd_graphics (uint8 data, int column) +{ + int i, j; + + sim_debug (DEBUG_CMD, &dd_dev, "GRAPHICS %03o %d@(%d,%d)\n", + data, dd_unit.CHANNEL, column, dd_unit.LINE); + + column = 8 * column + 4; + for (i = 0; i < 8; i++) { + dd_pixel (column, dd_unit.LINE, data >> 7); + column++; + data <<= 1; + } +} + +static void +dd_function (uint8 data) +{ + dd_function_code = data; + sim_debug(DEBUG_CMD, &dd_dev, "COMMAND: function code %03o\n", data); + if (data & FC_GRAPHICS) + sim_debug(DEBUG_DETAIL, &dd_dev, "Function: graphics mode\n"); + else + sim_debug(DEBUG_DETAIL, &dd_dev, "Function: text mode\n"); + if (data & FC_WRITE) + sim_debug(DEBUG_DETAIL, &dd_dev, "Function: write to disc\n"); + else + sim_debug(DEBUG_DETAIL, &dd_dev, "Function: write to display\n"); + if (data & FC_DARK) + sim_debug(DEBUG_DETAIL, &dd_dev, "Function: dark background\n"); + else + sim_debug(DEBUG_DETAIL, &dd_dev, "Function: light background\n"); + switch (data & (FC_GRAPHICS|FC_DOUBLE_W)) { + case 000: + sim_debug(DEBUG_DETAIL, &dd_dev, "Function: single width\n"); + break; + case FC_DOUBLE_W: + sim_debug(DEBUG_DETAIL, &dd_dev, "Function: double width\n"); + break; + case FC_GRAPHICS|FC_ERASE: + sim_debug(DEBUG_DETAIL, &dd_dev, "Function: erase\n"); + break; + } + if (data & FC_ADDITIVE) + sim_debug(DEBUG_DETAIL, &dd_dev, "Function: additive\n"); + else + sim_debug(DEBUG_DETAIL, &dd_dev, "Function: replace\n"); + if (data & FC_SINGLE_H) + sim_debug(DEBUG_DETAIL, &dd_dev, "Function: single height\n"); + else + sim_debug(DEBUG_DETAIL, &dd_dev, "Function: double height\n"); +} + +static void +dd_command (uint32 command, uint8 data) +{ + int i; + switch (command) { + case 0: + dd_execute ("COMMAND: execute"); + break; + case 1: + dd_function (data); + break; + case 2: + dd_unit.CHANNEL = data & 077; + sim_debug(DEBUG_CMD, &dd_dev, "COMMAND: channel select %d\n", + dd_unit.CHANNEL); + if ((dd_function_code & (FC_GRAPHICS|FC_ERASE)) == (FC_GRAPHICS|FC_ERASE)) { + sim_debug(DEBUG_CMD, &dd_dev, "COMMAND: erase channel %d\n", + dd_unit.CHANNEL); + dd_changed[dd_unit.CHANNEL] = 1; + for (i = 0; i < DD_PIXELS; i++) + dd_channel[dd_unit.CHANNEL][i] = 0; + } + break; + case 3: + dd_unit.COLUMN = dd_line_buffer_address = data & 0177; + if (dd_unit.COLUMN == 0 || dd_unit.COLUMN > DD_COLUMNS) + dd_hang ("Text column outside bounds"); + sim_debug(DEBUG_CMD, &dd_dev, "COMMAND: column select %d\n", + dd_unit.COLUMN); + break; + case 4: + dd_unit.LINE = ((data & 037) << 4) | (dd_unit.LINE & 017); + sim_debug(DEBUG_CMD, &dd_dev, "COMMAND: high order line address -> %d\n", + dd_unit.LINE); + break; + case 5: + dd_unit.LINE = (data & 017) | (dd_unit.LINE & 0760); + sim_debug(DEBUG_CMD, &dd_dev, "COMMAND: low order line address -> %d\n", + dd_unit.LINE); + break; + case 6: + sim_debug(DEBUG_CMD, &dd_dev, "COMMAND: write directly %03o (%d,%d)\n", + data, dd_unit.COLUMN, dd_unit.LINE); + dd_unit.COLUMN++; + dd_unit.COLUMN &= 0177; + break; + case 7: + dd_line_buffer_address = data & 0177; + sim_debug(DEBUG_CMD, &dd_dev, "COMMAND: line buffer address %03o\n", + dd_line_buffer_address); + break; + } +} + +static void +dd_decode (uint64 insn) +{ + switch (insn & 077) { + case 001: case 003: case 005: case 007: + case 011: case 013: case 015: case 017: + case 021: case 023: case 025: case 027: + case 031: case 033: case 035: case 037: + case 041: case 043: case 045: case 047: + case 051: case 053: case 055: case 057: + case 061: case 063: case 065: case 067: + case 071: case 073: case 075: case 077: + dd_text (insn); + break; + case 002: case 022: case 042: case 062: + sim_debug(DEBUG_CMD, &dd_dev, "COMMAND: graphics %012llo\n", insn >> 4); + dd_byte ((insn >> 28) & 0377); + dd_byte ((insn >> 20) & 0377); + dd_byte ((insn >> 12) & 0377); + dd_byte ((insn >> 4) & 0377); + break; + case 000: case 040: case 060: + dd_halt ("halt instruction"); + break; + case 020: + dd_unit.MA = insn >> 18; + sim_debug(DEBUG_CMD, &dd_dev, "JUMP %06o\n", dd_unit.MA); + break; + case 006: case 016: case 026: case 036: + case 046: case 056: case 066: case 076: + case 012: case 032: case 052: case 072: + sim_debug(DEBUG_CMD, &dd_dev, "NOP\n"); + break; + case 010: case 030: case 050: case 070: + sim_debug(DEBUG_CMD, &dd_dev, "(weird command)\n"); + case 004: case 014: case 024: case 034: + case 044: case 054: case 064: case 074: + dd_command ((insn >> 9) & 7, (insn >> 28) & 0377); + dd_command ((insn >> 6) & 7, (insn >> 20) & 0377); + dd_command ((insn >> 3) & 7, (insn >> 12) & 0377); + break; + default: + sim_debug(DEBUG_CMD, &dd_dev, "(UNDOCUMENTED %012llo)\n", insn); + break; + } +} + +static t_stat +dd_svc (UNIT *uptr) +{ + if (uptr->MA >= MEMSIZE) { + uptr->STATUS |= DD_NXM; + dd_halt ("NXM"); + } else { + dd_decode (M[uptr->MA++]); + } + + if (uptr->STATUS & DD_HALT) { + uptr->STATUS |= DD_INT; + if (uptr->STATUS & DD_HALT_ENA) { + sim_debug(DEBUG_IRQ, &dd_dev, "Interrupt: halt\n"); + set_interrupt (DD_DEVNUM, uptr->PIA); + } + } else + sim_activate_after (uptr, 100); + + return SCPE_OK; +} + +static void +dd_display (int n) +{ + uint32 selection = vds_selection[n]; + int i, j; + + if (selection == 0) { + sim_debug(DEBUG_DETAIL, &vds_dev, "Output %d displays no channels\n", n); + return; + } + +#if 1 + if (!(selection & (selection - 1))) { + for (i = 0; (selection & 020000000000) == 0; i++) + selection <<= 1; + if (!dd_changed[i] && !vds_changed[n]) + return; + sim_debug(DEBUG_DETAIL, &vds_dev, "Output %d from channel %d\n", n, i); + for (j = 0; j < DD_PIXELS; j++) + vds_surface[n][j] = vds_palette[n][dd_channel[i][j]]; + } else { +#endif + +#if 0 + for (j = 0; j < DD_PIXELS; j++) { + uint8 pixel = 0; + for (i = 0; i < DD_CHANNELS; i++, selection <<= 1) { + if (selection & 020000000000) + pixel |= dd_channel[i][j]; + vds_surface[n][j] = vds_palette[n][pixel]; + } + } +#else + } +#endif + + vid_draw_window (vds_vptr[n], 0, 0, DD_WIDTH, DD_HEIGHT, vds_surface[n]); + vid_refresh_window (vds_vptr[n]); + sim_debug (DEBUG_DETAIL, &vds_dev, "Refresh window %p\n", vds_vptr[n]); +} + +static t_stat +vds_svc (UNIT *uptr) +{ + int i; + for (i = III_DISPLAYS; i < dd_windows + III_DISPLAYS; i++) + dd_display (i); + for (i = 0; i < DD_CHANNELS; i++) + dd_changed[i] = 0; + for (i = 0; i < VDS_OUTPUTS; i++) + vds_changed[i] = 0; + + sim_activate_after (uptr, 33333); + return SCPE_OK; +} + +uint32 dd_keyboard_line (void *p) +{ + int i; + VID_DISPLAY *vptr = (VID_DISPLAY *)p; + sim_debug(DEBUG_DETAIL, &vds_dev, "Key event on window %p\n", vptr); + for (i = 0; i < VDS_OUTPUTS; i++) { + if (vptr == vds_vptr[i]) + return i; + } + return ~0U; +} + +static t_stat +dd_reset (DEVICE *dptr) +{ + if (dptr->flags & DEV_DIS || sim_switches & SWMASK('P')) { + sim_cancel (&dd_unit); + memset (dd_channel, 0, sizeof dd_channel); + memset (dd_changed, 0, sizeof dd_changed); + return SCPE_OK; + } + if (dptr->flags & DEV_DIS) + set_cmd (0, "VDS DISABLED"); + else + set_cmd (0, "VDS ENABLED"); + + return SCPE_OK; +} + +static t_stat dd_set_windows (UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + t_value x; + t_stat r; + if (cptr == NULL) + return SCPE_ARG; + x = get_uint (cptr, 10, 32, &r); + if (r != SCPE_OK) + return r; + dd_windows = x; + return SCPE_OK; +} + +static t_stat dd_show_windows (FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + if (uptr == NULL) + return SCPE_IERR; + fprintf (st, "WINDOWS=%d", dd_windows); + return SCPE_OK; +} + +static t_stat +dd_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + return SCPE_OK; +} + +static const char * +dd_description (DEVICE *dptr) +{ + return "Data Disc Television Display System"; +} + +static t_stat +vds_reset (DEVICE *dptr) +{ + t_stat r; + int i; + if (dptr->flags & DEV_DIS || sim_switches & SWMASK('P')) { + for (i = 0; i < VDS_OUTPUTS; i++) { + if (vds_vptr[i] != NULL) + vid_close_window (vds_vptr[i]); + } + vds_channel = 0; + memset (vds_vptr, 0, sizeof vds_vptr); + memset (vds_palette, 0, sizeof vds_palette); + memset (vds_selection, 0, sizeof vds_selection); + memset (vds_sync_inhibit, 0, sizeof vds_sync_inhibit); + memset (vds_analog, 0, sizeof vds_analog); + sim_cancel (&vds_unit); + return SCPE_OK; + } + + for (i = III_DISPLAYS; i < dd_windows + III_DISPLAYS; i++) { + if (vds_vptr[i] == NULL) { + char title[40]; + snprintf (title, sizeof title, "Data Disc display %d", i); + r = vid_open_window (&vds_vptr[i], &dd_dev, title, DD_WIDTH, DD_HEIGHT, 0); + if (r != SCPE_OK) + return r; + fprintf(stderr, "Window %d is %p\r\n", i, vds_vptr[i]); + vds_palette[i][0] = vid_map_rgb_window (vds_vptr[i], 0x00, 0x00, 0x00); + vds_palette[i][1] = vid_map_rgb_window (vds_vptr[i], 0x00, 0xFF, 0x30); + } + } + + sim_activate (&vds_unit, 1); + return SCPE_OK; +} + +static t_stat +vds_devio(uint32 dev, uint64 *data) +{ + switch(dev & 3) { + case CONO: + sim_debug(DEBUG_CONO, &vds_dev, "%012llo (%6o)\n", *data, PC); + vds_channel = *data & 077; + break; + case DATAO: + sim_debug(DEBUG_DATAIO, &vds_dev, "%012llo (%6o)\n", *data, PC); + vds_changed[vds_channel] = 1; + vds_selection[vds_channel] = *data >> 4; + vds_sync_inhibit[vds_channel] = (*data >> 3) & 1; + vds_analog[vds_channel] = *data & 7; + sim_debug(DEBUG_DETAIL, &vds_dev, "Output %d selection %011o\n", + vds_channel, vds_selection[vds_channel]); +#if 0 + sim_debug(DEBUG_DETAIL, &vds_dev, "Sync inhibit %d\n", + vds_sync_inhibit[vds_channel]); + sim_debug(DEBUG_DETAIL, &vds_dev, "Analog %d\n", + vds_analog[vds_channel]); +#endif + break; + } + return SCPE_OK; +} + +static t_stat +vds_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + return SCPE_OK; +} + +static const char * +vds_description (DEVICE *dptr) +{ + return "Video Switch"; +} +#endif diff --git a/PDP10/ka10_dd_font.c b/PDP10/ka10_dd_font.c new file mode 100644 index 0000000..c056d4c --- /dev/null +++ b/PDP10/ka10_dd_font.c @@ -0,0 +1,1858 @@ +#include + +/* ka10_dd_font.c: Font data for Data Disc 6600 Television Display System. + + Copyright (c) 2022-2023, Lars Brinkhoff + + Process this with a C compiler supporting the binary 0b prefix + to generate the ka10_dd_font.h file included in the emulator. + + 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 + LARS BRINKHOFF 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 Lars Brinkhoff shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Lars Brinkhoff. +*/ + +/* Font from http://www.bitsavers.org/pdf/dataDisc/Television_Display_System_Reference_Manual_Jul69.pdf */ +static unsigned int tds_font[128][12] = { + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 000 + { 0b00000, + 0b00000, + 0b00000, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b10101, + 0b01110, + 0b00100, + 0b00000, + 0b00000 }, // 001 down arrow + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 002 alpha + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 003 beta + { 0b00000, + 0b00000, + 0b00000, + 0b00100, + 0b01010, + 0b01010, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b00000, + 0b00000 }, // 004 AND + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 005 NOT + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b01111, + 0b10001, + 0b01110, + 0b10000, + 0b01111, + 0b00000, + 0b00000 }, // 006 epsilon + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b11111, + 0b01010, + 0b01010, + 0b01010, + 0b01010, + 0b00000, + 0b00000 }, // 007 pi + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 010 lambda + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 011 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 012 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 013 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 014 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 015 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b01010, + 0b10101, + 0b10101, + 0b01010, + 0b00000, + 0b00000, + 0b00000 }, // 016 infinity + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 017 partial differential + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b11110, + 0b00001, + 0b00001, + 0b11110, + 0b00000, + 0b00000, + 0b00000 }, // 020 subset + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b01111, + 0b10000, + 0b10000, + 0b01111, + 0b00000, + 0b00000, + 0b00000 }, // 021 superset + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 022 intersection + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 023 union + { 0b00000, + 0b00000, + 0b00000, + 0b10001, + 0b10001, + 0b11111, + 0b10001, + 0b01010, + 0b01010, + 0b00100, + 0b00000, + 0b00000 }, // 024 for all + { 0b00000, + 0b00000, + 0b00000, + 0b11111, + 0b00001, + 0b00001, + 0b01111, + 0b00001, + 0b00001, + 0b11111, + 0b00000, + 0b00000 }, // 025 there exists + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b11011, + 0b10101, + 0b11011, + 0b01110, + 0b00000, + 0b00000, + 0b00000 }, // 026 circled times + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b01010, + 0b11111, + 0b01010, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 027 double arrow + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b11111, + 0b00000, + 0b00000 }, // 030 underscore + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00100, + 0b00010, + 0b11111, + 0b00010, + 0b00100, + 0b00000, + 0b00000, + 0b00000 }, // 031 right arrow + { 0b00000, + 0b00000, + 0b00000, + 0b01010, + 0b10100, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 032 tilde + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00010, + 0b11111, + 0b00100, + 0b11111, + 0b01000, + 0b00000, + 0b00000 }, // 033 not equal + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 034 less than or equal + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 035 greater than or equal + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b11111, + 0b00000, + 0b11111, + 0b00000, + 0b11111, + 0b00000, + 0b00000, + 0b00000 }, // 036 equivalence + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 037 OR + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 040 SPC + { 0b00000, + 0b00000, + 0b00000, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00000, + 0b00100, + 0b00000, + 0b00000 }, // 041 ! + { 0b00000, + 0b00000, + 0b00000, + 0b01010, + 0b01010, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 042 " + { 0b00000, + 0b00000, + 0b00000, + 0b01010, + 0b01010, + 0b11111, + 0b01010, + 0b11111, + 0b01010, + 0b01010, + 0b00000, + 0b00000 }, // 043 # + { 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b10101, + 0b10100, + 0b01110, + 0b00101, + 0b10101, + 0b01110, + 0b00000, + 0b00000 }, // 044 $ + { 0b00000, + 0b00000, + 0b00000, + 0b11001, + 0b11001, + 0b00010, + 0b00100, + 0b01000, + 0b10011, + 0b10011, + 0b00000, + 0b00000 }, // 045 % + { 0b00000, + 0b00000, + 0b00000, + 0b01000, + 0b10100, + 0b10100, + 0b01000, + 0b10101, + 0b10010, + 0b01101, + 0b00000, + 0b00000 }, // 046 & + { 0b00000, + 0b00000, + 0b00000, + 0b01000, + 0b00100, + 0b00100, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 047 ' + { 0b00000, + 0b00000, + 0b00000, + 0b00100, + 0b01000, + 0b10000, + 0b10000, + 0b10000, + 0b01000, + 0b00100, + 0b00000, + 0b00000 }, // 050 ( + { 0b00000, + 0b00000, + 0b00000, + 0b00100, + 0b00010, + 0b00001, + 0b00001, + 0b00001, + 0b00010, + 0b00100, + 0b00000, + 0b00000 }, // 051 ) + { 0b00000, + 0b00000, + 0b00000, + 0b00100, + 0b10101, + 0b01110, + 0b11111, + 0b01110, + 0b10101, + 0b00100, + 0b00000, + 0b00000 }, // 052 * + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00100, + 0b00100, + 0b11111, + 0b00100, + 0b00100, + 0b00000, + 0b00000, + 0b00000 }, // 053 + + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b01000, + 0b00100, + 0b00100, + 0b00000 }, // 054 , + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b11111, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 055 - + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b01100, + 0b01100, + 0b00000, + 0b00000 }, // 056 . + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00001, + 0b00010, + 0b00100, + 0b01000, + 0b10000, + 0b00000, + 0b00000, + 0b00000 }, // 057 / + { 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b10001, + 0b10001, + 0b10101, + 0b10001, + 0b10001, + 0b01110, + 0b00000, + 0b00000 }, // 060 0 + { 0b00000, + 0b00000, + 0b00000, + 0b00100, + 0b01100, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b01110, + 0b00000, + 0b00000 }, // 061 1 + { 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b10001, + 0b00001, + 0b00010, + 0b00100, + 0b01000, + 0b11111, + 0b00000, + 0b00000 }, // 062 + { 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b00001, + 0b00001, + 0b00110, + 0b00001, + 0b10001, + 0b01110, + 0b00000, + 0b00000 }, // 063 + { 0b00000, + 0b00000, + 0b00000, + 0b00010, + 0b00110, + 0b01010, + 0b10010, + 0b11111, + 0b00010, + 0b00010, + 0b00000, + 0b00000 }, // 064 + { 0b00000, + 0b00000, + 0b00000, + 0b01111, + 0b01000, + 0b01000, + 0b01110, + 0b00001, + 0b10001, + 0b01110, + 0b00000, + 0b00000 }, // 065 + { 0b00000, + 0b00000, + 0b00000, + 0b00110, + 0b01000, + 0b10000, + 0b11110, + 0b10001, + 0b10001, + 0b01110, + 0b00000, + 0b00000 }, // 066 + { 0b00000, + 0b00000, + 0b00000, + 0b11111, + 0b00001, + 0b00010, + 0b00100, + 0b00100, + 0b01000, + 0b01000, + 0b00000, + 0b00000 }, // 067 + { 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b10001, + 0b10001, + 0b01110, + 0b10001, + 0b10001, + 0b01110, + 0b00000, + 0b00000 }, // 070 + { 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b10001, + 0b10001, + 0b01111, + 0b00001, + 0b00001, + 0b00001, + 0b00000, + 0b00000 }, // 071 9 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00100, + 0b00000, + 0b00100, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 072 : + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00100, + 0b00000, + 0b00100, + 0b00100, + 0b01000, + 0b00000 }, // 073 ; + { 0b00000, + 0b00000, + 0b00000, + 0b00010, + 0b00100, + 0b01000, + 0b10000, + 0b01000, + 0b00100, + 0b00010, + 0b00000, + 0b00000 }, // 074 < + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b11111, + 0b00000, + 0b11111, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 075 = + { 0b00000, + 0b00000, + 0b00000, + 0b01000, + 0b00100, + 0b00010, + 0b00001, + 0b00010, + 0b00100, + 0b01000, + 0b00000, + 0b00000 }, // 076 > + { 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b10001, + 0b00001, + 0b00010, + 0b00100, + 0b00100, + 0b00000, + 0b00100, + 0b00000 }, // 077 ? + { 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b10001, + 0b10111, + 0b10101, + 0b10111, + 0b10000, + 0b10000, + 0b01110, + 0b00000 }, // 100 @ + { 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b10001, + 0b10001, + 0b11111, + 0b10001, + 0b10001, + 0b10001, + 0b00000, + 0b00000 }, // 101 A + { 0b00000, + 0b00000, + 0b00000, + 0b11110, + 0b10001, + 0b10001, + 0b11110, + 0b10001, + 0b10001, + 0b11110, + 0b00000, + 0b00000 }, // 102 B + { 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b10001, + 0b10000, + 0b10000, + 0b10000, + 0b10001, + 0b01110, + 0b00000, + 0b00000 }, // 103 C + { 0b00000, + 0b00000, + 0b00000, + 0b11110, + 0b01001, + 0b01001, + 0b01001, + 0b01001, + 0b01001, + 0b11110, + 0b00000, + 0b00000 }, // 104 D + { 0b00000, + 0b00000, + 0b00000, + 0b11111, + 0b10000, + 0b10000, + 0b11110, + 0b10000, + 0b10000, + 0b11111, + 0b00000, + 0b00000 }, // 105 E + { 0b00000, + 0b00000, + 0b00000, + 0b11111, + 0b10000, + 0b10000, + 0b11110, + 0b10000, + 0b10000, + 0b10000, + 0b00000, + 0b00000 }, // 106 F + { 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b10001, + 0b10000, + 0b10000, + 0b10111, + 0b10001, + 0b01110, + 0b00000, + 0b00000 }, // 107 G + { 0b00000, + 0b00000, + 0b00000, + 0b10001, + 0b10001, + 0b10001, + 0b11111, + 0b10001, + 0b10001, + 0b10001, + 0b00000, + 0b00000 }, // 110 H + { 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b01110, + 0b00000, + 0b00000 }, // 111 I + { 0b00000, + 0b00000, + 0b00000, + 0b00001, + 0b00001, + 0b00001, + 0b00001, + 0b00001, + 0b10001, + 0b01110, + 0b00000, + 0b00000 }, // 112 J + { 0b00000, + 0b00000, + 0b00000, + 0b10001, + 0b10010, + 0b10100, + 0b11000, + 0b10100, + 0b10010, + 0b10001, + 0b00000, + 0b00000 }, // 113 K + { 0b00000, + 0b00000, + 0b00000, + 0b10000, + 0b10000, + 0b10000, + 0b10000, + 0b10000, + 0b10000, + 0b11111, + 0b00000, + 0b00000 }, // 114 L + { 0b00000, + 0b00000, + 0b00000, + 0b10001, + 0b11011, + 0b10101, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b00000, + 0b00000 }, // 115 M + { 0b00000, + 0b00000, + 0b00000, + 0b10001, + 0b11001, + 0b11101, + 0b10111, + 0b10011, + 0b10001, + 0b10001, + 0b00000, + 0b00000 }, // 116 N + { 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b01110, + 0b00000, + 0b00000 }, // 117 O + { 0b00000, + 0b00000, + 0b00000, + 0b11110, + 0b10001, + 0b10001, + 0b11110, + 0b10000, + 0b10000, + 0b10000, + 0b00000, + 0b00000 }, // 120 P + { 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b10001, + 0b10001, + 0b10001, + 0b10101, + 0b10010, + 0b01101, + 0b00000, + 0b00000 }, // 121 Q + { 0b00000, + 0b00000, + 0b00000, + 0b11110, + 0b10001, + 0b10001, + 0b11110, + 0b10100, + 0b10010, + 0b10001, + 0b00000, + 0b00000 }, // 122 R + { 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b10000, + 0b10000, + 0b01110, + 0b00001, + 0b10001, + 0b01110, + 0b00000, + 0b00000 }, // 123 S + { 0b00000, + 0b00000, + 0b00000, + 0b11111, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00000, + 0b00000 }, // 124 T + { 0b00000, + 0b00000, + 0b00000, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b01110, + 0b00000, + 0b00000 }, // 125 U + { 0b00000, + 0b00000, + 0b00000, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b01010, + 0b01010, + 0b00100, + 0b00000, + 0b00000 }, // 126 V + { 0b00000, + 0b00000, + 0b00000, + 0b10001, + 0b10001, + 0b10001, + 0b10001, + 0b10101, + 0b11011, + 0b10001, + 0b00000, + 0b00000 }, // 127 W + { 0b00000, + 0b00000, + 0b00000, + 0b10001, + 0b10001, + 0b01010, + 0b00100, + 0b01010, + 0b10001, + 0b10001, + 0b00000, + 0b00000 }, // 130 X + { 0b00000, + 0b00000, + 0b00000, + 0b10001, + 0b10001, + 0b01010, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00000, + 0b00000 }, // 131 Y + { 0b00000, + 0b00000, + 0b00000, + 0b11111, + 0b00001, + 0b00010, + 0b00100, + 0b01000, + 0b10000, + 0b11111, + 0b00000, + 0b00000 }, // 132 Z + { 0b00000, + 0b00000, + 0b00000, + 0b11110, + 0b10000, + 0b10000, + 0b10000, + 0b10000, + 0b10000, + 0b11110, + 0b00000, + 0b00000 }, // 133 [ + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b10000, + 0b01000, + 0b00100, + 0b00010, + 0b00001, + 0b00000, + 0b00000, + 0b00000 }, // 134 backslash + { 0b00000, + 0b00000, + 0b00000, + 0b01111, + 0b00001, + 0b00001, + 0b00001, + 0b00001, + 0b00001, + 0b01111, + 0b00000, + 0b00000 }, // 135 ] + { 0b00000, + 0b00000, + 0b00000, + 0b00100, + 0b01110, + 0b10101, + 0b00100, + 0b00100, + 0b00100, + 0b00100, + 0b00000, + 0b00000 }, // 136 up arrow + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00100, + 0b01000, + 0b11111, + 0b01000, + 0b00100, + 0b00000, + 0b00000, + 0b00000 }, // 137 left arrow + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 140 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b00001, + 0b01111, + 0b10001, + 0b01111, + 0b00000, + 0b00000 }, // 141 a + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 142 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 143 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 144 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b10001, + 0b11111, + 0b10000, + 0b01111, + 0b00000, + 0b00000 }, // 145 e + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 146 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 147 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 150 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 151 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 152 + { 0b00000, + 0b00000, + 0b00000, + 0b10000, + 0b10000, + 0b10010, + 0b10100, + 0b11000, + 0b10100, + 0b10010, + 0b00000, + 0b00000 }, // 153 k + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 154 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b11010, + 0b10101, + 0b10101, + 0b10101, + 0b10101, + 0b00000, + 0b00000 }, // 155 m + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 156 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b01110, + 0b10001, + 0b10001, + 0b10001, + 0b01110, + 0b00000, + 0b00000 }, // 157 o + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 160 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 161 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b10110, + 0b11001, + 0b10000, + 0b10000, + 0b10000, + 0b00000, + 0b00000 }, // 162 r + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b01111, + 0b10000, + 0b01110, + 0b00001, + 0b11110, + 0b00000, + 0b00000 }, // 163 s + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 164 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b10001, + 0b10001, + 0b10001, + 0b10011, + 0b01101, + 0b00000, + 0b00000 }, // 165 u + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 166 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 167 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 170 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 171 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 172 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 173 { + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 174 | + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 175 + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 176 } + { 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000, + 0b00000 }, // 177 +}; + +/* Font from Knight TV. */ +static unsigned int knight_font[128][12] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } +}; + +/* SAIL7 font. */ +static unsigned int sail7_font[128][12] = { + { 0, 0x00, 0x1F, 0x11, 0x15, 0x11, 0x1F, 0x00, 0x00, 0, 0, 0 }, // 000 + { 0, 0x04, 0x04, 0x04, 0x15, 0x0E, 0x04, 0x00, 0x00, 0, 0, 0 }, // 001 down arrow + { 0, 0x00, 0x00, 0x0D, 0x12, 0x12, 0x0D, 0x00, 0x00, 0, 0, 0 }, // 002 alpha + { 0, 0x06, 0x09, 0x0E, 0x09, 0x09, 0x0E, 0x08, 0x00, 0, 0, 0 }, // 003 beta + { 0, 0x00, 0x04, 0x0A, 0x11, 0x00, 0x00, 0x00, 0x00, 0, 0, 0 }, // 004 AND + { 0, 0x00, 0x00, 0x1F, 0x01, 0x01, 0x00, 0x00, 0x00, 0, 0, 0 }, // 005 NOT + { 0, 0x00, 0x07, 0x08, 0x0E, 0x08, 0x07, 0x00, 0x00, 0, 0, 0 }, // 006 epsilon + { 0, 0x00, 0x1F, 0x0A, 0x0A, 0x0A, 0x09, 0x00, 0x00, 0, 0, 0 }, // 007 pi + { 0, 0x10, 0x08, 0x04, 0x0A, 0x11, 0x11, 0x00, 0x00, 0, 0, 0 }, // 010 lambda + { 0, 0x1C, 0x08, 0x0E, 0x0D, 0x06, 0x05, 0x06, 0x00, 0, 0, 0 }, // 011 TB + { 0, 0x10, 0x10, 0x17, 0x1C, 0x07, 0x04, 0x04, 0x00, 0, 0, 0 }, // 012 LF + { 0, 0x0A, 0x0A, 0x04, 0x07, 0x02, 0x02, 0x02, 0x00, 0, 0, 0 }, // 013 VT + { 0, 0x1C, 0x10, 0x1F, 0x14, 0x16, 0x04, 0x04, 0x00, 0, 0, 0 }, // 014 FF + { 0, 0x0E, 0x10, 0x16, 0x15, 0x0E, 0x05, 0x05, 0x00, 0, 0, 0 }, // 015 CR + { 0, 0x00, 0x0A, 0x15, 0x15, 0x15, 0x0A, 0x00, 0x00, 0, 0, 0 }, // 016 infinity + { 0, 0x0C, 0x02, 0x07, 0x09, 0x09, 0x06, 0x00, 0x00, 0, 0, 0 }, // 017 partial differential + { 0, 0x00, 0x0F, 0x10, 0x10, 0x0F, 0x00, 0x00, 0x00, 0, 0, 0 }, // 020 subset + { 0, 0x00, 0x1E, 0x01, 0x01, 0x1E, 0x00, 0x00, 0x00, 0, 0, 0 }, // 021 superset + { 0, 0x06, 0x09, 0x09, 0x09, 0x09, 0x09, 0x00, 0x00, 0, 0, 0 }, // 022 intersection + { 0, 0x09, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x00, 0, 0, 0 }, // 023 union + { 0, 0x11, 0x11, 0x1F, 0x11, 0x0A, 0x04, 0x00, 0x00, 0, 0, 0 }, // 024 for all + { 0, 0x1F, 0x01, 0x07, 0x01, 0x01, 0x1F, 0x00, 0x00, 0, 0, 0 }, // 025 there exists + { 0, 0x00, 0x0E, 0x15, 0x1B, 0x15, 0x0E, 0x00, 0x00, 0, 0, 0 }, // 026 circled times + { 0, 0x00, 0x00, 0x0A, 0x1F, 0x0A, 0x00, 0x00, 0x00, 0, 0, 0 }, // 027 double arrow + { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0, 0, 0 }, // 030 underscore + { 0, 0x00, 0x04, 0x02, 0x1F, 0x02, 0x04, 0x00, 0x00, 0, 0, 0 }, // 031 right arrow + { 0, 0x00, 0x08, 0x15, 0x02, 0x00, 0x00, 0x00, 0x00, 0, 0, 0 }, // 032 tilde + { 0, 0x01, 0x02, 0x1F, 0x04, 0x1F, 0x08, 0x10, 0x00, 0, 0, 0 }, // 033 not equal + { 0, 0x00, 0x02, 0x04, 0x08, 0x04, 0x02, 0x0F, 0x00, 0, 0, 0 }, // 034 less than or equal + { 0, 0x00, 0x08, 0x04, 0x02, 0x04, 0x08, 0x1E, 0x00, 0, 0, 0 }, // 035 greater than or equal + { 0, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x00, 0, 0, 0 }, // 036 equivalence + { 0, 0x00, 0x11, 0x0A, 0x04, 0x00, 0x00, 0x00, 0x00, 0, 0, 0 }, // 037 OR + { 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0, 0, 0 }, // 040 SPC + { 0, 0x06, 0x06, 0x06, 0x06, 0x00, 0x06, 0x00, 0x00, 0, 0, 0 }, // 041 ! + { 0, 0x0A, 0x0A, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0, 0, 0 }, // 042 " + { 0, 0x0A, 0x1F, 0x0A, 0x0A, 0x1F, 0x0A, 0x00, 0x00, 0, 0, 0 }, // 043 # + { 0, 0x04, 0x0F, 0x14, 0x0E, 0x05, 0x1E, 0x04, 0x00, 0, 0, 0 }, // 044 $ + { 0, 0x1F, 0x19, 0x02, 0x04, 0x0B, 0x13, 0x00, 0x00, 0, 0, 0 }, // 045 % + { 0, 0x0C, 0x14, 0x08, 0x15, 0x12, 0x1D, 0x00, 0x00, 0, 0, 0 }, // 046 & + { 0, 0x06, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0, 0, 0 }, // 047 ' + { 0, 0x02, 0x04, 0x08, 0x08, 0x08, 0x04, 0x02, 0x00, 0, 0, 0 }, // 050 ( + { 0, 0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08, 0x00, 0, 0, 0 }, // 051 ) + { 0, 0x00, 0x15, 0x0E, 0x1B, 0x0E, 0x15, 0x00, 0x00, 0, 0, 0 }, // 052 * + { 0, 0x00, 0x04, 0x04, 0x1F, 0x04, 0x04, 0x00, 0x00, 0, 0, 0 }, // 053 + + { 0, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, 0x04, 0x00, 0, 0, 0 }, // 054 , + { 0, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0, 0, 0 }, // 055 - + { 0, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0, 0, 0 }, // 056 . + { 0, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x00, 0x00, 0, 0, 0 }, // 057 / + { 0, 0x06, 0x09, 0x0B, 0x0D, 0x09, 0x06, 0x00, 0x00, 0, 0, 0 }, // 060 0 + { 0, 0x02, 0x06, 0x02, 0x02, 0x02, 0x07, 0x00, 0x00, 0, 0, 0 }, // 061 1 + { 0, 0x0E, 0x11, 0x01, 0x0E, 0x10, 0x1F, 0x00, 0x00, 0, 0, 0 }, // 062 2 + { 0, 0x0E, 0x11, 0x06, 0x01, 0x11, 0x0E, 0x00, 0x00, 0, 0, 0 }, // 063 3 + { 0, 0x02, 0x06, 0x0A, 0x1F, 0x02, 0x02, 0x00, 0x00, 0, 0, 0 }, // 064 4 + { 0, 0x1F, 0x10, 0x1E, 0x01, 0x11, 0x0E, 0x00, 0x00, 0, 0, 0 }, // 065 5 + { 0, 0x0E, 0x10, 0x1E, 0x11, 0x11, 0x0E, 0x00, 0x00, 0, 0, 0 }, // 066 6 + { 0, 0x1F, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0, 0, 0 }, // 067 7 + { 0, 0x0E, 0x11, 0x0E, 0x11, 0x11, 0x0E, 0x00, 0x00, 0, 0, 0 }, // 070 8 + { 0, 0x0E, 0x11, 0x11, 0x0F, 0x01, 0x0E, 0x00, 0x00, 0, 0, 0 }, // 071 9 + { 0, 0x00, 0x04, 0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0, 0, 0 }, // 072 : + { 0, 0x00, 0x04, 0x04, 0x00, 0x06, 0x02, 0x04, 0x00, 0, 0, 0 }, // 073 ; + { 0, 0x00, 0x02, 0x04, 0x08, 0x04, 0x02, 0x00, 0x00, 0, 0, 0 }, // 074 < + { 0, 0x00, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x00, 0x00, 0, 0, 0 }, // 075 = + { 0, 0x00, 0x08, 0x04, 0x02, 0x04, 0x08, 0x00, 0x00, 0, 0, 0 }, // 076 > + { 0, 0x0E, 0x11, 0x01, 0x06, 0x00, 0x04, 0x00, 0x00, 0, 0, 0 }, // 077 ? + { 0, 0x0E, 0x11, 0x17, 0x17, 0x10, 0x0E, 0x00, 0x00, 0, 0, 0 }, // 100 @ + { 0, 0x0E, 0x11, 0x1F, 0x11, 0x11, 0x11, 0x00, 0x00, 0, 0, 0 }, // 101 A + { 0, 0x1E, 0x11, 0x1E, 0x11, 0x11, 0x1E, 0x00, 0x00, 0, 0, 0 }, // 102 B + { 0, 0x0E, 0x11, 0x10, 0x10, 0x11, 0x0E, 0x00, 0x00, 0, 0, 0 }, // 103 C + { 0, 0x1E, 0x11, 0x11, 0x11, 0x11, 0x1E, 0x00, 0x00, 0, 0, 0 }, // 104 D + { 0, 0x1F, 0x10, 0x1E, 0x10, 0x10, 0x1F, 0x00, 0x00, 0, 0, 0 }, // 105 E + { 0, 0x1F, 0x10, 0x1E, 0x10, 0x10, 0x10, 0x00, 0x00, 0, 0, 0 }, // 106 F + { 0, 0x0E, 0x11, 0x10, 0x13, 0x11, 0x0E, 0x00, 0x00, 0, 0, 0 }, // 107 G + { 0, 0x11, 0x11, 0x1F, 0x11, 0x11, 0x11, 0x00, 0x00, 0, 0, 0 }, // 110 H + { 0, 0x0E, 0x04, 0x04, 0x04, 0x04, 0x0E, 0x00, 0x00, 0, 0, 0 }, // 111 I + { 0, 0x01, 0x01, 0x01, 0x01, 0x11, 0x0E, 0x00, 0x00, 0, 0, 0 }, // 112 J + { 0, 0x11, 0x12, 0x14, 0x1C, 0x12, 0x11, 0x00, 0x00, 0, 0, 0 }, // 113 K + { 0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0, 0, 0 }, // 114 L + { 0, 0x11, 0x1B, 0x15, 0x15, 0x11, 0x11, 0x00, 0x00, 0, 0, 0 }, // 115 M + { 0, 0x11, 0x19, 0x15, 0x13, 0x11, 0x11, 0x00, 0x00, 0, 0, 0 }, // 116 N + { 0, 0x0E, 0x11, 0x11, 0x11, 0x11, 0x0E, 0x00, 0x00, 0, 0, 0 }, // 117 O + { 0, 0x1E, 0x11, 0x1E, 0x10, 0x10, 0x10, 0x00, 0x00, 0, 0, 0 }, // 120 P + { 0, 0x0E, 0x11, 0x11, 0x15, 0x13, 0x0E, 0x01, 0x00, 0, 0, 0 }, // 121 Q + { 0, 0x1E, 0x11, 0x1E, 0x14, 0x12, 0x11, 0x00, 0x00, 0, 0, 0 }, // 122 R + { 0, 0x0E, 0x11, 0x0C, 0x02, 0x11, 0x0E, 0x00, 0x00, 0, 0, 0 }, // 123 S + { 0, 0x1F, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0, 0, 0 }, // 124 T + { 0, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E, 0x00, 0x00, 0, 0, 0 }, // 125 U + { 0, 0x11, 0x11, 0x11, 0x0A, 0x0A, 0x04, 0x00, 0x00, 0, 0, 0 }, // 126 V + { 0, 0x11, 0x11, 0x15, 0x15, 0x1B, 0x11, 0x00, 0x00, 0, 0, 0 }, // 127 W + { 0, 0x11, 0x0A, 0x04, 0x0A, 0x11, 0x11, 0x00, 0x00, 0, 0, 0 }, // 130 X + { 0, 0x11, 0x11, 0x0E, 0x04, 0x04, 0x04, 0x00, 0x00, 0, 0, 0 }, // 131 Y + { 0, 0x1F, 0x01, 0x02, 0x08, 0x10, 0x1F, 0x00, 0x00, 0, 0, 0 }, // 132 Z + { 0, 0x0E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0E, 0x00, 0, 0, 0 }, // 133 [ + { 0, 0x10, 0x08, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0, 0, 0 }, // 134 backslash + { 0, 0x0E, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0E, 0x00, 0, 0, 0 }, // 135 ] + { 0, 0x04, 0x0E, 0x15, 0x04, 0x04, 0x04, 0x00, 0x00, 0, 0, 0 }, // 136 ^ + { 0, 0x00, 0x04, 0x08, 0x1F, 0x08, 0x04, 0x00, 0x00, 0, 0, 0 }, // 137 _ + { 0, 0x06, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0, 0, 0 }, // 140 ` + { 0, 0x00, 0x0E, 0x01, 0x0F, 0x11, 0x0D, 0x00, 0x00, 0, 0, 0 }, // 141 a + { 0, 0x10, 0x16, 0x19, 0x11, 0x11, 0x16, 0x00, 0x00, 0, 0, 0 }, // 142 b + { 0, 0x00, 0x0E, 0x10, 0x10, 0x10, 0x0E, 0x00, 0x00, 0, 0, 0 }, // 143 c + { 0, 0x01, 0x0D, 0x13, 0x11, 0x11, 0x0D, 0x00, 0x00, 0, 0, 0 }, // 144 d + { 0, 0x00, 0x0E, 0x11, 0x1F, 0x10, 0x0E, 0x00, 0x00, 0, 0, 0 }, // 145 e + { 0, 0x07, 0x08, 0x1E, 0x08, 0x08, 0x08, 0x00, 0x00, 0, 0, 0 }, // 146 f + { 0, 0x00, 0x0F, 0x11, 0x11, 0x0E, 0x01, 0x1E, 0x00, 0, 0, 0 }, // 147 g + { 0, 0x10, 0x16, 0x19, 0x11, 0x11, 0x11, 0x00, 0x00, 0, 0, 0 }, // 150 h + { 0, 0x04, 0x00, 0x0C, 0x04, 0x04, 0x04, 0x00, 0x00, 0, 0, 0 }, // 151 i + { 0, 0x02, 0x00, 0x06, 0x02, 0x02, 0x02, 0x0C, 0x00, 0, 0, 0 }, // 152 j + { 0, 0x08, 0x09, 0x0A, 0x0C, 0x0A, 0x09, 0x00, 0x00, 0, 0, 0 }, // 153 k + { 0, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0, 0, 0 }, // 154 l + { 0, 0x00, 0x1A, 0x15, 0x15, 0x15, 0x15, 0x00, 0x00, 0, 0, 0 }, // 155 m + { 0, 0x00, 0x16, 0x19, 0x11, 0x11, 0x11, 0x00, 0x00, 0, 0, 0 }, // 156 n + { 0, 0x00, 0x0E, 0x11, 0x11, 0x11, 0x0E, 0x00, 0x00, 0, 0, 0 }, // 157 o + { 0, 0x00, 0x16, 0x19, 0x11, 0x11, 0x16, 0x10, 0x00, 0, 0, 0 }, // 160 p + { 0, 0x00, 0x0D, 0x13, 0x11, 0x11, 0x0D, 0x01, 0x00, 0, 0, 0 }, // 161 q + { 0, 0x00, 0x16, 0x19, 0x10, 0x10, 0x10, 0x00, 0x00, 0, 0, 0 }, // 162 r + { 0, 0x00, 0x0F, 0x10, 0x0E, 0x01, 0x1E, 0x00, 0x00, 0, 0, 0 }, // 163 s + { 0, 0x08, 0x1F, 0x08, 0x08, 0x08, 0x06, 0x00, 0x00, 0, 0, 0 }, // 164 t + { 0, 0x00, 0x11, 0x11, 0x11, 0x11, 0x0D, 0x00, 0x00, 0, 0, 0 }, // 165 u + { 0, 0x00, 0x11, 0x11, 0x0A, 0x0A, 0x04, 0x00, 0x00, 0, 0, 0 }, // 166 v + { 0, 0x00, 0x11, 0x11, 0x15, 0x15, 0x0A, 0x00, 0x00, 0, 0, 0 }, // 167 w + { 0, 0x00, 0x11, 0x0A, 0x04, 0x0A, 0x11, 0x00, 0x00, 0, 0, 0 }, // 170 x + { 0, 0x00, 0x11, 0x11, 0x11, 0x0F, 0x01, 0x0E, 0x00, 0, 0, 0 }, // 171 y + { 0, 0x00, 0x1F, 0x02, 0x04, 0x08, 0x1F, 0x00, 0x00, 0, 0, 0 }, // 172 z + { 0, 0x03, 0x04, 0x04, 0x08, 0x04, 0x04, 0x03, 0x00, 0, 0, 0 }, // 173 { + { 0, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0, 0, 0 }, // 174 | + { 0, 0x00, 0x04, 0x0A, 0x11, 0x0A, 0x04, 0x00, 0x00, 0, 0, 0 }, // 175 altmode + { 0, 0x18, 0x04, 0x04, 0x02, 0x04, 0x04, 0x18, 0x00, 0, 0, 0 }, // 176 } + { 0, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0, 0, 0 }, // 177 +}; + +int main (void) +{ + unsigned int *font; + unsigned int i; + + FILE *f = fopen ("ka10_dd_font.h", "w"); + if (f == NULL) + return 1; + + fprintf (f, "static uint8 font[128][12] = {\n"); + + for (i = 0; i < 128; i++) { + font = sail7_font[i]; + fprintf (f, " { %03o, %03o, %03o, %03o, %03o, %03o, ", + font[0], font[1], font[2], font[3], font[4], font[5]); + fprintf (f, "%03o, %03o, %03o, %03o, %03o, %03o }, // %03o\n", + font[6], font[7], font[8], font[9], font[10], font[11], i); + } + + fprintf (f, "};\n"); + fclose (f); + return 0; +} diff --git a/PDP10/ka10_dd_font.h b/PDP10/ka10_dd_font.h new file mode 100644 index 0000000..7b7573c --- /dev/null +++ b/PDP10/ka10_dd_font.h @@ -0,0 +1,134 @@ +/* ka10_dd_font.h: Font data for Data Disc 6600 Television Display System. + + Copyright (c) 2022-2023, Lars Brinkhoff */ + +static uint8 font[128][12] = { + { 000, 000, 037, 021, 025, 021, 037, 000, 000, 000, 000, 000 }, // 000 + { 000, 004, 004, 004, 025, 016, 004, 000, 000, 000, 000, 000 }, // 001 + { 000, 000, 000, 015, 022, 022, 015, 000, 000, 000, 000, 000 }, // 002 + { 000, 006, 011, 016, 011, 011, 016, 010, 000, 000, 000, 000 }, // 003 + { 000, 000, 004, 012, 021, 000, 000, 000, 000, 000, 000, 000 }, // 004 + { 000, 000, 000, 037, 001, 001, 000, 000, 000, 000, 000, 000 }, // 005 + { 000, 000, 007, 010, 016, 010, 007, 000, 000, 000, 000, 000 }, // 006 + { 000, 000, 037, 012, 012, 012, 011, 000, 000, 000, 000, 000 }, // 007 + { 000, 020, 010, 004, 012, 021, 021, 000, 000, 000, 000, 000 }, // 010 + { 000, 034, 010, 016, 015, 006, 005, 006, 000, 000, 000, 000 }, // 011 + { 000, 020, 020, 027, 034, 007, 004, 004, 000, 000, 000, 000 }, // 012 + { 000, 012, 012, 004, 007, 002, 002, 002, 000, 000, 000, 000 }, // 013 + { 000, 034, 020, 037, 024, 026, 004, 004, 000, 000, 000, 000 }, // 014 + { 000, 016, 020, 026, 025, 016, 005, 005, 000, 000, 000, 000 }, // 015 + { 000, 000, 012, 025, 025, 025, 012, 000, 000, 000, 000, 000 }, // 016 + { 000, 014, 002, 007, 011, 011, 006, 000, 000, 000, 000, 000 }, // 017 + { 000, 000, 017, 020, 020, 017, 000, 000, 000, 000, 000, 000 }, // 020 + { 000, 000, 036, 001, 001, 036, 000, 000, 000, 000, 000, 000 }, // 021 + { 000, 006, 011, 011, 011, 011, 011, 000, 000, 000, 000, 000 }, // 022 + { 000, 011, 011, 011, 011, 011, 006, 000, 000, 000, 000, 000 }, // 023 + { 000, 021, 021, 037, 021, 012, 004, 000, 000, 000, 000, 000 }, // 024 + { 000, 037, 001, 007, 001, 001, 037, 000, 000, 000, 000, 000 }, // 025 + { 000, 000, 016, 025, 033, 025, 016, 000, 000, 000, 000, 000 }, // 026 + { 000, 000, 000, 012, 037, 012, 000, 000, 000, 000, 000, 000 }, // 027 + { 000, 000, 000, 000, 000, 000, 000, 000, 077, 000, 000, 000 }, // 030 + { 000, 000, 004, 002, 037, 002, 004, 000, 000, 000, 000, 000 }, // 031 + { 000, 000, 010, 025, 002, 000, 000, 000, 000, 000, 000, 000 }, // 032 + { 000, 001, 002, 037, 004, 037, 010, 020, 000, 000, 000, 000 }, // 033 + { 000, 000, 002, 004, 010, 004, 002, 017, 000, 000, 000, 000 }, // 034 + { 000, 000, 010, 004, 002, 004, 010, 036, 000, 000, 000, 000 }, // 035 + { 000, 000, 037, 000, 037, 000, 037, 000, 000, 000, 000, 000 }, // 036 + { 000, 000, 021, 012, 004, 000, 000, 000, 000, 000, 000, 000 }, // 037 + { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000 }, // 040 + { 000, 006, 006, 006, 006, 000, 006, 000, 000, 000, 000, 000 }, // 041 + { 000, 012, 012, 012, 000, 000, 000, 000, 000, 000, 000, 000 }, // 042 + { 000, 012, 037, 012, 012, 037, 012, 000, 000, 000, 000, 000 }, // 043 + { 000, 004, 017, 024, 016, 005, 036, 004, 000, 000, 000, 000 }, // 044 + { 000, 037, 031, 002, 004, 013, 023, 000, 000, 000, 000, 000 }, // 045 + { 000, 014, 024, 010, 025, 022, 035, 000, 000, 000, 000, 000 }, // 046 + { 000, 006, 002, 004, 000, 000, 000, 000, 000, 000, 000, 000 }, // 047 + { 000, 002, 004, 010, 010, 010, 004, 002, 000, 000, 000, 000 }, // 050 + { 000, 010, 004, 002, 002, 002, 004, 010, 000, 000, 000, 000 }, // 051 + { 000, 000, 025, 016, 033, 016, 025, 000, 000, 000, 000, 000 }, // 052 + { 000, 000, 004, 004, 037, 004, 004, 000, 000, 000, 000, 000 }, // 053 + { 000, 000, 000, 000, 000, 006, 002, 004, 000, 000, 000, 000 }, // 054 + { 000, 000, 000, 000, 077, 000, 000, 000, 000, 000, 000, 000 }, // 055 + { 000, 000, 000, 000, 000, 004, 004, 000, 000, 000, 000, 000 }, // 056 + { 000, 001, 002, 002, 004, 004, 010, 000, 000, 000, 000, 000 }, // 057 + { 000, 006, 011, 013, 015, 011, 006, 000, 000, 000, 000, 000 }, // 060 + { 000, 002, 006, 002, 002, 002, 007, 000, 000, 000, 000, 000 }, // 061 + { 000, 016, 021, 001, 016, 020, 037, 000, 000, 000, 000, 000 }, // 062 + { 000, 016, 021, 006, 001, 021, 016, 000, 000, 000, 000, 000 }, // 063 + { 000, 002, 006, 012, 037, 002, 002, 000, 000, 000, 000, 000 }, // 064 + { 000, 037, 020, 036, 001, 021, 016, 000, 000, 000, 000, 000 }, // 065 + { 000, 016, 020, 036, 021, 021, 016, 000, 000, 000, 000, 000 }, // 066 + { 000, 037, 001, 002, 002, 004, 004, 000, 000, 000, 000, 000 }, // 067 + { 000, 016, 021, 016, 021, 021, 016, 000, 000, 000, 000, 000 }, // 070 + { 000, 016, 021, 021, 017, 001, 016, 000, 000, 000, 000, 000 }, // 071 + { 000, 000, 004, 004, 000, 004, 004, 000, 000, 000, 000, 000 }, // 072 + { 000, 000, 004, 004, 000, 006, 002, 004, 000, 000, 000, 000 }, // 073 + { 000, 000, 002, 004, 010, 004, 002, 000, 000, 000, 000, 000 }, // 074 + { 000, 000, 000, 037, 000, 037, 000, 000, 000, 000, 000, 000 }, // 075 + { 000, 000, 010, 004, 002, 004, 010, 000, 000, 000, 000, 000 }, // 076 + { 000, 016, 021, 001, 006, 000, 004, 000, 000, 000, 000, 000 }, // 077 + { 000, 016, 021, 027, 027, 020, 016, 000, 000, 000, 000, 000 }, // 100 + { 000, 016, 021, 037, 021, 021, 021, 000, 000, 000, 000, 000 }, // 101 + { 000, 036, 021, 036, 021, 021, 036, 000, 000, 000, 000, 000 }, // 102 + { 000, 016, 021, 020, 020, 021, 016, 000, 000, 000, 000, 000 }, // 103 + { 000, 036, 021, 021, 021, 021, 036, 000, 000, 000, 000, 000 }, // 104 + { 000, 037, 020, 036, 020, 020, 037, 000, 000, 000, 000, 000 }, // 105 + { 000, 037, 020, 036, 020, 020, 020, 000, 000, 000, 000, 000 }, // 106 + { 000, 016, 021, 020, 023, 021, 016, 000, 000, 000, 000, 000 }, // 107 + { 000, 021, 021, 037, 021, 021, 021, 000, 000, 000, 000, 000 }, // 110 + { 000, 016, 004, 004, 004, 004, 016, 000, 000, 000, 000, 000 }, // 111 + { 000, 001, 001, 001, 001, 021, 016, 000, 000, 000, 000, 000 }, // 112 + { 000, 021, 022, 024, 034, 022, 021, 000, 000, 000, 000, 000 }, // 113 + { 000, 020, 020, 020, 020, 020, 037, 000, 000, 000, 000, 000 }, // 114 + { 000, 021, 033, 025, 025, 021, 021, 000, 000, 000, 000, 000 }, // 115 + { 000, 021, 031, 025, 023, 021, 021, 000, 000, 000, 000, 000 }, // 116 + { 000, 016, 021, 021, 021, 021, 016, 000, 000, 000, 000, 000 }, // 117 + { 000, 036, 021, 036, 020, 020, 020, 000, 000, 000, 000, 000 }, // 120 + { 000, 016, 021, 021, 025, 023, 016, 001, 000, 000, 000, 000 }, // 121 + { 000, 036, 021, 036, 024, 022, 021, 000, 000, 000, 000, 000 }, // 122 + { 000, 016, 021, 014, 002, 021, 016, 000, 000, 000, 000, 000 }, // 123 + { 000, 037, 004, 004, 004, 004, 004, 000, 000, 000, 000, 000 }, // 124 + { 000, 021, 021, 021, 021, 021, 016, 000, 000, 000, 000, 000 }, // 125 + { 000, 021, 021, 021, 012, 012, 004, 000, 000, 000, 000, 000 }, // 126 + { 000, 021, 021, 025, 025, 033, 021, 000, 000, 000, 000, 000 }, // 127 + { 000, 021, 012, 004, 012, 021, 021, 000, 000, 000, 000, 000 }, // 130 + { 000, 021, 021, 016, 004, 004, 004, 000, 000, 000, 000, 000 }, // 131 + { 000, 037, 001, 002, 010, 020, 037, 000, 000, 000, 000, 000 }, // 132 + { 000, 016, 010, 010, 010, 010, 010, 016, 000, 000, 000, 000 }, // 133 + { 000, 020, 010, 004, 004, 002, 001, 000, 000, 000, 000, 000 }, // 134 + { 000, 016, 002, 002, 002, 002, 002, 016, 000, 000, 000, 000 }, // 135 + { 000, 004, 016, 025, 004, 004, 004, 000, 000, 000, 000, 000 }, // 136 + { 000, 000, 004, 010, 037, 010, 004, 000, 000, 000, 000, 000 }, // 137 + { 000, 006, 004, 002, 000, 000, 000, 000, 000, 000, 000, 000 }, // 140 + { 000, 000, 016, 001, 017, 021, 015, 000, 000, 000, 000, 000 }, // 141 + { 000, 020, 026, 031, 021, 021, 026, 000, 000, 000, 000, 000 }, // 142 + { 000, 000, 016, 020, 020, 020, 016, 000, 000, 000, 000, 000 }, // 143 + { 000, 001, 015, 023, 021, 021, 015, 000, 000, 000, 000, 000 }, // 144 + { 000, 000, 016, 021, 037, 020, 016, 000, 000, 000, 000, 000 }, // 145 + { 000, 007, 010, 036, 010, 010, 010, 000, 000, 000, 000, 000 }, // 146 + { 000, 000, 017, 021, 021, 016, 001, 036, 000, 000, 000, 000 }, // 147 + { 000, 020, 026, 031, 021, 021, 021, 000, 000, 000, 000, 000 }, // 150 + { 000, 004, 000, 014, 004, 004, 004, 000, 000, 000, 000, 000 }, // 151 + { 000, 002, 000, 006, 002, 002, 002, 014, 000, 000, 000, 000 }, // 152 + { 000, 010, 011, 012, 014, 012, 011, 000, 000, 000, 000, 000 }, // 153 + { 000, 014, 004, 004, 004, 004, 004, 000, 000, 000, 000, 000 }, // 154 + { 000, 000, 032, 025, 025, 025, 025, 000, 000, 000, 000, 000 }, // 155 + { 000, 000, 026, 031, 021, 021, 021, 000, 000, 000, 000, 000 }, // 156 + { 000, 000, 016, 021, 021, 021, 016, 000, 000, 000, 000, 000 }, // 157 + { 000, 000, 026, 031, 021, 021, 026, 020, 000, 000, 000, 000 }, // 160 + { 000, 000, 015, 023, 021, 021, 015, 001, 000, 000, 000, 000 }, // 161 + { 000, 000, 026, 031, 020, 020, 020, 000, 000, 000, 000, 000 }, // 162 + { 000, 000, 017, 020, 016, 001, 036, 000, 000, 000, 000, 000 }, // 163 + { 000, 010, 037, 010, 010, 010, 006, 000, 000, 000, 000, 000 }, // 164 + { 000, 000, 021, 021, 021, 021, 015, 000, 000, 000, 000, 000 }, // 165 + { 000, 000, 021, 021, 012, 012, 004, 000, 000, 000, 000, 000 }, // 166 + { 000, 000, 021, 021, 025, 025, 012, 000, 000, 000, 000, 000 }, // 167 + { 000, 000, 021, 012, 004, 012, 021, 000, 000, 000, 000, 000 }, // 170 + { 000, 000, 021, 021, 021, 017, 001, 016, 000, 000, 000, 000 }, // 171 + { 000, 000, 037, 002, 004, 010, 037, 000, 000, 000, 000, 000 }, // 172 + { 000, 003, 004, 004, 010, 004, 004, 003, 000, 000, 000, 000 }, // 173 + { 000, 004, 004, 004, 004, 004, 004, 004, 000, 000, 000, 000 }, // 174 + { 000, 000, 004, 012, 021, 012, 004, 000, 000, 000, 000, 000 }, // 175 + { 000, 030, 004, 004, 002, 004, 004, 030, 000, 000, 000, 000 }, // 176 + { 000, 077, 077, 077, 077, 077, 077, 077, 077, 000, 000, 000 }, // 177 +}; diff --git a/PDP10/ka10_dkb.c b/PDP10/ka10_dkb.c index 2b044a0..163195c 100644 --- a/PDP10/ka10_dkb.c +++ b/PDP10/ka10_dkb.c @@ -44,8 +44,8 @@ #define CHAR 001777 #define SHFT 000100 #define TOP 000200 -#define META 000400 -#define CTRL 001000 +#define CTRL 000400 +#define META 001000 #define STATUS u3 #define DATA u4 @@ -53,6 +53,7 @@ #define LINE u6 t_stat dkb_devio(uint32 dev, uint64 *data); +t_stat dkb_svc(UNIT *uptr); int dkb_keyboard (SIM_KEY_EVENT *kev); t_stat dkb_reset(DEVICE *dptr); t_stat dkb_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); @@ -64,8 +65,7 @@ int dkb_kmod = 0; DIB dkb_dib = { DKB_DEVNUM, 1, dkb_devio, NULL}; UNIT dkb_unit[] = { - {UDATA (NULL, UNIT_IDLE, 0) }, - { 0 } + {UDATA (&dkb_svc, UNIT_IDLE, 0) }, }; @@ -75,7 +75,7 @@ MTAB dkb_mod[] = { DEVICE dkb_dev = { "DKB", dkb_unit, NULL, dkb_mod, - 2, 10, 31, 1, 8, 8, + 1, 10, 31, 1, 8, 8, NULL, NULL, dkb_reset, NULL, NULL, NULL, &dkb_dib, DEV_DEBUG | DEV_DISABLE | DEV_DIS, 0, dev_debug, NULL, NULL, &dkb_help, NULL, NULL, &dkb_description @@ -127,11 +127,11 @@ int dkb_modifiers (SIM_KEY_EVENT *kev) return 1; case SIM_KEY_WIN_L: case SIM_KEY_WIN_R: - dkb_kmod |= META; + dkb_kmod |= TOP; return 1; case SIM_KEY_ALT_L: case SIM_KEY_ALT_R: - dkb_kmod |= TOP; + dkb_kmod |= META; return 1; } return 0; @@ -149,11 +149,11 @@ int dkb_modifiers (SIM_KEY_EVENT *kev) return 1; case SIM_KEY_WIN_L: case SIM_KEY_WIN_R: - dkb_kmod &= ~META; + dkb_kmod &= ~TOP; return 1; case SIM_KEY_ALT_L: case SIM_KEY_ALT_R: - dkb_kmod &= ~TOP; + dkb_kmod &= ~META; return 1; } return 0; @@ -163,8 +163,11 @@ int dkb_modifiers (SIM_KEY_EVENT *kev) int dkb_keys (SIM_KEY_EVENT *kev, UNIT *uptr) { - if (kev->state == SIM_KEYPRESS_UP) + if (kev->state == SIM_KEYPRESS_UP) { + if (kev->key == SIM_KEY_F11) + vid_set_fullscreen_window (kev->vptr, !vid_is_fullscreen_window (kev->vptr)); return 0; + } switch (kev->key) { case SIM_KEY_0: /* ok */ @@ -181,7 +184,7 @@ int dkb_keys (SIM_KEY_EVENT *kev, UNIT *uptr) return 1; case SIM_KEY_2: if ((dkb_kmod & (TOP|SHFT)) == TOP) - uptr->DATA = (dkb_kmod | 052) & ~TOP; /* Circle Star */ + uptr->DATA = (dkb_kmod | 005) & ~TOP; /* @ */ else uptr->DATA = dkb_kmod | 062; return 1; @@ -211,19 +214,19 @@ int dkb_keys (SIM_KEY_EVENT *kev, UNIT *uptr) return 1; case SIM_KEY_7: if ((dkb_kmod & (TOP|SHFT)) == TOP) - uptr->DATA = (dkb_kmod | 024) & ~TOP; /* & */ + uptr->DATA = (dkb_kmod | 024) & ~TOP; /* & (TOP+T) */ else uptr->DATA = dkb_kmod | 067; return 1; case SIM_KEY_8: /* ok */ if ((dkb_kmod & (TOP|SHFT)) == TOP) - uptr->DATA = (dkb_kmod | 052) & ~TOP; /* * */ + uptr->DATA = dkb_kmod | 052 | SHFT; /* * */ else uptr->DATA = dkb_kmod | 070; return 1; case SIM_KEY_9: /* ok */ if ((dkb_kmod & (TOP|SHFT)) == TOP) - uptr->DATA = dkb_kmod | 050; /* ( */ + uptr->DATA = dkb_kmod | 050 | SHFT; /* ( */ else uptr->DATA = dkb_kmod | 071; return 1; @@ -308,38 +311,41 @@ int dkb_keys (SIM_KEY_EVENT *kev, UNIT *uptr) case SIM_KEY_Z: uptr->DATA = dkb_kmod | 032; return 1; - case SIM_KEY_BACKQUOTE: /* ` ~ */ + case SIM_KEY_BACKQUOTE: if ((dkb_kmod & (TOP|SHFT)) == TOP) - uptr->DATA = dkb_kmod | 043; + uptr->DATA = (dkb_kmod | 025) & ~TOP; //` (TOP+U) else - uptr->DATA = dkb_kmod | 00; + uptr->DATA = (dkb_kmod | 070) & ~TOP; //~ (TOP+8) return 1; case SIM_KEY_MINUS: /* - not */ - uptr->DATA = dkb_kmod | 055; + if ((dkb_kmod & (TOP|SHFT)) == TOP) + uptr->DATA = (dkb_kmod | 071) & ~TOP; //_ (TOP+9) + else + uptr->DATA = dkb_kmod | 055; return 1; case SIM_KEY_EQUALS: /* = + */ if ((dkb_kmod & (TOP|SHFT)) == TOP) - uptr->DATA = dkb_kmod | 053; + uptr->DATA = dkb_kmod | 053 | SHFT; else - uptr->DATA = (dkb_kmod | 010) & ~TOP; + uptr->DATA = (dkb_kmod | 010) & ~TOP; //TOP+H return 1; case SIM_KEY_LEFT_BRACKET: /* [ { */ if ((dkb_kmod & (TOP|SHFT)) == TOP) - uptr->DATA = (dkb_kmod | 017) & ~TOP; + uptr->DATA = (dkb_kmod | 017) & ~TOP; //TOP+P else - uptr->DATA = (dkb_kmod | 050) & ~TOP;; + uptr->DATA = (dkb_kmod | 050) & ~TOP; //TOP+( return 1; case SIM_KEY_RIGHT_BRACKET: /* ] } */ if ((dkb_kmod & (TOP|SHFT)) == TOP) - uptr->DATA = (dkb_kmod | 020) & ~TOP; + uptr->DATA = (dkb_kmod | 020) & ~TOP; //TOP+O else - uptr->DATA = (dkb_kmod | 051) & ~TOP;; + uptr->DATA = (dkb_kmod | 051) & ~TOP; //TOP+) return 1; case SIM_KEY_SEMICOLON: /* ; : */ if ((dkb_kmod & (TOP|SHFT)) == TOP) - uptr->DATA = dkb_kmod | 072 | TOP; + uptr->DATA = dkb_kmod | 072 | SHFT; else - uptr->DATA = dkb_kmod | 073 | TOP; + uptr->DATA = dkb_kmod | 073; return 1; case SIM_KEY_SINGLE_QUOTE: /* ok */ /* ' " */ if ((dkb_kmod & (TOP|SHFT)) == TOP) @@ -349,35 +355,33 @@ int dkb_keys (SIM_KEY_EVENT *kev, UNIT *uptr) return 1; case SIM_KEY_BACKSLASH: /* Ok */ if ((dkb_kmod & (TOP|SHFT)) == TOP) /* \ | */ - uptr->DATA = (dkb_kmod | 053) & ~TOP; - else if ((dkb_kmod & (TOP|SHFT)) == SHFT) - uptr->DATA = (dkb_kmod | 034) & ~TOP; + uptr->DATA = (dkb_kmod | 053) & ~TOP; //TOP++ else - uptr->DATA = dkb_kmod | 034 | TOP; + uptr->DATA = dkb_kmod | 034; return 1; case SIM_KEY_LEFT_BACKSLASH: uptr->DATA = dkb_kmod | 034; return 1; case SIM_KEY_COMMA: /* ok */ if ((dkb_kmod & (TOP|SHFT)) == TOP) /* , < */ - uptr->DATA = (dkb_kmod | 04) & ~TOP; + uptr->DATA = (dkb_kmod | 04) & ~TOP; //TOP+D else - uptr->DATA = dkb_kmod | 054 | TOP; + uptr->DATA = dkb_kmod | 054; return 1; case SIM_KEY_PERIOD: /* Ok */ if ((dkb_kmod & (TOP|SHFT)) == TOP) /* . > */ - uptr->DATA = (dkb_kmod | 06) & ~TOP; + uptr->DATA = (dkb_kmod | 06) & ~TOP; //TOP+F else uptr->DATA = dkb_kmod | 056; return 1; case SIM_KEY_SLASH: /* Ok */ if ((dkb_kmod & (TOP|SHFT)) == TOP) /* / ? */ - uptr->DATA = (dkb_kmod | 056) & ~TOP; + uptr->DATA = (dkb_kmod | 056) & ~TOP; //TOP+. else uptr->DATA = dkb_kmod | 057; return 1; case SIM_KEY_ESC: - uptr->DATA = dkb_kmod | 042; + uptr->DATA = dkb_kmod | 075; //ALT return 1; case SIM_KEY_BACKSPACE: uptr->DATA = dkb_kmod | 074; @@ -394,20 +398,65 @@ int dkb_keys (SIM_KEY_EVENT *kev, UNIT *uptr) case SIM_KEY_SPACE: uptr->DATA = dkb_kmod | 040; return 1; + case SIM_KEY_F1: + uptr->DATA = dkb_kmod | 043; //CALL + return 1; + case SIM_KEY_F2: + uptr->DATA = dkb_kmod | 042; //ESC + return 1; + case SIM_KEY_F3: + uptr->DATA = dkb_kmod | 041; //BREAK + return 1; + case SIM_KEY_F4: + uptr->DATA = dkb_kmod | 035; //LINE + return 1; + case SIM_KEY_F5: + uptr->DATA = dkb_kmod | 046; //FORM + return 1; + case SIM_KEY_F6: + uptr->DATA = dkb_kmod | 047; //VT + return 1; + case SIM_KEY_LEFT: + uptr->DATA = (dkb_kmod | 012) & ~TOP; //Left arrow (TOP+J) + return 1; + case SIM_KEY_RIGHT: + uptr->DATA = (dkb_kmod | 013) & ~TOP; //Right arrow (TOP+K) + return 1; + case SIM_KEY_DOWN: + uptr->DATA = (dkb_kmod | 072 ) & ~TOP; //Down arrow (TOP+;) + return 1; + case SIM_KEY_UP: + uptr->DATA = (dkb_kmod | 073) & ~TOP; //Up arrow (TOP+:) + return 1; default: return 0; } } +uint32 dkb_line (SIM_KEY_EVENT *kev) +{ +#if NUM_DEVS_III + if (kev->dev == &iii_dev) + return iii_keyboard_line ((void *)kev->vptr); +#endif +#if NUM_DEVS_DD + if (kev->dev == &dd_dev) + return dd_keyboard_line ((void *)kev->vptr); +#endif + return ~0U; +} + int dkb_keyboard (SIM_KEY_EVENT *kev) { sim_debug(DEBUG_DETAIL, &dkb_dev, "DKB key %d %o\n", kev->key, kev->state); if (dkb_modifiers (kev)) return 0; - if (dkb_keys (kev, &dkb_unit[0])) { + dkb_unit[0].LINE = dkb_line (kev); + if (dkb_unit[0].LINE != ~0U && dkb_keys (kev, &dkb_unit[0])) { dkb_unit[0].DATA |= VALID; dkb_unit[0].STATUS |= DONE; + sim_debug(DEBUG_DETAIL, &dkb_dev, "DKB interrupt, data %o\n", dkb_unit[0].DATA); set_interrupt(DKB_DEVNUM, dkb_unit[0].PIA); return 0; } @@ -415,11 +464,19 @@ int dkb_keyboard (SIM_KEY_EVENT *kev) return 1; } +t_stat dkb_svc(UNIT *uptr) +{ + SIM_KEY_EVENT ev; + sim_activate_after (uptr, 10000); + if (vid_poll_kb (&ev) == SCPE_OK) + dkb_keyboard (&ev); + return SCPE_OK; +} t_stat dkb_reset( DEVICE *dptr) { if ((dkb_dev.flags & DEV_DIS) == 0) - vid_display_kb_event_process = dkb_keyboard; + sim_activate_abs (dkb_unit, 0); dkb_kmod = SHFT|TOP|META|CTRL; return SCPE_OK; } @@ -427,12 +484,12 @@ t_stat dkb_reset( DEVICE *dptr) t_stat dkb_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) { - fprintf (stderr, "This is the keyboard input for the Stanford III display\n"); + fprintf (stderr, "Keyboard input for the Stanford III and Data Disc displays\n"); return SCPE_OK; } const char *dkb_description (DEVICE *dptr) { - return "Keyboard scanner for III display devices"; + return "Keyboard scanner for III and DD display devices"; } #endif diff --git a/PDP10/ka10_iii.c b/PDP10/ka10_iii.c index 167b57b..341a1b6 100644 --- a/PDP10/ka10_iii.c +++ b/PDP10/ka10_iii.c @@ -635,6 +635,12 @@ skip_up: return SCPE_OK; } +uint32 iii_keyboard_line (void *p) +{ + /* III keyboards are 0 to 5, but only one is supported now. */ + return 0; +} + t_stat iii_reset (DEVICE *dptr) { if (dptr->flags & DEV_DIS) { diff --git a/PDP10/kx10_defs.h b/PDP10/kx10_defs.h index 92abc5a..75da569 100644 --- a/PDP10/kx10_defs.h +++ b/PDP10/kx10_defs.h @@ -513,6 +513,8 @@ extern DEVICE pd_dev; extern DEVICE pclk_dev; extern DEVICE dpy_dev; extern DEVICE iii_dev; +extern DEVICE dd_dev; +extern DEVICE vds_dev; extern DEVICE imx_dev; extern DEVICE imp_dev; extern DEVICE ch10_dev; @@ -791,6 +793,7 @@ extern void ka10_lights_clear_aux (int); #define NUM_DEVS_DKB (WAITS * USE_DISPLAY) #define NUM_DEVS_III (WAITS * USE_DISPLAY) #define NUM_DEVS_TV (WAITS * USE_DISPLAY) +#define NUM_DEVS_DD (WAITS * USE_DISPLAY) #define NUM_DEVS_PD ITS #define NUM_DEVS_PCLK WAITS #define NUM_DEVS_IMX ITS @@ -843,6 +846,12 @@ extern UNIT auxcpu_unit[]; //int slave_write (t_addr addr, uint64); //extern UNIT slave_unit[]; #endif +#if NUM_DEVS_III +extern uint32 iii_keyboard_line (void *); +#endif +#if NUM_DEVS_DD +extern uint32 dd_keyboard_line (void *); +#endif #if PIDP10 void pi_panel_start(); diff --git a/PDP10/kx10_sys.c b/PDP10/kx10_sys.c index 01c2b50..eb9c47e 100644 --- a/PDP10/kx10_sys.c +++ b/PDP10/kx10_sys.c @@ -177,6 +177,10 @@ DEVICE *sim_devices[] = { #if (NUM_DEVS_TV > 0) &tv_dev, #endif +#if (NUM_DEVS_DD > 0) + &dd_dev, + &vds_dev, +#endif #if NUM_DEVS_IMP > 0 &imp_dev, #endif diff --git a/Visual Studio Projects/PDP10-KA.vcproj b/Visual Studio Projects/PDP10-KA.vcproj index f16cc30..e8659cf 100644 --- a/Visual Studio Projects/PDP10-KA.vcproj +++ b/Visual Studio Projects/PDP10-KA.vcproj @@ -209,6 +209,10 @@ RelativePath="..\PDP10\ka10_dkb.c" > + + diff --git a/makefile b/makefile index acb0e99..2c72904 100644 --- a/makefile +++ b/makefile @@ -1448,6 +1448,7 @@ KA10 = ${KA10D}/kx10_cpu.c ${KA10D}/kx10_sys.c ${KA10D}/kx10_df.c \ ${KA10D}/pdp6_dcs.c ${KA10D}/ka10_dpk.c ${KA10D}/kx10_dpy.c \ ${PDP10D}/ka10_ai.c ${KA10D}/ka10_iii.c ${KA10D}/kx10_disk.c \ ${PDP10D}/ka10_pclk.c ${PDP10D}/ka10_tv.c ${KA10D}/kx10_ddc.c \ + ${PDP10D}/ka10_dd.c \ ${DISPLAYL} ${DISPLAY340} KA10_OPT = -DKA=1 -DUSE_INT64 -I ${KA10D} -DUSE_SIM_CARD ${NETWORK_OPT} ${DISPLAY_OPT} ${KA10_DISPLAY_OPT} ifneq (${PANDA_LIGHTS},)