BESM6: Schedule the serial line timer by instruction count when I/O is pending, and by wallclock time otherwise. This achieves a good TTY output rate even when the CPU is busy with a user process.

This commit is contained in:
Leo Broukhis 2015-01-06 01:37:43 -08:00
parent aa16857edc
commit bd260dd523
6 changed files with 22 additions and 34 deletions

View file

@ -708,6 +708,12 @@ void check_initial_setup ()
/* 7 р. яч. ЗАНЯТА - разр любые приказы */
const t_value ALL_REQS_ENABLED = 1 << 6;
if (!vt_is_idle()) {
/* Avoid sending setup requests while the OS
* is still printing boot-up messages.
*/
return;
}
if ((memory[TAKEN] & SETUP_REQS_ENABLED) == 0 ||
(memory[TAKEN] & ALL_REQS_ENABLED) != 0 ||
(MGRP & GRP_PANEL_REQ) == 0) {
@ -1427,15 +1433,8 @@ void cpu_one_inst ()
/* Не находимся ли мы в цикле "ЖДУ" диспака? */
if (RUU == 047 && PC == 04440 && RK == 067704440) {
/* Если периферия простаивает, освобождаем процессор
* до следующего тика таймера. */
if (vt_is_idle()) {
check_initial_setup ();
sim_idle (0, TRUE);
} else if (sim_activate_time(tty_unit) > 1000*MSEC/300) {
/* Insert a TTY interrupt if a regular one is too far away */
sim_activate_abs(tty_unit, 0);
}
check_initial_setup ();
sim_idle(0, TRUE);
}
}

View file

@ -128,6 +128,7 @@ enum {
extern UNIT cpu_unit;
extern UNIT tty_unit[];
extern UNIT clocks[];
extern t_value memory [MEMSIZE];
extern t_value pult [8];
extern uint32 PC, RAU, RUU;
@ -326,7 +327,6 @@ int disk_errors (void);
*/
void printer_control (int num, uint32 cmd);
void printer_hammer (int num, int pos, uint32 mask);
int printer_is_idle (void);
/*
* Терминалы (телетайпы, видеотоны, "Консулы").
@ -344,7 +344,6 @@ int vt_is_idle (void);
*/
void fs_control (int num, uint32 cmd);
int fs_read (int num);
int fs_is_idle (void);
/*
* Отладочная выдача.

View file

@ -317,15 +317,3 @@ offset_gost_write (int num, FILE *fout)
memset(dev->line, 0, sizeof (dev->line));
dev->length = dev->strikes = 0;
}
/*
* Выясняем, остановлены ли АЦПУ. Нужно для входа в "спящий" режим.
*/
int printer_is_idle ()
{
if (sim_is_active(&printer_unit[0]))
return 0;
if (sim_is_active(&printer_unit[1]))
return 0;
return 1;
}

View file

@ -279,11 +279,6 @@ int fs_read(int num) {
return FS[num];
}
int fs_is_idle (void)
{
return fs_state[0] == FS_IDLE && fs_state[1] == FS_IDLE;
}
unsigned char
unicode_to_gost (unsigned short val)
{

View file

@ -238,12 +238,19 @@ t_stat vt_clk (UNIT * this)
/* Polling sockets for transmission. */
tmxr_poll_tx (&tty_desc);
/* We'll get a guaranteed interrupt rate of 250 Hz (wallclock)
* plus additional interrupts during the idle loop for speedup
* (see besm6_cpu.c).
/* If the TTY system is not idle, schedule the next interrupt
* by instruction count using the target interrupt rate of 300 Hz;
* otherwise we can wait for a roughly equivalent wallclock time period,
* e.g. until the next 250 Hz wallclock interrupt, but making sure
* that the model time interval between GRP_SERIAL interrupts
* is never less than expected.
* Using sim_activate_after() would be more straightforward (no need for a check
* as the host is faster than the target), but likely less efficient for idling.
*/
return sim_clock_coschedule (this, tmr_poll);
if (vt_is_idle() && sim_activate_time(clocks) > 1000*MSEC/300)
return sim_clock_coschedule (this, tmr_poll);
else
return sim_activate(this, 1000*MSEC/300);
}
t_stat tty_setmode (UNIT *u, int32 val, char *cptr, void *desc)

View file

@ -29,7 +29,7 @@ attach -e disk2 alt2048.bin
;
; Подключаем АЦПУ.
;
attach prn0 /dev/tty
attach prn0 output.txt
;
; Активируем операторский терминал,