Как написать игру для ZX Spectrum на ассемблере


         

Прежде чем привести ее текст,


Прежде чем привести ее текст, объясним смысл вновь встретившейся здесь команды. Это инструкция EX (SP),HL, которая обменивает содержимое регистровой пары HL со значением, находящимся на вершине машинного стека: то, что было в HL, помещается на вершину стека, а два байта со стека перемещаются в HL. Значение регистра SP при этом не изменяется. Обратите внимание на то, как в подпрограмме WRITE2 осуществляется переход по выбранному адресу: число заносится в стек командой EX (SP),HL, а затем выполняется команда RET.

Другой момент, требующий пояснения, это процедура, расположенная в ПЗУ по адресу 8, благодаря чему ее можно вызывать командой RST. Она используется интерпретатором для выдачи различных сообщений и с ее помощью можно в любой момент остановить практически любую программу в кодах при возникновении критической ошибки. Код сообщения, уменьшенный на единицу (например, -1 для 0 OK), записывается в директиве DEFB непосредственно за командой RST 8.

WRITE LD A,(HL) ;берем очередной символ из строки INC HL AND A RET Z ;вывод символов до кода 0 CP " " JR C,WRITE2 ;если управляющий код (< 32) WRITE1 CALL PRSYM JR WRITE ; Выбор из таблицы адреса перехода в зависимости от кода WRITE2 PUSH HL PUSH BC LD HL,TABLE ;адрес таблицы LD C,A ;сохраняем код в C WRITE3 LD A,(HL) ;читаем код из таблицы INC HL AND A JR Z,WRITE5 ;если встречен маркер конца таблицы CP C JR Z,WRITE4 ;если код найден INC HL ;пропускаем 2 байта адреса INC HL JR WRITE3 ;проверяем следующий код WRITE4 POP BC LD A,(HL) ;берем из таблицы адрес перехода INC HL LD H,(HL) ;помещаем его в HL LD L,A EX (SP),HL ;восстанавливаем HL, а адрес записываем ; на вершину стека RET ;переходим по адресу с вершины стека WRITE5 POP BC ;если код отсутствует в таблице, POP HL ; то восстанавливаем регистры LD A,"?" ; и печатаем символ ?

JR WRITE1 ; Перевод строки PR_13 PUSH HL LD HL,(23684) ;адрес текущей позиции печати LD A,L AND %11100000 ;возвращаемся к началу строки ADD A,#20 ;переходим к следующей строке LD L,A JR NZ,PR13_1 ;если не перешли в следующую треть LD A,H ADD A,8 ;старший байт адреса увеличиваем на 8 LD H,A CP #58 ;проверяем, был ли выход за пределы экрана JR C,PR13_1 LD H,#40 ;переводим позицию печати в верхнюю ; строку экрана PR13_1 LD (23684),HL ;возвращаем рассчитанный адрес ; позиции печати POP HL JR WRITE ; Цвет «чернил» INK PR_16 LD A,(HL) ;читаем следующий байт из строки AND %111 ;выделяем 3 младших бита (значения 0...7) PUSH BC LD B,%11111000 ;в регистре B - маска битов для INK PR16_1 LD C,A LD A,(IY+85) ;23695 AND B ;освобождаем биты предыдущего атрибута OR C ; и записываем на их место новое значение LD (IY+85),A ;возвращаем байт атрибутов PR16_2 POP BC INC HL JR WRITE ; Цвет «бумаги» PAPER PR_17 LD A,(HL) ;с цветом PAPER аналогично INK AND %111 RLCA ; только предварительно сдвигаем RLCA ; биты на свое место RLCA PUSH BC LD B,%11000111 JR PR16_1 ; Мерцание FLASH PR_18 LD A,(HL) AND 1 PUSH BC LD B,%01111111 PR18_1 RRCA JR PR16_1 ; Яркость BRIGHT PR_19 LD A,(HL) AND 1 PUSH BC LD B,%10111111 RRCA JR PR18_1 ; Инверсия INVERSE (3-й бит в системной переменной P_FLAG) PR_20 LD A,(HL) AND 1 PUSH BC LD B,%11110111 RLCA RLCA PR20_1 RLCA LD C,A LD A,(IY+87) AND B OR C LD (IY+87),A JR PR16_2 ; Режим наложения OVER (1-й бит в системной переменной P_FLAG) PR_21 LD A,(HL) AND 1 PUSH BC LD B,%11111101 JR PR20_1 ; Позиционирование курсора AT PR_22 LD A,(HL) ;берем номер строки CP 24 ;если больше 24, то выход позиции JR NC,OUTSCR ; печати за пределы экрана INC HL PUSH DE PUSH HL CALL 3742 ;вычисляем адрес начала строки POP DE LD A,(DE) ;берем номер столбца CP 32 ;если больше 32, то выход позиции JR NC,OUTSCR ; печати за пределы экрана INC DE ADD A,L LD L,A LD (23684),HL ;запоминаем адрес новой позиции POP HL EX DE,HL JP WRITE OUTSCR RST 8 ;сообщение Бейсика DEFB 4 ; «Out of screen»


Содержание  Назад  Вперед