/* * besm6_defs.h: BESM-6 simulator definitions * * Copyright (c) 2009, Serge Vakulenko * Copyright (c) 2009, Leonid Broukhis * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * SERGE VAKULENKO OR LEONID BROUKHIS BE LIABLE FOR ANY CLAIM, DAMAGES * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE * OR OTHER DEALINGS IN THE SOFTWARE. * Except as contained in this notice, the name of Leonid Broukhis or * Serge Vakulenko shall not be used in advertising or otherwise to promote * the sale, use or other dealings in this Software without prior written * authorization from Leonid Broukhis and Serge Vakulenko. */ #ifndef _BESM6_DEFS_H_ #define _BESM6_DEFS_H_ 0 #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 */ /* * Drums and disks. * * One zone contains 1024 words of user memory and 8 system data words. * 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 */ /* * 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 */ }; /* * Разряды машинного слова, справа налево, начиная с 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)) /* адрес слова */ /* * Работа со сверткой. Значение разрядов свертки слова равно значению * регистров ПКЛ и ПКП при записи слова. * 00 - командная свертка * 01 или 10 - контроль числа * 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) /* * Вычисление правдоподобного времени выполнения команды, * зная количество тактов в УУ и среднее в АУ. * Предполагаем, что в 50% случаев происходит совмещение * выполнения, поэтому суммируем большее и половину * от меньшего значения. */ #define MEAN_TIME(x,y) (x>y ? x+y/2 : x/2+y) /* * Считаем, что моделируеммая машина имеет опорную частоту 10 МГц. */ #define USEC 1 /* одна микросекунда - десять тактов */ #define MSEC (1000*USEC) /* одна миллисекунда */ #define CLK_TPS 250 /* Fast Clock Ticks Per Second (every 4ms) */ #define CLK_DELAY 4000 /* Uncalibrated instructions per clock tick */ extern UNIT cpu_unit; extern UNIT tty_unit[]; extern UNIT clocks[]; extern t_value memory [MEMSIZE]; extern t_value pult [8]; extern uint32 PC, RAU, RUU; extern uint32 M[NREGS]; extern t_value BRZ[8], RP[8], GRP, MGRP; extern uint32 PRP, MPRP; extern t_value ACC, RMR; extern uint32 BAZ[8], TABST, RZ; extern uint32 READY; /* read by ext 4031 */ extern uint32 READY2; /* read by ext 4102 */ extern DEVICE cpu_dev, drum_dev, mmu_dev, disk_dev; extern DEVICE clock_dev; extern DEVICE printer_dev; extern DEVICE tty_dev; extern DEVICE fs_dev; extern jmp_buf cpu_halt; /* * Разряды режима АУ. */ #define RAU_NORM_DISABLE 001 /* блокировка нормализации */ #define RAU_ROUND_DISABLE 002 /* блокировка округления */ #define RAU_LOG 004 /* признак логической группы */ #define RAU_MULT 010 /* признак группы умножения */ #define RAU_ADD 020 /* признак группы слодения */ #define RAU_OVF_DISABLE 040 /* блокировка переполнения */ #define RAU_MODE (RAU_LOG | RAU_MULT | RAU_ADD) #define SET_MODE(x,m) (((x) & ~RAU_MODE) | (m)) #define SET_LOGICAL(x) (((x) & ~RAU_MODE) | RAU_LOG) #define SET_MULTIPLICATIVE(x) (((x) & ~RAU_MODE) | RAU_MULT) #define SET_ADDITIVE(x) (((x) & ~RAU_MODE) | RAU_ADD) #define IS_LOGICAL(x) (((x) & RAU_MODE) == RAU_LOG) #define IS_MULTIPLICATIVE(x) (((x) & (RAU_ADD | RAU_MULT)) == RAU_MULT) #define IS_ADDITIVE(x) ((x) & RAU_ADD) /* * Искусственный регистр режимов УУ, в реальной машине отсутствует. */ #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 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 /* АвтБ - признак режима Автомат Б */ /* * Регистр 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 /* БлПр - блокировка внешнего прерывания */ /* * Кириллица 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 /* * Процедуры работы с памятью */ extern void mmu_store (int addr, t_value word); extern t_value mmu_load (int addr); extern t_value mmu_fetch (int addr); extern t_value mmu_prefetch (int addr, int actual); extern void mmu_setcache (int idx, t_value word); extern t_value mmu_getcache (int idx); extern void mmu_setrp (int idx, t_value word); extern void mmu_setup (void); extern void mmu_setprotection (int idx, t_value word); extern void mmu_print_brz (void); /* * Выполнение обращения к барабану. */ void drum (int ctlr, uint32 cmd); int drum_errors (void); /* * Обращение к дискам. */ void disk_io (int ctlr, uint32 cmd); void disk_ctl (int ctlr, uint32 cmd); int disk_state (int ctlr); int disk_errors (void); /* * Печать на АЦПУ. */ void printer_control (int num, uint32 cmd); void printer_hammer (int num, int pos, uint32 mask); /* * Терминалы (телетайпы, видеотоны, "Консулы"). */ void tty_send (uint32 mask); int tty_query (void); void vt_print (void); void vt_receive (void); void consul_print (int num, uint32 cmd); uint32 consul_read (int num); int vt_is_idle (void); /* * Ввод с перфоленты. */ void fs_control (int num, uint32 cmd); int fs_read (int num); /* * Отладочная выдача. */ void besm6_fprint_cmd (FILE *of, uint32 cmd); 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); void besm6_draw_panel (void); /* * Арифметика. */ double besm6_to_ieee (t_value word); void besm6_add (t_value val, int negate_acc, int negate_val); void besm6_divide (t_value val); void besm6_multiply (t_value val); void besm6_change_sign (int sign); void besm6_add_exponent (int val); int besm6_highest_bit (t_value val); void besm6_shift (int toright); int besm6_count_ones (t_value word); t_value besm6_pack (t_value val, t_value mask); 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_SERIAL 00000000001000000LL /* 19 */ #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_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; #endif