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



         

СПРАЙТ-ГЕНЕРАТОР - часть 5


Подпрограмма RAMKA выводит на экран пунктирный прямоугольник, отмечающий границы создаваемого спрайта. Вывод производится по принципу XOR, поэтому при повторном обращении к процедуре прежний вид экрана полностью восстанавливается.

Подпрограмма SVSCR нужна для сохранения экранного изображения в памяти для последующего его восстановления процедурой RESTOR.

В пакет включены также две описанные ранее процедуры CLSV и SETV для очистки окна экрана и установки в нем постоянных атрибутов.

ORG 65000 ORIGIN EQU $ ;верхняя допустимая граница спрайт-файла ADDR EQU 23670 ;текущий адрес в спрайт-файле ATTR EQU 23695 ;значение атрибутов окна SCREEN EQU 30000 ;адрес «теневого» экрана N_SYM EQU 23300 ;рассчитанная в Бейсике площадь спрайта COL EQU 23301 ;координаты спрайта ROW EQU 23302 LEN EQU 23303 ;размеры спрайта HGT EQU 23304 ; 65000 JP RAMKA ; 65003 JP SVSCR ; 65006 JP RESTOR ; 65009 JP CLSV ; 65012 JP SETV ; 65015 GTBL CALL RESTOR ;восстанавливаем экранную картинку LD (__SP),SP ;запоминаем состояние стека для ; возврата при возникновении ошибки LD IX,(ADDR) ;адрес конца спрайт-файла ; Формирование заголовка LD A,(N_SYM) ;количество знакомест ; в создаваемом спрайте CALL OUT_BT ;записываем первый байт в спрайт-файл LD A,(ROW) ;вычисляем адрес атрибутов LD L,A LD H,0 ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL LD A,#58 ADD A,H LD H,A LD A,(COL) ADD A,L LD L,A LD DE,(LEN) LD BC,0 GTBL1 PUSH BC PUSH DE PUSH HL GTBL2 LD A,B CALL OUT_BT ;позиция по вертикали внутри спрайта LD A,C CALL OUT_BT ;позиция по горизонтали LD A,(HL) CALL OUT_BT ;байт атрибутов INC HL INC C DEC E JR NZ,GTBL2 POP HL LD DE,32 ;переходим к следующей строке ADD HL,DE POP DE POP BC INC B DEC D JR NZ,GTBL1 ; Данные состояния пикселей LD A,(HGT) LD B,A LD A,(ROW) GTBL3 PUSH AF PUSH BC CALL 3742 ;вычисляем адрес начального знакоместа LD A,(COL) ADD A,L LD L,A LD A,(LEN) LD B,A GTBL4 PUSH BC PUSH HL LD B,8 ;переписываем в спрайт-файл 8 байт ; знакоместа GTBL5 LD A,(HL) CALL OUT_BT INC H DJNZ GTBL5 POP HL INC HL ;переходим к следующему знакоместу POP BC DJNZ GTBL4 POP BC POP AF INC A ;переходим к следующей строке DJNZ GTBL3 PUSH IX ;возвращаем в Бейсик адрес POP BC ; конца спрайт-файла RET OUT_BT PUSH BC ;запись в спрайт-файл байта из A PUSH HL ; Проверка наличия свободной памяти PUSH IX POP HL LD BC,ORIGIN ;адрес конца свободной памяти ; для спрайт-файла AND A ;очистка флага CY перед вычитанием ; (если этого не сделать, результат будет неверен!) SBC HL,BC ;если текущий адрес достиг ORIGIN, JR NC,OUTRAM ; происходит выход в Бейсик POP HL POP BC LD (IX),A ;записываем байт в спрайт-файл INC IX ;увеличиваем адрес размещения кодов RET OUTRAM LD SP,(__SP) ;восстанавливаем значение стека LD BC,0 ;возвращаем в Бейсик код ошибки RET __SP DEFW 0 ;переменная для сохранения указателя стека ; Рисование прямоугольной пунктирной рамки RAMKA LD A,(ROW) PUSH AF CALL 3742 ;вычисляем адрес экрана LD A,(COL) ADD A,L LD L,A CALL HOR ;проводим верхнюю линию CALL VERT1 ;рисуем боковые стороны в первой ; строке окна LD A,(HGT) DEC A JR Z,RAMK2 ;обходим, если единственная строка LD B,A ;иначе рисуем боковые стороны по всей ; высоте окна POP AF RAMK1 PUSH AF CALL VERT ;заканчиваем предыдущую строку POP AF INC A ;переходим к следующей PUSH AF CALL 3742 ;вычисляем адрес экрана LD A,(COL) ADD A,L LD L,A CALL VERT ;ставим верхние точки CALL VERT1 ;заканчиваем вертикальный пунктир POP AF DJNZ RAMK1 ;повторяем PUSH AF RAMK2 POP AF ; Горизонтальная пунктирная линия HOR PUSH BC PUSH HL LD A,(LEN) ;рисуем пунктир по ширине окна LD B,A HOR1 LD A,%10011001 ;фактура пунктирной линии XOR (HL) ;объединяем с экранным изображением LD (HL),A ;возвращаем на экран INC HL DJNZ HOR1 POP HL POP BC RET ; Рисование двух точек для боковых сторон рамки VERT PUSH HL LD A,128 ;левая точка XOR (HL) LD (HL),A LD A,(LEN) ;ищем адрес правой стороны окна DEC A ADD A,L LD L,A LD A,1 ;правая точка XOR (HL) LD (HL),A POP HL RET ; Боковые стороны рамки по высоте знакоместа VERT1 INC H ;пропускаем 3 ряда пикселей INC H INC H CALL VERT ;ставим точки на левой и правой ; сторонах прямоугольника INC H CALL VERT ;повторяем для следующего ряда INC H ;делаем следующий промежуток INC H INC H RET ; Сохранение области видеобуфера в «теневом» экране SVSCR LD HL,16384 LD DE,SCREEN LD BC,6912 LDIR RET ; Восстановление изображения на экране RESTOR LD HL,SCREEN LD DE,16384 LD BC,6912 LDIR RET ; Подпрограмма очистки окна

; Подпрограмма установки атрибутов в окне




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