Загрузка данных


;!SaveMemory = True

; Итоговое задание 3
; Вариант 1
; Многоцветное изображение со сжатием
; Рисунок: Птичка
;
; Формат сжатия:
; старшие 4 бита = цвет (0h=черный, 8h=серый, Bh=бирюзовый, Eh=желтый, Fh=белый)
; младшие 4 бита = количество повторений - 1

MOV BX, 0200h

; ----------------------------------------------------------------
; Сжатый массив изображения (строго из твоего примера)
; ----------------------------------------------------------------

; 1 строка
MOV BYTE PTR DS:[BX]+0, 0FFh
MOV BYTE PTR DS:[BX]+1, 0F6h
; 2 строка
MOV BYTE PTR DS:[BX]+2, 0F3h
MOV BYTE PTR DS:[BX]+3, 000h
MOV BYTE PTR DS:[BX]+4, 0FFh
MOV BYTE PTR DS:[BX]+5, 0F1h
; 3 строка
MOV BYTE PTR DS:[BX]+6, 0F2h
MOV BYTE PTR DS:[BX]+7, 000h
MOV BYTE PTR DS:[BX]+8, 0B0h
MOV BYTE PTR DS:[BX]+9, 000h
MOV BYTE PTR DS:[BX]+10, 0F4h
MOV BYTE PTR DS:[BX]+11, 003h
MOV BYTE PTR DS:[BX]+12, 0F7h
; 4 строка
MOV BYTE PTR DS:[BX]+13, 0F2h
MOV BYTE PTR DS:[BX]+14, 000h
MOV BYTE PTR DS:[BX]+15, 0B3h
MOV BYTE PTR DS:[BX]+16, 000h
MOV BYTE PTR DS:[BX]+17, 0F1h
MOV BYTE PTR DS:[BX]+18, 000h
MOV BYTE PTR DS:[BX]+19, 0B3h
MOV BYTE PTR DS:[BX]+20, 000h
MOV BYTE PTR DS:[BX]+21, 0F5h
; 5 строка
MOV BYTE PTR DS:[BX]+22, 0F1h
MOV BYTE PTR DS:[BX]+23, 000h
MOV BYTE PTR DS:[BX]+24, 0B0h
MOV BYTE PTR DS:[BX]+25, 000h
MOV BYTE PTR DS:[BX]+26, 0B3h
MOV BYTE PTR DS:[BX]+27, 000h
MOV BYTE PTR DS:[BX]+28, 0F0h
MOV BYTE PTR DS:[BX]+29, 000h
MOV BYTE PTR DS:[BX]+30, 0B5h
MOV BYTE PTR DS:[BX]+31, 000h
MOV BYTE PTR DS:[BX]+32, 0F3h
; 6 строка
MOV BYTE PTR DS:[BX]+33, 0F1h
MOV BYTE PTR DS:[BX]+34, 000h
MOV BYTE PTR DS:[BX]+35, 0F0h
MOV BYTE PTR DS:[BX]+36, 000h
MOV BYTE PTR DS:[BX]+37, 0B4h
MOV BYTE PTR DS:[BX]+38, 000h
MOV BYTE PTR DS:[BX]+39, 0B0h
MOV BYTE PTR DS:[BX]+40, 000h
MOV BYTE PTR DS:[BX]+41, 0B0h
MOV BYTE PTR DS:[BX]+42, 000h
MOV BYTE PTR DS:[BX]+43, 0F7h
; 7 строка
MOV BYTE PTR DS:[BX]+44, 0F2h
MOV BYTE PTR DS:[BX]+45, 000h
MOV BYTE PTR DS:[BX]+46, 0B5h
MOV BYTE PTR DS:[BX]+47, 000h
MOV BYTE PTR DS:[BX]+48, 083h
MOV BYTE PTR DS:[BX]+49, 0B0h
MOV BYTE PTR DS:[BX]+50, 000h
MOV BYTE PTR DS:[BX]+51, 0F5h
; 8 строка
MOV BYTE PTR DS:[BX]+52, 0F3h
MOV BYTE PTR DS:[BX]+53, 000h
MOV BYTE PTR DS:[BX]+54, 0B2h
MOV BYTE PTR DS:[BX]+55, 0F0h
MOV BYTE PTR DS:[BX]+56, 0B0h
MOV BYTE PTR DS:[BX]+57, 082h
MOV BYTE PTR DS:[BX]+58, 000h
MOV BYTE PTR DS:[BX]+59, 080h
MOV BYTE PTR DS:[BX]+60, 000h
MOV BYTE PTR DS:[BX]+61, 0F6h
; 9 строка
MOV BYTE PTR DS:[BX]+62, 0F3h
MOV BYTE PTR DS:[BX]+63, 000h
MOV BYTE PTR DS:[BX]+64, 0B2h
MOV BYTE PTR DS:[BX]+65, 0F0h
MOV BYTE PTR DS:[BX]+66, 0B0h
MOV BYTE PTR DS:[BX]+67, 083h
MOV BYTE PTR DS:[BX]+68, 0E0h
MOV BYTE PTR DS:[BX]+69, 000h
MOV BYTE PTR DS:[BX]+70, 0F6h
; 10 строка
MOV BYTE PTR DS:[BX]+71, 0F4h
MOV BYTE PTR DS:[BX]+72, 000h
MOV BYTE PTR DS:[BX]+73, 0B2h
MOV BYTE PTR DS:[BX]+74, 085h
MOV BYTE PTR DS:[BX]+75, 000h
MOV BYTE PTR DS:[BX]+76, 0F6h
; 11 строка
MOV BYTE PTR DS:[BX]+77, 0F0h
MOV BYTE PTR DS:[BX]+78, 006h
MOV BYTE PTR DS:[BX]+79, 084h
MOV BYTE PTR DS:[BX]+80, 0B0h
MOV BYTE PTR DS:[BX]+81, 000h
MOV BYTE PTR DS:[BX]+82, 0F7h
; 12 строка
MOV BYTE PTR DS:[BX]+83, 0F0h
MOV BYTE PTR DS:[BX]+84, 000h
MOV BYTE PTR DS:[BX]+85, 0B4h
MOV BYTE PTR DS:[BX]+86, 084h
MOV BYTE PTR DS:[BX]+87, 0B1h
MOV BYTE PTR DS:[BX]+88, 000h
MOV BYTE PTR DS:[BX]+89, 0F7h
; 13 строка
MOV BYTE PTR DS:[BX]+90, 0F1h
MOV BYTE PTR DS:[BX]+91, 000h
MOV BYTE PTR DS:[BX]+92, 0B4h
MOV BYTE PTR DS:[BX]+93, 084h
MOV BYTE PTR DS:[BX]+94, 0B2h
MOV BYTE PTR DS:[BX]+95, 000h
MOV BYTE PTR DS:[BX]+96, 0F5h
; 14 строка
MOV BYTE PTR DS:[BX]+97, 0F2h
MOV BYTE PTR DS:[BX]+98, 000h
MOV BYTE PTR DS:[BX]+99, 0B3h
MOV BYTE PTR DS:[BX]+100, 084h
MOV BYTE PTR DS:[BX]+101, 0B3h
MOV BYTE PTR DS:[BX]+102, 000h
MOV BYTE PTR DS:[BX]+103, 0F4h
; 15 строка
MOV BYTE PTR DS:[BX]+104, 0F2h
MOV BYTE PTR DS:[BX]+105, 000h
MOV BYTE PTR DS:[BX]+106, 0B0h
MOV BYTE PTR DS:[BX]+107, 000h
MOV BYTE PTR DS:[BX]+108, 0B0h
MOV BYTE PTR DS:[BX]+109, 083h
MOV BYTE PTR DS:[BX]+110, 0B4h
MOV BYTE PTR DS:[BX]+111, 000h
MOV BYTE PTR DS:[BX]+112, 0F5h
; 16 строка
MOV BYTE PTR DS:[BX]+113, 0F3h
MOV BYTE PTR DS:[BX]+114, 000h
MOV BYTE PTR DS:[BX]+115, 0B0h
MOV BYTE PTR DS:[BX]+116, 000h
MOV BYTE PTR DS:[BX]+117, 0F0h
MOV BYTE PTR DS:[BX]+118, 003h
MOV BYTE PTR DS:[BX]+119, 0B4h
MOV BYTE PTR DS:[BX]+120, 000h
MOV BYTE PTR DS:[BX]+121, 0F4h
; 17 строка
MOV BYTE PTR DS:[BX]+122, 0F3h
MOV BYTE PTR DS:[BX]+123, 000h
MOV BYTE PTR DS:[BX]+124, 0F1h
MOV BYTE PTR DS:[BX]+125, 003h
MOV BYTE PTR DS:[BX]+126, 0B4h
MOV BYTE PTR DS:[BX]+127, 000h
MOV BYTE PTR DS:[BX]+128, 0F5h
; 18 строка
MOV BYTE PTR DS:[BX]+129, 0F4h
MOV BYTE PTR DS:[BX]+130, 000h
MOV BYTE PTR DS:[BX]+131, 0F1h
MOV BYTE PTR DS:[BX]+132, 000h
MOV BYTE PTR DS:[BX]+133, 0B1h
MOV BYTE PTR DS:[BX]+134, 001h
MOV BYTE PTR DS:[BX]+135, 0B1h
MOV BYTE PTR DS:[BX]+136, 000h
MOV BYTE PTR DS:[BX]+137, 0F5h
; 19 строка
MOV BYTE PTR DS:[BX]+138, 0F5h
MOV BYTE PTR DS:[BX]+139, 000h
MOV BYTE PTR DS:[BX]+140, 0F1h
MOV BYTE PTR DS:[BX]+141, 000h
MOV BYTE PTR DS:[BX]+142, 0F0h
MOV BYTE PTR DS:[BX]+143, 001h
MOV BYTE PTR DS:[BX]+144, 0F0h
MOV BYTE PTR DS:[BX]+145, 001h
MOV BYTE PTR DS:[BX]+146, 0F0h
MOV BYTE PTR DS:[BX]+147, 000h
MOV BYTE PTR DS:[BX]+148, 0F5h
; 20 строка
MOV BYTE PTR DS:[BX]+149, 0FFh
MOV BYTE PTR DS:[BX]+150, 0F6h

; ----------------------------------------------------------------
; Подготовка адресов дисплея
; ----------------------------------------------------------------

MOV SI, 0200h

; Начальный адрес в видеопамяти (отступ сверху отсутствует)
MOV DI, 0F600h
; Сдвиг вправо на 4 символа (4 символа * 2 байта = 8 байт)
ADD DI, 8

; DH — общее количество строк изображения
MOV DH, 20

row_loop:
    CMP DH, 0
    JE done          ; Если вывели все 20 строк, выходим

    ; CH — счетчик пикселей в текущей строке (ровно 23)
    MOV CH, 23

run_loop:
    ; Берём ОДИН упакованный байт (в нем и цвет, и количество)
    MOV BH, DS:[SI]
    INC SI

    ; Извлекаем старшие 4 бита — это цвет пикселя
    MOV AH, BH
    SHR AH, 1
    SHR AH, 1
    SHR AH, 1
    SHR AH, 1

    ; Извлекаем младшие 4 бита — это количество повторений минус 1
    MOV CL, BH
    AND CL, 0Fh
    INC CL           ; Делаем реальное количество (прибавляем 1)

draw_run:
    CALL draw_pixel

    DEC CH           ; Уменьшаем остаток пикселей в строке дисплея
    DEC CL           ; Уменьшаем остаток пикселей в текущей пачке (RLE)
    JNZ draw_run

    CMP CH, 0
    JNZ run_loop     ; Если строка еще не заполнена до 23, читаем следующий байт

    ; Переход на новую строку экрана:
    ; Ширина экрана = 64 символа (128 байт)
    ; Ширина рисунка = 23 пикселя. Из-за дублирования это 46 символов (92 байта)
    ; Свободный остаток в строке: 128 - 92 = 36 байт
    ADD DI, 36

    DEC DH
    JMP row_loop

; ----------------------------------------------------------------
; Подпрограмма вывода одного пикселя (с дублированием по горизонтали)
; ----------------------------------------------------------------
draw_pixel:
    MOV AL, 0DBh     ; Символ заливки (плотный блок)

    MOV ES:[DI], AX  ; Выводим пиксель
    ADD DI, 2

    MOV ES:[DI], AX  ; Дублируем пиксель справа
    ADD DI, 2

    RET

done:
    HLT              ; Остановка процессора