Файл: Курсовая работа по дисциплине Архитектура эвм.docx

ВУЗ: Не указан

Категория: Курсовая работа

Дисциплина: Не указана

Добавлен: 16.03.2024

Просмотров: 55

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

СОДЕРЖАНИЕ

Оглавление

Постановка задачи

Обработка команд центральным процессором

Транслятор с языка Simple Assembler

Транслятор с языка Simple Basic

Архитектура simpleComputer

Оперативная память

Внешние устройства

Центральный процессор

Система команд Simple Computer

Выполнение команд центральным процессором Simple Computer

Консоль управления

Блок-схемы

SimpleComputer

SimpleAssembler

SimpleBasic

Результаты проведенного исследования

Примеры работы программы

Приложение. Листинг Makefile d.PHONY: all clean runCOMPILER := g++FLAGS := -fdiagnostics-color=always -Werror -MMDSRC_SC := src/scBUILD_SC := build/scLIBS_SC := libs/scSRC_SA := src/saBUILD_SA := build/saSRC_SB := src/sbBUILD_SB := build/sbBIN := binSC := simpleComputerSA := simpleAssemblerSB := simpleBasicall: create $(BIN)/$(SC) $(BIN)/$(SA) $(BIN)/$(SB)-include $((BUILD_SC)/*.d-include $((BUILD_SA)/*.d-include $((BUILD_SB)/*.dsc: create $(BIN)/$(SC)run_sc: sc ./$(BIN)/$(SC)$(BIN)/$(SC): $(LIBS_SC)/libsimpleComputer.a $(LIBS_SC)/libmyTerm.a $(LIBS_SC)/libmyBigChars.a $(LIBS_SC)/libmyReadkey.a $(LIBS_SC)/libmyUI.a $(LIBS_SC)/libmyALU.a $(LIBS_SC)/libmyCU.a $(BUILD_SC)/main.o $(COMPILER) $(FLAGS) -o $(BIN)/$(SC) $(BUILD_SC)/main.o -L $(LIBS_SC) -lsimpleComputer -lmyUI -lmyTerm -lmyBigChars -lmyReadkey -lmyCU -lmyALU$(BUILD_SC)/%.o: $(SRC_SC)/%.cpp $(COMPILER) $(FLAGS) -c $^ -o $@$(LIBS_SC)/libsimpleComputer.a: $(BUILD_SC)/simpleComputer.o ar cr $@ $^$(LIBS_SC)/libmyTerm.a: $(BUILD_SC)/myTerm.o ar cr $@ $^$(LIBS_SC)/libmyBigChars.a: $(BUILD_SC)/myBigChars.o ar cr $@ $^$(LIBS_SC)/libmyReadkey.a: $(BUILD_SC)/myReadkey.o ar cr $@ $^$(LIBS_SC)/libmyUI.a: $(BUILD_SC)/myUI.o ar cr $@ $^$(LIBS_SC)/libmyALU.a: $(BUILD_SC)/myALU.o ar cr $@ $^$(LIBS_SC)/libmyCU.a: $(BUILD_SC)/myCU.o ar cr $@ $^sa: create $(BIN)/$(SA)run_sa: create $(BIN)/$(SA) ./$(BIN)/$(SA)$(BIN)/$(SA): $(BUILD_SA)/main.o $(COMPILER) $(FLAGS) -o $(BIN)/$(SA) $(BUILD_SA)/main.o$(BUILD_SA)/%.o: $(SRC_SA)/%.cpps $(COMPILER) $(FLAGS) -c $^ -o $@sb: create $(BIN)/$(SB)run_sb: create $(BIN)/$(SB) ./$(BIN)/$(SB)$(BIN)/$(SB): $(BUILD_SB)/main.o $(COMPILER) $(FLAGS) -o $(BIN)/$(SB) $(BUILD_SB)/main.o$(BUILD_SB)/%.o: $(SRC_SB)/%.cpp $(COMPILER) $(FLAGS) -c $^ -o $@create: mkdir -p $(BUILD_SC) $(BUILD_SA) $(BUILD_SB) $(LIBS_SC) $(BIN)clean: @rm -rf build libs $(BIN) SimpleComputer main.cpp#include #include "simpleComputer.hpp"#include "myUI.hpp"#include "myReadkey.hpp"#include "myCU.hpp"void signalHandler(int signal) ;#include int main(int argc, char const *argv[]){ui_initial() ;signal(SIGALRM, signalHandler) ;signal(SIGUSR1, signalHandler) ;bool zero, out, ignor, comm ;keys key;if (argc == 2){sc_memoryLoad((char *)argv[1]) ;}else if (argc > 2){ui_messageOutput((char *)"Exceeded the number of arguments", colors::RED) ; return -1 ;}do {sc_regGet(IGNORING_TACT_PULSES, &ignor);ui_update() ;rk_readKey(&key);if (ignor){sc_regGet(DIVISION_ERR_BY_ZERO, &zero) ;sc_regGet(OUT_OF_MEMORY, &out) ;sc_regGet(INCORRECT_COMMAND, &comm) ;if (zero || out || comm){switch(key){case keys::KEY_L:ui_initial() ;ui_loadMemory() ;break ;case keys::KEY_S:ui_saveMemory() ;break ;case keys::KEY_I:raise(SIGUSR1) ;break ;}}else{switch(key){case keys::KEY_UP:ui_moveCurrMemPointer(keys::KEY_UP) ;break ;case keys::KEY_RIGHT:ui_moveCurrMemPointer(keys::KEY_RIGHT) ;break ;case keys::KEY_DOWN:ui_moveCurrMemPointer(keys::KEY_DOWN) ;break ;case keys::KEY_LEFT:ui_moveCurrMemPointer(keys::KEY_LEFT) ;break ;case keys::KEY_L:ui_initial() ;ui_loadMemory() ;break ;case keys::KEY_S:ui_saveMemory() ;break ;case keys::KEY_R:sc_regInit() ;raise(SIGALRM) ;break ;case keys::KEY_T:setCurrMemPointer_to_ICounter() ;ui_update() ;CU() ;break ;case keys::KEY_I:raise(SIGUSR1) ;break ;case keys::KEY_F5:ui_setAccumulator() ;break ;case keys::KEY_F6:ui_setICounter() ;break ;case keys::KEY_ENTER:ui_setMCellValue() ;break ;}}}elseif (key == keys::KEY_I)raise(SIGUSR1) ;} while(key != keys::KEY_ESC) ;return 0 ;}void signalHandler(int signal){switch (signal) {case SIGALRM:setCurrMemPointer_to_ICounter() ;ui_update() ;if (CU()){sc_regSet(IGNORING_TACT_PULSES, true);ui_update() ;alarm(0) ;}elsealarm(1) ;rk_myTermRegime(false, 0, 0, false, false) ;break ;case SIGUSR1:alarm(0) ;ui_initial() ;break ;default:break ;}}simpleComputer.hpp#ifndef SIMPLECOMPUTER_HPP#define SIMPLECOMPUTER_HPP#include #define OVERFLOW 0 // Переполнение при выполнении операции#define DIVISION_ERR_BY_ZERO 1 // Ошибка деления на 0#define OUT_OF_MEMORY 2 // Ошибка выхода за границы памяти#define IGNORING_TACT_PULSES 3 // Игнорирование тактовых импульсов#define INCORRECT_COMMAND 4 // Указана неверная командаconst short int SC_REG_SIZE = 5 ;const short int SC_MEM_SIZE = 100 ;extern unsigned short int sc_accumulator ;extern uint8_t sc_instructionCounter ;int sc_memoryInit () ;int sc_memorySet (unsigned short int address, unsigned short int value) ;int sc_memoryGet (unsigned short int address, unsigned short int * value) ;int sc_memorySave (char* filename) ;int sc_memoryLoad (char* filename) ;int sc_regInit () ;int sc_regSet (int8_t reg, bool value) ;int sc_regGet (int8_t reg, bool * value) ;int sc_commandEncode (unsigned short int command, unsigned short int operand, unsigned short int * value) ;int sc_commandDecode (unsigned short int value, unsigned short int * command, unsigned short int * operand) ;#endif //SIMPLECOMPUTER_HPPsimpleComputer.cpp#include "simpleComputer.hpp"unsigned short int sc_memory[SC_MEM_SIZE] ;uint8_t sc_regFLAGS ;unsigned short int sc_accumulator ;uint8_t sc_instructionCounter ;/// Инициализирует оперативную память SC, задавая всем её ячейкам нулевые значения/// \return 0int sc_memoryInit(){sc_instructionCounter = 0 ;for (unsigned short & mem : sc_memory)mem = 0 ;return 0 ;}/// Задает значение указанной ячейки памяти/// \param address - ячейка памяти/// \param value - значение/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint sc_memorySet(unsigned short int address, unsigned short int value){if (address >= SC_MEM_SIZE){sc_regSet(OUT_OF_MEMORY, true) ;return -1 ;}sc_memory[address] = value ;return 0 ;}/// Возвращает значение указанной ячейки памяти/// \param address - ячейка памяти/// \param value - значение/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint sc_memoryGet(unsigned short int address, unsigned short int * value){if (address >= SC_MEM_SIZE){sc_regSet(OUT_OF_MEMORY, true) ;return -1 ;}*value = sc_memory[address] ;return 0 ;}/// Сохраняет содержимое памяти в файл в бинарном виде/// \param filename - имя файла/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint sc_memorySave(char* filename){FILE * fb ;if (!(fb = fopen(filename, "wb"))){return -1 ;}fwrite(sc_memory, sizeof(sc_memory), 1, fb) ;fclose(fb) ;return 0 ;}/// Загружает из указанного файла содержимое оперативной памяти/// \param filename - имя файла/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint sc_memoryLoad(char* filename){FILE * fb ;if (!(fb = fopen(filename, "rb"))){return -1 ;}fread(sc_memory, sizeof(sc_memory), 1, fb) ;fclose(fb) ;return 0 ;}/// Инициализирует регистр флагов нулевым значением/// \return 0int sc_regInit(){sc_regFLAGS = 0 ;return 0 ;}/// Устанавливает значение указанного регистра флагов/// \param reg - флаг/// \param value - значение/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint sc_regSet(int8_t reg, bool value){if (reg < 0 || reg >= SC_REG_SIZE)return -1 ;value == 1 ? (sc_regFLAGS |= (1 << reg)) : (sc_regFLAGS &= (1 << reg)) ;return 0 ;}/// Возвращает значение указанного флага/// \param reg - флаг/// \param value - значение/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint sc_regGet(int8_t reg, bool *value){if (reg < 0 || reg >= SC_REG_SIZE)return -1 ;*value = sc_regFLAGS & (1 << reg) ;return 0 ;}/// Кодирует команду с указанным номером и операндом и помещает результат в value/// \param command - команда/// \param operand - операнд/// \param value - значение/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint sc_commandEncode(unsigned short int command, unsigned short int operand, unsigned short int * value){if (command > 0x7F)return -1 ;if (operand > 0x7F)return -1 ;* value = 0 ;/* Операнд */for (int i = 0 ; i < 7 ; i++) {int8_t bit = (operand >> i) & 1 ;*value |= (bit << i) ;}/* Команда */for (int i = 0 ; i < 7 ; i++) {int8_t bit = (command >> i) & 1 ;*value |= (bit << (i + 7)) ;}return 0 ;}/// Декодирует значение как команду SС/// \param value - значение/// \param command - команда/// \param operand - операнд/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint sc_commandDecode(unsigned short int value, unsigned short int * command, unsigned short int * operand){int tmpCom = 0, tmpOp = 0 ;if ((value >> 14) & 1){sc_regSet(INCORRECT_COMMAND, true) ;return -1 ;}for (int i = 0 ; i < 7 ; i++) {int bit = (value >> i) & 1 ;tmpOp |= (bit << i) ;}for (int i = 0 ; i < 7 ; i++) {int bit = (value >> (i + 7)) & 1 ;tmpCom |= (bit << i) ;}* command = tmpCom ;* operand = tmpOp ;return 0 ;}myTerm.hpp#ifndef MYTERM_HPP#define MYTERM_HPP#include #include enum colors {RED = 196,PEACH = 203,GREEN = 10,SOFT_GREEN =192,BLUE = 20,BLACK = 16,GRAY = 240,WHITE = 15,DEFAULT = 0};int mt_clrScreen () ;int mt_gotoXY(unsigned int col,unsigned int row) ;int mt_getScreenSize(unsigned int *rows, unsigned int* cols) ;int mt_setFGcolor(enum colors color) ;int mt_setBGcolor(enum colors color) ;int mt_setDefaultColorSettings() ;#endif //MYTERM_HPPmyTerm.cpp#include "myTerm.hpp"/// Производит очистку и перемещение курсора в левый верхний угол экрана/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint mt_clrScreen (){printf("\033[H\033[2J") ;return 0 ;}/// Перемещает курсор в указанную позицию/// \param col - столбец/// \param row - строка/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint mt_gotoXY(unsigned int col, unsigned int row){unsigned int rows, cols ;if (mt_getScreenSize(&rows, &cols) == -1)return -1 ;if ((row > rows) || (row <= 0)||(col > cols) || (col <= 0))return -1 ;printf("\033[%d;%dH", row, col) ;return 0 ;}/// Определяет размер экрана терминала/// \param rows - кол-во строк/// \param cols - кол-во столбцов/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint mt_getScreenSize(unsigned int *rows, unsigned int *cols){winsize ws{} ;if (ioctl(1, TIOCGWINSZ, &ws))return -1 ;* rows = ws.ws_row ;* cols = ws.ws_col ;return 0 ;}/// Устанавливает цвет последующих выводимых символов/// \param color - цвет из перечисления colors/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint mt_setFGcolor(enum colors color){printf("\033[38;5;%dm",color) ;return 0 ;}/// Устанавливает цвет фона последующих выводимых символов/// \param color - цвет из перечисления colors/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint mt_setBGcolor(enum colors color){printf("\033[48;5;%dm",color) ;return 0 ;}/// Возвращает цвета в стандартное состояние/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint mt_setDefaultColorSettings(){printf("\033[0m") ;return 0 ;}myUI.hpp#ifndef MYUI_HPP#define MYUI_HPP#include #include "myBigChars.hpp"#include "myReadkey.hpp"#include "simpleComputer.hpp"int ui_initial() ;int ui_update() ;int setCurrMemPointer_to_ICounter() ;int ui_moveCurrMemPointer(keys key) ;int ui_setMCellValue() ;int ui_saveMemory() ;int ui_loadMemory() ;int ui_setAccumulator() ;int ui_setICounter() ;bool checkCorrectInputHEX(const char *buffer) ;int ui_messageOutput(char *str, enum colors color);int clearBuffIn() ;#endif //MYUI_HPPmyUI.cpp#include "myUI.hpp"#include "myReadkey.hpp"int8_t currMemCell = 0 ;int drawingBoxes() ;int drawingTexts() ;int drawingMemory() ;int drawingAccumulator() ;int drawingInstructionCounter() ;int drawingOperation() ;int drawingFlags() ;int drawingBigChar() ;bool checkCorrectInputHEX(const char *buffer) ;bool checkCorrectInputDEC(const char *buffer) ;int ui_messageOutput(char *str, enum colors color) ;/// "Инициализация" интерфейса пользователя/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint ui_initial(){currMemCell = 0 ;if (rk_myTermSave())return -1 ;sc_memoryInit() ;sc_accumulator &= (1 << 14) ;sc_regInit() ;sc_regSet(IGNORING_TACT_PULSES, true) ;return 0 ;}/// Обновление интерфейса пользователя/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint ui_update(){mt_clrScreen() ;if (drawingBoxes())return -1 ;if (drawingTexts())return -1 ;if (drawingMemory())return -1 ;if (drawingAccumulator())return -1 ;if (drawingInstructionCounter())return -1 ;if (drawingOperation())return -1 ;if (drawingFlags())return -1 ;if (drawingBigChar())return -1 ;mt_gotoXY(1, 23) ;printf("Input/Output:\n") ;return 0 ;}/// Перемещение выделенной ячейки на значение ICounter/// \return 0int setCurrMemPointer_to_ICounter(){currMemCell = sc_instructionCounter ;return 0 ;}/// Перемещение выделенной ячейки/// \param key - Клавиша/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint ui_moveCurrMemPointer(keys key){switch (key) {case keys::KEY_UP: (currMemCell <= 9) ? (currMemCell = 90 + currMemCell) : (currMemCell -= 10) ; return 0 ;case keys::KEY_RIGHT: (!((currMemCell + 1) % 10)) ? (currMemCell -= 9) : (currMemCell += 1) ; return 0 ;case keys::KEY_DOWN: (currMemCell >= 90) ? (currMemCell = currMemCell - 90) : (currMemCell += 10) ; return 0 ;case keys::KEY_LEFT: (!(currMemCell % 10)) ? (currMemCell += 9) : (currMemCell -= 1) ; return 0 ;}return -1 ;}int ui_setMCellValue(){printf("Set the value of the cell under the number \033[38;5;%dm0x%02X\033[0m\n", colors::SOFT_GREEN, currMemCell) ;printf("Enter value in \033[38;5;%dmHEX\033[0m format > ", colors::PEACH);char buffer[10] ;fgets(buffer, 10, stdin) ;if (buffer[strlen(buffer) - 1] != '\n')clearBuffIn(); // очистка потока вводаelsebuffer[strlen(buffer) - 1] = '\0' ;unsigned short int res = 0 ;int i ;if (buffer[0] == '+')i = 1 ;else{res |= (1 << 14) ;if (buffer[0] == '-') {i = 1 ;res |= (1 << 13) ;}elsei = 0 ;}if (!checkCorrectInputHEX(&buffer[i])){ui_messageOutput((char *)"Invalid input", colors::RED) ;return -1 ;}long int number ;char * tmp ;number = strtol(&buffer[i], &tmp, 16) ;if (buffer[0] == '+') { // Проверка на командуif ((number >> 8) > 0x7F){ui_messageOutput((char *)"The command cannot be more than 7 bits (0x7F)", colors::RED) ;return -1 ;}if ((number & 0xFF) > 0x7F){ui_messageOutput((char *)"The operand cannot be more than 7 bits (0x7F)", colors::RED) ;return -1 ;}unsigned short int value = 0;if (sc_commandEncode((unsigned short int)((number >> 8)), (unsigned short int)(number & 0xFF), &value))return -1 ;res |= value ;}else{if(number > 0x2000 or (number > 0x1FFF and buffer[0] != '-') ){ui_messageOutput((char *)"The valid range for the value of the number from -0x2000 to 0x1FFF inclusive", colors::RED) ;return -1 ;}if (buffer[0] == '-'){number = number + 1 ;if (!((number >> 13) & 1))res &= (1 << 13) ;}number &= 0x1FFF ;res |= number ;}if (sc_memorySet(currMemCell, res))return -1 ;return 0 ;}int ui_saveMemory(){char filename[102] ;printf("Saving file...\n") ;printf("Enter the file name to save > ");mt_setFGcolor(colors::SOFT_GREEN) ;fgets(filename, 102, stdin) ;mt_setDefaultColorSettings() ;if (filename[strlen(filename) - 1] != '\n'){printf("\033[38;5;%dmThe file name is too long. The length is trimmed to the first 100 characters.\033[0m\n", BLUE) ;clearBuffIn(); // очистка потока ввода}elsefilename[strlen(filename) - 1] = '\0' ;if (sc_memorySave(filename)){ui_messageOutput((char *)"Failed to save memory", colors::RED) ;return -1 ;}elseui_messageOutput((char *)"Successful save", colors::GREEN) ;return 0 ;}int ui_loadMemory(){char filename[102] ;printf("Loading file...\n") ;printf("Enter the file name to load > ");mt_setFGcolor(colors::SOFT_GREEN) ;fgets(filename, 102, stdin) ;mt_setDefaultColorSettings() ;if (filename[strlen(filename) - 1] != '\n'){ui_messageOutput((char *)"The name of the file to open is too long (up to 100 characters are allowed)", colors::BLUE) ;clearBuffIn(); // очистка потока вводаreturn -1 ;}filename[strlen(filename) - 1] = '\0' ;if (sc_memoryLoad(filename)){ui_messageOutput((char *)"Failed to load memory", colors::RED) ;return -1 ;}return 0 ;}int ui_setAccumulator(){// может ли в accumulator храниться команда ? (теперь нет)char buffer[10] ;printf("Set a value \033[38;5;%dm\"Accumulator\"\033[0m", colors::GREEN) ;printf("\nEnter value in \033[38;5;%dmHEX\033[0m format > ", colors::PEACH);fgets(buffer, 10, stdin) ;if (buffer[strlen(buffer) - 1] != '\n')clearBuffIn(); // очистка потока вводаelsebuffer[strlen(buffer) - 1] = '\0' ;unsigned short int res = 0 ;int i ;if (buffer[0] == '+'){ui_messageOutput((char *)"Invalid input", colors::RED) ;return -1 ;}else{res |= (1 << 14) ;if (buffer[0] == '-') {i = 1 ;res |= (1 << 13) ;}elsei = 0 ;}if (!checkCorrectInputHEX(&buffer[i])){ui_messageOutput((char *)"Invalid input", colors::RED) ;return -1 ;}long int number ;char * tmp ;number = strtol(&buffer[i], &tmp, 16) ;if (buffer[0] == '+') { // Проверка на командуif(number > 0x3FFF){ui_messageOutput((char *)"The command value must not exceed 14 bits (0x3FFF)", colors::RED) ;return -1 ;}else{number &= 0x3FFF ;if ((number >> 8) > 0x7F){ui_messageOutput((char *)"The command cannot be more than 7 bits (0x7F)", colors::RED) ;return -1 ;}if ((number & 0xFF) > 0x7F){ui_messageOutput((char *)"The operand cannot be more than 7 bits (0x7F)", colors::RED) ;return -1 ;}else{unsigned short int value = 0;if (sc_commandEncode((unsigned short int)((number >> 8)), (unsigned short int)(number & 0xFF), &value))return -1 ;res |= value ;}}}else{if(number > 0x2000 or (number > 0x1FFF and buffer[0] != '-') ){ui_messageOutput((char *)"The valid range for the value of the number from -0x2000 to 0x1FFF inclusive", colors::RED) ;return -1 ;}if (buffer[0] == '-'){number = number + 1 ;if (!((number >> 13) & 1))res &= (1 << 13) ;}number &= 0x1FFF ;res |= number ;}sc_accumulator = res ;return 0 ;}int ui_setICounter(){char buffer[10] ;printf("Set a value \033[38;5;%dm\"InstructionCounter\"\033[0m between \033[38;5;%dm00\033[0m and \033[38;5;%dm99\033[0m inclusive\n", colors::GREEN, colors::SOFT_GREEN, colors::SOFT_GREEN) ;printf("Enter value in \033[38;5;%dmDEC\033[0m format > ", colors::PEACH);fgets(buffer, 10, stdin) ;if (buffer[strlen(buffer) - 1] != '\n')clearBuffIn(); // очистка потока вводаelsebuffer[strlen(buffer) - 1] = '\0' ;if (!checkCorrectInputDEC(buffer)){ui_messageOutput((char *)"Invalid input", colors::RED) ;return -1 ;}long int number ;char * tmp ;number = strtol(buffer, &tmp, 10);if(number > 99){ui_messageOutput((char *)"The value must not exceed the amount of memory", colors::RED) ;return -1 ;}sc_instructionCounter = (uint8_t)number ;return 0 ;}/// Отрисовка "боксов"/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint drawingBoxes(){if (bc_box(1, 1, 61, 12)) // Окно Memoryreturn -1 ;if (bc_box(62, 1, 22, 3)) // Окно accumulatorreturn -1 ;if (bc_box(62, 4, 22, 3)) // Окно instructionCounterreturn -1 ;if (bc_box(62, 7, 22, 3)) // Окно Operationreturn -1 ;if (bc_box(62, 10, 22, 3)) // Окно Flagsreturn -1 ;if (bc_box(1, 13, 52, 10)) // Окно BigCharsreturn -1 ;if (bc_box(53, 13, 31, 10)) // Окно Keysreturn -1 ;return 0 ;}/// Отрисовка заголовков и текста/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint drawingTexts(){/* Заголовки */mt_gotoXY(30,1) ;printf(" Memory ") ;mt_gotoXY(66,1) ;printf(" accumulator ") ;mt_gotoXY(63,4) ;printf(" instructionCounter ") ;mt_gotoXY(67,7) ;printf(" Operation ") ;mt_gotoXY(69,10) ;printf(" Flags ") ;mt_gotoXY(54,13) ;printf(" Keys: ") ;/* HotKeys */char* hotK[] = {(char *)"l - load",(char *)"s - save",(char *)"r - run",(char *)"t - step",(char *)"i - reset",(char *)"F5 - accumulator",(char *)"F6 - instructionCounter"};for (int i = 0 ; i < sizeof(hotK) / sizeof(*hotK) ; ++i) {mt_gotoXY(54,i + 14) ;printf("%s", hotK[i]) ;}return 0 ;}/// Отрисовка памяти/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint drawingMemory(){for (int i = 0 ; i < 10 ; ++i)for (int j = 0 ; j < 10 ; ++j) {mt_gotoXY(2 + (5 * j + j), 2 + i) ;unsigned short int tmp ;sc_memoryGet(i * 10 + j, &tmp) ;if ((i * 10 + j) == currMemCell)mt_setBGcolor(colors::GREEN) ;if((tmp >> 14) & 1)if((tmp >> 13) & 1)printf("-%04X", ((tmp - 1)) & 0x3FFF) ;elseprintf(" %04X", tmp & 0x1FFF) ;elseprintf("+%04X", tmp) ;mt_setDefaultColorSettings() ;}return 0 ;}/// Отрисовка accumulator/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint drawingAccumulator(){mt_gotoXY(70,2) ;// bool over ;// sc_regGet(OVERFLOW, &over) ;// if (over){// mt_setFGcolor(colors::PEACH) ;// printf(" over") ;// mt_setDefaultColorSettings() ;// }// else{if((sc_accumulator >> 14) & 1)if((sc_accumulator >> 13) & 1)printf("-%04X", ((sc_accumulator - 1)) & 0x3FFF) ;elseprintf(" %04X", sc_accumulator & 0x1FFF) ;elseprintf("+%04X", sc_accumulator) ;// }return 0 ;}/// Отрисовка Operation/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint drawingOperation(){mt_gotoXY(69,8) ;unsigned short int tmp ;sc_memoryGet(currMemCell, &tmp) ;if(!((tmp >> 14) & 1)){unsigned short int operand, command ;sc_commandDecode(tmp, &command, &operand) ;printf("+%02X:%02X", command, operand) ;}else{unsigned short int left, right ;bool negative = (tmp >> 13) & 1 ;if(negative)tmp = ((tmp - 1)) & 0x3FFF ;elsetmp &= 0x1FFF ;left = tmp >> 8 ;right = tmp & 0xFF ;negative ? printf("-%02X:%02X", left, right) : printf(" %02X:%02X", left, right) ;}return 0 ;}/// Отрисовка instructionCounter/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint drawingInstructionCounter(){mt_gotoXY(71,5) ;// bool over, zero, out, comm ;// sc_regGet(OVERFLOW, &over) ;// sc_regGet(DIVISION_ERR_BY_ZERO, &zero) ;// sc_regGet(OUT_OF_MEMORY, &out) ;// sc_regGet(INCORRECT_COMMAND, &comm) ;// mt_gotoXY(71,5) ;// if (over || zero || out || comm){// mt_setFGcolor(colors::SOFT_GREEN) ;// printf("null") ;// mt_setDefaultColorSettings() ;// }// elseprintf("%04X", sc_instructionCounter) ;return 0 ;}/// Отрисовка флагов/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint drawingFlags(){char tmp[] = {'O', 'Z', 'M', 'I', 'C'};for (int i = 0 ; i < SC_REG_SIZE ; ++i) {bool value ;if (sc_regGet(i, &value))return -1 ;mt_gotoXY(68 + (i * 2), 11) ;if (value){mt_setFGcolor(colors::PEACH) ;printf("%c", tmp[i]) ;}else{mt_setFGcolor(colors::GRAY) ;printf("%c", tmp[i]) ;}mt_setDefaultColorSettings() ;}return 0 ;}/// Отрисовка "BigChar'ов"/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint drawingBigChar(){unsigned short int tmp ;sc_memoryGet(currMemCell, &tmp) ;if(!((tmp >> 14) & 1))bc_printBigChar(bc[16], 2, 14, GREEN) ;else if((tmp >> 13) & 1){bc_printBigChar(bc[17], 2, 14, GREEN) ;tmp = ((tmp - 1)) & 0x3FFF;}elsetmp &= 0x3FFF ;for (int i = 0; i < 4; ++i) {int ch = (tmp & ( 0xF << (4 * (3 - i)) )) >> (4 * (3 - i)) ;bc_printBigChar(bc[ch], 2 + 8 * (i + 1) + 2 * (i + 1), 14, GREEN) ;}return 0 ;}bool checkCorrectInputHEX(const char *buffer){if (strlen(buffer) == 0 or strlen(buffer) > 4)return false ;for (int i = 0 ; i < strlen(buffer) ; ++i)if (!(isxdigit(buffer[i])))return false ;return true ;}bool checkCorrectInputDEC(const char *buffer){if (strlen(buffer) == 0 or strlen(buffer) > 5)return false ;for (int i = 0 ; i < strlen(buffer) ; ++i)if (!(isdigit(buffer[i])))return false ;return true ;}int ui_messageOutput(char *str, enum colors color){printf("\033[38;5;%dm%s\033[0m", color, str) ;fflush(stdout) ; // очистка потока выводаchar buffer[5] = "\0" ;rk_myTermRegime(false, 0, 0, false, false) ;read(fileno(stdin), buffer, 5) ;return 0 ;}int clearBuffIn(){int c;do {c = getchar();} while (c != '\n' && c != '\0');return 0 ;}myReadkey.hpp#ifndef MYREADKEY_HPP#define MYREADKEY_HPP#include #include #include extern termios save;enum keys{KEY_L,KEY_S,KEY_R,KEY_T,KEY_I,KEY_F5,KEY_F6 ,KEY_UP,KEY_DOWN,KEY_RIGHT,KEY_LEFT,KEY_ESC,KEY_ENTER,KEY_OTHER,};int rk_readKey(enum keys *key) ;int rk_myTermSave() ;int rk_myTermRestore() ;int rk_myTermRegime (bool regime, unsigned int vtime, unsigned int vmin, bool echo, bool sigint) ;#endif //MYREADKEY_HPPmyReadkey.cpp#include "myReadkey.hpp"termios save;/// Возвращающую первую клавишу, которую нажал пользователь/// \param key - Адрес переменной, в которую возвращается номер нажатой клавиши/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint rk_readKey (enum keys * key){fflush(stdout) ; // очистка потока выводаchar buffer[5] = "\0" ;rk_myTermRegime(false, 0, 0, false, false) ;read(fileno(stdin), buffer, 5) ;rk_myTermRestore() ;if (buffer[0] == '\033')if (buffer[1] == '\0')*key = KEY_ESC ;else if (buffer[1] == '[')if (buffer[2] == 'A' and buffer[3] == '\0')*key = KEY_UP ;else if (buffer[2] == 'B' and buffer[3] == '\0')*key = KEY_DOWN ;else if (buffer[2] == 'C' and buffer[3] == '\0')*key = KEY_RIGHT ;else if (buffer[2] == 'D' and buffer[3] == '\0')*key = KEY_LEFT ;else if (buffer[2] == '1' and buffer[3] == '5')*key = KEY_F5 ;else if (buffer[2] == '1' and buffer[3] == '7')*key = KEY_F6 ;else*key = KEY_OTHER ;else*key = KEY_OTHER ;else if (buffer[0] == '\n' and buffer[1] == '\0')*key = KEY_ENTER ;elseif ((buffer[0] == 'l' or buffer[0] == 'L') and buffer[1] == '\0')*key = KEY_L ;else if ((buffer[0] == 's' or buffer[0] == 'S') and buffer[1] == '\0')*key = KEY_S ;else if ((buffer[0] == 'r' or buffer[0] == 'R') and buffer[1] == '\0')*key = KEY_R ;else if ((buffer[0] == 't' or buffer[0] == 'T') and buffer[1] == '\0')*key = KEY_T ;else if ((buffer[0] == 'i' or buffer[0] == 'I') and buffer[1] == '\0')*key = KEY_I ;else*key = KEY_OTHER ;return 0 ;}/// Функция, сохраняющая текущие параметры терминала/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint rk_myTermSave(){if (tcgetattr(fileno(stdin), &save))return -1 ;return 0 ;}/// Функция, восстанавливающая сохраненные параметры терминала/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint rk_myTermRestore(){tcsetattr(fileno(stdin), TCSAFLUSH, &save) ;return 0 ;}/// Функция, переключающая режим работы терминала (канонический / неканонический)/// \param regime/// \param vtime/// \param vmin/// \param echo/// \param sigint/// \return 0 - в случае успешного выполнения, -1 - в случае ошибкиint rk_myTermRegime(bool regime, unsigned int vtime, unsigned int vmin, bool echo, bool sigint){termios curr{} ;tcgetattr(fileno(stdin), &curr) ;if(regime)curr.c_lflag |= ICANON ;else{curr.c_lflag &= ICANON ;sigint ? (curr.c_lflag |= ISIG) : (curr.c_lflag &= ISIG) ;echo ? (curr.c_lflag |= ECHO) : (curr.c_lflag &= ECHO) ;curr.c_cc[VMIN] = vmin ;curr.c_cc[VTIME] = vtime ;}tcsetattr(0,TCSAFLUSH,&curr) ;return 0 ;}commands.hpp#ifndef COMMANDS_HPP#define COMMANDS_HPP#define READ 0x10#define WRITE 0x11#define LOAD 0x20#define STORE 0x21#define ADD 0x30#define SUB 0x31#define DIVIDE 0x32#define MUL 0x33#define JUMP 0x40#define JNEG 0x41#define JZ 0x42#define HALT 0x43#define RCR 0x63#endif //COMMANDS_HPPmyCU.hpp#ifndef CU_HPP#define CU_HPP#include "commands.hpp"#include "simpleComputer.hpp"#include "myTerm.hpp"#include "myUI.hpp"#include "myALU.hpp"int CU() ;#endif //CU_HPPmyCU.cpp#include "myCU.hpp"int cu_read(unsigned short int operand) ;int cu_write(unsigned short int operand) ;int cu_load(unsigned short int operand) ;int cu_store(unsigned short int operand) ;int cu_jump(unsigned short int operand) ;int cu_jneg(unsigned short int operand) ;int cu_jz(unsigned short int operand) ;int CU (){unsigned short int command = 0;unsigned short int operand = 0;unsigned short int currCell;sc_memoryGet(sc_instructionCounter, &currCell) ;if (sc_commandDecode(currCell, &command, &operand)){return -1 ;}switch (command) {case READ:if (cu_read(operand))return -1 ;elsesc_instructionCounter++ ;break ;case WRITE:if (cu_write(operand))return -1 ;elsesc_instructionCounter++ ;break ;case LOAD :if (cu_load(operand))return -1 ;elsesc_instructionCounter++ ;break ;case STORE :if (cu_store(operand))return -1 ;elsesc_instructionCounter++ ;break ;case JUMP :if (cu_jump(operand))return -1 ;break ;case JNEG :if (cu_jneg(operand))return -1 ;break ;case JZ :if (cu_jz(operand))return -1 ;break ;case HALT :return -1 ;break ;default:if (ALU(command, operand))return -1 ;break ;}return 0 ;}int cu_read(unsigned short int operand){rk_myTermRestore() ;printf("Enter value of cell[\033[38;5;%dm0x%02X\033[0m] in \033[38;5;%dmHEX\033[0m format > ", colors::SOFT_GREEN, operand, colors::PEACH) ;char buffer[10] ;fgets(buffer, 10, stdin) ;if (buffer[strlen(buffer) - 1] != '\n')clearBuffIn(); // очистка потока вводаelsebuffer[strlen(buffer) - 1] = '\0' ;rk_myTermRegime(false, 0, 0, false, false) ;unsigned short int res = 0 ;int i ;if (buffer[0] == '+' or buffer[0] == '-')i = 1 ;else{res |= (1 << 14) ;(buffer[0] == '-') ? (res |= (1 << 13)) : i = 0 ;}if (!checkCorrectInputHEX(&buffer[i])){res |= (1 << 15) ;}else{long int number ;char * tmp ;number = strtol(&buffer[i], &tmp, 16) ;if (buffer[0] == '+') { // Проверка на командуif (number > 0x3FFF)res |= (1 << 15) ;else{number &= 0x3FFF ;unsigned short int value = 0;if (sc_commandEncode((unsigned short int)((number >> 8)), (unsigned short int)(number & 0xFF), &value)){res |= (1 << 15) ;}elseres |= value ;}}else{if (number > 0x2000 or (number > 0x1FFF and buffer[0] != '-') ){res |= (1 << 15) ;}if (buffer[0] == '-'){number = number + 1 ;if (!((number >> 13) & 1))res &= (1 << 13) ;}number &= 0x1FFF ;res |= number ;}}if (sc_memorySet(operand, (unsigned short int)res))return -1 ;return 0 ;}int cu_write(unsigned short int operand){unsigned short int value;if(sc_memoryGet(operand, &value)){return -1 ;}printf("Value in a cell [\033[38;5;%dm0x%02X\033[0m] < ", colors::SOFT_GREEN, operand) ;if ((value >> 14) & 1)if ((value >> 13) & 1)printf("-%04X", ((value - 1)) & 0x3FFF) ;elseprintf(" %04X", value & 0x1FFF) ;elseprintf("+%04X", value) ;getchar() ;return 0 ;}int cu_load(unsigned short int operand){unsigned short int value;if (sc_memoryGet(operand, &value)){return -1 ;}if (!((value >> 14) & 1)){sc_regSet(INCORRECT_COMMAND, true) ;return - 1;}sc_accumulator = value ;return 0 ;}int cu_store(unsigned short int operand){if (sc_memorySet(operand, sc_accumulator))return -1 ;return 0 ;}int cu_jump(unsigned short int operand){if (operand > 0x63){sc_regSet(OUT_OF_MEMORY, true) ;return -1 ;}sc_instructionCounter = operand ;return 0 ;}int cu_jneg(unsigned short int operand){if (((sc_accumulator >> 14) & 1) and ((sc_accumulator >> 13) & 1)){if (operand > 0x63){sc_regSet(OUT_OF_MEMORY, true) ;return -1 ;}sc_instructionCounter = operand ;}elsesc_instructionCounter++ ;return 0 ;}int cu_jz(unsigned short int operand){if (((sc_accumulator >> 14) & 1) and ((sc_accumulator & 0x3FFF) == 0)){if (operand > 0x63){sc_regSet(OUT_OF_MEMORY, true) ;return -1 ;}sc_instructionCounter = operand ;}elsesc_instructionCounter++ ;return 0 ;}myALU.hpp#ifndef MYALU_HPP#define MYALU_HPP#include "commands.hpp"#include "simpleComputer.hpp"#include "myTerm.hpp"#include "myUI.hpp"int ALU(unsigned short int command, unsigned short int operand) ;#endif //MYALU_HPP myALU.cpp#include "myALU.hpp"int alu_add(unsigned short int value) ;int alu_divide(unsigned short int operand) ;int alu_mul(unsigned short int operand) ;int alu_rcr(unsigned short int operand) ;int ALU(unsigned short int command, unsigned short int operand){unsigned short int value ;switch (command) {case ADD:if (sc_memoryGet(operand, &value))return -1 ;if (!((value >> 14) & 1)){sc_regSet(INCORRECT_COMMAND, true) ;return -1 ;}if (alu_add(value))return -1 ;elsesc_instructionCounter++ ;break ;case SUB:if (sc_memoryGet(operand, &value))return -1 ;if (!((value >> 14) & 1)){sc_regSet(INCORRECT_COMMAND, true) ;return -1 ;}if ((value >> 13) & 1) // Отрицательноеvalue = ((value & 0x3FFF) - 1) ;elsevalue = ((value & 0x3FFF)) + 1 ;value &= 0x3FFF ;value |= (1 << 14) ;if (alu_add(value))return -1 ;elsesc_instructionCounter++ ;break ;case DIVIDE:if (alu_divide(operand))return -1 ;elsesc_instructionCounter++ ;break ;case MUL:if (alu_mul(operand))return -1 ;elsesc_instructionCounter++ ;break ;case RCR:if (alu_rcr(operand))return -1 ;elsesc_instructionCounter++ ;break ;default:sc_regSet(INCORRECT_COMMAND, true) ;return -1 ;}return 0 ;}int alu_add(unsigned short int value){unsigned short int accumulator, res;accumulator = sc_accumulator & 0x3FFF ;value &= 0x3FFF;if (((accumulator >> 13) & 1) and ((value >> 13) & 1)){ // Если оба отрицательныvalue = (value - 1) & 0x3FFF ;accumulator = (accumulator - 1) & 0x3FFF ;res = accumulator + value;if (res > 0x2000){sc_regSet(OVERFLOW, true) ;}res = res + 1 ;}else if (((accumulator >> 13) & 1) or ((value >> 13) & 1)) { // Если одно из чисел отрицательноres = accumulator + value ;}else{res = accumulator + value ;if (res > 0x1FFF){sc_regSet(OVERFLOW, true) ;}}res |= (1 << 14) ;sc_accumulator = res ;return 0 ;}int alu_divide(unsigned short int operand){unsigned short int value,accumulator, res ;if (sc_memoryGet(operand, &value))return -1 ;if (!((value >> 14) & 1)){sc_regSet(INCORRECT_COMMAND, true) ;return -1 ;}bool negative = 0 ;accumulator = sc_accumulator & 0x3FFF ;value &= 0x3FFF;if ((accumulator >> 13) & 1){negative = !negative ;accumulator = (accumulator - 1);}accumulator &= 0x3FFF ;if ((value >> 13) & 1){negative = !negative ;value = (value - 1);}value &= 0x3FFF ;if (value == 0){sc_regSet(DIVISION_ERR_BY_ZERO, true) ;return -1 ;}res = accumulator / value ;if (negative){if (res > 0x2000){sc_regSet(OVERFLOW, true) ;}res = (res + 1) & 0x3FFF ;res |= (1 << 14) ;sc_accumulator = res ;}else {if (res > 0x1FFF){sc_regSet(OVERFLOW, true) ;}res |= (1 << 14) ;sc_accumulator = res ;}return 0 ;}int alu_mul(unsigned short int operand){unsigned short int value,accumulator, res ;if (sc_memoryGet(operand, &value))return -1 ;if (!((value >> 14) & 1)){sc_regSet(INCORRECT_COMMAND, true) ;return -1 ;}bool negative = 0 ;accumulator = sc_accumulator & 0x3FFF ;value &= 0x3FFF;if ((accumulator >> 13) & 1){negative = !negative ;accumulator = (accumulator - 1);}accumulator &= 0x1FFF ;if ((value >> 13) & 1){negative = !negative ;value = (value - 1);}value &= 0x1FFF ;res = accumulator * value ;if (negative){if (res > 0x2000){sc_regSet(OVERFLOW, true) ;}res = (res + 1) & 0x3FFF ;res |= (1 << 14) ;sc_accumulator = res ;}else {if (res > 0x1FFF){sc_regSet(OVERFLOW, true) ;}res |= (1 << 14) ;sc_accumulator = res ;}return 0 ;}int alu_rcr(unsigned short int operand){unsigned short int res, value ;if (sc_memoryGet(operand, &value))return -1 ;if (!((value >> 14) & 1)){sc_regSet(INCORRECT_COMMAND, true) ;return -1 ;}bool negative = (value >> 13) & 1;if (negative) // Отрицательноеvalue = (value - 1) & 0x3FFF ;elsevalue &= 0x1FFF ;res = (value>> 1) | ((value & 1) << 12) ;if (negative){if (res > 0x2000)sc_regSet(OVERFLOW, true) ;res = (

SimpleAssembler main.cppconst short int MEM_SIZE = 100 ;unsigned short int memory[MEM_SIZE] {0};#include #include #include #include #include "commands.hpp"int readFile(FILE * fb) ;int commandEncode(unsigned short int command, unsigned short int operand, unsigned short int * value) ; bool checkCorrectInputHEX(const char *buffer) ;int main(int argc, char const *argv[]){if (argc != 3) { printf("\033[38;5;196mThe number of arguments does not match the condition!\033[0m \nThe translator launch command must look like: simpleAssembler file.sa file.o, where file.sa – name of the file that contains the program in Simple Assembler, file. o-translation result\n") ; return -1 ; }if (strcmp(strrchr(argv[1], '.'), ".sa") != 0) { printf("\033[38;5;196mThe extension of the first argument, \"%s\", does not match the conditions\033[0m \nThe translator launch command must look like: simpleAssembler file.sa file.o, where file.sa – name of the file that contains the program in Simple Assembler, file. o-translation result\n", argv[1]) ; return -1 ; }if (strcmp(strrchr(argv[2], '.'), ".o") != 0) { printf("\033[38;5;196mThe extension of the second argument, \"%s\", does not match the conditions\033[0m \nThe translator launch command must look like: simpleAssembler file.sa file.o, where file.sa – name of the file that contains the program in Simple Assembler, file. o-translation result\n", argv[2]) ; return -1 ; }FILE * fb ;if (!(fb = fopen(argv[1], "r"))){printf("\033[38;5;196mUnable to open the \"%s\" file. \033[0m \nCheck whether the file is in the directory, as well as access rights.\n", argv[1]) ;return -1 ;}if (readFile(fb))return -1 ;fclose(fb) ;if (!(fb = fopen(argv[2], "wb"))){printf("\033[38;5;196mUnable to open the \"%s\" file. \033[0m \nCheck your access rights.\n", argv[2]) ;return -1 ;}fwrite(memory, sizeof(memory), 1, fb) ;fclose(fb) ;return 0 ;}int readFile(FILE * fb){char buffer[256] ;short int prevCell = -1, currCell ;unsigned short int currLine = 1, comm = 0, op = 0, res;char *part, *strCell; while (fgets(buffer, 256, fb)) {/* Часть с адресом ячейки */part = strtok (buffer, " ") ;if (strlen(part) != 2){printf("\033[38;5;196mError | line %d\033[0m \nThe cell address number must be 2 characters long.\n", currLine) ;return -1 ;}for (int i = 0 ; i < 2 ; ++i){if (part[i] < '0' || part[i] > '9'){printf("\033[38;5;196mError | line %d\033[0m \nThe cell number cannot consist of letters. The cell number must be entered in the 10 number system.\n", currLine) ;return -1 ;}}currCell = atoi(part);if (currCell <= prevCell){printf("\033[38;5;196mError | line %d\033[0m \nThe number of the memory address must be increasing and must not be repeated.\n", currLine) ;return -1 ;}elseprevCell = currCell ; /* Часть с командой */part = strtok (NULL, " ");if (strcmp(part, "READ") == 0)comm = READ;else if (strcmp(part, "WRITE") == 0)comm = WRITE;else if (strcmp(part, "LOAD") == 0)comm = LOAD;else if (strcmp(part, "STORE") == 0)comm = STORE;else if (strcmp(part, "ADD") == 0)comm = ADD;else if (strcmp(part, "SUB") == 0)comm = SUB;else if (strcmp(part, "DIVIDE") == 0)comm = DIVIDE;else if (strcmp(part, "MUL") == 0)comm = MUL;else if (strcmp(part, "JUMP") == 0)comm = JUMP;else if (strcmp(part, "JNEG") == 0)comm = JNEG;else if (strcmp(part, "JZ") == 0)comm = JZ;else if (strcmp(part, "HALT") == 0)comm = HALT;else if (strcmp(part, "RCR") == 0)comm = RCR;else if (strcmp(part, "=") == 0)comm = 0 ;else{printf("\033[38;5;196mError | line %d\033[0m \nUnknown command\n", currLine) ;return -1 ;}/* Часть с операндом */part = strtok (NULL, " ");if (part[strlen(part) - 1] == '\n') part[strlen(part) - 1] = '\0' ;if (comm != 0){ // Если не присваивание for (int i = 0 ; i < strlen(part) ; ++i)if (part[i] < '0' || part[i] > '9'){printf("\033[38;5;196mError | line %d\033[0m \nThe operand cannot contain letters. The operand must be set in the 10 number system.\n", currLine) ;return -1 ;}op = atoi(part) ;if (commandEncode((unsigned short int)((comm & 0xFF)), (unsigned short int)(op & 0xFF), &res)){printf("\033[38;5;196mError | line %d\033[0m \nInvalid command, the command cannot exceed 3FFF.\n", currLine) ;return -1 ;}}else{res = 0 ;int i = 0;if (part[0] == '+')i = 1 ;else{res |= (1 << 14) ;if (part[0] == '-') {i = 1 ;res |= (1 << 13) ;}elsei = 0 ;}if (!checkCorrectInputHEX(&part[i])){printf("\033[38;5;196mError | line %d\033[0m \nIncorrect assignment.\n", currLine) ;return -1 ;}long int number ;char * tmp ;number = strtol(&part[i], &tmp, 16) ;if (part[0] == '+') { // Если командаif ((number >> 8) > 0x7F){printf("\033[38;5;196mError | line %d\033[0m \nThe command cannot be more than 7 bits (0x7F).\n", currLine) ;return -1 ;}if ((number & 0xFF) > 0x7F){printf("\033[38;5;196mError | line %d\033[0m \nThe operand cannot be more than 7 bits (0x7F).\n", currLine) ;return -1 ;}unsigned short int value = 0;commandEncode((unsigned short int)((number >> 8)), (unsigned short int)(number & 0xFF), &value) ;res |= value ;}else { // Если числоif(number > 0x2000 or (number > 0x1FFF and part[0] != '-') ){printf("\033[38;5;196mError | line %d\033[0m \nThe valid range for the value of the number from -0x2000 to 0x1FFF inclusive.\n", currLine) ;return -1 ;}if (part[0] == '-') {number = number + 1 ;if (!((number >> 13) & 1))res &=

SimpleBasic


Федеральное агентство связи

Федеральное государственное бюджетное образовательное учреждение высшего образования «Сибирский государственный университет телекоммуникаций и информатики»

Кафедра Вычислительных Систем

Курсовая работа

по дисциплине «Архитектура ЭВМ»

Вариант - 13

Выполнил: студент 2 курса гр. ИП-017 Горбань Д.В

Проверил: Доцент кафедры ВС Майданов Ю.С.


Оглавление




Постановка задачи 3

Обработка команд центральным процессором 3

Транслятор с языка Simple Assembler 3

Транслятор с языка Simple Basic 4

Архитектура simpleComputer 6

Оперативная память 6

Внешние устройства 6

Центральный процессор 7

Система команд Simple Computer 8

Выполнение команд центральным процессором Simple Computer 8

Консоль управления 8

Блок-схемы 10

SimpleComputer 10

SimpleAssembler 11

SimpleBasic 12

Результаты проведенного исследования 13

Примеры работы программы 14

Приложение. Листинг 19

Makefile 19

SimpleComputer 21

SimpleAssembler 58

SimpleBasic 64


Постановка задачи


В рамках курсовой работы необходимо доработать модель Simple Computer так, чтобы она обрабатывала команды, записанные в оперативной памяти. Система команд представлена в таблице 1. Из пользовательских функций необходимо реализовать только одну согласно варианту задания. Для разработки программ требуется создать трансляторы с языков Simple Assembler и Simple Basic.

Обработка команд центральным процессором


Для выполнения программ моделью Simple Computer необходимо реализовать две функции:

  • int ALU (int command, int operand) - реализует алгоритм работы арифметико-логического устройства. Если при выполнении функции возникла ошибка, которая не позволяет дальше выполнять программу, то функция возвращает -1, иво всех остальных случаях - 0;

  • void CU () - обеспечивает работу устройства управления. Обработку команд осуществляет устройство управления. Функция CU вызывается либо обработчиком сигнала от системного таймера, если не установлен флаг «игнорирование тактовых импульсов», либо при нажатии на клавишу t. Алгоритм работы функции, следующий:

  1. из оперативной памяти считывается ячейка, адрес которой хранится в регистре instructionCounter;

  2. полученное значение декодируется как команда;

  3. если декодирование невозможно, то устанавливаются флаги «указана неверная команда» и «игнорирование тактовых импульсов» (системный таймер можно отключить) и работа функции прекращается.

  4. Если получена арифметическая или логическая операция, то вызывается функция ALU, иначе команда выполняется самим устройством управления.

  5. Определяется, какая команда должна быть выполнена следующей и адрес её ячейки памяти заносится в регистр instructionCounter.

  6. Работа функции завершается.



Транслятор с языка Simple Assembler


Разработка программ для Simple Computer может осуществляться с использованием низкоуровневого языка Simple Assembler. Для того чтобы программа могла быть обработана Simple Computer необходимо реализовать транслятор, переводящий текст Simple Assembler в бинарный формат, которым может быть считан консолью управления.

Пример программы на Simple Assembler:

00 READ 09 ; (Ввод А)

01 READ 10 ; (Ввод В)

02 LOAD 09 ; (Загрузка А в аккумулятор)

03 SUB 10 ; (Отнять В)

04 JNEG 07 ; (Переход на 07, если отрицательное)

05 WRITE 09 ; (Вывод А)

06 HALT 00 ; (Останов)

07 WRITE 10 ; (Вывод В)

08 HALT 00 ; (Останов)

09 = +0000 ; (Переменная А)

10 = +9999 ; (Переменная В)

Программа транслируется по строкам, задающим значение одной ячейки памяти. Каждая строка состоит как минимум из трех полей: адрес ячейки памяти, команда (символьное обозначение), операнд. Четвертым полем может быть указан комментарий, который обязательно должен начинаться с символа точка с запятой. Название команд представлено в таблице 1. Дополнительно используется команда =, которая явно задает значение ячейки памяти в формате вывода его на экран консоли (+XXXX).

Команда запуска транслятора должна иметь вид: sat файл.sa файл.o, где файл.sa - имя файла, в котором содержится программа на Simple Assembler, файл.o - результат трансляции.

Транслятор с языка Simple Basic


Для упрощения программирования пользователю модели Simple Computer должен быть предоставлен транслятор с высокоуровневого языка Simple Basic. Файл, содержащий программу на Simple Basic, преобразуется в файл с кодом Simple Assembler. Затем Simple Assembler-файл транслируется в бинарный формат. В языке Simple Basic используются следующие операторы: REM, INPUT, PRINT, GOTO, IF, LET, END.

Пример программы на Simple Basic:

10 REM Это комментарий

20 INPUT A

30 INPUT B

40 LET C = A – B

50 IF C < 0 GOTO 20

60 PRINT C

70 END

Каждая строка программы состоит из номера строки, оператора Simple Basic и параметров. Номера строк должны следовать в возрастающем порядке. Все команды за исключением команды конца программы могут встречаться в программе многократно. Simple Basic должен оперировать с целыми выражениями, включающими операции +, -, *, и /. Приоритет операций аналогичен стандартным правилам математики. Для того чтобы изменить порядок вычисления, можно использовать скобки.

Транслятор должен распознавания только букв верхнего регистра, то есть все символы в программе на Simple Basic должны быть набраны в верхнем регистре (символ нижнего регистра приведет к ошибке). Имя переменной может состоять только из одной буквы. Simple Basic оперирует только с целыми значениями переменных, в нем отсутствует объявление переменных, а упоминание переменной автоматически вызывает ее объявление и присваивает ей нулевое значение. Синтаксис языка не позволяет выполнять операций со строками.


Архитектура simpleComputer


Архитектура Simple Computer представлена на рисунке 1 и включает следующие функциональные блоки:

  • оперативную память;

  • внешние устройства;

  • центральный процессор.



Рисунок 1 – Архитектуравычислительной машины Simple Computer

Оперативная память


Оперативная память – это часть Simple Computer, где хранятся программа и данные. Память состоит из ячеек (массив), каждая из которых хранит 15 двоичных разрядов. Ячейка – минимальная единица, к которой можно обращаться при доступе к памяти. Все ячейки последовательно пронумерованы целыми числами. Номер ячейки является её адресом и задается 7-миразрядным числом. Предполагаем, что Simple Computer оборудован памятью из 100 ячеек (с адресами от 0 до 99
10).

Внешние устройства


Внешние устройства включают: клавиатуру и монитор, используемые для взаимодействия с пользователем, системный таймер, задающий такты работы Simple Computer и кнопку «Reset», позволяющую сбросить Simple Computer в исходное состояние.

Центральный процессор


Выполнение программ осуществляется центральным процессором Simple Computer. Процессор состоит из следующих функциональных блоков:

регистры (аккумулятор, счетчик команд, регистр флагов);

  • арифметико-логическое устройство (АЛУ);

  • управляющее устройство (УУ);

  • обработчик прерываний от внешних устройств (ОП);

  • интерфейс доступа к оперативной памяти.

Регистры являются внутренней памятью процессора. Центральный процессор Simple Computer имеет: аккумулятор, используемый для временного хранения данных и результатов операций, счетчик команд, указывающий на адрес ячейки памяти, в которой хранится текущая выполняемая команда и регистр флагов, сигнализирующий об определённых событиях. Аккумулятор имеет разрядность 15 бит, счетчика команд – 7 бит. Регистр флагов содержит 5 разрядов: переполнение при выполнении операции, ошибка деления на 0, ошибка выхода за границы памяти, игнорирование тактовых импульсов, указана неверная команда.

Арифметико-логическое устройство (англ. arithmetic and logic unit, ALU) — блок процессора, который служит для выполнения логических и арифметических преобразований над данными. В качестве данных могут использоваться значения, находящиеся в аккумуляторе, заданные в операнде команды или хранящиеся в оперативной памяти. Результат выполнения операции сохраняется в аккумуляторе или может помещаться в оперативную память. В ходе выполнения операций АЛУ устанавливает значения флагов «деление на 0» и «переполнение».

Управляющее устройство (англ. control unit, CU) координирует работу центрального процессора. По сути, именно это устройство отвечает за выполнение программы, записанной в оперативной памяти. В его функции входит: чтение текущей команды из памяти, её декодирование, передача номера команды и операнда в АЛУ, определение следующей выполняемой команды и реализации взаимодействий с клавиатурой и монитором. Выбор очередной команды из оперативной памяти производится по сигналу от системного таймера. Если установлен флаг «игнорирование тактовых импульсов», то эти сигналы устройством управления игнорируются. В ходе выполнения операций устройство управления устанавливает значения флагов «указана неверная команда» и «игнорирование тактовых импульсов».


Обработчик прерываний реагирует на сигналы от системного таймера и кнопки «Reset». При поступлении сигнала от кнопки «Reset» состояние процессора сбрасывается в начальное (значения всех регистров обнуляется и устанавливается флаг «игнорирование сигналов от таймера»). При поступлении сигнала от системного таймера, работать начинает устройство управления.