Я программист, но обычно разрабатывал какие-то простые вещи, разработка которых мне уже надоела. Я давно мечтаю о том, как бы научиться электронике, и строить разные схемы. Но я не работаю, и пенсия по инвалидности не такая большая, чтобы я мог себе позволить заниматься электроникой, для этого нужны деньги. Просто так получиться только в программе строить схемы, и нужно продвигать своё обучение в том, что я уже умею.
Так как меня привлекает электроника, то мне бы хотелось спуститься на низкий уровень кодинга, и пока-что учиться писать код для железа. Пока я этим не занялся.
Давным давно я вынашивал план создать 3d игру, где программист то ли на космической станции, то ли на дне океана на станции, ходит с отладчиком и взламывает устройства, и возможно за ним ещё монстр охотиться, и надо в страхе побыстрее что-то сделать и спрятаться в шкаф. 🙂
Начитавшись некоторых книг, у меня начал немного проясняться сюжет игры. Сначала я хотел сделать игру про 80-е в Америке. Для этого я задумал сделать свою операционную систему, компилятор и разные программы. Уже насоздавал некоторые модели в blender, скачал документацию по i386, распечатал, и начал изучать. В этой документации ещё предлагалось почитать руководство по системному программированию для i386. Я скачал, сходил в салон, мне сделали книгу-брошуру.
Первоначальная цель была делать ОС, эмулятор и компилятор. Я понимал, что просто так сложно будет за это взяться, так как эмоциональный интеллект у взрослого человека требует какое разумное объяснение тому, чем ты должен заниматься. Поэтому создание ОС, эмулятора и компилятора я решил делать в рамках игры. Так общественность бы не сильно давило вопросами, — зачем это нужно. Да и мне эмоции подсказывают, что это правильное решение.
Читая документацию по i386, я вновь вспомнил о таких понятиях как задача, что есть специальный транслятор виртуальной памяти, который для программиста прозрачен (если я правильно помню). И только читая неделю, я понял, что мне не нужно сразу делать такой сложный эмулятор процессора, я просто сломаюсь. Нужно брать что-то попроще и делать. И так пришло решение делать свою архитектуру процессора, немного поглядывая на 8086 и процессор, который использовался в NES, 8-битный.
Я вдохновился! Сделаю более простую архитектуру эмулятора, я смогу сделать более быстрый эмулятор, так как будет требоваться меньше работы. Читая про операционные системы, я узнал, что раньше вместо ОС были так называемые мониторы. Я подумал, что может быть даже сделаю тоже монитор, а не ОС, посмотрим.
Также купив книгу по операционным системам, я также купил книгу crafting interpreters, но английский в ней для меня чуть более сложноват оказался, я понимаю только некоторые формулировки, которых вроде бы достаточно. В данный момент я не читаю ни по ОС, ни по компиляторам.
Когда я только прочитал первую и вторую главу по компиляторам, я подумал, что попробую сначала сам сделать компилятор ассемблера. Если не получиться, то буду читать.
Первая версия получилась неудобной и невозможной для поддерживания, я удалил код. Подумав над ошибками, я сделал более лучший вариант компилятора, который до сих пор делаю. Он умеет работать с метками, понимает команды, требует указывать размер для [BX + SI]. У меня свой байткод. Я решил не делать как в i386 некоторые двухбайтные операнды, каждый операнд один байт имеет плюс его разновидность. На всякий случай оставил один байт для расширения как это делается в i386, в i386 байт 0x66 служит тому, что вместо AX будет EAX. Так называемый префикс байт (если я правильно выражаюсь).
Сначала я делал компилятор вместе с эмулятором, но в последнии дни я занимаюсь только компилятором. У меня был ужасный код, я его привёл чуточку в порядок. Я понимаю, что хакеры компиляторов на многие годы усовершенствовали свой код так, что его трудно понять. Мой же код пока простой и я не могу придумать что-то более сложное и крутое. Например для описания опкодов команд я сделал так.
#define BEGIN_STRUCT_OPCODE_DEFINE() \ 14 static struct asm_code asm_code[] = { 15 16 #define END_STRUCT_OPCODE_DEFINE() \ 17 }; 18 19 #define ADD_OPCODE(lbl, level, req) \ 20 {#lbl, level, lbl, req}, 21 22 struct asm_code { 23 char *label; 24 uint8_t level_rm; 25 uint8_t opcode; 26 uint8_t req_ops; 27 }; 28 29 BEGIN_STRUCT_OPCODE_DEFINE () 30 ADD_OPCODE (INT, IMM8, 1) 31 ADD_OPCODE (ADD, RM_IMM_2, 2) 32 ADD_OPCODE (SUB, RM_IMM_2, 2) 33 ADD_OPCODE (XCHG, RM_RM_2, 2) 34 ADD_OPCODE (MOV, RM_IMM_2, 2) 35 ADD_OPCODE (MUL, RM_1, 1) 36 ADD_OPCODE (DIV, RM_1, 1) 37 ADD_OPCODE (INC, RM_1, 1) 38 ADD_OPCODE (DEC, RM_1, 1) 39 ADD_OPCODE (AND, RM_IMM_2, 2) 40 ADD_OPCODE (OR, RM_IMM_2, 2) 41 ADD_OPCODE (CLI, VOID, 0) 42 ADD_OPCODE (STI, VOID, 0) 43 ADD_OPCODE (CMP, RM_IMM_2, 2) 44 ADD_OPCODE (XOR, RM_IMM_2, 2) 45 ADD_OPCODE (CLC, VOID, 0) 46 ADD_OPCODE (STC, VOID, 0) 47 ADD_OPCODE (CLD, VOID, 0) 48 ADD_OPCODE (STD, VOID, 0) 49 ADD_OPCODE (SAL, RM_R_IMM_2, 2) 50 ADD_OPCODE (SAR, RM_R_IMM_2, 2) 51 ADD_OPCODE (SHL, RM_R_IMM_2, 2) 52 ADD_OPCODE (SHR, RM_R_IMM_2, 2) 53 ADD_OPCODE (IN, AX_R_IMM_2, 2) 54 ADD_OPCODE (OUT, IMM_R_AX_2, 2) 55 ADD_OPCODE (PUSHA, VOID, 0) 56 ADD_OPCODE (PUSHF, VOID, 0) 57 ADD_OPCODE (POPA, VOID, 0) 58 ADD_OPCODE (POPF, VOID, 0) 59 ADD_OPCODE (PUSH, RM_R_IMM_1, 1) 60 ADD_OPCODE (POP, RM_1, 1) 61 ADD_OPCODE (NEG, RM_1, 1) 62 END_STRUCT_OPCODE_DEFINE () 63 64 static uint32_t size_asm_code = sizeof (asm_code) / sizeof (asm_code[0]);
Да, я пробовал читать чужой код компиляторов, но совсем чуть-чуть, просто я не понимал вообще ничего тогда, и решил, что буду развиваться самостоятельно.
Продумывая эту игру про космос я придумал мини игру по военной симуляции. Эта идея ошеломила меня. Я подумал, а неплохо бы её выделить в отдельную игру, как раз протестирую компилятор с эмулятором.
Идея игры заключается в том, что нам нужно разработать код прошивки для каждого юнита и здания. Писать нужно на ассемблере 16-битном. Я подготовил картинки как будут выглядеть юниты.
Коллектор:
Коллектор собирает жидкость из под земли, которая требуется для производства юнитов и сборки зданий.
Сканер:
Сканер может перехватывать данные в радиусе нескольких клеток и сообщать оператору. Оператор, это мы. Мы следим за ходом действий и можем вмешиваться. Например, если сканер перехватил команды от командного центра к танку, то мы будет знать куда он отправиться. Конечно если поймешь язык общения, ведь его можно зашифровать. 🙂
Танк:
Боевая единица, пока сказать особо нечего.
Инжектор:
Может внедрять свой код врагам, дезинформация, внедрение своих прошивок, это всё его работа.
Дрон:
Дрон может обнаружить вражеские юниты, если они не замаскировались. Юнит может замаскироваться полностью, то-есть если на клетке 120 единиц, то маскируются все, но можно замаскировать например 100 единиц и оставить 20 на виду. Это я прочитал в книге «Искусство войны», когда ты специально делаешь вид, что отряд слабый и тем самым привлекаешь врага в ловушку.
Доставщик:
Доставщик доставляет боеприпасы, так как у киборгов и танков они кончаемы.
Киборг:
Боевая единица
Ещё я подумываю сделать флот, но пока это только в планах.
Сделан кстати командный центр:
Может выглядит не очень круто, но это же роботостроение, здесь дизайн придумывал не человек. 🙂
Также хочется сделать игру по локальной сети. Здесь код компилируется в байткод, и поэтому можно делиться с друзьями или дать эту прошивку ИИ боту, чтобы он играл против вас.
Делаю игру на своём простеньком движке с opengl. У меня ещё такое желание есть. В windows при падении приложения можно получить coredump файл. Это настраивается через реестр. Думаю сделать возможность, чтобы игроки могли скинуть мне coredump по почте или в мессенджере, чтобы я мог изучить где ошибка. Очень бы этого хотелось, но специально баг не буду делать. 🙂
Ссылку к игре я оставлю здесь, если кого заинтересовала игра, то буду рад, если вы добавите в список желаемого. Я вчера вообще хотел бросить разработку, но потом понял, что надо продолжать делать сложные вещи и будь что будет.
https://vkplay.ru/play/game/radio_attack/
ссылка на оригинал статьи https://habr.com/ru/articles/838522/
Добавить комментарий