- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
#include <stdio.h>
#include <inttypes.h>
#include <stddef.h>
void printuint64(const uint64_t state);
uint64_t game_of_life8x8(const uint64_t old);
uint8_t getbit(uint64_t in, uint8_t y, uint8_t x);
uint8_t getbit(uint64_t in, uint8_t y, uint8_t x)
{
return !!((in) & (1ULL << ((y&0b111) + (x&0b111)*8)) );
}
uint64_t setbit(uint8_t y, uint8_t x, uint8_t bit)
{
if (bit)
{
return 1ULL << ((y&0b111) + (x&0b111)*8);
}
return 0;
}
uint64_t game_of_life8x8(const uint64_t old)
{
uint64_t new_state = 0;
#define GETBIT(y,x,val) getbit(val, y, x)
#define SETBIT(y,x,bit) setbit(y,x,bit)
#define SUMAROUND(y,x,val) ( \
GETBIT(y+1,x,val) + GETBIT(y-1,x,val) \
+ GETBIT(y,x+1,val) + GETBIT(y,x-1,val) \
+ GETBIT(y+1,x+1,val) + GETBIT(y+1,x-1,val) \
+ GETBIT(y-1,x+1,val) + GETBIT(y-1,x-1,val) \
)
#define CELLSTATE(y,x,val) \
(GETBIT(y,x,old) == 1 ? \
( ((SUMAROUND(y,x,val) == 2 ) || ( SUMAROUND(y,x,val) == 3 )) ? 1 : 0) \
: \
( ( SUMAROUND(y,x,val) == 3 ) ? 1 : 0 ) \
)
#define SETCELL_SH(y,x,val) SETBIT(y,x,CELLSTATE(y,x,val))
#define FILL_LINE(y) \
SETCELL_SH(y,7,old) | SETCELL_SH(y,6,old) | SETCELL_SH(y,5,old) | \
SETCELL_SH(y,4,old) | SETCELL_SH(y,3,old) | SETCELL_SH(y,2,old) | \
SETCELL_SH(y,1,old) | SETCELL_SH(y,0,old)
new_state = FILL_LINE(7) | FILL_LINE(6) | FILL_LINE(5)
| FILL_LINE(4) | FILL_LINE(3) | FILL_LINE(2)
| FILL_LINE(1) | FILL_LINE(0);
return new_state;
}
void printuint64(const uint64_t state)
{
for (size_t i = 7; i != SIZE_MAX; i--)
{
for (size_t j = 7; j != SIZE_MAX; j--)
{
printf("%u", !!((state >> (j+i*8)) & 1) );
}
printf("\n");
}
}
int main(void)
{
// Glider
uint64_t state =
(( 0b01000000ULL ) << 8*7 ) |
(( 0b00100000ULL ) << 8*6 ) |
(( 0b11100000ULL ) << 8*5 ) |
(( 0b00000000ULL ) << 8*4 ) |
(( 0b00000000ULL ) << 8*3 ) |
(( 0b00000000ULL ) << 8*2 ) |
(( 0b00000000ULL ) << 8*1 ) |
(( 0b00000000ULL ) << 8*0 );
for (size_t i = 0; i < 50; i++)
{
printuint64(state);
state = game_of_life8x8(state);
printf("\n");
}
return 0;
}
Conway's game of life внутри uint64_t (8 на 8) с периодическими граничными условиями.
Анскилльно. Надо на операционные усилители сразу переводить.
http://www.nablaman.com/relay/
Дык никто не заставлял юзать именно in/out. Можно и как к обычной памяти через lda/sta. Отдельной линии не было, т.е. всё как MMIO.
Не сравнивай труъ аппаратный отладчик с этим софтовым убожеством.
В том говносимуляторе одна инструкция хуево реализована. Инструкция DAD которая складывает регистровые пары.
DAD H 29 Сложить HL с HL (удвоение HL)
Если складывать регистровую пару HL с самой собой, то в говноэмуляторе складывалась сначала старший регистр, а потом младший (хотя должно быть наоборот). Т.е. "флаг переноса" из младшего регистра в старший пробрасывается после того, как старший просуммировался. Или может я что-то путаю, это вообще хер знает когда было
Оно там так же растет.
16 байтный регистр SP служит указателем на вершину стека. Помещение 16 байтного значения в стек происходит следующим образом: 1. SP декрементируется; 2. старший байт заносится в ячейку памяти по адресу на который указывает SP; 3. SP декрементируется; 4. младший байт заносится в ячейку памяти по адресу SP.
Т.е. при пуше там стекпоинтер уменьшается, аналогичное поведение и в x86 https://c9x.me/x86/html/file_module_x86_id_269.html
Decrements the stack pointer and then stores the source operand on the top of the stack.
> RST 0... RST 7 — это аналог INT, чтобы вызывать функции ОС?
Это программное прерывание, да. Только никакой ОС у тебя может и не быть. Можно какое-нибудь говно из биоса дергать (если он есть)
А вообще, я за отдельный стек для данных.
https://stackoverflow.com/a/1782905
Для новых интерфейсов изготавливать свои девайсы уже труднее.
USB Full Speed сейчас даже на копеечных армах есть, так что жить можно.
Но кроме USB FS ничего доступного в компах не осталось :(
Напомнило, как я собирал 1-wire адаптер для COM порта из нескольких резисторов и диодов. Даже читало домофонные ключи :)
> я не про армы
Ну зацепишь ARM или FTDI какой-нибудь как преобразователь в параллельный порт. А дальше играйся с чем хочешь.
Завладеешь USB контроллером и будешь кидать пакеты напрямую чтобы дескрипторы и прочую хуйню не пилить (с xHCI не прокатит, он сделает твоей железке set address и сфейлится).
На USB LS всего 1.5МГц. Берёшь генератор с кварцем на 6МГц, ждёшь стартовый импульс, пропускаешь пару тиков для верности и загоняешь xnor между текущим и предыдущим стейтом в сдвиговый регистр каждые 4 тика (NRZI).
Остаётся выкинуть наполнитель после каждых 5 единичек подряд (отводы от сдвигового регистра, and, ну ты понял).
Или можно просто усилить сигнал да зажигать им светодиод. Чем чаще пакеты - тем сильнее горит.
Быстрее. Раза в три.
З.Ы. Ты видимо байты с битами где-то попутал.
Ещё были load/store через [BC] и [DE].
Ну кстати можно попробовать. Правда на циклоняшке всего 22к ячеек, сильно большое поле не получится.
Бедный оптимизатор пердолился с ним почти 5 минут... Получилось по 4 ячейки на пиксель - одна детектит 2 соседа, вторая детектит 3 соседа, третья хранит и обновляет значение, четвёртая встроена в цепочку для загрузки/просмотра. Меньше походу никак.
Теоретический пирфоманс 1.5Тпикс/сек (300МГц * 4800пикс) выглядит неплохо.
С ним просто накладка возникла - поле сожрало почти все ячейки и NIOS не влез. Придётся пилить железную стейтмашину для инициализации.
https://xeno-by.livejournal.com/28122.html
Полиэдральная модель оптимизации циклов
Есть 100% инфа.
кароче жилибыли астерикс и обеликс, судя по историческим хроникам они жили на полуострове бретань, а так же они плавали в омерику потому что у римлян был такой вот злой план сбросиить их за край земли. Кароче от туда привезли кукурузу. Далее по мере развития мира нам ничего не известно об этих ребятах, но по какой-то причине пипн короткий (меровинг или каролинг хз) не захватил полуостров бретань, значит поцоны все еще пиздили "римлян" даже потом собственное королевство сделали, а так же есть свидетельства в том что корноул это была населена этими же самыми бритами. Так как самими англичанами эта територия была занята только около 1400