Блог страдающего Лиса
Lorem ipsum hello dolor sit world amet

25 окт 2024 Пт Что бы я хотел сделать

Наверное назову этот свой раздел так: фоторамка. Генерироваться будет некое изображение в виде цифрового арта. Первая идея на цифровой арт.
  • Шахматная доска 3Д (сделано)
  • Цветовой градиент
  • Белый шум
  • Горы
  • Шум Перлина
  • Окружность на вычитаниях
  • Графический интерфейс винды
  • LED часы
Этот список буду еще пополнять. Собственно, интересно разработать различные алгоритмы для вывода графики в очень быстром виде, чтобы работало все за один такт, если так можно выразиться. У меня не очень много времени и сил заниматься этим делом, и мотивации тоже маловато.
Мне просто нравится делать эти демки, но показывать некому и никто не оценит этого особо.
Генератор псевдослучайностей 17 бит
Я просто оставлю это здесь.
reg [16:0] rnd;
always @(posedge clock)
rnd <= rnd ? (rnd >> 1) ^ {rnd[0], 2'b00, rnd[0], 13'b0} : 1'b1;
Теги: Идеи

24 окт 2024 Чт Микропроекты и квадратный корень

Я часто думаю, что мне от этого программирования нужно, и понимаю, что мне очень нравится делать микроскопические проекты, демосцены. Все время вспоминая прошлое и прежние времена, когда я радовался кубу, нарисованному где угодно, хоть на туалетной бумаге, теперь я тоже понимаю, что мне все равно нравится рисовать эти кубы. И даже шары (oh my balls!).
Поскольку вчера я сделал шахматную трехмерную доску, то думаю, что можно в принципе, продолжить делать что-то такое в этом же стиле и куда-то складировать на сайте с исходниками, которые никому абсолютно не нужны.
Все что было в детстве — было лучше всего, потому что там радовался всему, даже stosb радовал так, что я аж подпрыгивал от счастья на месте. Раньше у меня были очень простые радости, не то что сейчас, когда ничего не радует, но ладно, это лирическое отступление от темы.
Из ближайших мыслей о проектах — нарисовать стохастические горные вершины, флаппи бёрд, попробовать вырисовывать окружность по принципу вычисления x = \sqrt{r^2 - y^2} . Есть такой метод довольно простого поиска quadratного корня, через серию вычитаний -1, -3, -5, -7 и так далее. Я уже ранее рассказывал об этом методе, где 1+3+5+7+9 дает значение квадратов от чисел 1,2,3,4 и т.д. Если же действовать в обратную сторону, то получим корень.
Возьмем число 100, вычислим куадраутный корень через серию вычитаний:
1) 100-1=99,
2) 99-3=96,
3) 96-5=91,
4) 91-7=84
5) 84-9=75,
6) 75-11=64,
7) 64-13=51,
8) 51-15=36,
9) 36-17=19,
10) 19-19=0
Количество вычитаний получилось 10. А значит, квадратный корень из 100 будет 10. На верилоге это бы записано было таким образом:
always @(posedge clock) if (A >= B) begin A <= A - B; B <= B + 2; C <= C + 1; end
Где A — исходное число, B=1 на старте, C=0 на старте, и это результат. Ну и A будет в остатке потом. Короче, через серию вычитаний можно добиться вычисления квадратного корня. Есть только один баг в том, что если исходное число например 65535, то придется 255 раз вычесть прежде чем добьемся ответа от него. Есть и другие методы, например, поиск корня через серию делений, например, или там, по табличке искать сначала, двоичной.
Есть быстрый, шустрый метод быстро найти квадратный корень (приблизительно) через подсчет количества значимых битов, для начала. Например, нам надо вычислить быстренько квадратный корневище через такой подсчет. Возьмем крупное число, 25612461 например, что в шестнадцатеричном виде будет 186D0AD, а в двоичном виде:
0001 1000 0110 1101 0000 1010 1101
Сразу быстро можно посчитать высоту последнего разряда у числа, который содержит единицу. И это бит номер 24, начиная с 0. Если разделить число 24 на 2, то получится 12 битов. Это значит что результат корня гарантированно старше чем 2^12, и не меньше чем 4096 (то есть 4096^2=16'777'216). Результат будет находиться между 4096^2 и 8192^2.
Понятное дело, что это является лишь грубой оценкой корня и что придется еще искать, но подобный подход позволяет снизить количество проб c 24 до 12 при бинарном поиске. И конечно же, чем больше число, тем больше оно и занимает времени на поиск решения.

23 окт 2024 Ср Нарисовать шахматную доску в перспективе

У меня есть одна демка, это "шахматка", она основана на принципе:
t.x = x / y
t.y = H / y
Вот тут t.x и t.y это точки текстуры, а H — высота над шахматной доской, x меняется от -160 до 160 (для экрана 320 пикселей по ширине), y меняется от 1 до 100, где y=1 самая дальняя точка перспективы, а y=100 ближняя.

Вот так эта программа пока что выглядит на Quick Basic 4.5. Моя же задача в том, чтобы использовать только одно деление, причем, это деление будет выполнено как серия вычитаний (и еще одно сложение), и выдать тоже самое на экране со скоростью 25 мгц. Я думаю, что у меня это может получиться.
Как я и говорил ранее, при ширине линии 800 пикселей я могу даже увеличить размеры поля, использовать не только 320, но и 800, но делать так, конечно, пока не буду. Сначала, вывод на экран без использования памяти и любых блоков DSP. Чистый хардкор, как в детстве.
У меня есть идеи на небольшие демки и мне хочется их показывать и рассказывать и я буду это делать в этом великолепном блоге.
Программа
У меня получилось сделать программу для верилятора, которая выдает точно такую же картинку, какую я изобразил ранее. Я весь код приводить тут не буду, только ядро алгоритма.
always @(posedge clock) begin

    // Вычисление текстуры XOR
    if (rx >= ry) begin rx <= rx + 1 - ry; tx <= tx + 1; end
    else          begin rx <= rx + 1; end

    // ----------------
    // Инициализация [на первой точки вывода]
    if (X == hzb) begin

        A <= 320;
        B <= Y - (199 + vtb);
        C <= 0;

    end
    // Запись результата [перед тем как начать выводить на экран]
    else if (X == hzb-1) begin

        tx <= C[0];
        ty <= C[0];
        rx <= (B - 1) - A;
        ry <= B;

    end
    // Деление числа A : B => C (остаток A)
    else begin if (A >= B) begin A <= A - B; C <= C + 1; end end
    // ----------------

    // Вывод окна видеоадаптера
    if (X >= hzb && X < hzb+hzv && Y >= vtb && Y < vtb+vtv)
    {r, g, b} <= Y > (200 + vtb) && (tx ^ ty) ? 3'b111 : 3'b000;

end
Объяснить тут как она работает, я не могу, потому что сложно. Вся фишка в делении, которое представляет собой тут просто серию вычитаний: if (A >= B) begin A <= A - B; C <= C + 1; end. Здесь A-делимое, B-делитель, C-результат, а в конце деления получается остаток. Деление это происходить может с разной скоростью. Например, разделить 320 на 200 займет всего 1 такт, а 320 на 8 уже 40 тактов. Но, поскольку ширина строки все равно 800, а результат всегда меньше 320, то поделить всегда получится подобным макаром.
Для процессора EPM570 это заняло только 150 LE, то есть, этот код влазит даже в EPM240.
Теги: Демо

22 окт 2024 Вт Видеоигра на EPM570

Удивительно, но я подумал, что можно сделать игру "Гонки", причем, в псевдотрехмерном виде, для этого чипа. Нарисовать дорогу не настолько сложно, как это кажется, потому что там всего лишь потребуется процедурно делать изгибы, не прибегая к помощи памяти, которой в этом чипе просто нет, кроме регистровой. Пока лишь это только проект в голове, как сделать их реально, в данный момент не знаю.
Еще я подумал написать статью про деление и умножение, сложение и вычитание. Однажды даже писал такую статью, но что-то еще раз хочется, чтобы досконально изучить этот вопрос, причем хотелось бы не только написать, но еще и иллюстрировать на js, возможно. У меня давно идея была, чтобы рисовать не на paint где-то или quick basic, а на js делать иллюстрации или даже анимации, но для этого мне нужно разработать некий sdk. Вообще, создание инструментов разработки это отлично, как по мне, и лучше сначала сделать их, а не писать статью.
Сегодня еще один цикл перезаписи потрачен на проверку видеоадаптера, который оказался рабочим. Это прекрасно.
Демосцена
Вечер у меня прошел в поисках решения стандартной перспективной проекции, XOR-текстурированный пол. Это обычная схема, с необычным подходом. Я подумал, можно ли сделать на MAX2 вывод такой текстуры, причем, чтобы она выводилась наиболее быстро, без деления или умножения. И решение пришло. Но правда, деление сделать придется, но лишь один раз на строку, а это не так и много. По сути придется делить число 320 на Y=1..240. Для 320 достаточно использовать 9 бит, да и в целях экономии ЛЕ можно делить число при помощи вычитания. На линии 800 точек, а вычитать максимум можно 320 раз (так как 320 делить 1). Это очень занимательное решение, конечно, ведь можно делить и побыстрее, например, сдвигами, тогда разделить число получится ровно за 9 тактов.

Теги: MAX2

21 окт 2024 Пн EPM570 в качестве ROM

Мне стало интересно и я попробовал запихнуть таблицу шрифтов, 256 байт в микросхему EPM570 и у меня даже получилось это сделать, а это всего лишь 32 символа... Этот ROM занимает 223 логических элементов. Насколько это много? Всего элементов 570, так что 39%, а в EPM240 будет 92%. В любую из этих микросхем у меня помещается. Конечно, для EPM240 только это и поместится, но не суть важно.
Думаю, что можно будет сделать какие-нибудь простенькие программки, вроде электронных часов и вывести их на дисплей монитора дисплейного. Но вообще для начала, перед тем как цифры выводить и буквы, я попробую пока что вывести VGA сигнал. Это ведь тоже не так просто, учитывая то, как именно мне придется программировать. В этом чипе нет нормального доступа к программной памяти. Да и не буду я наверное делать тут классические программные решения вроде процессора. Сделал уж эти процессоры. Попробую создать некоторую игрушку очень простую.
Поскольку очень мало можно прошивать этот чип, то я буду считать количество перепрошивок. Я думаю, что примерно раз 40 я уже ее прошил, так что осталось около 60 перепрошивок. Сегодня прошил 1 раз.
Рядом с этой фоткой "марсохода" я еще на всякий случай разместил пины к VGA, чтобы не забыть где и что находится.

Теги: MAX2

20 окт 2024 Вс Встроил VIDAC в DE0

Вчера понемногу делал видеопроцессор и медленно, но постепенно двигаюсь к конечной цели по видеоускорителю, к рисованию текстурированных прямоугольников и треугольников. Примерно набросал код растеризатора, но не проверял, боюсь, что там будет сложно, но что поделать, надо все же доделать как-нибудь. dash1
С утра сел и разметил новую память, встроил новый видеопроцессор в ПЛИС и проверил. Все работает как надо, у меня получилось сделать минимальный набор геометрических фигур, таких как рисование линии, кругов, прямоугольников.
Всего потрачено памяти:
  • 64K память программ
  • 128К видеопамять (2х буферная)
  • 64К видеопамять видак
  • 32К текстурная память
  • 4К шрифты
  • 1К палитра
Это составляет 293К памяти из 308К, то есть еще 15К памяти свободно. Видеопамять (да и текстурную тоже) можно использовать не только для хранения информации, но и для исполнения программ.
Вчера еще придумал довольно простой метод деления чисел, для текстуризации я пока что использовал деление максимум на 15, то есть, результат не может превышать это число, но можно сделать какое угодно, на самом деле, просто я специально сократил, чтобы не сильно место занимать в процессоре. Вместе с видаком и процессором 3548 ALM (или 7096 LE) было занято из 18480 ALM, то есть, всего 19% от площади кристалла.
Мне бы наверное все-таки хотелось сделать бы несколько видео и выложить их на сайте, по принципам работы процессора и компьютера. Начать с того, что такое двоичные числа и как они считаются, и заканчивая делением чисел.
Теги: Видак

19 окт 2024 Сб Закрашенный круг

Единственное мое достижение за день было нарисовать закрашенный круг. Скорость рисования такого круга уже приближается к КПД 100%, то есть, 25 млн точек в секунду, в отличии от простого рисования окружности, где этот показатель уменьшается вдвое, так что в каком-то смысле, круги закрашенные рисовать чуть быстрее.
Несмотря на то что эти круги якобы "ускорены", на процессоре, который у меня есть, с помощью REP STOSB выполняется тоже с такой же скоростью, 1 такт = 1 пиксель, так что прямо так сказать, существенного ускорения в рисовании закрашенных кругов тут нет, софтверный метод лишь на несколько десятков тактов медленнее. Преимущество рисования с помощью сопроцессора проявляется в том, что пока ему отдается задача на это действие, процессор может заниматься своими делами, получая параллельное выполнение вместо последовательного. Так что в этом тоже есть смысл.
Мне осталось по 2Д видеоускорителю сделать всего лишь 2 компонента:
  • Рисование текстурного прямоугольника
  • И закрашенного треугольника
Треугольник этот не 3Д, а просто рисуется как обычно, слева направо, сверху вниз построчно. Насчет 3Д ускорителя видака, я не уверен, что смогу сделать его пока что. Когда я закончу создание 2Д версии, то все-таки, приступлю к разработке игры про Лиса, о которой уже так давно мечтал и которую все никак сделать не могу.

Теги: Видак

18 окт 2024 Пт Разработка VIDAC

Как ни удивительно, но вчера я довольно много сделал по этому проекту. Встроил модуль рядом с 8088 процессором и смог нарисовать линию, прямоугольник, окружность и даже полигональные линии. Это в общем и целом говорит о том, что примерно сделать у меня получается что-то, но остается еще много чего. Это и текстурированный треугольник, и просто треугольник, и прямоугольник с текстурой.
С трехмерным треугольником я так и не смог придумать что делать. Для качественного 3D требуется использование буфера глубины, а это сразу требует определенного места в памяти. Память у меня есть и это SDRAM. Ее можно использовать для этой задачи.
Но мне кажется, что с 3D будет сложно. Для начала надо бы вообще просто треугольник научиться рисовать, прежде чем получится его текстурировать. Все это невероятно сложная задача. Пожалуй я все-таки сделаю сначала 2D вариант, а пока говорить о 3D даже не стоит. Да и много ли у меня времени на все это...

Теги: Видак

17 окт 2024 Чт Встраивание VIDAC в верилятор

Наконец-то мне удалось совместить 8088 с видеоускорителем, и я смог нарисовать первую линию. Надо еще проверять и тестировать, но вроде получается и это хорошо. Используется разделяемая память, когда контроллер работает, выставлен статус BSY, то тогда невозможно ничего прочитать или записать в память $A0000...$CFFFF как минимум (192К). Это потому что видеоускоритель занимает адреса и использует их сам для записи.
Планируемый функционал.
  • Рисование линии. Выполнено, но не проверено до конца.
  • Прямоугольники — как закрашенные, так и не закрашенные (контурные)
  • Круг — не закрашенный и закрашенный
  • Текстурированный прямоугольник с прозрачностью (в том числе спрайты)
  • Закрашенный треугольник
  • Трехмерный текстурированный треугольник
  • Рисование тайловой сетки
Это большая работа и мне придется ее делать очень долго и много. Сегодня по крайней мере я смог сделать рисование линии, полигональных линии и закрашенного и не закрашенного прямоугольника и вроде все работает нормально.
1
2        include "app/macro.asm"
3        org     100h
4
5        screen  13
6        mov     ax, $C000
7        mov     es, ax
8        mov     si, draw
9        xor     di, di
10        mov     cx, size
11        rep     movsb
12        mov     dx, $300
13        out     dx, al
14        hlt
15
16draw:   vidacline   160,10,300,150,2
17        vidacpoly   100,100,3
18        vidacpoly   160,10,4
19        vidacrect   20,20,30,25,5
20        vidacfill   40,40,70,50,6
21        db 0
22size    = $ - draw
Рисуется треугольник и всякая дребеда.
Теги: 8088, Видак

16 окт 2024 Ср Первые две программы на новом процессоре

Мне удалось создать программы, при этом изрядно попортив себе нервы на отладке. Оказывается, не работают некоторые инструкции, причем довольно важные, так что пришлось поискать где баг. Мне бы написать юнит-тесты на процессор, но видимо, не получится. Это слишком сложная и неоднозначная задача.
Сначала я сделал программу сортировки QuickSort.
1        org     100h
2        include "../macro.asm"
3start:  screen  13
4        mov     cx, 64000       ; Сгенерировать случайный шум
5        xor     di, di
6@@:     add     al, ah
7        imul    ax, 3235
8        inc     ax
9        stosb
10        loop    @b
11        mov     si, 0           ; Начать сортировку
12        mov     di, 64000
13        call    qsort
14        hlt
15qsort:  push    si di           ; L-si, R-di
16        mov     ax, si
17        mov     bx, di
18        shr     ax, 1
19        shr     bx, 1
20        add     bx, ax          ; BX=середина
21        mov     cl, [es:bx]     ; CL=PIVOT
22.w1:    cmp     [es:si], cl     ; WHILE (Arr[si] < pivot): si = si + 1
23        jnb     .w2
24        inc     si
25        jmp     .w1
26.w2:    cmp     [es:di], cl     ; WHILE (Arr[di] > pivot): di = di - 1
27        jbe     .w3
28        dec     di
29        jmp     .w2
30.w3:    cmp     si, di          ; IF a% <= b% THEN
31        ja      .w4
32        mov     al, [es:si]     ; SWAP Arr(a%), Arr(b%)
33        xchg    al, [es:di]
34        xchg    al, [es:si]
35        inc     si
36        dec     di
37        cmp     si, di          ; LOOP WHILE a% <= b%
38        jbe     .w1
39.w4:    pop     bx ax           ; AX-было ранее L, BX-R
40        cmp     ax, di          ; IF l% < b% THEN QSort l%, b%
41        jnb     .s1
42        push    ax bx si di
43        mov     si, ax          ; ax=l%, di=b%
44        call    qsort
45        pop     di si bx ax
46.s1:    cmp     si, bx          ; IF a% < r% THEN QSort a%, r%
47        jnb     .s2
48        push    ax bx si di
49        mov     di, bx
50        call    qsort
51        pop     di si bx ax
52.s2:    ret
Потом сделал программу для создания эффекта пламени. Получилось хоть и красиво, но медленно. Сортировка 64к элементов производится за примерно 1.5 секунды (за 37822337 тактов процессора). Среднее количество тактов на одну инструкцию составляет 4.8 тактов на инструкцию. Если проверять эквивалент в DOSBOX, то там выставлено по умолчанию количество 3 млн инструкции в секунду. Если разделить 25 на 4.8 равно 5.2 млн инструкции в секунду.
Это просто для интереса я подсчитал. Еще вот надо будет проверить как работает XCHG ax, r16...
Теги: 8088