From 9ff642f6169105128583fc7bf366a3f236dfe831 Mon Sep 17 00:00:00 2001 From: Leo Broukhis Date: Wed, 14 Jan 2015 00:39:55 -0800 Subject: [PATCH] BESM6: Implemented hardwired front panel programs, smoothed front panel lights, corrected a typo in besm6_tty.c --- BESM6/besm6_cpu.c | 105 +++++++++++++++++++++++++---------- BESM6/besm6_defs.h | 5 +- BESM6/besm6_mmu.c | 130 ++++++++++++++++++++++++++++++++++++++++---- BESM6/besm6_panel.c | 118 ++++++++++++++++++++++++++++++---------- BESM6/besm6_sys.c | 6 +- BESM6/besm6_tty.c | 2 +- 6 files changed, 290 insertions(+), 76 deletions(-) diff --git a/BESM6/besm6_cpu.c b/BESM6/besm6_cpu.c index 9b7295f0..637586c5 100644 --- a/BESM6/besm6_cpu.c +++ b/BESM6/besm6_cpu.c @@ -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_reset (DEVICE *dptr); 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 @@ -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, "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|MTAB_VALO, 0, "PULT", "PULT", &cpu_set_pult, &cpu_show_pult, NULL, "Selects a hardwired program or switch reg." }, { 0 } }; @@ -222,13 +226,13 @@ REG reg_reg[] = { { "RP6", &RP[6], 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 }, - { "FP1", &pult[1], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, - { "FP2", &pult[2], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, - { "FP3", &pult[3], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, - { "FP4", &pult[4], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, - { "FP5", &pult[5], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, - { "FP6", &pult[6], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, - { "FP7", &pult[7], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, + { "FP1", &pult[0][1], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, + { "FP2", &pult[0][2], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, + { "FP3", &pult[0][3], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, + { "FP4", &pult[0][4], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, + { "FP5", &pult[0][5], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, + { "FP6", &pult[0][6], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, + { "FP7", &pult[0][7], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, { 0 } }; @@ -303,9 +307,15 @@ t_stat cpu_examine (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) if (addr >= MEMSIZE) return SCPE_NXM; if (vptr) { - if (addr < 010) - *vptr = pult [addr]; - else + if (addr < 010) { + if ((pult[pult_packet_switch][0] >> addr) & 1) { + /* hardwired */ + *vptr = pult[pult_packet_switch][addr]; + } else { + /* from switch regs */ + *vptr = pult[0][addr]; + } + } else *vptr = memory [addr]; } return SCPE_OK; @@ -318,9 +328,12 @@ t_stat cpu_deposit (t_value val, t_addr addr, UNIT *uptr, int32 sw) { if (addr >= MEMSIZE) return SCPE_NXM; - if (addr < 010) - pult [addr] = SET_CONVOL (val, CONVOL_INSN); - else + if (addr < 010) { + /* Deposited values for the switch register address range + * always go to switch registers. + */ + pult [0][addr] = SET_CONVOL (val, CONVOL_INSN); + } else memory [addr] = SET_CONVOL (val, CONVOL_INSN); return SCPE_OK; } @@ -351,9 +364,13 @@ t_stat cpu_reset (DEVICE *dptr) SPSW_INTR_DISABLE; GRP = MGRP = 0; + PC = 1; /* "reset cpu; go" should start from 1 */ + sim_brk_types = SWMASK ('E') | SWMASK('R') | SWMASK('W'); sim_brk_dflt = SWMASK ('E'); + besm6_draw_panel(1); + return SCPE_OK; } @@ -366,6 +383,31 @@ t_stat cpu_req (UNIT *u, int32 val, char *cptr, void *desc) 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. * Convert to UTF-8 encoding: @@ -755,9 +797,9 @@ void check_initial_setup () /* Номер смены в 22-24 рр. МГРП: если еще не установлен, установить */ if (((memory[MGRP_COPY] >> 21) & 3) == 0) { /* приказ СМЕ: ТР6 = 010, ТР4 = 1, 22-24 р ТР5 - #смены */ - pult[6] = 010; - pult[4] = 1; - pult[5] = 1 << 21; + pult[0][6] = 010; + pult[0][4] = 1; + pult[0][5] = 1 << 21; GRP |= GRP_PANEL_REQ; } else { struct tm * d; @@ -777,9 +819,9 @@ void check_initial_setup () (memory[YEAR] & 7); memory[YEAR] = SET_CONVOL (date, CONVOL_NUMBER); /* приказ ВРЕ: ТР6 = 016, ТР5 = 9-14 р.-часы, 1-8 р.-минуты */ - pult[6] = 016; - pult[4] = 0; - pult[5] = (d->tm_hour / 10) << 12 | + pult[0][6] = 016; + pult[0][4] = 0; + pult[0][5] = (d->tm_hour / 10) << 12 | (d->tm_hour % 10) << 8 | (d->tm_min / 10) << 4 | (d->tm_min % 10); @@ -1551,7 +1593,7 @@ t_stat sim_instr (void) */ switch (r) { default: - ret: besm6_draw_panel(); + ret: besm6_draw_panel(1); return r; case STOP_RWATCH: case STOP_WWATCH: @@ -1678,7 +1720,7 @@ t_stat sim_instr (void) } if (iintr > 1) { - besm6_draw_panel(); + besm6_draw_panel(1); return STOP_DOUBLE_INTR; } /* Main instruction fetch/decode loop */ @@ -1686,7 +1728,7 @@ t_stat sim_instr (void) if (sim_interval <= 0) { /* check clock queue */ r = sim_process_event (); if (r) { - besm6_draw_panel(); + besm6_draw_panel(1); return r; } } @@ -1696,13 +1738,13 @@ t_stat sim_instr (void) * Runaway instruction execution in supervisor mode * warrants attention. */ - besm6_draw_panel(); + besm6_draw_panel(1); return STOP_RUNOUT; /* stop simulation */ } if (sim_brk_summ & SWMASK('E') && /* breakpoint? */ sim_brk_test (PC, SWMASK ('E'))) { - besm6_draw_panel(); + besm6_draw_panel(1); return STOP_IBKPT; /* stop simulation */ } @@ -1720,7 +1762,8 @@ t_stat sim_instr (void) cpu_one_inst (); /* one instr */ iintr = 0; if (redraw_panel) { - besm6_draw_panel(); + /* Periodic panel redraw is not forcing */ + besm6_draw_panel(0); redraw_panel = 0; } @@ -1746,14 +1789,18 @@ t_stat fast_clk (UNIT * this) if ((counter & 15) == 0) { /* - * The OS used the (undocumented, later addition) slow clock interrupt to initiate servicing - * terminal I/O. Its frequency was reportedly 16 Hz; 64 ms is a good enough approximation. + * The OS used the (undocumented, later addition) + * 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; } - /* Requesting panel redraw every 64 ms. */ - if ((counter & 15) == 0) { + /* Requesting a panel sample every 32 ms + * (a redraw actually happens at every other sample). */ + if ((counter & 7) == 0) { redraw_panel = 1; } diff --git a/BESM6/besm6_defs.h b/BESM6/besm6_defs.h index ebae7176..ed12ef70 100644 --- a/BESM6/besm6_defs.h +++ b/BESM6/besm6_defs.h @@ -130,7 +130,8 @@ extern UNIT cpu_unit; extern UNIT tty_unit[]; extern UNIT clocks[]; 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 M[NREGS]; @@ -356,7 +357,7 @@ void besm6_log_cont (const char *fmt, ...); void besm6_debug (const char *fmt, ...); t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, 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_close_panel (UNIT *u, int32 val, char *cptr, void *desc); diff --git a/BESM6/besm6_mmu.c b/BESM6/besm6_mmu.c index 486f4e45..ba00c3a8 100644 --- a/BESM6/besm6_mmu.c +++ b/BESM6/besm6_mmu.c @@ -58,7 +58,101 @@ uint32 TLB[32]; 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[] = { { "БРЗ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}, { "РП7", &RP[7], 8, 48, 0, 1, NULL, NULL, REG_VMIO}, { "РЗ", &RZ, 8, 32, 0, 1 }, /* Регистр защиты */ - { "ТР1", &pult[1], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, /* Тумблерные регистры */ - { "ТР2", &pult[2], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, - { "ТР3", &pult[3], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, - { "ТР4", &pult[4], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, - { "ТР5", &pult[5], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, - { "ТР6", &pult[6], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, - { "ТР7", &pult[7], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, + { "ТР1", &pult[0][1], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, /* Тумблерные регистры */ + { "ТР2", &pult[0][2], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, + { "ТР3", &pult[0][3], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, + { "ТР4", &pult[0][4], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, + { "ТР5", &pult[0][5], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, + { "ТР6", &pult[0][6], 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}, /* Буферные регистры слов */ { "БРС1", &BRS[1], 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) 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))) { fprintf (sim_log, "--- (%05o) чтение ", addr & BITS(15)); @@ -532,9 +632,15 @@ t_value mmu_prefetch (int addr, int actual) addr = addr & BITS(15); } - if (addr < 010) - val = pult[addr]; - else + if (addr < 010) { + if ((pult[pult_packet_switch][0] >> addr) & 1) { + /* hardwired */ + val = pult[pult_packet_switch][addr]; + } else { + /* from switch regs */ + val = pult[0][addr]; + } + } else val = memory[addr]; BRS[i] = val; return val; diff --git a/BESM6/besm6_panel.c b/BESM6/besm6_panel.c index 4e5d396a..d4ac0d9b 100644 --- a/BESM6/besm6_panel.c +++ b/BESM6/besm6_panel.c @@ -70,12 +70,22 @@ static const SDL_Color cyan = { 0, 128, 128 }; static const SDL_Color grey = { 64, 64, 64 }; static t_value old_BRZ [8], old_GRP [2]; static t_value old_M [NREGS]; +static char M_lamps[NREGS][15], BRZ_lamps[8][48], GRP_lamps[2][48]; static const int regnum[] = { 013, 012, 011, 010, 7, 6, 5, 4, 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; /* @@ -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\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"; - static SDL_Surface *sprite_on, *sprite_off; - SDL_Rect area; - if (! sprite_on) { - sprite_on = sprite_from_data (lamp_width, lamp_height, - lamp_on); - } - if (! sprite_off) { - sprite_off = sprite_from_data (lamp_width, lamp_height, + static unsigned char lamp_mid [sizeof(lamp_on)]; + static SDL_Surface * sprites[3]; + SDL_Rect area; + int i; + + if (! sprites[0]) { + sprites[0] = sprite_from_data (lamp_width, lamp_height, 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.y = top; area.w = lamp_width; 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) { - int x, y, reg, val; + int x, y, reg, val, anded, ored; for (y=0; y<8; ++y) { reg = regnum [y + group*8]; val = M [reg]; - if (val == old_M [reg]) - continue; + anded = old_M [reg] & val; + ored = old_M [reg] | val; old_M [reg] = val; - for (x=0; x<15; ++x) { - draw_lamp (left+76 + x*STEPX, top+28 + y*STEPY, val >> (14-x) & 1); + for (x=0; act && x<15; ++x) { + 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) { int x, y; - t_value val; + t_value val, anded, ored; for (y=0; y<2; ++y) { val = y ? MGRP : GRP; - if (val == old_GRP [y]) - continue; + anded = old_GRP [y] & val; + ored = old_GRP [y] | val; old_GRP [y] = val; - for (x=0; x<48; ++x) { - draw_lamp (100 + x*STEPX, top+28 + y*STEPY, val >> (47-x) & 1); + for (x=0; act && x<48; ++x) { + 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) { int x, y; - t_value val; + t_value val, anded, ored; for (y=0; y<8; ++y) { val = BRZ [7-y]; - if (val == old_BRZ [7-y]) - continue; + anded = old_BRZ [7-y] & val; + ored = old_BRZ [7-y] | val; old_BRZ [7-y] = val; - for (x=0; x<48; ++x) { - draw_lamp (100 + x*STEPX, top+28 + y*STEPY, val >> (47-x) & 1); + for (x=0; act && x<48; ++x) { + 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_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 */ 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. */ -void besm6_draw_panel (void) +void besm6_draw_panel (int force) { SDL_Event event; if (! screen) return; + if (force) { + /* When the CPU is stopped */ + act = 1; + besm6_draw_panel(0); + act = 1; + besm6_draw_panel(0); + return; + } + /* Do the blinkenlights */ draw_modifiers_periodic (0, 24, 10); draw_modifiers_periodic (1, 400, 10); draw_grp_periodic (180); draw_brz_periodic (230); + act = !act; + /* Tell SDL to update the whole screen */ SDL_UpdateTexture(sdlTexture, NULL, screen->pixels, screen->pitch); 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_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 */ 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 */ -void besm6_draw_panel () +void besm6_draw_panel (int force) { SDL_Event event; if (! screen) return; + if (force) { + /* When the CPU is stopped */ + act = 1; + besm6_draw_panel(0); + act = 1; + besm6_draw_panel(0); + return; + } + /* Do the blinkenlights */ draw_modifiers_periodic (0, 24, 10); draw_modifiers_periodic (1, 400, 10); @@ -537,7 +597,7 @@ void besm6_draw_panel () #endif /* SDL_MAJOR_VERSION */ #else /* HAVE_LIBSDL */ -void besm6_draw_panel (void) +void besm6_draw_panel (int force) { } #endif /* HAVE_LIBSDL */ diff --git a/BESM6/besm6_sys.c b/BESM6/besm6_sys.c index c342174c..c26543c6 100644 --- a/BESM6/besm6_sys.c +++ b/BESM6/besm6_sys.c @@ -656,14 +656,14 @@ t_stat besm6_load (FILE *input) break; case '=': /* word */ if (addr < 010) - pult [addr] = SET_CONVOL (word, CONVOL_NUMBER); + pult [0][addr] = SET_CONVOL (word, CONVOL_NUMBER); else memory [addr] = SET_CONVOL (word, CONVOL_NUMBER); ++addr; break; case '*': /* instruction */ if (addr < 010) - pult [addr] = SET_CONVOL (word, CONVOL_INSN); + pult [0][addr] = SET_CONVOL (word, CONVOL_INSN); else memory [addr] = SET_CONVOL (word, CONVOL_INSN); ++addr; @@ -689,7 +689,7 @@ t_stat besm6_dump (FILE *of, char *fnam) fprintf (of, "; %s\n", fnam); for (addr=1; addr