Deja Vu
#0A
30 сентября 2000 |
|
Программирование - Качесвенная процедура конверсия ZX картинки в ASCII.
__________________________________________ (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. │ │ КИСЕЛЕВУ АЛЕКСАНДРУ ПЕТРОВИЧУ │ └─────────────────────────────────┘ ------------------------------------------
Другие статьи номера:
Похожие статьи:
В этот день... 9 октября