From cc33257836cf4f27bca7d57e5c991fac001f53b7 Mon Sep 17 00:00:00 2001 From: Leo Broukhis Date: Tue, 30 Dec 2014 11:42:52 -0800 Subject: [PATCH] BESM6: Removed tabs, reindented, removed GNU extensions. --- BESM6/besm6_arith.c | 622 ++++----- BESM6/besm6_cpu.c | 2934 ++++++++++++++++++++-------------------- BESM6/besm6_defs.h | 396 +++--- BESM6/besm6_disk.c | 806 +++++------ BESM6/besm6_drum.c | 464 +++---- BESM6/besm6_mmu.c | 800 +++++------ BESM6/besm6_panel.c | 720 +++++----- BESM6/besm6_printer.c | 355 +++-- BESM6/besm6_punch.c | 676 +++++---- BESM6/besm6_sys.c | 1006 +++++++------- BESM6/besm6_tty.c | 1850 ++++++++++++------------- BESM6/boot_dispak.b6 | 910 ++++++------- BESM6/formatdisk.c | 0 BESM6/test_pprog05.b6 | 18 +- BESM6/test_pprog05.ini | 1 - 15 files changed, 5776 insertions(+), 5782 deletions(-) mode change 100755 => 100644 BESM6/formatdisk.c diff --git a/BESM6/besm6_arith.c b/BESM6/besm6_arith.c index d88bdd6e..016c2c01 100644 --- a/BESM6/besm6_arith.c +++ b/BESM6/besm6_arith.c @@ -30,37 +30,37 @@ #include "besm6_defs.h" typedef struct { - t_uint64 mantissa; - unsigned exponent; /* offset by 64 */ -} alureg_t; /* ALU register type */ + t_uint64 mantissa; + unsigned exponent; /* offset by 64 */ +} alureg_t; /* ALU register type */ static alureg_t toalu (t_value val) { - alureg_t ret; + alureg_t ret; - ret.mantissa = val & BITS41; - ret.exponent = (val >> 41) & BITS(7); - if (ret.mantissa & BIT41) - ret.mantissa |= BIT42; - return ret; + ret.mantissa = val & BITS41; + ret.exponent = (val >> 41) & BITS(7); + if (ret.mantissa & BIT41) + ret.mantissa |= BIT42; + return ret; } static int inline is_negative (alureg_t *word) { - return (word->mantissa & BIT41) != 0; + return (word->mantissa & BIT41) != 0; } static void negate (alureg_t *val) { - if (is_negative (val)) - val->mantissa |= BIT42; - val->mantissa = (~val->mantissa + 1) & BITS42; - if (((val->mantissa >> 1) ^ val->mantissa) & BIT41) { - val->mantissa >>= 1; - ++val->exponent; - } - if (is_negative (val)) - val->mantissa |= BIT42; + if (is_negative (val)) + val->mantissa |= BIT42; + val->mantissa = (~val->mantissa + 1) & BITS42; + if (((val->mantissa >> 1) ^ val->mantissa) & BIT41) { + val->mantissa >>= 1; + ++val->exponent; + } + if (is_negative (val)) + val->mantissa |= BIT42; } /* @@ -70,15 +70,15 @@ static void negate (alureg_t *val) */ int besm6_highest_bit (t_value val) { - int n = 32, cnt = 0; - do { - t_value tmp = val; - if (tmp >>= n) { - cnt += n; - val = tmp; - } - } while (n >>= 1); - return 48 - cnt; + int n = 32, cnt = 0; + do { + t_value tmp = val; + if (tmp >>= n) { + cnt += n; + val = tmp; + } + } while (n >>= 1); + return 48 - cnt; } /* @@ -88,86 +88,86 @@ int besm6_highest_bit (t_value val) */ static void normalize_and_round (alureg_t acc, t_uint64 mr, int rnd_rq) { - t_uint64 rr = 0; - int i; - t_uint64 r; + t_uint64 rr = 0; + int i; + t_uint64 r; - if (RAU & RAU_NORM_DISABLE) - goto chk_rnd; - i = (acc.mantissa >> 39) & 3; - if (i == 0) { - r = acc.mantissa & BITS40; - if (r) { - int cnt = besm6_highest_bit (r) - 9; - r <<= cnt; - rr = mr >> (40 - cnt); - acc.mantissa = r | rr; - mr <<= cnt; - acc.exponent -= cnt; - goto chk_zero; - } - r = mr & BITS40; - if (r) { - int cnt = besm6_highest_bit (r) - 9; - rr = mr; - r <<= cnt; - acc.mantissa = r; - mr = 0; - acc.exponent -= 40 + cnt; - goto chk_zero; - } - goto zero; - } else if (i == 3) { - r = ~acc.mantissa & BITS40; - if (r) { - int cnt = besm6_highest_bit (r) - 9; - r = (r << cnt) | ((1LL << cnt) - 1); - rr = mr >> (40 - cnt); - acc.mantissa = BIT41 | (~r & BITS40) | rr; - mr <<= cnt; - acc.exponent -= cnt; - goto chk_zero; - } - r = ~mr & BITS40; - if (r) { - int cnt = besm6_highest_bit (r) - 9; - rr = mr; - r = (r << cnt) | ((1LL << cnt) - 1); - acc.mantissa = BIT41 | (~r & BITS40); - mr = 0; - acc.exponent -= 40 + cnt; - goto chk_zero; - } else { - rr = 1; - acc.mantissa = BIT41; - mr = 0; - acc.exponent -= 80; - goto chk_zero; - } - } -chk_zero: - if (rr) - rnd_rq = 0; -chk_rnd: - if (acc.exponent & 0x8000) - goto zero; - if (! (RAU & RAU_ROUND_DISABLE) && rnd_rq) - acc.mantissa |= 1; + if (RAU & RAU_NORM_DISABLE) + goto chk_rnd; + i = (acc.mantissa >> 39) & 3; + if (i == 0) { + r = acc.mantissa & BITS40; + if (r) { + int cnt = besm6_highest_bit (r) - 9; + r <<= cnt; + rr = mr >> (40 - cnt); + acc.mantissa = r | rr; + mr <<= cnt; + acc.exponent -= cnt; + goto chk_zero; + } + r = mr & BITS40; + if (r) { + int cnt = besm6_highest_bit (r) - 9; + rr = mr; + r <<= cnt; + acc.mantissa = r; + mr = 0; + acc.exponent -= 40 + cnt; + goto chk_zero; + } + goto zero; + } else if (i == 3) { + r = ~acc.mantissa & BITS40; + if (r) { + int cnt = besm6_highest_bit (r) - 9; + r = (r << cnt) | ((1LL << cnt) - 1); + rr = mr >> (40 - cnt); + acc.mantissa = BIT41 | (~r & BITS40) | rr; + mr <<= cnt; + acc.exponent -= cnt; + goto chk_zero; + } + r = ~mr & BITS40; + if (r) { + int cnt = besm6_highest_bit (r) - 9; + rr = mr; + r = (r << cnt) | ((1LL << cnt) - 1); + acc.mantissa = BIT41 | (~r & BITS40); + mr = 0; + acc.exponent -= 40 + cnt; + goto chk_zero; + } else { + rr = 1; + acc.mantissa = BIT41; + mr = 0; + acc.exponent -= 80; + goto chk_zero; + } + } + chk_zero: + if (rr) + rnd_rq = 0; + chk_rnd: + if (acc.exponent & 0x8000) + goto zero; + if (! (RAU & RAU_ROUND_DISABLE) && rnd_rq) + acc.mantissa |= 1; - if (! acc.mantissa && ! (RAU & RAU_NORM_DISABLE)) { -zero: ACC = 0; - RMR &= ~BITS40; - return; - } + if (! acc.mantissa && ! (RAU & RAU_NORM_DISABLE)) { + zero: ACC = 0; + RMR &= ~BITS40; + return; + } - ACC = (t_value) (acc.exponent & BITS(7)) << 41 | - (acc.mantissa & BITS41); - RMR = (RMR & ~BITS40) | (mr & BITS40); - /* При переполнении мантисса и младшие разряды порядка верны */ - if (acc.exponent & 0x80) { - if (! (RAU & RAU_OVF_DISABLE)) - longjmp (cpu_halt, STOP_OVFL); - } + ACC = (t_value) (acc.exponent & BITS(7)) << 41 | + (acc.mantissa & BITS41); + RMR = (RMR & ~BITS40) | (mr & BITS40); + /* При переполнении мантисса и младшие разряды порядка верны */ + if (acc.exponent & 0x80) { + if (! (RAU & RAU_OVF_DISABLE)) + longjmp (cpu_halt, STOP_OVFL); + } } /* @@ -177,80 +177,80 @@ zero: ACC = 0; */ void besm6_add (t_value val, int negate_acc, int negate_val) { - t_uint64 mr; - alureg_t acc, word, a1, a2; - int diff, neg, rnd_rq = 0; + t_uint64 mr; + alureg_t acc, word, a1, a2; + int diff, neg, rnd_rq = 0; - acc = toalu (ACC); - word = toalu (val); - if (! negate_acc) { - if (! negate_val) { - /* Сложение */ - } else { - /* Вычитание */ - negate (&word); - } - } else { - if (! negate_val) { - /* Обратное вычитание */ - negate (&acc); - } else { - /* Вычитание модулей */ - if (is_negative (&acc)) - negate (&acc); - if (! is_negative (&word)) - negate (&word); - } - } + acc = toalu (ACC); + word = toalu (val); + if (! negate_acc) { + if (! negate_val) { + /* Сложение */ + } else { + /* Вычитание */ + negate (&word); + } + } else { + if (! negate_val) { + /* Обратное вычитание */ + negate (&acc); + } else { + /* Вычитание модулей */ + if (is_negative (&acc)) + negate (&acc); + if (! is_negative (&word)) + negate (&word); + } + } - diff = acc.exponent - word.exponent; - if (diff < 0) { - diff = -diff; - a1 = acc; - a2 = word; - } else { - a1 = word; - a2 = acc; - } - mr = 0; - neg = is_negative (&a1); - if (diff == 0) { - /* Nothing to do. */ - } else if (diff <= 40) { - rnd_rq = (mr = (a1.mantissa << (40 - diff)) & BITS40) != 0; - a1.mantissa = ((a1.mantissa >> diff) | - (neg ? (~0ll << (40 - diff)) : 0)) & BITS42; - } else if (diff <= 80) { - diff -= 40; - rnd_rq = a1.mantissa != 0; - mr = ((a1.mantissa >> diff) | - (neg ? (~0ll << (40 - diff)) : 0)) & BITS40; - if (neg) { - a1.mantissa = BITS42; - } else - a1.mantissa = 0; - } else { - rnd_rq = a1.mantissa != 0; - if (neg) { - mr = BITS40; - a1.mantissa = BITS42; - } else - mr = a1.mantissa = 0; - } - acc.exponent = a2.exponent; - acc.mantissa = a1.mantissa + a2.mantissa; + diff = acc.exponent - word.exponent; + if (diff < 0) { + diff = -diff; + a1 = acc; + a2 = word; + } else { + a1 = word; + a2 = acc; + } + mr = 0; + neg = is_negative (&a1); + if (diff == 0) { + /* Nothing to do. */ + } else if (diff <= 40) { + rnd_rq = (mr = (a1.mantissa << (40 - diff)) & BITS40) != 0; + a1.mantissa = ((a1.mantissa >> diff) | + (neg ? (~0ll << (40 - diff)) : 0)) & BITS42; + } else if (diff <= 80) { + diff -= 40; + rnd_rq = a1.mantissa != 0; + mr = ((a1.mantissa >> diff) | + (neg ? (~0ll << (40 - diff)) : 0)) & BITS40; + if (neg) { + a1.mantissa = BITS42; + } else + a1.mantissa = 0; + } else { + rnd_rq = a1.mantissa != 0; + if (neg) { + mr = BITS40; + a1.mantissa = BITS42; + } else + mr = a1.mantissa = 0; + } + acc.exponent = a2.exponent; + acc.mantissa = a1.mantissa + a2.mantissa; - /* Если требуется нормализация вправо, биты 42:41 - * принимают значение 01 или 10. */ - switch ((acc.mantissa >> 40) & 3) { - case 2: - case 1: - rnd_rq |= acc.mantissa & 1; - mr = (mr >> 1) | ((acc.mantissa & 1) << 39); - acc.mantissa >>= 1; - ++acc.exponent; - } - normalize_and_round (acc, mr, rnd_rq); + /* Если требуется нормализация вправо, биты 42:41 + * принимают значение 01 или 10. */ + switch ((acc.mantissa >> 40) & 3) { + case 2: + case 1: + rnd_rq |= acc.mantissa & 1; + mr = (mr >> 1) | ((acc.mantissa & 1) << 39); + acc.mantissa >>= 1; + ++acc.exponent; + } + normalize_and_round (acc, mr, rnd_rq); } /* @@ -260,37 +260,37 @@ void besm6_add (t_value val, int negate_acc, int negate_val) #define INT64(x) ((x) & BIT41 ? (-1LL << 40) | (x) : x) static alureg_t nrdiv (alureg_t n, alureg_t d) { - t_int64 nn, dd, q, res; - alureg_t quot; + t_int64 nn, dd, q, res; + alureg_t quot; - /* to compensate for potential normalization to the right */ - nn = INT64(n.mantissa)*2; - dd = INT64(d.mantissa)*2; - res = 0, q = BIT41; + /* to compensate for potential normalization to the right */ + nn = INT64(n.mantissa)*2; + dd = INT64(d.mantissa)*2; + res = 0, q = BIT41; - if (ABS(nn) >= ABS(dd)) { - /* normalization to the right */ - nn/=2; - n.exponent++; - } - while (q > 1) { - if (nn == 0) - break; + if (ABS(nn) >= ABS(dd)) { + /* normalization to the right */ + nn/=2; + n.exponent++; + } + while (q > 1) { + if (nn == 0) + break; - if (ABS(nn) < BIT40) - nn *= 2; /* magic shortcut */ - else if ((nn > 0) ^ (dd > 0)) { - res -= q; - nn = 2*nn+dd; - } else { - res += q; - nn = 2*nn-dd; - } - q /= 2; - } - quot.mantissa = res/2; - quot.exponent = n.exponent-d.exponent+64; - return quot; + if (ABS(nn) < BIT40) + nn *= 2; /* magic shortcut */ + else if ((nn > 0) ^ (dd > 0)) { + res -= q; + nn = 2*nn+dd; + } else { + res += q; + nn = 2*nn-dd; + } + q /= 2; + } + quot.mantissa = res/2; + quot.exponent = n.exponent-d.exponent+64; + return quot; } /* @@ -300,19 +300,19 @@ static alureg_t nrdiv (alureg_t n, alureg_t d) */ void besm6_divide (t_value val) { - alureg_t acc; - alureg_t dividend, divisor; + alureg_t acc; + alureg_t dividend, divisor; - if (((val ^ (val << 1)) & BIT41) == 0) { - /* Ненормализованный делитель: деление на ноль. */ - longjmp (cpu_halt, STOP_DIVZERO); - } - dividend = toalu(ACC); - divisor = toalu(val); + if (((val ^ (val << 1)) & BIT41) == 0) { + /* Ненормализованный делитель: деление на ноль. */ + longjmp (cpu_halt, STOP_DIVZERO); + } + dividend = toalu(ACC); + divisor = toalu(val); - acc = nrdiv(dividend, divisor); + acc = nrdiv(dividend, divisor); - normalize_and_round (acc, 0, 0); + normalize_and_round (acc, 0, 0); } /* @@ -322,56 +322,56 @@ void besm6_divide (t_value val) */ void besm6_multiply (t_value val) { - uint8 neg = 0; - alureg_t acc, word, a, b; - t_uint64 mr, alo, blo, ahi, bhi; + uint8 neg = 0; + alureg_t acc, word, a, b; + t_uint64 mr, alo, blo, ahi, bhi; - register t_uint64 l; + register t_uint64 l; - if (! ACC || ! val) { - /* multiplication by zero is zero */ - ACC = 0; - RMR &= ~BITS40; - return; - } - acc = toalu (ACC); - word = toalu (val); + if (! ACC || ! val) { + /* multiplication by zero is zero */ + ACC = 0; + RMR &= ~BITS40; + return; + } + acc = toalu (ACC); + word = toalu (val); - a = acc; - b = word; - mr = 0; + a = acc; + b = word; + mr = 0; - if (is_negative (&a)) { - neg = 1; - negate (&a); - } - if (is_negative (&b)) { - neg ^= 1; - negate (&b); - } - acc.exponent = a.exponent + b.exponent - 64; + if (is_negative (&a)) { + neg = 1; + negate (&a); + } + if (is_negative (&b)) { + neg ^= 1; + negate (&b); + } + acc.exponent = a.exponent + b.exponent - 64; - alo = a.mantissa & BITS(20); - ahi = a.mantissa >> 20; + alo = a.mantissa & BITS(20); + ahi = a.mantissa >> 20; - blo = b.mantissa & BITS(20); - bhi = b.mantissa >> 20; + blo = b.mantissa & BITS(20); + bhi = b.mantissa >> 20; - l = alo * blo + ((alo * bhi + ahi * blo) << 20); + l = alo * blo + ((alo * bhi + ahi * blo) << 20); - mr = l & BITS40; - l >>= 40; + mr = l & BITS40; + l >>= 40; - acc.mantissa = l + ahi * bhi; + acc.mantissa = l + ahi * bhi; - if (neg) { - mr = (~mr & BITS40) + 1; - acc.mantissa = ((~acc.mantissa & BITS40) + (mr >> 40)) - | BIT41 | BIT42; - mr &= BITS40; - } + if (neg) { + mr = (~mr & BITS40) + 1; + acc.mantissa = ((~acc.mantissa & BITS40) + (mr >> 40)) + | BIT41 | BIT42; + mr &= BITS40; + } - normalize_and_round (acc, mr, mr != 0); + normalize_and_round (acc, mr, mr != 0); } /* @@ -380,13 +380,13 @@ void besm6_multiply (t_value val) */ void besm6_change_sign (int negate_acc) { - alureg_t acc; + alureg_t acc; - acc = toalu (ACC); - if (negate_acc) - negate (&acc); - RMR = 0; - normalize_and_round (acc, 0, 0); + acc = toalu (ACC); + if (negate_acc) + negate (&acc); + RMR = 0; + normalize_and_round (acc, 0, 0); } /* @@ -395,12 +395,12 @@ void besm6_change_sign (int negate_acc) */ void besm6_add_exponent (int val) { - alureg_t acc; + alureg_t acc; - acc = toalu (ACC); - acc.exponent += val; - RMR = 0; - normalize_and_round (acc, 0, 0); + acc = toalu (ACC); + acc.exponent += val; + RMR = 0; + normalize_and_round (acc, 0, 0); } /* @@ -408,16 +408,16 @@ void besm6_add_exponent (int val) */ t_value besm6_pack (t_value val, t_value mask) { - t_value result; + t_value result; - result = 0; - for (; mask; mask>>=1, val>>=1) - if (mask & 1) { - result >>= 1; - if (val & 1) - result |= BIT48; - } - return result; + result = 0; + for (; mask; mask>>=1, val>>=1) + if (mask & 1) { + result >>= 1; + if (val & 1) + result |= BIT48; + } + return result; } /* @@ -425,20 +425,20 @@ t_value besm6_pack (t_value val, t_value mask) */ t_value besm6_unpack (t_value val, t_value mask) { - t_value result; - int i; + t_value result; + int i; - result = 0; - for (i=0; i<48; ++i) { - result <<= 1; - if (mask & BIT48) { - if (val & BIT48) - result |= 1; - val <<= 1; - } - mask <<= 1; - } - return result; + result = 0; + for (i=0; i<48; ++i) { + result <<= 1; + if (mask & BIT48) { + if (val & BIT48) + result |= 1; + val <<= 1; + } + mask <<= 1; + } + return result; } /* @@ -446,11 +446,11 @@ t_value besm6_unpack (t_value val, t_value mask) */ int besm6_count_ones (t_value word) { - int c; + int c; - for (c=0; word; ++c) - word &= word-1; - return c; + for (c=0; word; ++c) + word &= word-1; + return c; } /* @@ -459,25 +459,25 @@ int besm6_count_ones (t_value word) */ void besm6_shift (int i) { - RMR = 0; - if (i > 0) { - /* Сдвиг вправо. */ - if (i < 48) { - RMR = (ACC << (48-i)) & BITS48; - ACC >>= i; - } else { - RMR = ACC >> (i-48); - ACC = 0; - } - } else if (i < 0) { - /* Сдвиг влево. */ - i = -i; - if (i < 48) { - RMR = ACC >> (48-i); - ACC = (ACC << i) & BITS48; - } else { - RMR = (ACC << (i-48)) & BITS48; - ACC = 0; - } - } + RMR = 0; + if (i > 0) { + /* Сдвиг вправо. */ + if (i < 48) { + RMR = (ACC << (48-i)) & BITS48; + ACC >>= i; + } else { + RMR = ACC >> (i-48); + ACC = 0; + } + } else if (i < 0) { + /* Сдвиг влево. */ + i = -i; + if (i < 48) { + RMR = ACC >> (48-i); + ACC = (ACC << i) & BITS48; + } else { + RMR = (ACC << (i-48)) & BITS48; + ACC = 0; + } + } } diff --git a/BESM6/besm6_cpu.c b/BESM6/besm6_cpu.c index 4b782a1e..9da7c6be 100644 --- a/BESM6/besm6_cpu.c +++ b/BESM6/besm6_cpu.c @@ -98,189 +98,189 @@ t_stat cpu_reset (DEVICE *dptr); UNIT cpu_unit = { UDATA (NULL, UNIT_FIX, MEMSIZE) }; REG cpu_reg[] = { -{ "СчАС", &PC, 8, 15, 0, 1 }, /* счётчик адреса команды */ -{ "РК", &RK, 8, 24, 0, 1 }, /* регистр выполняемой команды */ -{ "Аисп", &Aex, 8, 15, 0, 1 }, /* исполнительный адрес */ -{ "СМ", &ACC, 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* сумматор */ -{ "РМР", &RMR, 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* регистр младших разрядов */ -{ "РАУ", &RAU, 2, 6, 0, 1 }, /* режимы АУ */ -{ "М1", &M[1], 8, 15, 0, 1 }, /* регистры-модификаторы */ -{ "М2", &M[2], 8, 15, 0, 1 }, -{ "М3", &M[3], 8, 15, 0, 1 }, -{ "М4", &M[4], 8, 15, 0, 1 }, -{ "М5", &M[5], 8, 15, 0, 1 }, -{ "М6", &M[6], 8, 15, 0, 1 }, -{ "М7", &M[7], 8, 15, 0, 1 }, -{ "М10", &M[010], 8, 15, 0, 1 }, -{ "М11", &M[011], 8, 15, 0, 1 }, -{ "М12", &M[012], 8, 15, 0, 1 }, -{ "М13", &M[013], 8, 15, 0, 1 }, -{ "М14", &M[014], 8, 15, 0, 1 }, -{ "М15", &M[015], 8, 15, 0, 1 }, -{ "М16", &M[016], 8, 15, 0, 1 }, -{ "М17", &M[017], 8, 15, 0, 1 }, /* указатель магазина */ -{ "М20", &M[020], 8, 15, 0, 1 }, /* MOD - модификатор адреса */ -{ "М21", &M[021], 8, 15, 0, 1 }, /* PSW - режимы УУ */ -{ "М27", &M[027], 8, 15, 0, 1 }, /* SPSW - упрятывание режимов УУ */ -{ "М32", &M[032], 8, 15, 0, 1 }, /* ERET - адрес возврата из экстракода */ -{ "М33", &M[033], 8, 15, 0, 1 }, /* IRET - адрес возврата из прерывания */ -{ "М34", &M[034], 8, 16, 0, 1 }, /* IBP - адрес прерывания по выполнению */ -{ "М35", &M[035], 8, 16, 0, 1 }, /* DWP - адрес прерывания по чтению/записи */ -{ "РУУ", &RUU, 2, 9, 0, 1 }, /* ПКП, ПКЛ, РежЭ, РежПр, ПрИК, БРО, ПрК */ -{ "ГРП", &GRP, 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* главный регистр прерываний */ -{ "МГРП", &MGRP, 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* маска ГРП */ -{ "ПРП", &PRP, 8, 24, 0, 1 }, /* периферийный регистр прерываний */ -{ "МПРП", &MPRP, 8, 24, 0, 1 }, /* маска ПРП */ -{ 0 } + { "СчАС", &PC, 8, 15, 0, 1 }, /* счётчик адреса команды */ + { "РК", &RK, 8, 24, 0, 1 }, /* регистр выполняемой команды */ + { "Аисп", &Aex, 8, 15, 0, 1 }, /* исполнительный адрес */ + { "СМ", &ACC, 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* сумматор */ + { "РМР", &RMR, 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* регистр младших разрядов */ + { "РАУ", &RAU, 2, 6, 0, 1 }, /* режимы АУ */ + { "М1", &M[1], 8, 15, 0, 1 }, /* регистры-модификаторы */ + { "М2", &M[2], 8, 15, 0, 1 }, + { "М3", &M[3], 8, 15, 0, 1 }, + { "М4", &M[4], 8, 15, 0, 1 }, + { "М5", &M[5], 8, 15, 0, 1 }, + { "М6", &M[6], 8, 15, 0, 1 }, + { "М7", &M[7], 8, 15, 0, 1 }, + { "М10", &M[010], 8, 15, 0, 1 }, + { "М11", &M[011], 8, 15, 0, 1 }, + { "М12", &M[012], 8, 15, 0, 1 }, + { "М13", &M[013], 8, 15, 0, 1 }, + { "М14", &M[014], 8, 15, 0, 1 }, + { "М15", &M[015], 8, 15, 0, 1 }, + { "М16", &M[016], 8, 15, 0, 1 }, + { "М17", &M[017], 8, 15, 0, 1 }, /* указатель магазина */ + { "М20", &M[020], 8, 15, 0, 1 }, /* MOD - модификатор адреса */ + { "М21", &M[021], 8, 15, 0, 1 }, /* PSW - режимы УУ */ + { "М27", &M[027], 8, 15, 0, 1 }, /* SPSW - упрятывание режимов УУ */ + { "М32", &M[032], 8, 15, 0, 1 }, /* ERET - адрес возврата из экстракода */ + { "М33", &M[033], 8, 15, 0, 1 }, /* IRET - адрес возврата из прерывания */ + { "М34", &M[034], 8, 16, 0, 1 }, /* IBP - адрес прерывания по выполнению */ + { "М35", &M[035], 8, 16, 0, 1 }, /* DWP - адрес прерывания по чтению/записи */ + { "РУУ", &RUU, 2, 9, 0, 1 }, /* ПКП, ПКЛ, РежЭ, РежПр, ПрИК, БРО, ПрК */ + { "ГРП", &GRP, 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* главный регистр прерываний */ + { "МГРП", &MGRP, 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* маска ГРП */ + { "ПРП", &PRP, 8, 24, 0, 1 }, /* периферийный регистр прерываний */ + { "МПРП", &MPRP, 8, 24, 0, 1 }, /* маска ПРП */ + { 0 } }; MTAB cpu_mod[] = { - { 0 } + { 0 } }; DEVICE cpu_dev = { - "CPU", &cpu_unit, cpu_reg, cpu_mod, - 1, 8, 17, 1, 8, 50, - &cpu_examine, &cpu_deposit, &cpu_reset, - NULL, NULL, NULL, NULL, - DEV_DEBUG + "CPU", &cpu_unit, cpu_reg, cpu_mod, + 1, 8, 17, 1, 8, 50, + &cpu_examine, &cpu_deposit, &cpu_reset, + NULL, NULL, NULL, NULL, + DEV_DEBUG }; /* * REG: псевдоустройство, содержащее латинские синонимы всех регистров. */ REG reg_reg[] = { -{ "PC", &PC, 8, 15, 0, 1 }, /* счётчик адреса команды */ -{ "RK", &RK, 8, 24, 0, 1 }, /* регистр выполняемой команды */ -{ "Aex", &Aex, 8, 15, 0, 1 }, /* исполнительный адрес */ -{ "ACC", &ACC, 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* сумматор */ -{ "RMR", &RMR, 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* регистр младших разрядов */ -{ "RAU", &RAU, 2, 6, 0, 1 }, /* режимы АУ */ -{ "M1", &M[1], 8, 15, 0, 1 }, /* регистры-модификаторы */ -{ "M2", &M[2], 8, 15, 0, 1 }, -{ "M3", &M[3], 8, 15, 0, 1 }, -{ "M4", &M[4], 8, 15, 0, 1 }, -{ "M5", &M[5], 8, 15, 0, 1 }, -{ "M6", &M[6], 8, 15, 0, 1 }, -{ "M7", &M[7], 8, 15, 0, 1 }, -{ "M10", &M[010], 8, 15, 0, 1 }, -{ "M11", &M[011], 8, 15, 0, 1 }, -{ "M12", &M[012], 8, 15, 0, 1 }, -{ "M13", &M[013], 8, 15, 0, 1 }, -{ "M14", &M[014], 8, 15, 0, 1 }, -{ "M15", &M[015], 8, 15, 0, 1 }, -{ "M16", &M[016], 8, 15, 0, 1 }, -{ "M17", &M[017], 8, 15, 0, 1 }, /* указатель магазина */ -{ "M20", &M[020], 8, 15, 0, 1 }, /* MOD - модификатор адреса */ -{ "M21", &M[021], 8, 15, 0, 1 }, /* PSW - режимы УУ */ -{ "M27", &M[027], 8, 15, 0, 1 }, /* SPSW - упрятывание режимов УУ */ -{ "M32", &M[032], 8, 15, 0, 1 }, /* ERET - адрес возврата из экстракода */ -{ "M33", &M[033], 8, 15, 0, 1 }, /* IRET - адрес возврата из прерывания */ -{ "M34", &M[034], 8, 16, 0, 1 }, /* IBP - адрес прерывания по выполнению */ -{ "M35", &M[035], 8, 16, 0, 1 }, /* DWP - адрес прерывания по чтению/записи */ -{ "RUU", &RUU, 2, 9, 0, 1 }, /* ПКП, ПКЛ, РежЭ, РежПр, ПрИК, БРО, ПрК */ -{ "GRP", &GRP, 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* главный регистр прерываний */ -{ "MGRP", &MGRP, 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* маска ГРП */ -{ "PRP", &PRP, 8, 24, 0, 1 }, /* периферийный регистр прерываний */ -{ "MPRP", &MPRP, 8, 24, 0, 1 }, /* маска ПРП */ + { "PC", &PC, 8, 15, 0, 1 }, /* счётчик адреса команды */ + { "RK", &RK, 8, 24, 0, 1 }, /* регистр выполняемой команды */ + { "Aex", &Aex, 8, 15, 0, 1 }, /* исполнительный адрес */ + { "ACC", &ACC, 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* сумматор */ + { "RMR", &RMR, 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* регистр младших разрядов */ + { "RAU", &RAU, 2, 6, 0, 1 }, /* режимы АУ */ + { "M1", &M[1], 8, 15, 0, 1 }, /* регистры-модификаторы */ + { "M2", &M[2], 8, 15, 0, 1 }, + { "M3", &M[3], 8, 15, 0, 1 }, + { "M4", &M[4], 8, 15, 0, 1 }, + { "M5", &M[5], 8, 15, 0, 1 }, + { "M6", &M[6], 8, 15, 0, 1 }, + { "M7", &M[7], 8, 15, 0, 1 }, + { "M10", &M[010], 8, 15, 0, 1 }, + { "M11", &M[011], 8, 15, 0, 1 }, + { "M12", &M[012], 8, 15, 0, 1 }, + { "M13", &M[013], 8, 15, 0, 1 }, + { "M14", &M[014], 8, 15, 0, 1 }, + { "M15", &M[015], 8, 15, 0, 1 }, + { "M16", &M[016], 8, 15, 0, 1 }, + { "M17", &M[017], 8, 15, 0, 1 }, /* указатель магазина */ + { "M20", &M[020], 8, 15, 0, 1 }, /* MOD - модификатор адреса */ + { "M21", &M[021], 8, 15, 0, 1 }, /* PSW - режимы УУ */ + { "M27", &M[027], 8, 15, 0, 1 }, /* SPSW - упрятывание режимов УУ */ + { "M32", &M[032], 8, 15, 0, 1 }, /* ERET - адрес возврата из экстракода */ + { "M33", &M[033], 8, 15, 0, 1 }, /* IRET - адрес возврата из прерывания */ + { "M34", &M[034], 8, 16, 0, 1 }, /* IBP - адрес прерывания по выполнению */ + { "M35", &M[035], 8, 16, 0, 1 }, /* DWP - адрес прерывания по чтению/записи */ + { "RUU", &RUU, 2, 9, 0, 1 }, /* ПКП, ПКЛ, РежЭ, РежПр, ПрИК, БРО, ПрК */ + { "GRP", &GRP, 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* главный регистр прерываний */ + { "MGRP", &MGRP, 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* маска ГРП */ + { "PRP", &PRP, 8, 24, 0, 1 }, /* периферийный регистр прерываний */ + { "MPRP", &MPRP, 8, 24, 0, 1 }, /* маска ПРП */ -{ "BRZ0", &BRZ[0], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, -{ "BRZ1", &BRZ[1], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, -{ "BRZ2", &BRZ[2], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, -{ "BRZ3", &BRZ[3], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, -{ "BRZ4", &BRZ[4], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, -{ "BRZ5", &BRZ[5], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, -{ "BRZ6", &BRZ[6], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, -{ "BRZ7", &BRZ[7], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, -{ "BAZ0", &BAZ[0], 8, 16, 0, 1 }, -{ "BAZ1", &BAZ[1], 8, 16, 0, 1 }, -{ "BAZ2", &BAZ[2], 8, 16, 0, 1 }, -{ "BAZ3", &BAZ[3], 8, 16, 0, 1 }, -{ "BAZ4", &BAZ[4], 8, 16, 0, 1 }, -{ "BAZ5", &BAZ[5], 8, 16, 0, 1 }, -{ "BAZ6", &BAZ[6], 8, 16, 0, 1 }, -{ "BAZ7", &BAZ[7], 8, 16, 0, 1 }, -{ "TABST", &TABST, 8, 28, 0, 1 }, -{ "RP0", &RP[0], 8, 48, 0, 1, NULL, NULL, REG_VMIO }, -{ "RP1", &RP[1], 8, 48, 0, 1, NULL, NULL, REG_VMIO }, -{ "RP2", &RP[2], 8, 48, 0, 1, NULL, NULL, REG_VMIO }, -{ "RP3", &RP[3], 8, 48, 0, 1, NULL, NULL, REG_VMIO }, -{ "RP4", &RP[4], 8, 48, 0, 1, NULL, NULL, REG_VMIO }, -{ "RP5", &RP[5], 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 }, -{ "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 }, -{ 0 } + { "BRZ0", &BRZ[0], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, + { "BRZ1", &BRZ[1], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, + { "BRZ2", &BRZ[2], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, + { "BRZ3", &BRZ[3], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, + { "BRZ4", &BRZ[4], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, + { "BRZ5", &BRZ[5], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, + { "BRZ6", &BRZ[6], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, + { "BRZ7", &BRZ[7], 8, 50, 0, 1, NULL, NULL, REG_VMIO }, + { "BAZ0", &BAZ[0], 8, 16, 0, 1 }, + { "BAZ1", &BAZ[1], 8, 16, 0, 1 }, + { "BAZ2", &BAZ[2], 8, 16, 0, 1 }, + { "BAZ3", &BAZ[3], 8, 16, 0, 1 }, + { "BAZ4", &BAZ[4], 8, 16, 0, 1 }, + { "BAZ5", &BAZ[5], 8, 16, 0, 1 }, + { "BAZ6", &BAZ[6], 8, 16, 0, 1 }, + { "BAZ7", &BAZ[7], 8, 16, 0, 1 }, + { "TABST", &TABST, 8, 28, 0, 1 }, + { "RP0", &RP[0], 8, 48, 0, 1, NULL, NULL, REG_VMIO }, + { "RP1", &RP[1], 8, 48, 0, 1, NULL, NULL, REG_VMIO }, + { "RP2", &RP[2], 8, 48, 0, 1, NULL, NULL, REG_VMIO }, + { "RP3", &RP[3], 8, 48, 0, 1, NULL, NULL, REG_VMIO }, + { "RP4", &RP[4], 8, 48, 0, 1, NULL, NULL, REG_VMIO }, + { "RP5", &RP[5], 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 }, + { "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 }, + { 0 } }; UNIT reg_unit = { - UDATA (NULL, 0, 8) + UDATA (NULL, 0, 8) }; DEVICE reg_dev = { - "REG", ®_unit, reg_reg, NULL, - 1, 8, 1, 1, 8, 50, + "REG", ®_unit, reg_reg, NULL, + 1, 8, 1, 1, 8, 50, }; /* * SCP data structures and interface routines * - * sim_name simulator name string - * sim_PC pointer to saved PC register descriptor - * sim_emax maximum number of words for examine/deposit - * sim_devices array of pointers to simulated devices - * sim_stop_messages array of pointers to stop messages - * sim_load binary loader + * sim_name simulator name string + * sim_PC pointer to saved PC register descriptor + * sim_emax maximum number of words for examine/deposit + * sim_devices array of pointers to simulated devices + * sim_stop_messages array of pointers to stop messages + * sim_load binary loader */ char sim_name[] = "БЭСМ-6"; REG *sim_PC = &cpu_reg[0]; -int32 sim_emax = 1; /* максимальное количество слов в машинной команде */ +int32 sim_emax = 1; /* максимальное количество слов в машинной команде */ DEVICE *sim_devices[] = { - &cpu_dev, - ®_dev, - &drum_dev, - &disk_dev, - &mmu_dev, - &clock_dev, - &printer_dev, - &fs_dev, - &tty_dev, /* терминалы - телетайпы, видеотоны, "Консулы" */ - 0 + &cpu_dev, + ®_dev, + &drum_dev, + &disk_dev, + &mmu_dev, + &clock_dev, + &printer_dev, + &fs_dev, + &tty_dev, /* терминалы - телетайпы, видеотоны, "Консулы" */ + 0 }; const char *sim_stop_messages[] = { - "Неизвестная ошибка", /* Unknown error */ - "Останов", /* STOP */ - "Точка останова", /* Emulator breakpoint */ - "Точка останова по считыванию", /* Emulator read watchpoint */ - "Точка останова по записи", /* Emulator write watchpoint */ - "Выход за пределы памяти", /* Run out end of memory */ - "Запрещенная команда", /* Invalid instruction */ - "Контроль команды", /* A data-tagged word fetched */ - "Команда в чужом листе", /* Paging error during fetch */ - "Число в чужом листе", /* Paging error during load/store */ - "Контроль числа МОЗУ", /* RAM parity error */ - "Контроль числа БРЗ", /* Write cache parity error */ - "Переполнение АУ", /* Arith. overflow */ - "Деление на нуль", /* Division by zero or denorm */ - "Двойное внутреннее прерывание", /* SIMH: Double internal interrupt */ - "Чтение неформатированного барабана", /* Reading unformatted drum */ - "Чтение неформатированного диска", /* Reading unformatted disk */ - "Останов по КРА", /* Hardware breakpoint */ - "Останов по считыванию", /* Load watchpoint */ - "Останов по записи", /* Store watchpoint */ - "Не реализовано", /* Unimplemented I/O or special reg. access */ + "Неизвестная ошибка", /* Unknown error */ + "Останов", /* STOP */ + "Точка останова", /* Emulator breakpoint */ + "Точка останова по считыванию", /* Emulator read watchpoint */ + "Точка останова по записи", /* Emulator write watchpoint */ + "Выход за пределы памяти", /* Run out end of memory */ + "Запрещенная команда", /* Invalid instruction */ + "Контроль команды", /* A data-tagged word fetched */ + "Команда в чужом листе", /* Paging error during fetch */ + "Число в чужом листе", /* Paging error during load/store */ + "Контроль числа МОЗУ", /* RAM parity error */ + "Контроль числа БРЗ", /* Write cache parity error */ + "Переполнение АУ", /* Arith. overflow */ + "Деление на нуль", /* Division by zero or denorm */ + "Двойное внутреннее прерывание", /* SIMH: Double internal interrupt */ + "Чтение неформатированного барабана", /* Reading unformatted drum */ + "Чтение неформатированного диска", /* Reading unformatted disk */ + "Останов по КРА", /* Hardware breakpoint */ + "Останов по считыванию", /* Load watchpoint */ + "Останов по записи", /* Store watchpoint */ + "Не реализовано", /* Unimplemented I/O or special reg. access */ }; /* @@ -288,15 +288,15 @@ const char *sim_stop_messages[] = { */ 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 - *vptr = memory [addr]; - } - return SCPE_OK; + if (addr >= MEMSIZE) + return SCPE_NXM; + if (vptr) { + if (addr < 010) + *vptr = pult [addr]; + else + *vptr = memory [addr]; + } + return SCPE_OK; } /* @@ -304,13 +304,13 @@ 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) { - if (addr >= MEMSIZE) - return SCPE_NXM; - if (addr < 010) - pult [addr] = SET_CONVOL (val, CONVOL_INSN); - else - memory [addr] = SET_CONVOL (val, CONVOL_INSN); - return SCPE_OK; + if (addr >= MEMSIZE) + return SCPE_NXM; + if (addr < 010) + pult [addr] = SET_CONVOL (val, CONVOL_INSN); + else + memory [addr] = SET_CONVOL (val, CONVOL_INSN); + return SCPE_OK; } /* @@ -318,26 +318,26 @@ t_stat cpu_deposit (t_value val, t_addr addr, UNIT *uptr, int32 sw) */ static void cpu_sigalarm (int signum) { - static unsigned counter; + static unsigned counter; - ++counter; + ++counter; #ifndef SOFT_CLOCK - /* В 9-й части частота таймера 250 Гц (4 мс). */ - GRP |= GRP_TIMER; + /* В 9-й части частота таймера 250 Гц (4 мс). */ + GRP |= GRP_TIMER; - /* Медленный таймер: должен быть 16 Гц. - * Но от него почему-то зависит вывод на терминалы, - * поэтому ускорим. */ - if ((counter & 3) == 0) { - GRP |= GRP_SLOW_CLK; - } + /* Медленный таймер: должен быть 16 Гц. + * Но от него почему-то зависит вывод на терминалы, + * поэтому ускорим. */ + if ((counter & 3) == 0) { + GRP |= GRP_SLOW_CLK; + } #endif - /* Перерисовка панели каждые 64 миллисекунды. */ - if ((counter & 15) == 0) { - redraw_panel = 1; - } + /* Перерисовка панели каждые 64 миллисекунды. */ + if ((counter & 15) == 0) { + redraw_panel = 1; + } } /* @@ -345,44 +345,44 @@ static void cpu_sigalarm (int signum) */ t_stat cpu_reset (DEVICE *dptr) { - int i; + int i; - ACC = 0; - RMR = 0; - RAU = 0; - RUU = RUU_EXTRACODE | RUU_AVOST_DISABLE; - for (i=0; i> 6 | 0xc0, fout); - putc ((ch & 0x3f) | 0x80, fout); - return; - } - putc (ch >> 12 | 0xe0, fout); - putc (((ch >> 6) & 0x3f) | 0x80, fout); - putc ((ch & 0x3f) | 0x80, fout); + if (ch < 0x80) { + putc (ch, fout); + return; + } + if (ch < 0x800) { + putc (ch >> 6 | 0xc0, fout); + putc ((ch & 0x3f) | 0x80, fout); + return; + } + putc (ch >> 12 | 0xe0, fout); + putc (((ch >> 6) & 0x3f) | 0x80, fout); + putc ((ch & 0x3f) | 0x80, fout); } /* @@ -415,27 +415,27 @@ utf8_putc (unsigned ch, FILE *fout) */ void besm6_okno (const char *message) { - besm6_log_cont ("_%%%%%% %s: ", message); - if (sim_log) - besm6_fprint_cmd (sim_log, RK); - besm6_log ("_"); + besm6_log_cont ("_%%%%%% %s: ", message); + if (sim_log) + besm6_fprint_cmd (sim_log, RK); + besm6_log ("_"); - /* СчАС, системные индекс-регистры 020-035. */ - besm6_log ("_ СчАС:%05o 20:%05o 21:%05o 27:%05o 32:%05o 33:%05o 34:%05o 35:%05o", - PC, M[020], M[021], M[027], M[032], M[033], M[034], M[035]); - /* Индекс-регистры 1-7. */ - besm6_log ("_ 1:%05o 2:%05o 3:%05o 4:%05o 5:%05o 6:%05o 7:%05o", - M[1], M[2], M[3], M[4], M[5], M[6], M[7]); - /* Индекс-регистры 010-017. */ - besm6_log ("_ 10:%05o 11:%05o 12:%05o 13:%05o 14:%05o 15:%05o 16:%05o 17:%05o", - M[010], M[011], M[012], M[013], M[014], M[015], M[016], M[017]); - /* Сумматор, РМР, режимы АУ и УУ. */ - besm6_log ("_ СМ:%04o %04o %04o %04o РМР:%04o %04o %04o %04o РАУ:%02o РУУ:%03o", - (int) (ACC >> 36) & BITS(12), (int) (ACC >> 24) & BITS(12), - (int) (ACC >> 12) & BITS(12), (int) ACC & BITS(12), - (int) (RMR >> 36) & BITS(12), (int) (RMR >> 24) & BITS(12), - (int) (RMR >> 12) & BITS(12), (int) RMR & BITS(12), - RAU, RUU); + /* СчАС, системные индекс-регистры 020-035. */ + besm6_log ("_ СчАС:%05o 20:%05o 21:%05o 27:%05o 32:%05o 33:%05o 34:%05o 35:%05o", + PC, M[020], M[021], M[027], M[032], M[033], M[034], M[035]); + /* Индекс-регистры 1-7. */ + besm6_log ("_ 1:%05o 2:%05o 3:%05o 4:%05o 5:%05o 6:%05o 7:%05o", + M[1], M[2], M[3], M[4], M[5], M[6], M[7]); + /* Индекс-регистры 010-017. */ + besm6_log ("_ 10:%05o 11:%05o 12:%05o 13:%05o 14:%05o 15:%05o 16:%05o 17:%05o", + M[010], M[011], M[012], M[013], M[014], M[015], M[016], M[017]); + /* Сумматор, РМР, режимы АУ и УУ. */ + besm6_log ("_ СМ:%04o %04o %04o %04o РМР:%04o %04o %04o %04o РАУ:%02o РУУ:%03o", + (int) (ACC >> 36) & BITS(12), (int) (ACC >> 24) & BITS(12), + (int) (ACC >> 12) & BITS(12), (int) ACC & BITS(12), + (int) (RMR >> 36) & BITS(12), (int) (RMR >> 24) & BITS(12), + (int) (RMR >> 12) & BITS(12), (int) RMR & BITS(12), + RAU, RUU); } /* @@ -444,66 +444,72 @@ void besm6_okno (const char *message) static void cmd_002 () { #if 0 - besm6_debug ("*** рег %03o", Aex & 0377); + besm6_debug ("*** рег %03o", Aex & 0377); #endif - switch (Aex & 0377) { - case 0 ... 7: - /* Запись в БРЗ */ - mmu_setcache (Aex & 7, ACC); - break; - case 020 ... 027: - /* Запись в регистры приписки */ - mmu_setrp (Aex & 7, ACC); - break; - case 030 ... 033: - /* Запись в регистры защиты */ - mmu_setprotection (Aex & 3, ACC); - break; - case 036: - /* Запись в маску главного регистра прерываний */ - MGRP = ACC; - break; - case 037: - /* Гашение главного регистра прерываний */ - /* нехранящие биты невозможно погасить */ - GRP &= ACC | GRP_WIRED_BITS; - break; - case 0100 ... 0137: - /* Бит 1: управление блокировкой режима останова БРО. - * Биты 2 и 3 - признаки формирования контрольных - * разрядов (ПКП и ПКЛ). */ - if (Aex & 1) - RUU |= RUU_AVOST_DISABLE; - else - RUU &= ~RUU_AVOST_DISABLE; - if (Aex & 2) - RUU |= RUU_CONVOL_RIGHT; - else - RUU &= ~RUU_CONVOL_RIGHT; - if (Aex & 4) - RUU |= RUU_CONVOL_LEFT; - else - RUU &= ~RUU_CONVOL_LEFT; - break; - case 0140 ... 0177: - /* TODO: управление блокировкой схемы - * автоматического запуска */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 0200 ... 0207: - /* Чтение БРЗ */ - ACC = mmu_getcache (Aex & 7); - break; - case 0237: - /* Чтение главного регистра прерываний */ - ACC = GRP; - break; - default: - /* Неиспользуемые адреса */ - besm6_debug ("*** %05o%s: РЕГ %o - неправильный адрес спец.регистра", - PC, (RUU & RUU_RIGHT_INSTR) ? "п" : "л", Aex); - break; - } + switch (Aex & 0377) { + case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: + /* Запись в БРЗ */ + mmu_setcache (Aex & 7, ACC); + break; + case 020: case 021: case 022: case 023: + case 024: case 025: case 026: case 027: + /* Запись в регистры приписки */ + mmu_setrp (Aex & 7, ACC); + break; + case 030: case 031: case 032: case 033: + /* Запись в регистры защиты */ + mmu_setprotection (Aex & 3, ACC); + break; + case 036: + /* Запись в маску главного регистра прерываний */ + MGRP = ACC; + break; + case 037: + /* Гашение главного регистра прерываний */ + /* нехранящие биты невозможно погасить */ + GRP &= ACC | GRP_WIRED_BITS; + break; + case 64: case 65: case 66: case 67: case 68: case 69: case 70: case 71: + case 72: case 73: case 74: case 75: case 76: case 77: case 78: case 79: + case 80: case 81: case 82: case 83: case 84: case 85: case 86: case 87: + case 88: case 89: case 90: case 91: case 92: case 93: case 94: case 95: + /* 0100 - 0137: + * Бит 1: управление блокировкой режима останова БРО. + * Биты 2 и 3 - признаки формирования контрольных + * разрядов (ПКП и ПКЛ). */ + if (Aex & 1) + RUU |= RUU_AVOST_DISABLE; + else + RUU &= ~RUU_AVOST_DISABLE; + if (Aex & 2) + RUU |= RUU_CONVOL_RIGHT; + else + RUU &= ~RUU_CONVOL_RIGHT; + if (Aex & 4) + RUU |= RUU_CONVOL_LEFT; + else + RUU &= ~RUU_CONVOL_LEFT; + break; + case 0200: case 0201: case 0202: case 0203: + case 0204: case 0205: case 0206: case 0207: + /* Чтение БРЗ */ + ACC = mmu_getcache (Aex & 7); + break; + case 0237: + /* Чтение главного регистра прерываний */ + ACC = GRP; + break; + default: + if ((Aex & 0340) == 0140) { + /* TODO: управление блокировкой схемы + * автоматического запуска */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + } + /* Неиспользуемые адреса */ + besm6_debug ("*** %05o%s: РЕГ %o - неправильный адрес спец.регистра", + PC, (RUU & RUU_RIGHT_INSTR) ? "п" : "л", Aex); + break; + } } /* @@ -512,278 +518,281 @@ static void cmd_002 () static void cmd_033 () { #if 0 - besm6_debug ("*** увв %04o, СМ[24:1]=%08o", - Aex & 04177, (uint32) ACC & BITS(24)); + besm6_debug ("*** увв %04o, СМ[24:1]=%08o", + Aex & 04177, (uint32) ACC & BITS(24)); #endif - switch (Aex & 04177) { - case 0: - /* Точно неизвестно, что это такое, но драйвер МД - * иногда выдает команду "увв 0". */ - break; - case 1 ... 2: - /* Управление обменом с магнитными барабанами */ - drum (Aex - 1, (uint32) ACC); - break; - case 3 ... 4: - /* Передача управляющего слова для обмена - * с магнитными дисками */ - disk_io (Aex - 3, (uint32) ACC); - break; - case 5 ... 7: - /* TODO: управление обменом с магнитными лентами */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 010 ... 011: - /* управление устройствами ввода с перфоленты */ - fs_control (Aex - 010, (uint32) (ACC & 07)); - break; - case 012 ... 013: - /* TODO: управление устройствами ввода с перфоленты по запаянной программе */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 014 ... 015: - /* Управление АЦПУ */ - printer_control (Aex - 014, (uint32) (ACC & 017)); - break; - case 023 ... 024: - /* Управление обменом с магнитными дисками */ - disk_ctl (Aex - 023, (uint32) ACC); - break; - case 030: - /* Гашение ПРП */ -/* besm6_debug(">>> гашение ПРП");*/ - PRP &= ACC | PRP_WIRED_BITS; - break; - case 031: - /* Имитация сигналов прерывания ГРП */ - /*besm6_debug ("*** %05o%s: имитация прерываний ГРП %016llo", - PC, (RUU & RUU_RIGHT_INSTR) ? "п" : "л", ACC << 24);*/ - GRP |= (ACC & BITS(24)) << 24; - break; - case 032 ... 033: - /* TODO: имитация сигналов из КМБ в КВУ */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 034: - /* Запись в МПРП */ -/* besm6_debug(">>> запись в МПРП");*/ - MPRP = ACC & 077777777; - break; - case 035: - /* TODO: управление режимом имитации обмена - * с МБ и МЛ, имитация обмена */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 040 ... 057: - /* Управление молоточками АЦПУ */ - printer_hammer (Aex >= 050, Aex & 7, (uint32) (ACC & BITS(16))); - break; - case 0100 ... 0137: - /* Управление лентопротяжными механизмами - * и гашение разрядов регистров признаков - * окончания подвода зоны. Игнорируем. */ - break; - case 0140: - /* Запись в регистр телеграфных каналов */ - tty_send ((uint32) ACC & BITS(24)); - break; - case 0141: - /* TODO: управление разметкой магнитной ленты */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 0142: - /* TODO: имитация сигналов прерывания ПРП */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 0147: - /* Запись в регистр управления электропитанием, */ - /* не оказывает видимого эффекта на выполнение */ - break; - case 0150 ... 0151: - /* TODO: управление вводом с перфокарт */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 0153: - /* гашение аппаратуры сопряжения с терминалами */ -/* besm6_debug(">>> гашение АС: %08o", (uint32) ACC & BITS(24));*/ - break; - case 0154 ... 0155: - /* TODO: управление выводом на перфокарты */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 0160 ... 0167: - /* TODO: управление электромагнитами пробивки перфокарт */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 0170 ... 0171: - /* TODO: пробивка строки на перфоленте */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 0174 ... 0175: - /* Выдача кода в пульт оператора */ - consul_print (Aex & 1, (uint32) ACC & BITS(8)); - break; - case 0177: - /* управление табло ГПВЦ СО АН СССР */ -/* besm6_debug(">>> ТАБЛО: %08o", (uint32) ACC & BITS(24));*/ - break; - case 04001 ... 04002: - /* TODO: считывание слога в режиме имитации обмена */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 04003 ... 04004: - /* Запрос статуса контроллера магнитных дисков */ - ACC = disk_state (Aex - 04003); - break; - case 04006: - /* TODO: считывание строки с устройства ввода - * с перфоленты в запаянной программе */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 04007: - /* TODO: опрос синхроимпульса ненулевой строки - * в запаянной программе ввода с перфоленты */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 04014 ... 04015: - /* считывание строки с устройства ввода с перфоленты */ - ACC = fs_read (Aex - 04014); - break; - case 04016 ... 04017: - /* TODO: считывание строки с устройства - * ввода с перфоленты */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 04020 ... 04023: - /* TODO: считывание слога в режиме имитации - * внешнего обмена */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 04030: - /* Чтение старшей половины ПРП */ - ACC = PRP & 077770000; - break; - case 04031: - /* Опрос сигналов готовности (АЦПУ и пр.) */ -/* besm6_debug("Reading READY");*/ - ACC = READY; - break; - case 04034: - /* Чтение младшей половины ПРП */ - ACC = (PRP & 07777) | 0377; - break; - case 04035: - /* Опрос триггера ОШМi - наличие ошибок при внешнем обмене. */ - ACC = drum_errors() | disk_errors(); - break; - case 04100: - /* Опрос телеграфных каналов связи */ - ACC = tty_query (); - break; - case 04102: - /* Опрос сигналов готовности перфокарт и перфолент */ -/* besm6_debug("Reading punchcard/punchtape READY @%05o", PC);*/ - ACC = READY2; - break; - case 04103 ... 04106: - /* Опрос состояния лентопротяжных механизмов. - * Все устройства не готовы. */ - ACC = BITS(24); - break; - case 04107: - /* TODO: опрос схемы контроля записи на МЛ */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 04115: - /* Неизвестное обращение. ДИСПАК выдаёт эту команду - * группами по 8 штук каждые несколько секунд. */ - ACC = 0; - break; - case 04140 ... 04157: - /* TODO: считывание строки перфокарты */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 04160 ... 04167: - /* TODO: контрольное считывание строки перфокарты */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 04170 ... 04173: - /* TODO: считывание контрольного кода - * строки перфоленты */ - longjmp (cpu_halt, STOP_UNIMPLEMENTED); - break; - case 04174 ... 04175: - /* Считывание кода с пульта оператора */ - ACC = consul_read (Aex & 1); - break; - case 04177: - /* чтение табло ГПВЦ СО АН СССР */ - ACC = 0; - break; - default: - /* Неиспользуемые адреса */ -/* if (sim_deb && cpu_dev.dctrl)*/ - besm6_debug ("*** %05o%s: УВВ %o - неправильный адрес ввода-вывода", - PC, (RUU & RUU_RIGHT_INSTR) ? "п" : "л", Aex); - ACC = 0; - break; - } + switch (Aex & 04177) { + case 0: + /* Точно неизвестно, что это такое, но драйвер МД + * иногда выдает команду "увв 0". */ + break; + case 1: case 2: + /* Управление обменом с магнитными барабанами */ + drum (Aex - 1, (uint32) ACC); + break; + case 3: case 4: + /* Передача управляющего слова для обмена + * с магнитными дисками */ + disk_io (Aex - 3, (uint32) ACC); + break; + case 5: case 6: case 7: + /* TODO: управление обменом с магнитными лентами */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + break; + case 010: case 011: + /* управление устройствами ввода с перфоленты */ + fs_control (Aex - 010, (uint32) (ACC & 07)); + break; + case 012: case 013: + /* TODO: управление устройствами ввода с перфоленты по запаянной программе */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + break; + case 014: case 015: + /* Управление АЦПУ */ + printer_control (Aex - 014, (uint32) (ACC & 017)); + break; + case 023: case 024: + /* Управление обменом с магнитными дисками */ + disk_ctl (Aex - 023, (uint32) ACC); + break; + case 030: + /* Гашение ПРП */ +/* besm6_debug(">>> гашение ПРП");*/ + PRP &= ACC | PRP_WIRED_BITS; + break; + case 031: + /* Имитация сигналов прерывания ГРП */ + /*besm6_debug ("*** %05o%s: имитация прерываний ГРП %016llo", + PC, (RUU & RUU_RIGHT_INSTR) ? "п" : "л", ACC << 24);*/ + GRP |= (ACC & BITS(24)) << 24; + break; + case 032: case 033: + /* TODO: имитация сигналов из КМБ в КВУ */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + break; + case 034: + /* Запись в МПРП */ +/* besm6_debug(">>> запись в МПРП");*/ + MPRP = ACC & 077777777; + break; + case 035: + /* TODO: управление режимом имитации обмена + * с МБ и МЛ, имитация обмена */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + break; + case 040: case 041: case 042: case 043: + case 044: case 045: case 046: case 047: + case 050: case 051: case 052: case 053: + case 054: case 055: case 056: case 057: + /* Управление молоточками АЦПУ */ + printer_hammer (Aex >= 050, Aex & 7, (uint32) (ACC & BITS(16))); + break; + case 0140: + /* Запись в регистр телеграфных каналов */ + tty_send ((uint32) ACC & BITS(24)); + break; + case 0141: + /* TODO: управление разметкой магнитной ленты */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + break; + case 0142: + /* TODO: имитация сигналов прерывания ПРП */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + break; + case 0147: + /* Запись в регистр управления электропитанием, */ + /* не оказывает видимого эффекта на выполнение */ + break; + case 0150: case 0151: + /* TODO: управление вводом с перфокарт */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + break; + case 0153: + /* гашение аппаратуры сопряжения с терминалами */ +/* besm6_debug(">>> гашение АС: %08o", (uint32) ACC & BITS(24));*/ + break; + case 0154: case 0155: + /* TODO: управление выводом на перфокарты */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + break; + case 0160: case 0167: + /* TODO: управление электромагнитами пробивки перфокарт */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + break; + case 0170: case 0171: + /* TODO: пробивка строки на перфоленте */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + break; + case 0174: case 0175: + /* Выдача кода в пульт оператора */ + consul_print (Aex & 1, (uint32) ACC & BITS(8)); + break; + case 0177: + /* управление табло ГПВЦ СО АН СССР */ +/* besm6_debug(">>> ТАБЛО: %08o", (uint32) ACC & BITS(24));*/ + break; + case 04001: case 04002: + /* TODO: считывание слога в режиме имитации обмена */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + break; + case 04003: case 04004: + /* Запрос статуса контроллера магнитных дисков */ + ACC = disk_state (Aex - 04003); + break; + case 04006: + /* TODO: считывание строки с устройства ввода + * с перфоленты в запаянной программе */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + break; + case 04007: + /* TODO: опрос синхроимпульса ненулевой строки + * в запаянной программе ввода с перфоленты */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + break; + case 04014: case 04015: + /* считывание строки с устройства ввода с перфоленты */ + ACC = fs_read (Aex - 04014); + break; + case 04016: case 04017: + /* TODO: считывание строки с устройства + * ввода с перфоленты */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + break; + case 04020: case 04021: case 04022: case 04023: + /* TODO: считывание слога в режиме имитации + * внешнего обмена */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + break; + case 04030: + /* Чтение старшей половины ПРП */ + ACC = PRP & 077770000; + break; + case 04031: + /* Опрос сигналов готовности (АЦПУ и пр.) */ +/* besm6_debug("Reading READY");*/ + ACC = READY; + break; + case 04034: + /* Чтение младшей половины ПРП */ + ACC = (PRP & 07777) | 0377; + break; + case 04035: + /* Опрос триггера ОШМi - наличие ошибок при внешнем обмене. */ + ACC = drum_errors() | disk_errors(); + break; + case 04100: + /* Опрос телеграфных каналов связи */ + ACC = tty_query (); + break; + case 04102: + /* Опрос сигналов готовности перфокарт и перфолент */ +/* besm6_debug("Reading punchcard/punchtape READY @%05o", PC);*/ + ACC = READY2; + break; + case 04103: case 04104: case 04105: case 04106: + /* Опрос состояния лентопротяжных механизмов. + * Все устройства не готовы. */ + ACC = BITS(24); + break; + case 04107: + /* TODO: опрос схемы контроля записи на МЛ */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + break; + case 04115: + /* Неизвестное обращение. ДИСПАК выдаёт эту команду + * группами по 8 штук каждые несколько секунд. */ + ACC = 0; + break; + case 04170: case 04171: case 04172: case 04173: + /* TODO: считывание контрольного кода + * строки перфоленты */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + break; + case 04174: case 04175: + /* Считывание кода с пульта оператора */ + ACC = consul_read (Aex & 1); + break; + case 04177: + /* чтение табло ГПВЦ СО АН СССР */ + ACC = 0; + break; + default: { + unsigned val = Aex & 04177; + if (0100 <= val && val <= 0137) { + /* Управление лентопротяжными механизмами + * и гашение разрядов регистров признаков + * окончания подвода зоны. Игнорируем. */ + } else if (04140 <= val && val <= 04157) { + /* TODO: считывание строки перфокарты */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + } else if (04160 <= val && val <= 04167) { + /* TODO: контрольное считывание строки перфокарты */ + longjmp (cpu_halt, STOP_UNIMPLEMENTED); + } else { + /* Неиспользуемые адреса */ +/* if (sim_deb && cpu_dev.dctrl)*/ + besm6_debug ("*** %05o%s: УВВ %o - неправильный адрес ввода-вывода", + PC, (RUU & RUU_RIGHT_INSTR) ? "п" : "л", Aex); + ACC = 0; + } + } break; + } } void check_initial_setup () { - const int MGRP_COPY = 01455; /* OS version specific? */ - const int TAKEN = 0442; /* fixed? */ - const int YEAR = 0221; /* fixed */ + const int MGRP_COPY = 01455; /* OS version specific? */ + const int TAKEN = 0442; /* fixed? */ + const int YEAR = 0221; /* fixed */ - /* 47 р. яч. ЗАНЯТА - разр. приказы вообще */ - const t_value SETUP_REQS_ENABLED = 1LL << 46; + /* 47 р. яч. ЗАНЯТА - разр. приказы вообще */ + const t_value SETUP_REQS_ENABLED = 1LL << 46; - /* 7 р. яч. ЗАНЯТА - разр любые приказы */ - const t_value ALL_REQS_ENABLED = 1 << 6; + /* 7 р. яч. ЗАНЯТА - разр любые приказы */ + const t_value ALL_REQS_ENABLED = 1 << 6; - if ((memory[TAKEN] & SETUP_REQS_ENABLED) == 0 || - (memory[TAKEN] & ALL_REQS_ENABLED) != 0 || - (MGRP & GRP_PANEL_REQ) == 0) { - /* Слишком рано, или уже не надо, или невовремя */ - return; - } + if ((memory[TAKEN] & SETUP_REQS_ENABLED) == 0 || + (memory[TAKEN] & ALL_REQS_ENABLED) != 0 || + (MGRP & GRP_PANEL_REQ) == 0) { + /* Слишком рано, или уже не надо, или невовремя */ + return; + } - /* Выдаем приказы оператора СМЕ и ВРЕ, - * а дату корректируем непосредственно в памяти. - */ - /* Номер смены в 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; - GRP |= GRP_PANEL_REQ; - } else { - /* Яч. ГОД обновляем самостоятельно */ - time_t t; - t_value date; - time(&t); - struct tm * d; - d = localtime(&t); - ++d->tm_mon; - date = (t_value) (d->tm_mday / 10) << 33 | - (t_value) (d->tm_mday % 10) << 29 | - (d->tm_mon / 10) << 28 | - (d->tm_mon % 10) << 24 | - (d->tm_year % 10) << 20 | - ((d->tm_year / 10) % 10) << 16 | - (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 | - (d->tm_hour % 10) << 8 | - (d->tm_min / 10) << 4 | - (d->tm_min % 10); - GRP |= GRP_PANEL_REQ; - } + /* Выдаем приказы оператора СМЕ и ВРЕ, + * а дату корректируем непосредственно в памяти. + */ + /* Номер смены в 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; + GRP |= GRP_PANEL_REQ; + } else { + /* Яч. ГОД обновляем самостоятельно */ + time_t t; + t_value date; + time(&t); + struct tm * d; + d = localtime(&t); + ++d->tm_mon; + date = (t_value) (d->tm_mday / 10) << 33 | + (t_value) (d->tm_mday % 10) << 29 | + (d->tm_mon / 10) << 28 | + (d->tm_mon % 10) << 24 | + (d->tm_year % 10) << 20 | + ((d->tm_year / 10) % 10) << 16 | + (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 | + (d->tm_hour % 10) << 8 | + (d->tm_min / 10) << 4 | + (d->tm_min % 10); + GRP |= GRP_PANEL_REQ; + } } /* @@ -793,680 +802,685 @@ void check_initial_setup () */ void cpu_one_inst () { - int reg, opcode, addr, nextpc, next_mod; + int reg, opcode, addr, nextpc, next_mod; - corr_stack = 0; - t_value word = mmu_fetch (PC); - if (RUU & RUU_RIGHT_INSTR) - RK = word; /* get right instruction */ - else - RK = word >> 24; /* get left instruction */ + corr_stack = 0; + t_value word = mmu_fetch (PC); + if (RUU & RUU_RIGHT_INSTR) + RK = word; /* get right instruction */ + else + RK = word >> 24; /* get left instruction */ - RK &= BITS(24); + RK &= BITS(24); - reg = RK >> 20; - if (RK & BBIT(20)) { - addr = RK & BITS(15); - opcode = (RK >> 12) & 0370; - } else { - addr = RK & BITS(12); - if (RK & BBIT(19)) - addr |= 070000; - opcode = (RK >> 12) & 077; - } + reg = RK >> 20; + if (RK & BBIT(20)) { + addr = RK & BITS(15); + opcode = (RK >> 12) & 0370; + } else { + addr = RK & BITS(12); + if (RK & BBIT(19)) + addr |= 070000; + opcode = (RK >> 12) & 077; + } - if (sim_deb && cpu_dev.dctrl) { - fprintf (sim_deb, "*** %05o%s: ", PC, - (RUU & RUU_RIGHT_INSTR) ? "п" : "л"); - besm6_fprint_cmd (sim_deb, RK); - fprintf (sim_deb, "\tСМ="); - fprint_sym (sim_deb, 0, &ACC, 0, 0); - fprintf (sim_deb, "\tРАУ=%02o", RAU); - if (reg) - fprintf (sim_deb, "\tМ[%o]=%05o", reg, M[reg]); - fprintf (sim_deb, "\n"); - } - nextpc = ADDR(PC + 1); - if (RUU & RUU_RIGHT_INSTR) { - PC += 1; /* increment PC */ - RUU &= ~RUU_RIGHT_INSTR; - } else { - mmu_prefetch(nextpc | (IS_SUPERVISOR(RUU) ? BBIT(16) : 0), 0); - RUU |= RUU_RIGHT_INSTR; - } + if (sim_deb && cpu_dev.dctrl) { + fprintf (sim_deb, "*** %05o%s: ", PC, + (RUU & RUU_RIGHT_INSTR) ? "п" : "л"); + besm6_fprint_cmd (sim_deb, RK); + fprintf (sim_deb, "\tСМ="); + fprint_sym (sim_deb, 0, &ACC, 0, 0); + fprintf (sim_deb, "\tРАУ=%02o", RAU); + if (reg) + fprintf (sim_deb, "\tМ[%o]=%05o", reg, M[reg]); + fprintf (sim_deb, "\n"); + } + nextpc = ADDR(PC + 1); + if (RUU & RUU_RIGHT_INSTR) { + PC += 1; /* increment PC */ + RUU &= ~RUU_RIGHT_INSTR; + } else { + mmu_prefetch(nextpc | (IS_SUPERVISOR(RUU) ? BBIT(16) : 0), 0); + RUU |= RUU_RIGHT_INSTR; + } - if (RUU & RUU_MOD_RK) { - addr = ADDR (addr + M[MOD]); - } - next_mod = 0; - delay = 0; + if (RUU & RUU_MOD_RK) { + addr = ADDR (addr + M[MOD]); + } + next_mod = 0; + delay = 0; - switch (opcode) { - case 000: /* зп, atx */ - Aex = ADDR (addr + M[reg]); - mmu_store (Aex, ACC); - if (! addr && reg == 017) - M[017] = ADDR (M[017] + 1); - delay = MEAN_TIME (3, 3); - break; - case 001: /* зпм, stx */ - Aex = ADDR (addr + M[reg]); - mmu_store (Aex, ACC); - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - ACC = mmu_load (M[017]); - RAU = SET_LOGICAL (RAU); - delay = MEAN_TIME (6, 6); - break; - case 002: /* рег, mod */ - Aex = ADDR (addr + M[reg]); - if (! IS_SUPERVISOR (RUU)) - longjmp (cpu_halt, STOP_BADCMD); - cmd_002 (); - /* Режим АУ - логический, если операция была "чтение" */ - if (Aex & 0200) - RAU = SET_LOGICAL (RAU); - delay = MEAN_TIME (3, 3); - break; - case 003: /* счм, xts */ - mmu_store (M[017], ACC); - M[017] = ADDR (M[017] + 1); - corr_stack = -1; - Aex = ADDR (addr + M[reg]); - ACC = mmu_load (Aex); - RAU = SET_LOGICAL (RAU); - delay = MEAN_TIME (6, 6); - break; - case 004: /* сл, a+x */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - besm6_add (mmu_load (Aex), 0, 0); - RAU = SET_ADDITIVE (RAU); - delay = MEAN_TIME (3, 11); - break; - case 005: /* вч, a-x */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - besm6_add (mmu_load (Aex), 0, 1); - RAU = SET_ADDITIVE (RAU); - delay = MEAN_TIME (3, 11); - break; - case 006: /* вчоб, x-a */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - besm6_add (mmu_load (Aex), 1, 0); - RAU = SET_ADDITIVE (RAU); - delay = MEAN_TIME (3, 11); - break; - case 007: /* вчаб, amx */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - besm6_add (mmu_load (Aex), 1, 1); - RAU = SET_ADDITIVE (RAU); - delay = MEAN_TIME (3, 11); - break; - case 010: /* сч, xta */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - ACC = mmu_load (Aex); - RAU = SET_LOGICAL (RAU); - delay = MEAN_TIME (3, 3); - break; - case 011: /* и, aax */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - ACC &= mmu_load (Aex); - RMR = 0; - RAU = SET_LOGICAL (RAU); - delay = MEAN_TIME (3, 4); - break; - case 012: /* нтж, aex */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - RMR = ACC; - ACC ^= mmu_load (Aex); - RAU = SET_LOGICAL (RAU); - delay = MEAN_TIME (3, 3); - break; - case 013: /* слц, arx */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - ACC += mmu_load (Aex); - if (ACC & BIT49) - ACC = (ACC + 1) & BITS48; - RMR = 0; - RAU = SET_MULTIPLICATIVE (RAU); - delay = MEAN_TIME (3, 6); - break; - case 014: /* знак, avx */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - besm6_change_sign (mmu_load (Aex) >> 40 & 1); - RAU = SET_ADDITIVE (RAU); - delay = MEAN_TIME (3, 5); - break; - case 015: /* или, aox */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - ACC |= mmu_load (Aex); - RMR = 0; - RAU = SET_LOGICAL (RAU); - delay = MEAN_TIME (3, 4); - break; - case 016: /* дел, a/x */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - besm6_divide (mmu_load (Aex)); - RAU = SET_MULTIPLICATIVE (RAU); - delay = MEAN_TIME (3, 50); - break; - case 017: /* умн, a*x */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - besm6_multiply (mmu_load (Aex)); - RAU = SET_MULTIPLICATIVE (RAU); - delay = MEAN_TIME (3, 18); - break; - case 020: /* сбр, apx */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - ACC = besm6_pack (ACC, mmu_load (Aex)); - RMR = 0; - RAU = SET_LOGICAL (RAU); - delay = MEAN_TIME (3, 53); - break; - case 021: /* рзб, aux */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - ACC = besm6_unpack (ACC, mmu_load (Aex)); - RMR = 0; - RAU = SET_LOGICAL (RAU); - delay = MEAN_TIME (3, 53); - break; - case 022: /* чед, acx */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - ACC = besm6_count_ones (ACC) + mmu_load (Aex); - if (ACC & BIT49) - ACC = (ACC + 1) & BITS48; - RAU = SET_LOGICAL (RAU); - delay = MEAN_TIME (3, 56); - break; - case 023: /* нед, anx */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - if (ACC) { - int n = besm6_highest_bit (ACC); + switch (opcode) { + case 000: /* зп, atx */ + Aex = ADDR (addr + M[reg]); + mmu_store (Aex, ACC); + if (! addr && reg == 017) + M[017] = ADDR (M[017] + 1); + delay = MEAN_TIME (3, 3); + break; + case 001: /* зпм, stx */ + Aex = ADDR (addr + M[reg]); + mmu_store (Aex, ACC); + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + ACC = mmu_load (M[017]); + RAU = SET_LOGICAL (RAU); + delay = MEAN_TIME (6, 6); + break; + case 002: /* рег, mod */ + Aex = ADDR (addr + M[reg]); + if (! IS_SUPERVISOR (RUU)) + longjmp (cpu_halt, STOP_BADCMD); + cmd_002 (); + /* Режим АУ - логический, если операция была "чтение" */ + if (Aex & 0200) + RAU = SET_LOGICAL (RAU); + delay = MEAN_TIME (3, 3); + break; + case 003: /* счм, xts */ + mmu_store (M[017], ACC); + M[017] = ADDR (M[017] + 1); + corr_stack = -1; + Aex = ADDR (addr + M[reg]); + ACC = mmu_load (Aex); + RAU = SET_LOGICAL (RAU); + delay = MEAN_TIME (6, 6); + break; + case 004: /* сл, a+x */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + besm6_add (mmu_load (Aex), 0, 0); + RAU = SET_ADDITIVE (RAU); + delay = MEAN_TIME (3, 11); + break; + case 005: /* вч, a-x */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + besm6_add (mmu_load (Aex), 0, 1); + RAU = SET_ADDITIVE (RAU); + delay = MEAN_TIME (3, 11); + break; + case 006: /* вчоб, x-a */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + besm6_add (mmu_load (Aex), 1, 0); + RAU = SET_ADDITIVE (RAU); + delay = MEAN_TIME (3, 11); + break; + case 007: /* вчаб, amx */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + besm6_add (mmu_load (Aex), 1, 1); + RAU = SET_ADDITIVE (RAU); + delay = MEAN_TIME (3, 11); + break; + case 010: /* сч, xta */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + ACC = mmu_load (Aex); + RAU = SET_LOGICAL (RAU); + delay = MEAN_TIME (3, 3); + break; + case 011: /* и, aax */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + ACC &= mmu_load (Aex); + RMR = 0; + RAU = SET_LOGICAL (RAU); + delay = MEAN_TIME (3, 4); + break; + case 012: /* нтж, aex */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + RMR = ACC; + ACC ^= mmu_load (Aex); + RAU = SET_LOGICAL (RAU); + delay = MEAN_TIME (3, 3); + break; + case 013: /* слц, arx */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + ACC += mmu_load (Aex); + if (ACC & BIT49) + ACC = (ACC + 1) & BITS48; + RMR = 0; + RAU = SET_MULTIPLICATIVE (RAU); + delay = MEAN_TIME (3, 6); + break; + case 014: /* знак, avx */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + besm6_change_sign (mmu_load (Aex) >> 40 & 1); + RAU = SET_ADDITIVE (RAU); + delay = MEAN_TIME (3, 5); + break; + case 015: /* или, aox */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + ACC |= mmu_load (Aex); + RMR = 0; + RAU = SET_LOGICAL (RAU); + delay = MEAN_TIME (3, 4); + break; + case 016: /* дел, a/x */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + besm6_divide (mmu_load (Aex)); + RAU = SET_MULTIPLICATIVE (RAU); + delay = MEAN_TIME (3, 50); + break; + case 017: /* умн, a*x */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + besm6_multiply (mmu_load (Aex)); + RAU = SET_MULTIPLICATIVE (RAU); + delay = MEAN_TIME (3, 18); + break; + case 020: /* сбр, apx */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + ACC = besm6_pack (ACC, mmu_load (Aex)); + RMR = 0; + RAU = SET_LOGICAL (RAU); + delay = MEAN_TIME (3, 53); + break; + case 021: /* рзб, aux */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + ACC = besm6_unpack (ACC, mmu_load (Aex)); + RMR = 0; + RAU = SET_LOGICAL (RAU); + delay = MEAN_TIME (3, 53); + break; + case 022: /* чед, acx */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + ACC = besm6_count_ones (ACC) + mmu_load (Aex); + if (ACC & BIT49) + ACC = (ACC + 1) & BITS48; + RAU = SET_LOGICAL (RAU); + delay = MEAN_TIME (3, 56); + break; + case 023: /* нед, anx */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + if (ACC) { + int n = besm6_highest_bit (ACC); - /* "Остаток" сумматора, исключая бит, - * номер которого определен, помещается в РМР, - * начиная со старшего бита РМР. */ - besm6_shift (48 - n); + /* "Остаток" сумматора, исключая бит, + * номер которого определен, помещается в РМР, + * начиная со старшего бита РМР. */ + besm6_shift (48 - n); - /* Циклическое сложение номера со словом по Аисп. */ - ACC = n + mmu_load (Aex); - if (ACC & BIT49) - ACC = (ACC + 1) & BITS48; - } else { - RMR = 0; - ACC = mmu_load (Aex); - } - RAU = SET_LOGICAL (RAU); - delay = MEAN_TIME (3, 32); - break; - case 024: /* слп, e+x */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - besm6_add_exponent ((mmu_load (Aex) >> 41) - 64); - RAU = SET_MULTIPLICATIVE (RAU); - delay = MEAN_TIME (3, 5); - break; - case 025: /* вчп, e-x */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - besm6_add_exponent (64 - (mmu_load (Aex) >> 41)); - RAU = SET_MULTIPLICATIVE (RAU); - delay = MEAN_TIME (3, 5); - break; - case 026: { /* сд, asx */ - int n; - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - n = (mmu_load (Aex) >> 41) - 64; - besm6_shift (n); - RAU = SET_LOGICAL (RAU); - delay = MEAN_TIME (3, 4 + abs (n)); - break; - } - case 027: /* рж, xtr */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - RAU = (mmu_load (Aex) >> 41) & 077; - delay = MEAN_TIME (3, 3); - break; - case 030: /* счрж, rte */ - Aex = ADDR (addr + M[reg]); - ACC = (t_value) (RAU & Aex & 0177) << 41; - RAU = SET_LOGICAL (RAU); - delay = MEAN_TIME (3, 3); - break; - case 031: /* счмр, yta */ - Aex = ADDR (addr + M[reg]); - if (IS_LOGICAL (RAU)) { - ACC = RMR; - } else { - t_value x = RMR; - ACC = (ACC & ~BITS41) | (RMR & BITS40); - besm6_add_exponent ((Aex & 0177) - 64); - RMR = x; - } - delay = MEAN_TIME (3, 5); - break; - case 032: /* э32, ext */ - /* Fall through... */ - case 033: /* увв, ext */ - Aex = ADDR (addr + M[reg]); - if (! IS_SUPERVISOR (RUU)) - longjmp (cpu_halt, STOP_BADCMD); - cmd_033 (); - /* Режим АУ - логический, если операция была "чтение" */ - if (Aex & 04000) - RAU = SET_LOGICAL (RAU); - delay = MEAN_TIME (3, 8); - break; - case 034: /* слпа, e+n */ - Aex = ADDR (addr + M[reg]); - besm6_add_exponent ((Aex & 0177) - 64); - RAU = SET_MULTIPLICATIVE (RAU); - delay = MEAN_TIME (3, 5); - break; - case 035: /* вчпа, e-n */ - Aex = ADDR (addr + M[reg]); - besm6_add_exponent (64 - (Aex & 0177)); - RAU = SET_MULTIPLICATIVE (RAU); - delay = MEAN_TIME (3, 5); - break; - case 036: { /* сда, asn */ - int n; - Aex = ADDR (addr + M[reg]); - n = (Aex & 0177) - 64; - besm6_shift (n); - RAU = SET_LOGICAL (RAU); - delay = MEAN_TIME (3, 4 + abs (n)); - break; - } - case 037: /* ржа, ntr */ - Aex = ADDR (addr + M[reg]); - RAU = Aex & 077; - delay = MEAN_TIME (3, 3); - break; - case 040: /* уи, ati */ - Aex = ADDR (addr + M[reg]); - if (IS_SUPERVISOR (RUU)) { - int reg = Aex & 037; - M[reg] = ADDR (ACC); - /* breakpoint/watchpoint regs will match physical - * or virtual addresses depending on the current - * mapping mode. - */ - if ((M[PSW] & PSW_MMAP_DISABLE) && - (reg == IBP || reg == DWP)) - M[reg] |= BBIT(16); + /* Циклическое сложение номера со словом по Аисп. */ + ACC = n + mmu_load (Aex); + if (ACC & BIT49) + ACC = (ACC + 1) & BITS48; + } else { + RMR = 0; + ACC = mmu_load (Aex); + } + RAU = SET_LOGICAL (RAU); + delay = MEAN_TIME (3, 32); + break; + case 024: /* слп, e+x */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + besm6_add_exponent ((mmu_load (Aex) >> 41) - 64); + RAU = SET_MULTIPLICATIVE (RAU); + delay = MEAN_TIME (3, 5); + break; + case 025: /* вчп, e-x */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + besm6_add_exponent (64 - (mmu_load (Aex) >> 41)); + RAU = SET_MULTIPLICATIVE (RAU); + delay = MEAN_TIME (3, 5); + break; + case 026: { /* сд, asx */ + int n; + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + n = (mmu_load (Aex) >> 41) - 64; + besm6_shift (n); + RAU = SET_LOGICAL (RAU); + delay = MEAN_TIME (3, 4 + abs (n)); + break; + } + case 027: /* рж, xtr */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + RAU = (mmu_load (Aex) >> 41) & 077; + delay = MEAN_TIME (3, 3); + break; + case 030: /* счрж, rte */ + Aex = ADDR (addr + M[reg]); + ACC = (t_value) (RAU & Aex & 0177) << 41; + RAU = SET_LOGICAL (RAU); + delay = MEAN_TIME (3, 3); + break; + case 031: /* счмр, yta */ + Aex = ADDR (addr + M[reg]); + if (IS_LOGICAL (RAU)) { + ACC = RMR; + } else { + t_value x = RMR; + ACC = (ACC & ~BITS41) | (RMR & BITS40); + besm6_add_exponent ((Aex & 0177) - 64); + RMR = x; + } + delay = MEAN_TIME (3, 5); + break; + case 032: /* э32, ext */ + /* Fall through... */ + case 033: /* увв, ext */ + Aex = ADDR (addr + M[reg]); + if (! IS_SUPERVISOR (RUU)) + longjmp (cpu_halt, STOP_BADCMD); + cmd_033 (); + /* Режим АУ - логический, если операция была "чтение" */ + if (Aex & 04000) + RAU = SET_LOGICAL (RAU); + delay = MEAN_TIME (3, 8); + break; + case 034: /* слпа, e+n */ + Aex = ADDR (addr + M[reg]); + besm6_add_exponent ((Aex & 0177) - 64); + RAU = SET_MULTIPLICATIVE (RAU); + delay = MEAN_TIME (3, 5); + break; + case 035: /* вчпа, e-n */ + Aex = ADDR (addr + M[reg]); + besm6_add_exponent (64 - (Aex & 0177)); + RAU = SET_MULTIPLICATIVE (RAU); + delay = MEAN_TIME (3, 5); + break; + case 036: { /* сда, asn */ + int n; + Aex = ADDR (addr + M[reg]); + n = (Aex & 0177) - 64; + besm6_shift (n); + RAU = SET_LOGICAL (RAU); + delay = MEAN_TIME (3, 4 + abs (n)); + break; + } + case 037: /* ржа, ntr */ + Aex = ADDR (addr + M[reg]); + RAU = Aex & 077; + delay = MEAN_TIME (3, 3); + break; + case 040: /* уи, ati */ + Aex = ADDR (addr + M[reg]); + if (IS_SUPERVISOR (RUU)) { + int reg = Aex & 037; + M[reg] = ADDR (ACC); + /* breakpoint/watchpoint regs will match physical + * or virtual addresses depending on the current + * mapping mode. + */ + if ((M[PSW] & PSW_MMAP_DISABLE) && + (reg == IBP || reg == DWP)) + M[reg] |= BBIT(16); - } else - M[Aex & 017] = ADDR (ACC); - M[0] = 0; - delay = MEAN_TIME (14, 3); - break; - case 041: { /* уим, sti */ - unsigned rg, ad; + } else + M[Aex & 017] = ADDR (ACC); + M[0] = 0; + delay = MEAN_TIME (14, 3); + break; + case 041: { /* уим, sti */ + unsigned rg, ad; - Aex = ADDR (addr + M[reg]); - rg = Aex & (IS_SUPERVISOR (RUU) ? 037 : 017); - ad = ADDR (ACC); - if (rg != 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - ACC = mmu_load (rg != 017 ? M[017] : ad); - M[rg] = ad; - if ((M[PSW] & PSW_MMAP_DISABLE) && (rg == IBP || rg == DWP)) - M[rg] |= BBIT(16); - M[0] = 0; - RAU = SET_LOGICAL (RAU); - delay = MEAN_TIME (14, 3); - break; - } - case 042: /* счи, ita */ - delay = MEAN_TIME (6, 3); -load_modifier: Aex = ADDR (addr + M[reg]); - ACC = ADDR(M[Aex & (IS_SUPERVISOR (RUU) ? 037 : 017)]); - RAU = SET_LOGICAL (RAU); - break; - case 043: /* счим, its */ - mmu_store (M[017], ACC); - M[017] = ADDR (M[017] + 1); - delay = MEAN_TIME (9, 6); - goto load_modifier; - case 044: /* уии, mtj */ - Aex = addr; - if (IS_SUPERVISOR (RUU)) { -transfer_modifier: M[Aex & 037] = M[reg]; - if ((M[PSW] & PSW_MMAP_DISABLE) && - ((Aex & 037) == IBP || (Aex & 037) == DWP)) - M[Aex & 037] |= BBIT(16); + Aex = ADDR (addr + M[reg]); + rg = Aex & (IS_SUPERVISOR (RUU) ? 037 : 017); + ad = ADDR (ACC); + if (rg != 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + ACC = mmu_load (rg != 017 ? M[017] : ad); + M[rg] = ad; + if ((M[PSW] & PSW_MMAP_DISABLE) && (rg == IBP || rg == DWP)) + M[rg] |= BBIT(16); + M[0] = 0; + RAU = SET_LOGICAL (RAU); + delay = MEAN_TIME (14, 3); + break; + } + case 042: /* счи, ita */ + delay = MEAN_TIME (6, 3); + load_modifier: Aex = ADDR (addr + M[reg]); + ACC = ADDR(M[Aex & (IS_SUPERVISOR (RUU) ? 037 : 017)]); + RAU = SET_LOGICAL (RAU); + break; + case 043: /* счим, its */ + mmu_store (M[017], ACC); + M[017] = ADDR (M[017] + 1); + delay = MEAN_TIME (9, 6); + goto load_modifier; + case 044: /* уии, mtj */ + Aex = addr; + if (IS_SUPERVISOR (RUU)) { + transfer_modifier: M[Aex & 037] = M[reg]; + if ((M[PSW] & PSW_MMAP_DISABLE) && + ((Aex & 037) == IBP || (Aex & 037) == DWP)) + M[Aex & 037] |= BBIT(16); - } else - M[Aex & 017] = M[reg]; - M[0] = 0; - delay = 6; - break; - case 045: /* сли, j+m */ - Aex = addr; - if ((Aex & 020) && IS_SUPERVISOR (RUU)) - goto transfer_modifier; - M[Aex & 017] = ADDR (M[Aex & 017] + M[reg]); - M[0] = 0; - delay = 6; - break; - case 046: /* э46, x46 */ - Aex = addr; - if (! IS_SUPERVISOR (RUU)) - longjmp (cpu_halt, STOP_BADCMD); - M[Aex & 017] = ADDR (Aex); - M[0] = 0; - delay = 6; - break; - case 047: /* э47, x47 */ - Aex = addr; - if (! IS_SUPERVISOR (RUU)) - longjmp (cpu_halt, STOP_BADCMD); - M[Aex & 017] = ADDR (M[Aex & 017] + Aex); - M[0] = 0; - delay = 6; - break; - case 050 ... 077: /* э50...э77 */ - case 0200: /* э20 */ - case 0210: /* э21 */ - stop_as_extracode: - Aex = ADDR (addr + M[reg]); - if (! sim_deb && sim_log && cpu_dev.dctrl && opcode != 075) { - /* Если включен console log и cpu debug, - * но нет console debug, то печатаем только экстракоды. - * Пропускаем э75, их обычно слишком много. */ - t_value word = mmu_load (Aex); - fprintf (sim_log, "*** %05o%s: ", PC, - (RUU & RUU_RIGHT_INSTR) ? "п" : "л"); - besm6_fprint_cmd (sim_log, RK); - fprintf (sim_log, "\tАисп=%05o (=", Aex); - fprint_sym (sim_log, 0, &word, 0, 0); - fprintf (sim_log, ") СМ="); - fprint_sym (sim_log, 0, &ACC, 0, 0); - if (reg) - fprintf (sim_log, " М[%o]=%05o", reg, M[reg]); - fprintf (sim_log, "\n"); - } - /*besm6_okno ("экстракод");*/ - /* Адрес возврата из экстракода. */ - M[ERET] = nextpc; - /* Сохранённые режимы УУ. */ - M[SPSW] = (M[PSW] & (PSW_INTR_DISABLE | PSW_MMAP_DISABLE | - PSW_PROT_DISABLE)) | IS_SUPERVISOR (RUU); - /* Текущие режимы УУ. */ - M[PSW] = PSW_INTR_DISABLE | PSW_MMAP_DISABLE | - PSW_PROT_DISABLE | /*?*/ PSW_INTR_HALT; - M[14] = Aex; - RUU = SET_SUPERVISOR (RUU, SPSW_EXTRACODE); + } else + M[Aex & 017] = M[reg]; + M[0] = 0; + delay = 6; + break; + case 045: /* сли, j+m */ + Aex = addr; + if ((Aex & 020) && IS_SUPERVISOR (RUU)) + goto transfer_modifier; + M[Aex & 017] = ADDR (M[Aex & 017] + M[reg]); + M[0] = 0; + delay = 6; + break; + case 046: /* э46, x46 */ + Aex = addr; + if (! IS_SUPERVISOR (RUU)) + longjmp (cpu_halt, STOP_BADCMD); + M[Aex & 017] = ADDR (Aex); + M[0] = 0; + delay = 6; + break; + case 047: /* э47, x47 */ + Aex = addr; + if (! IS_SUPERVISOR (RUU)) + longjmp (cpu_halt, STOP_BADCMD); + M[Aex & 017] = ADDR (M[Aex & 017] + Aex); + M[0] = 0; + delay = 6; + break; + case 050: case 051: case 052: case 053: + case 054: case 055: case 056: case 057: + case 060: case 061: case 062: case 063: + case 064: case 065: case 066: case 067: + case 070: case 071: case 072: case 073: + case 074: case 075: case 076: case 077: /* э50...э77 */ + case 0200: /* э20 */ + case 0210: /* э21 */ + stop_as_extracode: + Aex = ADDR (addr + M[reg]); + if (! sim_deb && sim_log && cpu_dev.dctrl && opcode != 075) { + /* Если включен console log и cpu debug, + * но нет console debug, то печатаем только экстракоды. + * Пропускаем э75, их обычно слишком много. */ + t_value word = mmu_load (Aex); + fprintf (sim_log, "*** %05o%s: ", PC, + (RUU & RUU_RIGHT_INSTR) ? "п" : "л"); + besm6_fprint_cmd (sim_log, RK); + fprintf (sim_log, "\tАисп=%05o (=", Aex); + fprint_sym (sim_log, 0, &word, 0, 0); + fprintf (sim_log, ") СМ="); + fprint_sym (sim_log, 0, &ACC, 0, 0); + if (reg) + fprintf (sim_log, " М[%o]=%05o", reg, M[reg]); + fprintf (sim_log, "\n"); + } + /*besm6_okno ("экстракод");*/ + /* Адрес возврата из экстракода. */ + M[ERET] = nextpc; + /* Сохранённые режимы УУ. */ + M[SPSW] = (M[PSW] & (PSW_INTR_DISABLE | PSW_MMAP_DISABLE | + PSW_PROT_DISABLE)) | IS_SUPERVISOR (RUU); + /* Текущие режимы УУ. */ + M[PSW] = PSW_INTR_DISABLE | PSW_MMAP_DISABLE | + PSW_PROT_DISABLE | /*?*/ PSW_INTR_HALT; + M[14] = Aex; + RUU = SET_SUPERVISOR (RUU, SPSW_EXTRACODE); - if (opcode <= 077) - PC = 0500 + opcode; /* э50-э77 */ - else - PC = 0540 + (opcode >> 3); /* э20, э21 */ - RUU &= ~RUU_RIGHT_INSTR; - delay = 7; - break; - case 0220: /* мода, utc */ - Aex = ADDR (addr + M[reg]); - next_mod = Aex; - delay = 4; - break; - case 0230: /* мод, wtc */ - if (! addr && reg == 017) { - M[017] = ADDR (M[017] - 1); - corr_stack = 1; - } - Aex = ADDR (addr + M[reg]); - next_mod = ADDR (mmu_load (Aex)); - delay = MEAN_TIME (13, 3); - break; - case 0240: /* уиа, vtm */ - Aex = addr; - M[reg] = addr; - M[0] = 0; - if (IS_SUPERVISOR (RUU) && reg == 0) { - M[PSW] &= ~(PSW_INTR_DISABLE | - PSW_MMAP_DISABLE | PSW_PROT_DISABLE); - M[PSW] |= addr & (PSW_INTR_DISABLE | - PSW_MMAP_DISABLE | PSW_PROT_DISABLE); - } - delay = 4; - break; - case 0250: /* слиа, utm */ - Aex = ADDR (addr + M[reg]); - M[reg] = Aex; - M[0] = 0; - if (IS_SUPERVISOR (RUU) && reg == 0) { - M[PSW] &= ~(PSW_INTR_DISABLE | - PSW_MMAP_DISABLE | PSW_PROT_DISABLE); - M[PSW] |= addr & (PSW_INTR_DISABLE | - PSW_MMAP_DISABLE | PSW_PROT_DISABLE); - } - delay = 4; - break; - case 0260: /* по, uza */ - Aex = ADDR (addr + M[reg]); - RMR = ACC; - delay = MEAN_TIME (12, 3); - if (IS_ADDITIVE (RAU)) { - if (ACC & BIT41) - break; - } else if (IS_MULTIPLICATIVE (RAU)) { - if (! (ACC & BIT48)) - break; - } else if (IS_LOGICAL (RAU)) { - if (ACC) - break; - } else - break; - PC = Aex; - RUU &= ~RUU_RIGHT_INSTR; - delay += 3; - break; - case 0270: /* пе, u1a */ - Aex = ADDR (addr + M[reg]); - RMR = ACC; - delay = MEAN_TIME (12, 3); - if (IS_ADDITIVE (RAU)) { - if (! (ACC & BIT41)) - break; - } else if (IS_MULTIPLICATIVE (RAU)) { - if (ACC & BIT48) - break; - } else if (IS_LOGICAL (RAU)) { - if (! ACC) - break; - } else - /* fall thru, i.e. branch */; - PC = Aex; - RUU &= ~RUU_RIGHT_INSTR; - delay += 3; - break; - case 0300: /* пб, uj */ - Aex = ADDR (addr + M[reg]); - PC = Aex; - RUU &= ~RUU_RIGHT_INSTR; - delay = 7; - break; - case 0310: /* пв, vjm */ - Aex = addr; - M[reg] = nextpc; - M[0] = 0; - PC = addr; - RUU &= ~RUU_RIGHT_INSTR; - delay = 7; - break; - case 0320: /* выпр, iret */ - Aex = addr; - if (! IS_SUPERVISOR (RUU)) { - longjmp (cpu_halt, STOP_BADCMD); - } - M[PSW] = (M[PSW] & PSW_WRITE_WATCH) | - (M[SPSW] & (SPSW_INTR_DISABLE | - SPSW_MMAP_DISABLE | SPSW_PROT_DISABLE)); - PC = M[(reg & 3) | 030]; - RUU &= ~RUU_RIGHT_INSTR; - if (M[SPSW] & SPSW_RIGHT_INSTR) - RUU |= RUU_RIGHT_INSTR; - else - RUU &= ~RUU_RIGHT_INSTR; - RUU = SET_SUPERVISOR (RUU, - M[SPSW] & (SPSW_EXTRACODE | SPSW_INTERRUPT)); - if (M[SPSW] & SPSW_MOD_RK) - next_mod = M[MOD]; - /*besm6_okno ("Выход из прерывания");*/ - delay = 7; - break; - case 0330: /* стоп, stop */ - Aex = ADDR (addr + M[reg]); - delay = 7; - if (! IS_SUPERVISOR(RUU)) { - if (M[PSW] & PSW_CHECK_HALT) - break; - else { - opcode = 063; - goto stop_as_extracode; - } - } - mmu_print_brz (); - longjmp (cpu_halt, STOP_STOP); - break; - case 0340: /* пио, vzm */ -branch_zero: Aex = addr; - delay = 4; - if (! M[reg]) { - PC = addr; - RUU &= ~RUU_RIGHT_INSTR; - delay += 3; - } - break; - case 0350: /* пино, v1m */ - Aex = addr; - delay = 4; - if (M[reg]) { - PC = addr; - RUU &= ~RUU_RIGHT_INSTR; - delay += 3; - } - break; - case 0360: /* э36, *36 */ - goto branch_zero; - case 0370: /* цикл, vlm */ - Aex = addr; - delay = 4; - if (! M[reg]) - break; - M[reg] = ADDR (M[reg] + 1); - PC = addr; - RUU &= ~RUU_RIGHT_INSTR; - delay += 3; - break; - default: - /* Unknown instruction - cannot happen. */ - longjmp (cpu_halt, STOP_STOP); - break; - } - if (next_mod) { - /* Модификация адреса следующей команды. */ - M[MOD] = next_mod; - RUU |= RUU_MOD_RK; - } else - RUU &= ~RUU_MOD_RK; + if (opcode <= 077) + PC = 0500 + opcode; /* э50-э77 */ + else + PC = 0540 + (opcode >> 3); /* э20, э21 */ + RUU &= ~RUU_RIGHT_INSTR; + delay = 7; + break; + case 0220: /* мода, utc */ + Aex = ADDR (addr + M[reg]); + next_mod = Aex; + delay = 4; + break; + case 0230: /* мод, wtc */ + if (! addr && reg == 017) { + M[017] = ADDR (M[017] - 1); + corr_stack = 1; + } + Aex = ADDR (addr + M[reg]); + next_mod = ADDR (mmu_load (Aex)); + delay = MEAN_TIME (13, 3); + break; + case 0240: /* уиа, vtm */ + Aex = addr; + M[reg] = addr; + M[0] = 0; + if (IS_SUPERVISOR (RUU) && reg == 0) { + M[PSW] &= ~(PSW_INTR_DISABLE | + PSW_MMAP_DISABLE | PSW_PROT_DISABLE); + M[PSW] |= addr & (PSW_INTR_DISABLE | + PSW_MMAP_DISABLE | PSW_PROT_DISABLE); + } + delay = 4; + break; + case 0250: /* слиа, utm */ + Aex = ADDR (addr + M[reg]); + M[reg] = Aex; + M[0] = 0; + if (IS_SUPERVISOR (RUU) && reg == 0) { + M[PSW] &= ~(PSW_INTR_DISABLE | + PSW_MMAP_DISABLE | PSW_PROT_DISABLE); + M[PSW] |= addr & (PSW_INTR_DISABLE | + PSW_MMAP_DISABLE | PSW_PROT_DISABLE); + } + delay = 4; + break; + case 0260: /* по, uza */ + Aex = ADDR (addr + M[reg]); + RMR = ACC; + delay = MEAN_TIME (12, 3); + if (IS_ADDITIVE (RAU)) { + if (ACC & BIT41) + break; + } else if (IS_MULTIPLICATIVE (RAU)) { + if (! (ACC & BIT48)) + break; + } else if (IS_LOGICAL (RAU)) { + if (ACC) + break; + } else + break; + PC = Aex; + RUU &= ~RUU_RIGHT_INSTR; + delay += 3; + break; + case 0270: /* пе, u1a */ + Aex = ADDR (addr + M[reg]); + RMR = ACC; + delay = MEAN_TIME (12, 3); + if (IS_ADDITIVE (RAU)) { + if (! (ACC & BIT41)) + break; + } else if (IS_MULTIPLICATIVE (RAU)) { + if (ACC & BIT48) + break; + } else if (IS_LOGICAL (RAU)) { + if (! ACC) + break; + } else + /* fall thru, i.e. branch */; + PC = Aex; + RUU &= ~RUU_RIGHT_INSTR; + delay += 3; + break; + case 0300: /* пб, uj */ + Aex = ADDR (addr + M[reg]); + PC = Aex; + RUU &= ~RUU_RIGHT_INSTR; + delay = 7; + break; + case 0310: /* пв, vjm */ + Aex = addr; + M[reg] = nextpc; + M[0] = 0; + PC = addr; + RUU &= ~RUU_RIGHT_INSTR; + delay = 7; + break; + case 0320: /* выпр, iret */ + Aex = addr; + if (! IS_SUPERVISOR (RUU)) { + longjmp (cpu_halt, STOP_BADCMD); + } + M[PSW] = (M[PSW] & PSW_WRITE_WATCH) | + (M[SPSW] & (SPSW_INTR_DISABLE | + SPSW_MMAP_DISABLE | SPSW_PROT_DISABLE)); + PC = M[(reg & 3) | 030]; + RUU &= ~RUU_RIGHT_INSTR; + if (M[SPSW] & SPSW_RIGHT_INSTR) + RUU |= RUU_RIGHT_INSTR; + else + RUU &= ~RUU_RIGHT_INSTR; + RUU = SET_SUPERVISOR (RUU, + M[SPSW] & (SPSW_EXTRACODE | SPSW_INTERRUPT)); + if (M[SPSW] & SPSW_MOD_RK) + next_mod = M[MOD]; + /*besm6_okno ("Выход из прерывания");*/ + delay = 7; + break; + case 0330: /* стоп, stop */ + Aex = ADDR (addr + M[reg]); + delay = 7; + if (! IS_SUPERVISOR(RUU)) { + if (M[PSW] & PSW_CHECK_HALT) + break; + else { + opcode = 063; + goto stop_as_extracode; + } + } + mmu_print_brz (); + longjmp (cpu_halt, STOP_STOP); + break; + case 0340: /* пио, vzm */ + branch_zero: Aex = addr; + delay = 4; + if (! M[reg]) { + PC = addr; + RUU &= ~RUU_RIGHT_INSTR; + delay += 3; + } + break; + case 0350: /* пино, v1m */ + Aex = addr; + delay = 4; + if (M[reg]) { + PC = addr; + RUU &= ~RUU_RIGHT_INSTR; + delay += 3; + } + break; + case 0360: /* э36, *36 */ + goto branch_zero; + case 0370: /* цикл, vlm */ + Aex = addr; + delay = 4; + if (! M[reg]) + break; + M[reg] = ADDR (M[reg] + 1); + PC = addr; + RUU &= ~RUU_RIGHT_INSTR; + delay += 3; + break; + default: + /* Unknown instruction - cannot happen. */ + longjmp (cpu_halt, STOP_STOP); + break; + } + if (next_mod) { + /* Модификация адреса следующей команды. */ + M[MOD] = next_mod; + RUU |= RUU_MOD_RK; + } else + RUU &= ~RUU_MOD_RK; - /* Не находимся ли мы в цикле "ЖДУ" диспака? */ - if (RUU == 047 && PC == 04440 && RK == 067704440) { - /* Притормаживаем выполнение каждой команды холостого цикла, - * чтобы быстрее обрабатывались прерывания: ускоряются - * терминалы и АЦПУ. */ - delay = sim_interval; + /* Не находимся ли мы в цикле "ЖДУ" диспака? */ + if (RUU == 047 && PC == 04440 && RK == 067704440) { + /* Притормаживаем выполнение каждой команды холостого цикла, + * чтобы быстрее обрабатывались прерывания: ускоряются + * терминалы и АЦПУ. */ + delay = sim_interval; - /* Если периферия простаивает, освобождаем процессор - * до следующего тика таймера. */ - if (vt_is_idle() && - printer_is_idle() && fs_is_idle()) { - check_initial_setup (); - pause (); - } - } + /* Если периферия простаивает, освобождаем процессор + * до следующего тика таймера. */ + if (vt_is_idle() && + printer_is_idle() && fs_is_idle()) { + check_initial_setup (); + pause (); + } + } } /* @@ -1475,20 +1489,20 @@ branch_zero: Aex = addr; */ void op_int_1 (const char *msg) { - /*besm6_okno (msg);*/ - M[SPSW] = (M[PSW] & (PSW_INTR_DISABLE | PSW_MMAP_DISABLE | - PSW_PROT_DISABLE)) | IS_SUPERVISOR (RUU); - if (RUU & RUU_RIGHT_INSTR) - M[SPSW] |= SPSW_RIGHT_INSTR; - M[IRET] = PC; - M[PSW] |= PSW_INTR_DISABLE | PSW_MMAP_DISABLE | PSW_PROT_DISABLE; - if (RUU & RUU_MOD_RK) { - M[SPSW] |= SPSW_MOD_RK; - RUU &= ~RUU_MOD_RK; - } - PC = 0500; - RUU &= ~RUU_RIGHT_INSTR; - RUU = SET_SUPERVISOR (RUU, SPSW_INTERRUPT); + /*besm6_okno (msg);*/ + M[SPSW] = (M[PSW] & (PSW_INTR_DISABLE | PSW_MMAP_DISABLE | + PSW_PROT_DISABLE)) | IS_SUPERVISOR (RUU); + if (RUU & RUU_RIGHT_INSTR) + M[SPSW] |= SPSW_RIGHT_INSTR; + M[IRET] = PC; + M[PSW] |= PSW_INTR_DISABLE | PSW_MMAP_DISABLE | PSW_PROT_DISABLE; + if (RUU & RUU_MOD_RK) { + M[SPSW] |= SPSW_MOD_RK; + RUU &= ~RUU_MOD_RK; + } + PC = 0500; + RUU &= ~RUU_RIGHT_INSTR; + RUU = SET_SUPERVISOR (RUU, SPSW_INTERRUPT); } /* @@ -1497,18 +1511,18 @@ void op_int_1 (const char *msg) */ void op_int_2 () { - /*besm6_okno ("Внешнее прерывание");*/ - M[SPSW] = (M[PSW] & (PSW_INTR_DISABLE | PSW_MMAP_DISABLE | - PSW_PROT_DISABLE)) | IS_SUPERVISOR (RUU); - M[IRET] = PC; - M[PSW] |= PSW_INTR_DISABLE | PSW_MMAP_DISABLE | PSW_PROT_DISABLE; - if (RUU & RUU_MOD_RK) { - M[SPSW] |= SPSW_MOD_RK; - RUU &= ~RUU_MOD_RK; - } - PC = 0501; - RUU &= ~RUU_RIGHT_INSTR; - RUU = SET_SUPERVISOR (RUU, SPSW_INTERRUPT); + /*besm6_okno ("Внешнее прерывание");*/ + M[SPSW] = (M[PSW] & (PSW_INTR_DISABLE | PSW_MMAP_DISABLE | + PSW_PROT_DISABLE)) | IS_SUPERVISOR (RUU); + M[IRET] = PC; + M[PSW] |= PSW_INTR_DISABLE | PSW_MMAP_DISABLE | PSW_PROT_DISABLE; + if (RUU & RUU_MOD_RK) { + M[SPSW] |= SPSW_MOD_RK; + RUU &= ~RUU_MOD_RK; + } + PC = 0501; + RUU &= ~RUU_RIGHT_INSTR; + RUU = SET_SUPERVISOR (RUU, SPSW_INTERRUPT); } /* @@ -1516,220 +1530,220 @@ void op_int_2 () */ t_stat sim_instr (void) { - t_stat r; - int iintr = 0; + t_stat r; + int iintr = 0; - /* Restore register state */ - PC = PC & BITS(15); /* mask PC */ - sim_cancel_step (); /* defang SCP step */ - mmu_setup (); /* copy RP to TLB */ + /* Restore register state */ + PC = PC & BITS(15); /* mask PC */ + sim_cancel_step (); /* defang SCP step */ + mmu_setup (); /* copy RP to TLB */ - /* An internal interrupt or user intervention */ - r = setjmp (cpu_halt); - if (r) { - M[017] += corr_stack; - if (cpu_dev.dctrl) { - const char *message = (r >= SCPE_BASE) ? - scp_errors [r - SCPE_BASE] : - sim_stop_messages [r]; - besm6_debug ("/// %05o%s: %s", PC, - (RUU & RUU_RIGHT_INSTR) ? "п" : "л", - message); - } + /* An internal interrupt or user intervention */ + r = setjmp (cpu_halt); + if (r) { + M[017] += corr_stack; + if (cpu_dev.dctrl) { + const char *message = (r >= SCPE_BASE) ? + scp_errors [r - SCPE_BASE] : + sim_stop_messages [r]; + besm6_debug ("/// %05o%s: %s", PC, + (RUU & RUU_RIGHT_INSTR) ? "п" : "л", + message); + } - /* - * ПоП и ПоК вызывают останов при любом внутреннем прерывании - * или прерывании по контролю, соответственно. - * Если произошёл останов по ПоП или ПоК, - * то продолжение выполнения начнётся с команды, следующей - * за вызвавшей прерывание. Как если бы кнопка "ТП" (тип - * перехода) была включена. Подробнее на странице 119 ТО9. - */ - switch (r) { - default: -ret: besm6_draw_panel(); - return r; - case STOP_RWATCH: - case STOP_WWATCH: - /* Step back one insn to reexecute it */ - if (! (RUU & RUU_RIGHT_INSTR)) { - --PC; - } - RUU ^= RUU_RIGHT_INSTR; - goto ret; - case STOP_BADCMD: - if (M[PSW] & PSW_INTR_HALT) /* ПоП */ - goto ret; - op_int_1 (sim_stop_messages[r]); - // SPSW_NEXT_RK is not important for this interrupt - GRP |= GRP_ILL_INSN; - break; - case STOP_INSN_CHECK: - if (M[PSW] & PSW_CHECK_HALT) /* ПоК */ - goto ret; - op_int_1 (sim_stop_messages[r]); - // SPSW_NEXT_RK must be 0 for this interrupt; it is already - GRP |= GRP_INSN_CHECK; - break; - case STOP_INSN_PROT: - if (M[PSW] & PSW_INTR_HALT) /* ПоП */ - goto ret; - if (RUU & RUU_RIGHT_INSTR) { - ++PC; - } - RUU ^= RUU_RIGHT_INSTR; - op_int_1 (sim_stop_messages[r]); - // SPSW_NEXT_RK must be 1 for this interrupt - M[SPSW] |= SPSW_NEXT_RK; - GRP |= GRP_INSN_PROT; - break; - case STOP_OPERAND_PROT: + /* + * ПоП и ПоК вызывают останов при любом внутреннем прерывании + * или прерывании по контролю, соответственно. + * Если произошёл останов по ПоП или ПоК, + * то продолжение выполнения начнётся с команды, следующей + * за вызвавшей прерывание. Как если бы кнопка "ТП" (тип + * перехода) была включена. Подробнее на странице 119 ТО9. + */ + switch (r) { + default: + ret: besm6_draw_panel(); + return r; + case STOP_RWATCH: + case STOP_WWATCH: + /* Step back one insn to reexecute it */ + if (! (RUU & RUU_RIGHT_INSTR)) { + --PC; + } + RUU ^= RUU_RIGHT_INSTR; + goto ret; + case STOP_BADCMD: + if (M[PSW] & PSW_INTR_HALT) /* ПоП */ + goto ret; + op_int_1 (sim_stop_messages[r]); + // SPSW_NEXT_RK is not important for this interrupt + GRP |= GRP_ILL_INSN; + break; + case STOP_INSN_CHECK: + if (M[PSW] & PSW_CHECK_HALT) /* ПоК */ + goto ret; + op_int_1 (sim_stop_messages[r]); + // SPSW_NEXT_RK must be 0 for this interrupt; it is already + GRP |= GRP_INSN_CHECK; + break; + case STOP_INSN_PROT: + if (M[PSW] & PSW_INTR_HALT) /* ПоП */ + goto ret; + if (RUU & RUU_RIGHT_INSTR) { + ++PC; + } + RUU ^= RUU_RIGHT_INSTR; + op_int_1 (sim_stop_messages[r]); + // SPSW_NEXT_RK must be 1 for this interrupt + M[SPSW] |= SPSW_NEXT_RK; + GRP |= GRP_INSN_PROT; + break; + case STOP_OPERAND_PROT: #if 0 /* ДИСПАК держит признак ПоП установленным. * При запуске СЕРП возникает обращение к чужому листу. */ - if (M[PSW] & PSW_INTR_HALT) /* ПоП */ - goto ret; + if (M[PSW] & PSW_INTR_HALT) /* ПоП */ + goto ret; #endif - if (RUU & RUU_RIGHT_INSTR) { - ++PC; - } - RUU ^= RUU_RIGHT_INSTR; - op_int_1 (sim_stop_messages[r]); - M[SPSW] |= SPSW_NEXT_RK; - // The offending virtual page is in bits 5-9 - GRP |= GRP_OPRND_PROT; - GRP = GRP_SET_PAGE (GRP, iintr_data); - break; - case STOP_RAM_CHECK: - if (M[PSW] & PSW_CHECK_HALT) /* ПоК */ - goto ret; - op_int_1 (sim_stop_messages[r]); - // The offending interleaved block # is in bits 1-3. - GRP |= GRP_CHECK | GRP_RAM_CHECK; - GRP = GRP_SET_BLOCK (GRP, iintr_data); - break; - case STOP_CACHE_CHECK: - if (M[PSW] & PSW_CHECK_HALT) /* ПоК */ - goto ret; - op_int_1 (sim_stop_messages[r]); - // The offending BRZ # is in bits 1-3. - GRP |= GRP_CHECK; - GRP &= ~GRP_RAM_CHECK; - GRP = GRP_SET_BLOCK (GRP, iintr_data); - break; - case STOP_INSN_ADDR_MATCH: - if (M[PSW] & PSW_INTR_HALT) /* ПоП */ - goto ret; - if (RUU & RUU_RIGHT_INSTR) { - ++PC; - } - RUU ^= RUU_RIGHT_INSTR; - op_int_1 (sim_stop_messages[r]); - M[SPSW] |= SPSW_NEXT_RK; - GRP |= GRP_BREAKPOINT; - break; - case STOP_LOAD_ADDR_MATCH: - if (M[PSW] & PSW_INTR_HALT) /* ПоП */ - goto ret; - if (RUU & RUU_RIGHT_INSTR) { - ++PC; - } - RUU ^= RUU_RIGHT_INSTR; - op_int_1 (sim_stop_messages[r]); - M[SPSW] |= SPSW_NEXT_RK; - GRP |= GRP_WATCHPT_R; - break; - case STOP_STORE_ADDR_MATCH: - if (M[PSW] & PSW_INTR_HALT) /* ПоП */ - goto ret; - if (RUU & RUU_RIGHT_INSTR) { - ++PC; - } - RUU ^= RUU_RIGHT_INSTR; - op_int_1 (sim_stop_messages[r]); - M[SPSW] |= SPSW_NEXT_RK; - GRP |= GRP_WATCHPT_W; - break; - case STOP_OVFL: - /* Прерывание по АУ вызывает останов, если БРО=0 - * и установлен ПоП или ПоК. - * Страница 118 ТО9.*/ - if (! (RUU & RUU_AVOST_DISABLE) && /* ! БРО */ - ((M[PSW] & PSW_INTR_HALT) || /* ПоП */ - (M[PSW] & PSW_CHECK_HALT))) /* ПоК */ - goto ret; - op_int_1 (sim_stop_messages[r]); - GRP |= GRP_OVERFLOW|GRP_RAM_CHECK; - break; - case STOP_DIVZERO: - if (! (RUU & RUU_AVOST_DISABLE) && /* ! БРО */ - ((M[PSW] & PSW_INTR_HALT) || /* ПоП */ - (M[PSW] & PSW_CHECK_HALT))) /* ПоК */ - goto ret; - op_int_1 (sim_stop_messages[r]); - GRP |= GRP_DIVZERO|GRP_RAM_CHECK; - break; - } - ++iintr; - } + if (RUU & RUU_RIGHT_INSTR) { + ++PC; + } + RUU ^= RUU_RIGHT_INSTR; + op_int_1 (sim_stop_messages[r]); + M[SPSW] |= SPSW_NEXT_RK; + // The offending virtual page is in bits 5-9 + GRP |= GRP_OPRND_PROT; + GRP = GRP_SET_PAGE (GRP, iintr_data); + break; + case STOP_RAM_CHECK: + if (M[PSW] & PSW_CHECK_HALT) /* ПоК */ + goto ret; + op_int_1 (sim_stop_messages[r]); + // The offending interleaved block # is in bits 1-3. + GRP |= GRP_CHECK | GRP_RAM_CHECK; + GRP = GRP_SET_BLOCK (GRP, iintr_data); + break; + case STOP_CACHE_CHECK: + if (M[PSW] & PSW_CHECK_HALT) /* ПоК */ + goto ret; + op_int_1 (sim_stop_messages[r]); + // The offending BRZ # is in bits 1-3. + GRP |= GRP_CHECK; + GRP &= ~GRP_RAM_CHECK; + GRP = GRP_SET_BLOCK (GRP, iintr_data); + break; + case STOP_INSN_ADDR_MATCH: + if (M[PSW] & PSW_INTR_HALT) /* ПоП */ + goto ret; + if (RUU & RUU_RIGHT_INSTR) { + ++PC; + } + RUU ^= RUU_RIGHT_INSTR; + op_int_1 (sim_stop_messages[r]); + M[SPSW] |= SPSW_NEXT_RK; + GRP |= GRP_BREAKPOINT; + break; + case STOP_LOAD_ADDR_MATCH: + if (M[PSW] & PSW_INTR_HALT) /* ПоП */ + goto ret; + if (RUU & RUU_RIGHT_INSTR) { + ++PC; + } + RUU ^= RUU_RIGHT_INSTR; + op_int_1 (sim_stop_messages[r]); + M[SPSW] |= SPSW_NEXT_RK; + GRP |= GRP_WATCHPT_R; + break; + case STOP_STORE_ADDR_MATCH: + if (M[PSW] & PSW_INTR_HALT) /* ПоП */ + goto ret; + if (RUU & RUU_RIGHT_INSTR) { + ++PC; + } + RUU ^= RUU_RIGHT_INSTR; + op_int_1 (sim_stop_messages[r]); + M[SPSW] |= SPSW_NEXT_RK; + GRP |= GRP_WATCHPT_W; + break; + case STOP_OVFL: + /* Прерывание по АУ вызывает останов, если БРО=0 + * и установлен ПоП или ПоК. + * Страница 118 ТО9.*/ + if (! (RUU & RUU_AVOST_DISABLE) && /* ! БРО */ + ((M[PSW] & PSW_INTR_HALT) || /* ПоП */ + (M[PSW] & PSW_CHECK_HALT))) /* ПоК */ + goto ret; + op_int_1 (sim_stop_messages[r]); + GRP |= GRP_OVERFLOW|GRP_RAM_CHECK; + break; + case STOP_DIVZERO: + if (! (RUU & RUU_AVOST_DISABLE) && /* ! БРО */ + ((M[PSW] & PSW_INTR_HALT) || /* ПоП */ + (M[PSW] & PSW_CHECK_HALT))) /* ПоК */ + goto ret; + op_int_1 (sim_stop_messages[r]); + GRP |= GRP_DIVZERO|GRP_RAM_CHECK; + break; + } + ++iintr; + } - if (iintr > 1) { - besm6_draw_panel(); - return STOP_DOUBLE_INTR; - } - /* Main instruction fetch/decode loop */ - for (;;) { - if (sim_interval <= 0) { /* check clock queue */ - r = sim_process_event (); - if (r) { - besm6_draw_panel(); - return r; - } - } + if (iintr > 1) { + besm6_draw_panel(); + return STOP_DOUBLE_INTR; + } + /* Main instruction fetch/decode loop */ + for (;;) { + if (sim_interval <= 0) { /* check clock queue */ + r = sim_process_event (); + if (r) { + besm6_draw_panel(); + return r; + } + } - if (PC > BITS(15)) { /* выход за пределы памяти */ - besm6_draw_panel(); - return STOP_RUNOUT; /* stop simulation */ - } + if (PC > BITS(15)) { /* выход за пределы памяти */ + besm6_draw_panel(); + return STOP_RUNOUT; /* stop simulation */ + } - if (sim_brk_summ & SWMASK('E') && /* breakpoint? */ - sim_brk_test (PC, SWMASK ('E'))) { - besm6_draw_panel(); - return STOP_IBKPT; /* stop simulation */ - } + if (sim_brk_summ & SWMASK('E') && /* breakpoint? */ + sim_brk_test (PC, SWMASK ('E'))) { + besm6_draw_panel(); + return STOP_IBKPT; /* stop simulation */ + } - if (PRP & MPRP) { - /* регистр хранящий, сбрасывается программно */ - GRP |= GRP_SLAVE; - } + if (PRP & MPRP) { + /* регистр хранящий, сбрасывается программно */ + GRP |= GRP_SLAVE; + } - if (! iintr && ! (RUU & RUU_RIGHT_INSTR) && - ! (M[PSW] & PSW_INTR_DISABLE) && (GRP & MGRP)) { - /* external interrupt */ - op_int_2(); - } - cpu_one_inst (); /* one instr */ - iintr = 0; - if (redraw_panel) { - besm6_draw_panel(); - redraw_panel = 0; - } + if (! iintr && ! (RUU & RUU_RIGHT_INSTR) && + ! (M[PSW] & PSW_INTR_DISABLE) && (GRP & MGRP)) { + /* external interrupt */ + op_int_2(); + } + cpu_one_inst (); /* one instr */ + iintr = 0; + if (redraw_panel) { + besm6_draw_panel(); + redraw_panel = 0; + } - if (delay < 1) - delay = 1; - sim_interval -= delay; /* count down delay */ - if (sim_step && (--sim_step <= 0)) { /* do step count */ - besm6_draw_panel(); - return SCPE_STOP; - } - } + if (delay < 1) + delay = 1; + sim_interval -= delay; /* count down delay */ + if (sim_step && (--sim_step <= 0)) { /* do step count */ + besm6_draw_panel(); + return SCPE_STOP; + } + } } t_stat slow_clk (UNIT * this) { - /*besm6_debug ("*** таймер 80 мсек");*/ - GRP |= GRP_SLOW_CLK; - return sim_activate (this, MSEC*125/2); + /*besm6_debug ("*** таймер 80 мсек");*/ + GRP |= GRP_SLOW_CLK; + return sim_activate (this, MSEC*125/2); } /* @@ -1738,31 +1752,31 @@ t_stat slow_clk (UNIT * this) */ t_stat fast_clk (UNIT * this) { - /*besm6_debug ("*** таймер 20 мсек");*/ - GRP |= GRP_TIMER; - return sim_activate (this, 20*MSEC); + /*besm6_debug ("*** таймер 20 мсек");*/ + GRP |= GRP_TIMER; + return sim_activate (this, 20*MSEC); } UNIT clocks[] = { - { UDATA(slow_clk, 0, 0) }, /* 10 р, 16 Гц */ - { UDATA(fast_clk, 0, 0) }, /* 40 р, 50 Гц */ + { UDATA(slow_clk, 0, 0) }, /* 10 р, 16 Гц */ + { UDATA(fast_clk, 0, 0) }, /* 40 р, 50 Гц */ }; t_stat clk_reset (DEVICE * dev) { - /* Схема автозапуска включается по нереализованной кнопке "МР" */ + /* Схема автозапуска включается по нереализованной кнопке "МР" */ #ifdef SOFT_CLOCK - sim_activate (&clocks[0], MSEC*125/2); - return sim_activate (&clocks[1], 20*MSEC); + sim_activate (&clocks[0], MSEC*125/2); + return sim_activate (&clocks[1], 20*MSEC); #else - return SCPE_OK; + return SCPE_OK; #endif } DEVICE clock_dev = { - "CLK", clocks, NULL, NULL, - 2, 0, 0, 0, 0, 0, - NULL, NULL, &clk_reset, - NULL, NULL, NULL, NULL, - DEV_DEBUG + "CLK", clocks, NULL, NULL, + 2, 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 3da2fa62..faec0254 100644 --- a/BESM6/besm6_defs.h +++ b/BESM6/besm6_defs.h @@ -30,14 +30,15 @@ #ifndef _BESM6_DEFS_H_ #define _BESM6_DEFS_H_ 0 -#include "sim_defs.h" /* simulator defns */ +#include "sim_defs.h" /* simulator defns */ +#include "scp.h" #include /* * Memory. */ -#define NREGS 30 /* number of registers-modifiers */ -#define MEMSIZE (512 * 1024) /* memory size, words */ +#define NREGS 30 /* number of registers-modifiers */ +#define MEMSIZE (512 * 1024) /* memory size, words */ /* * Drums and disks. @@ -46,52 +47,52 @@ * Every word (t_value) is stored as 8-byte record, low byte first. * System data is stored first, then user data. */ -#define ZONE_SIZE (8 + 1024) /* 1kword zone size, words */ -#define DRUM_SIZE (256 * ZONE_SIZE) /* drum size per controller, words */ -#define DISK_SIZE (1024 * ZONE_SIZE) /* disk size per unit, words */ +#define ZONE_SIZE (8 + 1024) /* 1kword zone size, words */ +#define DRUM_SIZE (256 * ZONE_SIZE) /* drum size per controller, words */ +#define DISK_SIZE (1024 * ZONE_SIZE) /* disk size per unit, words */ /* * Simulator stop codes */ enum { - STOP_STOP = 1, /* STOP */ - STOP_IBKPT, /* SIMH breakpoint */ - STOP_RWATCH, /* SIMH read watchpoint */ - STOP_WWATCH, /* SIMH write watchpoint */ - STOP_RUNOUT, /* run out end of memory limits */ - STOP_BADCMD, /* invalid instruction */ - STOP_INSN_CHECK, /* not an instruction */ - STOP_INSN_PROT, /* fetch from blocked page */ - STOP_OPERAND_PROT, /* load from blocked page */ - STOP_RAM_CHECK, /* RAM parity error */ - STOP_CACHE_CHECK, /* data cache parity error */ - STOP_OVFL, /* arith. overflow */ - STOP_DIVZERO, /* division by 0 or denorm */ - STOP_DOUBLE_INTR, /* double internal interrupt */ - STOP_DRUMINVDATA, /* reading unformatted drum */ - STOP_DISKINVDATA, /* reading unformatted disk */ - STOP_INSN_ADDR_MATCH, /* fetch address matched breakpt reg */ - STOP_LOAD_ADDR_MATCH, /* load address matched watchpt reg */ - STOP_STORE_ADDR_MATCH, /* store address matched watchpt reg */ - STOP_UNIMPLEMENTED, /* unimplemented 033 or 002 insn feature */ + STOP_STOP = 1, /* STOP */ + STOP_IBKPT, /* SIMH breakpoint */ + STOP_RWATCH, /* SIMH read watchpoint */ + STOP_WWATCH, /* SIMH write watchpoint */ + STOP_RUNOUT, /* run out end of memory limits */ + STOP_BADCMD, /* invalid instruction */ + STOP_INSN_CHECK, /* not an instruction */ + STOP_INSN_PROT, /* fetch from blocked page */ + STOP_OPERAND_PROT, /* load from blocked page */ + STOP_RAM_CHECK, /* RAM parity error */ + STOP_CACHE_CHECK, /* data cache parity error */ + STOP_OVFL, /* arith. overflow */ + STOP_DIVZERO, /* division by 0 or denorm */ + STOP_DOUBLE_INTR, /* double internal interrupt */ + STOP_DRUMINVDATA, /* reading unformatted drum */ + STOP_DISKINVDATA, /* reading unformatted disk */ + STOP_INSN_ADDR_MATCH, /* fetch address matched breakpt reg */ + STOP_LOAD_ADDR_MATCH, /* load address matched watchpt reg */ + STOP_STORE_ADDR_MATCH, /* store address matched watchpt reg */ + STOP_UNIMPLEMENTED, /* unimplemented 033 or 002 insn feature */ }; /* * Разряды машинного слова, справа налево, начиная с 1. */ -#define BBIT(n) (1 << (n-1)) /* один бит, от 1 до 32 */ -#define BIT40 000010000000000000LL /* 40-й бит - старший разряд мантиссы */ -#define BIT41 000020000000000000LL /* 41-й бит - знак */ -#define BIT42 000040000000000000LL /* 42-й бит - дубль-знак в мантиссе */ -#define BIT48 004000000000000000LL /* 48-й бит - знак порядка */ -#define BIT49 010000000000000000LL /* бит 49 */ -#define BITS(n) (~0U >> (32-n)) /* маска битов n..1 */ -#define BITS40 00017777777777777LL /* биты 41..1 - мантисса */ -#define BITS41 00037777777777777LL /* биты 41..1 - мантисса и знак */ -#define BITS42 00077777777777777LL /* биты 42..1 - мантисса и оба знака */ -#define BITS48 07777777777777777LL /* биты 48..1 */ -#define BITS48_42 07740000000000000LL /* биты 48..42 - порядок */ -#define ADDR(x) ((x) & BITS(15)) /* адрес слова */ +#define BBIT(n) (1 << (n-1)) /* один бит, от 1 до 32 */ +#define BIT40 000010000000000000LL /* 40-й бит - старший разряд мантиссы */ +#define BIT41 000020000000000000LL /* 41-й бит - знак */ +#define BIT42 000040000000000000LL /* 42-й бит - дубль-знак в мантиссе */ +#define BIT48 004000000000000000LL /* 48-й бит - знак порядка */ +#define BIT49 010000000000000000LL /* бит 49 */ +#define BITS(n) (~0U >> (32-n)) /* маска битов n..1 */ +#define BITS40 00017777777777777LL /* биты 41..1 - мантисса */ +#define BITS41 00037777777777777LL /* биты 41..1 - мантисса и знак */ +#define BITS42 00077777777777777LL /* биты 42..1 - мантисса и оба знака */ +#define BITS48 07777777777777777LL /* биты 48..1 */ +#define BITS48_42 07740000000000000LL /* биты 48..42 - порядок */ +#define ADDR(x) ((x) & BITS(15)) /* адрес слова */ /* * Работа со сверткой. Значение разрядов свертки слова равно значению @@ -101,12 +102,12 @@ enum { * 11 - числовая свертка * В памяти биты свертки имитируют четность полуслов. */ -#define CONVOL_INSN 1 -#define CONVOL_NUMBER 2 -#define SET_CONVOL(x, c) (((x) & BITS48) | (((c) & 3LL) << 48)) -#define IS_INSN(x) (((x) >> 48) == CONVOL_INSN) -#define IS_NUMBER(x) (((x) >> 48) == CONVOL_INSN || \ - ((x) >> 48) == CONVOL_NUMBER) +#define CONVOL_INSN 1 +#define CONVOL_NUMBER 2 +#define SET_CONVOL(x, c) (((x) & BITS48) | (((c) & 3LL) << 48)) +#define IS_INSN(x) (((x) >> 48) == CONVOL_INSN) +#define IS_NUMBER(x) (((x) >> 48) == CONVOL_INSN || \ + ((x) >> 48) == CONVOL_NUMBER) /* * Вычисление правдоподобного времени выполнения команды, @@ -115,18 +116,13 @@ enum { * выполнения, поэтому суммируем большее и половину * от меньшего значения. */ -#define MEAN_TIME(x,y) (x>y ? x+y/2 : x/2+y) +#define MEAN_TIME(x,y) (x>y ? x+y/2 : x/2+y) /* * Считаем, что моделируеммая машина имеет опорную частоту 10 МГц. */ -#define USEC 10 /* одна микросекунда - десять тактов */ -#define MSEC (1000*USEC) /* одна миллисекунда */ - -extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ -extern int32 sim_interval, sim_step; -extern FILE *sim_deb, *sim_log; -extern int32 sim_switches; +#define USEC 10 /* одна микросекунда - десять тактов */ +#define MSEC (1000*USEC) /* одна миллисекунда */ extern UNIT cpu_unit; extern t_value memory [MEMSIZE]; @@ -168,131 +164,131 @@ extern jmp_buf cpu_halt; /* * Искусственный регистр режимов УУ, в реальной машине отсутствует. */ -#define RUU_CONVOL_RIGHT 000001 /* ПКП - признак контроля правой половины */ -#define RUU_CONVOL_LEFT 000002 /* ПКЛ - признак контроля левой половины */ -#define RUU_EXTRACODE 000004 /* РежЭ - режим экстракода */ -#define RUU_INTERRUPT 000010 /* РежПр - режим прерывания */ -#define RUU_MOD_RK 000020 /* ПрИК - модификация регистром М[16] */ -#define RUU_AVOST_DISABLE 000040 /* БРО - блокировка режима останова */ -#define RUU_RIGHT_INSTR 000400 /* ПрК - признак правой команды */ +#define RUU_CONVOL_RIGHT 000001 /* ПКП - признак контроля правой половины */ +#define RUU_CONVOL_LEFT 000002 /* ПКЛ - признак контроля левой половины */ +#define RUU_EXTRACODE 000004 /* РежЭ - режим экстракода */ +#define RUU_INTERRUPT 000010 /* РежПр - режим прерывания */ +#define RUU_MOD_RK 000020 /* ПрИК - модификация регистром М[16] */ +#define RUU_AVOST_DISABLE 000040 /* БРО - блокировка режима останова */ +#define RUU_RIGHT_INSTR 000400 /* ПрК - признак правой команды */ -#define IS_SUPERVISOR(x) ((x) & (RUU_EXTRACODE | RUU_INTERRUPT)) -#define SET_SUPERVISOR(x,m) (((x) & ~(RUU_EXTRACODE | RUU_INTERRUPT)) | (m)) +#define IS_SUPERVISOR(x) ((x) & (RUU_EXTRACODE | RUU_INTERRUPT)) +#define SET_SUPERVISOR(x,m) (((x) & ~(RUU_EXTRACODE | RUU_INTERRUPT)) | (m)) /* * Специальные регистры. */ -#define MOD 020 /* модификатор адреса */ -#define PSW 021 /* режимы УУ */ -#define SPSW 027 /* упрятывание режимов УУ */ -#define ERET 032 /* адрес возврата из экстракода */ -#define IRET 033 /* адрес возврата из прерывания */ -#define IBP 034 /* адрес прерывания по выполнению */ -#define DWP 035 /* адрес прерывания по чтению/записи */ +#define MOD 020 /* модификатор адреса */ +#define PSW 021 /* режимы УУ */ +#define SPSW 027 /* упрятывание режимов УУ */ +#define ERET 032 /* адрес возврата из экстракода */ +#define IRET 033 /* адрес возврата из прерывания */ +#define IBP 034 /* адрес прерывания по выполнению */ +#define DWP 035 /* адрес прерывания по чтению/записи */ /* * Регистр 021: режимы УУ. * PSW: program status word. */ -#define PSW_MMAP_DISABLE 000001 /* БлП - блокировка приписки */ -#define PSW_PROT_DISABLE 000002 /* БлЗ - блокировка защиты */ -#define PSW_INTR_HALT 000004 /* ПоП - признак останова при - любом внутреннем прерывании */ -#define PSW_CHECK_HALT 000010 /* ПоК - признак останова при - прерывании по контролю */ -#define PSW_WRITE_WATCH 000020 /* Зп(М29) - признак совпадения адреса - операнда прии записи в память - с содержанием регистра М29 */ -#define PSW_INTR_DISABLE 002000 /* БлПр - блокировка внешнего прерывания */ -#define PSW_AUT_B 004000 /* АвтБ - признак режима Автомат Б */ +#define PSW_MMAP_DISABLE 000001 /* БлП - блокировка приписки */ +#define PSW_PROT_DISABLE 000002 /* БлЗ - блокировка защиты */ +#define PSW_INTR_HALT 000004 /* ПоП - признак останова при + любом внутреннем прерывании */ +#define PSW_CHECK_HALT 000010 /* ПоК - признак останова при + прерывании по контролю */ +#define PSW_WRITE_WATCH 000020 /* Зп(М29) - признак совпадения адреса + операнда прии записи в память + с содержанием регистра М29 */ +#define PSW_INTR_DISABLE 002000 /* БлПр - блокировка внешнего прерывания */ +#define PSW_AUT_B 004000 /* АвтБ - признак режима Автомат Б */ /* * Регистр 027: сохранённые режимы УУ. * SPSW: saved program status word. */ -#define SPSW_MMAP_DISABLE 000001 /* БлП - блокировка приписки */ -#define SPSW_PROT_DISABLE 000002 /* БлЗ - блокировка защиты */ -#define SPSW_EXTRACODE 000004 /* РежЭ - режим экстракода */ -#define SPSW_INTERRUPT 000010 /* РежПр - режим прерывания */ -#define SPSW_MOD_RK 000020 /* ПрИК(РК) - на регистр РК принята - команда, которая должна быть - модифицирована регистром М[16] */ -#define SPSW_MOD_RR 000040 /* ПрИК(РР) - на регистре РР находится - команда, выполненная с модификацией */ -#define SPSW_UNKNOWN 000100 /* НОК? вписано карандашом в 9 томе */ -#define SPSW_RIGHT_INSTR 000400 /* ПрК - признак правой команды */ -#define SPSW_NEXT_RK 001000 /* ГД./ДК2 - на регистр РК принята - команда, следующая после вызвавшей - прерывание */ -#define SPSW_INTR_DISABLE 002000 /* БлПр - блокировка внешнего прерывания */ +#define SPSW_MMAP_DISABLE 000001 /* БлП - блокировка приписки */ +#define SPSW_PROT_DISABLE 000002 /* БлЗ - блокировка защиты */ +#define SPSW_EXTRACODE 000004 /* РежЭ - режим экстракода */ +#define SPSW_INTERRUPT 000010 /* РежПр - режим прерывания */ +#define SPSW_MOD_RK 000020 /* ПрИК(РК) - на регистр РК принята + команда, которая должна быть + модифицирована регистром М[16] */ +#define SPSW_MOD_RR 000040 /* ПрИК(РР) - на регистре РР находится + команда, выполненная с модификацией */ +#define SPSW_UNKNOWN 000100 /* НОК? вписано карандашом в 9 томе */ +#define SPSW_RIGHT_INSTR 000400 /* ПрК - признак правой команды */ +#define SPSW_NEXT_RK 001000 /* ГД./ДК2 - на регистр РК принята + команда, следующая после вызвавшей + прерывание */ +#define SPSW_INTR_DISABLE 002000 /* БлПр - блокировка внешнего прерывания */ /* * Кириллица Unicode. */ -#define CYRILLIC_CAPITAL_LETTER_A 0x0410 -#define CYRILLIC_CAPITAL_LETTER_BE 0x0411 -#define CYRILLIC_CAPITAL_LETTER_VE 0x0412 -#define CYRILLIC_CAPITAL_LETTER_GHE 0x0413 -#define CYRILLIC_CAPITAL_LETTER_DE 0x0414 -#define CYRILLIC_CAPITAL_LETTER_IE 0x0415 -#define CYRILLIC_CAPITAL_LETTER_ZHE 0x0416 -#define CYRILLIC_CAPITAL_LETTER_ZE 0x0417 -#define CYRILLIC_CAPITAL_LETTER_I 0x0418 -#define CYRILLIC_CAPITAL_LETTER_SHORT_I 0x0419 -#define CYRILLIC_CAPITAL_LETTER_KA 0x041a -#define CYRILLIC_CAPITAL_LETTER_EL 0x041b -#define CYRILLIC_CAPITAL_LETTER_EM 0x041c -#define CYRILLIC_CAPITAL_LETTER_EN 0x041d -#define CYRILLIC_CAPITAL_LETTER_O 0x041e -#define CYRILLIC_CAPITAL_LETTER_PE 0x041f -#define CYRILLIC_CAPITAL_LETTER_ER 0x0420 -#define CYRILLIC_CAPITAL_LETTER_ES 0x0421 -#define CYRILLIC_CAPITAL_LETTER_TE 0x0422 -#define CYRILLIC_CAPITAL_LETTER_U 0x0423 -#define CYRILLIC_CAPITAL_LETTER_EF 0x0424 -#define CYRILLIC_CAPITAL_LETTER_HA 0x0425 -#define CYRILLIC_CAPITAL_LETTER_TSE 0x0426 -#define CYRILLIC_CAPITAL_LETTER_CHE 0x0427 -#define CYRILLIC_CAPITAL_LETTER_SHA 0x0428 -#define CYRILLIC_CAPITAL_LETTER_SHCHA 0x0429 -#define CYRILLIC_CAPITAL_LETTER_HARD_SIGN 0x042a -#define CYRILLIC_CAPITAL_LETTER_YERU 0x042b -#define CYRILLIC_CAPITAL_LETTER_SOFT_SIGN 0x042c -#define CYRILLIC_CAPITAL_LETTER_E 0x042d -#define CYRILLIC_CAPITAL_LETTER_YU 0x042e -#define CYRILLIC_CAPITAL_LETTER_YA 0x042f -#define CYRILLIC_SMALL_LETTER_A 0x0430 -#define CYRILLIC_SMALL_LETTER_BE 0x0431 -#define CYRILLIC_SMALL_LETTER_VE 0x0432 -#define CYRILLIC_SMALL_LETTER_GHE 0x0433 -#define CYRILLIC_SMALL_LETTER_DE 0x0434 -#define CYRILLIC_SMALL_LETTER_IE 0x0435 -#define CYRILLIC_SMALL_LETTER_ZHE 0x0436 -#define CYRILLIC_SMALL_LETTER_ZE 0x0437 -#define CYRILLIC_SMALL_LETTER_I 0x0438 -#define CYRILLIC_SMALL_LETTER_SHORT_I 0x0439 -#define CYRILLIC_SMALL_LETTER_KA 0x043a -#define CYRILLIC_SMALL_LETTER_EL 0x043b -#define CYRILLIC_SMALL_LETTER_EM 0x043c -#define CYRILLIC_SMALL_LETTER_EN 0x043d -#define CYRILLIC_SMALL_LETTER_O 0x043e -#define CYRILLIC_SMALL_LETTER_PE 0x043f -#define CYRILLIC_SMALL_LETTER_ER 0x0440 -#define CYRILLIC_SMALL_LETTER_ES 0x0441 -#define CYRILLIC_SMALL_LETTER_TE 0x0442 -#define CYRILLIC_SMALL_LETTER_U 0x0443 -#define CYRILLIC_SMALL_LETTER_EF 0x0444 -#define CYRILLIC_SMALL_LETTER_HA 0x0445 -#define CYRILLIC_SMALL_LETTER_TSE 0x0446 -#define CYRILLIC_SMALL_LETTER_CHE 0x0447 -#define CYRILLIC_SMALL_LETTER_SHA 0x0448 -#define CYRILLIC_SMALL_LETTER_SHCHA 0x0449 -#define CYRILLIC_SMALL_LETTER_HARD_SIGN 0x044a -#define CYRILLIC_SMALL_LETTER_YERU 0x044b -#define CYRILLIC_SMALL_LETTER_SOFT_SIGN 0x044c -#define CYRILLIC_SMALL_LETTER_E 0x044d -#define CYRILLIC_SMALL_LETTER_YU 0x044e -#define CYRILLIC_SMALL_LETTER_YA 0x044f +#define CYRILLIC_CAPITAL_LETTER_A 0x0410 +#define CYRILLIC_CAPITAL_LETTER_BE 0x0411 +#define CYRILLIC_CAPITAL_LETTER_VE 0x0412 +#define CYRILLIC_CAPITAL_LETTER_GHE 0x0413 +#define CYRILLIC_CAPITAL_LETTER_DE 0x0414 +#define CYRILLIC_CAPITAL_LETTER_IE 0x0415 +#define CYRILLIC_CAPITAL_LETTER_ZHE 0x0416 +#define CYRILLIC_CAPITAL_LETTER_ZE 0x0417 +#define CYRILLIC_CAPITAL_LETTER_I 0x0418 +#define CYRILLIC_CAPITAL_LETTER_SHORT_I 0x0419 +#define CYRILLIC_CAPITAL_LETTER_KA 0x041a +#define CYRILLIC_CAPITAL_LETTER_EL 0x041b +#define CYRILLIC_CAPITAL_LETTER_EM 0x041c +#define CYRILLIC_CAPITAL_LETTER_EN 0x041d +#define CYRILLIC_CAPITAL_LETTER_O 0x041e +#define CYRILLIC_CAPITAL_LETTER_PE 0x041f +#define CYRILLIC_CAPITAL_LETTER_ER 0x0420 +#define CYRILLIC_CAPITAL_LETTER_ES 0x0421 +#define CYRILLIC_CAPITAL_LETTER_TE 0x0422 +#define CYRILLIC_CAPITAL_LETTER_U 0x0423 +#define CYRILLIC_CAPITAL_LETTER_EF 0x0424 +#define CYRILLIC_CAPITAL_LETTER_HA 0x0425 +#define CYRILLIC_CAPITAL_LETTER_TSE 0x0426 +#define CYRILLIC_CAPITAL_LETTER_CHE 0x0427 +#define CYRILLIC_CAPITAL_LETTER_SHA 0x0428 +#define CYRILLIC_CAPITAL_LETTER_SHCHA 0x0429 +#define CYRILLIC_CAPITAL_LETTER_HARD_SIGN 0x042a +#define CYRILLIC_CAPITAL_LETTER_YERU 0x042b +#define CYRILLIC_CAPITAL_LETTER_SOFT_SIGN 0x042c +#define CYRILLIC_CAPITAL_LETTER_E 0x042d +#define CYRILLIC_CAPITAL_LETTER_YU 0x042e +#define CYRILLIC_CAPITAL_LETTER_YA 0x042f +#define CYRILLIC_SMALL_LETTER_A 0x0430 +#define CYRILLIC_SMALL_LETTER_BE 0x0431 +#define CYRILLIC_SMALL_LETTER_VE 0x0432 +#define CYRILLIC_SMALL_LETTER_GHE 0x0433 +#define CYRILLIC_SMALL_LETTER_DE 0x0434 +#define CYRILLIC_SMALL_LETTER_IE 0x0435 +#define CYRILLIC_SMALL_LETTER_ZHE 0x0436 +#define CYRILLIC_SMALL_LETTER_ZE 0x0437 +#define CYRILLIC_SMALL_LETTER_I 0x0438 +#define CYRILLIC_SMALL_LETTER_SHORT_I 0x0439 +#define CYRILLIC_SMALL_LETTER_KA 0x043a +#define CYRILLIC_SMALL_LETTER_EL 0x043b +#define CYRILLIC_SMALL_LETTER_EM 0x043c +#define CYRILLIC_SMALL_LETTER_EN 0x043d +#define CYRILLIC_SMALL_LETTER_O 0x043e +#define CYRILLIC_SMALL_LETTER_PE 0x043f +#define CYRILLIC_SMALL_LETTER_ER 0x0440 +#define CYRILLIC_SMALL_LETTER_ES 0x0441 +#define CYRILLIC_SMALL_LETTER_TE 0x0442 +#define CYRILLIC_SMALL_LETTER_U 0x0443 +#define CYRILLIC_SMALL_LETTER_EF 0x0444 +#define CYRILLIC_SMALL_LETTER_HA 0x0445 +#define CYRILLIC_SMALL_LETTER_TSE 0x0446 +#define CYRILLIC_SMALL_LETTER_CHE 0x0447 +#define CYRILLIC_SMALL_LETTER_SHA 0x0448 +#define CYRILLIC_SMALL_LETTER_SHCHA 0x0449 +#define CYRILLIC_SMALL_LETTER_HARD_SIGN 0x044a +#define CYRILLIC_SMALL_LETTER_YERU 0x044b +#define CYRILLIC_SMALL_LETTER_SOFT_SIGN 0x044c +#define CYRILLIC_SMALL_LETTER_E 0x044d +#define CYRILLIC_SMALL_LETTER_YU 0x044e +#define CYRILLIC_SMALL_LETTER_YA 0x044f /* * Процедуры работы с памятью @@ -355,7 +351,7 @@ void besm6_log (const char *fmt, ...); 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); + UNIT *uptr, int32 sw); void besm6_draw_panel (void); /* @@ -377,48 +373,48 @@ t_value besm6_unpack (t_value val, t_value mask); * Разряды главного регистра прерываний (ГРП) * Внешние: */ -#define GRP_PRN1_SYNC 04000000000000000LL /* 48 */ -#define GRP_PRN2_SYNC 02000000000000000LL /* 47 */ -#define GRP_DRUM1_FREE 01000000000000000LL /* 46 */ -#define GRP_DRUM2_FREE 00400000000000000LL /* 45 */ -#define GRP_VNIIEM 00300000000000000LL /* 44-43, placeholder */ -#define GRP_FS1_SYNC 00040000000000000LL /* 42 */ -#define GRP_FS2_SYNC 00020000000000000LL /* 41 */ -#define GRP_TIMER 00010000000000000LL /* 40 */ -#define GRP_PRN1_ZERO 00004000000000000LL /* 39 */ -#define GRP_PRN2_ZERO 00002000000000000LL /* 38 */ -#define GRP_SLAVE 00001000000000000LL /* 37 */ -#define GRP_CHAN3_DONE 00000400000000000LL /* 36 */ -#define GRP_CHAN4_DONE 00000200000000000LL /* 35 */ -#define GRP_CHAN5_DONE 00000100000000000LL /* 34 */ -#define GRP_CHAN6_DONE 00000040000000000LL /* 33 */ -#define GRP_PANEL_REQ 00000020000000000LL /* 32 */ -#define GRP_TTY_START 00000010000000000LL /* 31 */ -#define GRP_IMITATION 00000004000000000LL /* 30 */ -#define GRP_CHAN3_FREE 00000002000000000LL /* 29 */ -#define GRP_CHAN4_FREE 00000001000000000LL /* 28 */ -#define GRP_CHAN5_FREE 00000000400000000LL /* 27 */ -#define GRP_CHAN6_FREE 00000000200000000LL /* 26 */ -#define GRP_CHAN7_FREE 00000000100000000LL /* 25 */ -#define GRP_WATCHDOG 00000000000002000LL /* 11 */ -#define GRP_SLOW_CLK 00000000000001000LL /* 10 */ +#define GRP_PRN1_SYNC 04000000000000000LL /* 48 */ +#define GRP_PRN2_SYNC 02000000000000000LL /* 47 */ +#define GRP_DRUM1_FREE 01000000000000000LL /* 46 */ +#define GRP_DRUM2_FREE 00400000000000000LL /* 45 */ +#define GRP_VNIIEM 00300000000000000LL /* 44-43, placeholder */ +#define GRP_FS1_SYNC 00040000000000000LL /* 42 */ +#define GRP_FS2_SYNC 00020000000000000LL /* 41 */ +#define GRP_TIMER 00010000000000000LL /* 40 */ +#define GRP_PRN1_ZERO 00004000000000000LL /* 39 */ +#define GRP_PRN2_ZERO 00002000000000000LL /* 38 */ +#define GRP_SLAVE 00001000000000000LL /* 37 */ +#define GRP_CHAN3_DONE 00000400000000000LL /* 36 */ +#define GRP_CHAN4_DONE 00000200000000000LL /* 35 */ +#define GRP_CHAN5_DONE 00000100000000000LL /* 34 */ +#define GRP_CHAN6_DONE 00000040000000000LL /* 33 */ +#define GRP_PANEL_REQ 00000020000000000LL /* 32 */ +#define GRP_TTY_START 00000010000000000LL /* 31 */ +#define GRP_IMITATION 00000004000000000LL /* 30 */ +#define GRP_CHAN3_FREE 00000002000000000LL /* 29 */ +#define GRP_CHAN4_FREE 00000001000000000LL /* 28 */ +#define GRP_CHAN5_FREE 00000000400000000LL /* 27 */ +#define GRP_CHAN6_FREE 00000000200000000LL /* 26 */ +#define GRP_CHAN7_FREE 00000000100000000LL /* 25 */ +#define GRP_WATCHDOG 00000000000002000LL /* 11 */ +#define GRP_SLOW_CLK 00000000000001000LL /* 10 */ /* Внутренние: */ -#define GRP_DIVZERO 00000000034000000LL /* 23-21 */ -#define GRP_OVERFLOW 00000000014000000LL /* 22-21 */ -#define GRP_CHECK 00000000004000000LL /* 21 */ -#define GRP_OPRND_PROT 00000000002000000LL /* 20 */ -#define GRP_WATCHPT_W 00000000000200000LL /* 17 */ -#define GRP_WATCHPT_R 00000000000100000LL /* 16 */ -#define GRP_INSN_CHECK 00000000000040000LL /* 15 */ -#define GRP_INSN_PROT 00000000000020000LL /* 14 */ -#define GRP_ILL_INSN 00000000000010000LL /* 13 */ -#define GRP_BREAKPOINT 00000000000004000LL /* 12 */ -#define GRP_PAGE_MASK 00000000000000760LL /* 9-5 */ -#define GRP_RAM_CHECK 00000000000000010LL /* 4 */ -#define GRP_BLOCK_MASK 00000000000000007LL /* 3-1 */ +#define GRP_DIVZERO 00000000034000000LL /* 23-21 */ +#define GRP_OVERFLOW 00000000014000000LL /* 22-21 */ +#define GRP_CHECK 00000000004000000LL /* 21 */ +#define GRP_OPRND_PROT 00000000002000000LL /* 20 */ +#define GRP_WATCHPT_W 00000000000200000LL /* 17 */ +#define GRP_WATCHPT_R 00000000000100000LL /* 16 */ +#define GRP_INSN_CHECK 00000000000040000LL /* 15 */ +#define GRP_INSN_PROT 00000000000020000LL /* 14 */ +#define GRP_ILL_INSN 00000000000010000LL /* 13 */ +#define GRP_BREAKPOINT 00000000000004000LL /* 12 */ +#define GRP_PAGE_MASK 00000000000000760LL /* 9-5 */ +#define GRP_RAM_CHECK 00000000000000010LL /* 4 */ +#define GRP_BLOCK_MASK 00000000000000007LL /* 3-1 */ -#define GRP_SET_BLOCK(x,m) (((x) & ~GRP_BLOCK_MASK) | ((m) & GRP_BLOCK_MASK)) -#define GRP_SET_PAGE(x,m) (((x) & ~GRP_PAGE_MASK) | (((m)<<4) & GRP_PAGE_MASK)) +#define GRP_SET_BLOCK(x,m) (((x) & ~GRP_BLOCK_MASK) | ((m) & GRP_BLOCK_MASK)) +#define GRP_SET_PAGE(x,m) (((x) & ~GRP_PAGE_MASK) | (((m)<<4) & GRP_PAGE_MASK)) /* Номер блока ОЗУ или номер страницы, вызвавших прерывание */ extern uint32 iintr_data; diff --git a/BESM6/besm6_disk.c b/BESM6/besm6_disk.c index 1ff0ed32..b5febae9 100644 --- a/BESM6/besm6_disk.c +++ b/BESM6/besm6_disk.c @@ -32,88 +32,88 @@ /* * Управляющее слово обмена с магнитным диском. */ -#define DISK_BLOCK 0740000000 /* номер блока памяти - 27-24 рр */ -#define DISK_READ_SYSDATA 004000000 /* считывание только служебных слов */ -#define DISK_PAGE_MODE 001000000 /* обмен целой страницей */ -#define DISK_READ 000400000 /* чтение с диска в память */ -#define DISK_PAGE 000370000 /* номер страницы памяти */ -#define DISK_HALFPAGE 000004000 /* выбор половины листа */ -#define DISK_UNIT 000001600 /* номер устройства */ -#define DISK_HALFZONE 000000001 /* выбор половины зоны */ +#define DISK_BLOCK 0740000000 /* номер блока памяти - 27-24 рр */ +#define DISK_READ_SYSDATA 004000000 /* считывание только служебных слов */ +#define DISK_PAGE_MODE 001000000 /* обмен целой страницей */ +#define DISK_READ 000400000 /* чтение с диска в память */ +#define DISK_PAGE 000370000 /* номер страницы памяти */ +#define DISK_HALFPAGE 000004000 /* выбор половины листа */ +#define DISK_UNIT 000001600 /* номер устройства */ +#define DISK_HALFZONE 000000001 /* выбор половины зоны */ /* * "Хороший" статус чтения/записи. * Вычислено по текстам ОС Дубна. * Диспак доволен. */ -#define STATUS_GOOD 014000400 +#define STATUS_GOOD 014000400 /* * Параметры обмена с внешним устройством. */ typedef struct { - int op; /* Условное слово обмена */ - int dev; /* Номер устройства, 0..7 */ - int zone; /* Номер зоны на диске */ - int track; /* Выбор половины зоны на диске */ - int memory; /* Начальный адрес памяти */ - int format; /* Флаг разметки */ - int status; /* Регистр состояния */ - t_value mask_grp; /* Маска готовности для ГРП */ - int mask_fail; /* Маска ошибки обмена */ - t_value *sysdata; /* Буфер системных данных */ + int op; /* Условное слово обмена */ + int dev; /* Номер устройства, 0..7 */ + int zone; /* Номер зоны на диске */ + int track; /* Выбор половины зоны на диске */ + int memory; /* Начальный адрес памяти */ + int format; /* Флаг разметки */ + int status; /* Регистр состояния */ + t_value mask_grp; /* Маска готовности для ГРП */ + int mask_fail; /* Маска ошибки обмена */ + t_value *sysdata; /* Буфер системных данных */ } KMD; -static KMD controller [2]; /* Две стойки КМД */ -int disk_fail; /* Маска ошибок по направлениям */ +static KMD controller [2]; /* Две стойки КМД */ +int disk_fail; /* Маска ошибок по направлениям */ t_stat disk_event (UNIT *u); /* * DISK data structures * - * disk_dev DISK device descriptor - * disk_unit DISK unit descriptor - * disk_reg DISK register list + * disk_dev DISK device descriptor + * disk_unit DISK unit descriptor + * disk_reg DISK register list */ UNIT disk_unit [16] = { - { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, - { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, - { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, - { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, - { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, - { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, - { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, - { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, - { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, - { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, - { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, - { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, - { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, - { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, - { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, - { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, + { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, + { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, + { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, + { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, + { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, + { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, + { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, + { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, + { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, + { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, + { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, + { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, + { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, + { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, + { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, + { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, }; REG disk_reg[] = { -{ "КУС_0", &controller[0].op, 8, 24, 0, 1 }, -{ "УСТР_0", &controller[0].dev, 8, 3, 0, 1 }, -{ "ЗОНА_0", &controller[0].zone, 8, 10, 0, 1 }, -{ "ДОРОЖКА_0", &controller[0].track, 8, 2, 0, 1 }, -{ "МОЗУ_0", &controller[0].memory, 8, 20, 0, 1 }, -{ "РС_0", &controller[0].status, 8, 24, 0, 1 }, -{ "КУС_1", &controller[1].op, 8, 24, 0, 1 }, -{ "УСТР_1", &controller[1].dev, 8, 3, 0, 1 }, -{ "ЗОНА_1", &controller[1].zone, 8, 10, 0, 1 }, -{ "ДОРОЖКА_1", &controller[1].track, 8, 2, 0, 1 }, -{ "МОЗУ_1", &controller[1].memory, 8, 20, 0, 1 }, -{ "РС_1", &controller[1].status, 8, 24, 0, 1 }, -{ "ОШ", &disk_fail, 8, 6, 0, 1 }, -{ 0 } + { "КУС_0", &controller[0].op, 8, 24, 0, 1 }, + { "УСТР_0", &controller[0].dev, 8, 3, 0, 1 }, + { "ЗОНА_0", &controller[0].zone, 8, 10, 0, 1 }, + { "ДОРОЖКА_0", &controller[0].track, 8, 2, 0, 1 }, + { "МОЗУ_0", &controller[0].memory, 8, 20, 0, 1 }, + { "РС_0", &controller[0].status, 8, 24, 0, 1 }, + { "КУС_1", &controller[1].op, 8, 24, 0, 1 }, + { "УСТР_1", &controller[1].dev, 8, 3, 0, 1 }, + { "ЗОНА_1", &controller[1].zone, 8, 10, 0, 1 }, + { "ДОРОЖКА_1", &controller[1].track, 8, 2, 0, 1 }, + { "МОЗУ_1", &controller[1].memory, 8, 20, 0, 1 }, + { "РС_1", &controller[1].status, 8, 24, 0, 1 }, + { "ОШ", &disk_fail, 8, 6, 0, 1 }, + { 0 } }; MTAB disk_mod[] = { - { 0 } + { 0 } }; t_stat disk_reset (DEVICE *dptr); @@ -121,10 +121,10 @@ t_stat disk_attach (UNIT *uptr, char *cptr); t_stat disk_detach (UNIT *uptr); DEVICE disk_dev = { - "DISK", disk_unit, disk_reg, disk_mod, - 16, 8, 21, 1, 8, 50, - NULL, NULL, &disk_reset, NULL, &disk_attach, &disk_detach, - NULL, DEV_DISABLE | DEV_DEBUG + "DISK", disk_unit, disk_reg, disk_mod, + 16, 8, 21, 1, 8, 50, + NULL, NULL, &disk_reset, NULL, &disk_attach, &disk_detach, + NULL, DEV_DISABLE | DEV_DEBUG }; /* @@ -132,10 +132,10 @@ DEVICE disk_dev = { */ static KMD *unit_to_ctlr (UNIT *u) { - if (u < &disk_unit[8]) - return &controller[0]; - else - return &controller[1]; + if (u < &disk_unit[8]) + return &controller[0]; + else + return &controller[1]; } /* @@ -143,45 +143,45 @@ static KMD *unit_to_ctlr (UNIT *u) */ t_stat disk_reset (DEVICE *dptr) { - int i; + int i; - memset (&controller, 0, sizeof (controller)); - controller[0].sysdata = &memory [030]; - controller[1].sysdata = &memory [040]; - controller[0].mask_grp = GRP_CHAN3_FREE; - controller[1].mask_grp = GRP_CHAN4_FREE; - controller[0].mask_fail = 020; - controller[1].mask_fail = 010; - for (i=0; i<16; ++i) - sim_cancel (&disk_unit[i]); - return SCPE_OK; + memset (&controller, 0, sizeof (controller)); + controller[0].sysdata = &memory [030]; + controller[1].sysdata = &memory [040]; + controller[0].mask_grp = GRP_CHAN3_FREE; + controller[1].mask_grp = GRP_CHAN4_FREE; + controller[0].mask_fail = 020; + controller[1].mask_fail = 010; + for (i=0; i<16; ++i) + sim_cancel (&disk_unit[i]); + return SCPE_OK; } t_stat disk_attach (UNIT *u, char *cptr) { - t_stat s; + t_stat s; - s = attach_unit (u, cptr); - if (s != SCPE_OK) - return s; - return SCPE_OK; + s = attach_unit (u, cptr); + if (s != SCPE_OK) + return s; + return SCPE_OK; } t_stat disk_detach (UNIT *u) { - /* TODO: сброс бита ГРП готовности направления при отключении последнего диска. */ - return detach_unit (u); + /* TODO: сброс бита ГРП готовности направления при отключении последнего диска. */ + return detach_unit (u); } t_value spread (t_value val) { - int i, j; - t_value res = 0; + int i, j; + t_value res = 0; - for (i = 0; i < 5; i++) for (j = 0; j < 9; j++) - if (val & (1LL<<(i+j*5))) - res |= 1LL << (i*9+j); - return res & BITS48; + for (i = 0; i < 5; i++) for (j = 0; j < 9; j++) + if (val & (1LL<<(i+j*5))) + res |= 1LL << (i*9+j); + return res & BITS48; } /* @@ -189,21 +189,21 @@ t_value spread (t_value val) */ static void log_data (t_value *data, int nwords) { - int i; - t_value val; + int i; + t_value val; - for (i=0; i> 36) & 07777, - (int) (val >> 24) & 07777, - (int) (val >> 12) & 07777, - (int) val & 07777); - if ((i & 3) == 3) - fprintf (sim_log, "\n"); - } - if ((i & 3) != 0) - fprintf (sim_log, "\n"); + for (i=0; i> 36) & 07777, + (int) (val >> 24) & 07777, + (int) (val >> 12) & 07777, + (int) val & 07777); + if ((i & 3) == 3) + fprintf (sim_log, "\n"); + } + if ((i & 3) != 0) + fprintf (sim_log, "\n"); } /* @@ -211,14 +211,14 @@ static void log_data (t_value *data, int nwords) */ static unsigned sum_with_right_carry (unsigned a, unsigned b) { - unsigned c; + unsigned c; - while (b) { - c = a & b; - a ^= b; - b = c >> 1; - } - return a; + while (b) { + c = a & b; + a ^= b; + b = c >> 1; + } + return a; } /* @@ -226,32 +226,32 @@ static unsigned sum_with_right_carry (unsigned a, unsigned b) */ void disk_write (UNIT *u) { - KMD *c = unit_to_ctlr (u); + KMD *c = unit_to_ctlr (u); - if (disk_dev.dctrl) - besm6_debug ("::: запись МД %o зона %04o память %05o-%05o", - c->dev, c->zone, c->memory, c->memory + 1023); - fseek (u->fileref, ZONE_SIZE * c->zone * 8, SEEK_SET); - sim_fwrite (c->sysdata, 8, 8, u->fileref); - sim_fwrite (&memory [c->memory], 8, 1024, u->fileref); - if (ferror (u->fileref)) - longjmp (cpu_halt, SCPE_IOERR); + if (disk_dev.dctrl) + besm6_debug ("::: запись МД %o зона %04o память %05o-%05o", + c->dev, c->zone, c->memory, c->memory + 1023); + fseek (u->fileref, ZONE_SIZE * c->zone * 8, SEEK_SET); + sim_fwrite (c->sysdata, 8, 8, u->fileref); + sim_fwrite (&memory [c->memory], 8, 1024, u->fileref); + if (ferror (u->fileref)) + longjmp (cpu_halt, SCPE_IOERR); } void disk_write_track (UNIT *u) { - KMD *c = unit_to_ctlr (u); + KMD *c = unit_to_ctlr (u); - if (disk_dev.dctrl) - besm6_debug ("::: запись МД %o полузона %04o.%d память %05o-%05o", - c->dev, c->zone, c->track, c->memory, c->memory + 511); - fseek (u->fileref, (ZONE_SIZE*c->zone + 4*c->track) * 8, SEEK_SET); - sim_fwrite (c->sysdata + 4*c->track, 8, 4, u->fileref); - fseek (u->fileref, (8 + ZONE_SIZE*c->zone + 512*c->track) * 8, - SEEK_SET); - sim_fwrite (&memory [c->memory], 8, 512, u->fileref); - if (ferror (u->fileref)) - longjmp (cpu_halt, SCPE_IOERR); + if (disk_dev.dctrl) + besm6_debug ("::: запись МД %o полузона %04o.%d память %05o-%05o", + c->dev, c->zone, c->track, c->memory, c->memory + 511); + fseek (u->fileref, (ZONE_SIZE*c->zone + 4*c->track) * 8, SEEK_SET); + sim_fwrite (c->sysdata + 4*c->track, 8, 4, u->fileref); + fseek (u->fileref, (8 + ZONE_SIZE*c->zone + 512*c->track) * 8, + SEEK_SET); + sim_fwrite (&memory [c->memory], 8, 512, u->fileref); + if (ferror (u->fileref)) + longjmp (cpu_halt, SCPE_IOERR); } /* @@ -259,35 +259,35 @@ void disk_write_track (UNIT *u) */ void disk_format (UNIT *u) { - KMD *c = unit_to_ctlr (u); - t_value fmtbuf[5], *ptr; - int i; + KMD *c = unit_to_ctlr (u); + t_value fmtbuf[5], *ptr; + int i; - /* По сути, эмулятору ничего делать не надо. */ - if (! disk_dev.dctrl) - return; + /* По сути, эмулятору ничего делать не надо. */ + if (! disk_dev.dctrl) + return; - /* Находим начало записываемого заголовка. */ - ptr = &memory [c->memory]; - while ((*ptr & BITS48) == 0) - ptr++; + /* Находим начало записываемого заголовка. */ + ptr = &memory [c->memory]; + while ((*ptr & BITS48) == 0) + ptr++; - /* Декодируем из гребенки в нормальный вид. */ - for (i = 0; i < 5; i++) - fmtbuf[i] = spread (ptr[i]); + /* Декодируем из гребенки в нормальный вид. */ + for (i = 0; i < 5; i++) + fmtbuf[i] = spread (ptr[i]); - /* При первой попытке разметки адресный маркер начинается в старшем 5-разрядном слоге, - * пропускаем первый слог. */ - for (i=0; i<4; i++) - fmtbuf[i] = ((fmtbuf[i] & BITS48) << 5) | - ((fmtbuf[i+1] >> 40) & BITS(5)); + /* При первой попытке разметки адресный маркер начинается в старшем 5-разрядном слоге, + * пропускаем первый слог. */ + for (i=0; i<4; i++) + fmtbuf[i] = ((fmtbuf[i] & BITS48) << 5) | + ((fmtbuf[i+1] >> 40) & BITS(5)); - /* Печатаем идентификатор, адрес и контрольную сумму адреса. */ - besm6_debug ("::: формат МД %o полузона %04o.%d память %05o и-а-кса %010o %010o", - c->dev, c->zone, c->track, c->memory, - (int) (fmtbuf[0] >> 8 & BITS(30)), - (int) (fmtbuf[2] >> 14 & BITS(30))); - /* log_data (fmtbuf, 4); */ + /* Печатаем идентификатор, адрес и контрольную сумму адреса. */ + besm6_debug ("::: формат МД %o полузона %04o.%d память %05o и-а-кса %010o %010o", + c->dev, c->zone, c->track, c->memory, + (int) (fmtbuf[0] >> 8 & BITS(30)), + (int) (fmtbuf[2] >> 14 & BITS(30))); + /* log_data (fmtbuf, 4); */ } /* @@ -295,66 +295,66 @@ void disk_format (UNIT *u) */ void disk_read (UNIT *u) { - KMD *c = unit_to_ctlr (u); + KMD *c = unit_to_ctlr (u); - if (disk_dev.dctrl) - besm6_debug ((c->op & DISK_READ_SYSDATA) ? - "::: чтение МД %o зона %04o служебные слова" : - "::: чтение МД %o зона %04o память %05o-%05o", - c->dev, c->zone, c->memory, c->memory + 1023); - fseek (u->fileref, ZONE_SIZE * c->zone * 8, SEEK_SET); - if (sim_fread (c->sysdata, 8, 8, u->fileref) != 8) { - /* Чтение неинициализированного диска */ - disk_fail |= c->mask_fail; - return; - } - if (! (c->op & DISK_READ_SYSDATA) && - sim_fread (&memory [c->memory], 8, 1024, u->fileref) != 1024) { - /* Чтение неинициализированного диска */ - disk_fail |= c->mask_fail; - return; - } - if (ferror (u->fileref)) - longjmp (cpu_halt, SCPE_IOERR); + if (disk_dev.dctrl) + besm6_debug ((c->op & DISK_READ_SYSDATA) ? + "::: чтение МД %o зона %04o служебные слова" : + "::: чтение МД %o зона %04o память %05o-%05o", + c->dev, c->zone, c->memory, c->memory + 1023); + fseek (u->fileref, ZONE_SIZE * c->zone * 8, SEEK_SET); + if (sim_fread (c->sysdata, 8, 8, u->fileref) != 8) { + /* Чтение неинициализированного диска */ + disk_fail |= c->mask_fail; + return; + } + if (! (c->op & DISK_READ_SYSDATA) && + sim_fread (&memory [c->memory], 8, 1024, u->fileref) != 1024) { + /* Чтение неинициализированного диска */ + disk_fail |= c->mask_fail; + return; + } + if (ferror (u->fileref)) + longjmp (cpu_halt, SCPE_IOERR); } t_value collect (t_value val) { - int i, j; - t_value res = 0; + int i, j; + t_value res = 0; - for (i = 0; i < 5; i++) for (j = 0; j < 9; j++) - if (val & (1LL<<(i*9+j))) - res |= 1LL << (i+j*5); - return res & BITS48; + for (i = 0; i < 5; i++) for (j = 0; j < 9; j++) + if (val & (1LL<<(i*9+j))) + res |= 1LL << (i+j*5); + return res & BITS48; } void disk_read_track (UNIT *u) { - KMD *c = unit_to_ctlr (u); + KMD *c = unit_to_ctlr (u); - if (disk_dev.dctrl) - besm6_debug ((c->op & DISK_READ_SYSDATA) ? - "::: чтение МД %o полузона %04o.%d служебные слова" : - "::: чтение МД %o полузона %04o.%d память %05o-%05o", - c->dev, c->zone, c->track, c->memory, c->memory + 511); - fseek (u->fileref, (ZONE_SIZE*c->zone + 4*c->track) * 8, SEEK_SET); - if (sim_fread (c->sysdata + 4*c->track, 8, 4, u->fileref) != 4) { - /* Чтение неинициализированного диска */ - disk_fail |= c->mask_fail; - return; - } - if (! (c->op & DISK_READ_SYSDATA)) { - fseek (u->fileref, (8 + ZONE_SIZE*c->zone + 512*c->track) * 8, - SEEK_SET); - if (sim_fread (&memory [c->memory], 8, 512, u->fileref) != 512) { - /* Чтение неинициализированного диска */ - disk_fail |= c->mask_fail; - return; - } - } - if (ferror (u->fileref)) - longjmp (cpu_halt, SCPE_IOERR); + if (disk_dev.dctrl) + besm6_debug ((c->op & DISK_READ_SYSDATA) ? + "::: чтение МД %o полузона %04o.%d служебные слова" : + "::: чтение МД %o полузона %04o.%d память %05o-%05o", + c->dev, c->zone, c->track, c->memory, c->memory + 511); + fseek (u->fileref, (ZONE_SIZE*c->zone + 4*c->track) * 8, SEEK_SET); + if (sim_fread (c->sysdata + 4*c->track, 8, 4, u->fileref) != 4) { + /* Чтение неинициализированного диска */ + disk_fail |= c->mask_fail; + return; + } + if (! (c->op & DISK_READ_SYSDATA)) { + fseek (u->fileref, (8 + ZONE_SIZE*c->zone + 512*c->track) * 8, + SEEK_SET); + if (sim_fread (&memory [c->memory], 8, 512, u->fileref) != 512) { + /* Чтение неинициализированного диска */ + disk_fail |= c->mask_fail; + return; + } + } + if (ferror (u->fileref)) + longjmp (cpu_halt, SCPE_IOERR); } /* @@ -362,34 +362,34 @@ void disk_read_track (UNIT *u) */ void disk_read_header (UNIT *u) { - KMD *c = unit_to_ctlr (u); - t_value *sysdata = c->sysdata + 4*c->track; - int iaksa, i, cyl, head; + KMD *c = unit_to_ctlr (u); + t_value *sysdata = c->sysdata + 4*c->track; + int iaksa, i, cyl, head; - /* Адрес: номер цилиндра и головки. */ - head = (c->zone << 1) + c->track; - cyl = head / 10; - head %= 10; - iaksa = (cyl << 20) | (head << 16); + /* Адрес: номер цилиндра и головки. */ + head = (c->zone << 1) + c->track; + cyl = head / 10; + head %= 10; + iaksa = (cyl << 20) | (head << 16); - /* Идентификатор дорожки замены. */ - if (c->zone >= 01750) - iaksa |= BBIT(30); + /* Идентификатор дорожки замены. */ + if (c->zone >= 01750) + iaksa |= BBIT(30); - /* Контрольная сумма адреса с переносом вправо. */ - iaksa |= BITS(12) & ~sum_with_right_carry (iaksa >> 12, iaksa >> 24); + /* Контрольная сумма адреса с переносом вправо. */ + iaksa |= BITS(12) & ~sum_with_right_carry (iaksa >> 12, iaksa >> 24); - /* Амиакса, 42 нуля, амиакса, много единиц. */ - sysdata[0] = 07404000000000000LL | (t_value) iaksa << 8; - sysdata[1] = 03740LL; - sysdata[2] = 00400000000037777LL | (t_value) iaksa << 14; - sysdata[3] = BITS48; - if (disk_dev.dctrl) - log_data (sysdata, 4); + /* Амиакса, 42 нуля, амиакса, много единиц. */ + sysdata[0] = 07404000000000000LL | (t_value) iaksa << 8; + sysdata[1] = 03740LL; + sysdata[2] = 00400000000037777LL | (t_value) iaksa << 14; + sysdata[3] = BITS48; + if (disk_dev.dctrl) + log_data (sysdata, 4); - /* Кодируем гребенку. */ - for (i=0; i<4; i++) - sysdata[i] = SET_CONVOL (collect (sysdata[i]), CONVOL_NUMBER); + /* Кодируем гребенку. */ + for (i=0; i<4; i++) + sysdata[i] = SET_CONVOL (collect (sysdata[i]), CONVOL_NUMBER); } /* @@ -398,26 +398,26 @@ void disk_read_header (UNIT *u) */ void disk_io (int ctlr, uint32 cmd) { - KMD *c = &controller [ctlr]; + KMD *c = &controller [ctlr]; - c->op = cmd; - c->format = 0; - if (c->op & DISK_PAGE_MODE) { - /* Обмен страницей */ - c->memory = (cmd & DISK_PAGE) >> 2 | (cmd & DISK_BLOCK) >> 8; - } else { - /* Обмен половиной страницы (дорожкой) */ - c->memory = (cmd & (DISK_PAGE | DISK_HALFPAGE)) >> 2 | (cmd & DISK_BLOCK) >> 8; - } + c->op = cmd; + c->format = 0; + if (c->op & DISK_PAGE_MODE) { + /* Обмен страницей */ + c->memory = (cmd & DISK_PAGE) >> 2 | (cmd & DISK_BLOCK) >> 8; + } else { + /* Обмен половиной страницы (дорожкой) */ + c->memory = (cmd & (DISK_PAGE | DISK_HALFPAGE)) >> 2 | (cmd & DISK_BLOCK) >> 8; + } #if 0 - if (disk_dev.dctrl) - besm6_debug ("::: КМД %c: задание на %s %08o", ctlr + '3', - (c->op & DISK_READ) ? "чтение" : "запись", cmd); + if (disk_dev.dctrl) + besm6_debug ("::: КМД %c: задание на %s %08o", ctlr + '3', + (c->op & DISK_READ) ? "чтение" : "запись", cmd); #endif - disk_fail &= ~c->mask_fail; + disk_fail &= ~c->mask_fail; - /* Гасим главный регистр прерываний. */ - GRP &= ~c->mask_grp; + /* Гасим главный регистр прерываний. */ + GRP &= ~c->mask_grp; } /* @@ -425,188 +425,188 @@ void disk_io (int ctlr, uint32 cmd) */ void disk_ctl (int ctlr, uint32 cmd) { - KMD *c = &controller [ctlr]; - UNIT *u = &disk_unit [c->dev]; + KMD *c = &controller [ctlr]; + UNIT *u = &disk_unit [c->dev]; - if (cmd & BBIT(12)) { - /* Выдача в КМД адреса дорожки. - * Здесь же выполняем обмен с диском. - * Номер дисковода к этому моменту уже известен. */ - if ((disk_dev.flags & DEV_DIS) || ! (u->flags & UNIT_ATT)) { - /* Device not attached. */ - disk_fail |= c->mask_fail; - return; - } - c->zone = (cmd >> 1) & BITS(10); - c->track = cmd & 1; + if (cmd & BBIT(12)) { + /* Выдача в КМД адреса дорожки. + * Здесь же выполняем обмен с диском. + * Номер дисковода к этому моменту уже известен. */ + if ((disk_dev.flags & DEV_DIS) || ! (u->flags & UNIT_ATT)) { + /* Device not attached. */ + disk_fail |= c->mask_fail; + return; + } + c->zone = (cmd >> 1) & BITS(10); + c->track = cmd & 1; #if 0 - if (disk_dev.dctrl) - besm6_debug ("::: КМД %c: выдача адреса дорожки %04o.%d", - ctlr + '3', c->zone, c->track); + if (disk_dev.dctrl) + besm6_debug ("::: КМД %c: выдача адреса дорожки %04o.%d", + ctlr + '3', c->zone, c->track); #endif - disk_fail &= ~c->mask_fail; - if (c->op & DISK_READ) { - if (c->op & DISK_PAGE_MODE) - disk_read (u); - else - disk_read_track (u); - } else { - if (u->flags & UNIT_RO) { - /* Read only. */ - /*longjmp (cpu_halt, SCPE_RO);*/ - disk_fail |= c->mask_fail; - return; - } - if (c->format) - disk_format (u); - else if (c->op & DISK_PAGE_MODE) - disk_write (u); - else - disk_write_track (u); - } + disk_fail &= ~c->mask_fail; + if (c->op & DISK_READ) { + if (c->op & DISK_PAGE_MODE) + disk_read (u); + else + disk_read_track (u); + } else { + if (u->flags & UNIT_RO) { + /* Read only. */ + /*longjmp (cpu_halt, SCPE_RO);*/ + disk_fail |= c->mask_fail; + return; + } + if (c->format) + disk_format (u); + else if (c->op & DISK_PAGE_MODE) + disk_write (u); + else + disk_write_track (u); + } - /* Ждём события от устройства. */ - sim_activate (u, 20*USEC); /* Ускорим для отладки. */ + /* Ждём события от устройства. */ + sim_activate (u, 20*USEC); /* Ускорим для отладки. */ - } else if (cmd & BBIT(11)) { - /* Выбора номера устройства и занесение в регистр маски КМД. - * Бит 8 - устройство 0, бит 7 - устройство 1, ... бит 1 - устройство 7. - * Также установлен бит 9 - что он означает? */ - if (cmd & BBIT(8)) c->dev = 7; - else if (cmd & BBIT(7)) c->dev = 6; - else if (cmd & BBIT(6)) c->dev = 5; - else if (cmd & BBIT(5)) c->dev = 4; - else if (cmd & BBIT(4)) c->dev = 3; - else if (cmd & BBIT(3)) c->dev = 2; - else if (cmd & BBIT(2)) c->dev = 1; - else if (cmd & BBIT(1)) c->dev = 0; - else { - /* Неверная маска выбора устройства. */ - c->dev = -1; - return; - } - c->dev += ctlr << 3; - u = &disk_unit[c->dev]; + } else if (cmd & BBIT(11)) { + /* Выбора номера устройства и занесение в регистр маски КМД. + * Бит 8 - устройство 0, бит 7 - устройство 1, ... бит 1 - устройство 7. + * Также установлен бит 9 - что он означает? */ + if (cmd & BBIT(8)) c->dev = 7; + else if (cmd & BBIT(7)) c->dev = 6; + else if (cmd & BBIT(6)) c->dev = 5; + else if (cmd & BBIT(5)) c->dev = 4; + else if (cmd & BBIT(4)) c->dev = 3; + else if (cmd & BBIT(3)) c->dev = 2; + else if (cmd & BBIT(2)) c->dev = 1; + else if (cmd & BBIT(1)) c->dev = 0; + else { + /* Неверная маска выбора устройства. */ + c->dev = -1; + return; + } + c->dev += ctlr << 3; + u = &disk_unit[c->dev]; #if 0 - if (disk_dev.dctrl) - besm6_debug ("::: КМД %c: выбор устройства %d", - ctlr + '3', c->dev); + if (disk_dev.dctrl) + besm6_debug ("::: КМД %c: выбор устройства %d", + ctlr + '3', c->dev); #endif - if ((disk_dev.flags & DEV_DIS) || ! (u->flags & UNIT_ATT)) { - /* Device not attached. */ - disk_fail |= c->mask_fail; - GRP &= ~c->mask_grp; - } - GRP |= c->mask_grp; + if ((disk_dev.flags & DEV_DIS) || ! (u->flags & UNIT_ATT)) { + /* Device not attached. */ + disk_fail |= c->mask_fail; + GRP &= ~c->mask_grp; + } + GRP |= c->mask_grp; - } else if (cmd & BBIT(9)) { - /* Проверка прерывания от КМД? */ + } else if (cmd & BBIT(9)) { + /* Проверка прерывания от КМД? */ #if 0 - if (disk_dev.dctrl) - besm6_debug ("::: КМД %c: проверка готовности", - ctlr + '3'); + if (disk_dev.dctrl) + besm6_debug ("::: КМД %c: проверка готовности", + ctlr + '3'); #endif - GRP |= c->mask_grp; + GRP |= c->mask_grp; - } else { - /* Команда, выдаваемая в КМД. */ - switch (cmd & 077) { - case 000: /* диспак выдаёт эту команду один раз в начале загрузки */ + } else { + /* Команда, выдаваемая в КМД. */ + switch (cmd & 077) { + case 000: /* диспак выдаёт эту команду один раз в начале загрузки */ #if 0 - if (disk_dev.dctrl) - besm6_debug ("::: КМД %c: недокументированная команда 00", - ctlr + '3'); + if (disk_dev.dctrl) + besm6_debug ("::: КМД %c: недокументированная команда 00", + ctlr + '3'); #endif - break; - case 001: /* сброс на 0 цилиндр */ + break; + case 001: /* сброс на 0 цилиндр */ #if 0 - if (disk_dev.dctrl) - besm6_debug ("::: КМД %c: сброс на 0 цилиндр", - ctlr + '3'); + if (disk_dev.dctrl) + besm6_debug ("::: КМД %c: сброс на 0 цилиндр", + ctlr + '3'); #endif - break; - case 002: /* подвод */ - if (disk_dev.dctrl) - besm6_debug ("::: КМД %c: подвод", ctlr + '3'); - break; - case 003: /* чтение (НСМД-МОЗУ) */ - case 043: /* резервной дорожки */ + break; + case 002: /* подвод */ + if (disk_dev.dctrl) + besm6_debug ("::: КМД %c: подвод", ctlr + '3'); + break; + case 003: /* чтение (НСМД-МОЗУ) */ + case 043: /* резервной дорожки */ #if 0 - if (disk_dev.dctrl) - besm6_debug ("::: КМД %c: чтение", ctlr + '3'); + if (disk_dev.dctrl) + besm6_debug ("::: КМД %c: чтение", ctlr + '3'); #endif - break; - case 004: /* запись (МОЗУ-НСМД) */ - case 044: /* резервной дорожки */ + break; + case 004: /* запись (МОЗУ-НСМД) */ + case 044: /* резервной дорожки */ #if 0 - if (disk_dev.dctrl) - besm6_debug ("::: КМД %c: запись", ctlr + '3'); + if (disk_dev.dctrl) + besm6_debug ("::: КМД %c: запись", ctlr + '3'); #endif - break; - case 005: /* разметка */ - c->format = 1; - break; - case 006: /* сравнение кодов (МОЗУ-НСМД) */ + break; + case 005: /* разметка */ + c->format = 1; + break; + case 006: /* сравнение кодов (МОЗУ-НСМД) */ #if 0 - if (disk_dev.dctrl) - besm6_debug ("::: КМД %c: сравнение кодов", ctlr + '3'); + if (disk_dev.dctrl) + besm6_debug ("::: КМД %c: сравнение кодов", ctlr + '3'); #endif - break; - case 007: /* чтение заголовка */ - case 047: /* резервной дорожки */ - if (disk_dev.dctrl) - besm6_debug ("::: КМД %c: чтение %s заголовка", ctlr + '3', - cmd & 040 ? "резервного" : ""); - disk_fail &= ~c->mask_fail; - disk_read_header (u); + break; + case 007: /* чтение заголовка */ + case 047: /* резервной дорожки */ + if (disk_dev.dctrl) + besm6_debug ("::: КМД %c: чтение %s заголовка", ctlr + '3', + cmd & 040 ? "резервного" : ""); + disk_fail &= ~c->mask_fail; + disk_read_header (u); - /* Ждём события от устройства. */ - sim_activate (u, 20*USEC); /* Ускорим для отладки. */ - break; - case 010: /* гашение PC */ + /* Ждём события от устройства. */ + sim_activate (u, 20*USEC); /* Ускорим для отладки. */ + break; + case 010: /* гашение PC */ #if 0 - if (disk_dev.dctrl) - besm6_debug ("::: КМД %c: гашение регистра состояния", - ctlr + '3'); + if (disk_dev.dctrl) + besm6_debug ("::: КМД %c: гашение регистра состояния", + ctlr + '3'); #endif - c->status = 0; - break; - case 011: /* опрос 1÷12 разрядов PC */ + c->status = 0; + break; + case 011: /* опрос 1÷12 разрядов PC */ #if 0 - if (disk_dev.dctrl) - besm6_debug ("::: КМД %c: опрос младших разрядов состояния", - ctlr + '3'); + if (disk_dev.dctrl) + besm6_debug ("::: КМД %c: опрос младших разрядов состояния", + ctlr + '3'); #endif - if (disk_unit[c->dev].flags & UNIT_ATT) - c->status = STATUS_GOOD & BITS(12); - else - c->status = 0; - break; - case 031: /* опрос 13÷24 разрядов РС */ + if (disk_unit[c->dev].flags & UNIT_ATT) + c->status = STATUS_GOOD & BITS(12); + else + c->status = 0; + break; + case 031: /* опрос 13÷24 разрядов РС */ #if 0 - if (disk_dev.dctrl) - besm6_debug ("::: КМД %c: опрос старших разрядов состояния", - ctlr + '3'); + if (disk_dev.dctrl) + besm6_debug ("::: КМД %c: опрос старших разрядов состояния", + ctlr + '3'); #endif - if (disk_unit[c->dev].flags & UNIT_ATT) - c->status = (STATUS_GOOD >> 12) & BITS(12); - else - c->status = 0; - break; - case 050: /* освобождение НМД */ + if (disk_unit[c->dev].flags & UNIT_ATT) + c->status = (STATUS_GOOD >> 12) & BITS(12); + else + c->status = 0; + break; + case 050: /* освобождение НМД */ #if 0 - if (disk_dev.dctrl) - besm6_debug ("::: КМД %c: освобождение накопителя", - ctlr + '3'); + if (disk_dev.dctrl) + besm6_debug ("::: КМД %c: освобождение накопителя", + ctlr + '3'); #endif - break; - default: - besm6_debug ("::: КМД %c: неизвестная команда %02o", - ctlr + '3', cmd & 077); - GRP |= c->mask_grp; /* чтобы не зависало */ - break; - } - } + break; + default: + besm6_debug ("::: КМД %c: неизвестная команда %02o", + ctlr + '3', cmd & 077); + GRP |= c->mask_grp; /* чтобы не зависало */ + break; + } + } } /* @@ -614,13 +614,13 @@ void disk_ctl (int ctlr, uint32 cmd) */ int disk_state (int ctlr) { - KMD *c = &controller [ctlr]; + KMD *c = &controller [ctlr]; #if 0 - if (disk_dev.dctrl) - besm6_debug ("::: КМД %c: опрос состояния = %04o", - ctlr + '3', c->status); + if (disk_dev.dctrl) + besm6_debug ("::: КМД %c: опрос состояния = %04o", + ctlr + '3', c->status); #endif - return c->status; + return c->status; } /* @@ -629,10 +629,10 @@ int disk_state (int ctlr) */ t_stat disk_event (UNIT *u) { - KMD *c = unit_to_ctlr (u); + KMD *c = unit_to_ctlr (u); - GRP |= c->mask_grp; - return SCPE_OK; + GRP |= c->mask_grp; + return SCPE_OK; } /* @@ -641,8 +641,8 @@ t_stat disk_event (UNIT *u) int disk_errors () { #if 0 - if (disk_dev.dctrl) - besm6_debug ("::: КМД: опрос шкалы ошибок = %04o", disk_fail); + if (disk_dev.dctrl) + besm6_debug ("::: КМД: опрос шкалы ошибок = %04o", disk_fail); #endif - return disk_fail; + return disk_fail; } diff --git a/BESM6/besm6_drum.c b/BESM6/besm6_drum.c index 6dedcb5a..e29df468 100644 --- a/BESM6/besm6_drum.c +++ b/BESM6/besm6_drum.c @@ -31,54 +31,54 @@ /* * Управляющее слово обмена с магнитным барабаном. */ -#define DRUM_READ_OVERLAY 020000000 /* считывание с наложением */ -#define DRUM_PARITY_FLAG 010000000 /* блокировка считывания слов с неверной - * чётностью или запись с неверной чётностью */ -#define DRUM_READ_SYSDATA 004000000 /* считывание только служебных слов */ -#define DRUM_PAGE_MODE 001000000 /* обмен целой страницей */ -#define DRUM_READ 000400000 /* чтение с барабана в память */ -#define DRUM_PAGE 000370000 /* номер страницы памяти */ -#define DRUM_BLOCK 0740000000 /* номер блока памяти - 27-24 рр */ -#define DRUM_PARAGRAF 000006000 /* номер абзаца */ -#define DRUM_UNIT 000001600 /* номер барабана */ -#define DRUM_CYLINDER 000000174 /* номер тракта на барабане */ -#define DRUM_SECTOR 000000003 /* номер сектора */ +#define DRUM_READ_OVERLAY 020000000 /* считывание с наложением */ +#define DRUM_PARITY_FLAG 010000000 /* блокировка считывания слов с неверной + * чётностью или запись с неверной чётностью */ +#define DRUM_READ_SYSDATA 004000000 /* считывание только служебных слов */ +#define DRUM_PAGE_MODE 001000000 /* обмен целой страницей */ +#define DRUM_READ 000400000 /* чтение с барабана в память */ +#define DRUM_PAGE 000370000 /* номер страницы памяти */ +#define DRUM_BLOCK 0740000000 /* номер блока памяти - 27-24 рр */ +#define DRUM_PARAGRAF 000006000 /* номер абзаца */ +#define DRUM_UNIT 000001600 /* номер барабана */ +#define DRUM_CYLINDER 000000174 /* номер тракта на барабане */ +#define DRUM_SECTOR 000000003 /* номер сектора */ /* * Параметры обмена с внешним устройством. */ -int drum_op; /* Условное слово обмена */ -int drum_zone; /* Номер зоны на барабане */ -int drum_sector; /* Начальный номер сектора на барабане */ -int drum_memory; /* Начальный адрес памяти */ -int drum_nwords; /* Количество слов обмена */ -int drum_fail; /* Маска ошибок по направлениям */ +int drum_op; /* Условное слово обмена */ +int drum_zone; /* Номер зоны на барабане */ +int drum_sector; /* Начальный номер сектора на барабане */ +int drum_memory; /* Начальный адрес памяти */ +int drum_nwords; /* Количество слов обмена */ +int drum_fail; /* Маска ошибок по направлениям */ t_stat drum_event (UNIT *u); /* * DRUM data structures * - * drum_dev DRUM device descriptor - * drum_unit DRUM unit descriptor - * drum_reg DRUM register list + * drum_dev DRUM device descriptor + * drum_unit DRUM unit descriptor + * drum_reg DRUM register list */ UNIT drum_unit [] = { - { UDATA (drum_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DRUM_SIZE) }, - { UDATA (drum_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DRUM_SIZE) }, + { UDATA (drum_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DRUM_SIZE) }, + { UDATA (drum_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DRUM_SIZE) }, }; REG drum_reg[] = { -{ "УС", &drum_op, 8, 24, 0, 1 }, -{ "ЗОНА", &drum_zone, 8, 10, 0, 1 }, -{ "СЕКТОР", &drum_sector, 8, 2, 0, 1 }, -{ "МОЗУ", &drum_memory, 8, 15, 0, 1 }, -{ "СЧСЛОВ", &drum_nwords, 8, 11, 0, 1 }, -{ 0 } + { "УС", &drum_op, 8, 24, 0, 1 }, + { "ЗОНА", &drum_zone, 8, 10, 0, 1 }, + { "СЕКТОР", &drum_sector, 8, 2, 0, 1 }, + { "МОЗУ", &drum_memory, 8, 15, 0, 1 }, + { "СЧСЛОВ", &drum_nwords, 8, 11, 0, 1 }, + { 0 } }; MTAB drum_mod[] = { - { 0 } + { 0 } }; t_stat drum_reset (DEVICE *dptr); @@ -86,10 +86,10 @@ t_stat drum_attach (UNIT *uptr, char *cptr); t_stat drum_detach (UNIT *uptr); DEVICE drum_dev = { - "DRUM", drum_unit, drum_reg, drum_mod, - 2, 8, 19, 1, 8, 50, - NULL, NULL, &drum_reset, NULL, &drum_attach, &drum_detach, - NULL, DEV_DISABLE | DEV_DEBUG + "DRUM", drum_unit, drum_reg, drum_mod, + 2, 8, 19, 1, 8, 50, + NULL, NULL, &drum_reset, NULL, &drum_attach, &drum_detach, + NULL, DEV_DISABLE | DEV_DEBUG }; /* @@ -97,37 +97,37 @@ DEVICE drum_dev = { */ t_stat drum_reset (DEVICE *dptr) { - drum_op = 0; - drum_zone = 0; - drum_sector = 0; - drum_memory = 0; - drum_nwords = 0; - sim_cancel (&drum_unit[0]); - sim_cancel (&drum_unit[1]); - return SCPE_OK; + drum_op = 0; + drum_zone = 0; + drum_sector = 0; + drum_memory = 0; + drum_nwords = 0; + sim_cancel (&drum_unit[0]); + sim_cancel (&drum_unit[1]); + return SCPE_OK; } t_stat drum_attach (UNIT *u, char *cptr) { - t_stat s; + t_stat s; - s = attach_unit (u, cptr); - if (s != SCPE_OK) - return s; - if (u == &drum_unit[0]) - GRP |= GRP_DRUM1_FREE; - else - GRP |= GRP_DRUM2_FREE; - return SCPE_OK; + s = attach_unit (u, cptr); + if (s != SCPE_OK) + return s; + if (u == &drum_unit[0]) + GRP |= GRP_DRUM1_FREE; + else + GRP |= GRP_DRUM2_FREE; + return SCPE_OK; } t_stat drum_detach (UNIT *u) { - if (u == &drum_unit[0]) - GRP &= ~GRP_DRUM1_FREE; - else - GRP &= ~GRP_DRUM2_FREE; - return detach_unit (u); + if (u == &drum_unit[0]) + GRP &= ~GRP_DRUM1_FREE; + else + GRP &= ~GRP_DRUM2_FREE; + return detach_unit (u); } /* @@ -136,37 +136,37 @@ t_stat drum_detach (UNIT *u) #if 0 static void log_io (UNIT *u) { - t_value *data, *sysdata; - int i; - void print_word (t_value val) { - fprintf (sim_log, " %o-%04o-%04o-%04o-%04o", - (int) (val >> 48) & 07, - (int) (val >> 36) & 07777, - (int) (val >> 24) & 07777, - (int) (val >> 12) & 07777, (int) val & 07777); - } + t_value *data, *sysdata; + int i; + void print_word (t_value val) { + fprintf (sim_log, " %o-%04o-%04o-%04o-%04o", + (int) (val >> 48) & 07, + (int) (val >> 36) & 07777, + (int) (val >> 24) & 07777, + (int) (val >> 12) & 07777, (int) val & 07777); + } - data = &memory [drum_memory]; - sysdata = (u == &drum_unit[0]) ? &memory [010] : &memory [020]; - if (drum_nwords == 1024) { - fprintf (sim_log, "=== зона МБ %d.%03o:", - (u == &drum_unit[0]) ? 1 : 2, drum_zone); - for (i=0; i<8; ++i) - print_word (sysdata[i]); - } else { - sysdata += drum_sector*2; - fprintf (sim_log, "=== сектор МБ %d.%03o.%o:", - (u == &drum_unit[0]) ? 1 : 2, - drum_zone, drum_sector); - for (i=0; i<2; ++i) - print_word (sysdata[i]); - } - if (! (drum_op & DRUM_READ_SYSDATA)) { - fprintf (sim_log, "\n\t\t "); - for (i=0; ifileref, ZONE_SIZE * drum_zone * 8, SEEK_SET); - sim_fwrite (sysdata, 8, 8, u->fileref); - sim_fwrite (&memory [drum_memory], 8, 1024, u->fileref); - if (ferror (u->fileref)) - longjmp (cpu_halt, SCPE_IOERR); + ctlr = (u == &drum_unit[1]); + sysdata = ctlr ? &memory [020] : &memory [010]; + fseek (u->fileref, ZONE_SIZE * drum_zone * 8, SEEK_SET); + sim_fwrite (sysdata, 8, 8, u->fileref); + sim_fwrite (&memory [drum_memory], 8, 1024, u->fileref); + if (ferror (u->fileref)) + longjmp (cpu_halt, SCPE_IOERR); } void drum_write_sector (UNIT *u) { - int ctlr; - t_value *sysdata; + int ctlr; + t_value *sysdata; - ctlr = (u == &drum_unit[1]); - sysdata = ctlr ? &memory [020] : &memory [010]; - fseek (u->fileref, (ZONE_SIZE*drum_zone + drum_sector*2) * 8, - SEEK_SET); - sim_fwrite (&sysdata [drum_sector*2], 8, 2, u->fileref); - fseek (u->fileref, (ZONE_SIZE*drum_zone + 8 + drum_sector*256) * 8, - SEEK_SET); - sim_fwrite (&memory [drum_memory], 8, 256, u->fileref); - if (ferror (u->fileref)) - longjmp (cpu_halt, SCPE_IOERR); + ctlr = (u == &drum_unit[1]); + sysdata = ctlr ? &memory [020] : &memory [010]; + fseek (u->fileref, (ZONE_SIZE*drum_zone + drum_sector*2) * 8, + SEEK_SET); + sim_fwrite (&sysdata [drum_sector*2], 8, 2, u->fileref); + fseek (u->fileref, (ZONE_SIZE*drum_zone + 8 + drum_sector*256) * 8, + SEEK_SET); + sim_fwrite (&memory [drum_memory], 8, 256, u->fileref); + if (ferror (u->fileref)) + longjmp (cpu_halt, SCPE_IOERR); } /* @@ -209,57 +209,57 @@ void drum_write_sector (UNIT *u) */ void drum_read (UNIT *u) { - int ctlr; - t_value *sysdata; + int ctlr; + t_value *sysdata; - ctlr = (u == &drum_unit[1]); - sysdata = ctlr ? &memory [020] : &memory [010]; - fseek (u->fileref, ZONE_SIZE * drum_zone * 8, SEEK_SET); - if (sim_fread (sysdata, 8, 8, u->fileref) != 8) { - /* Чтение неинициализированного барабана */ - drum_fail |= 0100 >> ctlr; - return; - } - if (! (drum_op & DRUM_READ_SYSDATA) && - sim_fread (&memory[drum_memory], 8, 1024, u->fileref) != 1024) { - /* Чтение неинициализированного барабана */ - drum_fail |= 0100 >> ctlr; - return; - } - if (ferror (u->fileref)) - longjmp (cpu_halt, SCPE_IOERR); + ctlr = (u == &drum_unit[1]); + sysdata = ctlr ? &memory [020] : &memory [010]; + fseek (u->fileref, ZONE_SIZE * drum_zone * 8, SEEK_SET); + if (sim_fread (sysdata, 8, 8, u->fileref) != 8) { + /* Чтение неинициализированного барабана */ + drum_fail |= 0100 >> ctlr; + return; + } + if (! (drum_op & DRUM_READ_SYSDATA) && + sim_fread (&memory[drum_memory], 8, 1024, u->fileref) != 1024) { + /* Чтение неинициализированного барабана */ + drum_fail |= 0100 >> ctlr; + return; + } + if (ferror (u->fileref)) + longjmp (cpu_halt, SCPE_IOERR); } void drum_read_sector (UNIT *u) { - int ctlr; - t_value *sysdata; + int ctlr; + t_value *sysdata; - ctlr = (u == &drum_unit[1]); - sysdata = ctlr ? &memory [020] : &memory [010]; - fseek (u->fileref, (ZONE_SIZE*drum_zone + drum_sector*2) * 8, SEEK_SET); - if (sim_fread (&sysdata [drum_sector*2], 8, 2, u->fileref) != 2) { - /* Чтение неинициализированного барабана */ - drum_fail |= 0100 >> ctlr; - return; - } - if (! (drum_op & DRUM_READ_SYSDATA)) { - fseek (u->fileref, (ZONE_SIZE*drum_zone + 8 + drum_sector*256) * 8, - SEEK_SET); - if (sim_fread (&memory[drum_memory], 8, 256, u->fileref) != 256) { - /* Чтение неинициализированного барабана */ - drum_fail |= 0100 >> ctlr; - return; - } - } - if (ferror (u->fileref)) - longjmp (cpu_halt, SCPE_IOERR); + ctlr = (u == &drum_unit[1]); + sysdata = ctlr ? &memory [020] : &memory [010]; + fseek (u->fileref, (ZONE_SIZE*drum_zone + drum_sector*2) * 8, SEEK_SET); + if (sim_fread (&sysdata [drum_sector*2], 8, 2, u->fileref) != 2) { + /* Чтение неинициализированного барабана */ + drum_fail |= 0100 >> ctlr; + return; + } + if (! (drum_op & DRUM_READ_SYSDATA)) { + fseek (u->fileref, (ZONE_SIZE*drum_zone + 8 + drum_sector*256) * 8, + SEEK_SET); + if (sim_fread (&memory[drum_memory], 8, 256, u->fileref) != 256) { + /* Чтение неинициализированного барабана */ + drum_fail |= 0100 >> ctlr; + return; + } + } + if (ferror (u->fileref)) + longjmp (cpu_halt, SCPE_IOERR); } static void clear_memory (t_value *p, int nwords) { - while (nwords-- > 0) - *p++ = SET_CONVOL (0, CONVOL_NUMBER); + while (nwords-- > 0) + *p++ = SET_CONVOL (0, CONVOL_NUMBER); } /* @@ -267,87 +267,87 @@ static void clear_memory (t_value *p, int nwords) */ void drum (int ctlr, uint32 cmd) { - UNIT *u = &drum_unit[ctlr]; + UNIT *u = &drum_unit[ctlr]; - drum_op = cmd; - if (drum_op & DRUM_PAGE_MODE) { - /* Обмен страницей */ - drum_nwords = 1024; - drum_zone = (cmd & (DRUM_UNIT | DRUM_CYLINDER)) >> 2; - drum_sector = 0; - drum_memory = (cmd & DRUM_PAGE) >> 2 | (cmd & DRUM_BLOCK) >> 8; - if (drum_dev.dctrl) - besm6_debug ("### %s МБ %c%d зона %02o память %05o-%05o", - (drum_op & DRUM_READ) ? "чтение" : "запись", - ctlr + '1', (drum_zone >> 5 & 7), drum_zone & 037, - drum_memory, drum_memory + drum_nwords - 1); - if (drum_op & DRUM_READ) { - clear_memory (ctlr ? &memory [020] : &memory [010], 8); - if (! (drum_op & DRUM_READ_SYSDATA)) - clear_memory (&memory[drum_memory], 1024); - } - } else { - /* Обмен сектором */ - drum_nwords = 256; - drum_zone = (cmd & (DRUM_UNIT | DRUM_CYLINDER)) >> 2; - drum_sector = cmd & DRUM_SECTOR; - drum_memory = (cmd & (DRUM_PAGE | DRUM_PARAGRAF)) >> 2 | (cmd & DRUM_BLOCK) >> 8; - if (drum_dev.dctrl) - besm6_debug ("### %s МБ %c%d зона %02o сектор %d память %05o-%05o", - (drum_op & DRUM_READ) ? "чтение" : "запись", - ctlr + '1', (drum_zone >> 5 & 7), drum_zone & 037, - drum_sector & 3, - drum_memory, drum_memory + drum_nwords - 1); - if (drum_op & DRUM_READ) { - clear_memory (ctlr ? &memory [020 + drum_sector*2] : - &memory [010 + drum_sector*2], 2); - if (! (drum_op & DRUM_READ_SYSDATA)) - clear_memory (&memory[drum_memory], 256); - } - } - if ((drum_dev.flags & DEV_DIS) || ! u->fileref) { - /* Device not attached. */ - drum_fail |= 0100 >> ctlr; - return; - } - drum_fail &= ~(0100 >> ctlr); - if (drum_op & DRUM_READ_OVERLAY) { - /* Not implemented. */ - longjmp (cpu_halt, SCPE_NOFNC); - } - if (drum_op & DRUM_READ) { - if (drum_op & DRUM_PAGE_MODE) - drum_read (u); - else - drum_read_sector (u); - } else { - if (drum_op & DRUM_PARITY_FLAG) { - besm6_log ("### запись МБ с неправильной чётностью не реализована"); - longjmp (cpu_halt, SCPE_NOFNC); - } - if (u->flags & UNIT_RO) { - /* Read only. */ - longjmp (cpu_halt, SCPE_RO); - } - if (drum_op & DRUM_PAGE_MODE) - drum_write (u); - else - drum_write_sector (u); - } - /*if (drum_dev.dctrl && sim_log) - log_io (u);*/ + drum_op = cmd; + if (drum_op & DRUM_PAGE_MODE) { + /* Обмен страницей */ + drum_nwords = 1024; + drum_zone = (cmd & (DRUM_UNIT | DRUM_CYLINDER)) >> 2; + drum_sector = 0; + drum_memory = (cmd & DRUM_PAGE) >> 2 | (cmd & DRUM_BLOCK) >> 8; + if (drum_dev.dctrl) + besm6_debug ("### %s МБ %c%d зона %02o память %05o-%05o", + (drum_op & DRUM_READ) ? "чтение" : "запись", + ctlr + '1', (drum_zone >> 5 & 7), drum_zone & 037, + drum_memory, drum_memory + drum_nwords - 1); + if (drum_op & DRUM_READ) { + clear_memory (ctlr ? &memory [020] : &memory [010], 8); + if (! (drum_op & DRUM_READ_SYSDATA)) + clear_memory (&memory[drum_memory], 1024); + } + } else { + /* Обмен сектором */ + drum_nwords = 256; + drum_zone = (cmd & (DRUM_UNIT | DRUM_CYLINDER)) >> 2; + drum_sector = cmd & DRUM_SECTOR; + drum_memory = (cmd & (DRUM_PAGE | DRUM_PARAGRAF)) >> 2 | (cmd & DRUM_BLOCK) >> 8; + if (drum_dev.dctrl) + besm6_debug ("### %s МБ %c%d зона %02o сектор %d память %05o-%05o", + (drum_op & DRUM_READ) ? "чтение" : "запись", + ctlr + '1', (drum_zone >> 5 & 7), drum_zone & 037, + drum_sector & 3, + drum_memory, drum_memory + drum_nwords - 1); + if (drum_op & DRUM_READ) { + clear_memory (ctlr ? &memory [020 + drum_sector*2] : + &memory [010 + drum_sector*2], 2); + if (! (drum_op & DRUM_READ_SYSDATA)) + clear_memory (&memory[drum_memory], 256); + } + } + if ((drum_dev.flags & DEV_DIS) || ! u->fileref) { + /* Device not attached. */ + drum_fail |= 0100 >> ctlr; + return; + } + drum_fail &= ~(0100 >> ctlr); + if (drum_op & DRUM_READ_OVERLAY) { + /* Not implemented. */ + longjmp (cpu_halt, SCPE_NOFNC); + } + if (drum_op & DRUM_READ) { + if (drum_op & DRUM_PAGE_MODE) + drum_read (u); + else + drum_read_sector (u); + } else { + if (drum_op & DRUM_PARITY_FLAG) { + besm6_log ("### запись МБ с неправильной чётностью не реализована"); + longjmp (cpu_halt, SCPE_NOFNC); + } + if (u->flags & UNIT_RO) { + /* Read only. */ + longjmp (cpu_halt, SCPE_RO); + } + if (drum_op & DRUM_PAGE_MODE) + drum_write (u); + else + drum_write_sector (u); + } + /*if (drum_dev.dctrl && sim_log) + log_io (u);*/ - /* Гасим главный регистр прерываний. */ - if (u == &drum_unit[0]) - GRP &= ~GRP_DRUM1_FREE; - else - GRP &= ~GRP_DRUM2_FREE; + /* Гасим главный регистр прерываний. */ + if (u == &drum_unit[0]) + GRP &= ~GRP_DRUM1_FREE; + else + GRP &= ~GRP_DRUM2_FREE; - /* Ждём события от устройства. - * Согласно данным из книжки Мазного Г.Л., - * даём 20 мсек на обмен, или 200 тыс.тактов. */ - /*sim_activate (u, 20*MSEC);*/ - sim_activate (u, 20*USEC); /* Ускорим для отладки. */ + /* Ждём события от устройства. + * Согласно данным из книжки Мазного Г.Л., + * даём 20 мсек на обмен, или 200 тыс.тактов. */ + /*sim_activate (u, 20*MSEC);*/ + sim_activate (u, 20*USEC); /* Ускорим для отладки. */ } /* @@ -356,11 +356,11 @@ void drum (int ctlr, uint32 cmd) */ t_stat drum_event (UNIT *u) { - if (u == &drum_unit[0]) - GRP |= GRP_DRUM1_FREE; - else - GRP |= GRP_DRUM2_FREE; - return SCPE_OK; + if (u == &drum_unit[0]) + GRP |= GRP_DRUM1_FREE; + else + GRP |= GRP_DRUM2_FREE; + return SCPE_OK; } /* @@ -368,5 +368,5 @@ t_stat drum_event (UNIT *u) */ int drum_errors () { - return drum_fail; + return drum_fail; } diff --git a/BESM6/besm6_mmu.c b/BESM6/besm6_mmu.c index c9d2c2e5..7428cb72 100644 --- a/BESM6/besm6_mmu.c +++ b/BESM6/besm6_mmu.c @@ -32,12 +32,12 @@ /* * MMU data structures * - * mmu_dev MMU device descriptor - * mmu_unit MMU unit descriptor - * mmu_reg MMU register list + * mmu_dev MMU device descriptor + * mmu_unit MMU unit descriptor + * mmu_reg MMU register list */ UNIT mmu_unit = { - UDATA (NULL, UNIT_FIX, 8) + UDATA (NULL, UNIT_FIX, 8) }; t_value BRZ[8]; @@ -56,80 +56,80 @@ uint32 BRSLRU; t_value RP[8]; 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]; REG mmu_reg[] = { -{ "БРЗ0", &BRZ[0], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, /* Буферные регистры записи */ -{ "БРЗ1", &BRZ[1], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, -{ "БРЗ2", &BRZ[2], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, -{ "БРЗ3", &BRZ[3], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, -{ "БРЗ4", &BRZ[4], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, -{ "БРЗ5", &BRZ[5], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, -{ "БРЗ6", &BRZ[6], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, -{ "БРЗ7", &BRZ[7], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, -{ "БАЗ0", &BAZ[0], 8, 16, 0, 1 }, /* Буферные адреса записи */ -{ "БАЗ1", &BAZ[1], 8, 16, 0, 1 }, -{ "БАЗ2", &BAZ[2], 8, 16, 0, 1 }, -{ "БАЗ3", &BAZ[3], 8, 16, 0, 1 }, -{ "БАЗ4", &BAZ[4], 8, 16, 0, 1 }, -{ "БАЗ5", &BAZ[5], 8, 16, 0, 1 }, -{ "БАЗ6", &BAZ[6], 8, 16, 0, 1 }, -{ "БАЗ7", &BAZ[7], 8, 16, 0, 1 }, -{ "ТАБСТ", &TABST, 8, 28, 0, 1, NULL, NULL, REG_HIDDEN },/* Таблица старшинства БРЗ */ -{ "ЗпТР", &FLUSH, 8, 4, 0, 1, NULL, NULL, REG_HIDDEN },/* Признак выталкивания БРЗ */ -{ "Старш", &OLDEST, 8, 3, 0, 1 }, /* Номер вытолкнутого БРЗ */ -{ "РП0", &RP[0], 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* Регистры приписки, по 12 бит */ -{ "РП1", &RP[1], 8, 48, 0, 1, NULL, NULL, REG_VMIO}, -{ "РП2", &RP[2], 8, 48, 0, 1, NULL, NULL, REG_VMIO}, -{ "РП3", &RP[3], 8, 48, 0, 1, NULL, NULL, REG_VMIO}, -{ "РП4", &RP[4], 8, 48, 0, 1, NULL, NULL, REG_VMIO}, -{ "РП5", &RP[5], 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}, -{ "РЗ", &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}, -{ "БРС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}, -{ "БРС3", &BRS[3], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, -{ "БАС0", &BAS[0], 8, 16, 0, 1 }, /* Буферные адреса слов */ -{ "БАС1", &BAS[1], 8, 16, 0, 1 }, -{ "БАС2", &BAS[2], 8, 16, 0, 1 }, -{ "БАС3", &BAS[3], 8, 16, 0, 1 }, -{ "БРСст", &BRSLRU, 8, 6, 0, 1, NULL, NULL, REG_HIDDEN}, -{ 0 } + { "БРЗ0", &BRZ[0], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, /* Буферные регистры записи */ + { "БРЗ1", &BRZ[1], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, + { "БРЗ2", &BRZ[2], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, + { "БРЗ3", &BRZ[3], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, + { "БРЗ4", &BRZ[4], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, + { "БРЗ5", &BRZ[5], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, + { "БРЗ6", &BRZ[6], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, + { "БРЗ7", &BRZ[7], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, + { "БАЗ0", &BAZ[0], 8, 16, 0, 1 }, /* Буферные адреса записи */ + { "БАЗ1", &BAZ[1], 8, 16, 0, 1 }, + { "БАЗ2", &BAZ[2], 8, 16, 0, 1 }, + { "БАЗ3", &BAZ[3], 8, 16, 0, 1 }, + { "БАЗ4", &BAZ[4], 8, 16, 0, 1 }, + { "БАЗ5", &BAZ[5], 8, 16, 0, 1 }, + { "БАЗ6", &BAZ[6], 8, 16, 0, 1 }, + { "БАЗ7", &BAZ[7], 8, 16, 0, 1 }, + { "ТАБСТ", &TABST, 8, 28, 0, 1, NULL, NULL, REG_HIDDEN },/* Таблица старшинства БРЗ */ + { "ЗпТР", &FLUSH, 8, 4, 0, 1, NULL, NULL, REG_HIDDEN },/* Признак выталкивания БРЗ */ + { "Старш", &OLDEST, 8, 3, 0, 1 }, /* Номер вытолкнутого БРЗ */ + { "РП0", &RP[0], 8, 48, 0, 1, NULL, NULL, REG_VMIO}, /* Регистры приписки, по 12 бит */ + { "РП1", &RP[1], 8, 48, 0, 1, NULL, NULL, REG_VMIO}, + { "РП2", &RP[2], 8, 48, 0, 1, NULL, NULL, REG_VMIO}, + { "РП3", &RP[3], 8, 48, 0, 1, NULL, NULL, REG_VMIO}, + { "РП4", &RP[4], 8, 48, 0, 1, NULL, NULL, REG_VMIO}, + { "РП5", &RP[5], 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}, + { "РЗ", &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}, + { "БРС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}, + { "БРС3", &BRS[3], 8, 50, 0, 1, NULL, NULL, REG_VMIO}, + { "БАС0", &BAS[0], 8, 16, 0, 1 }, /* Буферные адреса слов */ + { "БАС1", &BAS[1], 8, 16, 0, 1 }, + { "БАС2", &BAS[2], 8, 16, 0, 1 }, + { "БАС3", &BAS[3], 8, 16, 0, 1 }, + { "БРСст", &BRSLRU, 8, 6, 0, 1, NULL, NULL, REG_HIDDEN}, + { 0 } }; #define CACHE_ENB 1 MTAB mmu_mod[] = { - { 1, 0, "NOCACHE", "NOCACHE" }, - { 1, 1, "CACHE", "CACHE" }, - { 0 } + { 1, 0, "NOCACHE", "NOCACHE" }, + { 1, 1, "CACHE", "CACHE" }, + { 0 } }; t_stat mmu_reset (DEVICE *dptr); t_stat mmu_examine (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) { - mmu_print_brz(); - return SCPE_NOFNC; + mmu_print_brz(); + return SCPE_NOFNC; } DEVICE mmu_dev = { - "MMU", &mmu_unit, mmu_reg, mmu_mod, - 1, 8, 3, 1, 8, 50, - &mmu_examine, NULL, &mmu_reset, - NULL, NULL, NULL, NULL, - DEV_DEBUG + "MMU", &mmu_unit, mmu_reg, mmu_mod, + 1, 8, 3, 1, 8, 50, + &mmu_examine, NULL, &mmu_reset, + NULL, NULL, NULL, NULL, + DEV_DEBUG }; /* @@ -137,23 +137,23 @@ DEVICE mmu_dev = { */ t_stat mmu_reset (DEVICE *dptr) { - int i; - for (i = 0; i < 8; ++i) { - BRZ[i] = BAZ[i] = RP[i] = 0; - } - TABST = 0; - OLDEST = 0; - FLUSH = 0; - RZ = 0; - /* - * Front panel switches survive the reset - */ - sim_cancel (&mmu_unit); - return SCPE_OK; + int i; + for (i = 0; i < 8; ++i) { + BRZ[i] = BAZ[i] = RP[i] = 0; + } + TABST = 0; + OLDEST = 0; + FLUSH = 0; + RZ = 0; + /* + * Front panel switches survive the reset + */ + sim_cancel (&mmu_unit); + return SCPE_OK; } -#define loses_to_all(i) ((TABST & win_mask[i]) == 0 && \ - (TABST & lose_mask[i]) == lose_mask[i]) +#define loses_to_all(i) ((TABST & win_mask[i]) == 0 && \ + (TABST & lose_mask[i]) == lose_mask[i]) /* * N wins over M if the bit is set @@ -169,86 +169,86 @@ t_stat mmu_reset (DEVICE *dptr) */ static unsigned win_mask[8] = { - 0177, - 0077 << 7, - 0037 << 13, - 0017 << 18, - 0007 << 22, - 0003 << 25, - 0001 << 27, - 0 + 0177, + 0077 << 7, + 0037 << 13, + 0017 << 18, + 0007 << 22, + 0003 << 25, + 0001 << 27, + 0 }; static unsigned lose_mask[8] = { - 0, - 1<<0, - 1<<1|1<<7, - 1<<2|1<<8|1<<13, - 1<<3|1<<9|1<<14|1<<18, - 1<<4|1<<10|1<<15|1<<19|1<<22, - 1<<5|1<<11|1<<16|1<<20|1<<23|1<<25, - 1<<6|1<<12|1<<17|1<<21|1<<24|1<<26|1<<27 + 0, + 1<<0, + 1<<1|1<<7, + 1<<2|1<<8|1<<13, + 1<<3|1<<9|1<<14|1<<18, + 1<<4|1<<10|1<<15|1<<19|1<<22, + 1<<5|1<<11|1<<16|1<<20|1<<23|1<<25, + 1<<6|1<<12|1<<17|1<<21|1<<24|1<<26|1<<27 }; #define set_wins(i) TABST = (TABST & ~lose_mask[i]) | win_mask[i] void mmu_protection_check (int addr) { - /* Защита блокируется в режиме супервизора для физических (!) адресов 1-7 (ТО-8) - WTF? */ - int tmp_prot_disabled = (M[PSW] & PSW_PROT_DISABLE) || - (IS_SUPERVISOR (RUU) && (M[PSW] & PSW_MMAP_DISABLE) && addr < 010); + /* Защита блокируется в режиме супервизора для физических (!) адресов 1-7 (ТО-8) - WTF? */ + int tmp_prot_disabled = (M[PSW] & PSW_PROT_DISABLE) || + (IS_SUPERVISOR (RUU) && (M[PSW] & PSW_MMAP_DISABLE) && addr < 010); - /* Защита не заблокирована, а лист закрыт */ - if (! tmp_prot_disabled && (RZ & (1 << (addr >> 10)))) { - iintr_data = addr >> 10; - if (mmu_dev.dctrl) - besm6_debug ("--- (%05o) защита числа", addr); - longjmp (cpu_halt, STOP_OPERAND_PROT); - } + /* Защита не заблокирована, а лист закрыт */ + if (! tmp_prot_disabled && (RZ & (1 << (addr >> 10)))) { + iintr_data = addr >> 10; + if (mmu_dev.dctrl) + besm6_debug ("--- (%05o) защита числа", addr); + longjmp (cpu_halt, STOP_OPERAND_PROT); + } } void mmu_flush (int idx) { - if (! BAZ[idx]) { - /* Был пуст после сброса или выталкивания */ - return; - } - /* Вычисляем физический адрес выталкиваемого БРЗ */ - int waddr = BAZ[idx]; - waddr = (waddr > 0100000) ? (waddr - 0100000) : - (waddr & 01777) | (TLB[waddr >> 10] << 10); - memory[waddr] = BRZ[idx]; - BAZ[idx] = 0; - if (sim_log && mmu_dev.dctrl) { - fprintf (sim_log, "--- (%05o) запись ", waddr); - fprint_sym (sim_log, 0, &BRZ[idx], 0, 0); - fprintf (sim_log, " из БРЗ[%d]\n", idx); - } + if (! BAZ[idx]) { + /* Был пуст после сброса или выталкивания */ + return; + } + /* Вычисляем физический адрес выталкиваемого БРЗ */ + int waddr = BAZ[idx]; + waddr = (waddr > 0100000) ? (waddr - 0100000) : + (waddr & 01777) | (TLB[waddr >> 10] << 10); + memory[waddr] = BRZ[idx]; + BAZ[idx] = 0; + if (sim_log && mmu_dev.dctrl) { + fprintf (sim_log, "--- (%05o) запись ", waddr); + fprint_sym (sim_log, 0, &BRZ[idx], 0, 0); + fprintf (sim_log, " из БРЗ[%d]\n", idx); + } } void mmu_update_oldest () { - int i; + int i; - for (i = 0; i < 8; ++i) { - if (loses_to_all(i)) { - OLDEST = i; - // fprintf(stderr, "Oldest = %d\r\n", i); - return; - } - } + for (i = 0; i < 8; ++i) { + if (loses_to_all(i)) { + OLDEST = i; + // fprintf(stderr, "Oldest = %d\r\n", i); + return; + } + } } int mmu_match (int addr, int fail) { - int i; + int i; - for (i = 0; i < 8; ++i) { - if (addr == BAZ[i]) { - return i; - } - } - return fail; + for (i = 0; i < 8; ++i) { + if (addr == BAZ[i]) { + return i; + } + } + return fail; } /* @@ -258,39 +258,39 @@ int mmu_match (int addr, int fail) */ void mmu_flush_by_age() { - switch (FLUSH) { - case 0: - break; - case 1 ... 8: - set_wins (OLDEST); - mmu_update_oldest (); - mmu_flush (OLDEST); - if (FLUSH == 7) { - TABST = 0; - OLDEST = 0; - } - break; - } - ++FLUSH; + switch (FLUSH) { + case 0: + break; + case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: + set_wins (OLDEST); + mmu_update_oldest (); + mmu_flush (OLDEST); + if (FLUSH == 7) { + TABST = 0; + OLDEST = 0; + } + break; + } + ++FLUSH; } void mmu_flush_by_number() { - switch (FLUSH) { - case 0: - break; - case 1 ... 8: - mmu_flush (FLUSH-1); - set_wins (FLUSH-1); - if (FLUSH-1 == OLDEST) - mmu_update_oldest (); - if (FLUSH == 7) { - TABST = 0; - OLDEST = 0; - } - break; - } - ++FLUSH; + switch (FLUSH) { + case 0: + break; + case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: + mmu_flush (FLUSH-1); + set_wins (FLUSH-1); + if (FLUSH-1 == OLDEST) + mmu_update_oldest (); + if (FLUSH == 7) { + TABST = 0; + OLDEST = 0; + } + break; + } + ++FLUSH; } /* @@ -298,92 +298,92 @@ void mmu_flush_by_number() */ void mmu_store (int addr, t_value val) { - int matching; + int matching; - addr &= BITS(15); - if (addr == 0) - return; - if (sim_log && mmu_dev.dctrl) { - fprintf (sim_log, "--- (%05o) запись ", addr); - fprint_sym (sim_log, 0, &val, 0, 0); - fprintf (sim_log, "\n"); - } + addr &= BITS(15); + if (addr == 0) + return; + if (sim_log && mmu_dev.dctrl) { + fprintf (sim_log, "--- (%05o) запись ", addr); + fprint_sym (sim_log, 0, &val, 0, 0); + fprintf (sim_log, "\n"); + } - mmu_protection_check (addr); + mmu_protection_check (addr); - /* Различаем адреса с припиской и без */ - if (M[PSW] & PSW_MMAP_DISABLE) - addr |= 0100000; + /* Различаем адреса с припиской и без */ + if (M[PSW] & PSW_MMAP_DISABLE) + addr |= 0100000; - /* ЗПСЧ: ЗП */ - if (M[DWP] == addr && (M[PSW] & PSW_WRITE_WATCH)) - longjmp(cpu_halt, STOP_STORE_ADDR_MATCH); + /* ЗПСЧ: ЗП */ + if (M[DWP] == addr && (M[PSW] & PSW_WRITE_WATCH)) + longjmp(cpu_halt, STOP_STORE_ADDR_MATCH); - if (sim_brk_summ & SWMASK('W') && - sim_brk_test (addr, SWMASK('W'))) - longjmp(cpu_halt, STOP_WWATCH); + if (sim_brk_summ & SWMASK('W') && + sim_brk_test (addr, SWMASK('W'))) + longjmp(cpu_halt, STOP_WWATCH); - if (!(mmu_unit.flags & CACHE_ENB)) { - static int roundrobin; - int faked = (++roundrobin ^ addr ^ val) & 7; + if (!(mmu_unit.flags & CACHE_ENB)) { + static int roundrobin; + int faked = (++roundrobin ^ addr ^ val) & 7; - if (addr > 0100000 && addr < 0100010) - return; + if (addr > 0100000 && addr < 0100010) + return; - BRZ[faked] = SET_CONVOL (val, RUU ^ CONVOL_INSN); - BAZ[faked] = addr; - mmu_flush (faked); - return; - } + BRZ[faked] = SET_CONVOL (val, RUU ^ CONVOL_INSN); + BAZ[faked] = addr; + mmu_flush (faked); + return; + } - /* Запись в тумблерные регистры - выталкивание БРЗ */ - if (addr > 0100000 && addr < 0100010) { - mmu_flush_by_age(); - return; - } else - FLUSH = 0; + /* Запись в тумблерные регистры - выталкивание БРЗ */ + if (addr > 0100000 && addr < 0100010) { + mmu_flush_by_age(); + return; + } else + FLUSH = 0; - matching = mmu_match(addr, OLDEST); + matching = mmu_match(addr, OLDEST); - BRZ[matching] = SET_CONVOL (val, RUU ^ CONVOL_INSN); - BAZ[matching] = addr; - set_wins (matching); + BRZ[matching] = SET_CONVOL (val, RUU ^ CONVOL_INSN); + BAZ[matching] = addr; + set_wins (matching); - if (matching == OLDEST) { - mmu_update_oldest (); - mmu_flush (OLDEST); - } + if (matching == OLDEST) { + mmu_update_oldest (); + mmu_flush (OLDEST); + } } t_value mmu_memaccess (int addr) { - t_value val; + t_value val; - /* Вычисляем физический адрес слова */ - addr = (addr > 0100000) ? (addr - 0100000) : - (addr & 01777) | (TLB[addr >> 10] << 10); - if (addr >= 010) { - /* Из памяти */ - val = memory[addr]; - } else { - /* С тумблерных регистров */ - if (mmu_dev.dctrl) - besm6_debug("--- (%05o) чтение ТР%o", PC, addr); - val = pult[addr]; - } - if (sim_log && (mmu_dev.dctrl || (cpu_dev.dctrl && sim_deb))) { - fprintf (sim_log, "--- (%05o) чтение ", addr & BITS(15)); - fprint_sym (sim_log, 0, &val, 0, 0); - fprintf (sim_log, "\n"); - } + /* Вычисляем физический адрес слова */ + addr = (addr > 0100000) ? (addr - 0100000) : + (addr & 01777) | (TLB[addr >> 10] << 10); + if (addr >= 010) { + /* Из памяти */ + val = memory[addr]; + } else { + /* С тумблерных регистров */ + if (mmu_dev.dctrl) + besm6_debug("--- (%05o) чтение ТР%o", PC, addr); + val = pult[addr]; + } + if (sim_log && (mmu_dev.dctrl || (cpu_dev.dctrl && sim_deb))) { + fprintf (sim_log, "--- (%05o) чтение ", addr & BITS(15)); + fprint_sym (sim_log, 0, &val, 0, 0); + fprintf (sim_log, "\n"); + } - /* На тумблерных регистрах контроля числа не бывает */ - if (addr >= 010 && ! IS_NUMBER (val)) { - iintr_data = addr & 7; - besm6_debug ("--- (%05o) контроль числа", addr); - longjmp (cpu_halt, STOP_RAM_CHECK); - } - return val; + /* На тумблерных регистрах контроля числа не бывает */ + if (addr >= 010 && ! IS_NUMBER (val)) { + iintr_data = addr & 7; + besm6_debug ("--- (%05o) контроль числа", addr); + longjmp (cpu_halt, STOP_RAM_CHECK); + } + return val; } /* @@ -391,59 +391,59 @@ t_value mmu_memaccess (int addr) */ t_value mmu_load (int addr) { - int matching = -1; - t_value val; + int matching = -1; + t_value val; - addr &= BITS(15); - if (addr == 0) - return 0; + addr &= BITS(15); + if (addr == 0) + return 0; - mmu_protection_check (addr); + mmu_protection_check (addr); - /* Различаем адреса с припиской и без */ - if (M[PSW] & PSW_MMAP_DISABLE) - addr |= 0100000; + /* Различаем адреса с припиской и без */ + if (M[PSW] & PSW_MMAP_DISABLE) + addr |= 0100000; - /* ЗПСЧ: СЧ */ - if (M[DWP] == addr && !(M[PSW] & PSW_WRITE_WATCH)) - longjmp(cpu_halt, STOP_LOAD_ADDR_MATCH); + /* ЗПСЧ: СЧ */ + if (M[DWP] == addr && !(M[PSW] & PSW_WRITE_WATCH)) + longjmp(cpu_halt, STOP_LOAD_ADDR_MATCH); - if (sim_brk_summ & SWMASK('R') && - sim_brk_test (addr, SWMASK('R'))) - longjmp(cpu_halt, STOP_RWATCH); + if (sim_brk_summ & SWMASK('R') && + sim_brk_test (addr, SWMASK('R'))) + longjmp(cpu_halt, STOP_RWATCH); - if (!(mmu_unit.flags & CACHE_ENB)) { - return mmu_memaccess (addr) & BITS48; - } + if (!(mmu_unit.flags & CACHE_ENB)) { + return mmu_memaccess (addr) & BITS48; + } - matching = mmu_match(addr, -1); + matching = mmu_match(addr, -1); - if (matching == -1) { - val = mmu_memaccess (addr); - } else { - /* старшинство обновляется, только если оно не затрагивает - * старший БРЗ (ТО-2). - */ - if (matching != OLDEST) - set_wins (matching); - val = BRZ[matching]; - if (sim_log && (mmu_dev.dctrl || (cpu_dev.dctrl && sim_deb))) { - fprintf (sim_log, "--- (%05o) чтение ", addr & BITS(15)); - fprint_sym (sim_log, 0, &val, 0, 0); - fprintf (sim_log, " из БРЗ\n"); - } - if (! IS_NUMBER (val)) { - iintr_data = matching; - besm6_debug ("--- (%05o) контроль числа БРЗ", addr); - longjmp (cpu_halt, STOP_CACHE_CHECK); - } - } - return val & BITS48; + if (matching == -1) { + val = mmu_memaccess (addr); + } else { + /* старшинство обновляется, только если оно не затрагивает + * старший БРЗ (ТО-2). + */ + if (matching != OLDEST) + set_wins (matching); + val = BRZ[matching]; + if (sim_log && (mmu_dev.dctrl || (cpu_dev.dctrl && sim_deb))) { + fprintf (sim_log, "--- (%05o) чтение ", addr & BITS(15)); + fprint_sym (sim_log, 0, &val, 0, 0); + fprintf (sim_log, " из БРЗ\n"); + } + if (! IS_NUMBER (val)) { + iintr_data = matching; + besm6_debug ("--- (%05o) контроль числа БРЗ", addr); + longjmp (cpu_halt, STOP_CACHE_CHECK); + } + } + return val & BITS48; } /* A little BRS LRU table */ -#define brs_loses_to_all(i) ((BRSLRU & brs_win_mask[i]) == 0 && \ - (BRSLRU & brs_lose_mask[i]) == brs_lose_mask[i]) +#define brs_loses_to_all(i) ((BRSLRU & brs_win_mask[i]) == 0 && \ + (BRSLRU & brs_lose_mask[i]) == brs_lose_mask[i]) /* * N wins over M if the bit is set @@ -455,37 +455,37 @@ t_value mmu_load (int addr) */ static unsigned brs_win_mask[4] = { - 07, - 03 << 3, - 01 << 5, - 0 + 07, + 03 << 3, + 01 << 5, + 0 }; static unsigned brs_lose_mask[8] = { - 0, - 1<<0, - 1<<1|1<<3, - 1<<2|1<<4|1<<5 + 0, + 1<<0, + 1<<1|1<<3, + 1<<2|1<<4|1<<5 }; #define brs_set_wins(i) BRSLRU = (BRSLRU & ~brs_lose_mask[i]) | brs_win_mask[i] void mmu_fetch_check (int addr) { - /* В режиме супервизора защиты нет */ - if (! IS_SUPERVISOR(RUU)) { - int page = TLB[addr >> 10]; - /* - * Для команд в режиме пользователя признак защиты - - * 0 в регистре приписки. - */ - if (page == 0) { - iintr_data = addr >> 10; - if (mmu_dev.dctrl) - besm6_debug ("--- (%05o) защита команды", addr); - longjmp (cpu_halt, STOP_INSN_PROT); - } - } + /* В режиме супервизора защиты нет */ + if (! IS_SUPERVISOR(RUU)) { + int page = TLB[addr >> 10]; + /* + * Для команд в режиме пользователя признак защиты - + * 0 в регистре приписки. + */ + if (page == 0) { + iintr_data = addr >> 10; + if (mmu_dev.dctrl) + besm6_debug ("--- (%05o) защита команды", addr); + longjmp (cpu_halt, STOP_INSN_PROT); + } + } } /* @@ -493,50 +493,50 @@ void mmu_fetch_check (int addr) */ t_value mmu_prefetch (int addr, int actual) { - t_value val; - int i; + t_value val; + int i; - if (mmu_unit.flags & CACHE_ENB) { - for (i = 0; i < 4; ++i) { - if (BAS[i] == addr) { - if (actual) { - brs_set_wins (i); - } - return BRS[i]; - } - } + if (mmu_unit.flags & CACHE_ENB) { + for (i = 0; i < 4; ++i) { + if (BAS[i] == addr) { + if (actual) { + brs_set_wins (i); + } + return BRS[i]; + } + } - for (i = 0; i < 4; ++i) { - if (brs_loses_to_all (i)) { - BAS[i] = addr; - if (actual) { - brs_set_wins (i); - } - break; - } - } - } else if (!actual) { - return 0; - } else { - /* Чтобы лампочки мигали */ - i = addr & 3; - } + for (i = 0; i < 4; ++i) { + if (brs_loses_to_all (i)) { + BAS[i] = addr; + if (actual) { + brs_set_wins (i); + } + break; + } + } + } else if (!actual) { + return 0; + } else { + /* Чтобы лампочки мигали */ + i = addr & 3; + } - if (addr < 0100000) { - int page = TLB[addr >> 10]; + if (addr < 0100000) { + int page = TLB[addr >> 10]; - /* Вычисляем физический адрес слова */ - addr = (addr & 01777) | (page << 10); - } else { - addr = addr & BITS(15); - } + /* Вычисляем физический адрес слова */ + addr = (addr & 01777) | (page << 10); + } else { + addr = addr & BITS(15); + } - if (addr < 010) - val = pult[addr]; - else - val = memory[addr]; - BRS[i] = val; - return val; + if (addr < 010) + val = pult[addr]; + else + val = memory[addr]; + BRS[i] = val; + return val; } /* @@ -544,109 +544,109 @@ t_value mmu_prefetch (int addr, int actual) */ t_value mmu_fetch (int addr) { - t_value val; + t_value val; - if (addr == 0) { - if (mmu_dev.dctrl) - besm6_debug ("--- передача управления на 0"); - longjmp (cpu_halt, STOP_INSN_CHECK); - } + if (addr == 0) { + if (mmu_dev.dctrl) + besm6_debug ("--- передача управления на 0"); + longjmp (cpu_halt, STOP_INSN_CHECK); + } - mmu_fetch_check(addr); + mmu_fetch_check(addr); - /* Различаем адреса с припиской и без */ - if (IS_SUPERVISOR (RUU)) - addr |= 0100000; + /* Различаем адреса с припиской и без */ + if (IS_SUPERVISOR (RUU)) + addr |= 0100000; - /* КРА */ - if (M[IBP] == addr) - longjmp(cpu_halt, STOP_INSN_ADDR_MATCH); + /* КРА */ + if (M[IBP] == addr) + longjmp(cpu_halt, STOP_INSN_ADDR_MATCH); - val = mmu_prefetch(addr, 1); + val = mmu_prefetch(addr, 1); - if (sim_log && mmu_dev.dctrl) { - fprintf (sim_log, "--- (%05o) выборка ", addr); - fprint_sym (sim_log, 0, &val, 0, SWMASK ('I')); - fprintf (sim_log, "\n"); - } + if (sim_log && mmu_dev.dctrl) { + fprintf (sim_log, "--- (%05o) выборка ", addr); + fprint_sym (sim_log, 0, &val, 0, SWMASK ('I')); + fprintf (sim_log, "\n"); + } - /* Тумблерные регистры пока только с командной сверткой */ - if (addr >= 010 && ! IS_INSN (val)) { - besm6_debug ("--- (%05o) контроль команды", addr); - longjmp (cpu_halt, STOP_INSN_CHECK); - } - return val & BITS48; + /* Тумблерные регистры пока только с командной сверткой */ + if (addr >= 010 && ! IS_INSN (val)) { + besm6_debug ("--- (%05o) контроль команды", addr); + longjmp (cpu_halt, STOP_INSN_CHECK); + } + return val & BITS48; } void mmu_setrp (int idx, t_value val) { - uint32 p0, p1, p2, p3; - const uint32 mask = (MEMSIZE >> 10) - 1; + uint32 p0, p1, p2, p3; + const uint32 mask = (MEMSIZE >> 10) - 1; - /* Младшие 5 разрядов 4-х регистров приписки упакованы - * по 5 в 1-20 рр, 6-е разряды - в 29-32 рр, 7-е разряды - в 33-36 рр и т.п. - */ - p0 = (val & 037) | (((val>>28) & 1) << 5) | (((val>>32) & 1) << 6) | - (((val>>36) & 1) << 7) | (((val>>40) & 1) << 8) | (((val>>44) & 1) << 9); - p1 = ((val>>5) & 037) | (((val>>29) & 1) << 5) | (((val>>33) & 1) << 6) | - (((val>>37) & 1) << 7) | (((val>>41) & 1) << 8) | (((val>>45) & 1) << 9); - p2 = ((val>>10) & 037) | (((val>>30) & 1) << 5) | (((val>>34) & 1) << 6) | - (((val>>38) & 1) << 7) | (((val>>42) & 1) << 8) | (((val>>46) & 1) << 9); - p3 = ((val>>15) & 037) | (((val>>31) & 1) << 5) | (((val>>35) & 1) << 6) | - (((val>>39) & 1) << 7) | (((val>>43) & 1) << 8) | (((val>>47) & 1) << 9); + /* Младшие 5 разрядов 4-х регистров приписки упакованы + * по 5 в 1-20 рр, 6-е разряды - в 29-32 рр, 7-е разряды - в 33-36 рр и т.п. + */ + p0 = (val & 037) | (((val>>28) & 1) << 5) | (((val>>32) & 1) << 6) | + (((val>>36) & 1) << 7) | (((val>>40) & 1) << 8) | (((val>>44) & 1) << 9); + p1 = ((val>>5) & 037) | (((val>>29) & 1) << 5) | (((val>>33) & 1) << 6) | + (((val>>37) & 1) << 7) | (((val>>41) & 1) << 8) | (((val>>45) & 1) << 9); + p2 = ((val>>10) & 037) | (((val>>30) & 1) << 5) | (((val>>34) & 1) << 6) | + (((val>>38) & 1) << 7) | (((val>>42) & 1) << 8) | (((val>>46) & 1) << 9); + p3 = ((val>>15) & 037) | (((val>>31) & 1) << 5) | (((val>>35) & 1) << 6) | + (((val>>39) & 1) << 7) | (((val>>43) & 1) << 8) | (((val>>47) & 1) << 9); - p0 &= mask; - p1 &= mask; - p2 &= mask; - p3 &= mask; + p0 &= mask; + p1 &= mask; + p2 &= mask; + p3 &= mask; - RP[idx] = p0 | p1 << 12 | p2 << 24 | (t_value) p3 << 36; - TLB[idx*4] = p0; - TLB[idx*4+1] = p1; - TLB[idx*4+2] = p2; - TLB[idx*4+3] = p3; + RP[idx] = p0 | p1 << 12 | p2 << 24 | (t_value) p3 << 36; + TLB[idx*4] = p0; + TLB[idx*4+1] = p1; + TLB[idx*4+2] = p2; + TLB[idx*4+3] = p3; } void mmu_setup () { - const uint32 mask = (MEMSIZE >> 10) - 1; - int i; + const uint32 mask = (MEMSIZE >> 10) - 1; + int i; - /* Перепись РПi в TLBj. */ - for (i=0; i<8; ++i) { - TLB[i*4] = RP[i] & mask; - TLB[i*4+1] = RP[i] >> 12 & mask; - TLB[i*4+2] = RP[i] >> 24 & mask; - TLB[i*4+3] = RP[i] >> 36 & mask; - } + /* Перепись РПi в TLBj. */ + for (i=0; i<8; ++i) { + TLB[i*4] = RP[i] & mask; + TLB[i*4+1] = RP[i] >> 12 & mask; + TLB[i*4+2] = RP[i] >> 24 & mask; + TLB[i*4+3] = RP[i] >> 36 & mask; + } } void mmu_setprotection (int idx, t_value val) { - /* Разряды сумматора, записываемые в регистр защиты - 21-28 */ - int mask = 0xff << (idx * 8); - val = ((val >> 20) & 0xff) << (idx * 8); - RZ = (RZ & ~mask) | val; + /* Разряды сумматора, записываемые в регистр защиты - 21-28 */ + int mask = 0xff << (idx * 8); + val = ((val >> 20) & 0xff) << (idx * 8); + RZ = (RZ & ~mask) | val; } void mmu_setcache (int idx, t_value val) { - BRZ[idx] = SET_CONVOL (val, RUU ^ CONVOL_INSN); + BRZ[idx] = SET_CONVOL (val, RUU ^ CONVOL_INSN); } t_value mmu_getcache (int idx) { - return BRZ[idx] & BITS48; + return BRZ[idx] & BITS48; } void mmu_print_brz () { - int i, k; + int i, k; - for (i=7; i>=0; --i) { - besm6_log_cont ("БРЗ [%d] = '", i); - for (k=47; k>=0; --k) - besm6_log_cont ("%c", (BRZ[i] >> k & 1) ? '*' : ' '); - besm6_log ("'"); - } + for (i=7; i>=0; --i) { + besm6_log_cont ("БРЗ [%d] = '", i); + for (k=47; k>=0; --k) + besm6_log_cont ("%c", (BRZ[i] >> k & 1) ? '*' : ' '); + besm6_log ("'"); + } } diff --git a/BESM6/besm6_panel.c b/BESM6/besm6_panel.c index 6b673ab1..e2bc2e73 100644 --- a/BESM6/besm6_panel.c +++ b/BESM6/besm6_panel.c @@ -37,17 +37,17 @@ /* * Use a 640x480 window with 32 bit pixels. */ -#define WIDTH 800 -#define HEIGHT 400 -#define DEPTH 32 +#define WIDTH 800 +#define HEIGHT 400 +#define DEPTH 32 -#define STEPX 14 -#define STEPY 16 +#define STEPX 14 +#define STEPY 16 -#define FONTNAME "LucidaSansRegular.ttf" -#define FONTPATH1 "/usr/share/fonts" -#define FONTPATH2 "/usr/lib/jvm" -#define FONTPATH3 "/System/Library/Frameworks/JavaVM.framework/Versions" +#define FONTNAME "LucidaSansRegular.ttf" +#define FONTPATH1 "/usr/share/fonts" +#define FONTPATH2 "/usr/lib/jvm" +#define FONTPATH3 "/System/Library/Frameworks/JavaVM.framework/Versions" #include #include @@ -66,8 +66,8 @@ static t_value old_BRZ [8], old_GRP [2]; static t_value old_M [NREGS]; static const int regnum[] = { - 013, 012, 011, 010, 7, 6, 5, 4, - 027, 016, 015, 014, 3, 2, 1, 020, + 013, 012, 011, 010, 7, 6, 5, 4, + 027, 016, 015, 014, 3, 2, 1, 020, }; static SDL_Surface *screen; @@ -79,51 +79,51 @@ static SDL_Surface *screen; */ static void render_utf8 (TTF_Font *font, int x, int y, int halign, char *message) { - SDL_Surface *text; - SDL_Rect area; + SDL_Surface *text; + SDL_Rect area; - /* Build image from text */ - text = TTF_RenderUTF8_Shaded (font, message, foreground, background); + /* Build image from text */ + text = TTF_RenderUTF8_Shaded (font, message, foreground, background); - area.x = x; - if (halign < 0) - area.x -= text->w; /* align left */ - else if (halign == 0) - area.x -= text->w / 2; /* center */ - area.y = y; - area.w = text->w; - area.h = text->h; + area.x = x; + if (halign < 0) + area.x -= text->w; /* align left */ + else if (halign == 0) + area.x -= text->w / 2; /* center */ + area.y = y; + area.w = text->w; + area.h = text->h; - /* Put text image to screen */ - SDL_BlitSurface (text, 0, screen, &area); - SDL_FreeSurface (text); + /* Put text image to screen */ + SDL_BlitSurface (text, 0, screen, &area); + SDL_FreeSurface (text); } static SDL_Surface *sprite_from_data (int width, int height, - const unsigned char *data) + const unsigned char *data) { - SDL_Surface *sprite, *optimized; - unsigned *s, r, g, b, y, x; + SDL_Surface *sprite, *optimized; + unsigned *s, r, g, b, y, x; - sprite = SDL_CreateRGBSurface (SDL_SWSURFACE, - width, height, DEPTH, 0, 0, 0, 0); - /* - optimized = SDL_DisplayFormat (sprite); - SDL_FreeSurface (sprite); - sprite = optimized; - */ - SDL_LockSurface (sprite); - for (y=0; ypixels + y * sprite->pitch); - for (x=0; xformat, r, g, b); - } - } - SDL_UnlockSurface (sprite); - return sprite; + sprite = SDL_CreateRGBSurface (SDL_SWSURFACE, + width, height, DEPTH, 0, 0, 0, 0); + /* + optimized = SDL_DisplayFormat (sprite); + SDL_FreeSurface (sprite); + sprite = optimized; + */ + SDL_LockSurface (sprite); + for (y=0; ypixels + y * sprite->pitch); + for (x=0; xformat, r, g, b); + } + } + SDL_UnlockSurface (sprite); + return sprite; } /* @@ -131,54 +131,54 @@ static SDL_Surface *sprite_from_data (int width, int height, */ static void draw_lamp (int left, int top, int on) { - /* Images created by GIMP: save as C file without alpha channel. */ - static const int lamp_width = 12; - static const int lamp_height = 12; - static const unsigned char lamp_on [12 * 12 * 3 + 1] = - "\0\0\0\0\0\0\0\0\0\13\2\2-\14\14e\31\31e\31\31-\14\14\13\2\2\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0D\20\20\313,,\377??\377CC\377CC\377DD\31333D\21\21\0\0" - "\0\0\0\0\0\0\0D\20\20\357LL\377\243\243\376~~\37699\376@@\376@@\377AA\357" - "<>\377@@\377@@\377AA\31333\13\2\2-\14\14\377??\376~~\377\356\356\377\321" - "\321\377<<\377??\377@@\377@@\376@@\377DD-\14\14e\31\31\377CC\37699\377NN" - "\377<<\377??\377@@\377@@\377@@\376??\377CCe\31\31e\31\31\377CC\376@@\377" - ">>\377??\377@@\377@@\377@@\377@@\376??\377CCe\31\31-\14\14\377DD\376@@\377" - "@@\377@@\377@@\377@@\377@@\377@@\376@@\377DD-\14\14\13\2\2\31333\377AA\377" - "@@\377@@\377@@\377@@\377@@\377@@\377AA\31333\13\2\2\0\0\0D\21\21\357<<\377" - "AA\376@@\376??\376??\376@@\377AA\357<>\377@@\377@@\377AA\31333\13\2\2-\14\14\377??\376~~\377\356\356\377\321" + "\321\377<<\377??\377@@\377@@\376@@\377DD-\14\14e\31\31\377CC\37699\377NN" + "\377<<\377??\377@@\377@@\377@@\376??\377CCe\31\31e\31\31\377CC\376@@\377" + ">>\377??\377@@\377@@\377@@\377@@\376??\377CCe\31\31-\14\14\377DD\376@@\377" + "@@\377@@\377@@\377@@\377@@\377@@\376@@\377DD-\14\14\13\2\2\31333\377AA\377" + "@@\377@@\377@@\377@@\377@@\377@@\377AA\31333\13\2\2\0\0\0D\21\21\357<<\377" + "AA\376@@\376??\376??\376@@\377AA\357<> (14-x) & 1); - } - } + for (y=0; y<8; ++y) { + reg = regnum [y + group*8]; + val = M [reg]; + if (val == old_M [reg]) + continue; + old_M [reg] = val; + for (x=0; x<15; ++x) { + draw_lamp (left+76 + x*STEPX, top+28 + y*STEPY, val >> (14-x) & 1); + } + } } /* @@ -205,18 +205,18 @@ static void draw_modifiers_periodic (int group, int left, int top) */ static void draw_grp_periodic (int top) { - int x, y; - t_value val; + int x, y; + t_value val; - for (y=0; y<2; ++y) { - val = y ? MGRP : GRP; - if (val == old_GRP [y]) - continue; - old_GRP [y] = val; - for (x=0; x<48; ++x) { - draw_lamp (100 + x*STEPX, top+28 + y*STEPY, val >> (47-x) & 1); - } - } + for (y=0; y<2; ++y) { + val = y ? MGRP : GRP; + if (val == old_GRP [y]) + continue; + old_GRP [y] = val; + for (x=0; x<48; ++x) { + draw_lamp (100 + x*STEPX, top+28 + y*STEPY, val >> (47-x) & 1); + } + } } /* @@ -224,18 +224,18 @@ static void draw_grp_periodic (int top) */ static void draw_brz_periodic (int top) { - int x, y; - t_value val; + int x, y; + t_value val; - for (y=0; y<8; ++y) { - val = BRZ [7-y]; - if (val == old_BRZ [7-y]) - continue; - 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 (y=0; y<8; ++y) { + val = BRZ [7-y]; + if (val == old_BRZ [7-y]) + continue; + old_BRZ [7-y] = val; + for (x=0; x<48; ++x) { + draw_lamp (100 + x*STEPX, top+28 + y*STEPY, val >> (47-x) & 1); + } + } } /* @@ -243,35 +243,35 @@ static void draw_brz_periodic (int top) */ static void draw_modifiers_static (int group, int left, int top) { - int x, y, color, reg; - char message [40]; - SDL_Rect area; + int x, y, color, reg; + char message [40]; + SDL_Rect area; - background = black; - foreground = cyan; + background = black; + foreground = cyan; - /* Оттеняем группы разрядов. */ - color = grey.r << 16 | grey.g << 8 | grey.b; - for (x=3; x<15; x+=3) { - area.x = left + 74 + x*STEPX; - area.y = top + 26; - area.w = 2; - area.h = 8*STEPY + 2; - SDL_FillRect (screen, &area, color); - } - /* Названия регистров. */ - for (y=0; y<8; ++y) { - reg = regnum [y + group*8]; - sprintf (message, "М%2o", reg); - render_utf8 (font_big, left, top + 24 + y*STEPY, 1, message); - old_M [reg] = ~0; - } - /* Номера битов. */ - for (x=0; x<15; ++x) { - sprintf (message, "%d", 15-x); - render_utf8 (font_small, left+82 + x*STEPX, - (x & 1) ? top+4 : top+10, 0, message); - } + /* Оттеняем группы разрядов. */ + color = grey.r << 16 | grey.g << 8 | grey.b; + for (x=3; x<15; x+=3) { + area.x = left + 74 + x*STEPX; + area.y = top + 26; + area.w = 2; + area.h = 8*STEPY + 2; + SDL_FillRect (screen, &area, color); + } + /* Названия регистров. */ + for (y=0; y<8; ++y) { + reg = regnum [y + group*8]; + sprintf (message, "М%2o", reg); + render_utf8 (font_big, left, top + 24 + y*STEPY, 1, message); + old_M [reg] = ~0; + } + /* Номера битов. */ + for (x=0; x<15; ++x) { + sprintf (message, "%d", 15-x); + render_utf8 (font_small, left+82 + x*STEPX, + (x & 1) ? top+4 : top+10, 0, message); + } } /* @@ -279,33 +279,33 @@ static void draw_modifiers_static (int group, int left, int top) */ static void draw_grp_static (int top) { - int x, y, color; - char message [40]; - SDL_Rect area; + int x, y, color; + char message [40]; + SDL_Rect area; - background = black; - foreground = cyan; + background = black; + foreground = cyan; - /* Оттеняем группы разрядов. */ - color = grey.r << 16 | grey.g << 8 | grey.b; - for (x=3; x<48; x+=3) { - area.x = 98 + x*STEPX; - area.y = top + 26; - area.w = 2; - area.h = 2*STEPY + 2; - SDL_FillRect (screen, &area, color); - } - /* Названия регистров. */ - for (y=0; y<2; ++y) { - render_utf8 (font_big, 24, top + 24 + y*STEPY, 1, y ? "МГРП" : "ГРП"); - old_GRP[y] = ~0; - } - /* Номера битов. */ - for (x=0; x<48; ++x) { - sprintf (message, "%d", 48-x); - render_utf8 (font_small, 106 + x*STEPX, - (x & 1) ? top+10 : top+4, 0, message); - } + /* Оттеняем группы разрядов. */ + color = grey.r << 16 | grey.g << 8 | grey.b; + for (x=3; x<48; x+=3) { + area.x = 98 + x*STEPX; + area.y = top + 26; + area.w = 2; + area.h = 2*STEPY + 2; + SDL_FillRect (screen, &area, color); + } + /* Названия регистров. */ + for (y=0; y<2; ++y) { + render_utf8 (font_big, 24, top + 24 + y*STEPY, 1, y ? "МГРП" : "ГРП"); + old_GRP[y] = ~0; + } + /* Номера битов. */ + for (x=0; x<48; ++x) { + sprintf (message, "%d", 48-x); + render_utf8 (font_small, 106 + x*STEPX, + (x & 1) ? top+10 : top+4, 0, message); + } } /* @@ -313,28 +313,28 @@ static void draw_grp_static (int top) */ static void draw_brz_static (int top) { - int x, y, color; - char message [40]; - SDL_Rect area; + int x, y, color; + char message [40]; + SDL_Rect area; - background = black; - foreground = cyan; + background = black; + foreground = cyan; - /* Оттеняем группы разрядов. */ - color = grey.r << 16 | grey.g << 8 | grey.b; - for (x=3; x<48; x+=3) { - area.x = 98 + x*STEPX; - area.y = top + 26; - area.w = 2; - area.h = 8*STEPY + 2; - SDL_FillRect (screen, &area, color); - } - /* Названия регистров. */ - for (y=7; y>=0; --y) { - sprintf (message, "БРЗ %d", 7-y); - render_utf8 (font_big, 24, top + 24 + y*STEPY, 1, message); - old_BRZ[y] = ~0; - } + /* Оттеняем группы разрядов. */ + color = grey.r << 16 | grey.g << 8 | grey.b; + for (x=3; x<48; x+=3) { + area.x = 98 + x*STEPX; + area.y = top + 26; + area.w = 2; + area.h = 8*STEPY + 2; + SDL_FillRect (screen, &area, color); + } + /* Названия регистров. */ + for (y=7; y>=0; --y) { + sprintf (message, "БРЗ %d", 7-y); + render_utf8 (font_big, 24, top + 24 + y*STEPY, 1, message); + old_BRZ[y] = ~0; + } } /* @@ -342,15 +342,15 @@ static void draw_brz_static (int top) */ static int probe_font (const char *path, const struct stat *st, int flag) { - const char *p; + const char *p; - if (flag != FTW_F) - return 0; - p = path + strlen (path) - strlen (FONTNAME); - if (p < path || strcmp (p, FONTNAME) != 0) - return 0; - font_path = strdup (path); - return 1; + if (flag != FTW_F) + return 0; + p = path + strlen (path) - strlen (FONTNAME); + if (p < path || strcmp (p, FONTNAME) != 0) + return 0; + font_path = strdup (path); + return 1; } /* @@ -358,11 +358,11 @@ static int probe_font (const char *path, const struct stat *st, int flag) */ void besm6_close_panel () { - if (! screen) - return; - TTF_Quit(); - SDL_Quit(); - screen = 0; + if (! screen) + return; + TTF_Quit(); + SDL_Quit(); + screen = 0; } #if SDL_MAJOR_VERSION == 2 @@ -377,81 +377,81 @@ static SDL_Texture *sdlTexture; */ static void init_panel () { - if (sim_switches & SWMASK('Q')) - return; + if (sim_switches & SWMASK('Q')) + return; - /* Initialize SDL subsystems - in this case, only video. */ - if (SDL_Init (SDL_INIT_VIDEO) < 0) { - fprintf (stderr, "SDL: unable to init: %s\n", - SDL_GetError ()); - exit (1); - } - sdlWindow = SDL_CreateWindow ("BESM-6 panel", - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - WIDTH, HEIGHT, 0 /* regular window */); - if (! sdlWindow) { - fprintf (stderr, "SDL: unable to set %dx%dx%d mode: %s\n", - WIDTH, HEIGHT, DEPTH, SDL_GetError ()); - exit (1); - } + /* Initialize SDL subsystems - in this case, only video. */ + if (SDL_Init (SDL_INIT_VIDEO) < 0) { + fprintf (stderr, "SDL: unable to init: %s\n", + SDL_GetError ()); + exit (1); + } + sdlWindow = SDL_CreateWindow ("BESM-6 panel", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + WIDTH, HEIGHT, 0 /* regular window */); + if (! sdlWindow) { + fprintf (stderr, "SDL: unable to set %dx%dx%d mode: %s\n", + WIDTH, HEIGHT, DEPTH, SDL_GetError ()); + exit (1); + } - sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, 0); - /* Make black background */ - SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, 255); - SDL_RenderClear(sdlRenderer); + sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, 0); + /* Make black background */ + SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, 255); + SDL_RenderClear(sdlRenderer); - /* Initialize the TTF library */ - if (TTF_Init() < 0) { - fprintf (stderr, "SDL: couldn't initialize TTF: %s\n", - SDL_GetError()); - SDL_Quit(); - exit (1); - } + /* Initialize the TTF library */ + if (TTF_Init() < 0) { + fprintf (stderr, "SDL: couldn't initialize TTF: %s\n", + SDL_GetError()); + SDL_Quit(); + exit (1); + } - /* Find font file */ - if (ftw (FONTPATH1, probe_font, 255) <= 0 && - ftw (FONTPATH2, probe_font, 255) <= 0 && - ftw (FONTPATH3, probe_font, 255) <= 0) { - fprintf(stderr, "SDL: couldn't find font %s in directory %s\n", - FONTNAME, FONTPATH1); - besm6_close_panel(); - exit (1); - } + /* Find font file */ + if (ftw (FONTPATH1, probe_font, 255) <= 0 && + ftw (FONTPATH2, probe_font, 255) <= 0 && + ftw (FONTPATH3, probe_font, 255) <= 0) { + fprintf(stderr, "SDL: couldn't find font %s in directory %s\n", + FONTNAME, FONTPATH1); + besm6_close_panel(); + exit (1); + } - /* Open the font file with the requested point size */ - font_big = TTF_OpenFont (font_path, 16); - font_small = TTF_OpenFont (font_path, 9); - if (! font_big || ! font_small) { - fprintf(stderr, "SDL: couldn't load font %s: %s\n", - font_path, SDL_GetError()); - besm6_close_panel(); - exit (1); - } - atexit (besm6_close_panel); + /* Open the font file with the requested point size */ + font_big = TTF_OpenFont (font_path, 16); + font_small = TTF_OpenFont (font_path, 9); + if (! font_big || ! font_small) { + fprintf(stderr, "SDL: couldn't load font %s: %s\n", + font_path, SDL_GetError()); + besm6_close_panel(); + exit (1); + } + atexit (besm6_close_panel); - screen = SDL_CreateRGBSurface(0, WIDTH, HEIGHT, 32, - 0x00FF0000, - 0x0000FF00, - 0x000000FF, - 0xFF000000); + screen = SDL_CreateRGBSurface(0, WIDTH, HEIGHT, 32, + 0x00FF0000, + 0x0000FF00, + 0x000000FF, + 0xFF000000); - sdlTexture = SDL_CreateTexture(sdlRenderer, - SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STATIC, - WIDTH, HEIGHT); + sdlTexture = SDL_CreateTexture(sdlRenderer, + SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STATIC, + WIDTH, HEIGHT); - /* Отрисовка статичной части панели БЭСМ-6. */ - draw_modifiers_static (0, 24, 10); - draw_modifiers_static (1, 400, 10); - draw_grp_static (180); - draw_brz_static (230); + /* Отрисовка статичной части панели БЭСМ-6. */ + draw_modifiers_static (0, 24, 10); + draw_modifiers_static (1, 400, 10); + draw_grp_static (180); + draw_brz_static (230); - /* Tell SDL to update the whole screen */ - SDL_UpdateTexture(sdlTexture, NULL, screen->pixels, screen->pitch); - SDL_RenderClear(sdlRenderer); - SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL); - SDL_RenderPresent (sdlRenderer); + /* Tell SDL to update the whole screen */ + SDL_UpdateTexture(sdlTexture, NULL, screen->pixels, screen->pitch); + SDL_RenderClear(sdlRenderer); + SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL); + SDL_RenderPresent (sdlRenderer); } void (*sim_vm_init)() = init_panel; @@ -461,25 +461,25 @@ void (*sim_vm_init)() = init_panel; */ void besm6_draw_panel () { - if (! screen) - return; + if (! screen) + return; - /* Периодическая отрисовка: мигание лампочек. */ - draw_modifiers_periodic (0, 24, 10); - draw_modifiers_periodic (1, 400, 10); - draw_grp_periodic (180); - draw_brz_periodic (230); + /* Периодическая отрисовка: мигание лампочек. */ + draw_modifiers_periodic (0, 24, 10); + draw_modifiers_periodic (1, 400, 10); + draw_grp_periodic (180); + draw_brz_periodic (230); - /* Tell SDL to update the whole screen */ - SDL_UpdateTexture(sdlTexture, NULL, screen->pixels, screen->pitch); - SDL_RenderClear(sdlRenderer); - SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL); - SDL_RenderPresent (sdlRenderer); + /* Tell SDL to update the whole screen */ + SDL_UpdateTexture(sdlTexture, NULL, screen->pixels, screen->pitch); + SDL_RenderClear(sdlRenderer); + SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL); + SDL_RenderPresent (sdlRenderer); - /* Exit SIMH when window closed.*/ - SDL_Event event; - if (SDL_PollEvent (&event) && event.type == SDL_QUIT) - longjmp (cpu_halt, SCPE_STOP); + /* Exit SIMH when window closed.*/ + SDL_Event event; + if (SDL_PollEvent (&event) && event.type == SDL_QUIT) + longjmp (cpu_halt, SCPE_STOP); } #else @@ -489,59 +489,59 @@ void besm6_draw_panel () */ static void init_panel () { - if (sim_switches & SWMASK('Q')) - return; + if (sim_switches & SWMASK('Q')) + return; - /* Initialize SDL subsystems - in this case, only video. */ - if (SDL_Init (SDL_INIT_VIDEO) < 0) { - fprintf (stderr, "SDL: unable to init: %s\n", - SDL_GetError ()); - exit (1); - } - screen = SDL_SetVideoMode (WIDTH, HEIGHT, DEPTH, SDL_SWSURFACE); - if (! screen) { - fprintf (stderr, "SDL: unable to set %dx%dx%d mode: %s\n", - WIDTH, HEIGHT, DEPTH, SDL_GetError ()); - exit (1); - } + /* Initialize SDL subsystems - in this case, only video. */ + if (SDL_Init (SDL_INIT_VIDEO) < 0) { + fprintf (stderr, "SDL: unable to init: %s\n", + SDL_GetError ()); + exit (1); + } + screen = SDL_SetVideoMode (WIDTH, HEIGHT, DEPTH, SDL_SWSURFACE); + if (! screen) { + fprintf (stderr, "SDL: unable to set %dx%dx%d mode: %s\n", + WIDTH, HEIGHT, DEPTH, SDL_GetError ()); + exit (1); + } - /* Initialize the TTF library */ - if (TTF_Init() < 0) { - fprintf (stderr, "SDL: couldn't initialize TTF: %s\n", - SDL_GetError()); - SDL_Quit(); - exit (1); - } + /* Initialize the TTF library */ + if (TTF_Init() < 0) { + fprintf (stderr, "SDL: couldn't initialize TTF: %s\n", + SDL_GetError()); + SDL_Quit(); + exit (1); + } - /* Find font file */ - if (ftw (FONTPATH1, probe_font, 255) <= 0 && - ftw (FONTPATH2, probe_font, 255) <= 0 && - ftw (FONTPATH3, probe_font, 255) <= 0) { - fprintf(stderr, "SDL: couldn't find font %s in directory %s\n", - FONTNAME, FONTPATH1); - besm6_close_panel(); - exit (1); - } + /* Find font file */ + if (ftw (FONTPATH1, probe_font, 255) <= 0 && + ftw (FONTPATH2, probe_font, 255) <= 0 && + ftw (FONTPATH3, probe_font, 255) <= 0) { + fprintf(stderr, "SDL: couldn't find font %s in directory %s\n", + FONTNAME, FONTPATH1); + besm6_close_panel(); + exit (1); + } - /* Open the font file with the requested point size */ - font_big = TTF_OpenFont (font_path, 16); - font_small = TTF_OpenFont (font_path, 9); - if (! font_big || ! font_small) { - fprintf(stderr, "SDL: couldn't load font %s: %s\n", - FONTNAME, TTF_GetError()); - besm6_close_panel(); - exit (1); - } - atexit (besm6_close_panel); + /* Open the font file with the requested point size */ + font_big = TTF_OpenFont (font_path, 16); + font_small = TTF_OpenFont (font_path, 9); + if (! font_big || ! font_small) { + fprintf(stderr, "SDL: couldn't load font %s: %s\n", + FONTNAME, TTF_GetError()); + besm6_close_panel(); + exit (1); + } + atexit (besm6_close_panel); - /* Отрисовка статичной части панели БЭСМ-6. */ - draw_modifiers_static (0, 24, 10); - draw_modifiers_static (1, 400, 10); - draw_grp_static (180); - draw_brz_static (230); + /* Отрисовка статичной части панели БЭСМ-6. */ + draw_modifiers_static (0, 24, 10); + draw_modifiers_static (1, 400, 10); + draw_grp_static (180); + draw_brz_static (230); - /* Tell SDL to update the whole screen */ - SDL_UpdateRect (screen, 0, 0, WIDTH, HEIGHT); + /* Tell SDL to update the whole screen */ + SDL_UpdateRect (screen, 0, 0, WIDTH, HEIGHT); } void (*sim_vm_init)() = init_panel; @@ -551,27 +551,27 @@ void (*sim_vm_init)() = init_panel; */ void besm6_draw_panel () { - if (! screen) - return; + if (! screen) + return; - /* Периодическая отрисовка: мигание лампочек. */ - draw_modifiers_periodic (0, 24, 10); - draw_modifiers_periodic (1, 400, 10); - draw_grp_periodic (180); - draw_brz_periodic (230); + /* Периодическая отрисовка: мигание лампочек. */ + draw_modifiers_periodic (0, 24, 10); + draw_modifiers_periodic (1, 400, 10); + draw_grp_periodic (180); + draw_brz_periodic (230); - /* Tell SDL to update the whole screen */ - SDL_UpdateRect (screen, 0, 0, WIDTH, HEIGHT); + /* Tell SDL to update the whole screen */ + SDL_UpdateRect (screen, 0, 0, WIDTH, HEIGHT); - /* Exit SIMH when window closed.*/ - SDL_Event event; - if (SDL_PollEvent (&event) && event.type == SDL_QUIT) - longjmp (cpu_halt, SCPE_STOP); + /* Exit SIMH when window closed.*/ + SDL_Event event; + if (SDL_PollEvent (&event) && event.type == SDL_QUIT) + longjmp (cpu_halt, SCPE_STOP); } -#if !defined(__WIN32__) && \ - !(defined(__MWERKS__) && !defined(__BEOS__)) && \ - !defined(__MACOS__) && !defined(__MACOSX__) && \ +#if !defined(__WIN32__) && \ + !(defined(__MWERKS__) && !defined(__BEOS__)) && \ + !defined(__MACOS__) && !defined(__MACOSX__) && \ !defined(__SYMBIAN32__) && !defined(QWS) #undef main @@ -580,9 +580,9 @@ void besm6_draw_panel () */ int main (int argc, char *argv[]) { - extern int SDL_main (int, char**); + extern int SDL_main (int, char**); - return SDL_main (argc, argv); + return SDL_main (argc, argv); } #endif #endif /* SDL_MAJOR_VERSION */ diff --git a/BESM6/besm6_printer.c b/BESM6/besm6_printer.c index d6dee824..8cf88bf7 100644 --- a/BESM6/besm6_printer.c +++ b/BESM6/besm6_printer.c @@ -34,22 +34,22 @@ void offset_gost_write (int num, FILE *fout); /* * Printer data structures * - * printer_dev PRINTER device descriptor - * printer_unit PRINTER unit descriptor - * printer_reg PRINTER register list + * printer_dev PRINTER device descriptor + * printer_unit PRINTER unit descriptor + * printer_reg PRINTER register list */ UNIT printer_unit [] = { - { UDATA (printer_event, UNIT_ATTABLE+UNIT_SEQ, 0) }, - { UDATA (printer_event, UNIT_ATTABLE+UNIT_SEQ, 0) }, + { UDATA (printer_event, UNIT_ATTABLE+UNIT_SEQ, 0) }, + { UDATA (printer_event, UNIT_ATTABLE+UNIT_SEQ, 0) }, }; #define MAX_STRIKES 10 struct acpu_t { - int curchar, feed, rampup; - int strikes; - int length; - unsigned char line[128][MAX_STRIKES]; + int curchar, feed, rampup; + int strikes; + int length; + unsigned char line[128][MAX_STRIKES]; } acpu[2]; int acpu_isatty[2]; @@ -61,18 +61,18 @@ int acpu_isatty[2]; #define PRN1_LINEFEED (1<<23) #define PRN2_LINEFEED (1<<22) -#define SLOW_START 100*MSEC -#define FAST_START 1*MSEC -#define LINEFEED_SYNC 1 /* Чтобы быстрее печатало; в жизни 20-25 мс/1.4 мс ~= 17 */ +#define SLOW_START 100*MSEC +#define FAST_START 1*MSEC +#define LINEFEED_SYNC 1 /* Чтобы быстрее печатало; в жизни 20-25 мс/1.4 мс ~= 17 */ REG printer_reg[] = { -{ "Готов", &READY, 2, 2, 18, 1 }, -{ "Прогон", &READY, 2, 2, 22, 1 }, -{ 0 } + { "Готов", &READY, 2, 2, 18, 1 }, + { "Прогон", &READY, 2, 2, 22, 1 }, + { 0 } }; MTAB printer_mod[] = { - { 0 } + { 0 } }; t_stat printer_reset (DEVICE *dptr); @@ -80,10 +80,10 @@ t_stat printer_attach (UNIT *uptr, char *cptr); t_stat printer_detach (UNIT *uptr); DEVICE printer_dev = { - "PRN", printer_unit, printer_reg, printer_mod, - 2, 8, 19, 1, 8, 50, - NULL, NULL, &printer_reset, NULL, &printer_attach, &printer_detach, - NULL, DEV_DISABLE | DEV_DEBUG + "PRN", printer_unit, printer_reg, printer_mod, + 2, 8, 19, 1, 8, 50, + NULL, NULL, &printer_reset, NULL, &printer_attach, &printer_detach, + NULL, DEV_DISABLE | DEV_DEBUG }; /* @@ -91,46 +91,46 @@ DEVICE printer_dev = { */ t_stat printer_reset (DEVICE *dptr) { - memset(acpu, 0, sizeof (acpu)); - acpu[0].rampup = acpu[1].rampup = SLOW_START; - sim_cancel (&printer_unit[0]); - sim_cancel (&printer_unit[1]); - READY |= PRN1_NOT_READY | PRN2_NOT_READY; - if (printer_unit[0].flags & UNIT_ATT) - READY &= ~PRN1_NOT_READY; - if (printer_unit[1].flags & UNIT_ATT) - READY &= ~PRN2_NOT_READY; - return SCPE_OK; + memset(acpu, 0, sizeof (acpu)); + acpu[0].rampup = acpu[1].rampup = SLOW_START; + sim_cancel (&printer_unit[0]); + sim_cancel (&printer_unit[1]); + READY |= PRN1_NOT_READY | PRN2_NOT_READY; + if (printer_unit[0].flags & UNIT_ATT) + READY &= ~PRN1_NOT_READY; + if (printer_unit[1].flags & UNIT_ATT) + READY &= ~PRN2_NOT_READY; + return SCPE_OK; } t_stat printer_attach (UNIT *u, char *cptr) { - t_stat s; - int num = u - printer_unit; + t_stat s; + int num = u - printer_unit; - if (u->flags & UNIT_ATT) { - /* Switching files cleanly */ - detach_unit (u); - } - s = attach_unit (u, cptr); - if (s != SCPE_OK) - return s; + if (u->flags & UNIT_ATT) { + /* Switching files cleanly */ + detach_unit (u); + } + s = attach_unit (u, cptr); + if (s != SCPE_OK) + return s; - acpu_isatty[num] = !strcmp(cptr, "/dev/tty"); - if (!acpu_isatty[num]) { - /* Write UTF-8 tag: zero width no-break space. */ - fputs ("\xEF\xBB\xBF", u->fileref); - } + acpu_isatty[num] = !strcmp(cptr, "/dev/tty"); + if (!acpu_isatty[num]) { + /* Write UTF-8 tag: zero width no-break space. */ + fputs ("\xEF\xBB\xBF", u->fileref); + } - READY &= ~(PRN1_NOT_READY >> num); - return SCPE_OK; + READY &= ~(PRN1_NOT_READY >> num); + return SCPE_OK; } t_stat printer_detach (UNIT *u) { - int num = u - printer_unit; - READY |= PRN1_NOT_READY >> num; - return detach_unit (u); + int num = u - printer_unit; + READY |= PRN1_NOT_READY >> num; + return detach_unit (u); } /* @@ -138,37 +138,37 @@ t_stat printer_detach (UNIT *u) */ void printer_control (int num, uint32 cmd) { - UNIT *u = &printer_unit[num]; - struct acpu_t * dev = acpu + num; + UNIT *u = &printer_unit[num]; + struct acpu_t * dev = acpu + num; - if (printer_dev.dctrl) - besm6_debug(">>> АЦПУ%d команда %o", num, cmd); - if (READY & (PRN1_NOT_READY >> num)) { - if (printer_dev.dctrl) - besm6_debug(">>> АЦПУ%d не готово", num, cmd); - return; - } - switch (cmd) { - case 1: /* linefeed */ - READY &= ~(PRN1_LINEFEED >> num); - offset_gost_write (num, u->fileref); - dev->feed = LINEFEED_SYNC; - break; - case 4: /* start */ - /* стартуем из состояния прогона для надежности */ - dev->feed = LINEFEED_SYNC; - READY &= ~(PRN1_LINEFEED >> num); - if (dev->rampup) - sim_activate (u, dev->rampup); - dev->rampup = 0; - break; - case 10: /* motor and ribbon off */ - case 8: /* motor off? (undocumented) */ - case 2: /* ribbon off */ - dev->rampup = cmd == 2 ? FAST_START : SLOW_START; - sim_cancel (u); - break; - } + if (printer_dev.dctrl) + besm6_debug(">>> АЦПУ%d команда %o", num, cmd); + if (READY & (PRN1_NOT_READY >> num)) { + if (printer_dev.dctrl) + besm6_debug(">>> АЦПУ%d не готово", num, cmd); + return; + } + switch (cmd) { + case 1: /* linefeed */ + READY &= ~(PRN1_LINEFEED >> num); + offset_gost_write (num, u->fileref); + dev->feed = LINEFEED_SYNC; + break; + case 4: /* start */ + /* стартуем из состояния прогона для надежности */ + dev->feed = LINEFEED_SYNC; + READY &= ~(PRN1_LINEFEED >> num); + if (dev->rampup) + sim_activate (u, dev->rampup); + dev->rampup = 0; + break; + case 10: /* motor and ribbon off */ + case 8: /* motor off? (undocumented) */ + case 2: /* ribbon off */ + dev->rampup = cmd == 2 ? FAST_START : SLOW_START; + sim_cancel (u); + break; + } } /* @@ -176,23 +176,23 @@ void printer_control (int num, uint32 cmd) */ void printer_hammer (int num, int pos, uint32 mask) { - struct acpu_t * dev = acpu + num; - while (mask) { - if (mask & 1) { - int strike = 0; - while (dev->line[pos][strike] && strike < MAX_STRIKES) - ++strike; - if (strike < MAX_STRIKES) { - dev->line[pos][strike] = dev->curchar; - if (pos + 1 > dev->length) - dev->length = pos + 1; - if (strike + 1 > dev->strikes) - dev->strikes = strike + 1; - } - } - mask >>= 1; - pos += 8; - } + struct acpu_t * dev = acpu + num; + while (mask) { + if (mask & 1) { + int strike = 0; + while (dev->line[pos][strike] && strike < MAX_STRIKES) + ++strike; + if (strike < MAX_STRIKES) { + dev->line[pos][strike] = dev->curchar; + if (pos + 1 > dev->length) + dev->length = pos + 1; + if (strike + 1 > dev->strikes) + dev->strikes = strike + 1; + } + } + mask >>= 1; + pos += 8; + } } /* @@ -201,30 +201,27 @@ void printer_hammer (int num, int pos, uint32 mask) */ t_stat printer_event (UNIT *u) { - int num = u - printer_unit; - struct acpu_t * dev = acpu + num; + int num = u - printer_unit; + struct acpu_t * dev = acpu + num; - switch (dev->curchar) { - case 0 ... 0137: - GRP |= GRP_PRN1_SYNC >> num; - ++dev->curchar; - /* For next char */ - sim_activate (u, 1400*USEC); - if (dev->feed && --dev->feed == 0) { - READY |= PRN1_LINEFEED >> num; - } - break; - case 0140: - /* For "zero" */ - dev->curchar = 0; - GRP |= GRP_PRN1_ZERO >> num; - if (printer_dev.dctrl) - besm6_debug(">>> АЦПУ%d 'ноль'", num); - /* For first sync after "zero" */ - sim_activate (u, 1000*USEC); - break; - } - return SCPE_OK; + if (dev->curchar < 0140) { + GRP |= GRP_PRN1_SYNC >> num; + ++dev->curchar; + /* For next char */ + sim_activate (u, 1400*USEC); + if (dev->feed && --dev->feed == 0) { + READY |= PRN1_LINEFEED >> num; + } + } else { + /* For "zero" */ + dev->curchar = 0; + GRP |= GRP_PRN1_ZERO >> num; + if (printer_dev.dctrl) + besm6_debug(">>> АЦПУ%d 'ноль'", num); + /* For first sync after "zero" */ + sim_activate (u, 1000*USEC); + } + return SCPE_OK; } int gost_latin = 0; /* default cyrillics */ @@ -234,33 +231,33 @@ int gost_latin = 0; /* default cyrillics */ * Documentation: http://en.wikipedia.org/wiki/GOST_10859 */ static const unsigned short gost_to_unicode_cyr [256] = { -/* 000-007 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, -/* 010-017 */ 0x38, 0x39, 0x2b, 0x2d, 0x2f, 0x2c, 0x2e, 0x2423, -/* 020-027 */ 0x65, 0x2191, 0x28, 0x29, 0xd7, 0x3d, 0x3b, 0x5b, -/* 030-037 */ 0x5d, 0x2a, 0x2018, 0x2019, 0x2260, 0x3c, 0x3e, 0x3a, -/* 040-047 */ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, -/* 050-057 */ 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, -/* 060-067 */ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, -/* 070-077 */ 0x0428, 0x0429, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x44, -/* 100-107 */ 0x46, 0x47, 0x49, 0x4a, 0x4c, 0x4e, 0x51, 0x52, -/* 110-117 */ 0x53, 0x55, 0x56, 0x57, 0x5a, 0x203e, 0x2264, 0x2265, -/* 120-127 */ 0x2228, 0x2227, 0x2283, 0xac, 0xf7, 0x2261, 0x25, 0x25c7, -/* 130-137 */ 0x7c, 0x2015, 0x5f, 0x21, 0x22, 0x042a, 0xb0, 0x2032, + /* 000-007 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + /* 010-017 */ 0x38, 0x39, 0x2b, 0x2d, 0x2f, 0x2c, 0x2e, 0x2423, + /* 020-027 */ 0x65, 0x2191, 0x28, 0x29, 0xd7, 0x3d, 0x3b, 0x5b, + /* 030-037 */ 0x5d, 0x2a, 0x2018, 0x2019, 0x2260, 0x3c, 0x3e, 0x3a, + /* 040-047 */ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + /* 050-057 */ 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + /* 060-067 */ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + /* 070-077 */ 0x0428, 0x0429, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x44, + /* 100-107 */ 0x46, 0x47, 0x49, 0x4a, 0x4c, 0x4e, 0x51, 0x52, + /* 110-117 */ 0x53, 0x55, 0x56, 0x57, 0x5a, 0x203e, 0x2264, 0x2265, + /* 120-127 */ 0x2228, 0x2227, 0x2283, 0xac, 0xf7, 0x2261, 0x25, 0x25c7, + /* 130-137 */ 0x7c, 0x2015, 0x5f, 0x21, 0x22, 0x042a, 0xb0, 0x2032, }; static const unsigned short gost_to_unicode_lat [256] = { -/* 000-007 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, -/* 010-017 */ 0x38, 0x39, 0x2b, 0x2d, 0x2f, 0x2c, 0x2e, 0x2423, -/* 020-027 */ 0x65, 0x2191, 0x28, 0x29, 0xd7, 0x3d, 0x3b, 0x5b, -/* 030-037 */ 0x5d, 0x2a, 0x2018, 0x2019, 0x2260, 0x3c, 0x3e, 0x3a, -/* 040-047 */ 0x41, 0x0411, 0x42, 0x0413, 0x0414, 0x45, 0x0416, 0x0417, -/* 050-057 */ 0x0418, 0x0419, 0x4b, 0x041b, 0x4d, 0x48, 0x4f, 0x041f, -/* 060-067 */ 0x50, 0x43, 0x54, 0x59, 0x0424, 0x58, 0x0426, 0x0427, -/* 070-077 */ 0x0428, 0x0429, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x44, -/* 100-107 */ 0x46, 0x47, 0x49, 0x4a, 0x4c, 0x4e, 0x51, 0x52, -/* 110-117 */ 0x53, 0x55, 0x56, 0x57, 0x5a, 0x203e, 0x2264, 0x2265, -/* 120-127 */ 0x2228, 0x2227, 0x2283, 0xac, 0xf7, 0x2261, 0x25, 0x25c7, -/* 130-137 */ 0x7c, 0x2015, 0x5f, 0x21, 0x22, 0x042a, 0xb0, 0x2032, + /* 000-007 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + /* 010-017 */ 0x38, 0x39, 0x2b, 0x2d, 0x2f, 0x2c, 0x2e, 0x2423, + /* 020-027 */ 0x65, 0x2191, 0x28, 0x29, 0xd7, 0x3d, 0x3b, 0x5b, + /* 030-037 */ 0x5d, 0x2a, 0x2018, 0x2019, 0x2260, 0x3c, 0x3e, 0x3a, + /* 040-047 */ 0x41, 0x0411, 0x42, 0x0413, 0x0414, 0x45, 0x0416, 0x0417, + /* 050-057 */ 0x0418, 0x0419, 0x4b, 0x041b, 0x4d, 0x48, 0x4f, 0x041f, + /* 060-067 */ 0x50, 0x43, 0x54, 0x59, 0x0424, 0x58, 0x0426, 0x0427, + /* 070-077 */ 0x0428, 0x0429, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x44, + /* 100-107 */ 0x46, 0x47, 0x49, 0x4a, 0x4c, 0x4e, 0x51, 0x52, + /* 110-117 */ 0x53, 0x55, 0x56, 0x57, 0x5a, 0x203e, 0x2264, 0x2265, + /* 120-127 */ 0x2228, 0x2227, 0x2283, 0xac, 0xf7, 0x2261, 0x25, 0x25c7, + /* 130-137 */ 0x7c, 0x2015, 0x5f, 0x21, 0x22, 0x042a, 0xb0, 0x2032, }; /* * Write Unicode symbol to file. @@ -272,25 +269,25 @@ static const unsigned short gost_to_unicode_lat [256] = { static void utf8_putc (unsigned short ch, FILE *fout) { - if (ch < 0x80) { - putc (ch, fout); - return; - } - if (ch < 0x800) { - putc (ch >> 6 | 0xc0, fout); - putc ((ch & 0x3f) | 0x80, fout); - return; - } - putc (ch >> 12 | 0xe0, fout); - putc (((ch >> 6) & 0x3f) | 0x80, fout); + if (ch < 0x80) { + putc (ch, fout); + return; + } + if (ch < 0x800) { + putc (ch >> 6 | 0xc0, fout); putc ((ch & 0x3f) | 0x80, fout); + return; + } + putc (ch >> 12 | 0xe0, fout); + putc (((ch >> 6) & 0x3f) | 0x80, fout); + putc ((ch & 0x3f) | 0x80, fout); } unsigned short gost_to_unicode (unsigned char ch) { - return gost_latin ? gost_to_unicode_lat [ch] : - gost_to_unicode_cyr [ch]; + return gost_latin ? gost_to_unicode_lat [ch] : + gost_to_unicode_cyr [ch]; } /* @@ -300,12 +297,12 @@ gost_to_unicode (unsigned char ch) void gost_putc (unsigned char ch, FILE *fout) { - unsigned short u; + unsigned short u; - u = gost_to_unicode (ch); - if (! u) - u = ' '; - utf8_putc (u, fout); + u = gost_to_unicode (ch); + if (! u) + u = ' '; + utf8_putc (u, fout); } /* @@ -314,22 +311,22 @@ gost_putc (unsigned char ch, FILE *fout) void offset_gost_write (int num, FILE *fout) { - struct acpu_t * dev = acpu + num; - int s, p; - for (s = 0; s < dev->strikes; ++s) { - if (s) - fputc ('\r', fout); - for (p = 0; p < dev->length; ++p) { - gost_putc (dev->line[p][s] - 1, fout); - } + struct acpu_t * dev = acpu + num; + int s, p; + for (s = 0; s < dev->strikes; ++s) { + if (s) + fputc ('\r', fout); + for (p = 0; p < dev->length; ++p) { + gost_putc (dev->line[p][s] - 1, fout); } + } - if (acpu_isatty[num]) - fputc('\r', fout); + if (acpu_isatty[num]) + fputc('\r', fout); - fputc ('\n', fout); - memset(dev->line, 0, sizeof (dev->line)); - dev->length = dev->strikes = 0; + fputc ('\n', fout); + memset(dev->line, 0, sizeof (dev->line)); + dev->length = dev->strikes = 0; } /* @@ -337,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) - return 0; - if ((printer_unit[1].flags & UNIT_ATT) && acpu[1].rampup == 0) - return 0; - return 1; + if ((printer_unit[0].flags & UNIT_ATT) && acpu[0].rampup == 0) + return 0; + if ((printer_unit[1].flags & UNIT_ATT) && acpu[1].rampup == 0) + return 0; + return 1; } diff --git a/BESM6/besm6_punch.c b/BESM6/besm6_punch.c index 7f1a5235..42906b15 100644 --- a/BESM6/besm6_punch.c +++ b/BESM6/besm6_punch.c @@ -34,8 +34,8 @@ t_stat fs_event (UNIT *u); t_stat uvvk_event (UNIT *u); UNIT fs_unit [] = { - { UDATA (fs_event, UNIT_SEQ+UNIT_ATTABLE, 0) }, - { UDATA (fs_event, UNIT_SEQ+UNIT_ATTABLE, 0) }, + { UDATA (fs_event, UNIT_SEQ+UNIT_ATTABLE, 0) }, + { UDATA (fs_event, UNIT_SEQ+UNIT_ATTABLE, 0) }, }; int curchar[2], feed[2], isfifo[2]; @@ -47,33 +47,33 @@ char line[2][128]; /* #define NEGATIVE_RDY */ #ifndef NEGATIVE_RDY -#define ENB_RDY SET_RDY -#define DIS_RDY CLR_RDY -#define IS_RDY ISSET_RDY +#define ENB_RDY SET_RDY +#define DIS_RDY CLR_RDY +#define IS_RDY ISSET_RDY #else #define ENB_RDY CLR_RDY #define DIS_RDY SET_RDY #define IS_RDY ISCLR_RDY #endif -#define SET_RDY(x) do READY |= x; while (0) -#define CLR_RDY(x) do READY &= ~(x); while (0) -#define ISSET_RDY(x) ((READY & (x)) != 0) -#define ISCLR_RDY(x) ((READY & (x)) == 0) +#define SET_RDY(x) do READY |= x; while (0) +#define CLR_RDY(x) do READY &= ~(x); while (0) +#define ISSET_RDY(x) ((READY & (x)) != 0) +#define ISCLR_RDY(x) ((READY & (x)) == 0) -#define FS_RATE 1000*MSEC/1500 +#define FS_RATE 1000*MSEC/1500 unsigned char FS[2]; REG fs_reg[] = { -{ "Готов", &READY, 2, 2, 14, 1 }, -{ "ФС1500-1", &FS[0], 8, 8, 0, 1 }, -{ "ФС1500-2", &FS[2], 8, 8, 0, 1 }, -{ 0 } + { "Готов", &READY, 2, 2, 14, 1 }, + { "ФС1500-1", &FS[0], 8, 8, 0, 1 }, + { "ФС1500-2", &FS[2], 8, 8, 0, 1 }, + { 0 } }; MTAB fs_mod[] = { - { 0 } + { 0 } }; t_stat fs_reset (DEVICE *dptr); @@ -81,25 +81,25 @@ t_stat fs_attach (UNIT *uptr, char *cptr); t_stat fs_detach (UNIT *uptr); DEVICE fs_dev = { - "FS", fs_unit, fs_reg, fs_mod, - 2, 8, 19, 1, 8, 50, - NULL, NULL, &fs_reset, NULL, &fs_attach, &fs_detach, - NULL, DEV_DISABLE | DEV_DEBUG + "FS", fs_unit, fs_reg, fs_mod, + 2, 8, 19, 1, 8, 50, + NULL, NULL, &fs_reset, NULL, &fs_attach, &fs_detach, + NULL, DEV_DISABLE | DEV_DEBUG }; #define CARD_LEN 120 enum { - FS_IDLE, - FS_STARTING, - FS_RUNNING, - FS_IMAGE, - FS_IMAGE_LAST = FS_IMAGE + CARD_LEN - 1, - FS_TOOLONG, - FS_FILLUP, - FS_FILLUP_LAST = FS_FILLUP + CARD_LEN - 1, - FS_ENDA3, - FS_ENDA3_LAST = FS_ENDA3 + CARD_LEN - 1, - FS_TAIL, + FS_IDLE, + FS_STARTING, + FS_RUNNING, + FS_IMAGE, + FS_IMAGE_LAST = FS_IMAGE + CARD_LEN - 1, + FS_TOOLONG, + FS_FILLUP, + FS_FILLUP_LAST = FS_FILLUP + CARD_LEN - 1, + FS_ENDA3, + FS_ENDA3_LAST = FS_ENDA3 + CARD_LEN - 1, + FS_TAIL, } fs_state[2]; /* @@ -107,40 +107,40 @@ enum { */ t_stat fs_reset (DEVICE *dptr) { - sim_cancel (&fs_unit[0]); - sim_cancel (&fs_unit[1]); - fs_state[0] = fs_state[1] = FS_IDLE; - DIS_RDY(FS1_READY | FS2_READY); - if (fs_unit[0].flags & UNIT_ATT) - ENB_RDY(FS1_READY); - if (fs_unit[1].flags & UNIT_ATT) - ENB_RDY(FS2_READY); - return SCPE_OK; + sim_cancel (&fs_unit[0]); + sim_cancel (&fs_unit[1]); + fs_state[0] = fs_state[1] = FS_IDLE; + DIS_RDY(FS1_READY | FS2_READY); + if (fs_unit[0].flags & UNIT_ATT) + ENB_RDY(FS1_READY); + if (fs_unit[1].flags & UNIT_ATT) + ENB_RDY(FS2_READY); + return SCPE_OK; } t_stat fs_attach (UNIT *u, char *cptr) { - t_stat s; - int num = u - fs_unit; - s = attach_unit (u, cptr); - if (s != SCPE_OK) - return s; - struct stat stbuf; - fstat (fileno(u->fileref), &stbuf); - isfifo[num] = (stbuf.st_mode & S_IFIFO) != 0; - if (isfifo[num]) { - int flags = fcntl(fileno(u->fileref), F_GETFL, 0); - fcntl(fileno(u->fileref), F_SETFL, flags | O_NONBLOCK); - } - ENB_RDY(FS1_READY >> num); - return SCPE_OK; + t_stat s; + int num = u - fs_unit; + s = attach_unit (u, cptr); + if (s != SCPE_OK) + return s; + struct stat stbuf; + fstat (fileno(u->fileref), &stbuf); + isfifo[num] = (stbuf.st_mode & S_IFIFO) != 0; + if (isfifo[num]) { + int flags = fcntl(fileno(u->fileref), F_GETFL, 0); + fcntl(fileno(u->fileref), F_SETFL, flags | O_NONBLOCK); + } + ENB_RDY(FS1_READY >> num); + return SCPE_OK; } t_stat fs_detach (UNIT *u) { - int num = u - fs_unit; - DIS_RDY(FS1_READY >> num); - return detach_unit (u); + int num = u - fs_unit; + DIS_RDY(FS1_READY >> num); + return detach_unit (u); } /* @@ -148,49 +148,49 @@ t_stat fs_detach (UNIT *u) */ void fs_control (int num, uint32 cmd) { - UNIT *u = &fs_unit[num]; + UNIT *u = &fs_unit[num]; - static int bytecnt = 0; - if (fs_dev.dctrl) - besm6_debug("<<< ФС1500-%d команда %o", num, cmd); - if (! IS_RDY(FS1_READY >> num)) { - if (fs_dev.dctrl) - besm6_debug("<<< ФС1500-%d не готово", num, cmd); - return; - } - switch (cmd) { - case 0: /* полное выключение */ - sim_cancel (u); - fs_state[num] = FS_IDLE; - if (fs_dev.dctrl) - besm6_debug("<<<ФС1500-%d ВЫКЛ..", num); - bytecnt = 0; - break; - case 4: /* двигатель без протяжки */ - fs_state[num] = FS_STARTING; - if (fs_dev.dctrl) - besm6_debug("<<<ФС1500-%d ВКЛ.", num); - sim_cancel (u); - break; - case 5: /* протяжка */ - if (fs_state[num] == FS_IDLE) - besm6_debug("<<< ФС1500-%d протяжка без мотора", num); - else if (fs_state[num] != FS_TAIL) { - sim_activate (u, FS_RATE); - bytecnt++; - } else { - if (! isfifo[num]) { - fs_detach(u); - fs_state[num] = FS_IDLE; - } - } - break; - default: - besm6_debug ("<<< ФС1500-%d неизвестная команда %o", num, cmd); - } - if (cmd && fs_dev.dctrl) { - besm6_debug("<<<ФС1500-%d: %d симв.", num, bytecnt); - } + static int bytecnt = 0; + if (fs_dev.dctrl) + besm6_debug("<<< ФС1500-%d команда %o", num, cmd); + if (! IS_RDY(FS1_READY >> num)) { + if (fs_dev.dctrl) + besm6_debug("<<< ФС1500-%d не готово", num, cmd); + return; + } + switch (cmd) { + case 0: /* полное выключение */ + sim_cancel (u); + fs_state[num] = FS_IDLE; + if (fs_dev.dctrl) + besm6_debug("<<<ФС1500-%d ВЫКЛ..", num); + bytecnt = 0; + break; + case 4: /* двигатель без протяжки */ + fs_state[num] = FS_STARTING; + if (fs_dev.dctrl) + besm6_debug("<<<ФС1500-%d ВКЛ.", num); + sim_cancel (u); + break; + case 5: /* протяжка */ + if (fs_state[num] == FS_IDLE) + besm6_debug("<<< ФС1500-%d протяжка без мотора", num); + else if (fs_state[num] != FS_TAIL) { + sim_activate (u, FS_RATE); + bytecnt++; + } else { + if (! isfifo[num]) { + fs_detach(u); + fs_state[num] = FS_IDLE; + } + } + break; + default: + besm6_debug ("<<< ФС1500-%d неизвестная команда %o", num, cmd); + } + if (cmd && fs_dev.dctrl) { + besm6_debug("<<<ФС1500-%d: %d симв.", num, bytecnt); + } } unsigned char unicode_to_gost (unsigned short val); @@ -202,250 +202,238 @@ static int utf8_getc (FILE *fin); */ t_stat fs_event (UNIT *u) { - int num = u - fs_unit; -again: - switch (fs_state[num]) { - case FS_STARTING: - /* По первому прерыванию после запуска двигателя ничего не читаем */ - FS[num] = 0; - fs_state[num] = FS_RUNNING; - break; - case FS_RUNNING: { - int ch; - /* переводы строк игнорируются */ - while ((ch = utf8_getc (u->fileref)) == '\n'); - if (ch < 0) { - /* хвост ленты без пробивок */ - FS[num] = 0; - fs_state[num] = FS_TAIL; - } else if (ch == '\f') { - fs_state[num] = FS_IMAGE; - goto again; - } else { - ch = FS[num] = unicode_to_gost (ch); - ch = (ch & 0x55) + ((ch >> 1) & 0x55); - ch = (ch & 0x33) + ((ch >> 2) & 0x33); - ch = (ch & 0x0F) + ((ch >> 4) & 0x0F); - if (ch & 1); else FS[num] |= 0x80; - } - break; - } - case FS_IMAGE ... FS_IMAGE_LAST: { - int ch = utf8_getc (u->fileref); - if (ch < 0) { - /* обрыв ленты */ - FS[num] = 0; - fs_state[num] = FS_TAIL; - } else if (ch == '\n') { - /* идем дополнять образ карты нулевыми байтами */ - fs_state[num] = FS_FILLUP + (fs_state[num] - FS_IMAGE); - goto again; - } else if (ch == '\f') { - if (fs_state[num] != FS_IMAGE) - besm6_debug("<<< ENDA3 requested mid-card?"); - fs_state[num] = FS_ENDA3; - goto again; - } else { - ch = FS[num] = unicode_to_gost (ch); - ch = (ch & 0x55) + ((ch >> 1) & 0x55); - ch = (ch & 0x33) + ((ch >> 2) & 0x33); - ch = (ch & 0x0F) + ((ch >> 4) & 0x0F); - if (ch & 1); else FS[num] |= 0x80; - ++fs_state[num]; - } - break; - } - case FS_TOOLONG: { - /* дочитываем до конца строки */ - int ch; - besm6_debug("<<< too long???"); - while ((ch = utf8_getc (u->fileref)) != '\n' && ch >= 0); - if (ch < 0) { - /* хвост ленты без пробивок */ - FS[num] = 0; - fs_state[num] = FS_TAIL; - } else - goto again; - break; - } - case FS_FILLUP ... FS_FILLUP_LAST: - FS[num] = 0; - if (++fs_state[num] == FS_ENDA3) { - fs_state[num] = FS_IMAGE; - } - break; - case FS_ENDA3 ... FS_ENDA3_LAST: - if ((fs_state[num] - FS_ENDA3) % 5 == 0) - FS[num] = 0200; - else - FS[num] = 0; - if (++fs_state[num] == FS_TAIL) { - fs_state[num] = FS_RUNNING; - } - break; - case FS_IDLE: - case FS_TAIL: - FS[num] = 0; - break; - } - GRP |= GRP_FS1_SYNC >> num; - return SCPE_OK; + int num = u - fs_unit; + again: + if (fs_state[num] == FS_STARTING) { + /* По первому прерыванию после запуска двигателя ничего не читаем */ + FS[num] = 0; + fs_state[num] = FS_RUNNING; + } else if (fs_state[num] == FS_RUNNING) { + int ch; + /* переводы строк игнорируются */ + while ((ch = utf8_getc (u->fileref)) == '\n'); + if (ch < 0) { + /* хвост ленты без пробивок */ + FS[num] = 0; + fs_state[num] = FS_TAIL; + } else if (ch == '\f') { + fs_state[num] = FS_IMAGE; + goto again; + } else { + ch = FS[num] = unicode_to_gost (ch); + ch = (ch & 0x55) + ((ch >> 1) & 0x55); + ch = (ch & 0x33) + ((ch >> 2) & 0x33); + ch = (ch & 0x0F) + ((ch >> 4) & 0x0F); + if (ch & 1); else FS[num] |= 0x80; + } + } else if (FS_IMAGE <= fs_state[num] && fs_state[num] <= FS_IMAGE_LAST) { + int ch = utf8_getc (u->fileref); + if (ch < 0) { + /* обрыв ленты */ + FS[num] = 0; + fs_state[num] = FS_TAIL; + } else if (ch == '\n') { + /* идем дополнять образ карты нулевыми байтами */ + fs_state[num] = FS_FILLUP + (fs_state[num] - FS_IMAGE); + goto again; + } else if (ch == '\f') { + if (fs_state[num] != FS_IMAGE) + besm6_debug("<<< ENDA3 requested mid-card?"); + fs_state[num] = FS_ENDA3; + goto again; + } else { + ch = FS[num] = unicode_to_gost (ch); + ch = (ch & 0x55) + ((ch >> 1) & 0x55); + ch = (ch & 0x33) + ((ch >> 2) & 0x33); + ch = (ch & 0x0F) + ((ch >> 4) & 0x0F); + if (ch & 1); else FS[num] |= 0x80; + ++fs_state[num]; + } + } else if (fs_state[num] == FS_TOOLONG) { + /* дочитываем до конца строки */ + int ch; + besm6_debug("<<< too long???"); + while ((ch = utf8_getc (u->fileref)) != '\n' && ch >= 0); + if (ch < 0) { + /* хвост ленты без пробивок */ + FS[num] = 0; + fs_state[num] = FS_TAIL; + } else + goto again; + } else if (FS_FILLUP <= fs_state[num] && fs_state[num] <= FS_FILLUP_LAST) { + FS[num] = 0; + if (++fs_state[num] == FS_ENDA3) { + fs_state[num] = FS_IMAGE; + } + } else if (FS_ENDA3 <= fs_state[num] && fs_state[num] <= FS_ENDA3_LAST) { + if ((fs_state[num] - FS_ENDA3) % 5 == 0) + FS[num] = 0200; + else + FS[num] = 0; + if (++fs_state[num] == FS_TAIL) { + fs_state[num] = FS_RUNNING; + } + } else if (fs_state[num] == FS_IDLE || fs_state[num] == FS_TAIL) { + FS[num] = 0; + } + GRP |= GRP_FS1_SYNC >> num; + return SCPE_OK; } int fs_read(int num) { - if (fs_dev.dctrl) - besm6_debug("<<< ФС1500-%d: байт %03o", num, FS[num]); - - return FS[num]; + if (fs_dev.dctrl) + besm6_debug("<<< ФС1500-%d: байт %03o", num, FS[num]); + + return FS[num]; } int fs_is_idle (void) { - return fs_state[0] == FS_IDLE && fs_state[1] == FS_IDLE; + return fs_state[0] == FS_IDLE && fs_state[1] == FS_IDLE; } unsigned char unicode_to_gost (unsigned short val) { - static const unsigned char tab0 [256] = { -/* 00 - 07 */ 017, 017, 017, 017, 017, 017, 017, 017, -/* 08 - 0f */ 017, 017, 0214, 017, 017, 0174, 017, 017, -/* 10 - 17 */ 017, 017, 017, 017, 017, 017, 017, 017, -/* 18 - 1f */ 017, 017, 017, 017, 017, 017, 017, 017, -/* !"#$%&' */ 0017, 0133, 0134, 0034, 0127, 0126, 0121, 0033, -/* ()*+,-./ */ 0022, 0023, 0031, 0012, 0015, 0013, 0016, 0014, -/* 01234567 */ 0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007, -/* 89:;<=>? */ 0010, 0011, 0037, 0026, 0035, 0025, 0036, 0136, -/* @ABCDEFG */ 0021, 0040, 0042, 0061, 0077, 0045, 0100, 0101, -/* HIJKLMNO */ 0055, 0102, 0103, 0052, 0104, 0054, 0105, 0056, -/* PQRSTUVW */ 0060, 0106, 0107, 0110, 0062, 0111, 0112, 0113, -/* XYZ[\]^_ */ 0065, 0063, 0114, 0027, 017, 0030, 0115, 0132, -/* `abcdefg */ 0032, 0040, 0042, 0061, 0077, 0045, 0100, 0101, -/* hijklmno */ 0055, 0102, 0103, 0052, 0104, 0054, 0105, 0056, -/* pqrstuvw */ 0060, 0106, 0107, 0110, 0062, 0111, 0112, 0113, -/* xyz{|}~ */ 0065, 0063, 0114, 017, 0130, 017, 0123, 017, -/* 80 - 87 */ 017, 017, 017, 017, 017, 017, 017, 017, -/* 88 - 8f */ 017, 017, 017, 017, 017, 017, 017, 017, -/* 90 - 97 */ 017, 017, 017, 017, 017, 017, 017, 017, -/* 98 - 9f */ 017, 017, 017, 017, 017, 017, 017, 017, -/* a0 - a7 */ 017, 017, 017, 017, 017, 017, 017, 017, -/* a8 - af */ 017, 017, 017, 017, 0123, 017, 017, 017, -/* b0 - b7 */ 0136, 017, 017, 017, 017, 017, 017, 017, -/* b8 - bf */ 017, 017, 017, 017, 017, 017, 017, 017, -/* c0 - c7 */ 017, 017, 017, 017, 017, 017, 017, 017, -/* c8 - cf */ 017, 017, 017, 017, 017, 017, 017, 017, -/* d0 - d7 */ 017, 017, 017, 017, 017, 017, 017, 0024, -/* d8 - df */ 017, 017, 017, 017, 017, 017, 017, 017, -/* e0 - e7 */ 017, 017, 017, 017, 017, 017, 017, 017, -/* e8 - ef */ 017, 017, 017, 017, 017, 017, 017, 017, -/* f0 - f7 */ 017, 017, 017, 017, 017, 017, 017, 0124, -/* f8 - ff */ 017, 017, 017, 017, 017, 017, 017, 017, - }; - switch (val >> 8) { - case 0x00: - return tab0 [val]; - case 0x04: - switch ((unsigned char) val) { - case 0x10: return 0040; - case 0x11: return 0041; - case 0x12: return 0042; - case 0x13: return 0043; - case 0x14: return 0044; - case 0x15: return 0045; - case 0x16: return 0046; - case 0x17: return 0047; - case 0x18: return 0050; - case 0x19: return 0051; - case 0x1a: return 0052; - case 0x1b: return 0053; - case 0x1c: return 0054; - case 0x1d: return 0055; - case 0x1e: return 0056; - case 0x1f: return 0057; - case 0x20: return 0060; - case 0x21: return 0061; - case 0x22: return 0062; - case 0x23: return 0063; - case 0x24: return 0064; - case 0x25: return 0065; - case 0x26: return 0066; - case 0x27: return 0067; - case 0x28: return 0070; - case 0x29: return 0071; - case 0x2a: return 0135; - case 0x2b: return 0072; - case 0x2c: return 0073; - case 0x2d: return 0074; - case 0x2e: return 0075; - case 0x2f: return 0076; - case 0x30: return 0040; - case 0x31: return 0041; - case 0x32: return 0042; - case 0x33: return 0043; - case 0x34: return 0044; - case 0x35: return 0045; - case 0x36: return 0046; - case 0x37: return 0047; - case 0x38: return 0050; - case 0x39: return 0051; - case 0x3a: return 0052; - case 0x3b: return 0053; - case 0x3c: return 0054; - case 0x3d: return 0055; - case 0x3e: return 0056; - case 0x3f: return 0057; - case 0x40: return 0060; - case 0x41: return 0061; - case 0x42: return 0062; - case 0x43: return 0063; - case 0x44: return 0064; - case 0x45: return 0065; - case 0x46: return 0066; - case 0x47: return 0067; - case 0x48: return 0070; - case 0x49: return 0071; - case 0x4a: return 0135; - case 0x4b: return 0072; - case 0x4c: return 0073; - case 0x4d: return 0074; - case 0x4e: return 0075; - case 0x4f: return 0076; - } - break; - case 0x20: - switch ((unsigned char) val) { - case 0x15: return 0131; - case 0x18: return 0032; - case 0x19: return 0033; - case 0x32: return 0137; - case 0x3e: return 0115; - } - break; - case 0x21: - switch ((unsigned char) val) { - case 0x2f: return 0020; - case 0x91: return 0021; - } - break; - case 0x22: - switch ((unsigned char) val) { - case 0x27: return 0121; - case 0x28: return 0120; - case 0x60: return 0034; - case 0x61: return 0125; - case 0x64: return 0116; - case 0x65: return 0117; - case 0x83: return 0122; - } - break; - case 0x25: - switch ((unsigned char) val) { - case 0xc7: return 0127; - case 0xca: return 0127; - } - break; - } - return 017; + static const unsigned char tab0 [256] = { + /* 00 - 07 */ 017, 017, 017, 017, 017, 017, 017, 017, + /* 08 - 0f */ 017, 017, 0214, 017, 017, 0174, 017, 017, + /* 10 - 17 */ 017, 017, 017, 017, 017, 017, 017, 017, + /* 18 - 1f */ 017, 017, 017, 017, 017, 017, 017, 017, + /* !"#$%&' */ 0017, 0133, 0134, 0034, 0127, 0126, 0121, 0033, + /* ()*+,-./ */ 0022, 0023, 0031, 0012, 0015, 0013, 0016, 0014, + /* 01234567 */ 0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007, + /* 89:;<=>? */ 0010, 0011, 0037, 0026, 0035, 0025, 0036, 0136, + /* @ABCDEFG */ 0021, 0040, 0042, 0061, 0077, 0045, 0100, 0101, + /* HIJKLMNO */ 0055, 0102, 0103, 0052, 0104, 0054, 0105, 0056, + /* PQRSTUVW */ 0060, 0106, 0107, 0110, 0062, 0111, 0112, 0113, + /* XYZ[\]^_ */ 0065, 0063, 0114, 0027, 017, 0030, 0115, 0132, + /* `abcdefg */ 0032, 0040, 0042, 0061, 0077, 0045, 0100, 0101, + /* hijklmno */ 0055, 0102, 0103, 0052, 0104, 0054, 0105, 0056, + /* pqrstuvw */ 0060, 0106, 0107, 0110, 0062, 0111, 0112, 0113, + /* xyz{|}~ */ 0065, 0063, 0114, 017, 0130, 017, 0123, 017, + /* 80 - 87 */ 017, 017, 017, 017, 017, 017, 017, 017, + /* 88 - 8f */ 017, 017, 017, 017, 017, 017, 017, 017, + /* 90 - 97 */ 017, 017, 017, 017, 017, 017, 017, 017, + /* 98 - 9f */ 017, 017, 017, 017, 017, 017, 017, 017, + /* a0 - a7 */ 017, 017, 017, 017, 017, 017, 017, 017, + /* a8 - af */ 017, 017, 017, 017, 0123, 017, 017, 017, + /* b0 - b7 */ 0136, 017, 017, 017, 017, 017, 017, 017, + /* b8 - bf */ 017, 017, 017, 017, 017, 017, 017, 017, + /* c0 - c7 */ 017, 017, 017, 017, 017, 017, 017, 017, + /* c8 - cf */ 017, 017, 017, 017, 017, 017, 017, 017, + /* d0 - d7 */ 017, 017, 017, 017, 017, 017, 017, 0024, + /* d8 - df */ 017, 017, 017, 017, 017, 017, 017, 017, + /* e0 - e7 */ 017, 017, 017, 017, 017, 017, 017, 017, + /* e8 - ef */ 017, 017, 017, 017, 017, 017, 017, 017, + /* f0 - f7 */ 017, 017, 017, 017, 017, 017, 017, 0124, + /* f8 - ff */ 017, 017, 017, 017, 017, 017, 017, 017, + }; + switch (val >> 8) { + case 0x00: + return tab0 [val]; + case 0x04: + switch ((unsigned char) val) { + case 0x10: return 0040; + case 0x11: return 0041; + case 0x12: return 0042; + case 0x13: return 0043; + case 0x14: return 0044; + case 0x15: return 0045; + case 0x16: return 0046; + case 0x17: return 0047; + case 0x18: return 0050; + case 0x19: return 0051; + case 0x1a: return 0052; + case 0x1b: return 0053; + case 0x1c: return 0054; + case 0x1d: return 0055; + case 0x1e: return 0056; + case 0x1f: return 0057; + case 0x20: return 0060; + case 0x21: return 0061; + case 0x22: return 0062; + case 0x23: return 0063; + case 0x24: return 0064; + case 0x25: return 0065; + case 0x26: return 0066; + case 0x27: return 0067; + case 0x28: return 0070; + case 0x29: return 0071; + case 0x2a: return 0135; + case 0x2b: return 0072; + case 0x2c: return 0073; + case 0x2d: return 0074; + case 0x2e: return 0075; + case 0x2f: return 0076; + case 0x30: return 0040; + case 0x31: return 0041; + case 0x32: return 0042; + case 0x33: return 0043; + case 0x34: return 0044; + case 0x35: return 0045; + case 0x36: return 0046; + case 0x37: return 0047; + case 0x38: return 0050; + case 0x39: return 0051; + case 0x3a: return 0052; + case 0x3b: return 0053; + case 0x3c: return 0054; + case 0x3d: return 0055; + case 0x3e: return 0056; + case 0x3f: return 0057; + case 0x40: return 0060; + case 0x41: return 0061; + case 0x42: return 0062; + case 0x43: return 0063; + case 0x44: return 0064; + case 0x45: return 0065; + case 0x46: return 0066; + case 0x47: return 0067; + case 0x48: return 0070; + case 0x49: return 0071; + case 0x4a: return 0135; + case 0x4b: return 0072; + case 0x4c: return 0073; + case 0x4d: return 0074; + case 0x4e: return 0075; + case 0x4f: return 0076; + } + break; + case 0x20: + switch ((unsigned char) val) { + case 0x15: return 0131; + case 0x18: return 0032; + case 0x19: return 0033; + case 0x32: return 0137; + case 0x3e: return 0115; + } + break; + case 0x21: + switch ((unsigned char) val) { + case 0x2f: return 0020; + case 0x91: return 0021; + } + break; + case 0x22: + switch ((unsigned char) val) { + case 0x27: return 0121; + case 0x28: return 0120; + case 0x60: return 0034; + case 0x61: return 0125; + case 0x64: return 0116; + case 0x65: return 0117; + case 0x83: return 0122; + } + break; + case 0x25: + switch ((unsigned char) val) { + case 0xc7: return 0127; + case 0xca: return 0127; + } + break; + } + return 017; } /* @@ -455,18 +443,18 @@ unicode_to_gost (unsigned short val) static int utf8_getc (FILE *fin) { - int c1, c2, c3; -again: - c1 = getc (fin); - if (c1 < 0 || ! (c1 & 0x80)) - return c1; - c2 = getc (fin); - if (! (c1 & 0x20)) - return (c1 & 0x1f) << 6 | (c2 & 0x3f); - c3 = getc (fin); - if (c1 == 0xEF && c2 == 0xBB && c3 == 0xBF) { - /* Skip zero width no-break space. */ - goto again; - } - return (c1 & 0x0f) << 12 | (c2 & 0x3f) << 6 | (c3 & 0x3f); + int c1, c2, c3; + again: + c1 = getc (fin); + if (c1 < 0 || ! (c1 & 0x80)) + return c1; + c2 = getc (fin); + if (! (c1 & 0x20)) + return (c1 & 0x1f) << 6 | (c2 & 0x3f); + c3 = getc (fin); + if (c1 == 0xEF && c2 == 0xBB && c3 == 0xBF) { + /* Skip zero width no-break space. */ + goto again; + } + return (c1 & 0x0f) << 12 | (c2 & 0x3f) << 6 | (c3 & 0x3f); } diff --git a/BESM6/besm6_sys.c b/BESM6/besm6_sys.c index 1c128938..01014aa2 100644 --- a/BESM6/besm6_sys.c +++ b/BESM6/besm6_sys.c @@ -16,46 +16,46 @@ * This file implements three essential functions: * * sim_load() - loading and dumping memory and CPU state - * in a way, specific for BESM-6 architecture + * in a way, specific for BESM-6 architecture * fprint_sym() - print a machune instruction using - * opcode mnemonic or in a digital format - * parse_sym() - scan a string and build an instruction - * word from it + * opcode mnemonic or in a digital format + * parse_sym() - scan a string and build an instruction + * word from it */ #include "besm6_defs.h" #include #include const char *opname_short_bemsh [64] = { - "зп", "зпм", "рег", "счм", "сл", "вч", "вчоб", "вчаб", - "сч", "и", "нтж", "слц", "знак", "или", "дел", "умн", - "сбр", "рзб", "чед", "нед", "слп", "вчп", "сд", "рж", - "счрж", "счмр", "э32", "увв", "слпа", "вчпа", "сда", "ржа", - "уи", "уим", "счи", "счим", "уии", "сли", "э46", "э47", - "э50", "э51", "э52", "э53", "э54", "э55", "э56", "э57", - "э60", "э61", "э62", "э63", "э64", "э65", "э66", "э67", - "э70", "э71", "э72", "э73", "э74", "э75", "э76", "э77", + "зп", "зпм", "рег", "счм", "сл", "вч", "вчоб","вчаб", + "сч", "и", "нтж", "слц", "знак","или", "дел", "умн", + "сбр", "рзб", "чед", "нед", "слп", "вчп", "сд", "рж", + "счрж","счмр","э32", "увв", "слпа","вчпа","сда", "ржа", + "уи", "уим", "счи", "счим","уии", "сли", "э46", "э47", + "э50", "э51", "э52", "э53", "э54", "э55", "э56", "э57", + "э60", "э61", "э62", "э63", "э64", "э65", "э66", "э67", + "э70", "э71", "э72", "э73", "э74", "э75", "э76", "э77", }; static const char *opname_long_bemsh [16] = { - "э20", "э21", "мода", "мод", "уиа", "слиа", "по", "пе", - "пб", "пв", "выпр", "стоп", "пио", "пино", "э36", "цикл", + "э20", "э21", "мода","мод", "уиа", "слиа","по", "пе", + "пб", "пв", "выпр","стоп","пио", "пино","э36", "цикл", }; const char *opname_short_madlen [64] = { - "atx", "stx", "mod", "xts", "a+x", "a-x", "x-a", "amx", - "xta", "aax", "aex", "arx", "avx", "aox", "a/x", "a*x", - "apx", "aux", "acx", "anx", "e+x", "e-x", "asx", "xtr", - "rte", "yta", "*32", "ext", "e+n", "e-n", "asn", "ntr", - "ati", "sti", "ita", "its", "mtj", "j+m", "*46", "*47", - "*50", "*51", "*52", "*53", "*54", "*55", "*56", "*57", - "*60", "*61", "*62", "*63", "*64", "*65", "*66", "*67", - "*70", "*71", "*72", "*73", "*74", "*75", "*76", "*77", + "atx", "stx", "mod", "xts", "a+x", "a-x", "x-a", "amx", + "xta", "aax", "aex", "arx", "avx", "aox", "a/x", "a*x", + "apx", "aux", "acx", "anx", "e+x", "e-x", "asx", "xtr", + "rte", "yta", "*32", "ext", "e+n", "e-n", "asn", "ntr", + "ati", "sti", "ita", "its", "mtj", "j+m", "*46", "*47", + "*50", "*51", "*52", "*53", "*54", "*55", "*56", "*57", + "*60", "*61", "*62", "*63", "*64", "*65", "*66", "*67", + "*70", "*71", "*72", "*73", "*74", "*75", "*76", "*77", }; static const char *opname_long_madlen [16] = { - "*20", "*21", "utc", "wtc", "vtm", "utm", "uza", "u1a", - "uj", "vjm", "ij", "stop", "vzm", "v1m", "*36", "vlm", + "*20", "*21", "utc", "wtc", "vtm", "utm", "uza", "u1a", + "uj", "vjm", "ij", "stop", "vzm", "v1m", "*36", "vlm", }; /* @@ -64,33 +64,33 @@ static const char *opname_long_madlen [16] = { */ const char *besm6_opname (int opcode) { - if (sim_switches & SWMASK ('L')) { - /* Latin mnemonics. */ - if (opcode & 0200) - return opname_long_madlen [(opcode >> 3) & 017]; - return opname_short_madlen [opcode]; - } - if (opcode & 0200) - return opname_long_bemsh [(opcode >> 3) & 017]; - return opname_short_bemsh [opcode]; -}; + if (sim_switches & SWMASK ('L')) { + /* Latin mnemonics. */ + if (opcode & 0200) + return opname_long_madlen [(opcode >> 3) & 017]; + return opname_short_madlen [opcode]; + } + if (opcode & 0200) + return opname_long_bemsh [(opcode >> 3) & 017]; + return opname_short_bemsh [opcode]; +} /* * Выдача кода инструкции по мнемонике (UTF-8). */ int besm6_opcode (char *instr) { - int i; + int i; - for (i=0; i<64; ++i) - if (strcmp (opname_short_bemsh[i], instr) == 0 || - strcmp (opname_short_madlen[i], instr) == 0) - return i; - for (i=0; i<16; ++i) - if (strcmp (opname_long_bemsh[i], instr) == 0 || - strcmp (opname_long_madlen[i], instr) == 0) - return (i << 3) | 0200; - return -1; + for (i=0; i<64; ++i) + if (strcmp (opname_short_bemsh[i], instr) == 0 || + strcmp (opname_short_madlen[i], instr) == 0) + return i; + for (i=0; i<16; ++i) + if (strcmp (opname_long_bemsh[i], instr) == 0 || + strcmp (opname_long_madlen[i], instr) == 0) + return (i << 3) | 0200; + return -1; } /* @@ -100,25 +100,25 @@ int besm6_opcode (char *instr) */ void besm6_log (const char *fmt, ...) { - va_list args; + va_list args; - if (*fmt == '_') - ++fmt; - else { - va_start (args, fmt); - vprintf (fmt, args); - printf ("\r\n"); - va_end (args); - } - if (sim_log) { - va_start (args, fmt); - vfprintf (sim_log, fmt, args); - if (sim_log == stdout) - fprintf (sim_log, "\r"); - fprintf (sim_log, "\n"); - fflush (sim_log); - va_end (args); - } + if (*fmt == '_') + ++fmt; + else { + va_start (args, fmt); + vprintf (fmt, args); + printf ("\r\n"); + va_end (args); + } + if (sim_log) { + va_start (args, fmt); + vfprintf (sim_log, fmt, args); + if (sim_log == stdout) + fprintf (sim_log, "\r"); + fprintf (sim_log, "\n"); + fflush (sim_log); + va_end (args); + } } /* @@ -126,21 +126,21 @@ void besm6_log (const char *fmt, ...) */ void besm6_log_cont (const char *fmt, ...) { - va_list args; + va_list args; - if (*fmt == '_') - ++fmt; - else { - va_start (args, fmt); - vprintf (fmt, args); - va_end (args); - } - if (sim_log) { - va_start (args, fmt); - vfprintf (sim_log, fmt, args); - fflush (sim_log); - va_end (args); - } + if (*fmt == '_') + ++fmt; + else { + va_start (args, fmt); + vprintf (fmt, args); + va_end (args); + } + if (sim_log) { + va_start (args, fmt); + vfprintf (sim_log, fmt, args); + fflush (sim_log); + va_end (args); + } } /* @@ -149,27 +149,27 @@ void besm6_log_cont (const char *fmt, ...) */ void besm6_debug (const char *fmt, ...) { - va_list args; + va_list args; - va_start (args, fmt); - vprintf (fmt, args); - printf ("\r\n"); - va_end (args); - if (sim_deb && sim_deb != stdout) { - va_start (args, fmt); - vfprintf (sim_deb, fmt, args); - fprintf (sim_deb, "\n"); - fflush (sim_deb); - va_end (args); - } + va_start (args, fmt); + vprintf (fmt, args); + printf ("\r\n"); + va_end (args); + if (sim_deb && sim_deb != stdout) { + va_start (args, fmt); + vfprintf (sim_deb, fmt, args); + fprintf (sim_deb, "\n"); + fflush (sim_deb); + va_end (args); + } } /* * Преобразование вещественного числа в формат БЭСМ-6. * * Представление чисел в IEEE 754 (double): - * 64 63———53 52————–1 - * знак порядок мантисса + * 64 63———53 52————–1 + * знак порядок мантисса * Старший (53-й) бит мантиссы не хранится и всегда равен 1. * * Представление чисел в БЭСМ-6: @@ -178,48 +178,48 @@ void besm6_debug (const char *fmt, ...) */ t_value ieee_to_besm6 (double d) { - t_value word; - int exponent; - int sign; + t_value word; + int exponent; + int sign; - sign = d < 0; - if (sign) - d = -d; - d = frexp (d, &exponent); - /* 0.5 <= d < 1.0 */ - d = ldexp (d, 40); - word = d; - if (d - word >= 0.5) - word += 1; /* Округление. */ - if (exponent < -64) - return 0LL; /* Близкое к нулю число */ - if (exponent > 63) { - return sign ? - 0xFEFFFFFFFFFFLL : /* Максимальное число */ - 0xFF0000000000LL; /* Минимальное число */ - } - if (sign) - word = 0x20000000000LL-word; /* Знак. */ - word |= ((t_value) (exponent + 64)) << 41; - return word; + sign = d < 0; + if (sign) + d = -d; + d = frexp (d, &exponent); + /* 0.5 <= d < 1.0 */ + d = ldexp (d, 40); + word = d; + if (d - word >= 0.5) + word += 1; /* Округление. */ + if (exponent < -64) + return 0LL; /* Близкое к нулю число */ + if (exponent > 63) { + return sign ? + 0xFEFFFFFFFFFFLL : /* Максимальное число */ + 0xFF0000000000LL; /* Минимальное число */ + } + if (sign) + word = 0x20000000000LL-word; /* Знак. */ + word |= ((t_value) (exponent + 64)) << 41; + return word; } double besm6_to_ieee (t_value word) { - double mantissa; + double mantissa; - /* Убираем свертку */ - word &= BITS48; + /* Убираем свертку */ + word &= BITS48; - /* Сдвигаем так, чтобы знак мантиссы пришелся на знак целого; - * таким образом, mantissa равно исходной мантиссе, умноженной на 2**63. - */ - mantissa = (t_int64) word << (64 - 48 + 7); + /* Сдвигаем так, чтобы знак мантиссы пришелся на знак целого; + * таким образом, mantissa равно исходной мантиссе, умноженной на 2**63. + */ + mantissa = (t_int64) word << (64 - 48 + 7); - int exponent = word >> 41; + int exponent = word >> 41; - /* Порядок смещен вверх на 64, и мантиссу нужно скорректировать */ - return ldexp (mantissa, exponent - 64 - 63); + /* Порядок смещен вверх на 64, и мантиссу нужно скорректировать */ + return ldexp (mantissa, exponent - 64 - 63); } /* @@ -227,18 +227,18 @@ double besm6_to_ieee (t_value word) */ char *skip_spaces (char *p) { - for (;;) { - if (*p == (char) 0xEF && p[1] == (char) 0xBB && p[2] == (char) 0xBF) { - /* Skip zero width no-break space. */ - p += 3; - continue; - } - if (*p == ' ' || *p == '\t' || *p == '\r') { - ++p; - continue; - } - return p; - } + for (;;) { + if (*p == (char) 0xEF && p[1] == (char) 0xBB && p[2] == (char) 0xBF) { + /* Skip zero width no-break space. */ + p += 3; + continue; + } + if (*p == ' ' || *p == '\t' || *p == '\r') { + ++p; + continue; + } + return p; + } } /* @@ -247,37 +247,37 @@ char *skip_spaces (char *p) */ int utf8_to_unicode (char **p) { - int c1, c2, c3; + int c1, c2, c3; - c1 = (unsigned char) *(*p)++; - if (! (c1 & 0x80)) - return c1; - c2 = (unsigned char) *(*p)++; - if (! (c1 & 0x20)) - return (c1 & 0x1f) << 6 | (c2 & 0x3f); - c3 = (unsigned char) *(*p)++; - return (c1 & 0x0f) << 12 | (c2 & 0x3f) << 6 | (c3 & 0x3f); + c1 = (unsigned char) *(*p)++; + if (! (c1 & 0x80)) + return c1; + c2 = (unsigned char) *(*p)++; + if (! (c1 & 0x20)) + return (c1 & 0x1f) << 6 | (c2 & 0x3f); + c3 = (unsigned char) *(*p)++; + return (c1 & 0x0f) << 12 | (c2 & 0x3f) << 6 | (c3 & 0x3f); } char *besm6_parse_octal (char *cptr, int *offset) { - char *eptr; + char *eptr; - *offset = strtol (cptr, &eptr, 8); - if (eptr == cptr) - return 0; - return eptr; + *offset = strtol (cptr, &eptr, 8); + if (eptr == cptr) + return 0; + return eptr; } static char *get_alnum (char *iptr, char *optr) { - while ((*iptr >= 'a' && *iptr<='z') || - (*iptr >= 'A' && *iptr<='Z') || - (*iptr >= '0' && *iptr<='9') || (*iptr & 0x80)) { - *optr++ = *iptr++; - } - *optr = 0; - return iptr; + while ((*iptr >= 'a' && *iptr<='z') || + (*iptr >= 'A' && *iptr<='Z') || + (*iptr >= '0' && *iptr<='9') || (*iptr & 0x80)) { + *optr++ = *iptr++; + } + *optr = 0; + return iptr; } /* @@ -286,92 +286,92 @@ static char *get_alnum (char *iptr, char *optr) */ char *parse_instruction (char *cptr, uint32 *val) { - int opcode, reg, addr, negate; - char gbuf[CBUFSIZE]; + int opcode, reg, addr, negate; + char gbuf[CBUFSIZE]; - cptr = skip_spaces (cptr); /* absorb spaces */ - if (*cptr >= '0' && *cptr <= '7') { - /* Восьмеричное представление. */ - cptr = besm6_parse_octal (cptr, ®); /* get register */ - if (! cptr || reg > 15) { - /*printf ("Bad register\n");*/ - return 0; - } - cptr = skip_spaces (cptr); /* absorb spaces */ - if (*cptr == '2' || *cptr == '3') { - /* Длинная команда. */ - cptr = besm6_parse_octal (cptr, &opcode); - if (! cptr || opcode < 020 || opcode > 037) { - /*printf ("Bad long opcode\n");*/ - return 0; - } - opcode <<= 3; - } else { - /* Короткая команда. */ - cptr = besm6_parse_octal (cptr, &opcode); - if (! cptr || opcode > 0177) { - /*printf ("Bad short opcode\n");*/ - return 0; - } - } - cptr = besm6_parse_octal (cptr, &addr); /* get address */ - if (! cptr || addr > BITS(15) || - (opcode <= 0177 && addr > BITS(12))) { - /*printf ("Bad address\n");*/ - return 0; - } - } else { - /* Мнемоническое представление команды. */ - cptr = get_alnum (cptr, gbuf); /* get opcode */ - opcode = besm6_opcode (gbuf); - if (opcode < 0) { - /*printf ("Bad opname: %s\n", gbuf);*/ - return 0; - } - negate = 0; - cptr = skip_spaces (cptr); /* absorb spaces */ - if (*cptr == '-') { /* negative offset */ - negate = 1; - cptr = skip_spaces (cptr + 1); /* absorb spaces */ - } - addr = 0; - if (*cptr >= '0' && *cptr <= '7') { - /* Восьмеричный адрес. */ - cptr = besm6_parse_octal (cptr, &addr); - if (! cptr || addr > BITS(15)) { - /*printf ("Bad address: %o\n", addr);*/ - return 0; - } - if (negate) - addr = (- addr) & BITS(15); - if (opcode <= 077 && addr > BITS(12)) { - if (addr < 070000) { - /*printf ("Bad short address: %o\n", addr);*/ - return 0; - } - opcode |= 0100; - addr &= BITS(12); - } - } - reg = 0; - cptr = skip_spaces (cptr); /* absorb spaces */ - if (*cptr == '(') { - /* Индекс-регистр в скобках. */ - cptr = besm6_parse_octal (cptr+1, ®); - if (! cptr || reg > 15) { - /*printf ("Bad register: %o\n", reg);*/ - return 0; - } - cptr = skip_spaces (cptr); /* absorb spaces */ - if (*cptr != ')') { - /*printf ("No closing brace\n");*/ - return 0; - } - ++cptr; - } - } - *val = reg << 20 | opcode << 12 | addr; - return cptr; + cptr = skip_spaces (cptr); /* absorb spaces */ + if (*cptr >= '0' && *cptr <= '7') { + /* Восьмеричное представление. */ + cptr = besm6_parse_octal (cptr, ®); /* get register */ + if (! cptr || reg > 15) { + /*printf ("Bad register\n");*/ + return 0; + } + cptr = skip_spaces (cptr); /* absorb spaces */ + if (*cptr == '2' || *cptr == '3') { + /* Длинная команда. */ + cptr = besm6_parse_octal (cptr, &opcode); + if (! cptr || opcode < 020 || opcode > 037) { + /*printf ("Bad long opcode\n");*/ + return 0; + } + opcode <<= 3; + } else { + /* Короткая команда. */ + cptr = besm6_parse_octal (cptr, &opcode); + if (! cptr || opcode > 0177) { + /*printf ("Bad short opcode\n");*/ + return 0; + } + } + cptr = besm6_parse_octal (cptr, &addr); /* get address */ + if (! cptr || addr > BITS(15) || + (opcode <= 0177 && addr > BITS(12))) { + /*printf ("Bad address\n");*/ + return 0; + } + } else { + /* Мнемоническое представление команды. */ + cptr = get_alnum (cptr, gbuf); /* get opcode */ + opcode = besm6_opcode (gbuf); + if (opcode < 0) { + /*printf ("Bad opname: %s\n", gbuf);*/ + return 0; + } + negate = 0; + cptr = skip_spaces (cptr); /* absorb spaces */ + if (*cptr == '-') { /* negative offset */ + negate = 1; + cptr = skip_spaces (cptr + 1); /* absorb spaces */ + } + addr = 0; + if (*cptr >= '0' && *cptr <= '7') { + /* Восьмеричный адрес. */ + cptr = besm6_parse_octal (cptr, &addr); + if (! cptr || addr > BITS(15)) { + /*printf ("Bad address: %o\n", addr);*/ + return 0; + } + if (negate) + addr = (- addr) & BITS(15); + if (opcode <= 077 && addr > BITS(12)) { + if (addr < 070000) { + /*printf ("Bad short address: %o\n", addr);*/ + return 0; + } + opcode |= 0100; + addr &= BITS(12); + } + } + reg = 0; + cptr = skip_spaces (cptr); /* absorb spaces */ + if (*cptr == '(') { + /* Индекс-регистр в скобках. */ + cptr = besm6_parse_octal (cptr+1, ®); + if (! cptr || reg > 15) { + /*printf ("Bad register: %o\n", reg);*/ + return 0; + } + cptr = skip_spaces (cptr); /* absorb spaces */ + if (*cptr != ')') { + /*printf ("No closing brace\n");*/ + return 0; + } + ++cptr; + } + } + *val = reg << 20 | opcode << 12 | addr; + return cptr; } /* @@ -379,26 +379,26 @@ char *parse_instruction (char *cptr, uint32 *val) */ t_stat parse_instruction_word (char *cptr, t_value *val) { - uint32 left, right; + uint32 left, right; - *val = 0; - cptr = parse_instruction (cptr, &left); - if (! cptr) - return SCPE_ARG; - right = 0; - cptr = skip_spaces (cptr); - if (*cptr == ',') { - cptr = parse_instruction (cptr + 1, &right); - if (! cptr) - return SCPE_ARG; - } - cptr = skip_spaces (cptr); /* absorb spaces */ - if (*cptr != 0 && *cptr != ';' && *cptr != '\n' && *cptr != '\r') { - /*printf ("Extra symbols at eoln: %s\n", cptr);*/ - return SCPE_2MARG; - } - *val = (t_value) left << 24 | right; - return SCPE_OK; + *val = 0; + cptr = parse_instruction (cptr, &left); + if (! cptr) + return SCPE_ARG; + right = 0; + cptr = skip_spaces (cptr); + if (*cptr == ',') { + cptr = parse_instruction (cptr + 1, &right); + if (! cptr) + return SCPE_ARG; + } + cptr = skip_spaces (cptr); /* absorb spaces */ + if (*cptr != 0 && *cptr != ';' && *cptr != '\n' && *cptr != '\r') { + /*printf ("Extra symbols at eoln: %s\n", cptr);*/ + return SCPE_2MARG; + } + *val = (t_value) left << 24 | right; + return SCPE_OK; } /* @@ -406,31 +406,31 @@ t_stat parse_instruction_word (char *cptr, t_value *val) */ void besm6_fprint_cmd (FILE *of, uint32 cmd) { - int reg, opcode, addr; + int reg, opcode, addr; - reg = (cmd >> 20) & 017; - if (cmd & BBIT(20)) { - opcode = (cmd >> 12) & 0370; - addr = cmd & BITS(15); - } else { - opcode = (cmd >> 12) & 077; - addr = cmd & 07777; - if (cmd & BBIT(19)) - addr |= 070000; - } - fprintf (of, "%s", besm6_opname (opcode)); - if (addr) { - fprintf (of, " "); - if (addr >= 077700) - fprintf (of, "-%o", (addr ^ 077777) + 1); - else - fprintf (of, "%o", addr); - } - if (reg) { - if (! addr) - fprintf (of, " "); - fprintf (of, "(%o)", reg); - } + reg = (cmd >> 20) & 017; + if (cmd & BBIT(20)) { + opcode = (cmd >> 12) & 0370; + addr = cmd & BITS(15); + } else { + opcode = (cmd >> 12) & 077; + addr = cmd & 07777; + if (cmd & BBIT(19)) + addr |= 070000; + } + fprintf (of, "%s", besm6_opname (opcode)); + if (addr) { + fprintf (of, " "); + if (addr >= 077700) + fprintf (of, "-%o", (addr ^ 077777) + 1); + else + fprintf (of, "%o", addr); + } + if (reg) { + if (! addr) + fprintf (of, " "); + fprintf (of, "(%o)", reg); + } } /* @@ -438,185 +438,185 @@ void besm6_fprint_cmd (FILE *of, uint32 cmd) */ void besm6_fprint_insn (FILE *of, uint32 insn) { - if (insn & BBIT(20)) - fprintf (of, "%02o %02o %05o ", - insn >> 20, (insn >> 15) & 037, insn & BITS(15)); - else - fprintf (of, "%02o %03o %04o ", - insn >> 20, (insn >> 12) & 0177, insn & 07777); + if (insn & BBIT(20)) + fprintf (of, "%02o %02o %05o ", + insn >> 20, (insn >> 15) & 037, insn & BITS(15)); + else + fprintf (of, "%02o %03o %04o ", + insn >> 20, (insn >> 12) & 0177, insn & 07777); } /* * Symbolic decode * * Inputs: - * *of = output stream - * addr = current PC - * *val = pointer to data - * *uptr = pointer to unit - * sw = switches + * *of = output stream + * addr = current PC + * *val = pointer to data + * *uptr = pointer to unit + * sw = switches * Outputs: - * return = status code + * return = status code */ t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, - UNIT *uptr, int32 sw) + UNIT *uptr, int32 sw) { - t_value cmd; + t_value cmd; - if (uptr && (uptr != &cpu_unit)) /* must be CPU */ - return SCPE_ARG; + if (uptr && (uptr != &cpu_unit)) /* must be CPU */ + return SCPE_ARG; - cmd = val[0]; + cmd = val[0]; - if (sw & SWMASK ('M')) { /* symbolic decode? */ - if (sw & SIM_SW_STOP && addr == PC && !(RUU & RUU_RIGHT_INSTR)) - fprintf (of, "-> "); - besm6_fprint_cmd (of, cmd >> 24); - if (sw & SIM_SW_STOP) /* stop point */ - fprintf (of, ", "); - else - fprintf (of, ",\n\t"); - if (sw & SIM_SW_STOP && addr == PC && (RUU & RUU_RIGHT_INSTR)) - fprintf (of, "-> "); - besm6_fprint_cmd (of, cmd & BITS(24)); + if (sw & SWMASK ('M')) { /* symbolic decode? */ + if (sw & SIM_SW_STOP && addr == PC && !(RUU & RUU_RIGHT_INSTR)) + fprintf (of, "-> "); + besm6_fprint_cmd (of, cmd >> 24); + if (sw & SIM_SW_STOP) /* stop point */ + fprintf (of, ", "); + else + fprintf (of, ",\n\t"); + if (sw & SIM_SW_STOP && addr == PC && (RUU & RUU_RIGHT_INSTR)) + fprintf (of, "-> "); + besm6_fprint_cmd (of, cmd & BITS(24)); - } else if (sw & SWMASK ('I')) { - besm6_fprint_insn (of, (cmd >> 24) & BITS(24)); - besm6_fprint_insn (of, cmd & BITS(24)); - } else if (sw & SWMASK ('F')) { - fprintf (of, "%#.2g", besm6_to_ieee(cmd)); - } else if (sw & SWMASK ('B')) { - fprintf (of, "%03o %03o %03o %03o %03o %03o", - (int) (cmd >> 40) & 0377, - (int) (cmd >> 32) & 0377, - (int) (cmd >> 24) & 0377, - (int) (cmd >> 16) & 0377, - (int) (cmd >> 8) & 0377, - (int) cmd & 0377); - } else if (sw & SWMASK ('X')) { - fprintf (of, "%013llx", cmd); - } else - fprintf (of, "%04o %04o %04o %04o", - (int) (cmd >> 36) & 07777, - (int) (cmd >> 24) & 07777, - (int) (cmd >> 12) & 07777, - (int) cmd & 07777); - return SCPE_OK; + } else if (sw & SWMASK ('I')) { + besm6_fprint_insn (of, (cmd >> 24) & BITS(24)); + besm6_fprint_insn (of, cmd & BITS(24)); + } else if (sw & SWMASK ('F')) { + fprintf (of, "%#.2g", besm6_to_ieee(cmd)); + } else if (sw & SWMASK ('B')) { + fprintf (of, "%03o %03o %03o %03o %03o %03o", + (int) (cmd >> 40) & 0377, + (int) (cmd >> 32) & 0377, + (int) (cmd >> 24) & 0377, + (int) (cmd >> 16) & 0377, + (int) (cmd >> 8) & 0377, + (int) cmd & 0377); + } else if (sw & SWMASK ('X')) { + fprintf (of, "%013llx", cmd); + } else + fprintf (of, "%04o %04o %04o %04o", + (int) (cmd >> 36) & 07777, + (int) (cmd >> 24) & 07777, + (int) (cmd >> 12) & 07777, + (int) cmd & 07777); + return SCPE_OK; } /* * Symbolic input * * Inputs: - * *cptr = pointer to input string - * addr = current PC - * *uptr = pointer to unit - * *val = pointer to output values - * sw = switches + * *cptr = pointer to input string + * addr = current PC + * *uptr = pointer to unit + * *val = pointer to output values + * sw = switches * Outputs: - * status = error status + * status = error status */ t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) { - int32 i; + int32 i; - if (uptr && (uptr != &cpu_unit)) /* must be CPU */ - return SCPE_ARG; - if (! parse_instruction_word (cptr, val)) /* symbolic parse? */ - return SCPE_OK; + if (uptr && (uptr != &cpu_unit)) /* must be CPU */ + return SCPE_ARG; + if (! parse_instruction_word (cptr, val)) /* symbolic parse? */ + return SCPE_OK; - val[0] = 0; - for (i=0; i<16; i++) { - if (*cptr < '0' || *cptr > '7') - break; - val[0] = (val[0] << 3) | (*cptr - '0'); - cptr = skip_spaces (cptr+1); /* next char */ - } - if (*cptr != 0 && *cptr != ';' && *cptr != '\n' && *cptr != '\r') { - /*printf ("Extra symbols at eoln: %s\n", cptr);*/ - return SCPE_2MARG; - } - return SCPE_OK; + val[0] = 0; + for (i=0; i<16; i++) { + if (*cptr < '0' || *cptr > '7') + break; + val[0] = (val[0] << 3) | (*cptr - '0'); + cptr = skip_spaces (cptr+1); /* next char */ + } + if (*cptr != 0 && *cptr != ';' && *cptr != '\n' && *cptr != '\r') { + /*printf ("Extra symbols at eoln: %s\n", cptr);*/ + return SCPE_2MARG; + } + return SCPE_OK; } /* * Чтение строки входного файла. * Форматы строк: - * п 76543 - адрес пуска - * в 12345 - адрес ввода - * ч -123.45e+6 - вещественное число - * с 0123 4567 0123 4567 - восьмеричное слово - * к 00 22 00000 00 010 0000 - команды + * п 76543 - адрес пуска + * в 12345 - адрес ввода + * ч -123.45e+6 - вещественное число + * с 0123 4567 0123 4567 - восьмеричное слово + * к 00 22 00000 00 010 0000 - команды */ t_stat besm6_read_line (FILE *input, int *type, t_value *val) { - char buf [512], *p; - int i, c; -again: - if (! fgets (buf, sizeof (buf), input)) { - *type = 0; - return SCPE_OK; - } - p = skip_spaces (buf); - if (*p == '\n' || *p == ';') - goto again; - c = utf8_to_unicode (&p); - if (c == CYRILLIC_SMALL_LETTER_VE || - c == CYRILLIC_CAPITAL_LETTER_VE || - c == 'b' || c == 'B') { - /* Адрес размещения данных. */ - *type = ':'; - *val = strtol (p, 0, 8); - return SCPE_OK; - } - if (c == CYRILLIC_SMALL_LETTER_PE || - c == CYRILLIC_CAPITAL_LETTER_PE || - c == 'p' || c == 'P') { - /* Стартовый адрес. */ - *type = '@'; - *val = strtol (p, 0, 8); - return SCPE_OK; - } - if (c == CYRILLIC_SMALL_LETTER_CHE || - c == CYRILLIC_CAPITAL_LETTER_CHE || - c == 'f' || c == 'F') { - /* Вещественное число. */ - *type = '='; - *val = ieee_to_besm6 (strtod (p, 0)); - return SCPE_OK; - } - if (c == CYRILLIC_SMALL_LETTER_ES || - c == CYRILLIC_CAPITAL_LETTER_ES || - c == 'c' || c == 'C') { - /* Восьмеричное слово. */ - *type = '='; - *val = 0; - for (i=0; i<16; ++i) { - p = skip_spaces (p); - if (*p < '0' || *p > '7') { - if (i == 0) { - /* слишком короткое слово */ - goto bad; - } - break; - } - *val = *val << 3 | (*p++ - '0'); - } - return SCPE_OK; - } - if (c == CYRILLIC_SMALL_LETTER_KA || - c == CYRILLIC_CAPITAL_LETTER_KA || - c == 'k' || c == 'K') { - /* Команда. */ - *type = '*'; - if (parse_instruction_word (p, val) != SCPE_OK) - goto bad; - return SCPE_OK; - } - /* Неверная строка входного файла */ -bad: besm6_log ("Invalid input line: %s", buf); - return SCPE_FMT; + char buf [512], *p; + int i, c; + again: + if (! fgets (buf, sizeof (buf), input)) { + *type = 0; + return SCPE_OK; + } + p = skip_spaces (buf); + if (*p == '\n' || *p == ';') + goto again; + c = utf8_to_unicode (&p); + if (c == CYRILLIC_SMALL_LETTER_VE || + c == CYRILLIC_CAPITAL_LETTER_VE || + c == 'b' || c == 'B') { + /* Адрес размещения данных. */ + *type = ':'; + *val = strtol (p, 0, 8); + return SCPE_OK; + } + if (c == CYRILLIC_SMALL_LETTER_PE || + c == CYRILLIC_CAPITAL_LETTER_PE || + c == 'p' || c == 'P') { + /* Стартовый адрес. */ + *type = '@'; + *val = strtol (p, 0, 8); + return SCPE_OK; + } + if (c == CYRILLIC_SMALL_LETTER_CHE || + c == CYRILLIC_CAPITAL_LETTER_CHE || + c == 'f' || c == 'F') { + /* Вещественное число. */ + *type = '='; + *val = ieee_to_besm6 (strtod (p, 0)); + return SCPE_OK; + } + if (c == CYRILLIC_SMALL_LETTER_ES || + c == CYRILLIC_CAPITAL_LETTER_ES || + c == 'c' || c == 'C') { + /* Восьмеричное слово. */ + *type = '='; + *val = 0; + for (i=0; i<16; ++i) { + p = skip_spaces (p); + if (*p < '0' || *p > '7') { + if (i == 0) { + /* слишком короткое слово */ + goto bad; + } + break; + } + *val = *val << 3 | (*p++ - '0'); + } + return SCPE_OK; + } + if (c == CYRILLIC_SMALL_LETTER_KA || + c == CYRILLIC_CAPITAL_LETTER_KA || + c == 'k' || c == 'K') { + /* Команда. */ + *type = '*'; + if (parse_instruction_word (p, val) != SCPE_OK) + goto bad; + return SCPE_OK; + } + /* Неверная строка входного файла */ + bad: besm6_log ("Invalid input line: %s", buf); + return SCPE_FMT; } /* @@ -624,44 +624,44 @@ bad: besm6_log ("Invalid input line: %s", buf); */ t_stat besm6_load (FILE *input) { - int addr, type; - t_value word; - t_stat err; + int addr, type; + t_value word; + t_stat err; - addr = 1; - PC = 1; - for (;;) { - err = besm6_read_line (input, &type, &word); - if (err) - return err; - switch (type) { - case 0: /* EOF */ - return SCPE_OK; - case ':': /* address */ - addr = word; - break; - case '=': /* word */ - if (addr < 010) - pult [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); - else - memory [addr] = SET_CONVOL (word, CONVOL_INSN); - ++addr; - break; - case '@': /* start address */ - PC = word; - break; - } - if (addr > MEMSIZE) - return SCPE_FMT; - } - return SCPE_OK; + addr = 1; + PC = 1; + for (;;) { + err = besm6_read_line (input, &type, &word); + if (err) + return err; + switch (type) { + case 0: /* EOF */ + return SCPE_OK; + case ':': /* address */ + addr = word; + break; + case '=': /* word */ + if (addr < 010) + pult [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); + else + memory [addr] = SET_CONVOL (word, CONVOL_INSN); + ++addr; + break; + case '@': /* start address */ + PC = word; + break; + } + if (addr > MEMSIZE) + return SCPE_FMT; + } + return SCPE_OK; } /* @@ -669,42 +669,42 @@ t_stat besm6_load (FILE *input) */ t_stat besm6_dump (FILE *of, char *fnam) { - int addr, last_addr = -1; - t_value word; + int addr, last_addr = -1; + t_value word; - fprintf (of, "; %s\n", fnam); - for (addr=1; addr> 24); - fprintf (of, ", "); - besm6_fprint_cmd (of, word & BITS(24)); - fprintf (of, "\t\t; %05o - ", addr); - fprintf (of, "%04o %04o %04o %04o\n", - (int) (word >> 36) & 07777, - (int) (word >> 24) & 07777, - (int) (word >> 12) & 07777, - (int) word & 07777); - } else { - fprintf (of, "с %04o %04o %04o %04o", - (int) (word >> 36) & 07777, - (int) (word >> 24) & 07777, - (int) (word >> 12) & 07777, - (int) word & 07777); - fprintf (of, "\t\t; %05o\n", addr); - } - } - return SCPE_OK; + fprintf (of, "; %s\n", fnam); + for (addr=1; addr> 24); + fprintf (of, ", "); + besm6_fprint_cmd (of, word & BITS(24)); + fprintf (of, "\t\t; %05o - ", addr); + fprintf (of, "%04o %04o %04o %04o\n", + (int) (word >> 36) & 07777, + (int) (word >> 24) & 07777, + (int) (word >> 12) & 07777, + (int) word & 07777); + } else { + fprintf (of, "с %04o %04o %04o %04o", + (int) (word >> 36) & 07777, + (int) (word >> 24) & 07777, + (int) (word >> 12) & 07777, + (int) word & 07777); + fprintf (of, "\t\t; %05o\n", addr); + } + } + return SCPE_OK; } /* @@ -712,8 +712,8 @@ t_stat besm6_dump (FILE *of, char *fnam) */ t_stat sim_load (FILE *fi, char *cptr, char *fnam, int dump_flag) { - if (dump_flag) - return besm6_dump (fi, fnam); + if (dump_flag) + return besm6_dump (fi, fnam); - return besm6_load (fi); + return besm6_load (fi); } diff --git a/BESM6/besm6_tty.c b/BESM6/besm6_tty.c index 9d37e23f..14ea236e 100644 --- a/BESM6/besm6_tty.c +++ b/BESM6/besm6_tty.c @@ -19,41 +19,41 @@ #include "sim_tmxr.h" #include -#define TTY_MAX 24 /* Количество последовательных терминалов */ -#define LINES_MAX TTY_MAX + 2 /* Включая параллельные интерфейсы "Консулов" */ +#define TTY_MAX 24 /* Количество последовательных терминалов */ +#define LINES_MAX TTY_MAX + 2 /* Включая параллельные интерфейсы "Консулов" */ /* * Согласно таблице в http://ru.wikipedia.org/wiki/МТК-2 */ char * rus[] = { 0, "Т", "\r", "О", " ", "Х", "Н", "М", "\n", "Л", "Р", "Г", "И", "П", "Ц", "Ж", - "Е", "З", "Д", "Б", "С", "Ы", "Ф", "Ь", "А", "В", "Й", 0, "У", "Я", "К", 0 }; + "Е", "З", "Д", "Б", "С", "Ы", "Ф", "Ь", "А", "В", "Й", 0, "У", "Я", "К", 0 }; char * lat[] = { 0, "T", "\r", "O", " ", "H", "N", "M", "\n", "L", "R", "G", "I", "P", "C", "V", - "E", "Z", "D", "B", "S", "Y", "F", "X", "A", "W", "J", 0, "U", "Q", "K", 0 }; + "E", "Z", "D", "B", "S", "Y", "F", "X", "A", "W", "J", 0, "U", "Q", "K", 0 }; /* $ = Кто там? */ char * dig[] = { 0, "5", "\r", "9", " ", "Щ", ",", ".", "\n", ")", "4", "Ш", "8", "0", ":", "=", - "3", "+", "$", "?", "'", "6", "Э", "/", "-", "2", "Ю", 0, "7", "1", "(", 0 }; + "3", "+", "$", "?", "'", "6", "Э", "/", "-", "2", "Ю", 0, "7", "1", "(", 0 }; char ** reg = 0; char * process (int sym) { - /* Требуется инверсия */ - sym ^= 31; - switch (sym) { - case 0: - reg = rus; - break; - case 27: - reg = dig; - break; - case 31: - reg = lat; - break; - default: - return reg[sym]; - } - return ""; + /* Требуется инверсия */ + sym ^= 31; + switch (sym) { + case 0: + reg = rus; + break; + case 27: + reg = dig; + break; + case 31: + reg = lat; + break; + default: + return reg[sym]; + } + return ""; } /* Только для последовательных линий */ @@ -84,39 +84,39 @@ t_stat vt_clk(UNIT *); extern char *get_sim_sw (char *cptr); UNIT tty_unit [] = { - { UDATA (vt_clk, UNIT_DIS, 0) }, /* fake unit, clock */ - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - /* The next two units are parallel interface */ - { UDATA (NULL, UNIT_SEQ, 0) }, - { UDATA (NULL, UNIT_SEQ, 0) }, - { 0 } + { UDATA (vt_clk, UNIT_DIS, 0) }, /* fake unit, clock */ + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + /* The next two units are parallel interface */ + { UDATA (NULL, UNIT_SEQ, 0) }, + { UDATA (NULL, UNIT_SEQ, 0) }, + { 0 } }; REG tty_reg[] = { - { 0 } + { 0 } }; /* @@ -129,268 +129,268 @@ REG tty_reg[] = { * Для локальных терминалов оно равно 0. */ TMLN tty_line [LINES_MAX+1]; -TMXR tty_desc = { LINES_MAX+1, 0, 0, tty_line }; /* mux descriptor */ +TMXR tty_desc = { LINES_MAX+1, 0, 0, tty_line }; /* mux descriptor */ -#define TTY_UNICODE_CHARSET 0 -#define TTY_KOI7_JCUKEN_CHARSET (1<>= 1)) { - tt_print(); - /* Прием не реализован */ - clk_divider = 1<<29; - } + if (! (clk_divider >>= 1)) { + tt_print(); + /* Прием не реализован */ + clk_divider = 1<<29; + } - /* Есть новые сетевые подключения? */ - int num = tmxr_poll_conn (&tty_desc); - if (num > 0 && num <= LINES_MAX) { - char buf [80]; - TMLN *t = &tty_line [num]; - besm6_debug ("*** tty%d: новое подключение от %s", - num, t->ipad); - t->rcve = 1; - tty_unit[num].flags &= ~TTY_STATE_MASK; - tty_unit[num].flags |= TTY_VT340_STATE; - if (num <= TTY_MAX) - vt_mask |= 1 << (TTY_MAX - num); + /* Есть новые сетевые подключения? */ + int num = tmxr_poll_conn (&tty_desc); + if (num > 0 && num <= LINES_MAX) { + char buf [80]; + TMLN *t = &tty_line [num]; + besm6_debug ("*** tty%d: новое подключение от %s", + num, t->ipad); + t->rcve = 1; + tty_unit[num].flags &= ~TTY_STATE_MASK; + tty_unit[num].flags |= TTY_VT340_STATE; + if (num <= TTY_MAX) + vt_mask |= 1 << (TTY_MAX - num); - switch (tty_unit[num].flags & TTY_CHARSET_MASK) { - case TTY_KOI7_JCUKEN_CHARSET: - tmxr_linemsg (t, "Encoding is KOI-7 (jcuken)\r\n"); - break; - case TTY_KOI7_QWERTY_CHARSET: - tmxr_linemsg (t, "Encoding is KOI-7 (qwerty)\r\n"); - break; - case TTY_UNICODE_CHARSET: - tmxr_linemsg (t, "Encoding is UTF-8\r\n"); - break; - } - tty_idle_count[num] = 0; - tty_last_time[num] = time (0); - sprintf (buf, "%.24s from %s\r\n", - ctime (&tty_last_time[num]), - t->ipad); - tmxr_linemsg (t, buf); + switch (tty_unit[num].flags & TTY_CHARSET_MASK) { + case TTY_KOI7_JCUKEN_CHARSET: + tmxr_linemsg (t, "Encoding is KOI-7 (jcuken)\r\n"); + break; + case TTY_KOI7_QWERTY_CHARSET: + tmxr_linemsg (t, "Encoding is KOI-7 (qwerty)\r\n"); + break; + case TTY_UNICODE_CHARSET: + tmxr_linemsg (t, "Encoding is UTF-8\r\n"); + break; + } + tty_idle_count[num] = 0; + tty_last_time[num] = time (0); + sprintf (buf, "%.24s from %s\r\n", + ctime (&tty_last_time[num]), + t->ipad); + tmxr_linemsg (t, buf); - /* Ввод ^C, чтобы получить приглашение. */ - t->rxb [t->rxbpi++] = '\3'; - } + /* Ввод ^C, чтобы получить приглашение. */ + t->rxb [t->rxbpi++] = '\3'; + } - /* Опрашиваем сокеты на передачу. */ - tmxr_poll_tx (&tty_desc); + /* Опрашиваем сокеты на передачу. */ + tmxr_poll_tx (&tty_desc); - return sim_activate (this, 1000*MSEC/300); + return sim_activate (this, 1000*MSEC/300); } t_stat tty_setmode (UNIT *u, int32 val, char *cptr, void *desc) { - int num = u - tty_unit; - TMLN *t = &tty_line [num]; - uint32 mask = 1 << (TTY_MAX - num); + int num = u - tty_unit; + TMLN *t = &tty_line [num]; + uint32 mask = 1 << (TTY_MAX - num); - switch (val & TTY_STATE_MASK) { - case TTY_OFFLINE_STATE: - if (t->conn) { - if (t->rcve) { - tmxr_reset_ln (t); - t->rcve = 0; - } else - t->conn = 0; - if (num <= TTY_MAX) { - tty_sym[num] = - tty_active[num] = - tty_typed[num] = - tty_instate[num] = 0; - vt_mask &= ~mask; - tt_mask &= ~mask; - } - } - break; - case TTY_TELETYPE_STATE: - if (num > TTY_MAX) - return SCPE_NXPAR; - t->conn = 1; - t->rcve = 0; - tt_mask |= mask; - vt_mask &= ~mask; - break; - case TTY_VT340_STATE: - t->conn = 1; - t->rcve = 0; - if (num <= TTY_MAX) { - vt_mask |= mask; - tt_mask &= ~mask; - } - break; - case TTY_CONSUL_STATE: - if (num <= TTY_MAX) - return SCPE_NXPAR; - t->conn = 1; - t->rcve = 0; - break; - } - return SCPE_OK; + switch (val & TTY_STATE_MASK) { + case TTY_OFFLINE_STATE: + if (t->conn) { + if (t->rcve) { + tmxr_reset_ln (t); + t->rcve = 0; + } else + t->conn = 0; + if (num <= TTY_MAX) { + tty_sym[num] = + tty_active[num] = + tty_typed[num] = + tty_instate[num] = 0; + vt_mask &= ~mask; + tt_mask &= ~mask; + } + } + break; + case TTY_TELETYPE_STATE: + if (num > TTY_MAX) + return SCPE_NXPAR; + t->conn = 1; + t->rcve = 0; + tt_mask |= mask; + vt_mask &= ~mask; + break; + case TTY_VT340_STATE: + t->conn = 1; + t->rcve = 0; + if (num <= TTY_MAX) { + vt_mask |= mask; + tt_mask &= ~mask; + } + break; + case TTY_CONSUL_STATE: + if (num <= TTY_MAX) + return SCPE_NXPAR; + t->conn = 1; + t->rcve = 0; + break; + } + return SCPE_OK; } /* * Разрешение подключения к терминалам через telnet. * Делается командой: - * attach tty <порт> + * attach tty <порт> * Здесь <порт> - номер порта telnet, например 4199. */ t_stat tty_attach (UNIT *u, char *cptr) { - int num = u - tty_unit; - int r, m, n; + int num = u - tty_unit; + int r, m, n; - if (*cptr >= '0' && *cptr <= '9') { - /* Сохраняем и восстанавливаем все .conn, - * так как tmxr_attach() их обнуляет. */ - for (m=0, n=1; n<=LINES_MAX; ++n) - if (tty_line[n].conn) - m |= 1 << (LINES_MAX-n); - /* Неважно, какой номер порта указывать в команде задания - * порта telnet. Можно tty, можно tty1 - без разницы. */ - r = tmxr_attach (&tty_desc, &tty_unit[0], cptr); - for (n=1; n<=LINES_MAX; ++n) - if (m >> (LINES_MAX-n) & 1) - tty_line[n].conn = 1; - return r; - } - if (strcmp (cptr, "/dev/tty") == 0) { - /* Консоль. */ - u->flags &= ~TTY_STATE_MASK; - u->flags |= TTY_VT340_STATE; - tty_line[num].conn = 1; - tty_line[num].rcve = 0; - if (num <= TTY_MAX) - vt_mask |= 1 << (TTY_MAX - num); - besm6_debug ("*** консоль на T%03o", num); - return 0; - } - if (strcmp (cptr, "/dev/null") == 0) { - /* Запрещаем терминал. */ - tty_line[num].conn = 1; - tty_line[num].rcve = 0; - if (num <= TTY_MAX) { - vt_mask &= ~(1 << (TTY_MAX - num)); - tt_mask &= ~(1 << (TTY_MAX - num)); - } - besm6_debug ("*** отключение терминала T%03o", num); - return 0; - } - return SCPE_ALATT; + if (*cptr >= '0' && *cptr <= '9') { + /* Сохраняем и восстанавливаем все .conn, + * так как tmxr_attach() их обнуляет. */ + for (m=0, n=1; n<=LINES_MAX; ++n) + if (tty_line[n].conn) + m |= 1 << (LINES_MAX-n); + /* Неважно, какой номер порта указывать в команде задания + * порта telnet. Можно tty, можно tty1 - без разницы. */ + r = tmxr_attach (&tty_desc, &tty_unit[0], cptr); + for (n=1; n<=LINES_MAX; ++n) + if (m >> (LINES_MAX-n) & 1) + tty_line[n].conn = 1; + return r; + } + if (strcmp (cptr, "/dev/tty") == 0) { + /* Консоль. */ + u->flags &= ~TTY_STATE_MASK; + u->flags |= TTY_VT340_STATE; + tty_line[num].conn = 1; + tty_line[num].rcve = 0; + if (num <= TTY_MAX) + vt_mask |= 1 << (TTY_MAX - num); + besm6_debug ("*** консоль на T%03o", num); + return 0; + } + if (strcmp (cptr, "/dev/null") == 0) { + /* Запрещаем терминал. */ + tty_line[num].conn = 1; + tty_line[num].rcve = 0; + if (num <= TTY_MAX) { + vt_mask &= ~(1 << (TTY_MAX - num)); + tt_mask &= ~(1 << (TTY_MAX - num)); + } + besm6_debug ("*** отключение терминала T%03o", num); + return 0; + } + return SCPE_ALATT; } t_stat tty_detach (UNIT *u) { - return tmxr_detach (&tty_desc, &tty_unit[0]); + return tmxr_detach (&tty_desc, &tty_unit[0]); } /* * Управление терминалами. - * set ttyN unicode - выбор кодировки UTF-8 - * set ttyN jcuken - выбор кодировки КОИ-7, раскладка йцукен - * set ttyN qwerty - выбор кодировки КОИ-7, раскладка яверты - * set ttyN off - отключение - * set ttyN tt - установка типа терминала "Телетайп" - * set ttyN vt - установка типа терминала "Видеотон-340" - * set ttyN consul - установка типа терминала "Consul-254" - * set ttyN destrbs - "стирающий" backspace - * set ttyN authbs - классический backspace - * set tty disconnect=N - принудительное завершение сеанса telnet - * show tty - просмотр режимов терминалов - * show tty connections - просмотр IP-адресов и времени соединений - * show tty statistics - просмотр счетчиков переданных и принятых байтов + * set ttyN unicode - выбор кодировки UTF-8 + * set ttyN jcuken - выбор кодировки КОИ-7, раскладка йцукен + * set ttyN qwerty - выбор кодировки КОИ-7, раскладка яверты + * set ttyN off - отключение + * set ttyN tt - установка типа терминала "Телетайп" + * set ttyN vt - установка типа терминала "Видеотон-340" + * set ttyN consul - установка типа терминала "Consul-254" + * set ttyN destrbs - "стирающий" backspace + * set ttyN authbs - классический backspace + * set tty disconnect=N - принудительное завершение сеанса telnet + * show tty - просмотр режимов терминалов + * show tty connections - просмотр IP-адресов и времени соединений + * show tty statistics - просмотр счетчиков переданных и принятых байтов */ MTAB tty_mod[] = { - { TTY_CHARSET_MASK, TTY_UNICODE_CHARSET, "UTF-8 input", - "UNICODE" }, - { TTY_CHARSET_MASK, TTY_KOI7_JCUKEN_CHARSET, "KOI7 (jcuken) input", - "JCUKEN" }, - { TTY_CHARSET_MASK, TTY_KOI7_QWERTY_CHARSET, "KOI7 (qwerty) input", - "QWERTY" }, - { TTY_STATE_MASK, TTY_OFFLINE_STATE, "offline", - "OFF", &tty_setmode }, - { TTY_STATE_MASK, TTY_TELETYPE_STATE, "Teletype", - "TT", &tty_setmode }, - { TTY_STATE_MASK, TTY_VT340_STATE, "Videoton-340", - "VT", &tty_setmode }, - { TTY_STATE_MASK, TTY_CONSUL_STATE, "Consul-254", - "CONSUL", &tty_setmode }, - { TTY_BSPACE_MASK, TTY_DESTRUCTIVE_BSPACE, "destructive backspace", - "DESTRBS" }, - { TTY_BSPACE_MASK, TTY_AUTHENTIC_BSPACE, NULL, - "AUTHBS" }, - { MTAB_XTD | MTAB_VDV, 1, NULL, - "DISCONNECT", &tmxr_dscln, NULL, (void*) &tty_desc }, - { UNIT_ATT, UNIT_ATT, "connections", - NULL, NULL, &tmxr_show_summ, (void*) &tty_desc }, - { MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", - NULL, NULL, &tmxr_show_cstat, (void*) &tty_desc }, - { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", - NULL, NULL, &tmxr_show_cstat, (void*) &tty_desc }, - { MTAB_XTD | MTAB_VUN | MTAB_NC, 0, NULL, - "LOG", &tmxr_set_log, &tmxr_show_log, (void*) &tty_desc }, - { MTAB_XTD | MTAB_VUN | MTAB_NC, 0, NULL, - "NOLOG", &tmxr_set_nolog, NULL, (void*) &tty_desc }, - { 0 } + { TTY_CHARSET_MASK, TTY_UNICODE_CHARSET, "UTF-8 input", + "UNICODE" }, + { TTY_CHARSET_MASK, TTY_KOI7_JCUKEN_CHARSET, "KOI7 (jcuken) input", + "JCUKEN" }, + { TTY_CHARSET_MASK, TTY_KOI7_QWERTY_CHARSET, "KOI7 (qwerty) input", + "QWERTY" }, + { TTY_STATE_MASK, TTY_OFFLINE_STATE, "offline", + "OFF", &tty_setmode }, + { TTY_STATE_MASK, TTY_TELETYPE_STATE, "Teletype", + "TT", &tty_setmode }, + { TTY_STATE_MASK, TTY_VT340_STATE, "Videoton-340", + "VT", &tty_setmode }, + { TTY_STATE_MASK, TTY_CONSUL_STATE, "Consul-254", + "CONSUL", &tty_setmode }, + { TTY_BSPACE_MASK, TTY_DESTRUCTIVE_BSPACE, "destructive backspace", + "DESTRBS" }, + { TTY_BSPACE_MASK, TTY_AUTHENTIC_BSPACE, NULL, + "AUTHBS" }, + { MTAB_XTD | MTAB_VDV, 1, NULL, + "DISCONNECT", &tmxr_dscln, NULL, (void*) &tty_desc }, + { UNIT_ATT, UNIT_ATT, "connections", + NULL, NULL, &tmxr_show_summ, (void*) &tty_desc }, + { MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", + NULL, NULL, &tmxr_show_cstat, (void*) &tty_desc }, + { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", + NULL, NULL, &tmxr_show_cstat, (void*) &tty_desc }, + { MTAB_XTD | MTAB_VUN | MTAB_NC, 0, NULL, + "LOG", &tmxr_set_log, &tmxr_show_log, (void*) &tty_desc }, + { MTAB_XTD | MTAB_VUN | MTAB_NC, 0, NULL, + "NOLOG", &tmxr_set_nolog, NULL, (void*) &tty_desc }, + { 0 } }; DEVICE tty_dev = { - "TTY", tty_unit, tty_reg, tty_mod, - 27, 2, 1, 1, 2, 1, - NULL, NULL, &tty_reset, NULL, &tty_attach, &tty_detach, - NULL, DEV_NET|DEV_DEBUG + "TTY", tty_unit, tty_reg, tty_mod, + 27, 2, 1, 1, 2, 1, + NULL, NULL, &tty_reset, NULL, &tty_attach, &tty_detach, + NULL, DEV_NET|DEV_DEBUG }; void tty_send (uint32 mask) { - /* besm6_debug ("*** телетайпы: передача %08o", mask); */ + /* besm6_debug ("*** телетайпы: передача %08o", mask); */ - TTY_OUT = mask; + TTY_OUT = mask; } /* @@ -398,23 +398,23 @@ void tty_send (uint32 mask) */ void vt_putc (int num, int c) { - TMLN *t = &tty_line [num]; + TMLN *t = &tty_line [num]; - if (! t->conn) - return; - if (t->rcve) { - /* Передача через telnet. */ - tmxr_putc_ln (t, c); - } else { - /* Вывод на консоль. */ - if (t->txlog) { /* log if available */ - fputc (c, t->txlog); - if (c == '\n') - fflush (t->txlog); - } - fputc (c, stdout); - fflush (stdout); - } + if (! t->conn) + return; + if (t->rcve) { + /* Передача через telnet. */ + tmxr_putc_ln (t, c); + } else { + /* Вывод на консоль. */ + if (t->txlog) { /* log if available */ + fputc (c, t->txlog); + if (c == '\n') + fflush (t->txlog); + } + fputc (c, stdout); + fflush (stdout); + } } /* @@ -422,98 +422,98 @@ void vt_putc (int num, int c) */ void vt_puts (int num, const char *s) { - TMLN *t = &tty_line [num]; + TMLN *t = &tty_line [num]; - if (! t->conn) - return; - if (t->rcve) { - /* Передача через telnet. */ - tmxr_linemsg (t, (char*) s); - } else { - /* Вывод на консоль. */ - if (t->txlog) /* log if available */ - fputs (s, t->txlog); - fputs (s, stdout); - fflush (stdout); - } + if (! t->conn) + return; + if (t->rcve) { + /* Передача через telnet. */ + tmxr_linemsg (t, (char*) s); + } else { + /* Вывод на консоль. */ + if (t->txlog) /* log if available */ + fputs (s, t->txlog); + fputs (s, stdout); + fflush (stdout); + } } const char * koi7_rus_to_unicode [32] = { - "Ю", "А", "Б", "Ц", "Д", "Е", "Ф", "Г", - "Х", "И", "Й", "К", "Л", "М", "Н", "О", - "П", "Я", "Р", "С", "Т", "У", "Ж", "В", - "Ь", "Ы", "З", "Ш", "Э", "Щ", "Ч", "\0x7f", + "Ю", "А", "Б", "Ц", "Д", "Е", "Ф", "Г", + "Х", "И", "Й", "К", "Л", "М", "Н", "О", + "П", "Я", "Р", "С", "Т", "У", "Ж", "В", + "Ь", "Ы", "З", "Ш", "Э", "Щ", "Ч", "\0x7f", }; void vt_send(int num, uint32 sym, int destructive_bs) { - if (sym < 0x60) { - switch (sym) { - case '\031': - /* Up */ - vt_puts (num, "\033["); - sym = 'A'; - break; - case '\032': - /* Down */ - vt_puts (num, "\033["); - sym = 'B'; - break; - case '\030': - /* Right */ - vt_puts (num, "\033["); - sym = 'C'; - break; - case '\b': - /* Left */ - vt_puts (num, "\033["); - if (destructive_bs) { - /* Стираем предыдущий символ. */ - vt_puts (num, "D \033["); - } - sym = 'D'; - break; - case '\v': - case '\033': - case '\0': - /* Выдаём управляющий символ. */ - break; - case '\037': - /* Очистка экрана */ - vt_puts (num, "\033[H\033["); - sym = 'J'; - break; - case '\n': - /* На VDT-340 также возвращал курсор в 1-ю позицию */ - vt_putc (num, '\r'); - sym = '\n'; - break; - case '\f': - /* Сообщение ERR при нажатии некоторых управляющих - * клавиш выдается с использованием reverse wraparound. - */ - vt_puts(num, "\033["); - sym = 'H'; - break; - case '\r': - case '\003': - /* Неотображаемые символы */ - sym = 0; - break; - default: - if (sym < ' ') { - /* Нефункциональные ctrl-символы были видны в половинной яркости */ - vt_puts (num, "\033[2m"); - vt_putc (num, sym | 0x40); - vt_puts (num, "\033["); - /* Завершаем ESC-последовательность */ - sym = 'm'; - } - } - if (sym) - vt_putc (num, sym); - } else - vt_puts (num, koi7_rus_to_unicode[sym - 0x60]); + if (sym < 0x60) { + switch (sym) { + case '\031': + /* Up */ + vt_puts (num, "\033["); + sym = 'A'; + break; + case '\032': + /* Down */ + vt_puts (num, "\033["); + sym = 'B'; + break; + case '\030': + /* Right */ + vt_puts (num, "\033["); + sym = 'C'; + break; + case '\b': + /* Left */ + vt_puts (num, "\033["); + if (destructive_bs) { + /* Стираем предыдущий символ. */ + vt_puts (num, "D \033["); + } + sym = 'D'; + break; + case '\v': + case '\033': + case '\0': + /* Выдаём управляющий символ. */ + break; + case '\037': + /* Очистка экрана */ + vt_puts (num, "\033[H\033["); + sym = 'J'; + break; + case '\n': + /* На VDT-340 также возвращал курсор в 1-ю позицию */ + vt_putc (num, '\r'); + sym = '\n'; + break; + case '\f': + /* Сообщение ERR при нажатии некоторых управляющих + * клавиш выдается с использованием reverse wraparound. + */ + vt_puts(num, "\033["); + sym = 'H'; + break; + case '\r': + case '\003': + /* Неотображаемые символы */ + sym = 0; + break; + default: + if (sym < ' ') { + /* Нефункциональные ctrl-символы были видны в половинной яркости */ + vt_puts (num, "\033[2m"); + vt_putc (num, sym | 0x40); + vt_puts (num, "\033["); + /* Завершаем ESC-последовательность */ + sym = 'm'; + } + } + if (sym) + vt_putc (num, sym); + } else + vt_puts (num, koi7_rus_to_unicode[sym - 0x60]); } /* @@ -521,47 +521,47 @@ void vt_send(int num, uint32 sym, int destructive_bs) */ void vt_print() { - uint32 workset = (TTY_OUT & vt_mask) | vt_sending; - int num; + uint32 workset = (TTY_OUT & vt_mask) | vt_sending; + int num; - if (workset == 0) { - ++vt_idle; - return; - } - for (num = besm6_highest_bit (workset) - TTY_MAX; - workset; num = besm6_highest_bit (workset) - TTY_MAX) { - int mask = 1 << (TTY_MAX - num); - int c = (TTY_OUT & mask) != 0; - switch (tty_active[num]*2+c) { - case 0: /* idle */ - besm6_debug ("Warning: inactive ttys should have been screened"); - continue; - case 1: /* start bit */ - vt_sending |= mask; - tty_active[num] = 1; - break; - case 18: /* stop bit */ - tty_sym[num] = ~tty_sym[num] & 0x7f; - vt_send (num, tty_sym[num], - (tty_unit[num].flags & TTY_BSPACE_MASK) == TTY_DESTRUCTIVE_BSPACE); - tty_active[num] = 0; - tty_sym[num] = 0; - vt_sending &= ~mask; - break; - case 19: /* framing error */ - vt_putc (num, '#'); - break; - default: - /* little endian ordering */ - if (c) { - tty_sym[num] |= 1 << (tty_active[num]-1); - } - ++tty_active[num]; - break; - } - workset &= ~mask; - } - vt_idle = 0; + if (workset == 0) { + ++vt_idle; + return; + } + for (num = besm6_highest_bit (workset) - TTY_MAX; + workset; num = besm6_highest_bit (workset) - TTY_MAX) { + int mask = 1 << (TTY_MAX - num); + int c = (TTY_OUT & mask) != 0; + switch (tty_active[num]*2+c) { + case 0: /* idle */ + besm6_debug ("Warning: inactive ttys should have been screened"); + continue; + case 1: /* start bit */ + vt_sending |= mask; + tty_active[num] = 1; + break; + case 18: /* stop bit */ + tty_sym[num] = ~tty_sym[num] & 0x7f; + vt_send (num, tty_sym[num], + (tty_unit[num].flags & TTY_BSPACE_MASK) == TTY_DESTRUCTIVE_BSPACE); + tty_active[num] = 0; + tty_sym[num] = 0; + vt_sending &= ~mask; + break; + case 19: /* framing error */ + vt_putc (num, '#'); + break; + default: + /* little endian ordering */ + if (c) { + tty_sym[num] |= 1 << (tty_active[num]-1); + } + ++tty_active[num]; + break; + } + workset &= ~mask; + } + vt_idle = 0; } /* Ввод с телетайпа не реализован; вывод работает только при использовании @@ -569,44 +569,44 @@ void vt_print() */ void tt_print() { - uint32 workset = (TTY_OUT & tt_mask) | tt_sending; - int num; + uint32 workset = (TTY_OUT & tt_mask) | tt_sending; + int num; - if (workset == 0) { - return; - } + if (workset == 0) { + return; + } - for (num = besm6_highest_bit (workset) - TTY_MAX; - workset; num = besm6_highest_bit (workset) - TTY_MAX) { - int mask = 1 << (TTY_MAX - num); - int c = (TTY_OUT & mask) != 0; - switch (tty_active[num]*2+c) { - case 0: /* idle */ - break; - case 1: /* start bit */ - tt_sending |= mask; - tty_active[num] = 1; - break; - case 12: /* stop bit */ - vt_puts (num, process (tty_sym[num])); - tty_active[num] = 0; - tty_sym[num] = 0; - tt_sending &= ~mask; - break; - case 13: /* framing error */ - vt_putc (num, '#'); - break; - default: - /* big endian ordering */ - if (c) { - tty_sym[num] |= 1 << (5-tty_active[num]); - } - ++tty_active[num]; - break; - } - workset &= ~mask; - } - vt_idle = 0; + for (num = besm6_highest_bit (workset) - TTY_MAX; + workset; num = besm6_highest_bit (workset) - TTY_MAX) { + int mask = 1 << (TTY_MAX - num); + int c = (TTY_OUT & mask) != 0; + switch (tty_active[num]*2+c) { + case 0: /* idle */ + break; + case 1: /* start bit */ + tt_sending |= mask; + tty_active[num] = 1; + break; + case 12: /* stop bit */ + vt_puts (num, process (tty_sym[num])); + tty_active[num] = 0; + tty_sym[num] = 0; + tt_sending &= ~mask; + break; + case 13: /* framing error */ + vt_putc (num, '#'); + break; + default: + /* big endian ordering */ + if (c) { + tty_sym[num] |= 1 << (5-tty_active[num]); + } + ++tty_active[num]; + break; + } + workset &= ~mask; + } + vt_idle = 0; } /* @@ -615,43 +615,43 @@ void tt_print() */ static int unicode_to_koi7 (unsigned val) { - switch (val) { - case '\0'... '_': return val; - case 'a' ... 'z': return val + 'Z' - 'z'; - case 0x007f: return 0x7f; - case 0x0410: case 0x0430: return 0x61; - case 0x0411: case 0x0431: return 0x62; - case 0x0412: case 0x0432: return 0x77; - case 0x0413: case 0x0433: return 0x67; - case 0x0414: case 0x0434: return 0x64; - case 0x0415: case 0x0435: return 0x65; - case 0x0416: case 0x0436: return 0x76; - case 0x0417: case 0x0437: return 0x7a; - case 0x0418: case 0x0438: return 0x69; - case 0x0419: case 0x0439: return 0x6a; - case 0x041a: case 0x043a: return 0x6b; - case 0x041b: case 0x043b: return 0x6c; - case 0x041c: case 0x043c: return 0x6d; - case 0x041d: case 0x043d: return 0x6e; - case 0x041e: case 0x043e: return 0x6f; - case 0x041f: case 0x043f: return 0x70; - case 0x0420: case 0x0440: return 0x72; - case 0x0421: case 0x0441: return 0x73; - case 0x0422: case 0x0442: return 0x74; - case 0x0423: case 0x0443: return 0x75; - case 0x0424: case 0x0444: return 0x66; - case 0x0425: case 0x0445: return 0x68; - case 0x0426: case 0x0446: return 0x63; - case 0x0427: case 0x0447: return 0x7e; - case 0x0428: case 0x0448: return 0x7b; - case 0x0429: case 0x0449: return 0x7d; - case 0x042b: case 0x044b: return 0x79; - case 0x042c: case 0x044c: return 0x78; - case 0x042d: case 0x044d: return 0x7c; - case 0x042e: case 0x044e: return 0x60; - case 0x042f: case 0x044f: return 0x71; - } - return -1; + if ('_' <= val) return val; + else if ('a' <= val && val <= 'z') return val + 'Z' - 'z'; + else switch (val) { + case 0x007f: return 0x7f; + case 0x0410: case 0x0430: return 0x61; + case 0x0411: case 0x0431: return 0x62; + case 0x0412: case 0x0432: return 0x77; + case 0x0413: case 0x0433: return 0x67; + case 0x0414: case 0x0434: return 0x64; + case 0x0415: case 0x0435: return 0x65; + case 0x0416: case 0x0436: return 0x76; + case 0x0417: case 0x0437: return 0x7a; + case 0x0418: case 0x0438: return 0x69; + case 0x0419: case 0x0439: return 0x6a; + case 0x041a: case 0x043a: return 0x6b; + case 0x041b: case 0x043b: return 0x6c; + case 0x041c: case 0x043c: return 0x6d; + case 0x041d: case 0x043d: return 0x6e; + case 0x041e: case 0x043e: return 0x6f; + case 0x041f: case 0x043f: return 0x70; + case 0x0420: case 0x0440: return 0x72; + case 0x0421: case 0x0441: return 0x73; + case 0x0422: case 0x0442: return 0x74; + case 0x0423: case 0x0443: return 0x75; + case 0x0424: case 0x0444: return 0x66; + case 0x0425: case 0x0445: return 0x68; + case 0x0426: case 0x0446: return 0x63; + case 0x0427: case 0x0447: return 0x7e; + case 0x0428: case 0x0448: return 0x7b; + case 0x0429: case 0x0449: return 0x7d; + case 0x042b: case 0x044b: return 0x79; + case 0x042c: case 0x044c: return 0x78; + case 0x042d: case 0x044d: return 0x7c; + case 0x042e: case 0x044e: return 0x60; + case 0x042f: case 0x044f: return 0x71; + } + return -1; } /* @@ -659,47 +659,47 @@ static int unicode_to_koi7 (unsigned val) */ static t_stat cmd_set (int32 num, char *cptr) { - char gbuf [CBUFSIZE]; - int len; + char gbuf [CBUFSIZE]; + int len; - cptr = get_sim_sw (cptr); - if (! cptr) - return SCPE_INVSW; - if (! *cptr) - return SCPE_NOPARAM; - cptr = get_glyph (cptr, gbuf, 0); - if (*cptr) - return SCPE_2MARG; + cptr = get_sim_sw (cptr); + if (! cptr) + return SCPE_INVSW; + if (! *cptr) + return SCPE_NOPARAM; + cptr = get_glyph (cptr, gbuf, 0); + if (*cptr) + return SCPE_2MARG; - len = strlen (gbuf); - if (strncmp ("UNICODE", gbuf, len) == 0) { - tty_unit[num].flags &= ~TTY_CHARSET_MASK; - tty_unit[num].flags |= TTY_UNICODE_CHARSET; - } else if (strncmp ("JCUKEN", gbuf, len) == 0) { - tty_unit[num].flags &= ~TTY_CHARSET_MASK; - tty_unit[num].flags |= TTY_KOI7_JCUKEN_CHARSET; - } else if (strncmp ("QWERTY", gbuf, len) == 0) { - tty_unit[num].flags &= ~TTY_CHARSET_MASK; - tty_unit[num].flags |= TTY_KOI7_QWERTY_CHARSET; - } else if (strncmp ("TT", gbuf, len) == 0) { - tty_unit[num].flags &= ~TTY_STATE_MASK; - tty_unit[num].flags |= TTY_TELETYPE_STATE; - } else if (strncmp ("VT", gbuf, len) == 0) { - tty_unit[num].flags &= ~TTY_STATE_MASK; - tty_unit[num].flags |= TTY_VT340_STATE; - } else if (strncmp ("CONSUL", gbuf, len) == 0) { - tty_unit[num].flags &= ~TTY_STATE_MASK; - tty_unit[num].flags |= TTY_CONSUL_STATE; - } else if (strncmp ("DESTRBS", gbuf, len) == 0) { - tty_unit[num].flags &= ~TTY_BSPACE_MASK; - tty_unit[num].flags |= TTY_DESTRUCTIVE_BSPACE; - } else if (strncmp ("AUTHBS", gbuf, len) == 0) { - tty_unit[num].flags &= ~TTY_BSPACE_MASK; - tty_unit[num].flags |= TTY_AUTHENTIC_BSPACE; - } else { - return SCPE_NXPAR; - } - return SCPE_OK; + len = strlen (gbuf); + if (strncmp ("UNICODE", gbuf, len) == 0) { + tty_unit[num].flags &= ~TTY_CHARSET_MASK; + tty_unit[num].flags |= TTY_UNICODE_CHARSET; + } else if (strncmp ("JCUKEN", gbuf, len) == 0) { + tty_unit[num].flags &= ~TTY_CHARSET_MASK; + tty_unit[num].flags |= TTY_KOI7_JCUKEN_CHARSET; + } else if (strncmp ("QWERTY", gbuf, len) == 0) { + tty_unit[num].flags &= ~TTY_CHARSET_MASK; + tty_unit[num].flags |= TTY_KOI7_QWERTY_CHARSET; + } else if (strncmp ("TT", gbuf, len) == 0) { + tty_unit[num].flags &= ~TTY_STATE_MASK; + tty_unit[num].flags |= TTY_TELETYPE_STATE; + } else if (strncmp ("VT", gbuf, len) == 0) { + tty_unit[num].flags &= ~TTY_STATE_MASK; + tty_unit[num].flags |= TTY_VT340_STATE; + } else if (strncmp ("CONSUL", gbuf, len) == 0) { + tty_unit[num].flags &= ~TTY_STATE_MASK; + tty_unit[num].flags |= TTY_CONSUL_STATE; + } else if (strncmp ("DESTRBS", gbuf, len) == 0) { + tty_unit[num].flags &= ~TTY_BSPACE_MASK; + tty_unit[num].flags |= TTY_DESTRUCTIVE_BSPACE; + } else if (strncmp ("AUTHBS", gbuf, len) == 0) { + tty_unit[num].flags &= ~TTY_BSPACE_MASK; + tty_unit[num].flags |= TTY_AUTHENTIC_BSPACE; + } else { + return SCPE_NXPAR; + } + return SCPE_OK; } /* @@ -707,44 +707,44 @@ static t_stat cmd_set (int32 num, char *cptr) */ static t_stat cmd_show (int32 num, char *cptr) { - TMLN *t = &tty_line [num]; - char gbuf [CBUFSIZE]; - MTAB *m; - int len; + TMLN *t = &tty_line [num]; + char gbuf [CBUFSIZE]; + MTAB *m; + int len; - cptr = get_sim_sw (cptr); - if (! cptr) - return SCPE_INVSW; - if (! *cptr) { - sprintf (gbuf, "TTY%d", num); - tmxr_linemsg (t, gbuf); - for (m=tty_mod; m->mask; m++) { - if (m->pstring && - (tty_unit[num].flags & m->mask) == m->match) { - tmxr_linemsg (t, ", "); - tmxr_linemsg (t, m->pstring); - } - } - if (t->txlog) - tmxr_linemsg (t, ", log"); - tmxr_linemsg (t, "\r\n"); - return SCPE_OK; - } - cptr = get_glyph (cptr, gbuf, 0); - if (*cptr) - return SCPE_2MARG; + cptr = get_sim_sw (cptr); + if (! cptr) + return SCPE_INVSW; + if (! *cptr) { + sprintf (gbuf, "TTY%d", num); + tmxr_linemsg (t, gbuf); + for (m=tty_mod; m->mask; m++) { + if (m->pstring && + (tty_unit[num].flags & m->mask) == m->match) { + tmxr_linemsg (t, ", "); + tmxr_linemsg (t, m->pstring); + } + } + if (t->txlog) + tmxr_linemsg (t, ", log"); + tmxr_linemsg (t, "\r\n"); + return SCPE_OK; + } + cptr = get_glyph (cptr, gbuf, 0); + if (*cptr) + return SCPE_2MARG; - len = strlen (gbuf); - if (strncmp ("STATISTICS", gbuf, len) == 0) { - sprintf (gbuf, "line %d: input queued/total = %d/%d, " - "output queued/total = %d/%d\r\n", num, - t->rxbpi - t->rxbpr, t->rxcnt, - t->txbpi - t->txbpr, t->txcnt); - tmxr_linemsg (t, gbuf); - } else { - return SCPE_NXPAR; - } - return SCPE_OK; + len = strlen (gbuf); + if (strncmp ("STATISTICS", gbuf, len) == 0) { + sprintf (gbuf, "line %d: input queued/total = %d/%d, " + "output queued/total = %d/%d\r\n", num, + t->rxbpi - t->rxbpr, t->rxcnt, + t->txbpi - t->txbpr, t->txcnt); + tmxr_linemsg (t, gbuf); + } else { + return SCPE_NXPAR; + } + return SCPE_OK; } /* @@ -752,38 +752,38 @@ static t_stat cmd_show (int32 num, char *cptr) */ static t_stat cmd_exit (int32 num, char *cptr) { - return SCPE_EXIT; + return SCPE_EXIT; } static t_stat cmd_help (int32 num, char *cptr); static CTAB cmd_table[] = { - { "SET", &cmd_set, 0, - "set unicode select UTF-8 encoding\r\n" - "set jcuken select KOI7 encoding, 'jcuken' keymap\r\n" - "set qwerty select KOI7 encoding, 'qwerty' keymap\r\n" - "set tt use Teletype mode\r\n" - "set vt use Videoton-340 mode\r\n" - "set consul use Consul-254 mode\r\n" - "set destrbs destructive backspace\r\n" - "set authbs authentic backspace\r\n" - }, - { "SHOW", &cmd_show, 0, - "sh{ow} show modes of the terminal\r\n" - "sh{ow} s{tatistics} show network statistics\r\n" - }, - { "EXIT", &cmd_exit, 0, - "exi{t} | q{uit} | by{e} exit from simulation\r\n" - }, - { "QUIT", &cmd_exit, 0, NULL - }, - { "BYE", &cmd_exit, 0, NULL - }, - { "HELP", &cmd_help, 0, - "h{elp} type this message\r\n" - "h{elp} type help for command\r\n" - }, - { 0 } + { "SET", &cmd_set, 0, + "set unicode select UTF-8 encoding\r\n" + "set jcuken select KOI7 encoding, 'jcuken' keymap\r\n" + "set qwerty select KOI7 encoding, 'qwerty' keymap\r\n" + "set tt use Teletype mode\r\n" + "set vt use Videoton-340 mode\r\n" + "set consul use Consul-254 mode\r\n" + "set destrbs destructive backspace\r\n" + "set authbs authentic backspace\r\n" + }, + { "SHOW", &cmd_show, 0, + "sh{ow} show modes of the terminal\r\n" + "sh{ow} s{tatistics} show network statistics\r\n" + }, + { "EXIT", &cmd_exit, 0, + "exi{t} | q{uit} | by{e} exit from simulation\r\n" + }, + { "QUIT", &cmd_exit, 0, NULL + }, + { "BYE", &cmd_exit, 0, NULL + }, + { "HELP", &cmd_help, 0, + "h{elp} type this message\r\n" + "h{elp} type help for command\r\n" + }, + { 0 } }; /* @@ -791,15 +791,15 @@ static CTAB cmd_table[] = { */ static CTAB *lookup_cmd (char *command) { - CTAB *c; - int len; + CTAB *c; + int len; - len = strlen (command); - for (c=cmd_table; c->name; c++) { - if (strncmp (command, c->name, len) == 0) - return c; - } - return 0; + len = strlen (command); + for (c=cmd_table; c->name; c++) { + if (strncmp (command, c->name, len) == 0) + return c; + } + return 0; } /* @@ -807,30 +807,30 @@ static CTAB *lookup_cmd (char *command) */ static t_stat cmd_help (int32 num, char *cptr) { - TMLN *t = &tty_line [num]; - char gbuf [CBUFSIZE]; - CTAB *c; + TMLN *t = &tty_line [num]; + char gbuf [CBUFSIZE]; + CTAB *c; - cptr = get_sim_sw (cptr); - if (! cptr) - return SCPE_INVSW; - if (! *cptr) { - /* Список всех команд. */ - tmxr_linemsg (t, "Commands may be abbreviated. Commands are:\r\n\r\n"); - for (c=cmd_table; c && c->name; c++) - if (c->help) - tmxr_linemsg (t, c->help); - return SCPE_OK; - } - cptr = get_glyph (cptr, gbuf, 0); - if (*cptr) - return SCPE_2MARG; - c = lookup_cmd (gbuf); - if (! c) - return SCPE_ARG; - /* Описание конкретной команды. */ - tmxr_linemsg (t, c->help); - return SCPE_OK; + cptr = get_sim_sw (cptr); + if (! cptr) + return SCPE_INVSW; + if (! *cptr) { + /* Список всех команд. */ + tmxr_linemsg (t, "Commands may be abbreviated. Commands are:\r\n\r\n"); + for (c=cmd_table; c && c->name; c++) + if (c->help) + tmxr_linemsg (t, c->help); + return SCPE_OK; + } + cptr = get_glyph (cptr, gbuf, 0); + if (*cptr) + return SCPE_2MARG; + c = lookup_cmd (gbuf); + if (! c) + return SCPE_ARG; + /* Описание конкретной команды. */ + tmxr_linemsg (t, c->help); + return SCPE_OK; } /* @@ -838,27 +838,27 @@ static t_stat cmd_help (int32 num, char *cptr) */ void vt_cmd_exec (int num) { - TMLN *t = &tty_line [num]; - char *cptr, gbuf [CBUFSIZE]; - CTAB *cmdp; - t_stat err; - extern char *scp_errors[]; + TMLN *t = &tty_line [num]; + char *cptr, gbuf [CBUFSIZE]; + CTAB *cmdp; + t_stat err; + extern char *scp_errors[]; - cptr = get_glyph (vt_cbuf [num], gbuf, 0); /* get command glyph */ - cmdp = lookup_cmd (gbuf); /* lookup command */ - if (! cmdp) { - tmxr_linemsg (t, scp_errors[SCPE_UNK - SCPE_BASE]); - tmxr_linemsg (t, "\r\n"); - return; - } - err = cmdp->action (num, cptr); /* if found, exec */ - if (err >= SCPE_BASE) { /* error? */ - tmxr_linemsg (t, scp_errors [err - SCPE_BASE]); - tmxr_linemsg (t, "\r\n"); - } - if (err == SCPE_EXIT) { /* close telnet session */ - tmxr_reset_ln (t); - } + cptr = get_glyph (vt_cbuf [num], gbuf, 0); /* get command glyph */ + cmdp = lookup_cmd (gbuf); /* lookup command */ + if (! cmdp) { + tmxr_linemsg (t, scp_errors[SCPE_UNK - SCPE_BASE]); + tmxr_linemsg (t, "\r\n"); + return; + } + err = cmdp->action (num, cptr); /* if found, exec */ + if (err >= SCPE_BASE) { /* error? */ + tmxr_linemsg (t, scp_errors [err - SCPE_BASE]); + tmxr_linemsg (t, "\r\n"); + } + if (err == SCPE_EXIT) { /* close telnet session */ + tmxr_reset_ln (t); + } } /* @@ -866,70 +866,70 @@ void vt_cmd_exec (int num) */ void vt_cmd_loop (int num, int c) { - TMLN *t = &tty_line [num]; - char *cbuf, **cptr; + TMLN *t = &tty_line [num]; + char *cbuf, **cptr; - cbuf = vt_cbuf [num]; - cptr = &vt_cptr [num]; + cbuf = vt_cbuf [num]; + cptr = &vt_cptr [num]; - switch (c) { - case '\r': - case '\n': - tmxr_linemsg (t, "\r\n"); - if (*cptr <= cbuf) { - /* Пустая строка - возврат в обычный режим. */ - tty_unit[num].flags &= ~TTY_CMDLINE_MASK; - break; - } - /* Выполнение. */ - **cptr = 0; - vt_cmd_exec (num); - tmxr_linemsg (t, "sim>"); - *cptr = vt_cbuf[num]; - break; - case '\b': - case 0177: - /* Стирание предыдущего символа. */ - if (*cptr <= cbuf) - break; - tmxr_linemsg (t, "\b \b"); - while (*cptr > cbuf) { - --*cptr; - if (! (**cptr & 0x80)) - break; - } - break; - case 'U' & 037: - /* Стирание всей строки. */ -erase_line: while (*cptr > cbuf) { - --*cptr; - if (! (**cptr & 0x80)) - tmxr_linemsg (t, "\b \b"); - } - break; - case 033: - /* Escape [ X. */ - if (tmxr_getc_ln (t) != '[' + TMXR_VALID) - break; - switch (tmxr_getc_ln (t) - TMXR_VALID) { - case 'A': /* стрелка вверх */ - if (*cptr <= cbuf) { - *cptr = cbuf + strlen (cbuf); - if (*cptr > cbuf) - tmxr_linemsg (t, cbuf); - } - break; - case 'B': /* стрелка вниз */ - goto erase_line; - } - break; - default: - if (c < ' ' || *cptr > cbuf+CBUFSIZE-5) - break; - *(*cptr)++ = c; - tmxr_putc_ln (t, c); - break; - } + switch (c) { + case '\r': + case '\n': + tmxr_linemsg (t, "\r\n"); + if (*cptr <= cbuf) { + /* Пустая строка - возврат в обычный режим. */ + tty_unit[num].flags &= ~TTY_CMDLINE_MASK; + break; + } + /* Выполнение. */ + **cptr = 0; + vt_cmd_exec (num); + tmxr_linemsg (t, "sim>"); + *cptr = vt_cbuf[num]; + break; + case '\b': + case 0177: + /* Стирание предыдущего символа. */ + if (*cptr <= cbuf) + break; + tmxr_linemsg (t, "\b \b"); + while (*cptr > cbuf) { + --*cptr; + if (! (**cptr & 0x80)) + break; + } + break; + case 'U' & 037: + /* Стирание всей строки. */ + erase_line: while (*cptr > cbuf) { + --*cptr; + if (! (**cptr & 0x80)) + tmxr_linemsg (t, "\b \b"); + } + break; + case 033: + /* Escape [ X. */ + if (tmxr_getc_ln (t) != '[' + TMXR_VALID) + break; + switch (tmxr_getc_ln (t) - TMXR_VALID) { + case 'A': /* стрелка вверх */ + if (*cptr <= cbuf) { + *cptr = cbuf + strlen (cbuf); + if (*cptr > cbuf) + tmxr_linemsg (t, cbuf); + } + break; + case 'B': /* стрелка вниз */ + goto erase_line; + } + break; + default: + if (c < ' ' || *cptr > cbuf+CBUFSIZE-5) + break; + *(*cptr)++ = c; + tmxr_putc_ln (t, c); + break; + } } /* @@ -939,64 +939,64 @@ erase_line: while (*cptr > cbuf) { */ int vt_getc (int num) { - TMLN *t = &tty_line [num]; - extern int32 sim_int_char; - int c; - time_t now; + TMLN *t = &tty_line [num]; + extern int32 sim_int_char; + int c; + time_t now; - if (! t->conn) { - /* Пользователь отключился. */ - if (t->ipad) { - besm6_debug ("*** tty%d: отключение %s", - num, - t->ipad); - t->ipad = NULL; - } - tty_setmode (tty_unit+num, TTY_OFFLINE_STATE, 0, 0); - tty_unit[num].flags &= ~TTY_STATE_MASK; - return -1; - } - if (t->rcve) { - /* Приём через telnet. */ - c = tmxr_getc_ln (t); - if (! (c & TMXR_VALID)) { - now = time (0); - if (now > tty_last_time[num] + 5*60) { - ++tty_idle_count[num]; - if (tty_idle_count[num] > 3) { - tmxr_linemsg (t, "\r\nКОНЕЦ СЕАНСА\r\n"); - tmxr_reset_ln (t); - return -1; - } - tmxr_linemsg (t, "\r\nНЕ СПАТЬ!\r\n"); - tty_last_time[num] = now; - } - return -1; - } - tty_idle_count[num] = 0; - tty_last_time[num] = time (0); + if (! t->conn) { + /* Пользователь отключился. */ + if (t->ipad) { + besm6_debug ("*** tty%d: отключение %s", + num, + t->ipad); + t->ipad = NULL; + } + tty_setmode (tty_unit+num, TTY_OFFLINE_STATE, 0, 0); + tty_unit[num].flags &= ~TTY_STATE_MASK; + return -1; + } + if (t->rcve) { + /* Приём через telnet. */ + c = tmxr_getc_ln (t); + if (! (c & TMXR_VALID)) { + now = time (0); + if (now > tty_last_time[num] + 5*60) { + ++tty_idle_count[num]; + if (tty_idle_count[num] > 3) { + tmxr_linemsg (t, "\r\nКОНЕЦ СЕАНСА\r\n"); + tmxr_reset_ln (t); + return -1; + } + tmxr_linemsg (t, "\r\nНЕ СПАТЬ!\r\n"); + tty_last_time[num] = now; + } + return -1; + } + tty_idle_count[num] = 0; + tty_last_time[num] = time (0); - if (tty_unit[num].flags & TTY_CMDLINE_MASK) { - /* Продолжение режима управляющей командной строки. */ - vt_cmd_loop (num, c & 0377); - return -1; - } - if ((c & 0377) == sim_int_char) { - /* Вход в режим управляющей командной строки. */ - tty_unit[num].flags |= TTY_CMDLINE_MASK; - tmxr_linemsg (t, "sim>"); - vt_cptr[num] = vt_cbuf[num]; - return -1; - } - } else { - /* Ввод с клавиатуры. */ - c = sim_poll_kbd(); - if (c == SCPE_STOP) - return 0400; /* прерывание */ - if (! (c & SCPE_KFLAG)) - return -1; - } - return c & 0377; + if (tty_unit[num].flags & TTY_CMDLINE_MASK) { + /* Продолжение режима управляющей командной строки. */ + vt_cmd_loop (num, c & 0377); + return -1; + } + if ((c & 0377) == sim_int_char) { + /* Вход в режим управляющей командной строки. */ + tty_unit[num].flags |= TTY_CMDLINE_MASK; + tmxr_linemsg (t, "sim>"); + vt_cptr[num] = vt_cbuf[num]; + return -1; + } + } else { + /* Ввод с клавиатуры. */ + c = sim_poll_kbd(); + if (c == SCPE_STOP) + return 0400; /* прерывание */ + if (! (c & SCPE_KFLAG)) + return -1; + } + return c & 0377; } /* @@ -1008,32 +1008,32 @@ int vt_getc (int num) */ static int vt_kbd_input_unicode (int num) { - int c1, c2, c3, r; -again: - r = vt_getc (num); - if (r < 0 || r > 0377) - return r; - c1 = r & 0377; - if (! (c1 & 0x80)) - return unicode_to_koi7 (c1); + int c1, c2, c3, r; + again: + r = vt_getc (num); + if (r < 0 || r > 0377) + return r; + c1 = r & 0377; + if (! (c1 & 0x80)) + return unicode_to_koi7 (c1); - r = vt_getc (num); - if (r < 0 || r > 0377) - return r; - c2 = r & 0377; - if (! (c1 & 0x20)) - return unicode_to_koi7 ((c1 & 0x1f) << 6 | (c2 & 0x3f)); + r = vt_getc (num); + if (r < 0 || r > 0377) + return r; + c2 = r & 0377; + if (! (c1 & 0x20)) + return unicode_to_koi7 ((c1 & 0x1f) << 6 | (c2 & 0x3f)); - r = vt_getc (num); - if (r < 0 || r > 0377) - return r; - c3 = r & 0377; - if (c1 == 0xEF && c2 == 0xBB && c3 == 0xBF) { - /* Skip zero width no-break space. */ - goto again; - } - return unicode_to_koi7 ((c1 & 0x0f) << 12 | (c2 & 0x3f) << 6 | - (c3 & 0x3f)); + r = vt_getc (num); + if (r < 0 || r > 0377) + return r; + c3 = r & 0377; + if (c1 == 0xEF && c2 == 0xBB && c3 == 0xBF) { + /* Skip zero width no-break space. */ + goto again; + } + return unicode_to_koi7 ((c1 & 0x0f) << 12 | (c2 & 0x3f) << 6 | + (c3 & 0x3f)); } /* @@ -1043,62 +1043,62 @@ again: */ static int vt_kbd_input_koi7 (int num) { - int r; + int r; - r = vt_getc (num); - if (r < 0 || r > 0377) - return r; - r &= 0377; - switch (r) { - case '\r': return '\003'; - case 'q': return 'j'; - case 'w': return 'c'; - case 'e': return 'u'; - case 'r': return 'k'; - case 't': return 'e'; - case 'y': return 'n'; - case 'u': return 'g'; - case 'i': return '{'; - case 'o': return '}'; - case 'p': return 'z'; - case '[': return 'h'; - case '{': return '['; - case 'a': return 'f'; - case 's': return 'y'; - case 'd': return 'w'; - case 'f': return 'a'; - case 'g': return 'p'; - case 'h': return 'r'; - case 'j': return 'o'; - case 'k': return 'l'; - case 'l': return 'd'; - case ';': return 'v'; - case '}': return ';'; - case '\'': return '|'; - case '|': return '\''; - case 'z': return 'q'; - case 'x': return '~'; - case 'c': return 's'; - case 'v': return 'm'; - case 'b': return 'i'; - case 'n': return 't'; - case 'm': return 'x'; - case ',': return 'b'; - case '<': return ','; - case '.': return '`'; - case '>': return '.'; - case '~': return '>'; - case '`': return '<'; - default: return r; - } + r = vt_getc (num); + if (r < 0 || r > 0377) + return r; + r &= 0377; + switch (r) { + case '\r': return '\003'; + case 'q': return 'j'; + case 'w': return 'c'; + case 'e': return 'u'; + case 'r': return 'k'; + case 't': return 'e'; + case 'y': return 'n'; + case 'u': return 'g'; + case 'i': return '{'; + case 'o': return '}'; + case 'p': return 'z'; + case '[': return 'h'; + case '{': return '['; + case 'a': return 'f'; + case 's': return 'y'; + case 'd': return 'w'; + case 'f': return 'a'; + case 'g': return 'p'; + case 'h': return 'r'; + case 'j': return 'o'; + case 'k': return 'l'; + case 'l': return 'd'; + case ';': return 'v'; + case '}': return ';'; + case '\'': return '|'; + case '|': return '\''; + case 'z': return 'q'; + case 'x': return '~'; + case 'c': return 's'; + case 'v': return 'm'; + case 'b': return 'i'; + case 'n': return 't'; + case 'm': return 'x'; + case ',': return 'b'; + case '<': return ','; + case '.': return '`'; + case '>': return '.'; + case '~': return '>'; + case '`': return '<'; + default: return r; + } } int odd_parity(unsigned char c) { - c = (c & 0x55) + ((c >> 1) & 0x55); - c = (c & 0x33) + ((c >> 2) & 0x33); - c = (c & 0x0F) + ((c >> 4) & 0x0F); - return c & 1; + c = (c & 0x55) + ((c >> 1) & 0x55); + c = (c & 0x33) + ((c >> 2) & 0x33); + c = (c & 0x0F) + ((c >> 4) & 0x0F); + return c & 1; } /* @@ -1111,63 +1111,63 @@ void vt_receive() TTY_IN = 0; for (num = besm6_highest_bit (workset) - TTY_MAX; - workset; num = besm6_highest_bit (workset) - TTY_MAX) { - uint32 mask = 1 << (TTY_MAX - num); - switch (tty_instate[num]) { - case 0: - switch (tty_unit[num].flags & TTY_CHARSET_MASK) { - case TTY_KOI7_JCUKEN_CHARSET: - tty_typed[num] = vt_kbd_input_koi7 (num); - break; - case TTY_KOI7_QWERTY_CHARSET: - tty_typed[num] = vt_getc (num); - break; - case TTY_UNICODE_CHARSET: - tty_typed[num] = vt_kbd_input_unicode (num); - break; - default: - tty_typed[num] = '?'; - break; - } - if (tty_typed[num] < 0) { - /* TODO: обработать исключение от "неоператорского" терминала */ - sim_interval = 0; - break; - } - if (tty_typed[num] <= 0177) { - if (tty_typed[num] == '\r' || tty_typed[num] == '\n') - tty_typed[num] = 3; /* ^C - конец строки */ - if (tty_typed[num] == '\177') - tty_typed[num] = '\b'; /* ASCII DEL -> BS */ - tty_instate[num] = 1; - TTY_IN |= mask; /* start bit */ - GRP |= GRP_TTY_START; /* не используется ? */ - MGRP |= BBIT(19); /* для терминалов по методу МГУ */ - vt_receiving |= mask; - } - break; - case 1 ... 7: - /* need inverted byte */ - TTY_IN |= (tty_typed[num] & (1 << (tty_instate[num]-1))) ? 0 : mask; - tty_instate[num]++; - break; - case 8: - TTY_IN |= odd_parity(tty_typed[num]) ? 0 : mask; /* even parity of inverted */ - tty_instate[num]++; - break; - case 9 ... 11: - /* stop bits are 0 */ - tty_instate[num]++; - break; - case 12: - tty_instate[num] = 0; /* ready for the next char */ - vt_receiving &= ~mask; - break; - } - workset &= ~mask; + workset; num = besm6_highest_bit (workset) - TTY_MAX) { + uint32 mask = 1 << (TTY_MAX - num); + switch (tty_instate[num]) { + case 0: + switch (tty_unit[num].flags & TTY_CHARSET_MASK) { + case TTY_KOI7_JCUKEN_CHARSET: + tty_typed[num] = vt_kbd_input_koi7 (num); + break; + case TTY_KOI7_QWERTY_CHARSET: + tty_typed[num] = vt_getc (num); + break; + case TTY_UNICODE_CHARSET: + tty_typed[num] = vt_kbd_input_unicode (num); + break; + default: + tty_typed[num] = '?'; + break; + } + if (tty_typed[num] < 0) { + /* TODO: обработать исключение от "неоператорского" терминала */ + sim_interval = 0; + break; + } + if (tty_typed[num] <= 0177) { + if (tty_typed[num] == '\r' || tty_typed[num] == '\n') + tty_typed[num] = 3; /* ^C - конец строки */ + if (tty_typed[num] == '\177') + tty_typed[num] = '\b'; /* ASCII DEL -> BS */ + tty_instate[num] = 1; + TTY_IN |= mask; /* start bit */ + GRP |= GRP_TTY_START; /* не используется ? */ + MGRP |= BBIT(19); /* для терминалов по методу МГУ */ + vt_receiving |= mask; + } + break; + case 1: case 2: case 3: case 4: case 5: case 6: case 7: + /* need inverted byte */ + TTY_IN |= (tty_typed[num] & (1 << (tty_instate[num]-1))) ? 0 : mask; + tty_instate[num]++; + break; + case 8: + TTY_IN |= odd_parity(tty_typed[num]) ? 0 : mask; /* even parity of inverted */ + tty_instate[num]++; + break; + case 9: case 10: case 11: + /* stop bits are 0 */ + tty_instate[num]++; + break; + case 12: + tty_instate[num] = 0; /* ready for the next char */ + vt_receiving &= ~mask; + break; + } + workset &= ~mask; } if (vt_receiving) - vt_idle = 0; + vt_idle = 0; } /* @@ -1175,69 +1175,69 @@ void vt_receive() */ int vt_is_idle () { - return (tt_mask ? vt_idle > 300 : vt_idle > 10); + return (tt_mask ? vt_idle > 300 : vt_idle > 10); } int tty_query () { -/* besm6_debug ("*** телетайпы: приём");*/ - return TTY_IN; + /* besm6_debug ("*** телетайпы: приём");*/ + return TTY_IN; } void consul_print (int dev_num, uint32 cmd) { - int line_num = dev_num + TTY_MAX + 1; - if (tty_dev.dctrl) - besm6_debug(">>> CONSUL%o: %03o", line_num, cmd & 0377); - cmd &= 0177; - switch (tty_unit[line_num].flags & TTY_STATE_MASK) { - case TTY_VT340_STATE: - vt_send (line_num, cmd, - (tty_unit[line_num].flags & TTY_BSPACE_MASK) == TTY_DESTRUCTIVE_BSPACE); - break; - case TTY_CONSUL_STATE: - besm6_debug(">>> CONSUL%o: Native charset not implemented", line_num); - break; - } - // PRP |= CONS_CAN_PRINT[dev_num]; - vt_idle = 0; + int line_num = dev_num + TTY_MAX + 1; + if (tty_dev.dctrl) + besm6_debug(">>> CONSUL%o: %03o", line_num, cmd & 0377); + cmd &= 0177; + switch (tty_unit[line_num].flags & TTY_STATE_MASK) { + case TTY_VT340_STATE: + vt_send (line_num, cmd, + (tty_unit[line_num].flags & TTY_BSPACE_MASK) == TTY_DESTRUCTIVE_BSPACE); + break; + case TTY_CONSUL_STATE: + besm6_debug(">>> CONSUL%o: Native charset not implemented", line_num); + break; + } + // PRP |= CONS_CAN_PRINT[dev_num]; + vt_idle = 0; } void consul_receive () { - int c, line_num, dev_num; + int c, line_num, dev_num; - for (dev_num = 0; dev_num < 2; ++dev_num){ - line_num = dev_num + TTY_MAX + 1; - if (! tty_line[line_num].conn) - continue; - switch (tty_unit[line_num].flags & TTY_CHARSET_MASK) { - case TTY_KOI7_JCUKEN_CHARSET: - c = vt_kbd_input_koi7 (line_num); - break; - case TTY_KOI7_QWERTY_CHARSET: - c = vt_getc (line_num); - break; - case TTY_UNICODE_CHARSET: - c = vt_kbd_input_unicode (line_num); - break; - default: - c = '?'; - break; - } - if (c >= 0 && c <= 0177) { - CONSUL_IN[dev_num] = odd_parity(c) ? c | 0200 : c; - if (c == '\r' || c == '\n') - CONSUL_IN[dev_num] = 3; - PRP |= CONS_HAS_INPUT[dev_num]; - vt_idle = 0; - } - } + for (dev_num = 0; dev_num < 2; ++dev_num){ + line_num = dev_num + TTY_MAX + 1; + if (! tty_line[line_num].conn) + continue; + switch (tty_unit[line_num].flags & TTY_CHARSET_MASK) { + case TTY_KOI7_JCUKEN_CHARSET: + c = vt_kbd_input_koi7 (line_num); + break; + case TTY_KOI7_QWERTY_CHARSET: + c = vt_getc (line_num); + break; + case TTY_UNICODE_CHARSET: + c = vt_kbd_input_unicode (line_num); + break; + default: + c = '?'; + break; + } + if (c >= 0 && c <= 0177) { + CONSUL_IN[dev_num] = odd_parity(c) ? c | 0200 : c; + if (c == '\r' || c == '\n') + CONSUL_IN[dev_num] = 3; + PRP |= CONS_HAS_INPUT[dev_num]; + vt_idle = 0; + } + } } uint32 consul_read (int num) { - if (tty_dev.dctrl) - besm6_debug("<<< CONSUL%o: %03o", num+TTY_MAX+1, CONSUL_IN[num]); - return CONSUL_IN[num]; + if (tty_dev.dctrl) + besm6_debug("<<< CONSUL%o: %03o", num+TTY_MAX+1, CONSUL_IN[num]); + return CONSUL_IN[num]; } diff --git a/BESM6/boot_dispak.b6 b/BESM6/boot_dispak.b6 index 7c3c74a6..57f5a627 100644 --- a/BESM6/boot_dispak.b6 +++ b/BESM6/boot_dispak.b6 @@ -19,466 +19,466 @@ с 0 в 02000 -к рег 101, уиа 2260(2) ; 02000 - 0002 0101 1240 2260 -к уиа 2502(12), уиа -56(6) ; 02001 - 5240 2502 3247 7722 -к сч 2537, зп 2605 ; 02002 - 0010 2537 0000 2605 -к сда 101, зп 2664(6) ; 02003 - 0036 0101 3000 2664 -к цикл 2003(6), уиа -2(1) ; 02004 - 3370 2003 0647 7776 -к сч 2521(1), зп 502(1) ; 02005 - 0410 2521 0400 0502 -к цикл 2005(1), уиа -2(6) ; 02006 - 0770 2005 3247 7776 -к уиа (13), сч ; 02007 - 5640 0000 0010 0000 -к слц 2546(6), цикл 2010(6) ; 02010 - 3013 2546 3370 2010 -к нтж, по 2070 ; 02011 - 0012 0000 0260 2070 -к уиа 2444(5), пв 2346(10) ; 02012 - 2640 2444 4310 2346 -к нтж 2543, пе 2345 ; 02013 - 0012 2543 0270 2345 -к сч 2, пб 3000 ; 02014 - 0010 0002 0300 3000 -к сда 136, и 2427 ; 02015 - 0036 0136 0011 2427 -к по 2017, вч 2664 ; 02016 - 0260 2017 0005 2664 -к уи 16, уии 3(16) ; 02017 - 0040 0016 7044 0003 -к сли 16(16), сли 16(3) ; 02020 - 7045 0016 1445 0016 -к уиа -2(3), мода ; 02021 - 1647 7776 0220 0000 -к мода (16), сч 2546(3) ; 02022 - 7220 0000 1410 2546 -к зп 1777(3), цикл 2022(3) ; 02023 - 1400 1777 1770 2022 -к уиа -1(3), мода ; 02024 - 1647 7777 0220 0000 -к сч 1776, пио 2027(3) ; 02025 - 0010 1776 1740 2027 -к сда 110, мода ; 02026 - 0036 0110 0220 0000 -к сда 50, зп 1033(3) ; 02027 - 0036 0050 1400 1033 -к сч 1775, сда 115 ; 02030 - 0010 1775 0036 0115 -к пио 2032(3), сда 120 ; 02031 - 1740 2032 0036 0120 -к и 2540, сда 70 ; 02032 - 0011 2540 0036 0070 -к или 1033(3), зп 1033(3) ; 02033 - 1415 1033 1400 1033 -к сч 1777, пио 2036(3) ; 02034 - 0010 1777 1740 2036 -к сда 110, мода ; 02035 - 0036 0110 0220 0000 -к и 2541, или 1033(3) ; 02036 - 0011 2541 1415 1033 -к зп 1033(3), цикл 2025(3) ; 02037 - 1400 1033 1770 2025 -к уиа 3(16), уиа -1(3) ; 02040 - 7240 0003 1647 7777 -к сч, зп 1773 ; 02041 - 0010 0000 0000 1773 -к уиа 10(7), мода ; 02042 - 3640 0010 0220 0000 -к уиа -1(15), уиа -7(14) ; 02043 - 6647 7777 6247 7771 -к сч 1777(3), слиа 1(15) ; 02044 - 1410 1777 6650 0001 -к сда 140(7), и 2655(15) ; 02045 - 3436 0140 6411 2655 -к по 2060, счи 15 ; 02046 - 0260 2060 0042 0015 -к нтж 2415, уи 17 ; 02047 - 0012 2415 0040 0017 -к сда 71, или 2532 ; 02050 - 0036 0071 0015 2532 -к зп 1774, сч 1773 ; 02051 - 0000 1774 0010 1773 -к сда 33, или 1774 ; 02052 - 0036 0033 0015 1774 -к зп 1774, пв 2126(11) ; 02053 - 0000 1774 4710 2126 -к сч 2534, и 2615 ; 02054 - 0010 2534 0011 2615 -к по 2074, сч 2534 ; 02055 - 0260 2074 0010 2534 -к сда 114, нтж 1775 ; 02056 - 0036 0114 0012 1775 -к и 2423, по 2076 ; 02057 - 0011 2423 0260 2076 -к цикл 2044(14), слиа -10(7) ; 02060 - 6370 2044 3657 7770 -к сч 1773, слц 2664 ; 02061 - 0010 1773 0013 2664 -к зп 1773, сда 102 ; 02062 - 0000 1773 0036 0102 -к по 2043, пио 2066(3) ; 02063 - 0260 2043 1740 2066 -к уиа 4(16), уиа (3) ; 02064 - 7240 0004 1640 0000 -к пб 2041, мода ; 02065 - 0300 2041 0220 0000 -к уиа 2502(5), пв 2367(7) ; 02066 - 2640 2502 3710 2367 -к стоп, пб 2040 ; 02067 - 0330 0000 0300 2040 -к уиа -35(16), уиа 1(13) ; 02070 - 7247 7743 5640 0001 -к сч 72035(16), зп 2601(16) ; 02071 - 7110 2035 7000 2601 -к цикл 2071(16), пв 2346(10) ; 02072 - 7370 2071 4310 2346 -к зп 2543, пб 2014 ; 02073 - 0000 2543 0300 2014 -к сч 2534, нтж 1775 ; 02074 - 0010 2534 0012 1775 -к и 2423, пе 2060 ; 02075 - 0011 2423 0270 2060 -к счи 17, сда 71 ; 02076 - 0042 0017 0036 0071 -к или 2420, зп 1774 ; 02077 - 0015 2420 0000 1774 -к счи 16, сда 76 ; 02100 - 0042 0016 0036 0076 -к слц 1773, сда 33 ; 02101 - 0013 1773 0036 0033 -к или 1774, пб 2105 ; 02102 - 0015 1774 0300 2105 -к уиа 2257(11), мода ; 02103 - 4640 2257 0220 0000 -к уиа 2106(2), сч 1027 ; 02104 - 1240 2106 0010 1027 -к зп 1774, пб (2) ; 02105 - 0000 1774 1300 0000 -к сч 1774, сда 147 ; 02106 - 0010 1774 0036 0147 -к уи 16, сч 1774 ; 02107 - 0040 0016 0010 1774 -к сда 107, и 2415 ; 02110 - 0036 0107 0011 2415 -к уи 17, нтж 2415 ; 02111 - 0040 0017 0012 2415 -к уи 15, сч 1774 ; 02112 - 0040 0015 0010 1774 -к сда 145, и 2416 ; 02113 - 0036 0145 0011 2416 -к сда 75, уи 6 ; 02114 - 0036 0075 0040 0006 -к сли 6(17), сч 1027(16) ; 02115 - 7445 0006 7010 1027 -к и 2625(6), уиа (1) ; 02116 - 3011 2625 0640 0000 -к по 2120, уиа 2(1) ; 02117 - 0260 2120 0640 0002 -к сч 1775, мода ; 02120 - 0010 1775 0220 0000 -к сда 130, слц 2531 ; 02121 - 0036 0130 0013 2531 -к и 2526, мода ; 02122 - 0011 2526 0220 0000 -к сда 77(1), зп 2527 ; 02123 - 0436 0077 0000 2527 -к счмр, сда 146 ; 02124 - 0031 0000 0036 0146 -к и 2653, зп 2604 ; 02125 - 0011 2653 0000 2604 -к сч, рег 37 ; 02126 - 0010 0000 0002 0037 -к сч 2417, увв 20(16) ; 02127 - 0010 2417 7033 0020 -к уи, сч 1774 ; 02130 - 0040 0000 0010 1774 -к сда 145, и 2416 ; 02131 - 0036 0145 0011 2416 -к или 2654, или 2653 ; 02132 - 0015 2654 0015 2653 -к увв 20(16), уи ; 02133 - 7033 0020 0040 0000 -к рег 237, и 2625(16) ; 02134 - 0002 0237 7011 2625 -к по 2134, сч 2661 ; 02135 - 0260 2134 0010 2661 -к увв 20(16), уи ; 02136 - 7033 0020 0040 0000 -к уи, рег 37 ; 02137 - 0040 0000 0002 0037 -к уиа 2147(6), уиа 11(4) ; 02140 - 3240 2147 2240 0011 -к сч 2655(15), пио 2143(1) ; 02141 - 6410 2655 0740 2143 -к или 2604, мода ; 02142 - 0015 2604 0220 0000 -к или 2421, увв 20(16) ; 02143 - 0015 2421 7033 0020 -к уи, счи 4 ; 02144 - 0040 0000 0042 0004 -к увв 20(16), уи ; 02145 - 7033 0020 0040 0000 -к увв 4000(16), пб (6) ; 02146 - 7033 4000 3300 0000 -к и 2654, уиа 2430(5) ; 02147 - 0011 2654 2640 2430 -к по 2412, уиа -7(6) ; 02150 - 0260 2412 3247 7771 -к сч, мода ; 02151 - 0010 0000 0220 0000 -к мод 2521(16), зп 7(6) ; 02152 - 7230 2521 3000 0007 -к цикл 2152(6), уиа -7(6) ; 02153 - 3370 2152 3247 7771 -к зп 1, цикл 2154(6) ; 02154 - 0000 0001 3370 2154 -к сч 1774, увв (16) ; 02155 - 0010 1774 7033 0000 -к сч 2416, или 2422 ; 02156 - 0010 2416 0015 2422 -к увв 20(16), уи ; 02157 - 7033 0020 0040 0000 -к сч 2527, или 2651 ; 02160 - 0010 2527 0015 2651 -к уи, увв 20(16) ; 02161 - 0040 0000 7033 0020 -к уи, увв ; 02162 - 0040 0000 0033 0000 -к уиа -50(6), мода ; 02163 - 3247 7730 0220 0000 -к зп 1, цикл 2164(6) ; 02164 - 0000 0001 3370 2164 -к сч, уи ; 02165 - 0010 0000 0040 0000 -к рег 37, уиа 76030(6) ; 02166 - 0002 0037 3247 6030 -к уиа 77540(10), мода ; 02167 - 4247 7540 0220 0000 -к сбр, рег 237 ; 02170 - 0020 0000 0002 0237 -к и 2625(16), пе 2175 ; 02171 - 7011 2625 0270 2175 -к цикл 2170(10), цикл 2167(6) ; 02172 - 4370 2170 3370 2167 -к стоп, уиа 2126(7) ; 02173 - 0330 0000 3640 2126 -к уиа 2474(5), пб 2366 ; 02174 - 2640 2474 0300 2366 -к уиа 11(4), пв 2144(6) ; 02175 - 2240 0011 3310 2144 -к зп 2533, и 2651 ; 02176 - 0000 2533 0011 2651 -к пе 2351, увв 4035 ; 02177 - 0270 2351 0033 4035 -к и 2655(16), уиа 2436(5) ; 02200 - 7011 2655 2640 2436 -к пе 2412, уиа 1(10) ; 02201 - 0270 2412 4240 0001 -к уиа 2206(6), уиа 2206(5) ; 02202 - 3240 2206 2640 2206 -к сч 2424, уи 21 ; 02203 - 0010 2424 0040 0021 -к мод 2521(16), сч (10) ; 02204 - 7230 2521 4010 0000 -к уи, пб (6) ; 02205 - 0040 0000 3300 0000 -к зп 2534, и 2535 ; 02206 - 0000 2534 0011 2535 -к нтж 2536, уиа 2460(5) ; 02207 - 0012 2536 2640 2460 -к пе 2412, сч 1774 ; 02210 - 0270 2412 0010 1774 -к и 2660, пе 2302 ; 02211 - 0011 2660 0270 2302 -к сч 2533, и 2652 ; 02212 - 0010 2533 0011 2652 -к уиа 2444(5), пе 2366 ; 02213 - 2640 2444 0270 2366 -к уиа -3(4), уиа (12) ; 02214 - 2247 7775 5240 0000 -к счи 11, нтж 2530 ; 02215 - 0042 0011 0012 2530 -к пе 2217, слиа 2000(12) ; 02216 - 0270 2217 5250 2000 -к сч 2534, и 2614 ; 02217 - 0010 2534 0011 2614 -к пе 2240, уиа -1(10) ; 02220 - 0270 2240 4247 7777 -к уиа 2411(5), сч 2424 ; 02221 - 2640 2411 0010 2424 -к уи 21, уиа 77401(6) ; 02222 - 0040 0021 3247 7401 -к слиа 2(10), сч ; 02223 - 4250 0002 0010 0000 -к мода 70000(12), слц 377(6) ; 02224 - 5227 0000 3013 0377 -к цикл 2224(6), зп 2534 ; 02225 - 3370 2224 0000 2534 -к уиа 2227(5), пв 2203(6) ; 02226 - 2640 2227 3310 2203 -к зп 2533, нтж 2534 ; 02227 - 0000 2533 0012 2534 -к и 2423, пе 2250 ; 02230 - 0011 2423 0270 2250 -к сч 2533, и 2615 ; 02231 - 0010 2533 0011 2615 -к уиа 2444(5), по 2366 ; 02232 - 2640 2444 0260 2366 -к слиа 400(12), мода ; 02233 - 5250 0400 0220 0000 -к цикл 2221(4), уиа 2255(6) ; 02234 - 2370 2221 3240 2255 -к сч 2425, уи 21 ; 02235 - 0010 2425 0040 0021 -к сч 2417, увв 20(16) ; 02236 - 0010 2417 7033 0020 -к уи, пб (6) ; 02237 - 0040 0000 3300 0000 -к уиа 2411(5), сч 2424 ; 02240 - 2640 2411 0010 2424 -к уи 21, уиа 76001(6) ; 02241 - 0040 0021 3247 6001 -к сч, уиа 3(10) ; 02242 - 0010 0000 4240 0003 -к мода 70000(12), слц 1777(6) ; 02243 - 5227 0000 3013 1777 -к цикл 2243(6), зп 2534 ; 02244 - 3370 2243 0000 2534 -к уиа 2246(5), пв 2203(6) ; 02245 - 2640 2246 3310 2203 -к нтж 2534, пе 2213 ; 02246 - 0012 2534 0270 2213 -к уиа 2255(6), пб 2235 ; 02247 - 3240 2255 0300 2235 -к слиа -1(10), уиа 2252(5) ; 02250 - 4257 7777 2640 2252 -к мода, пв 2203(6) ; 02251 - 0220 0000 3310 2203 -к нтж 2534, и 2423 ; 02252 - 0012 2534 0011 2423 -к пе 2213, слиа 1(10) ; 02253 - 0270 2213 4250 0001 -к слиа 400(12), пб 2234 ; 02254 - 5250 0400 0300 2234 -к сч, уи ; 02255 - 0010 0000 0040 0000 -к рег 37, пб (11) ; 02256 - 0002 0037 4700 0000 -к уиа 1(14), пб 2335 ; 02257 - 6240 0001 0300 2335 -к зп 1027, сч 2516 ; 02260 - 0000 1027 0010 2516 -к или 1775, зп 1775 ; 02261 - 0015 1775 0000 1775 -к уиа 2265(11), пб 2104 ; 02262 - 4640 2265 0300 2104 -к слиа 40(4), цикл 2272(14) ; 02263 - 2250 0040 6370 2272 -к уиа 2466(5), пв 2367(7) ; 02264 - 2640 2466 3710 2367 -к сч 2, сда 130 ; 02265 - 0010 0002 0036 0130 -к и 2427, уиа -17(14) ; 02266 - 0011 2427 6247 7761 -к уиа (2), уиа (4) ; 02267 - 1240 0000 2240 0000 -к по 2271, вч 2664 ; 02270 - 0260 2271 0005 2664 -к зп 2542, мода ; 02271 - 0000 2542 0220 0000 -к уиа -37(7), сч 1775 ; 02272 - 3647 7741 0010 1775 -к нтж 70000(4), и 2423 ; 02273 - 2112 0000 0011 2423 -к пе 2263, сч 1775 ; 02274 - 0270 2263 0010 1775 -к сда 155, нтж 70016(4) ; 02275 - 0036 0155 2112 0016 -к и 2415, пе 2263 ; 02276 - 0011 2415 0270 2263 -к счи 2, нтж 2542 ; 02277 - 0042 0002 0012 2542 -к по 2303, слиа 1(2) ; 02300 - 0260 2303 1250 0001 -к пб 2263, мода ; 02301 - 0300 2263 0220 0000 -к уии 6(11), пб 2235 ; 02302 - 4444 0006 0300 2235 -к мода (4), сч 70037(7) ; 02303 - 2220 0000 3510 0037 -к зп 3537(7), цикл 2303(7) ; 02304 - 3400 3537 3770 2303 -к сч 3502, зп 1775 ; 02305 - 0010 3502 0000 1775 -к мода, пв 2040(2) ; 02306 - 0220 0000 1310 2040 -к зп 1030, сч 3500 ; 02307 - 0000 1030 0010 3500 -к зп 1775, сч 3 ; 02310 - 0000 1775 0010 0003 -к и 2660, пб 2103 ; 02311 - 0011 2660 0300 2103 -к уиа -2(14), сч 3515 ; 02312 - 6247 7776 0010 3515 -к сда 117, зп 1775 ; 02313 - 0036 0117 0000 1775 -к и 2423, по 2103 ; 02314 - 0011 2423 0260 2103 -к сч 2663, пв 2123(11) ; 02315 - 0010 2663 4710 2123 -к сч 3516, и 2415 ; 02316 - 0010 3516 0011 2415 -к сда 75, уи 6 ; 02317 - 0036 0075 0040 0006 -к сч 70000(6), нтж 3516 ; 02320 - 3110 0000 0012 3516 -к и 2415, пе 2103 ; 02321 - 0011 2415 0270 2103 -к мода (6), сч 70002(14) ; 02322 - 3220 0000 6110 0002 -к зп 2604(14), цикл 2322(14) ; 02323 - 6000 2604 6370 2322 -к уиа 2510(12), пв 2040(2) ; 02324 - 5240 2510 1310 2040 -к уиа -2(14), пв 2126(11) ; 02325 - 6247 7776 4710 2126 -к сч 70002(14), нтж 2604(14) ; 02326 - 6110 0002 6012 2604 -к уиа 2257(11), пе 2103 ; 02327 - 4640 2257 0270 2103 -к цикл 2326(14), уиа -22(14) ; 02330 - 6370 2326 6247 7756 -к сч 70026(14), зп 1026(14) ; 02331 - 6110 0026 6000 1026 -к цикл 2331(14), уиа 2335(11) ; 02332 - 6370 2331 4640 2335 -к сч 1774, зп 1031 ; 02333 - 0010 1774 0000 1031 -к пб 2104, мода ; 02334 - 0300 2104 0220 0000 -к сч 1774, слц 2650 ; 02335 - 0010 1774 0013 2650 -к зп 1774, сч 1775 ; 02336 - 0000 1774 0010 1775 -к слц 2634, пв 2121(11) ; 02337 - 0013 2634 4710 2121 -к сч 2522, зп 502 ; 02340 - 0010 2522 0000 0502 -к уиа -37(6), мода ; 02341 - 3247 7741 0220 0000 -к сч 3537(6), зп 71777(6) ; 02342 - 3010 3537 3100 1777 -к цикл 2342(6), сч ; 02343 - 3370 2342 0010 0000 -к зп 72000, пб 70000 ; 02344 - 0100 2000 0307 0000 -к уиа 2345(7), пб 2367 ; 02345 - 3640 2345 0300 2367 -к уиа -2(3), сч ; 02346 - 1647 7776 0010 0000 -к слц 2546(3), цикл 2347(3) ; 02347 - 1413 2546 1770 2347 -к пб (10), мода ; 02350 - 4300 0000 0220 0000 -к сч 1774, и 2660 ; 02351 - 0010 1774 0011 2660 -к пе 2060, уиа 31(4) ; 02352 - 0270 2060 2240 0031 -к мода, пв 2144(6) ; 02353 - 0220 0000 3310 2144 -к зп 2534, сч 2533 ; 02354 - 0000 2534 0010 2533 -к и 2654, по 2402 ; 02355 - 0011 2654 0260 2402 -к сч 2534, и 2662 ; 02356 - 0010 2534 0011 2662 -к уиа 2452(5), пе 2404 ; 02357 - 2640 2452 0270 2404 -к сч 2534, и 2660 ; 02360 - 0010 2534 0011 2660 -к уиа 2466(5), пе 2366 ; 02361 - 2640 2466 0270 2366 -к сч 2534, и 2661 ; 02362 - 0010 2534 0011 2661 -к пе 2410, сч 2534 ; 02363 - 0270 2410 0010 2534 -к и 2652, уиа 2452(5) ; 02364 - 0011 2652 2640 2452 -к пе 2366, уиа 2452(5) ; 02365 - 0270 2366 2640 2452 -к уиа 2126(7), пв 2235(6) ; 02366 - 3640 2126 3310 2235 -к уиа -10(10), мода ; 02367 - 4247 7770 0220 0000 -к зп 1, цикл 2370(10) ; 02370 - 0000 0001 4370 2370 -к сч, рег ; 02371 - 0010 0000 0002 0000 -к уиа -5(10), мода ; 02372 - 4247 7773 0220 0000 -к мода (5), сч 5(10) ; 02373 - 2620 0000 4010 0005 -к рег 6(10), цикл 2373(10) ; 02374 - 4002 0006 4370 2373 -к сч, рег 7 ; 02375 - 0010 0000 0002 0007 -к уиа 76030(10), мода ; 02376 - 4247 6030 0220 0000 -к уиа 77526(3), мода ; 02377 - 1647 7526 0220 0000 -к сбр, цикл 2400(3) ; 02400 - 0020 0000 1770 2400 -к цикл 2377(10), пб (7) ; 02401 - 4370 2377 3700 0000 -к сч 2533, уиа 2430(5) ; 02402 - 0010 2533 2640 2430 -к и 2653, по 2366 ; 02403 - 0011 2653 0260 2366 -к уиа 1(4), пв 2144(6) ; 02404 - 2240 0001 3310 2144 -к мода, пв 2235(6) ; 02405 - 0220 0000 3310 2235 -к уиа 76030(10), пв 2377(7) ; 02406 - 4247 6030 3710 2377 -к уиа 2126(7), пб 2367 ; 02407 - 3640 2126 0300 2367 -к уиа 2452(5), пб 2366 ; 02410 - 2640 2452 0300 2366 -к уиа 2126(6), пб 2235 ; 02411 - 3240 2126 0300 2235 -к сч 1774, и 2660 ; 02412 - 0010 1774 0011 2660 -к по 2366, пв 2235(6) ; 02413 - 0260 2366 3310 2235 -к пб 2060, мода ; 02414 - 0300 2060 0220 0000 +к рег 101, уиа 2260(2) ; 02000 - 0002 0101 1240 2260 +к уиа 2502(12), уиа -56(6) ; 02001 - 5240 2502 3247 7722 +к сч 2537, зп 2605 ; 02002 - 0010 2537 0000 2605 +к сда 101, зп 2664(6) ; 02003 - 0036 0101 3000 2664 +к цикл 2003(6), уиа -2(1) ; 02004 - 3370 2003 0647 7776 +к сч 2521(1), зп 502(1) ; 02005 - 0410 2521 0400 0502 +к цикл 2005(1), уиа -2(6) ; 02006 - 0770 2005 3247 7776 +к уиа (13), сч ; 02007 - 5640 0000 0010 0000 +к слц 2546(6), цикл 2010(6) ; 02010 - 3013 2546 3370 2010 +к нтж, по 2070 ; 02011 - 0012 0000 0260 2070 +к уиа 2444(5), пв 2346(10) ; 02012 - 2640 2444 4310 2346 +к нтж 2543, пе 2345 ; 02013 - 0012 2543 0270 2345 +к сч 2, пб 3000 ; 02014 - 0010 0002 0300 3000 +к сда 136, и 2427 ; 02015 - 0036 0136 0011 2427 +к по 2017, вч 2664 ; 02016 - 0260 2017 0005 2664 +к уи 16, уии 3(16) ; 02017 - 0040 0016 7044 0003 +к сли 16(16), сли 16(3) ; 02020 - 7045 0016 1445 0016 +к уиа -2(3), мода ; 02021 - 1647 7776 0220 0000 +к мода (16), сч 2546(3) ; 02022 - 7220 0000 1410 2546 +к зп 1777(3), цикл 2022(3) ; 02023 - 1400 1777 1770 2022 +к уиа -1(3), мода ; 02024 - 1647 7777 0220 0000 +к сч 1776, пио 2027(3) ; 02025 - 0010 1776 1740 2027 +к сда 110, мода ; 02026 - 0036 0110 0220 0000 +к сда 50, зп 1033(3) ; 02027 - 0036 0050 1400 1033 +к сч 1775, сда 115 ; 02030 - 0010 1775 0036 0115 +к пио 2032(3), сда 120 ; 02031 - 1740 2032 0036 0120 +к и 2540, сда 70 ; 02032 - 0011 2540 0036 0070 +к или 1033(3), зп 1033(3) ; 02033 - 1415 1033 1400 1033 +к сч 1777, пио 2036(3) ; 02034 - 0010 1777 1740 2036 +к сда 110, мода ; 02035 - 0036 0110 0220 0000 +к и 2541, или 1033(3) ; 02036 - 0011 2541 1415 1033 +к зп 1033(3), цикл 2025(3) ; 02037 - 1400 1033 1770 2025 +к уиа 3(16), уиа -1(3) ; 02040 - 7240 0003 1647 7777 +к сч, зп 1773 ; 02041 - 0010 0000 0000 1773 +к уиа 10(7), мода ; 02042 - 3640 0010 0220 0000 +к уиа -1(15), уиа -7(14) ; 02043 - 6647 7777 6247 7771 +к сч 1777(3), слиа 1(15) ; 02044 - 1410 1777 6650 0001 +к сда 140(7), и 2655(15) ; 02045 - 3436 0140 6411 2655 +к по 2060, счи 15 ; 02046 - 0260 2060 0042 0015 +к нтж 2415, уи 17 ; 02047 - 0012 2415 0040 0017 +к сда 71, или 2532 ; 02050 - 0036 0071 0015 2532 +к зп 1774, сч 1773 ; 02051 - 0000 1774 0010 1773 +к сда 33, или 1774 ; 02052 - 0036 0033 0015 1774 +к зп 1774, пв 2126(11) ; 02053 - 0000 1774 4710 2126 +к сч 2534, и 2615 ; 02054 - 0010 2534 0011 2615 +к по 2074, сч 2534 ; 02055 - 0260 2074 0010 2534 +к сда 114, нтж 1775 ; 02056 - 0036 0114 0012 1775 +к и 2423, по 2076 ; 02057 - 0011 2423 0260 2076 +к цикл 2044(14), слиа -10(7) ; 02060 - 6370 2044 3657 7770 +к сч 1773, слц 2664 ; 02061 - 0010 1773 0013 2664 +к зп 1773, сда 102 ; 02062 - 0000 1773 0036 0102 +к по 2043, пио 2066(3) ; 02063 - 0260 2043 1740 2066 +к уиа 4(16), уиа (3) ; 02064 - 7240 0004 1640 0000 +к пб 2041, мода ; 02065 - 0300 2041 0220 0000 +к уиа 2502(5), пв 2367(7) ; 02066 - 2640 2502 3710 2367 +к стоп, пб 2040 ; 02067 - 0330 0000 0300 2040 +к уиа -35(16), уиа 1(13) ; 02070 - 7247 7743 5640 0001 +к сч 72035(16), зп 2601(16) ; 02071 - 7110 2035 7000 2601 +к цикл 2071(16), пв 2346(10) ; 02072 - 7370 2071 4310 2346 +к зп 2543, пб 2014 ; 02073 - 0000 2543 0300 2014 +к сч 2534, нтж 1775 ; 02074 - 0010 2534 0012 1775 +к и 2423, пе 2060 ; 02075 - 0011 2423 0270 2060 +к счи 17, сда 71 ; 02076 - 0042 0017 0036 0071 +к или 2420, зп 1774 ; 02077 - 0015 2420 0000 1774 +к счи 16, сда 76 ; 02100 - 0042 0016 0036 0076 +к слц 1773, сда 33 ; 02101 - 0013 1773 0036 0033 +к или 1774, пб 2105 ; 02102 - 0015 1774 0300 2105 +к уиа 2257(11), мода ; 02103 - 4640 2257 0220 0000 +к уиа 2106(2), сч 1027 ; 02104 - 1240 2106 0010 1027 +к зп 1774, пб (2) ; 02105 - 0000 1774 1300 0000 +к сч 1774, сда 147 ; 02106 - 0010 1774 0036 0147 +к уи 16, сч 1774 ; 02107 - 0040 0016 0010 1774 +к сда 107, и 2415 ; 02110 - 0036 0107 0011 2415 +к уи 17, нтж 2415 ; 02111 - 0040 0017 0012 2415 +к уи 15, сч 1774 ; 02112 - 0040 0015 0010 1774 +к сда 145, и 2416 ; 02113 - 0036 0145 0011 2416 +к сда 75, уи 6 ; 02114 - 0036 0075 0040 0006 +к сли 6(17), сч 1027(16) ; 02115 - 7445 0006 7010 1027 +к и 2625(6), уиа (1) ; 02116 - 3011 2625 0640 0000 +к по 2120, уиа 2(1) ; 02117 - 0260 2120 0640 0002 +к сч 1775, мода ; 02120 - 0010 1775 0220 0000 +к сда 130, слц 2531 ; 02121 - 0036 0130 0013 2531 +к и 2526, мода ; 02122 - 0011 2526 0220 0000 +к сда 77(1), зп 2527 ; 02123 - 0436 0077 0000 2527 +к счмр, сда 146 ; 02124 - 0031 0000 0036 0146 +к и 2653, зп 2604 ; 02125 - 0011 2653 0000 2604 +к сч, рег 37 ; 02126 - 0010 0000 0002 0037 +к сч 2417, увв 20(16) ; 02127 - 0010 2417 7033 0020 +к уи, сч 1774 ; 02130 - 0040 0000 0010 1774 +к сда 145, и 2416 ; 02131 - 0036 0145 0011 2416 +к или 2654, или 2653 ; 02132 - 0015 2654 0015 2653 +к увв 20(16), уи ; 02133 - 7033 0020 0040 0000 +к рег 237, и 2625(16) ; 02134 - 0002 0237 7011 2625 +к по 2134, сч 2661 ; 02135 - 0260 2134 0010 2661 +к увв 20(16), уи ; 02136 - 7033 0020 0040 0000 +к уи, рег 37 ; 02137 - 0040 0000 0002 0037 +к уиа 2147(6), уиа 11(4) ; 02140 - 3240 2147 2240 0011 +к сч 2655(15), пио 2143(1) ; 02141 - 6410 2655 0740 2143 +к или 2604, мода ; 02142 - 0015 2604 0220 0000 +к или 2421, увв 20(16) ; 02143 - 0015 2421 7033 0020 +к уи, счи 4 ; 02144 - 0040 0000 0042 0004 +к увв 20(16), уи ; 02145 - 7033 0020 0040 0000 +к увв 4000(16), пб (6) ; 02146 - 7033 4000 3300 0000 +к и 2654, уиа 2430(5) ; 02147 - 0011 2654 2640 2430 +к по 2412, уиа -7(6) ; 02150 - 0260 2412 3247 7771 +к сч, мода ; 02151 - 0010 0000 0220 0000 +к мод 2521(16), зп 7(6) ; 02152 - 7230 2521 3000 0007 +к цикл 2152(6), уиа -7(6) ; 02153 - 3370 2152 3247 7771 +к зп 1, цикл 2154(6) ; 02154 - 0000 0001 3370 2154 +к сч 1774, увв (16) ; 02155 - 0010 1774 7033 0000 +к сч 2416, или 2422 ; 02156 - 0010 2416 0015 2422 +к увв 20(16), уи ; 02157 - 7033 0020 0040 0000 +к сч 2527, или 2651 ; 02160 - 0010 2527 0015 2651 +к уи, увв 20(16) ; 02161 - 0040 0000 7033 0020 +к уи, увв ; 02162 - 0040 0000 0033 0000 +к уиа -50(6), мода ; 02163 - 3247 7730 0220 0000 +к зп 1, цикл 2164(6) ; 02164 - 0000 0001 3370 2164 +к сч, уи ; 02165 - 0010 0000 0040 0000 +к рег 37, уиа 76030(6) ; 02166 - 0002 0037 3247 6030 +к уиа 77540(10), мода ; 02167 - 4247 7540 0220 0000 +к сбр, рег 237 ; 02170 - 0020 0000 0002 0237 +к и 2625(16), пе 2175 ; 02171 - 7011 2625 0270 2175 +к цикл 2170(10), цикл 2167(6) ; 02172 - 4370 2170 3370 2167 +к стоп, уиа 2126(7) ; 02173 - 0330 0000 3640 2126 +к уиа 2474(5), пб 2366 ; 02174 - 2640 2474 0300 2366 +к уиа 11(4), пв 2144(6) ; 02175 - 2240 0011 3310 2144 +к зп 2533, и 2651 ; 02176 - 0000 2533 0011 2651 +к пе 2351, увв 4035 ; 02177 - 0270 2351 0033 4035 +к и 2655(16), уиа 2436(5) ; 02200 - 7011 2655 2640 2436 +к пе 2412, уиа 1(10) ; 02201 - 0270 2412 4240 0001 +к уиа 2206(6), уиа 2206(5) ; 02202 - 3240 2206 2640 2206 +к сч 2424, уи 21 ; 02203 - 0010 2424 0040 0021 +к мод 2521(16), сч (10) ; 02204 - 7230 2521 4010 0000 +к уи, пб (6) ; 02205 - 0040 0000 3300 0000 +к зп 2534, и 2535 ; 02206 - 0000 2534 0011 2535 +к нтж 2536, уиа 2460(5) ; 02207 - 0012 2536 2640 2460 +к пе 2412, сч 1774 ; 02210 - 0270 2412 0010 1774 +к и 2660, пе 2302 ; 02211 - 0011 2660 0270 2302 +к сч 2533, и 2652 ; 02212 - 0010 2533 0011 2652 +к уиа 2444(5), пе 2366 ; 02213 - 2640 2444 0270 2366 +к уиа -3(4), уиа (12) ; 02214 - 2247 7775 5240 0000 +к счи 11, нтж 2530 ; 02215 - 0042 0011 0012 2530 +к пе 2217, слиа 2000(12) ; 02216 - 0270 2217 5250 2000 +к сч 2534, и 2614 ; 02217 - 0010 2534 0011 2614 +к пе 2240, уиа -1(10) ; 02220 - 0270 2240 4247 7777 +к уиа 2411(5), сч 2424 ; 02221 - 2640 2411 0010 2424 +к уи 21, уиа 77401(6) ; 02222 - 0040 0021 3247 7401 +к слиа 2(10), сч ; 02223 - 4250 0002 0010 0000 +к мода 70000(12), слц 377(6) ; 02224 - 5227 0000 3013 0377 +к цикл 2224(6), зп 2534 ; 02225 - 3370 2224 0000 2534 +к уиа 2227(5), пв 2203(6) ; 02226 - 2640 2227 3310 2203 +к зп 2533, нтж 2534 ; 02227 - 0000 2533 0012 2534 +к и 2423, пе 2250 ; 02230 - 0011 2423 0270 2250 +к сч 2533, и 2615 ; 02231 - 0010 2533 0011 2615 +к уиа 2444(5), по 2366 ; 02232 - 2640 2444 0260 2366 +к слиа 400(12), мода ; 02233 - 5250 0400 0220 0000 +к цикл 2221(4), уиа 2255(6) ; 02234 - 2370 2221 3240 2255 +к сч 2425, уи 21 ; 02235 - 0010 2425 0040 0021 +к сч 2417, увв 20(16) ; 02236 - 0010 2417 7033 0020 +к уи, пб (6) ; 02237 - 0040 0000 3300 0000 +к уиа 2411(5), сч 2424 ; 02240 - 2640 2411 0010 2424 +к уи 21, уиа 76001(6) ; 02241 - 0040 0021 3247 6001 +к сч, уиа 3(10) ; 02242 - 0010 0000 4240 0003 +к мода 70000(12), слц 1777(6) ; 02243 - 5227 0000 3013 1777 +к цикл 2243(6), зп 2534 ; 02244 - 3370 2243 0000 2534 +к уиа 2246(5), пв 2203(6) ; 02245 - 2640 2246 3310 2203 +к нтж 2534, пе 2213 ; 02246 - 0012 2534 0270 2213 +к уиа 2255(6), пб 2235 ; 02247 - 3240 2255 0300 2235 +к слиа -1(10), уиа 2252(5) ; 02250 - 4257 7777 2640 2252 +к мода, пв 2203(6) ; 02251 - 0220 0000 3310 2203 +к нтж 2534, и 2423 ; 02252 - 0012 2534 0011 2423 +к пе 2213, слиа 1(10) ; 02253 - 0270 2213 4250 0001 +к слиа 400(12), пб 2234 ; 02254 - 5250 0400 0300 2234 +к сч, уи ; 02255 - 0010 0000 0040 0000 +к рег 37, пб (11) ; 02256 - 0002 0037 4700 0000 +к уиа 1(14), пб 2335 ; 02257 - 6240 0001 0300 2335 +к зп 1027, сч 2516 ; 02260 - 0000 1027 0010 2516 +к или 1775, зп 1775 ; 02261 - 0015 1775 0000 1775 +к уиа 2265(11), пб 2104 ; 02262 - 4640 2265 0300 2104 +к слиа 40(4), цикл 2272(14) ; 02263 - 2250 0040 6370 2272 +к уиа 2466(5), пв 2367(7) ; 02264 - 2640 2466 3710 2367 +к сч 2, сда 130 ; 02265 - 0010 0002 0036 0130 +к и 2427, уиа -17(14) ; 02266 - 0011 2427 6247 7761 +к уиа (2), уиа (4) ; 02267 - 1240 0000 2240 0000 +к по 2271, вч 2664 ; 02270 - 0260 2271 0005 2664 +к зп 2542, мода ; 02271 - 0000 2542 0220 0000 +к уиа -37(7), сч 1775 ; 02272 - 3647 7741 0010 1775 +к нтж 70000(4), и 2423 ; 02273 - 2112 0000 0011 2423 +к пе 2263, сч 1775 ; 02274 - 0270 2263 0010 1775 +к сда 155, нтж 70016(4) ; 02275 - 0036 0155 2112 0016 +к и 2415, пе 2263 ; 02276 - 0011 2415 0270 2263 +к счи 2, нтж 2542 ; 02277 - 0042 0002 0012 2542 +к по 2303, слиа 1(2) ; 02300 - 0260 2303 1250 0001 +к пб 2263, мода ; 02301 - 0300 2263 0220 0000 +к уии 6(11), пб 2235 ; 02302 - 4444 0006 0300 2235 +к мода (4), сч 70037(7) ; 02303 - 2220 0000 3510 0037 +к зп 3537(7), цикл 2303(7) ; 02304 - 3400 3537 3770 2303 +к сч 3502, зп 1775 ; 02305 - 0010 3502 0000 1775 +к мода, пв 2040(2) ; 02306 - 0220 0000 1310 2040 +к зп 1030, сч 3500 ; 02307 - 0000 1030 0010 3500 +к зп 1775, сч 3 ; 02310 - 0000 1775 0010 0003 +к и 2660, пб 2103 ; 02311 - 0011 2660 0300 2103 +к уиа -2(14), сч 3515 ; 02312 - 6247 7776 0010 3515 +к сда 117, зп 1775 ; 02313 - 0036 0117 0000 1775 +к и 2423, по 2103 ; 02314 - 0011 2423 0260 2103 +к сч 2663, пв 2123(11) ; 02315 - 0010 2663 4710 2123 +к сч 3516, и 2415 ; 02316 - 0010 3516 0011 2415 +к сда 75, уи 6 ; 02317 - 0036 0075 0040 0006 +к сч 70000(6), нтж 3516 ; 02320 - 3110 0000 0012 3516 +к и 2415, пе 2103 ; 02321 - 0011 2415 0270 2103 +к мода (6), сч 70002(14) ; 02322 - 3220 0000 6110 0002 +к зп 2604(14), цикл 2322(14) ; 02323 - 6000 2604 6370 2322 +к уиа 2510(12), пв 2040(2) ; 02324 - 5240 2510 1310 2040 +к уиа -2(14), пв 2126(11) ; 02325 - 6247 7776 4710 2126 +к сч 70002(14), нтж 2604(14) ; 02326 - 6110 0002 6012 2604 +к уиа 2257(11), пе 2103 ; 02327 - 4640 2257 0270 2103 +к цикл 2326(14), уиа -22(14) ; 02330 - 6370 2326 6247 7756 +к сч 70026(14), зп 1026(14) ; 02331 - 6110 0026 6000 1026 +к цикл 2331(14), уиа 2335(11) ; 02332 - 6370 2331 4640 2335 +к сч 1774, зп 1031 ; 02333 - 0010 1774 0000 1031 +к пб 2104, мода ; 02334 - 0300 2104 0220 0000 +к сч 1774, слц 2650 ; 02335 - 0010 1774 0013 2650 +к зп 1774, сч 1775 ; 02336 - 0000 1774 0010 1775 +к слц 2634, пв 2121(11) ; 02337 - 0013 2634 4710 2121 +к сч 2522, зп 502 ; 02340 - 0010 2522 0000 0502 +к уиа -37(6), мода ; 02341 - 3247 7741 0220 0000 +к сч 3537(6), зп 71777(6) ; 02342 - 3010 3537 3100 1777 +к цикл 2342(6), сч ; 02343 - 3370 2342 0010 0000 +к зп 72000, пб 70000 ; 02344 - 0100 2000 0307 0000 +к уиа 2345(7), пб 2367 ; 02345 - 3640 2345 0300 2367 +к уиа -2(3), сч ; 02346 - 1647 7776 0010 0000 +к слц 2546(3), цикл 2347(3) ; 02347 - 1413 2546 1770 2347 +к пб (10), мода ; 02350 - 4300 0000 0220 0000 +к сч 1774, и 2660 ; 02351 - 0010 1774 0011 2660 +к пе 2060, уиа 31(4) ; 02352 - 0270 2060 2240 0031 +к мода, пв 2144(6) ; 02353 - 0220 0000 3310 2144 +к зп 2534, сч 2533 ; 02354 - 0000 2534 0010 2533 +к и 2654, по 2402 ; 02355 - 0011 2654 0260 2402 +к сч 2534, и 2662 ; 02356 - 0010 2534 0011 2662 +к уиа 2452(5), пе 2404 ; 02357 - 2640 2452 0270 2404 +к сч 2534, и 2660 ; 02360 - 0010 2534 0011 2660 +к уиа 2466(5), пе 2366 ; 02361 - 2640 2466 0270 2366 +к сч 2534, и 2661 ; 02362 - 0010 2534 0011 2661 +к пе 2410, сч 2534 ; 02363 - 0270 2410 0010 2534 +к и 2652, уиа 2452(5) ; 02364 - 0011 2652 2640 2452 +к пе 2366, уиа 2452(5) ; 02365 - 0270 2366 2640 2452 +к уиа 2126(7), пв 2235(6) ; 02366 - 3640 2126 3310 2235 +к уиа -10(10), мода ; 02367 - 4247 7770 0220 0000 +к зп 1, цикл 2370(10) ; 02370 - 0000 0001 4370 2370 +к сч, рег ; 02371 - 0010 0000 0002 0000 +к уиа -5(10), мода ; 02372 - 4247 7773 0220 0000 +к мода (5), сч 5(10) ; 02373 - 2620 0000 4010 0005 +к рег 6(10), цикл 2373(10) ; 02374 - 4002 0006 4370 2373 +к сч, рег 7 ; 02375 - 0010 0000 0002 0007 +к уиа 76030(10), мода ; 02376 - 4247 6030 0220 0000 +к уиа 77526(3), мода ; 02377 - 1647 7526 0220 0000 +к сбр, цикл 2400(3) ; 02400 - 0020 0000 1770 2400 +к цикл 2377(10), пб (7) ; 02401 - 4370 2377 3700 0000 +к сч 2533, уиа 2430(5) ; 02402 - 0010 2533 2640 2430 +к и 2653, по 2366 ; 02403 - 0011 2653 0260 2366 +к уиа 1(4), пв 2144(6) ; 02404 - 2240 0001 3310 2144 +к мода, пв 2235(6) ; 02405 - 0220 0000 3310 2235 +к уиа 76030(10), пв 2377(7) ; 02406 - 4247 6030 3710 2377 +к уиа 2126(7), пб 2367 ; 02407 - 3640 2126 0300 2367 +к уиа 2452(5), пб 2366 ; 02410 - 2640 2452 0300 2366 +к уиа 2126(6), пб 2235 ; 02411 - 3240 2126 0300 2235 +к сч 1774, и 2660 ; 02412 - 0010 1774 0011 2660 +к по 2366, пв 2235(6) ; 02413 - 0260 2366 3310 2235 +к пб 2060, мода ; 02414 - 0300 2060 0220 0000 в 02415 -с 0000 0000 0000 0007 ; 02415 -с 0000 0000 0000 0003 ; 02416 -с 0000 0000 0000 1050 ; 02417 -с 0000 0000 0174 0000 ; 02420 -с 0000 0000 0000 2400 ; 02421 -с 0000 0000 0000 0000 ; 02422 -с 0000 0000 0000 7777 ; 02423 -с 0000 0000 0000 2003 ; 02424 -с 0000 0000 0000 2013 ; 02425 -с 0000 0000 0000 0000 ; 02426 -с 0000 0000 0000 0017 ; 02427 -с 2236 0400 4176 2000 ; 02430 -с 2220 0400 4044 0000 ; 02431 -с 2220 0400 4044 0000 ; 02432 -с 3636 0400 4044 0000 ; 02433 -с 2220 0400 4044 0000 ; 02434 -с 2236 3700 7434 0000 ; 02435 -с 0003 4376 2022 0000 ; 02436 -с 0004 2222 2220 0000 ; 02437 -с 0004 2222 2220 0000 ; 02440 -с 0004 2222 2220 0000 ; 02441 -с 0004 2222 2520 0000 ; 02442 -с 0003 4222 3060 0000 ; 02443 -с 3476 2046 3440 4000 ; 02444 -с 4252 0044 4244 4000 ; 02445 -с 4252 0044 4044 4000 ; 02446 -с 4252 0070 4044 4000 ; 02447 -с 4252 0044 4252 4000 ; 02450 -с 3452 0046 3461 4000 ; 02451 -с 0000 0021 0740 0000 ; 02452 -с 0000 0021 0420 0000 ; 02453 -с 0000 0037 0420 0000 ; 02454 -с 0000 0021 0740 0000 ; 02455 -с 0000 0021 0420 0000 ; 02456 -с 0000 0017 0740 0000 ; 02457 -с 2236 0046 6247 0040 ; 02460 -с 2220 0044 2250 4040 ; 02461 -с 2220 0044 2250 4040 ; 02462 -с 3636 0070 2270 4740 ; 02463 -с 2220 0044 2250 4440 ; 02464 -с 2236 0046 1647 0440 ; 02465 -с 0022 3604 0070 4440 ; 02466 -с 0022 2004 0044 4440 ; 02467 -с 0022 2004 0044 4470 ; 02470 -с 0036 3604 0072 7444 ; 02471 -с 0022 2004 0044 4444 ; 02472 -с 0022 3637 0070 3470 ; 02473 -с 2236 0400 3470 4044 ; 02474 -с 2220 0400 4244 4440 ; 02475 -с 2220 0400 4244 4440 ; 02476 -с 3636 0400 4270 4440 ; 02477 -с 2220 0400 4240 5240 ; 02500 -с 2236 3700 3474 6140 ; 02501 -с 4561 0213 7462 2422 ; 02502 -с 4501 0211 1112 2420 ; 02503 -с 4501 0251 1013 6434 ; 02504 -с 7561 0251 1022 2422 ; 02505 -с 4501 0251 1112 2422 ; 02506 -с 4567 6330 7061 6734 ; 02507 -с 0456 1021 3716 2240 ; 02510 -с 0450 1021 1101 2240 ; 02511 -с 0450 1025 1107 2270 ; 02512 -с 0756 1025 1111 2244 ; 02513 -с 0450 1025 1111 2244 ; 02514 -с 0456 7633 0711 3670 ; 02515 -с 0000 0757 0000 0000 ; 02516 -с 0000 2523 0000 0000 ; 02517 -с 0010 2425 0040 0021 ; 02520 -с 0010 2523 2700 0000 ; 02521 -с 0010 2523 1700 0000 ; 02522 -с 0000 0000 0000 0000 ; 02523 -с 0000 0000 0000 0030 ; 02524 -с 0000 0000 0000 0040 ; 02525 -с 0000 0000 0003 7777 ; 02526 -с 0000 0000 0000 1334 ; 02527 -с 0000 0000 0000 2340 ; 02530 -с 0000 0000 0007 7775 ; 02531 -с 0000 0000 0440 0020 ; 02532 -с 0017 0707 4005 0513 ; 02533 -с 1646 5273 4157 0513 ; 02534 -с 0007 7777 0000 0000 ; 02535 -с 0007 0707 0000 0000 ; 02536 -с 4000 0000 0000 0000 ; 02537 -с 0000 0000 0017 7777 ; 02540 -с 0000 0000 0000 0377 ; 02541 -с 0000 0000 0000 0000 ; 02542 -с 2740 0000 0000 4007 ; 02543 -с 3000 0000 0000 4005 ; 02544 -с 7760 0000 0000 0000 ; 02545 -с 7760 0000 0000 0000 ; 02546 -с 3000 0000 0000 4005 ; 02547 -с 7777 7400 0000 0000 ; 02550 -с 7760 0000 0000 0000 ; 02551 -с 3000 0000 0000 4005 ; 02552 -с 7777 7400 0000 0000 ; 02553 -с 0000 0000 0000 0000 ; 02554 +с 0000 0000 0000 0007 ; 02415 +с 0000 0000 0000 0003 ; 02416 +с 0000 0000 0000 1050 ; 02417 +с 0000 0000 0174 0000 ; 02420 +с 0000 0000 0000 2400 ; 02421 +с 0000 0000 0000 0000 ; 02422 +с 0000 0000 0000 7777 ; 02423 +с 0000 0000 0000 2003 ; 02424 +с 0000 0000 0000 2013 ; 02425 +с 0000 0000 0000 0000 ; 02426 +с 0000 0000 0000 0017 ; 02427 +с 2236 0400 4176 2000 ; 02430 +с 2220 0400 4044 0000 ; 02431 +с 2220 0400 4044 0000 ; 02432 +с 3636 0400 4044 0000 ; 02433 +с 2220 0400 4044 0000 ; 02434 +с 2236 3700 7434 0000 ; 02435 +с 0003 4376 2022 0000 ; 02436 +с 0004 2222 2220 0000 ; 02437 +с 0004 2222 2220 0000 ; 02440 +с 0004 2222 2220 0000 ; 02441 +с 0004 2222 2520 0000 ; 02442 +с 0003 4222 3060 0000 ; 02443 +с 3476 2046 3440 4000 ; 02444 +с 4252 0044 4244 4000 ; 02445 +с 4252 0044 4044 4000 ; 02446 +с 4252 0070 4044 4000 ; 02447 +с 4252 0044 4252 4000 ; 02450 +с 3452 0046 3461 4000 ; 02451 +с 0000 0021 0740 0000 ; 02452 +с 0000 0021 0420 0000 ; 02453 +с 0000 0037 0420 0000 ; 02454 +с 0000 0021 0740 0000 ; 02455 +с 0000 0021 0420 0000 ; 02456 +с 0000 0017 0740 0000 ; 02457 +с 2236 0046 6247 0040 ; 02460 +с 2220 0044 2250 4040 ; 02461 +с 2220 0044 2250 4040 ; 02462 +с 3636 0070 2270 4740 ; 02463 +с 2220 0044 2250 4440 ; 02464 +с 2236 0046 1647 0440 ; 02465 +с 0022 3604 0070 4440 ; 02466 +с 0022 2004 0044 4440 ; 02467 +с 0022 2004 0044 4470 ; 02470 +с 0036 3604 0072 7444 ; 02471 +с 0022 2004 0044 4444 ; 02472 +с 0022 3637 0070 3470 ; 02473 +с 2236 0400 3470 4044 ; 02474 +с 2220 0400 4244 4440 ; 02475 +с 2220 0400 4244 4440 ; 02476 +с 3636 0400 4270 4440 ; 02477 +с 2220 0400 4240 5240 ; 02500 +с 2236 3700 3474 6140 ; 02501 +с 4561 0213 7462 2422 ; 02502 +с 4501 0211 1112 2420 ; 02503 +с 4501 0251 1013 6434 ; 02504 +с 7561 0251 1022 2422 ; 02505 +с 4501 0251 1112 2422 ; 02506 +с 4567 6330 7061 6734 ; 02507 +с 0456 1021 3716 2240 ; 02510 +с 0450 1021 1101 2240 ; 02511 +с 0450 1025 1107 2270 ; 02512 +с 0756 1025 1111 2244 ; 02513 +с 0450 1025 1111 2244 ; 02514 +с 0456 7633 0711 3670 ; 02515 +с 0000 0757 0000 0000 ; 02516 +с 0000 2523 0000 0000 ; 02517 +с 0010 2425 0040 0021 ; 02520 +с 0010 2523 2700 0000 ; 02521 +с 0010 2523 1700 0000 ; 02522 +с 0000 0000 0000 0000 ; 02523 +с 0000 0000 0000 0030 ; 02524 +с 0000 0000 0000 0040 ; 02525 +с 0000 0000 0003 7777 ; 02526 +с 0000 0000 0000 1334 ; 02527 +с 0000 0000 0000 2340 ; 02530 +с 0000 0000 0007 7775 ; 02531 +с 0000 0000 0440 0020 ; 02532 +с 0017 0707 4005 0513 ; 02533 +с 1646 5273 4157 0513 ; 02534 +с 0007 7777 0000 0000 ; 02535 +с 0007 0707 0000 0000 ; 02536 +с 4000 0000 0000 0000 ; 02537 +с 0000 0000 0017 7777 ; 02540 +с 0000 0000 0000 0377 ; 02541 +с 0000 0000 0000 0000 ; 02542 +с 2740 0000 0000 4007 ; 02543 +с 3000 0000 0000 4005 ; 02544 +с 7760 0000 0000 0000 ; 02545 +с 7760 0000 0000 0000 ; 02546 +с 3000 0000 0000 4005 ; 02547 +с 7777 7400 0000 0000 ; 02550 +с 7760 0000 0000 0000 ; 02551 +с 3000 0000 0000 4005 ; 02552 +с 7777 7400 0000 0000 ; 02553 +с 0000 0000 0000 0000 ; 02554 в 02600 -с 0000 0000 0000 0000 ; 02600 -с 0000 0000 0000 0037 ; 02601 -с 0000 0000 0742 1025 ; 02602 -с 0000 0000 0021 0000 ; 02603 -с 0000 0000 0000 0000 ; 02604 -с 4000 0000 0000 0000 ; 02605 -с 2000 0000 0000 0000 ; 02606 -с 1000 0000 0000 0000 ; 02607 -с 0400 0000 0000 0000 ; 02610 -с 0200 0000 0000 0000 ; 02611 -с 0100 0000 0000 0000 ; 02612 -с 0040 0000 0000 0000 ; 02613 -с 0020 0000 0000 0000 ; 02614 -с 0010 0000 0000 0000 ; 02615 -с 0004 0000 0000 0000 ; 02616 -с 0002 0000 0000 0000 ; 02617 -с 0001 0000 0000 0000 ; 02620 -с 0000 4000 0000 0000 ; 02621 -с 0000 2000 0000 0000 ; 02622 -с 0000 1000 0000 0000 ; 02623 -с 0000 0400 0000 0000 ; 02624 -с 0000 0200 0000 0000 ; 02625 -с 0000 0100 0000 0000 ; 02626 -с 0000 0040 0000 0000 ; 02627 -с 0000 0020 0000 0000 ; 02630 -с 0000 0010 0000 0000 ; 02631 -с 0000 0004 0000 0000 ; 02632 -с 0000 0002 0000 0000 ; 02633 -с 0000 0001 0000 0000 ; 02634 -с 0000 0000 4000 0000 ; 02635 -с 0000 0000 2000 0000 ; 02636 -с 0000 0000 1000 0000 ; 02637 -с 0000 0000 0400 0000 ; 02640 -с 0000 0000 0200 0000 ; 02641 -с 0000 0000 0100 0000 ; 02642 -с 0000 0000 0040 0000 ; 02643 -с 0000 0000 0020 0000 ; 02644 -с 0000 0000 0010 0000 ; 02645 -с 0000 0000 0004 0000 ; 02646 -с 0000 0000 0002 0000 ; 02647 -с 0000 0000 0001 0000 ; 02650 -с 0000 0000 0000 4000 ; 02651 -с 0000 0000 0000 2000 ; 02652 -с 0000 0000 0000 1000 ; 02653 -с 0000 0000 0000 0400 ; 02654 -с 0000 0000 0000 0200 ; 02655 -с 0000 0000 0000 0100 ; 02656 -с 0000 0000 0000 0040 ; 02657 -с 0000 0000 0000 0020 ; 02660 -с 0000 0000 0000 0010 ; 02661 -с 0000 0000 0000 0004 ; 02662 -с 0000 0000 0000 0002 ; 02663 -с 0000 0000 0000 0001 ; 02664 +с 0000 0000 0000 0000 ; 02600 +с 0000 0000 0000 0037 ; 02601 +с 0000 0000 0742 1025 ; 02602 +с 0000 0000 0021 0000 ; 02603 +с 0000 0000 0000 0000 ; 02604 +с 4000 0000 0000 0000 ; 02605 +с 2000 0000 0000 0000 ; 02606 +с 1000 0000 0000 0000 ; 02607 +с 0400 0000 0000 0000 ; 02610 +с 0200 0000 0000 0000 ; 02611 +с 0100 0000 0000 0000 ; 02612 +с 0040 0000 0000 0000 ; 02613 +с 0020 0000 0000 0000 ; 02614 +с 0010 0000 0000 0000 ; 02615 +с 0004 0000 0000 0000 ; 02616 +с 0002 0000 0000 0000 ; 02617 +с 0001 0000 0000 0000 ; 02620 +с 0000 4000 0000 0000 ; 02621 +с 0000 2000 0000 0000 ; 02622 +с 0000 1000 0000 0000 ; 02623 +с 0000 0400 0000 0000 ; 02624 +с 0000 0200 0000 0000 ; 02625 +с 0000 0100 0000 0000 ; 02626 +с 0000 0040 0000 0000 ; 02627 +с 0000 0020 0000 0000 ; 02630 +с 0000 0010 0000 0000 ; 02631 +с 0000 0004 0000 0000 ; 02632 +с 0000 0002 0000 0000 ; 02633 +с 0000 0001 0000 0000 ; 02634 +с 0000 0000 4000 0000 ; 02635 +с 0000 0000 2000 0000 ; 02636 +с 0000 0000 1000 0000 ; 02637 +с 0000 0000 0400 0000 ; 02640 +с 0000 0000 0200 0000 ; 02641 +с 0000 0000 0100 0000 ; 02642 +с 0000 0000 0040 0000 ; 02643 +с 0000 0000 0020 0000 ; 02644 +с 0000 0000 0010 0000 ; 02645 +с 0000 0000 0004 0000 ; 02646 +с 0000 0000 0002 0000 ; 02647 +с 0000 0000 0001 0000 ; 02650 +с 0000 0000 0000 4000 ; 02651 +с 0000 0000 0000 2000 ; 02652 +с 0000 0000 0000 1000 ; 02653 +с 0000 0000 0000 0400 ; 02654 +с 0000 0000 0000 0200 ; 02655 +с 0000 0000 0000 0100 ; 02656 +с 0000 0000 0000 0040 ; 02657 +с 0000 0000 0000 0020 ; 02660 +с 0000 0000 0000 0010 ; 02661 +с 0000 0000 0000 0004 ; 02662 +с 0000 0000 0000 0002 ; 02663 +с 0000 0000 0000 0001 ; 02664 в 03000 -к по 3002, мода ; 03000 - 0260 3002 0220 0000 -к ржа 3, пб 2015 ; 03001 - 0037 0003 0300 2015 -к уиа 3004(7), уиа 2466(5) ; 03002 - 3640 3004 2640 2466 -к пб 2367, мода ; 03003 - 0300 2367 0220 0000 -к слиа 1(1), пб 3004 ; 03004 - 0650 0001 0300 3004 +к по 3002, мода ; 03000 - 0260 3002 0220 0000 +к ржа 3, пб 2015 ; 03001 - 0037 0003 0300 2015 +к уиа 3004(7), уиа 2466(5) ; 03002 - 3640 3004 2640 2466 +к пб 2367, мода ; 03003 - 0300 2367 0220 0000 +к слиа 1(1), пб 3004 ; 03004 - 0650 0001 0300 3004 в 03500 -с 0000 0560 0000 4005 ; 03500 -с 4000 0000 0000 4005 ; 03501 -с 0000 0000 0000 4005 ; 03502 -с 0000 0000 0000 4005 ; 03503 -с 0000 0000 0000 0006 ; 03504 -с 4000 0000 0000 0000 ; 03505 -с 0000 0000 0000 3320 ; 03506 -с 0000 0000 0000 0022 ; 03507 -с 0000 0000 0000 0021 ; 03510 -с 7760 0000 3760 0000 ; 03511 -с 0000 0000 0000 0000 ; 03512 -с 0000 0000 0000 0000 ; 03513 -с 0000 0000 0000 0000 ; 03514 -с 4000 0070 0004 0310 ; 03515 -с 1770 0000 0000 0003 ; 03516 -с 0000 0000 1600 4227 ; 03517 -с 3722 1066 0361 6435 ; 03520 -с 0000 0000 0000 0000 ; 03521 -с 7760 0000 0000 0000 ; 03522 -с 7760 0000 0000 3220 ; 03523 -с 0000 0000 1022 4005 ; 03524 -с 1240 0000 0000 0000 ; 03525 -с 1313 1413 1413 1413 ; 03526 -с 7777 4000 6000 0000 ; 03527 -с 7403 0000 0000 0000 ; 03530 -с 7777 7777 7777 7777 ; 03531 -с 0000 0017 7760 0000 ; 03532 -с 0000 0000 0000 0000 ; 03533 -с 0000 0000 0000 0000 ; 03534 -с 0000 0000 0000 0000 ; 03535 -с 0000 0000 7760 0000 ; 03536 -с 0000 0000 0000 0000 ; 03537 +с 0000 0560 0000 4005 ; 03500 +с 4000 0000 0000 4005 ; 03501 +с 0000 0000 0000 4005 ; 03502 +с 0000 0000 0000 4005 ; 03503 +с 0000 0000 0000 0006 ; 03504 +с 4000 0000 0000 0000 ; 03505 +с 0000 0000 0000 3320 ; 03506 +с 0000 0000 0000 0022 ; 03507 +с 0000 0000 0000 0021 ; 03510 +с 7760 0000 3760 0000 ; 03511 +с 0000 0000 0000 0000 ; 03512 +с 0000 0000 0000 0000 ; 03513 +с 0000 0000 0000 0000 ; 03514 +с 4000 0070 0004 0310 ; 03515 +с 1770 0000 0000 0003 ; 03516 +с 0000 0000 1600 4227 ; 03517 +с 3722 1066 0361 6435 ; 03520 +с 0000 0000 0000 0000 ; 03521 +с 7760 0000 0000 0000 ; 03522 +с 7760 0000 0000 3220 ; 03523 +с 0000 0000 1022 4005 ; 03524 +с 1240 0000 0000 0000 ; 03525 +с 1313 1413 1413 1413 ; 03526 +с 7777 4000 6000 0000 ; 03527 +с 7403 0000 0000 0000 ; 03530 +с 7777 7777 7777 7777 ; 03531 +с 0000 0017 7760 0000 ; 03532 +с 0000 0000 0000 0000 ; 03533 +с 0000 0000 0000 0000 ; 03534 +с 0000 0000 0000 0000 ; 03535 +с 0000 0000 7760 0000 ; 03536 +с 0000 0000 0000 0000 ; 03537 diff --git a/BESM6/formatdisk.c b/BESM6/formatdisk.c old mode 100755 new mode 100644 diff --git a/BESM6/test_pprog05.b6 b/BESM6/test_pprog05.b6 index e136bf5a..12b9e778 100644 --- a/BESM6/test_pprog05.b6 +++ b/BESM6/test_pprog05.b6 @@ -22,16 +22,16 @@ ; (110000 – порядок числа). ; в 1 -к сл 7, зп 11 ; код := т.рег.7 -к вчп 11, зп 10 ; в эталон -к умн 10, дел 10 -к вч 10, слпа 145 ; 64+37 -к пе 6, стоп +к сл 7, зп 11 ; код := т.рег.7 +к вчп 11, зп 10 ; в эталон +к умн 10, дел 10 +к вч 10, слпа 145 ; 64+37 +к пе 6, стоп в 6 -к сч 11, пб 1 ; если хорошо +к сч 11, пб 1 ; если хорошо в 7 -ч 1.0 ; тумб.регистр 7 -с 0 ; эталон -с 0 ; код +ч 1.0 ; тумб.регистр 7 +с 0 ; эталон +с 0 ; код п 1 diff --git a/BESM6/test_pprog05.ini b/BESM6/test_pprog05.ini index f809d939..024c235d 100644 --- a/BESM6/test_pprog05.ini +++ b/BESM6/test_pprog05.ini @@ -7,7 +7,6 @@ load test_pprog05.b6 ex -ml 1-6 ex 7-11 echo -go echo Должно быть четыре останова с числами на сумматоре: 1.0 2.0 3.0 4.0. br 2 go