LINUX.ORG.RU

В разработке игра, где программируешь в машинных кодах. DECU EMU

 


1

3

Прочитав первые две главы Криса Касперского «Техника отладки программ без исходных кодов», я вдохновился на написание простого эмулятора, где мы как в старые времена пишем в hex редакторе опкоды инструкций.

Очень даже занимательный процесс, особенно учитывая, что инструкций всего 16 и их можно запомнить. Если проект не заглохнет и будет интересен мне и далее, то я сделаю сборку для android и аврора, где можно будет делать игры прямо вписывая машинные инструкции. Мне кажется, что такое уровень сложности должен кого-то привлечь.

Ну вот, с помощью мотивации я сделал себе два прекрасных дня, и теперь можно продолжить читать книгу.

https://habr.com/ru/articles/871634/

Перемещено hobbit из games

Ответ на: комментарий от alysnix

где ты психов найдешь в кодах программировать? Мне захотелось пописать в машинных кодах, я сделал эмулятор. Теперь если кто-то захочет такого же, то может попробовать воспользоваться моим эмулятором, чтобы сразу испытать чувство удовлетворения или злости.

Такому человеку сразу будет ясно, что это такое, писать в машинных кодах. Например как на NES, люди до сих пор пишут игры для NES на ассемблере, а тут ещё проще ассемблер, да такой ассемблер, что хватает знаний машинного кода, и можно прямо машинными кодами писать. Это же удивительно!

Не каждому такое понравиться, как вам например, но на каждую мелочь можно создать софт, тем более что я создаю что мне по силам и интересно.

Многие умеют больше и пишут более сложный софт, пусть они этим и занимаются.

peeruoeso
() автор топика

как в старые времена пишем в hex редакторе опкоды инструкций.

В старые времена не было hex редакторов. Да и вообще, начало шестнадцатеричного программирования это ≈середина 1960-х с нелёгкой руки IBM.

Уважающие себя двоичные ЭВМ были восьмеричными (12-, 18-, 24-, 36-, 45-, 48- или 60-72-разрядными). У десятичных машин был десятичный машинный код. И у перфокарточных машин код из символов, которые можно набить на перфокарте 📦.

vM ★★
()

Флажок C несимметрично работает? Если к 5 прибавить -20, то переполнения не будет, а если к -20 прибавить 5, то будет?

Или я что-то путаю?

vM ★★
()
Ответ на: комментарий от vM

восьмеричными (12-, 18-, 24-, 36-, 45-, 48- или 60-72-разрядными).

Чё за бред? PDP были 16-разрядными, при этом в машкодах использовалась восьмеричка. (Граница между байтами в слове не очень удобно выглядела, да: 177400 | 377).

anonymous
()
Ответ на: комментарий от anonymous

PDP были 16-разрядными

16-разрядными были PDP-11 (и это уже 1970-е), а PDP-7, на которой зародилась UNIX, была 18-разрядной,

PDP-8 12-разрядные, PDP-10 36-разрядные

Согласен, в PDP-11 восьмеричное кодирование инструкций. И, в значительной степени в 8080 и 8086(побайтно восьмеричное), хотя в интеловской документации восьмеричная нотация явно не использовалась.

vM ★★
()
Последнее исправление: vM (всего исправлений: 2)

Да, в общем и целом увлекательная игра-упражнение, автор молодец.

Другое дело, что я, например, в такое в своё время уже наигрался и ниже чистой сишечки опускаться уже не хочу. Оно не прибито к архитектуре процессора, и на нём можно писать что-нибудь не только занятное, но и полезное. И при этом всё ещё достаточно низкоуровневое. :)

hobbit ★★★★★
()
Ответ на: комментарий от anonymous

а в тетрадке!

Ой, этого тоже в своё время было написано навалом. Правда, таки не в машинных кодах, а в мнемониках ассемблера. И что-то ностальгии особой не испытываю.

hobbit ★★★★★
()

После последнего улучшения коды в редакторе показываются со сдвигом на одну строчку, и первых 0x10 кодов не видно.

https://github.com/xverizex/decu_emu/blob/28cb60eda902de25023213de2d5a51be28bbadb6/src/hex_editor.c#L152

Где-то здесь в hex_editor_draw_line_bytes() нужно поправить сдвиг?

snprintf (bl, 4, " %02x", h->bytes[h->top_line + index_line - 2 ][x]);
vM ★★
()
Последнее исправление: vM (всего исправлений: 1)

В сегодняшнем варианте надпись hex editor иногда не там всплывает

┌stack---------------------┐┌screen----------------┐┌cpu-----------------------┐
|                          ||                      ||                          |
|                          ||                      ||                          |
|                          ||                      ||                          |
|                          ||                      ||                          |
|                          ||                      ||                          |
|                          ||                      ||                          |
|                          ||                      ||                          |
|                          ||                      ||                          |
|                          ||                      ||                          |
|                          ||                      ||                          |
└--------------------------┘└----------------------┘└--------------------------┘
┌------------------------------------------------------------------------------┐
|****|  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  'm' - movement mode    |
|0000: hex editor1 07 10 0b 10 ac 01 7c 70 f0 00 00 00  'i' - insert mode      |
|0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  'q' - quit editor      |
|0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  'q' - quit from game   |
|0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  'r' - run simulate     |
|0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  'w' - save to file     |
|0050: 00 00 00 00 77 66 55 44 66 55 00 00 00 00 00 00  'hjkl' - vim movement  |
|0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  'd' - run in debug     |
|0070: f7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  'space' - step debug   |
|0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                         |
|0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                         |
└------------------------------------------------------------------------------┘
vM ★★
()
Ответ на: комментарий от peeruoeso

С curses много что может поломаться на экране не по вине использующего curses кода.

Поэтому нужна команда, которая перерисует экран полностью.

anonymous
()
Ответ на: комментарий от peeruoeso

я скоро сделаю отладку.

Уже видна обрабока отладочных клавиш.👍

PS А зачем нам потоки?

Традиционная curses не thread-safe. Можно сделать wgetch() неблокирующим, получать и обрабатывать нажатия в начале каждой итерации как обычно в простых играх делают.

anonymous
()
Ответ на: комментарий от anonymous

Да, переделал. Осталось разобраться как сделать неблокирующим, и в отладке это будет проблема мне кажется, так как остальное всё блокирующее, наверное надо всё неблокирующим сделать, тогда менять код придется. Надо подумать.

Вот как сейчас выглядит отладка. Rutube

peeruoeso
() автор топика
Ответ на: комментарий от peeruoeso

Осталось разобраться как сделать неблокирующим

Поставить timeout(0) или nodelay() для неблокирующего ввода?

https://www.opennet.ru/man.shtml?topic=timeout&category=3

diff --git a/src/machine.c b/src/machine.c
index f75f9a2..d351902 100644
--- a/src/machine.c
+++ b/src/machine.c
@@ -696,6 +696,8 @@ machine_run (struct machine *m)
                int c = wgetch (hex_editor->win);
                debug_input (c);
        } else {
+               int c = wgetch (m->game_screen);
+               machine_input(m, c);
                execute_instruction (m, opcode, b);
        }

diff --git a/src/main.c b/src/main.c
index 76e3abe..210c28d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -106,6 +106,9 @@ main (int argc, char **argv)
                        real_window_height_game,
                        width_term / 2 - real_window_width_game / 2, 0);

+       wtimeout(screen_win, 0);
+
+
        uint32_t hex_editor_width_with_border = width_term;
        uint32_t hex_editor_height_with_border = height_term - real_window_height_game;
vM ★★
()
Последнее исправление: vM (всего исправлений: 1)
Ответ на: комментарий от vM

О, спасибо, но как быть, если это отладка? Может и возможно сделать логично. Проблема такая. Когда играешь с неблокирующим режимом, то программа записывает клавишы как и подобает, но когда в режиме отладки, то будет проблема. Например я дошел до нужной инструкции, я её запустил, и не успел нажать на кнопку, получается что в отладке неудобно пользоваться неблокирующим режимом.

Хотя может я сейчас мыслю неправильно. Можно ведь в отладке сделать блокирующий режим и таймаут неблокирующего.

peeruoeso
() автор топика

https://vk.com/wall583070625_121

Вот что реализовал. Может ещё help сделаю в самой игре, но пока не знаю, стоит ли. Хотя было бы удобно не выходя смотреть советы, но man страница есть, только она не объясняет всех интересных возможностей, считаю, что будет интересно, если интересующийся данным эмулятором сам поймёт как в нём работать, то-есть как витиевато писать код.

peeruoeso
() автор топика

Вопрос по оформлению.

Почему Вы пишете так:

	snprintf (line, 64, "FLAGS: %04x", machine->cpu.flags);
	mvwaddstr (debugger.cpu, 1, 2, line);

вместо

	mvwprintw ( debugger.cpu, 1, 2, "FLAGS: %04x", machine->cpu.flags);

Чтобы в отладчике посмотреть результат форматирования?

vM ★★
()
Ответ на: комментарий от vM

Чтобы в отладчике посмотреть результат форматирования?

Действительно, я не заметил что так можно. И код сделан в спешке, так как хотелось получить результат. Рефакторинг будет потом. И спасибо за это замечание.

peeruoeso
() автор топика
Ответ на: комментарий от anonymous

Переадресация без использования адресных и индексных регистров, прямой модификацией адресов в инструкциях, как фон Нейман завещал?

Я уже и забыл что он завещал, но вы совершенно правы, в этом простецком эмуляторе так можно.

peeruoeso
() автор топика
Ответ на: комментарий от anonymous

Вы совершенно правы. Я помню раньше, когда делал компилятор, делал дефайны для структуры. Хоть здесь и один тип передаваемых данных, но всё-равно мне такой способ объявления массива нравиться. Вот как я сделал.

typedef void (*def_handler) (struct machine *m, uint8_t *b);

#define BEGIN_STRUCT_HANDLER(name) \
        def_handler name[N_OPERATORS] = {

#define END_STRUCT_HANDLER() \
        };

#define ADD_HANDLER(name_function) \
        name_function,

#define HANDLER(opcode) \
        handler[(opcode)] (m, b);

BEGIN_STRUCT_HANDLER (handler)
        ADD_HANDLER (handle_add)
        ADD_HANDLER (handle_sub)
        ADD_HANDLER (handle_and)
        ADD_HANDLER (handle_or)
        ADD_HANDLER (handle_xor)
        ADD_HANDLER (handle_shl)
        ADD_HANDLER (handle_shr)
        ADD_HANDLER (handle_ld)
        ADD_HANDLER (handle_in)
        ADD_HANDLER (handle_nop)
        ADD_HANDLER (handle_out)
        ADD_HANDLER (handle_push)
        ADD_HANDLER (handle_pop)
        ADD_HANDLER (handle_test)
        ADD_HANDLER (handle_jc)
        ADD_HANDLER (handle_hlt)
END_STRUCT_HANDLER ()



static void
execute_instruction (struct machine *m, uint8_t opcode, uint8_t *b)
{
        HANDLER (opcode >> 4);
}

peeruoeso
() автор топика

надпись hex editor иногда не там всплывает

забыл отметить, что этот эффект полностью исчез в однопоточном режиме.

Мелкий недочёт: после прогона r команда d для отладки сразу не срабатывает. Нужно сначала явно переключиться в i или m

vM ★★
()