mirror of
https://github.com/rcornwell/sims.git
synced 2026-01-22 10:31:12 +00:00
Merge branch 'larsbrinkhoff-lars/ddd'
This commit is contained in:
commit
25d5fa8a32
756
PDP10/ka10_dd.c
Normal file
756
PDP10/ka10_dd.c
Normal file
@ -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
|
||||
1858
PDP10/ka10_dd_font.c
Normal file
1858
PDP10/ka10_dd_font.c
Normal file
File diff suppressed because it is too large
Load Diff
134
PDP10/ka10_dd_font.h
Normal file
134
PDP10/ka10_dd_font.h
Normal file
@ -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
|
||||
};
|
||||
135
PDP10/ka10_dkb.c
135
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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -209,6 +209,10 @@
|
||||
RelativePath="..\PDP10\ka10_dkb.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\PDP10\ka10_dd.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\PDP10\ka10_dpk.c"
|
||||
>
|
||||
|
||||
1
makefile
1
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},)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user