From db44518808033e11bf53a6e9d9603c55f2ef672c Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Wed, 31 Dec 2014 08:39:40 -0800 Subject: [PATCH] BESM6: Convert to simh calibrated clocks and idling --- BESM6/besm6_cpu.c | 102 +++++++++++++++--------------------------- BESM6/besm6_defs.h | 4 +- BESM6/besm6_disk.c | 4 +- BESM6/besm6_drum.c | 4 +- BESM6/besm6_printer.c | 10 ++--- BESM6/besm6_punch.c | 3 +- BESM6/besm6_tty.c | 7 +-- 7 files changed, 52 insertions(+), 82 deletions(-) diff --git a/BESM6/besm6_cpu.c b/BESM6/besm6_cpu.c index f1e6fc31..3e52ecbf 100644 --- a/BESM6/besm6_cpu.c +++ b/BESM6/besm6_cpu.c @@ -53,18 +53,15 @@ #include "besm6_defs.h" #include #include -#include -#include -#include #include -#undef SOFT_CLOCK t_value memory [MEMSIZE]; uint32 PC, RK, Aex, M [NREGS], RAU, RUU; t_value ACC, RMR, GRP, MGRP; uint32 PRP, MPRP; uint32 READY, READY2; /* ready flags of various devices */ +int32 tmr_poll = CLK_DELAY; /* pgm timer poll */ extern const char *scp_errors[]; @@ -133,6 +130,8 @@ REG cpu_reg[] = { }; MTAB cpu_mod[] = { + { MTAB_XTD|MTAB_VDV, 0, "IDLE", "IDLE", &sim_set_idle, &sim_show_idle, NULL, "Display idle detection mode" }, + { MTAB_XTD|MTAB_VDV, 0, NULL, "NOIDLE", &sim_clr_idle, NULL, NULL, "Disables idle detection" }, { 0 } }; @@ -311,33 +310,6 @@ t_stat cpu_deposit (t_value val, t_addr addr, UNIT *uptr, int32 sw) return SCPE_OK; } -/* - * Функция вызывается каждые 4 миллисекунды реального времени. - */ -static void cpu_sigalarm (int signum) -{ - static unsigned counter; - - ++counter; - -#ifndef SOFT_CLOCK - /* В 9-й части частота таймера 250 Гц (4 мс). */ - GRP |= GRP_TIMER; - - /* Медленный таймер: должен быть 16 Гц. - * Но от него почему-то зависит вывод на терминалы, - * поэтому ускорим. */ - if ((counter & 3) == 0) { - GRP |= GRP_SLOW_CLK; - } -#endif - - /* Перерисовка панели каждые 64 миллисекунды. */ - if ((counter & 15) == 0) { - redraw_panel = 1; - } -} - /* * Reset routine */ @@ -367,19 +339,6 @@ t_stat cpu_reset (DEVICE *dptr) sim_brk_types = SWMASK ('E') | SWMASK('R') | SWMASK('W'); sim_brk_dflt = SWMASK ('E'); - struct itimerval itv; - - /* Чтобы ход часов в ДИСПАКе соответствал реальному времени, - * используем сигналы от системного таймера. */ - signal (SIGALRM, cpu_sigalarm); - itv.it_interval.tv_sec = 0; - itv.it_interval.tv_usec = 4000; - itv.it_value.tv_sec = 0; - itv.it_value.tv_usec = 4000; - if (setitimer (ITIMER_REAL, &itv, 0) < 0) { - perror ("setitimer"); - return SCPE_TIMER; - } return SCPE_OK; } @@ -807,9 +766,9 @@ void cpu_one_inst () corr_stack = 0; word = mmu_fetch (PC); if (RUU & RUU_RIGHT_INSTR) - RK = word; /* get right instruction */ + RK = (uint32)word; /* get right instruction */ else - RK = word >> 24; /* get left instruction */ + RK = (uint32)(word >> 24);/* get left instruction */ RK &= BITS(24); @@ -1475,11 +1434,7 @@ void cpu_one_inst () /* Если периферия простаивает, освобождаем процессор * до следующего тика таймера. */ - if (vt_is_idle() && - printer_is_idle() && fs_is_idle()) { - check_initial_setup (); - pause (); - } + sim_idle (0, TRUE); } } @@ -1739,43 +1694,56 @@ t_stat sim_instr (void) } } -t_stat slow_clk (UNIT * this) -{ - /*besm6_debug ("*** таймер 80 мсек");*/ - GRP |= GRP_SLOW_CLK; - return sim_activate (this, MSEC*125/2); -} - /* * В 9-й части частота таймера 250 Гц (4 мс), * в жизни - 50 Гц (20 мс). */ t_stat fast_clk (UNIT * this) { + static unsigned counter; + + ++counter; + /*besm6_debug ("*** таймер 20 мсек");*/ GRP |= GRP_TIMER; - return sim_activate (this, 20*MSEC); + + /* Медленный таймер: должен быть 16 Гц. + * Но от него почему-то зависит вывод на терминалы, + * поэтому ускорим. */ + if ((counter & 3) == 0) { + /*besm6_debug ("*** таймер 80 мсек");*/ + GRP |= GRP_SLOW_CLK; + } + + /* Перерисовка панели каждые 64 миллисекунды. */ + if ((counter & 15) == 0) { + redraw_panel = 1; + } + + tmr_poll = sim_rtcn_calb (CLK_TPS, 0); /* calibrate clock */ + return sim_activate_after (this, 1000000/CLK_TPS); /* reactivate unit */ } UNIT clocks[] = { - { UDATA(slow_clk, 0, 0) }, /* 10 р, 16 Гц */ - { UDATA(fast_clk, 0, 0) }, /* 40 р, 50 Гц */ + { UDATA(fast_clk, 0, 0), CLK_DELAY }, /* 40 р, 50 Гц */ }; t_stat clk_reset (DEVICE * dev) { + sim_register_clock_unit (&clocks[0]); + /* Схема автозапуска включается по нереализованной кнопке "МР" */ -#ifdef SOFT_CLOCK - sim_activate (&clocks[0], MSEC*125/2); - return sim_activate (&clocks[1], 20*MSEC); -#else + + if (!sim_is_running) { /* RESET (not IORESET)? */ + tmr_poll = sim_rtcn_init (clocks[0].wait, 0); /* init timer */ + sim_activate (&clocks[0], tmr_poll); /* activate unit */ + } return SCPE_OK; -#endif } DEVICE clock_dev = { "CLK", clocks, NULL, NULL, - 2, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, NULL, NULL, &clk_reset, NULL, NULL, NULL, NULL, DEV_DEBUG diff --git a/BESM6/besm6_defs.h b/BESM6/besm6_defs.h index faec0254..c1110a87 100644 --- a/BESM6/besm6_defs.h +++ b/BESM6/besm6_defs.h @@ -121,8 +121,10 @@ enum { /* * Считаем, что моделируеммая машина имеет опорную частоту 10 МГц. */ -#define USEC 10 /* одна микросекунда - десять тактов */ +#define USEC 1 /* одна микросекунда - десять тактов */ #define MSEC (1000*USEC) /* одна миллисекунда */ +#define CLK_TPS 250 /* Fast Clock Ticks Per Second (every 4ms) */ +#define CLK_DELAY 4000 /* Uncalibrated instructions per clock tick */ extern UNIT cpu_unit; extern t_value memory [MEMSIZE]; diff --git a/BESM6/besm6_disk.c b/BESM6/besm6_disk.c index 40e5065c..22a870c1 100644 --- a/BESM6/besm6_disk.c +++ b/BESM6/besm6_disk.c @@ -519,7 +519,7 @@ void disk_ctl (int ctlr, uint32 cmd) } /* Ждём события от устройства. */ - sim_activate (u, 20*USEC); /* Ускорим для отладки. */ + sim_activate_after (u, 20*USEC); /* Ускорим для отладки. */ } else if (cmd & BBIT(11)) { /* Выбора номера устройства и занесение в регистр маски КМД. @@ -614,7 +614,7 @@ void disk_ctl (int ctlr, uint32 cmd) disk_read_header (u); /* Ждём события от устройства. */ - sim_activate (u, 20*USEC); /* Ускорим для отладки. */ + sim_activate_after (u, 20*USEC); /* Ускорим для отладки. */ break; case 010: /* гашение PC */ #if 0 diff --git a/BESM6/besm6_drum.c b/BESM6/besm6_drum.c index e29df468..6bbb02ed 100644 --- a/BESM6/besm6_drum.c +++ b/BESM6/besm6_drum.c @@ -346,8 +346,8 @@ void drum (int ctlr, uint32 cmd) /* Ждём события от устройства. * Согласно данным из книжки Мазного Г.Л., * даём 20 мсек на обмен, или 200 тыс.тактов. */ - /*sim_activate (u, 20*MSEC);*/ - sim_activate (u, 20*USEC); /* Ускорим для отладки. */ + /*sim_activate_after (u, 20*MSEC);*/ + sim_activate_after (u, 20*USEC); /* Ускорим для отладки. */ } /* diff --git a/BESM6/besm6_printer.c b/BESM6/besm6_printer.c index 8cf88bf7..6270e486 100644 --- a/BESM6/besm6_printer.c +++ b/BESM6/besm6_printer.c @@ -159,7 +159,7 @@ void printer_control (int num, uint32 cmd) dev->feed = LINEFEED_SYNC; READY &= ~(PRN1_LINEFEED >> num); if (dev->rampup) - sim_activate (u, dev->rampup); + sim_activate_after (u, dev->rampup); dev->rampup = 0; break; case 10: /* motor and ribbon off */ @@ -208,7 +208,7 @@ t_stat printer_event (UNIT *u) GRP |= GRP_PRN1_SYNC >> num; ++dev->curchar; /* For next char */ - sim_activate (u, 1400*USEC); + sim_activate_after (u, 1400*USEC); if (dev->feed && --dev->feed == 0) { READY |= PRN1_LINEFEED >> num; } @@ -219,7 +219,7 @@ t_stat printer_event (UNIT *u) if (printer_dev.dctrl) besm6_debug(">>> АЦПУ%d 'ноль'", num); /* For first sync after "zero" */ - sim_activate (u, 1000*USEC); + sim_activate_after (u, 1000*USEC); } return SCPE_OK; } @@ -334,9 +334,9 @@ offset_gost_write (int num, FILE *fout) */ int printer_is_idle () { - if ((printer_unit[0].flags & UNIT_ATT) && acpu[0].rampup == 0) + if (sim_is_active(&printer_unit[0])) return 0; - if ((printer_unit[1].flags & UNIT_ATT) && acpu[1].rampup == 0) + if (sim_is_active(&printer_unit[1])) return 0; return 1; } diff --git a/BESM6/besm6_punch.c b/BESM6/besm6_punch.c index c160bf3b..e1b65705 100644 --- a/BESM6/besm6_punch.c +++ b/BESM6/besm6_punch.c @@ -27,7 +27,6 @@ * authorization from Leonid Broukhis and Serge Vakulenko. */ #include "besm6_defs.h" -#include t_stat fs_event (UNIT *u); t_stat uvvk_event (UNIT *u); @@ -169,7 +168,7 @@ void fs_control (int num, uint32 cmd) if (fs_state[num] == FS_IDLE) besm6_debug("<<< ФС1500-%d протяжка без мотора", num); else if (fs_state[num] != FS_TAIL) { - sim_activate (u, FS_RATE); + sim_activate_after (u, FS_RATE); bytecnt++; } else { if (! isfifo[num]) { diff --git a/BESM6/besm6_tty.c b/BESM6/besm6_tty.c index f260fe8b..d2d77f5c 100644 --- a/BESM6/besm6_tty.c +++ b/BESM6/besm6_tty.c @@ -82,9 +82,10 @@ void tt_print(); void consul_receive(); t_stat vt_clk(UNIT *); extern char *get_sim_sw (char *cptr); +extern int32 tmr_poll; /* calibrated clock timer poll */ UNIT tty_unit [] = { - { UDATA (vt_clk, UNIT_DIS, 0) }, /* fake unit, clock */ + { UDATA (vt_clk, UNIT_DIS|UNIT_IDLE, 0) }, /* fake unit, clock */ { UDATA (NULL, UNIT_SEQ, 0) }, { UDATA (NULL, UNIT_SEQ, 0) }, { UDATA (NULL, UNIT_SEQ, 0) }, @@ -160,7 +161,7 @@ t_stat tty_reset (DEVICE *dptr) /* Готовность устройства в READY2 инверсная, а устройство всегда готово */ /* Провоцируем передачу */ PRP |= CONS_CAN_PRINT[0] | CONS_CAN_PRINT[1]; - return sim_activate (tty_unit, 1000*MSEC/300); + return sim_clock_coschedule (tty_unit, 5*tmr_poll); } /* 19 р ГРП, 300 Гц */ @@ -223,7 +224,7 @@ t_stat vt_clk (UNIT * this) /* Опрашиваем сокеты на передачу. */ tmxr_poll_tx (&tty_desc); - return sim_activate (this, 1000*MSEC/300); + return sim_clock_coschedule (this, 5*tmr_poll); } t_stat tty_setmode (UNIT *u, int32 val, char *cptr, void *desc)