simh-testsetgenerator/PDP11/pdp11_daz.c

242 lines
7.8 KiB
C

#ifdef USE_DISPLAY
/* pdp11_daz.c: Control box
Copyright (c) 2018, 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
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the names of the authors shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the authors.
*/
#include "pdp11_defs.h"
#include "sim_video.h"
#include "pdp11_dazzle_dart_rom.h"
#define TURN_RIGHT 0001
#define TURN_LEFT 0002
#define GO_RIGHT 0004
#define GO_LEFT 0010
#define GO_UP 0020
#define GO_DOWN 0040
#define PASS 0100
#define FIRE 0200
t_stat daz_rd(int32 *data, int32 PA, int32 access);
t_stat daz_wr(int32 data, int32 PA, int32 access);
t_stat daz_reset(DEVICE *dptr);
t_stat daz_boot(int32 unit, DEVICE *dptr);
t_stat daz_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
const char *daz_description (DEVICE *dptr);
static int devadd = 0;
static int buttons[4] = { ~0, ~0, ~0, ~0 };
#define IOLN_DAZ 4
DIB daz_dib = {
IOBA_AUTO, IOLN_DAZ, &daz_rd, &daz_wr,
4, 0, VEC_AUTO, {NULL}, IOLN_DAZ
};
UNIT daz_unit = {
UDATA (NULL, 0, 0)
};
REG daz_reg[] = {
{ GRDATAD(DEVADD, devadd, 16, 16, 0, "Box selection"), REG_FIT},
{ NULL }
};
MTAB daz_mod[] = {
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 020, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL, "Bus address" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL, "Interrupt vector" },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "AUTOCONFIGURE",
&set_addr_flt, NULL, NULL, "Enable autoconfiguration of address & vector" },
{ 0 } };
DEVICE daz_dev = {
"DAZ", &daz_unit, daz_reg, daz_mod,
1, 8, 16, 1, 8, 16,
NULL, NULL, &daz_reset,
&daz_boot, NULL, NULL,
&daz_dib, DEV_DIS | DEV_DISABLE | DEV_UBUS,
0, NULL, NULL, NULL, NULL, &daz_help, NULL,
&daz_description
};
const char *daz_regnam[] = {
"DEVADD",
"DEVICE",
};
t_stat
daz_rd(int32 *data, int32 PA, int32 access)
{
switch (PA & 002) {
case 000:
*data = 0x0000;
break;
case 002:
*data = 0x8000 | buttons[(devadd >> 10) & 3];
break;
default:
return SCPE_NXM;
}
return SCPE_OK;
}
t_stat
daz_wr(int32 data, int32 PA, int32 access)
{
switch (PA & 002) {
case 000:
devadd = data;
return SCPE_OK;
case 002:
return SCPE_OK;
}
return SCPE_NXM;
}
int daz_keyboard (SIM_KEY_EVENT *kev)
{
uint32 mask;
int n;
switch (kev->key) {
case SIM_KEY_1: n = 0; mask = GO_LEFT; break;
case SIM_KEY_2: n = 0; mask = GO_RIGHT; break;
case SIM_KEY_3: n = 0; mask = GO_UP; break;
case SIM_KEY_4: n = 0; mask = GO_DOWN; break;
case SIM_KEY_5: n = 0; mask = TURN_LEFT; break;
case SIM_KEY_6: n = 0; mask = TURN_RIGHT; break;
case SIM_KEY_7: n = 0; mask = FIRE; break;
case SIM_KEY_8: n = 0; mask = PASS; break;
case SIM_KEY_Q: n = 1; mask = GO_LEFT; break;
case SIM_KEY_W: n = 1; mask = GO_RIGHT; break;
case SIM_KEY_E: n = 1; mask = GO_UP; break;
case SIM_KEY_R: n = 1; mask = GO_DOWN; break;
case SIM_KEY_T: n = 1; mask = TURN_LEFT; break;
case SIM_KEY_Y: n = 1; mask = TURN_RIGHT; break;
case SIM_KEY_U: n = 1; mask = FIRE; break;
case SIM_KEY_I: n = 1; mask = PASS; break;
case SIM_KEY_A: n = 2; mask = GO_LEFT; break;
case SIM_KEY_S: n = 2; mask = GO_RIGHT; break;
case SIM_KEY_D: n = 2; mask = GO_UP; break;
case SIM_KEY_F: n = 2; mask = GO_DOWN; break;
case SIM_KEY_G: n = 2; mask = TURN_LEFT; break;
case SIM_KEY_H: n = 2; mask = TURN_RIGHT; break;
case SIM_KEY_J: n = 2; mask = FIRE; break;
case SIM_KEY_K: n = 2; mask = PASS; break;
case SIM_KEY_Z: n = 3; mask = GO_LEFT; break;
case SIM_KEY_X: n = 3; mask = GO_RIGHT; break;
case SIM_KEY_C: n = 3; mask = GO_UP; break;
case SIM_KEY_V: n = 3; mask = GO_DOWN; break;
case SIM_KEY_B: n = 3; mask = TURN_LEFT; break;
case SIM_KEY_N: n = 3; mask = TURN_RIGHT; break;
case SIM_KEY_M: n = 3; mask = FIRE; break;
case SIM_KEY_COMMA: n = 3; mask = PASS; break;
default: return 0;
}
if (kev->state == SIM_KEYPRESS_UP)
buttons[n] |= mask;
else if (kev->state == SIM_KEYPRESS_DOWN)
buttons[n] &= ~mask;
return 0;
}
t_stat
daz_reset(DEVICE *dptr)
{
DEVICE *ng_dptr;
t_stat r;
if (dptr->flags & DEV_DIS) {
vid_display_kb_event_process = NULL;
return auto_config ("DAZ", (dptr->flags & DEV_DIS) ? 0 : 1);;
}
ng_dptr = find_dev ("NG");
if ((ng_dptr != NULL) && ((ng_dptr->flags & DEV_DIS) != 0)) {
set_cmd (0, "CPU 11/45"); /* Need a Unibus machine. */
r = set_cmd (0, "NG ENABLED"); /* Need NG display. */
if (r != SCPE_OK) {
dptr->flags |= DEV_DIS;
return r;
}
set_cmd (0, "DZ DISABLED"); /* DZ is in conflict with NG. */
}
r = auto_config ("DAZ", (dptr->flags & DEV_DIS) ? 0 : 1);
if (r != SCPE_OK)
return r;
vid_display_kb_event_process = &daz_keyboard;
return SCPE_OK;
}
/* Apologies to Wolfgang Petersen. */
t_stat
daz_boot(int32 unit, DEVICE *dptr)
{
t_stat r;
set_cmd (0, "CPU 56K");
set_cmd (0, "NG TYPE=DAZZLE");
set_cmd (0, "PCLK ENABLED");
set_cmd (0, "KE ENABLED");
sim_set_memory_load_file (BOOT_CODE_ARRAY, BOOT_CODE_SIZE);
r = load_cmd (0, BOOT_CODE_FILENAME);
sim_set_memory_load_file (NULL, 0);
cpu_set_boot (03252);
return r;
}
const char *daz_description (DEVICE *dptr)
{
return "Input buttons for Dazzle Dart";
}
t_stat daz_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
{
/* The '*'s in the next line represent the standard text width of a help line */
/****************************************************************************/
fprintf(st, "%s\n\n", daz_description (dptr));
fprintf(st, "The DAZ is a set of input buttons for the simulation of the MIT Logo\n");
fprintf(st, "group PDP-11/45. There are four sets of eight buttons. The buttons are:\n");
fprintf(st, "ROTATE LEFT, ROTATE RIGHT, MOVE LEFT, MOVE RIGHT, MOVE UP, MOVE DOWN,\n");
fprintf(st, "PASS, and FIRE.\n\n");
fprintf(st, "The first set is mapped from the keys 1-8. The second set is mapped from\n");
fprintf(st, "Q-I. The first set is mapped from A-K. The fourth set is mapped\n");
fprintf(st, "from Z-, (comma).\n\n");
fprintf(st, "The only software for the DAZ was the Dazzle Dart game by\n");
fprintf(st, "Hal Abelson, Andy diSessa, and Nat Goodman. To play the game:\n\n\n");
fprintf(st, " sim> set daz enable\n");
fprintf(st, " sim> boot daz\n\n");
return SCPE_OK;
}
#else /* USE_DISPLAY not defined */
char pdp11_daz_unused; /* sometimes empty object modules cause problems */
#endif /* USE_DISPLAY not defined */