From 68efe4d36a94d9d99b004e07c404dfce92c87221 Mon Sep 17 00:00:00 2001 From: Leo Broukhis Date: Thu, 12 Feb 2015 20:35:33 -0800 Subject: [PATCH] BESM6: Enhanced the front panel, code cleanup. --- BESM6/besm6_cpu.c | 17 +-- BESM6/besm6_panel.c | 298 ++++++++++++++++++++++++++---------------- BESM6/besm6_printer.c | 1 + BESM6/besm6_punch.c | 2 - 4 files changed, 192 insertions(+), 126 deletions(-) diff --git a/BESM6/besm6_cpu.c b/BESM6/besm6_cpu.c index 94c2c952..b0423f22 100644 --- a/BESM6/besm6_cpu.c +++ b/BESM6/besm6_cpu.c @@ -559,11 +559,7 @@ static void cmd_033 () switch (Aex & 04177) { case 0: /* - * Using an I/O control instruction with Aex == 0 - * after issuing a 033 instruction with a non-zero Aex - * to send data to a device was required - * for some devices (e.g. printers) according to the docs. - * What is the exact purpose is unclear (timing, power, ???) + * Releasing the drum printer solenoids. No effect on simulation. */ break; case 1: case 2: @@ -1761,6 +1757,12 @@ t_stat sim_instr (void) return STOP_IBKPT; /* stop simulation */ } + if (redraw_panel) { + /* Periodic panel redraw is not forcing */ + besm6_draw_panel(0); + redraw_panel = 0; + } + if (PRP & MPRP) { /* There are interrupts pending in the peripheral * interrupt register */ @@ -1774,11 +1776,6 @@ t_stat sim_instr (void) } cpu_one_inst (); /* one instr */ iintr = 0; - if (redraw_panel) { - /* Periodic panel redraw is not forcing */ - besm6_draw_panel(0); - redraw_panel = 0; - } sim_interval -= 1; /* count down instructions */ } diff --git a/BESM6/besm6_panel.c b/BESM6/besm6_panel.c index 162c9381..55b91dfe 100644 --- a/BESM6/besm6_panel.c +++ b/BESM6/besm6_panel.c @@ -46,11 +46,13 @@ * Use a 640x480 window with 32 bit pixels. */ #define WIDTH 800 -#define HEIGHT 400 +#define HEIGHT 450 #define DEPTH 32 #define STEPX 14 #define STEPY 16 +#define TEXTW 76 +#define HEADER 28 #include #include @@ -68,8 +70,9 @@ static const SDL_Color black = { 0, 0, 0 }; 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 uint32 old_M [NREGS], old_PRP [2], old_PC; +static char M_lamps[NREGS][15], BRZ_lamps[8][48], + GRP_lamps[2][48], PRP_lamps[2][24], PC_lamps[16]; static const int regnum[] = { 013, 012, 011, 010, 7, 6, 5, 4, @@ -207,25 +210,47 @@ static void draw_lamp (int left, int top, int on) SDL_BlitSurface (sprites[on], 0, screen, &area); } +static void draw_a_modifier (int reg, int hpos, int vpos) { + int x, val, anded, ored; + val = M [reg]; + anded = old_M [reg] & val; + ored = old_M [reg] | val; + old_M [reg] = val; + 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 (hpos + x*STEPX, vpos, new_lamp); + M_lamps[reg][x] = new_lamp; + } + } +} + /* * Drawing index (modifier) registers. They form two groups. */ static void draw_modifiers_periodic (int group, int left, int top) { - int x, y, reg, val, anded, ored; + int y, reg; for (y=0; y<8; ++y) { reg = regnum [y + group*8]; - val = M [reg]; - anded = old_M [reg] & val; - ored = old_M [reg] | val; - old_M [reg] = val; - 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; - } + draw_a_modifier (reg, left + TEXTW, top + HEADER + y*STEPY); + } +} + +static void draw_full_word (t_value val, t_value * old, char * lamps, + int hpos, int vpos) +{ + int x; + t_value anded, ored; + anded = *old & val; + ored = *old | val; + *old = val; + for (x=0; act && x<48; ++x) { + int new_lamp = anded >> (47-x) & 1 ? 2 : ored >> (47-x) & 1 ? 1 : 0; + if (new_lamp != lamps[x]) { + draw_lamp (hpos + x*STEPX, vpos, new_lamp); + lamps[x] = new_lamp; } } } @@ -233,46 +258,90 @@ static void draw_modifiers_periodic (int group, int left, int top) /* * Drawing the main interrupt register and its mask. */ -static void draw_grp_periodic (int top) +static void draw_grp_periodic (int left, int top) { - int x, y; - t_value val, anded, ored; + draw_full_word (GRP, &old_GRP[0], GRP_lamps[0], left + TEXTW, top+HEADER); + draw_full_word (MGRP, &old_GRP[1], GRP_lamps[1], left + TEXTW, top+HEADER+STEPY); +} - for (y=0; y<2; ++y) { - val = y ? MGRP : GRP; - anded = old_GRP [y] & val; - ored = old_GRP [y] | val; - old_GRP [y] = val; - 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; - } +static void draw_partial_word (uint32 val, int bits, uint32 * old, + char * lamps, int hpos, int vpos) +{ + int x; + uint32 anded, ored; + anded = *old & val; + ored = *old | val; + *old = val; + --bits; + for (x=0; act && x<=bits; ++x) { + int new_lamp = anded >> (bits-x) & 1 ? 2 : + ored >> (bits-x) & 1 ? 1 : 0; + if (new_lamp != lamps[x]) { + draw_lamp (hpos + x*STEPX, vpos, new_lamp); + lamps[x] = new_lamp; } } } +static void draw_counters_periodic (int left, int top) +{ + draw_a_modifier(017, left+TEXTW+STEPX, top+HEADER); + /* The MSB of the displayed PC is the supervisor mode tag */ + draw_partial_word(IS_SUPERVISOR(RUU) ? PC | BBIT(16) : PC, 16, + &old_PC, PC_lamps, left+TEXTW, top+HEADER+STEPY); +} + +/* + * Drawing the peripheral interrupt register and its mask. + */ +static void draw_prp_periodic (int left, int top) +{ + draw_partial_word(PRP, 24, &old_PRP[0], PRP_lamps[0], left+TEXTW, top+HEADER); + draw_partial_word(MPRP, 24, &old_PRP[1], PRP_lamps[1], left+TEXTW, top+HEADER+STEPY); +} + /* * Drawing the data cache registers. */ -static void draw_brz_periodic (int top) +static void draw_brz_periodic (int left, int top) { - int x, y; - t_value val, anded, ored; + int y; for (y=0; y<8; ++y) { - val = BRZ [7-y]; - anded = old_BRZ [7-y] & val; - ored = old_BRZ [7-y] | val; - old_BRZ [7-y] = val; - 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; - } - } + draw_full_word (BRZ[7-y], &old_BRZ[7-y], BRZ_lamps[y], + left+TEXTW, top+HEADER+y*STEPY); + } +} + +/* + * Visually separating groups of bits. + */ +static void draw_separators (int left, int top, int startbit, int step, int totbits, int rows) +{ + int x, color; + SDL_Rect area; + + color = grey.r << 16 | grey.g << 8 | grey.b; + for (x=startbit; x=0; --y) { sprintf (message, "БРЗ %d", 7-y); - render_utf8 (font_big, 24, top + 24 + y*STEPY, 1, message); - old_BRZ[y] = ~0; + render_utf8 (font_big, left, top + HEADER-4 + y*STEPY, 1, message); } + + /* Using bit numbers above GRP */ } /* @@ -439,6 +490,10 @@ t_stat besm6_init_panel (UNIT *u, int32 val, char *cptr, void *desc) return ret; } + /* Font colors */ + background = black; + foreground = cyan; + /* Open the font file with the requested point size */ font_big = TTF_OpenFont (QUOTE(FONTFILE), 16); font_small = TTF_OpenFont (QUOTE(FONTFILE), 9); @@ -463,13 +518,17 @@ t_stat besm6_init_panel (UNIT *u, int32 val, char *cptr, void *desc) /* Drawing the static part of the BESM-6 panel */ draw_modifiers_static (0, 24, 10); draw_modifiers_static (1, 400, 10); - draw_grp_static (180); - draw_brz_static (230); + draw_prp_static (24, 170); + draw_counters_static (24+32*STEPX, 170); + draw_grp_static (24, 230); + draw_brz_static (24, 280); /* 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)); + memset(PRP_lamps, ~0, sizeof(PRP_lamps)); + memset(PC_lamps, ~0, sizeof(PC_lamps)); besm6_draw_panel(1); /* Tell SDL to update the whole screen */ @@ -502,8 +561,10 @@ void besm6_draw_panel (int force) /* Do the blinkenlights */ draw_modifiers_periodic (0, 24, 10); draw_modifiers_periodic (1, 400, 10); - draw_grp_periodic (180); - draw_brz_periodic (230); + draw_counters_periodic (24+32*STEPX, 170); + draw_prp_periodic (24, 170); + draw_grp_periodic (24, 230); + draw_brz_periodic (24, 280); act = !act; @@ -556,16 +617,23 @@ t_stat besm6_init_panel (UNIT *u, int32 val, char *cptr, void *desc) return ret; } + /* Font colors */ + background = black; + foreground = cyan; + /* Drawing the static part of the BESM-6 panel */ draw_modifiers_static (0, 24, 10); draw_modifiers_static (1, 400, 10); - draw_grp_static (180); - draw_brz_static (230); + draw_prp_static (24, 170); + draw_counters_static (472, 170); + draw_grp_static (24, 230); + draw_brz_static (24, 280); /* 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)); + memset(PRP_lamps, ~0, sizeof(PRP_lamps)); besm6_draw_panel(1); /* Tell SDL to update the whole screen */ @@ -594,8 +662,10 @@ void besm6_draw_panel (int force) /* Do the blinkenlights */ draw_modifiers_periodic (0, 24, 10); draw_modifiers_periodic (1, 400, 10); - draw_grp_periodic (180); - draw_brz_periodic (230); + draw_counters_periodic (472, 170); + draw_prp_periodic (24, 170); + draw_grp_periodic (24, 230); + draw_brz_periodic (24, 280); /* Tell SDL to update the whole screen */ SDL_UpdateRect (screen, 0, 0, WIDTH, HEIGHT); diff --git a/BESM6/besm6_printer.c b/BESM6/besm6_printer.c index 07b8cf5f..6cfddad8 100644 --- a/BESM6/besm6_printer.c +++ b/BESM6/besm6_printer.c @@ -159,6 +159,7 @@ void printer_control (int num, uint32 cmd) case 2: /* ribbon off */ dev->rampup = cmd == 2 ? FAST_START : SLOW_START; sim_cancel (u); + fflush (u->fileref); break; } } diff --git a/BESM6/besm6_punch.c b/BESM6/besm6_punch.c index d9ca0a0d..c3d4a949 100644 --- a/BESM6/besm6_punch.c +++ b/BESM6/besm6_punch.c @@ -217,7 +217,6 @@ static int utf8_getc (FILE *fin); */ t_stat fs_event (UNIT *u) { - static int cnt; int num = u - fs_unit; again: if (fs_state[num] == FS_STARTING) { @@ -225,7 +224,6 @@ t_stat fs_event (UNIT *u) * no need to read anything from the attached file. */ FS[num] = 0; - cnt = 0; fs_state[num] = fs_textmode[num] ? FS_RUNNING : FS_BINARY; } else if (fs_state[num] == FS_BINARY) { int ch = getc (u->fileref);