Как стать автором
Обновить

#02 — И целого байта мало… | The Cross of Changes

Время на прочтение4 мин
Количество просмотров11K
Честь по чести и часть за частью. Примерно так мы будем погружаться с вами в увлекательный мир демосцены. Сегодня поговорим о конкретной работе в области sizecoding. Дело в том, что некоторые релизы не только имели культовый статус в узких кругах — они прямо и явно воздействовали на умы людей, заставляя учить IDA Pro, смотреть код, проникать во все мельчайшие детали. Было просто непонятно и очень интересно, как же такая магия работает.

Речь идет о cross by Queue Members Group — 128 байт интро для PC из далекого 1996 года:

image

Вот видеозапись работы:



В двух словах, как деды воевали… После успеха Enlight'95 в FIDO-конференции DEMO.DESIGN был объявлен виртуальный конкурс на создание работ размером 128 байт для PC. Он шел несколько месяцев, организаторы собрали результаты, провели голосование и определили победителей. Весь архив релизов с Demo design'96 доступен на Pouet для ознакомления. Победителем оказался cross от Mad Max / Queue Members Group. Группа QMG — из Самары, на тот момент ребята были студентами одного из технических вузов, а сам Mad Max — лидером всей команды.

Конкурс настолько «раскачал» молодые умы по всей стране, что организаторы Enlight'96 напечатали тираж футболок, где на спине была распечатка дампа cross. Вот несколько архивных фотографий:

image

image

image

И кадр из видеофильма про Enlight'96:

image

В марте 2020 года группа =RMDA= (которую я здесь официально представляю) успешно осуществила проект по цифровому сохранению / digital preservation этой исторической работы. Начали мы с создания видео… Да, банального видео, которое в последствии загрузили на YouTube. Ранее, на протяжении 25 лет видео-версии cross не существовало, и для просмотра требовалось мощное кунг-фу DosBox, которым далеко не каждый владеет.

Далее мы собрали в единый архив все дополнительные материалы, включая исходный код cross. К сожалению, автор не опубликовал исходников в свое время, более того, с его слов, последние изменения в работу вовсе вносились в HEX-редакторе. Соответственно, исходный код ниже — это наш реверс оригинала с нашими комментариями:

; NASM or FASM

        org 100h

        mov bx,es
        add bh,10h              ; bx = cs + 1000h
        mov es,bx               ; es = segment behind 64k of our code (extra video buffer)
        mov ds,bx               ; ds = es

        xor ax,ax
        mov cx,ax
        dec cx                  ; cx = -1
        rep stosb               ; clear extra video buffer
        dec ax                  ; ax = -1
        mov di,0A2D0h           ; set pointer to pixel at 130,80 (col,row)
        mov cl,80
        rep stosw               ; fill 80*2 = 160 pixels by 0FFh color (draw horizontal line)

        mov bx,19A0h            ; set pointer to pixel at 20,160 (col,row)
v:      mov [bx],ax             ; draw vertical line...
        add bx,320
        ja v                    ; ...until bottom

        mov ax,13h
        int 10h                 ; set 320x200 (256 colors) graphical video mode

        mov dx,3C8h
        xor al,al
        out dx,al               ; start palette set from 0 color
        inc dx
        mov cx,0C0h*3
        rep outsb               ; set first 0C0h (192) colors to black
p:
        out dx,al               ; red component
        outsb                   ; green = 0
        outsb                   ; blue = 0
        inc ax                  ; increase color (1, 2, 3..63)
        cmp al,64
        jb p                    ; set colors 0C0h..0FFh to red gradient (from dark to saturated)

        mov ch,0A0h
        mov ds,cx               ; ds = 0A000h = vedeo segment

l:      ; bx = pixel pointer, dx = pixel pointer delta value (initial values doesn't matter)
        cmp bh,0FAh
        jae s                   ; jump if current pixel is out of screen
        mov al,[bx]             ; else get color of pixel
        cmp al,0C0h
        jb s                    ; jump if pixel color is out of red gradient range (0C0h..0FFh)

        ; flame effect
        dec ax                  ; else decrase color by 1 (make it darker)
        mov [bx+1],al
        mov [bx-1],al
        mov [bx+320],al         ; di = 320
        mov [bx-320],al         ; and fill pixels around the current by new color

        mov si,-640             ; position delta: 2 lines up
        test dh,80h
        jnz n                   ; jump if dx is negative (poor pseudorandom boolean check)
        add si,2                ; wind effect
n:      mov [bx+si],al          ; add pixel 2 lines higher than current pixel considering possible wind
s:
        ; restore cross
        mov al,[es:bx]          ; get color from extra video buffer
        or [bx],al              ; replace pixel on screen by 0FFh is al = 0FFh (slow cross redraw)
        add bx,dx               ; increase pixel pointer by (pseudorandom) delta value
        inc dx                  ; increase delta value

        or bx,bx
        jnz l                   ; loop until full screen will be processed

        in al,60h               ; read keyboard scan code
        cmp al,1
        jnz l                   ; repeat if Esc key is not pressed

        mov al,3
        int 10h                 ; set text video mode

        ret                     ; return to DOS


Ясное дело, что в процессе реверса кода в исходник наш ключевой программист на x86 загорелся идеей оптимизации. Так получился cross2 — он занимает больше на 1 байт (127 вместо 126), но все, что было оптимизировано, потрачено на текст и звук. Цвет мы поменяли на зеленый, чтобы вы визуально не путали эти работы:



Никакой цели в глумлении над историческим наследием тут нет, просто любой sizecoding со временем может быть оптимизирован на несколько байт. Времени прошло изрядно, почти 30 лет, вот и оптимизация оказалась существенной — 20 байт (почти 16% от объема кода). Наша работа на один байт длиннее оригинала (в коде добавилось 13 байт текста, 6 байт кода для вывода, 2 байта на звук = 21, минус 1 байт разницы в размере).

Собственно все! Исходник cross2 вы сможете найти в архиве на Pouet и наглядно сравнить его с оригиналом. Большая благодарность Петру [frog] Соболеву и Майку [Mad Max] Широбокову за консультации и материалы при разработке этого проекта.

---EOF---

#FF — И целого байта мало… | Пилот)
#00 — ИЦБМ… | Приглашение на Revision Online 2020
#01 — ИЦБМ… | Какими бывают intro?
#02 — ИЦБМ… | The Cross of Changes
#03 — ИЦБМ… | 2B or not 2B
#04 — ИЦБМ… | Берем БК за рога
#05 — ИЦБМ… | Анимэ
#06 — ИЦБМ… | Метеоризмы

Развлекательный канал деда в Телеграм: teleg.run/bornded

Рядом с каналом есть чат. В нем можно попробовать поднять вопросы за демосцену, ассемблер, пиксель-арт, трекерную музыку и другие аспекты процессы. Вам могут ответить либо отправят в другие, более тематические чаты.

ТАК ПОБЕЖДАЛИ — ТАК ПОБЕДИМ!
Теги:
Хабы:
Всего голосов 32: ↑30 и ↓2+39
Комментарии62

Публикации

Истории

Ближайшие события

15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань