ZX Review #11-12
26 ноября 1997

Этюды - Ремейк процедур 93 года.

<b>Этюды</b> - Ремейк процедур 93 года.
┌──────────────────────────────┐
│                              │
│            ЭТЮДЫ             │
│                              │
└──────────────────────────────┘

Music by ZET and MITCHELL

(c) Колотов Сергей, г.Шадринск,
SerzhSoft, июль, 1997

    РЕМЕЙК НЕКОТОРЫХ ПРОЦЕДУР
            1993 ГОДА

   В ZX-РЕВЮ-93 с.121 была  опу-
бликована процедура  Н.М.Стинова
под  названием  DOORS, реализую-
щая эффект очистки экрана  путем
раздвигания изображения в сторо-
ны. Процедура занимает 101  байт
и, честно  говоря,  написана  не
очень  эффективно.  Использованы
альтернативные регистры, но  ре-
гистр HL так нигде и  не  сохра-
няется, что не дает  возможности
вызывать эту  процедуру  из  BA-
SIC'а. Применив команды  блочной
пересылки  LDIR и  LDDR, удалось
"сдружить"  новую  процедуру   с
бейсиком (благо в ней  альтерна-
тивные регистры  вообще  не  ис-
пользуются), более чем вдвое со-
кратить обьем занимаемой  памяти
и значительно  повысить  быстро-
действие. Новая процедура  также
стала  полностью   перемещаемой.
При очистке изображения на экра-
не устанавливаются текущие  сис-
темные атрибуты из ячейки 23693.
То есть  существует  возможность
изменить цвета прямо из  бейсика
командами  INK,  PAPER,  BRIGHT,
FLASH или напрямую подав  коман-
ду POKE  23693,n  перед  вызовом
процедуры по RANDOMIZE USR  adr.
Выполнив POKE adr+1,n (n=1..16),
можно   установить    количество
сдвигов, выполняемых за один за-
пуск процедуры.
140.
;  SCREEN-APART
3;(c) SerzhSoft, 11 july 1997
;
        ORG     60000        ;адрес ассемблирования
;
ATTR_P  EQU     23693        ;текущие атрибуты основного экрана
;
APART
        LD      B,#10        ;число пар сдвигов экрана в стороны
LP_APR1 PUSH    BC           ;сохраняем счетчик сдвигов на стеке
        LD      A,(ATTR_P)   ;A=атрибуты для заполн. после сдига
        LD      DE,#5AFF     ;самый последний байт атрибутов
LP_APR2 LD      H,D          ;скопировали этот адрес
        LD      L,E          ; в HL и уменьшили на 1:
        DEC     HL           ; адрес предпоследнего байта линии
        LD      BC,#000F     ;сдвигать: 15 байт
        LDDR                 ;сдвиг правой полу-линии вправо
        LD      (DE),A       ;устанавливаем новое значение
        LD      BC,#FFF2     ;коррекция р-ра HL - теперь он
        ADD     HL,BC        ; указывает на второй байт линии
        LD      E,L          ;DE=HL
        DEC     E            ;первый байт слева в линии
        LD      BC,#000F     ;будем сдвигать 15 байт
        LDIR                 ;сдвиг левой полу-линии влево
        LD      (DE),A       ;устанавливаем новый байт (очистка)
        LD      BC,#FFEF     ;коррекция регистра DE -
        ADD     HL,BC        ; переход на одну
        EX      DE,HL        ; линию вверх в экране (атрибутах)
        BIT     3,D          ;если атрибуты не кончились,
        JR      NZ,LP_APR2   ; то крутим цикл
        XOR     A            ;перешли в область графики
        BIT     6,D          ;если мы пока еще не залезли в ПЗУ,
        JR      NZ,LP_APR2   ; то продолжаем крутить цикл
        POP     BC           ;восстанавливаем счетчик сдвигов
        DJNZ    LP_APR1      ;крутим цикл положенное число раз
        RET                  ;выход из процедуры
2
   Шестнадцатеричный дамп проце-
дуры APART:

    EA60: 06 10 C5 3A 8D 5C 11 FF :58
    EA68: 5A 62 6B 2B 01 0F 00 ED :A1
    EA70: B8 12 01 F2 FF 09 5D 1D :99
    EA78: 01 0F 00 ED B0 12 01 EF :11
    EA80: FF 09 EB CB 5A 20 E2 AF :33
    EA88: CB 72 20 DD C1 10 D3 C9 :19

Сохранение: SAVE "aрart.c"  CODE
60000,48

   На  стр.35  ZX-РЕВЮ-93   была
опубликована программа  "теневой
контур". Мне удалось  существен-
но улучшить  эту  процедуру, для
этого просто переписав ее "с ну-
ля".  Новая  процедура  занимает
138 байт (старая - 211  байт)  и
стала релоцируемой. Как и  преж-
де, чтобы получить  псевдо-трех-
мерное  изображение,  достаточно
выделить атрибутами  с  повышен-
ной яркостью те места на экране,
которым необходима тень, и  выз-
вать  процедуру  SHADOW.  Сущес-
твует возможность изменять  кон-
фигурацию самой тени. Для  этого
необходимо поменять  значения  в
двух командах загрузки регистро-
вой  пары  DE, которые  помечены
звездочками.  В   представленной
программе  установлены  значения
#5500, #5500 соответственно, что
дает тень с  немного  закруглен-
ными  краями.  Подставив  #2A80,
#AA80, получим  тень  с  прямыми
краями. Чтобы  получить  тот  же
результат, что и в  оригинальном
варианте, необходимо  установить
#AA00,  #2A80.  Ну  а   значения
#7F80, #FF80 покажут Вам  сплош-
ную, нештрихованную  тень.
140.
;SHADOW-PROCESSOR
3; (c) SerzhSoft, 11 july 1997
;
        ORG     60000        ;адрес ассемблирования
SHADOW
        LD      HL,#5AFF     ;последний байт атрибутов
LP_SHD1 LD      BC,#0020     ;число байт в одной линии атрибутов
        DEC     HL           ;переход к предыдущему атрибуту
        BIT     3,H          ;мы еще не "заехали" в графику?
        RET     Z            ; если уже, то выход из процедуры
        BIT     6,(HL)       ;это атрибут с повышенной яркостью?
LP_SHD0 JR      Z,LP_SHD1    ; если нет, то предыдущий атрибут
        PUSH    HL           ;сохраняем адрес атрибута на стеке
        INC     L            ;переход к следующему атрибуту
        LD      A,L          ;проверка на переход
        AND     #1F          ; к следующей линии атрибутов
        JR      Z,GO_SHD2    ;если да, то перепрыгиваем
        BIT     6,(HL)       ;включена ли яркость?
        JR      NZ,GO_SHD2   ; если да, то перепрыгиваем
        PUSH    HL           ;сохраняем адрес атрибута на стеке
        ADD     HL,BC        ;переход к атрибуту на линию ниже
        LD      C,(HL)       ;поместили этот атрибут в регистр C
        POP     HL           ;восстанавливаем адрес атрибута
        LD      A,H          ;расчет адреса
        AND     #03          ; верхней линии
        RLCA                 ; знакоместа
        RLCA                 ; в экране
        RLCA                 ; по заданному
        OR      #40          ; адресу в
        LD      H,A          ; области атрибутов
        LD      DE,#5500     ;* образ для создания тени справа *
        LD      B,#0C        ;высота тени: 12 пикселов
LP_SHD2 LD      A,E          ;сдвигаемый байт образа линии тени
        AND     #F0          ;отбрасываем лишние "правые" биты
        OR      (HL)         ;накладываем содержимое экрана
        LD      (HL),A       ;и записываем новый байт в экран
        INC     H            ;----------------------------------
        LD      A,H          ;
        AND     #07          ;стандартная
        JR      NZ,GO_SHD0   ; последовательность
        LD      A,L          ; команд для перехода
        ADD     A,#20        ; на линию ниже
        LD      L,A          ; в экранной области
        JR      C,GO_SHD1    ;
        LD      A,H          ;
        SUB     #08          ;
        LD      H,A          ;----------------------------------
GO_SHD1 LD      A,H          ;старший байт адреса в графике
        CP      #58          ;провер. на выход за границы экрана
        JR      NC,GO_SHD2   ;если да, то перепрыгиваем
        BIT     6,C          ;проверка яркости: можно ли изобра-
        JR      NZ,GO_SHD2   ; жать тень. если нет, то прыжок
GO_SHD0 SRL     D            ;вращение образа
        RR      E            ; линии тени вправо
        DJNZ    LP_SHD2      ;цикл по числу линий в тени
GO_SHD2 POP     HL           ;восстанавливаем адрес атрибута
        PUSH    HL           ;сохраняем адрес атрибута на стеке
        LD      BC,#0020     ;число байт в одной линии атрибутов
        ADD     HL,BC        ;переход к атрибуту под текущим
        LD      A,H          ;проверка нового адреса атрибута
        CP      #5B          ; на вхождение в границы экрана
        JR      NC,GO_SHD4   ;если за пределами, то переход
        BIT     6,(HL)       ;если же входит в экран, но яркость
        JR      NZ,GO_SHD4   ; включена, то все равно - переход
        INC     L            ;следующий байт атрибутов (правый)
        LD      C,(HL)       ; помещаем в регистр C
        LD      A,H          ;расчет адреса
        AND     #03          ; верхней линии
        RLCA                 ; знакоместа
        RLCA                 ; в экране
        RLCA                 ; по заданному
        OR      #40          ; адресу в
        LD      H,A          ; области атрибутов
        LD      DE,#5500     ;* образ для создания тени снизу *
        LD      B,#04        ;высота тени снизу
LP_SHD3 DEC     L            ;возврат на байт назад
        LD      A,(HL)       ;взяли байт с экрана
        OR      D            ;наложили левый байт образа линии
        LD      (HL),A       ; тени и поместили назад в экран
        INC     L            ;переход на байт вправо
        LD      A,L          ;проверка на выход
        AND     #1F          ; за правую границу экрана:
        JR      Z,GO_SHD3    ; если да, то перепрыгиваем
        BIT     6,C          ;если же атрибут с яркостью,
        JR      NZ,GO_SHD3   ; то так же - перепрыгиваем
        LD      A,(HL)       ;взяли байт с экрана
        OR      E            ;наложили правый байт образа линии
        LD      (HL),A       ; тени и поместили назад в экран
GO_SHD3 INC     H            ;переход к следующей линии
        SRL     D            ;вращение образа одной
        RR      E            ; линии тени вправо
        DJNZ    LP_SHD3      ;цикл по числу линий в образе тени
GO_SHD4 POP     HL           ;восстанавливаем адрес атрибута
        XOR     A            ;уст. флаг Z, чтобы JR Z сработала
        JR      LP_SHD0      ;переходим на команду JR Z,LP_SHD1
2
   Шестнадцатеричный дамп проце-
дуры SHADOW:

    EA60: 21 FF 5A 01 20 00 2B CB :DB
    EA68: 5C C8 CB 76 28 F5 E5 2C :E5
    EA70: 7D E6 1F 28 3A CB 76 20 :9F
    EA78: 36 E5 09 4E E1 7C E6 03 :1A
    EA80: 07 07 07 F6 40 67 11 00 :2D
    EA88: 55 06 0C 7B E6 F0 B6 77 :57
    EA90: 24 7C E6 07 20 13 7D C6 :7D
    EA98: 20 6F 38 04 7C D6 08 67 :0E
    EAA0: 7C FE 58 30 0A CB 71 20 :F2
    EAA8: 06 CB 3A CB 1B 10 DC E1 :50
    EAB0: E5 01 20 00 09 7C FE 5B :7E
    EAB8: 30 2C CB 76 20 28 2C 4E :01
    EAC0: 7C E6 03 07 07 07 F6 40 :5A
    EAC8: 67 11 00 55 06 04 2D 7E :34
    EAD0: B2 77 2C 7D E6 1F 28 07 :C0
    EAD8: CB 71 20 03 7E B3 77 24 :ED
    EAE0: CB 3A CB 1B 10 E8 E1 AF :3D
    EAE8: 18 82 00 00 00 00 00 00 :6C

Сохранение: SAVE "shadow.c" CODE
60000,13

   В ZX-РЕВЮ-93 на стр.117  была
напечатана процедура LOOK  BASIC
PROGRAMMS, автор - Бессонов Але-
ксандр. Она занимает 344  байта,
что на мой  взгляд - просто  ко-
щунственно! Мне  удалось  сокра-
тить  эту  программу  более  чем
вдвое (точнее, переписать ее за-
ново). Принцип работы  почти  не
изменился, правда, появилась од-
на новая возможность. При  печа-
ти обозначения какого-либо упра-
вляющего кода вслед за ним выво-
дится  значение  его  параметра.
Например,  после  упр.  кода  16
(INK CTRL)  идет  байт  значения
цвета, что на экране будет  выг-
лядеть примерно так:  I[7]  (все
инверсно). А после кодов 22 и 23
(AT CTRL, TAB CTRL) должно  сле-
довать  два  значения:  A[2][10]
или T[18][0].  В остальном прог-
рамма  работает  так  же, как  и
оригинал. Процедура занимает 158
байт.
140.
;
;   LOOK BASIC PROGRAMS II
3; (c) SerzhSoft, 11 july 1997
;
        ORG     65000        ;адрес ассемблирования
;
PROG    EQU     #5C53 ;сист. пер. "адрес начала BASIC-программы"
VARS    EQU     #5C4B ;сис. пер. "адрес начала BASIC-переменных"
;
OUT_NUM_2 EQU   #1A28 ;сис. пр-ра "печать номера строки (HL)"
CHAN_OPEN EQU   #1601 ;сис. пр-ра "открытие канала вывода"
STACK_NUM EQU   #33B4 ;сис. пр-ра "поместить (HL) на стек к-ра"
STACK_A   EQU   #2D28 ;сис. пр-ра "поместить A на стек кальк-ра"
STACK_BC  EQU   #2D2B ;сис. пр-ра "поместить BC на стек к-ра"
PRINT_FP  EQU   #2DE3 ;сис. пр-ра "печать содержимого стека к."
;
LBP_2
        LD      A,#02        ;открываем канал вывода
        CALL    CHAN_OPEN    ; на основной экран
        LD      HL,(PROG)    ;адрес начала BASIC-программы
LP_LBP1 LD      DE,(VARS)    ;адрес начала BASIC-переменных
        AND     A            ;сброс флага переноса для SBC
        SBC     HL,DE        ;проверка на окончание программы
        RET     NC           ;если HL>=DE, то выход из процедуры
        ADD     HL,DE        ;восстанавливаем значение HL
        PUSH    HL           ;сохраняем адрес строки на стеке
        CALL    OUT_NUM_2    ;печать номера строки
        POP     HL           ;восстан-ем адрес строки со стека
        PUSH    HL           ; и - опять же - сохраняем
        LD      B,H          ;скопировали
        LD      C,L          ; HL в BC


140.        CALL    PRN_BC       ;распечатали адрес строки в памяти
        POP     HL           ;восстан-ем адрес строки со стека
        INC     HL           ;переход к
        INC     HL           ; длине строки
        LD      C,(HL)       ;младший байт длины строки
        INC     HL           ;дальше
        LD      B,(HL)       ;старший байт длины строки
        INC     HL           ;переход к содержимому строки
        PUSH    HL           ;сохраняем адрес на стеке
        CALL    PRN_BC       ;печать длины текущей BASIC-строки
        POP     HL           ;восстанавливаем адрес со стека
LP_LBP2 LD      A,(HL)       ;текущий символ строки
        INC     HL           ;переход к следующему
        CP      #0D          ;проверка на конец строки
        JR      Z,GO_LBP1    ;если да, то переход на обработку
        LD      DE,LP_LBP2   ;адрес цикла по символам кидаем на
        PUSH    DE           ; стек, чтобы "вернуться" по RET
        CP      #0E          ;наткнулись на число?
        JR      Z,GO_LBP2    ; если да, то переход на обработку
        CP      #08          ;код сдвига на одну позицию назад?
        JR      Z,GO_LBP3    ;если да, то обрабатываем
        CP      #10          ;если код символа меньше 16,
        JR      C,GO_LBP0    ; то печатаем его и -> к сл. симв.
        CP      #18          ;если 16 <= код символа <= 23,
        JR      C,GO_LBP4    ; то переход на обработку упр. кода
GO_LBP0 RST     #10          ;печать одного символа
        RET                  ;переход на LP_LBP2
;
GO_LBP1 RST     #10          ;печать кода #0D - перевод строки
        LD      A,#0D        ;и еще раз
        RST     #10          ; переводим строку
        JR      LP_LBP1      ;переход к следующей BASIC-строке
;
GO_LBP2 PUSH    HL           ;сохраняем адрес на стеке
        CALL    STACK_NUM    ;5-байтное число -> на стек кальк.
        CALL    PRN_NUM      ;печатаем его
        POP     HL           ;восстанавливаем адрес со стека
        LD      BC,#0005     ;переход к символу BASIC-строки за
        ADD     HL,BC        ; данным 5-байтным числом
        RET                  ;переход на LP_LBP2
;
GO_LBP3 ADD     A,#07        ;корректировка кода для #08
GO_LBP4 SUB     #0F          3;получили число #00...#07 и занесли
        LD      C,A          ; его в BC - это индекс (позиция)
        LD      B,#00        ; обозначения упр. кода в таблице
        PUSH    HL           ;сохраняем адрес на стеке
        LD      HL,TBLCODE   ;адрес таблицы обозначений упр. к.
        ADD     HL,BC        ;адресовали элемент в этой таблице
        SET     2,(IY+87)    ;включить инверсию при печати
        LD      A,(HL)       ;взяли обозн. упр. кода из таблицы
        RST     #10          ;напечатали его (обозначение)
        RES     2,(IY+87)    ;отключаем инверсию при печати
        POP     HL           ;восстанавливаем адрес со стека
        LD      A,C          ;определяем размер управл. кода:
        OR      A            ;если это был код #08,
        RET     Z            ;то выходим (у него нет параметров)
        CP      #06          ;если это были коды #16, #17, то
        CALL    NC,GO_LBP5   ; надо печатать два пераметра
GO_LBP5 LD      A,(HL)       ;взяли один байт из памяти (пар-р)
        PUSH    HL           ;сохраняем адрес на стеке
        CALL    STACK_A      ;забрасываем значение A на стек к.
        CALL    PRN_NUM      ;печатаем это значение (параметр)
        POP     HL           ;восстанавливаем адрес со стека
        INC     HL           ;переход к след. символу в строке
        RET                  ;"возврат" на GO_LBP5 или LP_LBP2
;
PRN_BC  CALL    STACK_BC     ;помещаем BC на стек калькулятора
;
PRN_NUM SET     2,(IY+87)    ;включить инверсию при печати
        LD      A,"["        ;распечатываем
        RST     #10          ; левую скобку (открывающую),
        CALL    PRINT_FP     ; затем - число со стека кальк-ра,
        LD      A,"]"        ; и, наконец печатаем
        RST     #10          ; правую скобку (закрывающую)
        RES     2,(IY+87)    ;отключаем инверсию при печати
        RET                  ;возврат из подпрограммы
;
TBLCODE DB      "<IPFBVAT"   ;таблица обозначений управл. кодов
2
   Шестнадцатеричный дамп проце-
дуры LBP_2:

    FDE8: 3E 02 CD 01 16 2A 53 5C :E2
    FDF0: ED 5B 4B 5C A7 ED 52 D0 :92
    FDF8: 19 E5 CD 28 1A E1 E5 44 :0C
    FE00: 4D CD 69 FE E1 23 23 4E :F4
    FE08: 23 46 23 E5 CD 69 FE E1 :8C
    FE10: 7E 23 FE 0D 28 16 11 10 :19
    FE18: FE D5 FE 0E 28 14 FE 08 :37
    FE20: 28 1D FE 10 38 04 FE 18 :C3
    FE28: 38 17 D7 C9 D7 3E 0D D7 :0E
    FE30: 18 BE E5 CD B4 33 CD 6C :D6
    FE38: FE E1 01 05 00 09 C9 C6 :B3
    FE40: 07 D6 0F 4F 06 00 E5 21 :85
    FE48: 7E FE 09 FD CB 57 D6 7E :3E
    FE50: D7 FD CB 57 96 E1 79 B7 :EB
    FE58: C8 FE 06 D4 5E FE 7E E5 :B5
    FE60: CD 28 2D CD 6C FE E1 23 :BB
    FE68: C9 CD 2B 2D FD CB 57 D6 :49
    FE70: 3E 5B D7 CD E3 2D 3E 5D :56
    FE78: D7 FD CB 57 96 C9 3C 49 :50
    FE80: 50 46 42 56 41 54 00 00 :41

Сохранение: SAVE "lbp_02.c" CODE
65000,15

           *   *   *




Другие статьи номера:

Авторская разработка - С.Зонов, А.Ларченко. О контроллере SMUC (HDD и IBM периферия).

Компьютерная новелла - Воины Звезд (по игре Shadowfire).

Новые программы - Обзор Digital Studio v1.12, Digital Studio Compiler v1.01

Новые программы - Обзор Xas редактор-ассемблер 128К (v5.05).

Новые программы - Обзор Музыкального редактора Instrument v3.01

Новые программы - Обзор программ FASTzasm и @-zasm.

Новые программы - Обзор программы No Kempston.

Профессиональный подход - Алгоритмы построения и прохождения Лабиринтов.

Смех без причины... - Материалы из юмористического журнала SpectrofUn.

Советы экспертов - Игра FEUD.

Советы экспертов - Игра Killed Until Dead.

Советы экспертов - Игра War in Middle Earth.

Форум - Конверсия цветной спектрумовской картинки на IBM. Конверсия ч/б картинки с IBM на ZX Spectrum.

Форум - О русификации игровых программ.

Форум - Программа детекта эмулятора.

Форум - Процедура "цветные полосы на бордюре". Снижение шума FDD.

Форум - Процедура перевода числа в десятичный вид. Процедура - сканер пароля.

Форум - Снятие защиты Microprotector'а.

Форум - Эмуляторы, которые мы выбираем: 'UKV Spectrum Debugger', 'Z80TRDOS'.

Читатель-читателю - Драйвер ввода в режимах последовательного и прямого доступа из файлов системы TR-DOS.

Этюды - Графический эффект "плазма 2".

Этюды - Графический эффект "плазма 2".

Этюды - Графический эффект "плазма".

Этюды - Полезные советы. Быстрая переброска экрана.

Этюды - Ремейк процедур 93 года.

Этюды - Эффект "пламя".


Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
CHEATING - CHEAT к игре Sextris и коды бессмертия к играм : After the War 1 & 2, Nany Moves 1 & 2
Анекдоты - расслабуха.
Video - Конвертирование анимации на примере атрибутного видео.
Мысли - Crank заплатит любому 1000р за переделку STS под Scorpion.
Семь и 1/2 - Рассказ "Падал прошлогодний снег".

В этот день...   21 ноября