__________________________________________
(C) KAPsoft '2000
__________________________________________
К ВОПРОСУ ...
В своей небольшой статье я постарался
осветить некоторые вопросы, с которыми
столкнулся в последнее время. В основном
этот материал рассчитан на программиста,
но и другим не мешало бы его почитать.
...О КОНВЕРСИИ
В Deja Vu #08 была статья о конверсии
SCREEN'ов в текстовые файлы. Идея была та-
кова: подсчитываем количество включенных
пикселов (точек) в блоке (8 на 4), и,в со-
ответствии с их количеством,ставим тот или
иной символ.
Я предлагаю другой алгоритм. Опишу
вкратце его суть. На рассматреваемый блок
накладываем по очереди все символы загру-
женного FONT'а. Подсчитываем количество
совпадений (одинакого включенных или вык-
люченных пикселов). Тот символ, у которого
совпадений больше, ставим вместо блока.
Повторяем все для остальных блоков.
Да,это все будет работать довольно мед-
ленно. Но и качество будет лучше.
Вот листинг программы, выполняющей та-
кую конверсию.
DEMO CALL START
LD A,2
CALL #1601
LD A,22
RST 16
XOR A
RST 16
XOR A
RST 16
LD BC,768
LD DE,TEXT
JP #203C
;
START LD HL,#4000
LD DE,TEXT
CALL ST1
LD HL,#4800
CALL ST1
LD HL,#5000
JP ST1
;
ST1 LD BC,256
LOOP PUSH BC
PUSH DE
LD DE,15616
LD B,96
XOR A
LD (NUM+1),A
LD (NUP+1),A
DEC A
LD (RAZL+1),A
N_4 PUSH BC
LD C,0
PUSH HL
LD A,8
N_2 PUSH AF
LD A,(DE)
XOR (HL)
LD B,8
N_1 RRA
JR NC,NO
INC C
NO DJNZ N_1
INC DE
INC H
POP AF
DEC A
JR NZ,N_2
LD HL,NUP+1
INC (HL)
RAZL LD A,0
POP HL
CP C
JR C,N_3
NUP LD A,0
DEC A
LD (NUM+1),A
LD A,C
N_3 POP BC
LD (RAZL+1),A
DJNZ N_4
NUM LD A,0
ADD A,32
POP DE
LD (DE),A
INC DE
POP BC
INC L
DEC BC
LD A,B
OR C
JR NZ,LOOP
RET
В программе есть некоторые интересные
приемчики.
Например, если у вас в прогах есть та-
кие строки:
LD (МЕТКА),A
...
LD A,(МЕТКА)
...
METKA DEFB 0,
то их можно заменить на:
LD (METKA+1),A
...
METKA LD A,0
Т.е. хранить переменные в тексте самой
программы.
Сравнение происходит с помощью XOR'ива-
ния байтов и подсчета включенных битов.Ес-
ли биты одинаковы (1-1 или 0-0), то после
XOR'ки получаются 0, а если разные, то 1.
Т.к. нам нужны различия, то подсчитываем
нули командой JR NC,S.
В этой программе блоком является одно
знакоместо,и сравнение происходит со стан-
дартным SPECTRUM'овским FONT'ом, располо-
женным в ПЗУ.
Это лишь пример,серьезную программу на-
до делать более универсально: различные
размеры блока, подгружаемый FONT и т.п.
...О СТРЕЛКАХ.
А точнее о стрелочных интерфейсах. Во
всех виденных мною "интеллектуальных" ин-
терфейсах (таких, что если вы долго давите
джойстик в одном направлении, то скорость
курсора - стрелки увеличивается) скорость
увеличивается в одном направлении, и ее
сброс на начальную происходит при любом
движении джойстика.
Я предлагаю другой алгоритм. Скорость
изменяется для четырех направлений отдель-
но. Если пользователь не давит в каком-ли-
бо направлении, то скорость в этом направ-
лении сбрасывается на начальное значение.
Вот листинг:
ORG 30000
ENT
LD DE,#8080 ;Начальные
START HALT ;координаты
LD HL,TABL
IN A,(#1F) ;Опросили джойстик
BIT 0,A ;Вправо ?
PUSH AF
LD A,#3C
LD (LOOP),A
LD A,#51
LD (SBROS),A
LD A,#57
LD (REG),A
CALL NZ,MOVE ;Да - двигаемся
POP AF
CALL Z,SBR ;Нет - сброс
BIT 1,A ;Влево ?
PUSH AF
LD A,#3D
LD (LOOP),A
CALL NZ,MOVE
POP AF
CALL Z,SBR
BIT 2,A ;Вниз ?
PUSH AF
LD A,#5F
LD (REG),A
LD A,#59
LD (SBROS),A
CALL NZ,MOVE
POP AF
CALL Z,SBR
BIT 3,A ;Вверх ?
PUSH AF
LD A,#3C
LD (LOOP),A
CALL NZ,MOVE
POP AF
CALL Z,SBR
BIT 4,A ;Огонь - выход
RET NZ
LD C,D ;Рисуем точку с
LD B,E ;помощью программы
PUSH DE ;ПЗУ по адресу ┐
CALL #22E5 ; <────────────┘
POP DE
JR START
;
MOVE LD A,(REG) ;Подпрограмма
CP #57 ;перемещения
LD A,E
JR NZ,NEXT
LD A,D
NEXT LD C,(HL)
INC HL
LD B,(HL)
LOOM CP C
JR Z,SBROS
LOOP INC A ;или DEC A
DJNZ LOOM
REG LD D,A ;или LD E,A
INC HL
DEC (HL)
JR NZ,L_1
LD (HL),24 ;Время закончи-
DEC HL ;лось - увеличиваем
INC (HL) ;скорость
INC HL
L_1 INC HL
RET
;
SBROS LD D,C ;или LD E,C
JR CONT
SBR INC HL ;Сброс скорости и
LD (HL),1 ;времени на началь-
INC HL ;ные значения.
LD (HL),24
INC HL
RET
;
TABL DEFB 255,1,24 ;Первое - MAX/MIN
DEFB 0,1,24 ;Второе - скорость
DEFB 0,1,24 ;Третье - время
DEFB 175,1,24
Для упрощения вместо стрелки использу-
ется точка. Для того, чтобы бегала стре-
лочка, вместо CALL #22E5 поставьте вызов
своей процедуры вывода стрелки.
Чтобы точка бегала быстрее,можете умень-
шать значение времени, но не в таблице, а
в строках LD (HL),24 в конце процедур MOVE
и SBROS. Также можно участить вызов проце-
дуры (в этой программе-один раз в прерыва-
ние или 50 раз в секунду).
...О МНОГОЗАДАЧНОСТИ.
Как вы знаете, процессоры Intel способ-
ны выполнять несколько программ одновре-
менно. На самом деле они, конечно же, не
работают все сразу. Операционная система
запускает маленький кусочек одной програм-
мы, потом кусочек другой, третьей. И поль-
зователям кажется, что все они работают
одновременно.
Мне пришла в голову (бредовая ?) идея -
попробовать создать такую систему на SPEC-
CY. На первой же минуте обдумывания встала
проблема:КАК ПРЕРЫВАТЬ ПРОЦЕССОР ПОСЛЕ НЕ-
КОТОРОГО ВРЕМЕНИ? На РС все просто: есть
специальные прерывания.Так бы и канула эта
идея в лету, если бы не вторая моя идея:
IM 2. Но оно уже задействовано под опрос
клавиатуры, музоны и т.д.
Что поделаешь, программы под такую сис-
тему придется писать особые. Но это, как
говорится, если прижмет (сильно надо бу-
дет), то сделают. Причем,сама система тра-
тит около 1% процессорного времени. А вы-
зов музонов и др. осуществляется как и без
системы, т.е. 50 раз в секунду.
Итак, идея:
* Для каждой программы создается лич-
ный стек.
* Подключается первый, и запускается
первая программа.
┌>* Когда приходит прерывание, запуска-
│ ется система, которая сохраняет все
│ регистры процессора в стеке выпол-
│ няемой программы. Она запоминает
│ значение стека в специальной табли-
│ це. Подключается стек для следующей
│ задачи, с него берутся значения ре-
│ гистров и адрес запуска(или продол-
│ жения, если это не запуск).
│ * Запускается вторая программа.
└─┘
Вот листинг :
ORG 30000
ENT
DEMO DI
LD HL,KOL+1
LD (HL),3
LD HL,PROG2
LD (29022),HL
LD A,#7F
LD I,A
LD HL,INT
LD (#7FFF),HL
IM 2
EI
;
PROG1 LD A,#87
LD (#5800),A
LD A,#7F
IN A,(#FE)
AND #1F
XOR #1F
JR Z,PROG1
DI
LD A,63
LD I,A
IM 1
EI
RET
;
PROG2 LD A,#78
LD (#581F),A
JR PROG2
;
NUMB DEFB 0
TABL1 DEFB 0,1,0
TABL2 DEFW 0,29000
;
INT PUSH AF
LD A,R
PUSH AF
PUSH DE
PUSH BC
PUSH HL
PUSH IX
PUSH IY
EX AF,AF'
PUSH AF
EXX
PUSH DE
PUSH BC
PUSH HL
LD A,(NUMB)
LD E,A
LD D,0
LD HL,TABL1
ADD HL,DE
LD A,(HL)
ADD A,A
LD E,A
LD HL,TABL2
ADD HL,DE
LD A,L
LD (KK+2),A
LD A,H
LD (KK+3),A
KK LD (#FFFF),SP
;Здесь можно поставить вызовы ваших
;программ обработки прерываний
;типа CALL MYINT
LD A,(NUMB)
INC A
KOL CP 3
JR NZ,OBHOD
LD A,0
OBHOD LD (NUMB),A
LD HL,TABL1
LD E,A
ADD HL,DE
LD A,(HL)
ADD A,A
LD E,A
LD HL,TABL2
ADD HL,DE
LD A,L
LD (LL+2),A
LD A,H
LD (LL+3),A
LL LD SP,(#FFFF)
POP HL
POP BC
POP DE
EXX
POP AF
AX AF,AF'
POP IY
POP IX
POP HL
POP BC
POP DE
POP AF
SUB 7
LD R,A
POP AF
EI
RET
Часть DEMO - демонстация. Сама система
начинается с NUMB.
Как ей пользоваться ?
1.Определяетесь,сколько программ вам нуж-
но использовать.
2.По адресу KOL+1 заносите это число :
LD HL,KOL+1
LD (HL),N
3.Для каждой выделяете место для стека.
4.По адресу STACK+22 каждой программы за-
носите адрес ее запуска.
5.Составляете таблицу вызова задач.
Например :
TABL1 DEFB 0
DEFB 1
DEFB 0
DEFB 2
DEFB 0
Где 0,1,2 - номера программ (соответс-
твенно 1-ая, 2-ая и 3-я). При такой
таблице 1-ой задаче отводится 3/5*100=
=60% времени. 2-ой и 3-ей -по 1/5*100=
=20% времени.
6.В TABL2 заносите адреса стеков задач :
TABL2 DEFW STACK0
DEFW STACK1
DEFW STACK2
7.Устанавливаете в регистре SP адрес сте-
ка первой задачи :
LD SP,STACK0
8.Переустанавливаете прерывания :
DI
LD A,#NN
LD I,A
LD HL,INT
LD (#NNFF),HL
IM 2
EI
9.Запускаете первую программу :
JP PROG0
Примечание :
Если предусматривается выход из задач по
RET, то поместите по адресу STACK+24 каж-
дого стека адрес программы выхода. Это мо-
жет быть процедура отключения одной задачи
от системы (замена в TABL1 номера этой за-
дачи на номер другой), или процедура выхо-
да из системы :
DI
LD SP,стандартное значение
LD A,63
LD I,A
IM 1
EI
RET
В демонстрационной программе одна зада-
ча рисует мигающий квадрат в левом верхнем
углу экрана и опрашивает клавиатуру.Другая
только рисует квадрат в правом верхнем уг-
лу экрана. При нажатии на пробел происхо-
дит выход.
Если вы хотите использовать музоны, оп-
рашивать клавиатуру или наращивать какие-
-либо счетчики, поставьте CALL'ы в указан-
ом месте.
Ограничения на задачи:
1.Не портить память, занятую другими зада-
чами.
2.Не изменять регистр I.
3.Перед использованием расширенной памяти
запрещать прерывания. Разрешать только
тогда, когда установлена стандартная
конфигурация.
4.Не запрещать надолго прерывания.
Ограничение '3' можно снять,если в сис-
теме организовать проверку конфигурации,
запоминания ее на стеке и последующего
восстановления.
...ОБ ЭЛЕКТРОННЫХ ЖУРНАЛАХ.
Мне, как обычному пользователю, хоте-
лось бы дать пару замечаний для изготови-
телей электронных журналов.
1.Если вы придумали какой-нибудь крутой
трюк и засунули его в заставку журнала, то
опишите его в журнале, или ассемблерный
текст в приложение, чтобы другие тоже мог-
ли им воспользоваться.
2.Расширьте меню SAVE. Например, если в
тексте есть картинка, то добавить пункт
SAVE SCREEN, если есть ассемблерный лис-
тинг, то дать возможность выгрузить его
сразу, а не вырезать из отгруженной ста-
тьи.
3.Дайте возможность отгружать музоны, с
проигрывателем или без него.
Вот пока и вся критика.
...О РЕКЛАМЕ.
С радостью буду переписываться со все-
ми, кто любит и работает со SPECCY.
У вас есть какие-либо вопросы по прог-
раммированию? Пишите. Если смогу, то отве-
чу.
Вам нужен кодер? Если вам понравились
мои разработки (смотри выше), пишите.
И еще: кто поможет достать книгу П. Фе-
дина "ПОЛНОЕ ОПИСАНИЕ И ПОЛНЫЙ ДИЗАССЕМБ-
ЛЕР TR-DOS 5.04(5.03)". Можно и на диске.
...О СЕБЕ.
Мне 16 лет. Увлекаюсь программированием
на SPECTRUME, который у меня уже 6 лет.
Сейчас у меня SCORPION. В совершенстве
знаю бейсик, паскаль. Довольно хорошо ра-
ботаю и на ассемблере.
...О ПРОЩАНИИ.
Ну вот и подошла к концу моя эпопея,над
которой я работал полтора месяца.
Пожелания,замечания,предложения и прос-
то письма присылайте по адресу:
┌─────────────────────────────────┐
│ 612831 Кировская обл., │
│ Верхнекамский р-н, │
│ пос. Рудничный, │
│ ул. Орджоникидзе, │
│ д. 33, кв. 48. │
│ КИСЕЛЕВУ АЛЕКСАНДРУ ПЕТРОВИЧУ │
└─────────────────────────────────┘
------------------------------------------
Other articles: