ZX-Ревю 1996 №6 1996 г.

Этюды - программы и процедуры присланные читателями.


ЭТЮДЫ

(c) Е.Любимов, г.Новокузнецк.

Хочу предложить в раздел "Этюды" две процедуры. Первая процедура - это вывод картинки на экран:

; (C) Lubimov Eugene from

; RUSSIAN BEAR GROUP

; SPECIAL FOR INFORCOM!

?

SCREEN EQU 40000 ; Адрес картинки - спрайта ORG 25000

LD HL,SCREEN ; Настройка LD DE,16384 ; переменных LD IX,SCREEN+6112 ; программы LD BC,22496 ; для LD (ADR),HL ; многоразового LD (ADR1),DE ; использования LD (ADR2),IX ; LD (ADR3),BC ; LD B,96

PR1 PUSH BC LD HL,(ADR) LD DE,(ADR1) CALL PRINT LD (ADR),HL LD (ADR1),DE LD HL,LINE1 LD (LIN+1),HL LD (LIN0+1),HL LD HL,(ADR2) LD DE,(ADR3) CALL PRINT LD (ADR3),DE LD DE,128 SBC HL,DE LD (ADR2),HL LD HL,LINE LD (LIN+1),HL LD (LIN0+1),HL POP BC HALT DJNZ PR1

LD HL,SCREEN+6144

LD DE,22528

LD BC,768

LDIR

RET

PRINT PUSH DE LD B,32

L2 PUSH BC LDI

POP BC DJNZ L2 LD DE,32 ADD HL,DE POP DE

LIN CALL LINE LIN0 CALL LINE RET

LINE PUSH AF INC D LD A,D AND 7 JR NZ,LIN1 LD A,E ADD A,32 LD E,A JR C,LIN1 LD A,D SUB 8 LD D,A LIN1 POP AF RET

LINE1 PUSH AF DEC D LD A,D AND 7 CP 7

JR NZ,LIN10 LD A,E SUB 32 LD E,A JR C,LIN10 LD A,D ADD A,8 LD D,A LIN10 POP AF RET

FORMAT LD HL,16384 LD DE,SCREEN LD B,182 LOOP PUSH BC PUSH HL LD BC,32 LDIR POP HL POP BC EX DE,HL CALL LINE EX DE,HL DJNZ LOOP LD BC,768 LDIR RET

ADR DEFW SCREEN ADR1 DEFW 16384 ADR2 DEFW SCREEN+6112 ADR3 DEFW 22496

Процедура выводит картинку в виде спрайта, поэтому необходимо сначала переделать картинку в спрайт. Этим занимается процедура FORMAT, которая

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

Пример использования: 10 BORDER 0 : PAPER 0 : INK 7 : CLS

20 RANDOMIZE USR 15619 : REM : LOAD "SCREEN$" CODE 16384 30 RANDOMIZE USR 25165 : CLS : PAUSE 0 40 RANDOMIZE USR 25000

Вторая процедура - это индикатор амплитуды для музыкального сопроцессора. ORG 25000 LD HL,16418 LD A,8 CALL L1 LD HL,16419 LD A,9 CALL L1 LD HL,16420 LD A,10 CALL L1 RET

L1 LD BC,65533

OUT

(C),A

IN

A,(C)

AND

15

LD

E,A

LD

C,16

LD

A,E

CP

C

LD

A,0

JR

C,L2

LD

A,#7F

L2 LD (HL),A CALL L3 DEC C JR NZ,L4 RET

L3 PUSH AF INC H LD A,H AND 7 JR NZ,L5 LD A,L ADD A,32 LD L,A JR C,L5 LD A,H SUB 8 LD H,A

L5 POP AF RET

(c) С.Мятнов, г.Хабаровск.

Предлагаю программу обслуживания клавиатуры, которая состоит из трех

частей: DEMO, SCAN, RED. DEMO - демонстрационная п/п. SCAN - опрос клавиатуры. RED - программирование клавиатуры.

Подпрограмма SCAN имеет на выходе в "A" - состояние кнопок клавиатуры:

00 - LEFT

01 - RIGHT

02 - UP

03 - DOWN

04 - FIRE

ORG #9000 DEMO LD BC,#6464 GO PUSH BC CALL 8933 CALL SCAN HALT POP BC RRCA

CALL C,LEFT RRCA

CALL C,RIGHT RRCA

CALL C,UP RRCA

CALL C,DOWN RRCA RET C JR GO LEFT DEC C

RET RIGHT INC C RET

DOWN INC B

RET UP DEC B RET

SCAN LD DE,#0001 LD BC,#0500 LD HL,TAB L1 LD A,(HL) INC HL IN A,(#FE) CPL

AND (HL) INC HL JR Z,NO LD A,E OR C LD C,A NO RL E DJNZ L1 LD A,C RET ENT

RED LD A,#02 CALL #1601 CALL WAIT CALL SET_VAR LD B,5 LOOP3 PUSH BC LD HL,(ADR) CALL PRINT INC HL LD (ADR),HL LOOP4 LD A,(NP) INC A LD (NP),A CP 8 JR NZ,OK XOR A LD (NP),A OK LD A,(N) RRCA LD (N),A IN A,(#FE) CPL

AND #1F JR Z,LOOP4 CALL SVTB CALL KEYF CALL CHECK CALL PRINT CALL WAIT POP BC DJNZ LOOP3 JP DEMO SVTB LD HL,(TAB2)

LD

E,A

LD

A,(N)

LD

(HL),A

INC

HL

LD

(HL),E

INC

HL

LD

(TAB2),HL

LD

B,#FF

LOOP5

RR E

INC B RET C JR LOOP5 KEYF LD A,(NP) LD H,0 LD L,A PUSH HL POP DE ADD HL,HL ADD HL,HL ADD HL,DE LD DE,KEY ADD HL,DE

LD E,B

LD

D,0

ADD

HL,DE

LD

A,(HL)

LD

HL,PR

LD

(HL),A

RET

CHECK CP 4

RET

NC

LD

HL,ADRT

ADD

A,A

LD

D,0

LD

E,A

ADD

HL,DE

LD

A,(HL)

INC

HL

LD

H,(HL)

LD

L,A

RET

PRINT LD A,(HL) OR A RET Z INC HL RST #10 JR PRINT WAIT XOR A

LD B,8 LOP PUSH BC PUSH AF LD A,(N) RRCA LD (N),A IN A,(#FE) AND #1F CP #1F JR Z,NO1 POP AF INC A JR CONT NO1 POP AF CONT POP BC DJNZ LOP OR A JR NZ,WAIT LD B,20 LOOP HALT DJNZ LOOP RET

SET_VAR LD HL,TAB LD (TABL),HL LD HL,TEXT LD (ADR),HL LD A,#F7 LD (N),A XOR A

LD (NP),A XOR A LD (NP),A RET

KEY DEFM "12345QWERT" DEFM "ASDFG" DEFB 0 DEFM "ZXCV" DEFB 2,1 DEFM "MNB" DEFB 3

DEFM "LKJHPOIUY" DEFM "09876" ADRT DEFW CS,SS,SPF,EN CS DEFM "CAPS SHIFT"

DEFB 0 SS DEFM "SIMVOL SHIFT"

DEFB 0 SPF DEFM "SPACE"

DEFB 0 EN DEFN "ENTER"

DEFB 0 N DEFB 0 NP DEFB 0 PR DEFB 0,0 TABL DEFW TAB TAB DEFS 10 ADR DEFW TEXT TEXT DEFB 22,10,10 DEFM "LEFT: " DEFB 0,22,11,10 DEFM "RIGHT: " DEFB 0,22,12,10 DEFM "DOWN: " DEFB 0,22,13,10 DEFM "UP: " DEFB 0,22,14,10 DEFM "FIRE: " DEFB 0 END NOP

Следующая программа переводит текст из формата ZEUS в формат текста IS-DOS. Для этого выполните следующие действия:

1. Наберите и запустите следующую бейсик-программу: 10 LET A=127

15 FOR I=ADR TO ADR+1600 STEP 16

20 RESTORE

30 FOR J=0 TO 15

40 READ S : POKE (1+J),S

50 NEXT J : LET A=A+1

60 POKE (I+6),A

70 NEXT I

80 POKE I,255 : POKE (I+1),255

90 DATA 0,0,10,6,151,34,0,34,0,0,0,10,6,150,48,0

ADR - начало текстового файла. Для обычного ZEUS^ - 32768 (#8000).

2. В ZEUSS перенумировать файл (R) и ввести наглядную строку так, как она была введена с клавиатуры.

3. Набрать следующую программу:

ORG #9000 ENT

ZEUS EQU #8000 TEXT EQU #A000 LD HL,ZEUS LD DE,TEXT PUSH DE CONT2 LD A,(HL) INC A JR Z,EXIT INC HL CONT1 INC HL LD A,(HL) CP #0A JR Z,TAB CONT CP #7F JR NC,TOKEN OR A JR Z,END LD (DE),A INC DE JR CONT1 TAB INC HL LD B,(HL) LD A,32 LB LD (DE),A INC DE DJNZ LB JR CONT1 EXIT EX DE,HL POP DE OR A SBC HL,DE PUSH HL POP BC RET

TOKEN SUB 127 LD B,A PUSH HL LD HL,TOK-1 L1 DEC B JR Z,PR L2 INC HL LD A,(HL) OR A JR Z,L1 JR L2 PR INC HL LD LD A,(HL)

OR A JR Z,STOP LD (DE),A INC HL INC DE JR LP STOP POP HL JR CONT1 END INC HL LD A,13 LD (DE),A INC DE JR CONT2 TOK DEFM "A" DEFB 0

DEFM "2" DEFB 0

Файл в формате ZEUS находится по адресу ZEUS. Текст получается по адресу TEXT.

Начиная с TOK, находятся зарезервированные слова ZEUSS. (c) Wdlks, 1996.

В разделе "ЭТЮДЫ" всегда полно разных великолепных программ в машинных кодах, но я не видел ни одной на BASICS. Попробую заполнить этот пробел. Наберите программу:

10 BORDER 0: BORDER 0: BORDER 0: BORDER 7: BORDER 1: BORDER 2: BORDER 0: BORDER 0: LET A=0+5+0: IF INKEY$="" THEN GOTO 10

Попробуйте в эту строку добавить еще один оператор BORDER, или убрать какой нибудь оператор. Увидите, что будет и как это работает.

(с) В.Аншуков (MITCHELL & ROSSIA SOFT), г.Норильск, 1996

Всем тем, кто не знает как можно организовать вывод бегущей строки под сопровождением AY-сопроцессорной музыки, посвящается. Музыка для примера откомпилирована под адрес 49152. Бегущую строку лучше взять из раздела "Этюды" в ZX РЕВЮ.

10 ORG 45000

20 CALL 38986 ; Включаем бегущую строку. 30 CALL 49152 ; Инициализируем музыкальный сопроцессор. 40 N1 LD A,(23560) ; Опрос клавиши 50 CP 32 ; "пробел".

60 JR Z,KN ; Если нажата, то переход на метку KN.

70 HALT ; Аналог PAUSE = 1.

80 CALL 49157 ; Включаем музыку.

90 JR N1 ; Возврат на метку N1.

100 KN CALL 39015 ; Выключение бегущей строки.

110 CALL 49152 ; Выключение музыки.

120 RET ; Возврат из подпрограммы.

Текст набран в ассемблере "ZEUZ". Вызов подпрограммы производится через RANDOMIZE USR 45000. При нажатии клавиши SPACE происходит выход из подпрограммы.

(c) Е.Усов г. Оренбург.

Предлагаю программу для вывода картинки на экран, вытащенную мною из одной игры:

LD B, 05 PUSH BC LD C,00 LD B,#FF LD HL,#4000 LD A,#51 INC C DEC A JR NZ,-2 PUSH BC PUSH HL LD B,00 ADD HL,BC PUSH HL LD DE,#3530 ADD HL,DE POP DE LD A,(HL) LD (DE),A POP HL LD A,R ADD A,C LD A,A INC H LD A,H CP #58 JR NZ,#-10 POP BC DJNZ #-1D LD HL,#7530 LD DE,#4000 LD BC,#1B00 LDIR RET

Адрес рассчитывается так: Картинка - 16384.

Начало расположения картинки - 7530 h. (с) А.Сергиенко.

Хочу предложить процедуру для удвоения символа по горизонтали. Она не запоминает флаг "C" на стеке, поэтому, при той же длине, работает быстрее. На входе в "DE" - адрес начала шаблона, в "HL" - адрес в экранной области.

Поскольку адрес переноса запоминается в самом же аккумуляторе, возникает разница в 13 тактов за раз.

LD BC,0802 D_8 PUSH BC LD A,(DE) D_2 LD B,4 D_1 RLCA RLCA RL (HL) RLA

RL (HL) DJNZ D_1 INC L DEC C JR NZ,D_2 DEC L DEC L INC H INC DE POP BC DJNZ D_8 RET

И еще одна процедура, которая позволяет распечатать содержимое "A" от "00" до "90" DEC. Я вытащил ее из игрушки "I BALL". Я применяю ее для ввода количества попыток в начале игры.

LD A,10 ; ваше число LD B,9 LOOP1 CP #0A JP C,M_1 SUB #0A DJNZ LOOP1 M_1 LD C,A LD A,9 SUB B PUSH BC CALL PRINT LD A,(LINES)

ADD 10 ; расстояние между цифрами LD (LINES),A POP BC LD A,C CALL PRINT RET PRINT ... LINES ...

Я применял ее со своей "PRINT". Цифры учетверенные. В LINES - адрес на экране для позиции печати. Если пользоваться RST 16, то перед вызовом надо сделать ADD A,#30.

(с) В.Яворский, г.Белгород.

Предлагаю свою процедуру довольно эффективного вывода значения

шестого бита 254 порта, в результате которого получается примитивный цифровой осциллограф :

ORG 30000 DI

LD BC,(XY) BEG1 PUSH BC LD B,24 CALL #0E44 POP BC BEG2 IN A,(254) BIT 6,A JR Z,BEG4 BEG3 DEC B

LD A,0 ; количество удаляемых строк CP B JR Z,BEG4 JR BEG5 BEG4 INC B

LD A,175 ; границы по Y CP B ; границы по X JR Z,BEG3 BEG5 PUSH BC CALL 8933 POP BC DEC C

LD

A,0

CP

C

JR

NZ,BEG2

LD

A,#7F

IN

A,(254)

BIT

0,A

JR

NZ,BEG1

EI

RET

XY DEFB 255,87

(с) Потапов Дмитрий (D.V.P. Computing), 1996

Дмитрий предложил следующую бегущую строку. Скроллинг происходит посредством манипуляций атрибутов. В тексте для этой процедуры могут попадаться управляющие коды. Мы надеемся, что Дмитрий не обидится на изменения в управляющих кодах, т.к. процедура стала немного короче, а также, можно вставить еще и другие коды без использования команды CP NN. Коды интерпретируются следующим образом: #00 - конец бегущей строки

#01 - изменение цвета INK. Цвет вычисляется следующим образом:

128 * FLASH + 64 * BRIGHT + 8 * PAPER + INK #02 - изменение цвета PAPER. Цвет вычисляется так же. #04 - изменение ширины символов. Далее идет код ширины символа.

Итак, листинг программы:

10 ORG 40000 20 INSTALL LD A,128

30 LD (PBA),A 40 LD HL,TEXT 50 LD (TXTA),HL 60 LD (TXTAI),HL 70 RET

80 SCROLL CALL SCR_ATT 90 A_M4 LD HL,(TXTA)

100

LD

L,(HL)

110

LD

A,L

120

CP

#20

130

JR

C,CONCA

140

LD

H,0

150

ADD

HL,HL

160

ADD

HL,HL

170

ADD

HL,HL

180

LD

DE,(23606)

190

ADD

HL,DE

200

LD

BC,(PBA)

210

LD

B,8

220

LD

IX,23071

230 A_M3 LD A,(HL)

240 INC HL

250 AND C

260 JR Z,A_M1

270 COL1 LD (IX+0),255

280 JR A_M2

290 A_M1 LD (IX+0),0

300 A_M2 LD DE,32

310 ADD IX,DE

320 DJNZ A_M3

330 LD A,(WDA)

340 DEC A

350 LD (WDA),A

360 RET NZ

370 LD A,(WDAI)

380 LD (WDA),A

390 LD A,(PBA)

400 RRCA

410 LD (PBA),A

420 RET NC

430 A_M5 LD HL,(TXTA)

440 INC HL

450 LD (TXTA),HL

460 RET

470 SCR_ATT LD HL,23040

480 LD C,8

490 S_A2 PUSH HL

500 LD B,32

510 S_A1 INC HL

520 LD A,(HL)

530 DEC HL

540 LD (HL),A

550 INC HL

560 DJNZ S_A1

570 POP HL

580 LD DE,32 590 ADD HL,DE 600 DEC C 610 JR NZ,S_A2 620 RET

630 CC4 LD HL,(TXTAI)

640 LD (TXTA),HL

650 A_M6 JR A_M4

660 CONCA AND #07

670 JR Z,CC4

680 RRA

690 JR C,CC1

700 RRA

710 JR C,CC2

720 RRA

730 JR C,CC3

740 RET

750 CC1 CALL TAKN

760 LD (COL1+3),A

770 JR A_M6

780 CC2 CALL TAKN

790 LD (A_M1+3),A

800 JR A_M6

810 CC3 CALL TAKN

820 LD (WDA),A

830 LD (WDAI),A

840 JR A_M6

850 TAKN CALL A_M5

860 LD A,(HL)

870 JR A_M5

880 TXTA DEFW 0

890 TXTAI DEFW 0

900 PBA DEFB 128

910 WDA DEFB 1

920 WDAI DEFB 1

930 TEXT DEFB " HELLO ALL USER !!! " 940 DEFB 0

В процедуре имеется две точки входа:

INSTALL - инициализация переменных;

SCROLL - скроллинг на одну позицию.

Бегущую строку можно вызывать из BASICS или "вешать" на прерывания -как будет удобнее. В первом случае можно вызывать следующим образом:

10 RANDOMIZE USR 40000

20 RANDOMIZE USR 40015: PAUSE 1: GO TO 20

В первую строку надо подставить адрес метки INSTALL, а во вторую -адрес метки SCROLL.

На прерывания можно подвесить следующим образом:

ORG 30000 ;процедура включения прерываний IMON DI

CALL INSTALL

LD

A,9

LD

I,A

LD

HL,IMWRK

LD

(65525),HL

LD

A,195

LD

(65524),A

LD

A,24

LD

(65535),A

IM

2

EI

RET

ORG 31000 ;процедура обработки прерывания IMWRK PUSH HL PUSH DE PUSH BC PUSH AF PUSH IX DI

CALL SCROLL EI

POP IX POP AF POP BC POP DE POP HL JP 56

IMOFF DI ;процедура отключения прерываний

LD A,63 LD I,A IM 1 EI RET

Все адреса взяты для примера, поэтому их можно свободно заменить на другие.

Если необходимо изменить положение бегущей строки на экране, то поменяйте числа в строках 220 и 470. Число в строке 220 рассчитывается по формуле 22528+Y*32+31, а в строке 470 по формуле 22528+Y*32, где Y - номер строки, с которой будет начинаться вывод бегущей строки. И, наконец, блок кодов программы:

9C40: 3E 80 32 F6 9C 21 F9 9C :14 9C48: 22 F2 9C 22 F4 9C C9 CD :DC 9C50: A3 9C 2A F2 9C 6E 7D FE :CC 9C58: 20 38 68 26 00 29 29 29 :55 9C60: ED 5B 36 5C 19 ED 4B F6 :1D 9C68: 9C 06 08 DD 21 1F 5A 7E :A3 9C70: 23 A1 28 06 DD 36 00 FF :10 9C78: 18 04 DD 36 00 00 11 20 :74 9C80: 00 DD 19 10 EA 3A F7 9C :D9 9C88: 3D 32 F7 9C C0 3A F8 9C :B4 9C90: 32 F7 9C 3A F6 9C 0F 32 :FE 9C98: F6 9C D0 2A F2 9C 23 22 :93

9CA0: F2 9C C9 21 00 5A 0E 08 :24 9CA8: E5 06 20 23 7E 2B 77 23 :B5 9CB0: 10 F9 E1 11 20 00 19 0D :8D 9CB8: 20 EE C9 2A F4 9C 22 F2 :F9 9CC0: 9C 18 8F E6 07 28 F4 1F :C7 9CC8: 38 07 1F 38 0C 1F 38 11 :6E 9CD0: C9 CD EC 9C 32 77 9C 18 :E7 9CD8: E8 CD EC 9C 32 7D 9C 18 :14 9CE0: E0 CD EC 9C 32 F7 9C 32 :A8 9CE8: F8 9C 18 D5 CD 9B 9C 7E :87 9CF0: 18 A9 02 9D F9 9C 02 01 :84 9CF8: 01 20 48 45 4C 4C 4F 20 :49 9D00: 41 4C 4C 20 55 53 45 52 :D5 9D08: 20 21 21 21 20 00 ED A0 :D5

(c) В.Сорокин, 1996.

Автор предложил программу, которая производит "осыпание" экрана, как это сделано в игре "TANK WARS" на IBM-машине. Т.е., если расставить на экране точки в произвольном порядке, то они упадут вниз, как будто под действием силы тяжести. В этой процедуре используется следующий алгоритм:

Адрес верхней строки находится в регистровой паре DE

Адрес строки, которая находится под ней - в регистровой паре HL

Содержимое ячеек до осыпания: (DE) 1101 0010

(hl) 1011 1001

Содержимое ячеек после осыпания: (DE) 1001 0000

(hl) 1111 1011

Содержимое верхней ячейки можно получить, если сложить с нижней по AND. А нижней, если сложить с верхней по OR. Это основная идея программы.

Теперь о программе:

XPOS - координата X точки из левого нижнего байта осыпаемого окна;

YPOS - координата Y той-же точки;

Y0 - не изменяется в ходе программы, в отличие от YPOS;

VIS - высота окна в пикселах.

Для изменения параметров окна осыпания, необходимо изменить переменные, описанные выше, а также, число в строке 180, которое указывает на ширину осыпаемого окна в знакоместах. В данном варианте переменные установлены на осыпание всего экрана - 175 строк на 32 знакоместа.

10

ORG

40000

20

LD

A,(VIS)

30

LD

B,A

40 L1

PUSH BC

50 L11

PUSH BC

60

LD

A,(XPOS)

70

LD

C,A

80

LD

A,(YPOS)

90

INC

A

100

LD

B,A

110

PUSH BC

120

CALL #22AA

130

LD D,H

140

LD E,L

150

POP BC

160

DEC B

170

CALL #22AA

180

LD B,32

190

LOOP LD A,(DE)

200

PUSH AF

210

AND (HL)

220

LD (DE),A

230

POP AF

240

OR (HL)

250

LD (HL),A

260

INC HL

270

INC DE

280

DJNZ LOOP

290

LD A,(YPOS)

300

INC A

310

LD (YPOS),A

320

POP BC

330

DJNZ L11

340

LD A,(VIS)

350

DEC A

360

LD (VIS),A

370

LD A,(Y0)

380

LD (YPOS),A

390

POP BC

400

DJNZ L1

410

RET

420

XPOS DEFB 0

430

YPOS DEFB 0

440

VIS

DEFB 175

450

Y0

DEFB 0

Далее приводим блок кодов для тех, кто не хочет набирать программу в ассемблере:

9C40: 3A 84 9C 47 C5 C5 3A 82 :C3 9C48: 9C 4F 3A 83 9C 3C 47 C5 :70 9C50: CD AA 22 54 5D C1 05 CD :C9 9C58: AA 22 06 20 1A F5 A6 12 :AD 9C60: F1 B6 77 23 13 10 F5 3A :8F 9C68: 83 9C 3C 32 83 9C C1 10 :81 9C70: D4 3A 84 9C 3D 32 84 9C :C9 9C78: 3A 85 9C 32 83 9C C1 10 :91 9C80: C3 C9 00 00 AF 00 00 00 :57

(c) Д.Чистяков, 1996.

Идея программы осталась той же, только она не использует процедуры ПЗУ и стала релоцируемой. Также, она немного превосходит в скорости работы - тесты проводились при параметре 175 строк на 32 знакоместа:

предыдущая программа производит осыпание за 15 секунд

данная версия производит его за 13 секунд

Также, эта программа "осыпает" экран при следующих параметрах - 192 строки на 32 знакоместа.

Для изменения параметров надо изменить число в строке 20, которое указывает на количество строк в осыпаемом экране, адрес в строке 40, показывающий адрес строки, с которой происходит "осыпание". В строке 90 можно изменить число знакомест для окна.

В строках 170 и 180 можно заменить команду INC на команду DEC, но при этом надо произвести коррекцию адреса в строке 40 так, чтобы он указывал на нижний правый угол окна. При данных переменных адрес указывает на нижний левый угол окна.

10 ORG 40000 20 LD C,175 30 GO PUSH BC 40 LD DE,22432 50 PUSH DE 60 JR START 70 Y PUSH HL 80 PUSH HL 90 LD B,32 100 STEP LD A,(DE) 110 PUSH AF 120 OR (HL) 130 LD (DE),A 140 POP AF 150 AND (HL) 160 LD (HL),A 170 INC L 180 INC E 190 DJNZ STEP 200 POP DE 210 START POP HL

220

DEC

H

230

LD

A,H

240

AND

7

250

CP

7

260

JR

NZ,OFF

270

LD

A,L

280

SUB

32

290

LD

L,A

300

JR

C,OFF

310

LD

A,H

320

ADD

A,8

330

LD

H,A

340 OFF

DEC C

350

JR

NZ,Y

360

POP

BC

370

DEC

C

380

JR

NZ,GO

390

RET

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

интересно, могут сами сравнить работу обеих программ.

9C40: 0E AF C5 11 A0 57 D5 18 :53 9C48: 10 E5 E5 06 20 1A F5 B6 :A9 9C50: 12 F1 A6 77 2C 1C 10 F5 :59 9C58: D1 E1 25 7C E6 07 FE 07 :39 9C60: 20 0A 7D D6 20 6F 38 04 :44 9C68: 7C C6 08 67 0D 20 DA C1 :7D 9C70: 0D 20 CF C9 00 00 00 00 :D1

(c) А.Александров, г.Липецк.

Данная программа производит вычисление факториала. Особенность ее в том, что предел вычислений неограничен, и производится индикация текущего множителя.

10 INPUT A : CLS 20 LET E=0 : LET B=1 30 FOR C=1 TO A : LET B=B*C 40 IF B<10 THEN GOTO 80 50 LET B=B/10 : LET E=E+1 60 IF B>10 THEN GOTO 50 70 PRINT AT 0,0;C 80 NEXT C

90 PRINT AT 0,0;A;"!=";B;"E+";E : GOTO 10 (c) А.Епончинцев, Кемеровская обл.

Я прочитал в ZX РЕВЮ 95/2 программу Антона Сидоренко " OPTION SELECTOR". Теперь я предлагаю читателям свою версию "OPTION SELECTOR'а". Она занимает 150 байт.

Антон для выделения опции использует атрибут, я же использую процедуру печати символа, накладывая его на изображение по "OVER". У Антона в метку "OPTN" загружается номер выбранного пункта, а у меня программа делает переход на нужный адрес. Впрочем, если это не нужно, Вы можете узнать номер выбранного пункта в метке "NUM".

ORG 40000 OPR CALL PRINT

CALL PAUSE OPR1 LD A,#FD IN A,(#FE) BIT 0,A JR Z,DOWN LD A,#FB IN A,(#FE) BIT 0,A JR Z,UP LD A,#7F IN A,(#FE) BIT 0,A JR Z,FIRE JR OPR1 PAUSE LD B,5 MM HALT DJNZ MM

RET

DOWN CALL PRINT

LD A,(YC) ; 1-> CP 5

JR Z,OPR INC A LD (YC),A LD A,(NUM) INC A

LD (NUM),A CALL PAUSE JR OPR UP CALL PRINT

LD A,(YC) ; 2-> CP 0

JR Z,OPR DEC A LD (YC),A LD A,(NUM) DEC A LD (NUM),A CALL PAUSE JR OPR FIRE LD A,(NUM) LD DE,VETKA LD L,A LD H,0 ADD HL,HL ADD HL,DE LD E,(HL) INC HL LD D,(HL) EX DE,HL JP (HL) PRINT LD (IY+87),3 LD HL,CUP LD A,(SH) LD B,A L1 LD A,22 RST 16 LD A,(YC) RST 16 LD A,(XC) RST 16 INC A LD (XC),A LD A,(HL) RST 16 DJNZ L1 LD A,(XPC) LD (XC),A LD (IY+87),0 RET

YC DEFB 0 XC DEFB 0 XPC DEFB 0 NUM DEFB 0 CUP DEFB 143 SH DEFB 10

DEFW; ПЕРЕХОД НА АДРЕС ADR1 DEFW; ADR2

DEFW; и т.д

DEFW;

В данной программе: Метка YC - печать опции; XC - печать по X;

XPC- должна равняться первому вводу метки XC, чтобы курсор не

прыгал по экрану; NUM- номер опции; CUP- код символа; SH - ширина опции; VETKA - адрес перехода. Изменив значения "CP" ( 1->, 2->), Вы можете увеличить или уменьшить количество выбераемых пунктов.

Клавиши управления у этой программы: Q, A, SP.

Сергей Русеев из с. Ленинское прислал несколько программ. Первые две программы "карают" встроенный шрифт: Программа 1:

ORG 40000 ENT $ FONT EQU 41000 LD HL,15616 LD DE,FONT PUSH DE LD BC,768 LDIR POP HL PUSH HL LD BC,768 LOOP PUSH HL LD A,(HL) PUSH AF LD HL,BUF RLD POP AF RLCA POP HL OR (HL) PUSH HL LD HL,BUF RRD POP HL LD (HL),A INC HL

DEC BC LD A,B OR C

JR NZ,LOOP POP HL DEC H

LD (23606),HL RET BUF DEFB 0

И программа 2: ORG 40000 ENT $ FONT EQU 41000 LD HL,15616 LD DE,FONT PUSH DE LD BC,768 LDIR POP HL PUSH HL LD B,96 LOOP INC HL CALL LABEL INC HL INC HL INC HL INC HL INC HL CALL LABEL INC HL INC HL DJNZ LOOP POP HL DEC H

LD (23606),HL RET

LABEL LD A,(HL) SRA A OR (HL) LD (HL),A SLA A OR (HL) LD (HL),A RET

КОРР: Так как у меня "Пентагон 128" с AY, то я не мог пройти эту тему вниманием, и сделал очередной индикатор уровня:

ORG 40000 LD HL,23290 LD A,8

LD E,3 ;цвет полоски индикатора CALL KANAL LD HL,23291

LD A,9 LD E,5

CALL KANAL LD HL,23292 LD A,10 LD E,7

CALL KANAL RET

KANAL LD BC,#FFFD OUT (C),A LD A,#3D LD (MODE),A IN A,(C) AND 15 LD B,16 LOOP CP 0

CALL Z,STIR LAB1 LD (HL),E PUSH DE LD DE,32 SBC HL,DE POP DE MODE DEC A DJNZ LOOP RET STIR XOR A

LD (MODE),A

LD E,0 ;цвет стирания

RET

Для демонстрации этой программы можно использовать следующий BASIC-блок:

10 INK 7: PAPER 0: BORDER 0: C LEAR 39999: RANDOMIZE USR 15619: REM : LOAD "ind_ay"CODE

15 INPUT "FILENAME "; LINE A$

16 INPUT "ADRES "; LINE D$: IF D$="" THEN LET ADR=49152: GO TO 20

17 LET ADR=VAL D$

20 RANDOMIZE USR 15619: REM : LOAD A$CODE ADR

30 INPUT "INIT "; LINE I$: IF

I$="" THEN LET INIT=49163: GO TO 32

31 LET INIT=VAL I$

32 INPUT "NEXT "; LINE N$: IF

N$="" THEN LET NEXT=49166: GO TO 40

33 LET NEXT=VAL N$

40 RESTORE 90: FOR N=0 TO 7: R EAD A: POKE USR "A"+N,A: NEXT N

50 FOR Y=8 TO 21: PRINT AT Y,2 6;"AAA": PRINT #0;AT 0,26;"AAA"; AT 1,26;"AAA"

60 RANDOMIZE USR INIT

70 RANDOMIZE USR NEXT: PAUSE 1 : RANDOMIZE USR 40000: IF INKEY$

="" THEN GO TO 70 80 RANDOMIZE USR INIT 90 DATA 238,238,2388,0,238,238 ,238,0

ИФК: Александр Кабанов из г.Прокопьевска прислал сокращенный на 5 байт и ускоренный вариант "бегущей строки", опубликованной в ZX РЕВЮ N6/95 (MUGY).

LD HL,#401F; адрес верхнего правого угла окна строки LD C,8

LOOP1 LD B,32 ; ширина строки в знакоместах LD E,L OR A LOOP2 RL (HL) DEC L

DJNZ LOOP2 LD L,E INC H DEC C

JR NZ,LOOP1 RET

Он также предложил свой вариант линейного загрузчика экрана:

; (C) BY KABANOV ALEXANDR DI

XOR A SUB 1 EX AF,AF LD C,COLOUR LD IX,#4000 LD DE,#0020 CALL #56A LD B,191 LOOP PUSH BC LD H,C LD BC,224 ADD IX,BC LD A,7 DEFB #DD AND H JR NZ,PROD DEFB #DD LD A,L ADD A,32 DEFB #DD LD L,A JR C,PROD LD BC,63488 ADD IX,BC PROD LD C,H LD E,32 CALL #5A9 POP BC DJNZ LOOP

LD D,3 CALL #5A9 EI RET

Данный загрузчик релоцируем, занимает 61 байт. На ленте - блок данных без заголовка, являющийся спрайтом, за ним - атрибуты.

[COLOR! Пилот i Байты |

! 0,7 ! черно-белый [пурпурно-зеленый!

! 1,6 ! сине-желтый ! красно-голубой !

! 2,5 ! красно-голубой ! сине-желтый !

! 3,4 !пурпурно-зеленый! черно-белый !

Между вызовами процедуры #5A9 нельзя портить регистры L и C. В регистре C (младшие три байта) содержится цвет полосы бордюра. Его можно менять, но старшие пять байтов этого регистра должны оставаться постоянными.

(с) К.Феськов, г.Абакан. 1996.

Если Вы откроете первое издание ZX FORUM, то увидите там программу Виккера В.В., которая позволяет организовать удобный стрелочный интерфейс. Это очень удобная программа, но, на данный момент, просто бегающая стрелка мало кого удовлетворит. Если мы посмотрим на программы Радионова, на мою последнюю программу, то увидим, что стрелка, попадая на меню, "зажигает" его. Как же реализовать эту функцию? Я приведу незначительные доработки вышеуказанной программы, которые позволят реализовать подобный эффект. Хочу упомянуть моего друга Старкова Павла, который любезно изложил мне смысл алгоритма.

Изменения исходного текста программы коснутся ТОЛЬКО процедуры START, остальные подпрограммы не изменяются.

Итак, я приведу сначала подпрограммы, а затем расскажу, что нужно для успешной работы программы.

START LD HL,(CRDS) ; Берем координаты вывода стрелки.

LD A,255 ; Заносим число 255 в номер опции, что говорит о том, LD (OPC1),A ; что стрелка на опцию не попала. PUSH IX ; Далее все так, как в программе. QO CALL SCRBF CALL FORM HALT IN A,(31) PUSH AF CALL BFSCR POP AF LD C,A LD E,STEP LD D,254 LD HL,CRDS+1 BIT 0,C CALL NZ,PL BIT 1,C CALL NZ,MIN LD D,190 DEC HL BIT 2,C

CALL NZ,PL BIT 3,C CALL NZ,MIN BIT 4,C JR NZ,EXIT

CALL COND ; Вызываем процедуру проверки попадания стрелки. CALL BAR ; Вызываем процедуру закрашивания/стирания опции. JR QO

COND LD IX,(TABLE) ; В IX заносим адрес данных.

LD A,1 ; Заносим номер первой опции в вспомогательную LD (OPC),A ; переменную.

LD HL,(CRDS) ; В HL текущие координаты стрелки.

SRL H ; Так как координаты стрелки в пикселях, а программа

SRL H ; работает с знакоместами мы делим координаты на 8.

SRL H

SRL L

SRL L

SRL L

COND1 LD A,(IX+0) ; В A координата X меню.

CP 255 ; Если 255, то данные кончились и стрелка не на опции. RET Z ; Выход.

LD D,A ; Проверяем попадание по X. LD A,H CP D

JR C,PROPOPC ; Если левее опции, пропускаем ее. LD A,D

LD B,(IX+2) ; В регистре B длина опции в знакоместах. DEC B ADD A,B CP H

JR C,PROPOPC ; Если правее опции, пропускаем ее. LD A,(IX+1) ; В A координата Y. CP L

JR NZ,PROPOPC ; Если не совпадает с текущей координатой Y, пропускаем. LD A,(OPC) ; Если все проверки прошли, значит мы нашли номер опции RET ; загружаем его в A и выходим. PROPOPC LD DE,3 ; Переходим к данным следующей опции. ADD IX,DE

LD A,(OPC) ; Номер текущей опции увеличиваем на 1. INC A LD (OPC),A

JR COND1 ; Снова проверяем. BAR LD L,A ; После выхода из процедуры COND в регистре A номер ; опции или 255, если стрелка не попала. LD A,(OPC1) ; Поместили в A номер предыдущей опции, сравниваем его CP L ; с новым и если они равны, то закрашивать не надо. RET Z ; Выходим.

CP 255 ; Если стрелка ушла с опции, то красить новую не надо, JR Z,BAR5 ; а надо погасить старую, что и делает BAR5. PUSH AF

LD A,L ; Заносим новый номер на место старого. LD (OPC1),A POP AF

CALL BAR1 ; Стираем старую опцию. BAR6 LD A,(OPC1) ; В A номер новой опции.

CP 255 RET Z

BAR1 DEC A LD H,0 LD L,A PUSH HL POP DE ADD HL,HL ADD HL,DE EX DE,HL LD IX,(TABLE) ADD IX,DE

BAR3 LD H,(IX+0) LD L,(IX+1) CALL FILL RET

BAR5 LD A,L LD (OPC1),A JR BAR6

FILL LD A,L AND 7 RRCA RRCA RRCA ADD A,H AND #18 RRCA RRCA RRCA OR #58 LD H,A LD A,(HL) ; PUSH AF ; AND 7 SLA A SLA A SLA A LD D,A POP AF AND 56 SRA A SRA A SRA A OR D

LD B,(IX+2) ; В регистре B длина опции в знакоместах.

FILL1 LD (HL),A ; Если опция напечатана на многоцветном фоне, то в цикл INC HL ; следует включить строки, начиная с "берем байт DJNZ FILL1 ; атрибута". RET

; Если это не опция, то красить не надо. ; Выходим.

; Подготовка к закраске новой опции.

; Процедура FILL закрашивает, либо стирает опцию.

; Следующие строки рассчитывают адрес опции в атрибутах.

; Берем байт атрибута.

; Следующие строки инвертируют опцию, меняя местами INK и PAPER. BRIGHT не учитывается.

START1 LD (TABLE),HL ; Эта отдельная процедура, которая задает координаты

LD A,(HL) ADD A,A ADD A,A ADD A,A LD D,A

стрелки так, чтобы она попадала на первую опцию.

INC HL LD A,(HL) ADD A,A ADD A,A ADD A,A LD E,A INC HL LD A,(HL) ADD A,A ADD A,A ADD A,A SUB 4 LD D,A LD (CRDS),DE RET

TABLE DEFW 0 ; Здесь будет адрес таблицы. OPC NOP ; Номер новой опции. OPC1 NOP ; Номер старой опции. TABLE1 X,Y,L,X1,Y1,L1, ... ,255 ; Данные меню.

Для успешной работы требуется:

Составьте таблицу описания опций меню в таком порядке - сначала координата X, затем Y, затем длина опции в знакоместах. X и Y задаются в знакоместах. Как практически использовать процедуру:

PROGRAM LD HL,TEXT ; Печатаем текст меню. CALL PRINT

LD HL,TABLE1 ; В HL адрес таблицы данных меню.

CALL START1 ; Заносим его в переменную TABLE и центрируем стрелку. L1 CALL START ; Вызов процедуры стрелки.

LD A,(OPC1) ; В A помещаем номер опции, на которой до нажатия

; выстрела стояла стрелка. CP 255 ; Если в A 255, то стрелка на меню не попала и мы вновь JR Z,L1 ; рисуем стрелку (можно реагировать по другому). CP 1 ; Далее проверяем на какой опции стояла стрелка и CALL Z,PROG1 ; делаем переход на нужную подпрограмму. CP 2 ; Номер НЕ ЗАВИСИТ от того как напечатаны опции на JR Z,PROG ; экране, а зависит от составленной таблицы. и т.д.

После нажатия выстрела опция остается гореть, но это не всегда приемлемо. Для принудительного гашения опции, после команды CALL START надо подать команду CALL BAR6.

Не редкость такая ситуация, когда нам не надо зажигать опцию, но необходимо знать, попала ли стрелка туда, куда нам надо. Для этого:

PROGRAM LD HL,TABLE1 ; В HL адрес таблицы, которая состоит только из кода 255 CALL START1

CALL START ; Вызываем подпрограмму стрелки. LD HL,TABLE2 ; В HL адрес настоящей таблицы описания. LD (TABLE),HL ; Заносим его в переменную.

CALL COND ; Ищем номер опции. После выхода номер будет в A, а не CP 255 ; в переменной OPC1!!!

JR Z,PROGRAM ; Далее обрабатываем номер как угодно. CP 1

CALL Z,PROG и т.д.

TABLE1 DEFB 255 ; Пустая таблица. TABLE2 X,Y,L,255 ; Настоящая таблица.

На этом позвольте закончить свое повествование. Рад, если кому-то эта информация поможет.




СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



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

Похожие статьи:
От автора - Практика отнимает много времени...
Проза - Бэтмэн, некpoмант, pешил сделать себе нoвый магический пoсox.
Реклама - Реклама и объявления.
Infotek - Реклама и объявления.
Почта - Анонс раздела.

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