BESM6: Implemented hardwired front panel programs,

smoothed front panel lights, corrected a typo in besm6_tty.c
This commit is contained in:
Leo Broukhis 2015-01-14 00:39:55 -08:00
parent a71e5e0599
commit 9ff642f616
6 changed files with 290 additions and 76 deletions

View file

@ -92,6 +92,9 @@ t_stat cpu_examine (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
t_stat cpu_deposit (t_value val, t_addr addr, UNIT *uptr, int32 sw); t_stat cpu_deposit (t_value val, t_addr addr, UNIT *uptr, int32 sw);
t_stat cpu_reset (DEVICE *dptr); t_stat cpu_reset (DEVICE *dptr);
t_stat cpu_req (UNIT *u, int32 val, char *cptr, void *desc); t_stat cpu_req (UNIT *u, int32 val, char *cptr, void *desc);
t_stat cpu_set_pult (UNIT *u, int32 val, char *cptr, void *desc);
t_stat cpu_show_pult (FILE *st, struct sim_unit *up, int32 v, void *dp);
/* /*
* CPU data structures * CPU data structures
@ -147,6 +150,7 @@ MTAB cpu_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, NULL, "REQ", &cpu_req, NULL, NULL, "Sends a request interrupt" }, { MTAB_XTD|MTAB_VDV, 0, NULL, "REQ", &cpu_req, NULL, NULL, "Sends a request interrupt" },
{ MTAB_XTD|MTAB_VDV, 0, "PANEL", "PANEL", &besm6_init_panel, NULL, NULL, "Displays graphical panel" }, { MTAB_XTD|MTAB_VDV, 0, "PANEL", "PANEL", &besm6_init_panel, NULL, NULL, "Displays graphical panel" },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "NOPANEL", &besm6_close_panel, NULL, NULL, "Closes graphical panel" }, { MTAB_XTD|MTAB_VDV, 0, NULL, "NOPANEL", &besm6_close_panel, NULL, NULL, "Closes graphical panel" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALO, 0, "PULT", "PULT", &cpu_set_pult, &cpu_show_pult, NULL, "Selects a hardwired program or switch reg." },
{ 0 } { 0 }
}; };
@ -222,13 +226,13 @@ REG reg_reg[] = {
{ "RP6", &RP[6], 8, 48, 0, 1, NULL, NULL, REG_VMIO }, { "RP6", &RP[6], 8, 48, 0, 1, NULL, NULL, REG_VMIO },
{ "RP7", &RP[7], 8, 48, 0, 1, NULL, NULL, REG_VMIO }, { "RP7", &RP[7], 8, 48, 0, 1, NULL, NULL, REG_VMIO },
{ "RZ", &RZ, 8, 32, 0, 1 }, { "RZ", &RZ, 8, 32, 0, 1 },
{ "FP1", &pult[1], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, { "FP1", &pult[0][1], 8, 50, 0, 1, NULL, NULL, REG_VMIO },
{ "FP2", &pult[2], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, { "FP2", &pult[0][2], 8, 50, 0, 1, NULL, NULL, REG_VMIO },
{ "FP3", &pult[3], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, { "FP3", &pult[0][3], 8, 50, 0, 1, NULL, NULL, REG_VMIO },
{ "FP4", &pult[4], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, { "FP4", &pult[0][4], 8, 50, 0, 1, NULL, NULL, REG_VMIO },
{ "FP5", &pult[5], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, { "FP5", &pult[0][5], 8, 50, 0, 1, NULL, NULL, REG_VMIO },
{ "FP6", &pult[6], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, { "FP6", &pult[0][6], 8, 50, 0, 1, NULL, NULL, REG_VMIO },
{ "FP7", &pult[7], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, { "FP7", &pult[0][7], 8, 50, 0, 1, NULL, NULL, REG_VMIO },
{ 0 } { 0 }
}; };
@ -303,9 +307,15 @@ t_stat cpu_examine (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)
if (addr >= MEMSIZE) if (addr >= MEMSIZE)
return SCPE_NXM; return SCPE_NXM;
if (vptr) { if (vptr) {
if (addr < 010) if (addr < 010) {
*vptr = pult [addr]; if ((pult[pult_packet_switch][0] >> addr) & 1) {
else /* hardwired */
*vptr = pult[pult_packet_switch][addr];
} else {
/* from switch regs */
*vptr = pult[0][addr];
}
} else
*vptr = memory [addr]; *vptr = memory [addr];
} }
return SCPE_OK; return SCPE_OK;
@ -318,9 +328,12 @@ t_stat cpu_deposit (t_value val, t_addr addr, UNIT *uptr, int32 sw)
{ {
if (addr >= MEMSIZE) if (addr >= MEMSIZE)
return SCPE_NXM; return SCPE_NXM;
if (addr < 010) if (addr < 010) {
pult [addr] = SET_CONVOL (val, CONVOL_INSN); /* Deposited values for the switch register address range
else * always go to switch registers.
*/
pult [0][addr] = SET_CONVOL (val, CONVOL_INSN);
} else
memory [addr] = SET_CONVOL (val, CONVOL_INSN); memory [addr] = SET_CONVOL (val, CONVOL_INSN);
return SCPE_OK; return SCPE_OK;
} }
@ -351,9 +364,13 @@ t_stat cpu_reset (DEVICE *dptr)
SPSW_INTR_DISABLE; SPSW_INTR_DISABLE;
GRP = MGRP = 0; GRP = MGRP = 0;
PC = 1; /* "reset cpu; go" should start from 1 */
sim_brk_types = SWMASK ('E') | SWMASK('R') | SWMASK('W'); sim_brk_types = SWMASK ('E') | SWMASK('R') | SWMASK('W');
sim_brk_dflt = SWMASK ('E'); sim_brk_dflt = SWMASK ('E');
besm6_draw_panel(1);
return SCPE_OK; return SCPE_OK;
} }
@ -366,6 +383,31 @@ t_stat cpu_req (UNIT *u, int32 val, char *cptr, void *desc)
return SCPE_OK; return SCPE_OK;
} }
/*
* Hardwired program selector validation
*/
t_stat cpu_set_pult (UNIT *u, int32 val, char *cptr, void *desc)
{
int sw;
if (cptr) sw = atoi(cptr); else sw = 0;
if (sw >= 0 && sw <= 10) {
pult_packet_switch = sw;
if (sw)
sim_printf("Pult packet switch set to hardwired program %d\n", sw);
else
sim_printf("Pult packet switch set to switch registers\n");
return SCPE_OK;
}
printf("Illegal value %s\n", cptr);
return SCPE_ARG;
}
t_stat cpu_show_pult (FILE *st, struct sim_unit *up, int32 v, void *dp)
{
sim_printf("Pult packet switch position is %d\n", pult_packet_switch);
return SCPE_OK;
}
/* /*
* Write Unicode symbol to file. * Write Unicode symbol to file.
* Convert to UTF-8 encoding: * Convert to UTF-8 encoding:
@ -755,9 +797,9 @@ void check_initial_setup ()
/* Номер смены в 22-24 рр. МГРП: если еще не установлен, установить */ /* Номер смены в 22-24 рр. МГРП: если еще не установлен, установить */
if (((memory[MGRP_COPY] >> 21) & 3) == 0) { if (((memory[MGRP_COPY] >> 21) & 3) == 0) {
/* приказ СМЕ: ТР6 = 010, ТР4 = 1, 22-24 р ТР5 - #смены */ /* приказ СМЕ: ТР6 = 010, ТР4 = 1, 22-24 р ТР5 - #смены */
pult[6] = 010; pult[0][6] = 010;
pult[4] = 1; pult[0][4] = 1;
pult[5] = 1 << 21; pult[0][5] = 1 << 21;
GRP |= GRP_PANEL_REQ; GRP |= GRP_PANEL_REQ;
} else { } else {
struct tm * d; struct tm * d;
@ -777,9 +819,9 @@ void check_initial_setup ()
(memory[YEAR] & 7); (memory[YEAR] & 7);
memory[YEAR] = SET_CONVOL (date, CONVOL_NUMBER); memory[YEAR] = SET_CONVOL (date, CONVOL_NUMBER);
/* приказ ВРЕ: ТР6 = 016, ТР5 = 9-14 р.-часы, 1-8 р.-минуты */ /* приказ ВРЕ: ТР6 = 016, ТР5 = 9-14 р.-часы, 1-8 р.-минуты */
pult[6] = 016; pult[0][6] = 016;
pult[4] = 0; pult[0][4] = 0;
pult[5] = (d->tm_hour / 10) << 12 | pult[0][5] = (d->tm_hour / 10) << 12 |
(d->tm_hour % 10) << 8 | (d->tm_hour % 10) << 8 |
(d->tm_min / 10) << 4 | (d->tm_min / 10) << 4 |
(d->tm_min % 10); (d->tm_min % 10);
@ -1551,7 +1593,7 @@ t_stat sim_instr (void)
*/ */
switch (r) { switch (r) {
default: default:
ret: besm6_draw_panel(); ret: besm6_draw_panel(1);
return r; return r;
case STOP_RWATCH: case STOP_RWATCH:
case STOP_WWATCH: case STOP_WWATCH:
@ -1678,7 +1720,7 @@ t_stat sim_instr (void)
} }
if (iintr > 1) { if (iintr > 1) {
besm6_draw_panel(); besm6_draw_panel(1);
return STOP_DOUBLE_INTR; return STOP_DOUBLE_INTR;
} }
/* Main instruction fetch/decode loop */ /* Main instruction fetch/decode loop */
@ -1686,7 +1728,7 @@ t_stat sim_instr (void)
if (sim_interval <= 0) { /* check clock queue */ if (sim_interval <= 0) { /* check clock queue */
r = sim_process_event (); r = sim_process_event ();
if (r) { if (r) {
besm6_draw_panel(); besm6_draw_panel(1);
return r; return r;
} }
} }
@ -1696,13 +1738,13 @@ t_stat sim_instr (void)
* Runaway instruction execution in supervisor mode * Runaway instruction execution in supervisor mode
* warrants attention. * warrants attention.
*/ */
besm6_draw_panel(); besm6_draw_panel(1);
return STOP_RUNOUT; /* stop simulation */ return STOP_RUNOUT; /* stop simulation */
} }
if (sim_brk_summ & SWMASK('E') && /* breakpoint? */ if (sim_brk_summ & SWMASK('E') && /* breakpoint? */
sim_brk_test (PC, SWMASK ('E'))) { sim_brk_test (PC, SWMASK ('E'))) {
besm6_draw_panel(); besm6_draw_panel(1);
return STOP_IBKPT; /* stop simulation */ return STOP_IBKPT; /* stop simulation */
} }
@ -1720,7 +1762,8 @@ t_stat sim_instr (void)
cpu_one_inst (); /* one instr */ cpu_one_inst (); /* one instr */
iintr = 0; iintr = 0;
if (redraw_panel) { if (redraw_panel) {
besm6_draw_panel(); /* Periodic panel redraw is not forcing */
besm6_draw_panel(0);
redraw_panel = 0; redraw_panel = 0;
} }
@ -1746,14 +1789,18 @@ t_stat fast_clk (UNIT * this)
if ((counter & 15) == 0) { if ((counter & 15) == 0) {
/* /*
* The OS used the (undocumented, later addition) slow clock interrupt to initiate servicing * The OS used the (undocumented, later addition)
* terminal I/O. Its frequency was reportedly 16 Hz; 64 ms is a good enough approximation. * slow clock interrupt to initiate servicing
* terminal I/O. Its frequency was reportedly 16 Hz;
* 64 ms is a good enough approximation. It can be sped up
* for faster console response (16 ms might be a good choice).
*/ */
GRP |= GRP_SLOW_CLK; GRP |= GRP_SLOW_CLK;
} }
/* Requesting panel redraw every 64 ms. */ /* Requesting a panel sample every 32 ms
if ((counter & 15) == 0) { * (a redraw actually happens at every other sample). */
if ((counter & 7) == 0) {
redraw_panel = 1; redraw_panel = 1;
} }

View file

@ -130,7 +130,8 @@ extern UNIT cpu_unit;
extern UNIT tty_unit[]; extern UNIT tty_unit[];
extern UNIT clocks[]; extern UNIT clocks[];
extern t_value memory [MEMSIZE]; extern t_value memory [MEMSIZE];
extern t_value pult [8]; extern t_value pult [11][8];
extern unsigned pult_packet_switch; /* selector of hardwired programs */
extern uint32 PC, RAU, RUU; extern uint32 PC, RAU, RUU;
extern uint32 M[NREGS]; extern uint32 M[NREGS];
@ -356,7 +357,7 @@ void besm6_log_cont (const char *fmt, ...);
void besm6_debug (const char *fmt, ...); void besm6_debug (const char *fmt, ...);
t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
UNIT *uptr, int32 sw); UNIT *uptr, int32 sw);
void besm6_draw_panel (void); void besm6_draw_panel (int force);
t_stat besm6_init_panel (UNIT *u, int32 val, char *cptr, void *desc); t_stat besm6_init_panel (UNIT *u, int32 val, char *cptr, void *desc);
t_stat besm6_close_panel (UNIT *u, int32 val, char *cptr, void *desc); t_stat besm6_close_panel (UNIT *u, int32 val, char *cptr, void *desc);

View file

@ -58,7 +58,101 @@ uint32 TLB[32];
unsigned iintr_data; /* protected page number or parity check location */ unsigned iintr_data; /* protected page number or parity check location */
t_value pult[8]; /* There were several hardwired configurations of registers
* corresponding to up to 7 first words of the memory space, selected by
* a packet switch. Here selection 0 corresponds to settable switch registers,
* the others are hardwired.
* The configuration is selected with "SET CPU PULT=N" where 0 <= N <= 10
* is the configuration number.
*/
unsigned pult_packet_switch;
/* Location 0 of each configuration is the bitset of its hardwired locations */
t_value pult[11][8] = {
/* Switch registers */
{ 0 },
/* Hardwired program 1, a simple CU test */
{ 0376,
SET_CONVOL(01240000007100002LL, CONVOL_INSN), /* 1: vtm (2), vjm 2(1) */
SET_CONVOL(00657777712577777LL, CONVOL_INSN), /* 2: utm -1(1), utm -1(2) */
SET_CONVOL(00444000317400007LL, CONVOL_INSN), /* 3: mtj 3(1), vzm 7(3) */
SET_CONVOL(01045000317500007LL, CONVOL_INSN), /* 4: j+m 3(2), v1m 7(3)*/
SET_CONVOL(00650000107700002LL, CONVOL_INSN), /* 5: utm 1(1), vlm 2(1) */
SET_CONVOL(01257777713400001LL, CONVOL_INSN), /* 6: utm -1(2), vzm 1(2) */
SET_CONVOL(00330000003000001LL, CONVOL_INSN) /* 7: stop, uj 1 */
},
/* Hardwired program 2, RAM write test. The "arx" insn (cyclic add)
* in word 3 could be changed to "atx" insn (load) to use a constant
* bit pattern with a "constant/variable code" front panel switch (TODO).
* The bit pattern to use is taken from switch register 7.
*/
{ 0176,
SET_CONVOL(00770000306400012LL, CONVOL_INSN), /* 1: vlm 3(1), vtm 12(1) */
SET_CONVOL(00010000000000010LL, CONVOL_INSN), /* 2: xta 0, atx 10 */
SET_CONVOL(00010001000130007LL, CONVOL_INSN), /* 3: xta 10, arx 7 */
SET_CONVOL(00500777700000010LL, CONVOL_INSN), /* 4: atx -1(1), atx 10 */
SET_CONVOL(00512777702600001LL, CONVOL_INSN), /* 5: aex -1(1), uza 1 */
SET_CONVOL(00737777703000001LL, CONVOL_INSN) /* 6: stop -1(1), uj 1 */
},
/* Hardwired program 3, RAM read test to use after program 2, arx/atx applies */
{ 0176,
SET_CONVOL(00770000306400012LL, CONVOL_INSN), /* 1: vlm 3(1), vtm 12(1) */
SET_CONVOL(00010000000000010LL, CONVOL_INSN), /* 2: xta 0, atx 10 */
SET_CONVOL(00010001000130007LL, CONVOL_INSN), /* 3: xta 10, arx 7 */
SET_CONVOL(00000000000000010LL, CONVOL_INSN), /* 4: atx 0, atx 10 */
SET_CONVOL(00512777702600001LL, CONVOL_INSN), /* 5: aex -1(1), uza 1 */
SET_CONVOL(00737777703000001LL, CONVOL_INSN) /* 6: stop -1(1), uj 1 */
},
/* Hardwired program 4, RAM write-read test to use after program 2, arx/atx applies */
{ 0176,
SET_CONVOL(00640001200100011LL, CONVOL_INSN), /* 1: vtm 12(1), xta 11 */
SET_CONVOL(00000001005127777LL, CONVOL_INSN), /* 2: atx 10, aex -1(1) */
SET_CONVOL(00260000407377777LL, CONVOL_INSN), /* 3: uza 4, stop -1(1) */
SET_CONVOL(00010001000130007LL, CONVOL_INSN), /* 4: xta 10, arx 7 */
SET_CONVOL(00500777707700002LL, CONVOL_INSN), /* 5: atx -1(1), vlm 2(1) */
SET_CONVOL(00300000100000000LL, CONVOL_INSN) /* 6: uj 1 */
},
/* Hardwired program 5, ALU test; switch reg 7 should contain a
normalized f. p. value, e.g. 1.0 = 4050 0000 0000 0000 */
{ 0176,
SET_CONVOL(00004000700000011LL, CONVOL_INSN), /* 1: a+x 7, atx 11 */
SET_CONVOL(00025001100000010LL, CONVOL_INSN), /* 2: e-x 11, atx 10 */
SET_CONVOL(00017001000160010LL, CONVOL_INSN), /* 3: a*x 10, a/x 10 */
SET_CONVOL(00005001000340145LL, CONVOL_INSN), /* 4: a-x 10, e+n 145 */
SET_CONVOL(00270000603300000LL, CONVOL_INSN), /* 5: u1a 6, stop */
SET_CONVOL(00010001103000001LL, CONVOL_INSN) /* 6: xta 11, uj 1*/
},
/* Hardwired program 6, reading from punch tape (originally) or a disk (rework);
* various bit groups not hardwired, marked [] (TODO). Disk operation is encoded.
*/
{ 0376,
SET_CONVOL(00640000300100006LL, CONVOL_INSN), /* 1: vtm [3](1), xta 6 */
SET_CONVOL(00433002004330020LL, CONVOL_INSN), /* 2: ext 20(1), ext 20(1) */
SET_CONVOL(00036015204330020LL, CONVOL_INSN), /* 3: asn 152, ext 20(1) */
SET_CONVOL(00010000704330000LL, CONVOL_INSN), /* 4: xta 7, ext (1) */
SET_CONVOL(00036014404330020LL, CONVOL_INSN), /* 5: asn 144, ext 20(1) */
SET_CONVOL(00330000000002401LL, CONVOL_INSN), /* 6: stop, =24[01] */
SET_CONVOL(04000000001400000LL, CONVOL_NUMBER) /* 7: bits 37-47 not hardwired */
},
/* Hardwired program 7, RAM peek/poke, bits 1-15 of word 1 not hardwired (TODO) */
{ 0176,
},
/* Hardwired program 8, reading the test program from a fixed drum location */
{ 0036,
},
/* Hardwired program 9, drum I/O */
{ 0176,
SET_CONVOL(00647774100100007LL, CONVOL_INSN), /* 1: vtm -31(1), xta 7 */
SET_CONVOL(00033000212460000LL, CONVOL_INSN), /* 2: ext 2, vtm 60000(2) */
SET_CONVOL(00040000013700003LL, CONVOL_INSN), /* 3: ati, vlm 3(2) */
SET_CONVOL(00013000607700002LL, CONVOL_INSN), /* 4: arx 6, vlm 2(1) */
SET_CONVOL(00330000103000005LL, CONVOL_INSN), /* 5: stop 1, uj 5 */
SET_CONVOL(00000000000010001LL, CONVOL_NUMBER) /* 6: =10001 */
},
/* Hardwired program 10, magtape read */
{ 0176,
},
};
REG mmu_reg[] = { REG mmu_reg[] = {
{ "БРЗ0", &BRZ[0], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, /* Буферные регистры записи */ { "БРЗ0", &BRZ[0], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, /* Буферные регистры записи */
@ -89,13 +183,13 @@ REG mmu_reg[] = {
{ "РП6", &RP[6], 8, 48, 0, 1, NULL, NULL, REG_VMIO}, { "РП6", &RP[6], 8, 48, 0, 1, NULL, NULL, REG_VMIO},
{ "РП7", &RP[7], 8, 48, 0, 1, NULL, NULL, REG_VMIO}, { "РП7", &RP[7], 8, 48, 0, 1, NULL, NULL, REG_VMIO},
{ "РЗ", &RZ, 8, 32, 0, 1 }, /* Регистр защиты */ { "РЗ", &RZ, 8, 32, 0, 1 }, /* Регистр защиты */
{ "ТР1", &pult[1], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, /* Тумблерные регистры */ { "ТР1", &pult[0][1], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, /* Тумблерные регистры */
{ "ТР2", &pult[2], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, { "ТР2", &pult[0][2], 8, 50, 0, 1, NULL, NULL, REG_VMIO},
{ "ТР3", &pult[3], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, { "ТР3", &pult[0][3], 8, 50, 0, 1, NULL, NULL, REG_VMIO},
{ "ТР4", &pult[4], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, { "ТР4", &pult[0][4], 8, 50, 0, 1, NULL, NULL, REG_VMIO},
{ "ТР5", &pult[5], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, { "ТР5", &pult[0][5], 8, 50, 0, 1, NULL, NULL, REG_VMIO},
{ "ТР6", &pult[6], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, { "ТР6", &pult[0][6], 8, 50, 0, 1, NULL, NULL, REG_VMIO},
{ "ТР7", &pult[7], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, { "ТР7", &pult[0][7], 8, 50, 0, 1, NULL, NULL, REG_VMIO},
{ "БРС0", &BRS[0], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, /* Буферные регистры слов */ { "БРС0", &BRS[0], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, /* Буферные регистры слов */
{ "БРС1", &BRS[1], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, { "БРС1", &BRS[1], 8, 50, 0, 1, NULL, NULL, REG_VMIO},
{ "БРС2", &BRS[2], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, { "БРС2", &BRS[2], 8, 50, 0, 1, NULL, NULL, REG_VMIO},
@ -370,7 +464,13 @@ t_value mmu_memaccess (int addr)
/* С тумблерных регистров */ /* С тумблерных регистров */
if (mmu_dev.dctrl) if (mmu_dev.dctrl)
besm6_debug("--- (%05o) чтение ТР%o", PC, addr); besm6_debug("--- (%05o) чтение ТР%o", PC, addr);
val = pult[addr]; if ((pult[pult_packet_switch][0] >> addr) & 1) {
/* hardwired */
val = pult[pult_packet_switch][addr];
} else {
/* from switch regs */
val = pult[0][addr];
}
} }
if (sim_log && (mmu_dev.dctrl || (cpu_dev.dctrl && sim_deb))) { if (sim_log && (mmu_dev.dctrl || (cpu_dev.dctrl && sim_deb))) {
fprintf (sim_log, "--- (%05o) чтение ", addr & BITS(15)); fprintf (sim_log, "--- (%05o) чтение ", addr & BITS(15));
@ -532,9 +632,15 @@ t_value mmu_prefetch (int addr, int actual)
addr = addr & BITS(15); addr = addr & BITS(15);
} }
if (addr < 010) if (addr < 010) {
val = pult[addr]; if ((pult[pult_packet_switch][0] >> addr) & 1) {
else /* hardwired */
val = pult[pult_packet_switch][addr];
} else {
/* from switch regs */
val = pult[0][addr];
}
} else
val = memory[addr]; val = memory[addr];
BRS[i] = val; BRS[i] = val;
return val; return val;

View file

@ -70,12 +70,22 @@ static const SDL_Color cyan = { 0, 128, 128 };
static const SDL_Color grey = { 64, 64, 64 }; static const SDL_Color grey = { 64, 64, 64 };
static t_value old_BRZ [8], old_GRP [2]; static t_value old_BRZ [8], old_GRP [2];
static t_value old_M [NREGS]; static t_value old_M [NREGS];
static char M_lamps[NREGS][15], BRZ_lamps[8][48], GRP_lamps[2][48];
static const int regnum[] = { static const int regnum[] = {
013, 012, 011, 010, 7, 6, 5, 4, 013, 012, 011, 010, 7, 6, 5, 4,
027, 016, 015, 014, 3, 2, 1, 020, 027, 016, 015, 014, 3, 2, 1, 020,
}; };
/* The lights can be of 3 brightness levels, averaging
* 2 samples. Drawing can be done in decay mode
* (a one-sample glitch == a half-bright light for 2 frames)
* or in PWM mode (a one-sample glitch = a half-bright light
* for 1 frame).
* PWM mode is used, 'act' toggles between 0 and 1.
*/
static int act;
static SDL_Surface *screen; static SDL_Surface *screen;
/* /*
@ -170,22 +180,32 @@ static void draw_lamp (int left, int top, int on)
"\0\0\0\25\5\5A\21\21h\32\32c\30\30c\30\30h\32\32A\21\21\25\5\5\0\0\0\0\0" "\0\0\0\25\5\5A\21\21h\32\32c\30\30c\30\30h\32\32A\21\21\25\5\5\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\14\2\2\14\2\2\14\2\2\14\2\2\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\14\2\2\14\2\2\14\2\2\14\2\2\0\0\0\0\0\0\0\0\0"
"\0\0\0"; "\0\0\0";
static SDL_Surface *sprite_on, *sprite_off;
SDL_Rect area;
if (! sprite_on) { static unsigned char lamp_mid [sizeof(lamp_on)];
sprite_on = sprite_from_data (lamp_width, lamp_height, static SDL_Surface * sprites[3];
lamp_on); SDL_Rect area;
} int i;
if (! sprite_off) {
sprite_off = sprite_from_data (lamp_width, lamp_height, if (! sprites[0]) {
sprites[0] = sprite_from_data (lamp_width, lamp_height,
lamp_off); lamp_off);
} }
if (!sprites[1]) {
for (i = 0; i < sizeof(lamp_mid); ++i)
lamp_mid[i] = (lamp_on[i] + lamp_off[i] + 1) / 2;
sprites[1] = sprite_from_data (lamp_width, lamp_height,
lamp_mid);
}
if (! sprites[2]) {
sprites[2] = sprite_from_data (lamp_width, lamp_height,
lamp_on);
}
area.x = left; area.x = left;
area.y = top; area.y = top;
area.w = lamp_width; area.w = lamp_width;
area.h = lamp_height; area.h = lamp_height;
SDL_BlitSurface (on ? sprite_on : sprite_off, 0, screen, &area); SDL_BlitSurface (sprites[on], 0, screen, &area);
} }
/* /*
@ -193,16 +213,20 @@ static void draw_lamp (int left, int top, int on)
*/ */
static void draw_modifiers_periodic (int group, int left, int top) static void draw_modifiers_periodic (int group, int left, int top)
{ {
int x, y, reg, val; int x, y, reg, val, anded, ored;
for (y=0; y<8; ++y) { for (y=0; y<8; ++y) {
reg = regnum [y + group*8]; reg = regnum [y + group*8];
val = M [reg]; val = M [reg];
if (val == old_M [reg]) anded = old_M [reg] & val;
continue; ored = old_M [reg] | val;
old_M [reg] = val; old_M [reg] = val;
for (x=0; x<15; ++x) { for (x=0; act && x<15; ++x) {
draw_lamp (left+76 + x*STEPX, top+28 + y*STEPY, val >> (14-x) & 1); int new_lamp = anded >> (14-x) & 1 ? 2 : ored >> (14-x) & 1 ? 1 : 0;
if (new_lamp != M_lamps[reg][x]) {
draw_lamp (left+76 + x*STEPX, top+28 + y*STEPY, new_lamp);
M_lamps[reg][x] = new_lamp;
}
} }
} }
} }
@ -213,15 +237,19 @@ static void draw_modifiers_periodic (int group, int left, int top)
static void draw_grp_periodic (int top) static void draw_grp_periodic (int top)
{ {
int x, y; int x, y;
t_value val; t_value val, anded, ored;
for (y=0; y<2; ++y) { for (y=0; y<2; ++y) {
val = y ? MGRP : GRP; val = y ? MGRP : GRP;
if (val == old_GRP [y]) anded = old_GRP [y] & val;
continue; ored = old_GRP [y] | val;
old_GRP [y] = val; old_GRP [y] = val;
for (x=0; x<48; ++x) { for (x=0; act && x<48; ++x) {
draw_lamp (100 + x*STEPX, top+28 + y*STEPY, val >> (47-x) & 1); int new_lamp = anded >> (47-x) & 1 ? 2 : ored >> (47-x) & 1 ? 1 : 0;
if (new_lamp != GRP_lamps[y][x]) {
draw_lamp (100 + x*STEPX, top+28 + y*STEPY, new_lamp);
GRP_lamps[y][x] = new_lamp;
}
} }
} }
} }
@ -232,15 +260,19 @@ static void draw_grp_periodic (int top)
static void draw_brz_periodic (int top) static void draw_brz_periodic (int top)
{ {
int x, y; int x, y;
t_value val; t_value val, anded, ored;
for (y=0; y<8; ++y) { for (y=0; y<8; ++y) {
val = BRZ [7-y]; val = BRZ [7-y];
if (val == old_BRZ [7-y]) anded = old_BRZ [7-y] & val;
continue; ored = old_BRZ [7-y] | val;
old_BRZ [7-y] = val; old_BRZ [7-y] = val;
for (x=0; x<48; ++x) { for (x=0; act && x<48; ++x) {
draw_lamp (100 + x*STEPX, top+28 + y*STEPY, val >> (47-x) & 1); int new_lamp = anded >> (47-x) & 1 ? 2 : ored >> (47-x) & 1 ? 1 : 0;
if (new_lamp != BRZ_lamps[y][x]) {
draw_lamp (100 + x*STEPX, top+28 + y*STEPY, new_lamp);
BRZ_lamps[y][x] = new_lamp;
}
} }
} }
} }
@ -425,7 +457,11 @@ t_stat besm6_init_panel (UNIT *u, int32 val, char *cptr, void *desc)
draw_grp_static (180); draw_grp_static (180);
draw_brz_static (230); draw_brz_static (230);
besm6_draw_panel(); /* Make sure all lights are updated */
memset(M_lamps, ~0, sizeof(M_lamps));
memset(BRZ_lamps, ~0, sizeof(BRZ_lamps));
memset(GRP_lamps, ~0, sizeof(GRP_lamps));
besm6_draw_panel(1);
/* Tell SDL to update the whole screen */ /* Tell SDL to update the whole screen */
SDL_UpdateTexture(sdlTexture, NULL, screen->pixels, screen->pitch); SDL_UpdateTexture(sdlTexture, NULL, screen->pixels, screen->pitch);
@ -437,19 +473,30 @@ t_stat besm6_init_panel (UNIT *u, int32 val, char *cptr, void *desc)
/* /*
* Refreshing the window. * Refreshing the window.
*/ */
void besm6_draw_panel (void) void besm6_draw_panel (int force)
{ {
SDL_Event event; SDL_Event event;
if (! screen) if (! screen)
return; return;
if (force) {
/* When the CPU is stopped */
act = 1;
besm6_draw_panel(0);
act = 1;
besm6_draw_panel(0);
return;
}
/* Do the blinkenlights */ /* Do the blinkenlights */
draw_modifiers_periodic (0, 24, 10); draw_modifiers_periodic (0, 24, 10);
draw_modifiers_periodic (1, 400, 10); draw_modifiers_periodic (1, 400, 10);
draw_grp_periodic (180); draw_grp_periodic (180);
draw_brz_periodic (230); draw_brz_periodic (230);
act = !act;
/* Tell SDL to update the whole screen */ /* Tell SDL to update the whole screen */
SDL_UpdateTexture(sdlTexture, NULL, screen->pixels, screen->pitch); SDL_UpdateTexture(sdlTexture, NULL, screen->pixels, screen->pitch);
SDL_RenderClear(sdlRenderer); SDL_RenderClear(sdlRenderer);
@ -505,7 +552,11 @@ t_stat besm6_init_panel (UNIT *u, int32 val, char *cptr, void *desc)
draw_grp_static (180); draw_grp_static (180);
draw_brz_static (230); draw_brz_static (230);
besm6_draw_panel(); /* Make sure all lights are updated */
memset(M_lamps, ~0, sizeof(M_lamps));
memset(BRZ_lamps, ~0, sizeof(BRZ_lamps));
memset(GRP_lamps, ~0, sizeof(GRP_lamps));
besm6_draw_panel(1);
/* Tell SDL to update the whole screen */ /* Tell SDL to update the whole screen */
SDL_UpdateRect (screen, 0, 0, WIDTH, HEIGHT); SDL_UpdateRect (screen, 0, 0, WIDTH, HEIGHT);
@ -514,12 +565,21 @@ t_stat besm6_init_panel (UNIT *u, int32 val, char *cptr, void *desc)
/* /*
* Refreshing the window * Refreshing the window
*/ */
void besm6_draw_panel () void besm6_draw_panel (int force)
{ {
SDL_Event event; SDL_Event event;
if (! screen) if (! screen)
return; return;
if (force) {
/* When the CPU is stopped */
act = 1;
besm6_draw_panel(0);
act = 1;
besm6_draw_panel(0);
return;
}
/* Do the blinkenlights */ /* Do the blinkenlights */
draw_modifiers_periodic (0, 24, 10); draw_modifiers_periodic (0, 24, 10);
draw_modifiers_periodic (1, 400, 10); draw_modifiers_periodic (1, 400, 10);
@ -537,7 +597,7 @@ void besm6_draw_panel ()
#endif /* SDL_MAJOR_VERSION */ #endif /* SDL_MAJOR_VERSION */
#else /* HAVE_LIBSDL */ #else /* HAVE_LIBSDL */
void besm6_draw_panel (void) void besm6_draw_panel (int force)
{ {
} }
#endif /* HAVE_LIBSDL */ #endif /* HAVE_LIBSDL */

View file

@ -656,14 +656,14 @@ t_stat besm6_load (FILE *input)
break; break;
case '=': /* word */ case '=': /* word */
if (addr < 010) if (addr < 010)
pult [addr] = SET_CONVOL (word, CONVOL_NUMBER); pult [0][addr] = SET_CONVOL (word, CONVOL_NUMBER);
else else
memory [addr] = SET_CONVOL (word, CONVOL_NUMBER); memory [addr] = SET_CONVOL (word, CONVOL_NUMBER);
++addr; ++addr;
break; break;
case '*': /* instruction */ case '*': /* instruction */
if (addr < 010) if (addr < 010)
pult [addr] = SET_CONVOL (word, CONVOL_INSN); pult [0][addr] = SET_CONVOL (word, CONVOL_INSN);
else else
memory [addr] = SET_CONVOL (word, CONVOL_INSN); memory [addr] = SET_CONVOL (word, CONVOL_INSN);
++addr; ++addr;
@ -689,7 +689,7 @@ t_stat besm6_dump (FILE *of, char *fnam)
fprintf (of, "; %s\n", fnam); fprintf (of, "; %s\n", fnam);
for (addr=1; addr<MEMSIZE; ++addr) { for (addr=1; addr<MEMSIZE; ++addr) {
if (addr < 010) if (addr < 010)
word = pult [addr]; word = pult [0][addr];
else else
word = memory [addr]; word = memory [addr];
if (word == 0) if (word == 0)

View file

@ -237,7 +237,7 @@ t_stat vt_clk (UNIT * this)
if (!attached_console) { if (!attached_console) {
static int divider; static int divider;
if (++divider == CLK_TPS/10) { if (++divider == CLK_TPS/10) {
divider == 0; divider = 0;
if (SCPE_STOP == sim_poll_kbd()) if (SCPE_STOP == sim_poll_kbd())
stop_cpu = 1; stop_cpu = 1;
} }