ZX-Ревю 1993 №11-12 1992 г.

Применение ассемблера для создания быстроработающих программ - окончание. начало см. с. 9-12, 48-61, 97-103, 139-144, 187-189. перевод бейсик-программы в машинные коды.


ПРИМЕНЕНИЕ АССЕМБЛЕРА ДЛЯ СОЗДАНИЯ БЫСТРОРАБОТАЮЩИХ ПРОГРАММ

Перевод с английского Пашорина В.И.

Редактирование текста "ИНФОРКОМ".

Окончание.

Начало см. с. 9-12, 48-61, 97-103, 139-144, 187-189.

10. ПЕРЕВОД БЕЙСИК-ПРОГРАММЫ В МАШИННЫЕ КОДЫ

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

В этой же главе мы разберем способ создания игровой программы полностью в машинных кодах, используя в качестве примера программу на БЕЙСИКе. Мы полагаем, что, Вы уже умеете программировать на этом языке.

Весьма важно перед созданием любой программы отработать ее алгоритм в виде структурной схемы. Это облегчит выполнение перевода BASIC-программы в машинные коды. Мы займемся переводом в машинные коды игровой БЕЙСИК-программы "CROSS", что позволит приобрести навыки для перевода прочих собственных программ.

Идея игровой программы "CROSS" состоит в том, чтобы управляя перемещением человечка вернуть его домой целым и невредимым, несмотря на обилие всевозможных препятствий (Лист._1).

Главная программа включает в себя инициализацию программных переменных, вывод на экран инструкции пользователю и цикл перемещения человечка по экрану с определением его текущего положения. Существует две точки выхода из этого цикла:

1. Если человечек сталкивается с препятствием, то осуществляется переход к процедуре HIT и проводится проверка оставшегося числа жизней. Если это число равно нулю, то игра заканчивается, в противном случае осуществляется переход к основному циклу главной программы.

2. Выход к процедуре HOME. Здесь производится проверка числа занятых домов, а затем увеличивается значение скорости перемещения и добавляется еще один паук-людоед. Из процедуры HOME возврат осуществляется к основному циклу главной программы.

БЕЙСИК-программа довольно проста, хотя для задания UDG, цвета и звука, а также попиксельного перемещения экрана используются фрагменты в машинных кодах, так как на БЕЙСИКе это выполнялось бы крайне медленно. Машинные коды вводятся в программу через оператор РОКЕ. Хорошо разберитесь с работой БЕЙСИК-программы, потому что мы переходим к построчному переводу ее в машинные коды.

Листинг_1.

Программа CROSS на БЕЙСИКе (с сокращениями).

Внимание: Символы графики пользователя [UDG] в тексте программы взяты в квадратные скобки [...]. Они набираются в графическом режиме.

20 CLEAR 32243: GO TO 40

25 BEEP .01,b-a

30 PRINT OVER 1; PAPER 8; INK 8; AT a,y2; "[G]": RETURN

40 PRINT AT 11,5; "Please wait"

50...140 - запись кодов процедуры ROLL через цикл FOR...NEXT с помощью READ...DATA и POKE.

150 LET a=PEEK 23675 + 256*PEEK 23676

160 FOR b=a TO a+167: READ c: POKE b,c: NEXT c 180 DATA.... Данные по конструкции

............. символов UDG-графики

270 DATA..... (168 байтов)

280 PRINT AT 11,3; "Do you want instructions?";AT 13,11; "(Y)es"; AT 15,11;"(n)o" 290 LET a$=INKEY$: IF a$="" THEN GO TO 290 295 IF a$<>"y" THEN GO TO 400

300 CLS: PRINT AT 0,11;"OBJECT": PRINT: PRINT "To guide a [G] across a road and a river,

avoiding [AB] [CDE] [F] [GRRS] [TU]": 310 PRINT: PRINT "A [OP] patrols the central island.":

320 PRINT: PRINT "There are 4 HOMES to be filled. i.e. gaps in fence [NNN] [NNN]"

330 PRINT: PRINT "Once all 4 HOMES are filled the speed will increase, an extra spider is

added and the HOMES will empty" 340 PRINT AT 18,9; "Press any Key" 350 PAUSE 0

370 CLS: PRINT AT 7,11; "CONTROLS": PRINT

375 PRINT " ! 380 PRINT AT 11,6; "1"; FLASH 0

385 PRINT AT 18,5; "Press any Key to PLAY" 390 PAUSE 0

400 BRIGHT 1: PAPER 5: BORDER 5: CLS 410 LET hi=0

420 PRINT PAPER 4; AT 10,0;"

<0>"; FLASH 1 FLASH 0;" 2 3 4 5 6 7 8

FLASH 1; "9"; FLASH 0;

FLASH 1; "0"

[OP]

LET score=0: LET home=0: POKE 32425,201: POKE 32450,201: POKE 32469,201

430 LET lives=9

450 PRINT AT 0,0; PAPER 4; "[NNNN]"; PAPER 7;

PAPER 4 PAPER 4 PAPER 4 PAPER 4

455 IF home<>0 THEN GO TO 660

'[NNNNNN]"; PAPER 7;" ' '[NNNNNNN]"; PAPER 7;"

'[NNNNNNN]"; PAPER 7;" [

460 PRINT PAPER 4 470 PRINT 480 PRINT INK 7 490 PRINT INK 2 500 PRINT INK 7 510 PRINT INK 1 520 PRINT INK 7 530 PRINT 540 PRINT PAPER 4 550 PRINT PAPER 0 560 PRINT PAPER 0 570 PRINT PAPER 0 580 PRINT PAPER 0 590 PRINT PAPER 0 600 PRINT PAPER 0 610 PRINT PAPER 0 620 PRINT PAPER 0 630 PRINT PAPER 4 640 PRINT PAPER 4 650 PRINT PAPER 1 [QRRRS QRRRS QRRSB QRRS [ MMM MMMM MMM MM [ TU TU TU TU TU [MM M MMMMM MMM [ RS QRRS QRRRRS [ MM MMMMMMM MMM [U TU TU TU [NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN [NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

INK 5;

FF

AB

AB

AB

[B

AB

A

[ CD AB

AB

FF

SCORE ";AT 21,11;" MEN "; PAPER 5; INK 0; " LIVES "; PAPER 1; INK

INK 7 7; " HI SCORE " 660 LET X1=20: LET y1 = 16: LET x2=x1: LET y2=y1 670 PRINT PAPER 8; INK 8; AT x1,y1; " " 680 RANDOMIZE USR 32295 690 IF SCREEN$ (x2,y2)=" " THEN GO TO 880 700 LET a=x2: FOR b=25 TO 35: GO SUB 25: GO SUB 25: NEXT b 730 FOR a=x2 TO 20 STEP 2: GO SUB 25: GO SUB 25: NEXT a 740 LET lives=lives-1: PRINT AT 21,16; lives 750 LET x2 = 20

760 IF lives <> 0 THEN GO TO 680

770 IF hi >score THEN GO TO 790

780 LET hi = score: PRINT AT 21,27; hi

790 PRINT FLASH 1; PAPER 7; AT 12,0; " GAME OVER

800 PRINT AT 14,0; "Another game? (y)es (n)o "

[ AB F AB CDCDE

[ AB AB

AB AB

EDCDC

[NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

840 IF INKEY$ = "n" THEN RANDOMIZE USR 0 850 IF INKEY$ <> "y" THEN GO TO 840 860 PRINT PAPER 5; AT 21,7;" ": GO TO 480 880 IF x2<>0 THEN GO TO 1050

890 PRINT PAPER 8; INK 8; AT x1,y1;" ": PRINT AT x2,y2;"[G]" 900 RESTORE 920: FOR a=1 TO 8: READ b,c 910 BEEP b,c: NEXT a

920 DATA .1,11,.1,11,.8,16,.05,11,.05,16,.05,11,.05,16,1,20

930 LET home=home+1: LET score=score+50: PRINT AT 21,7; score

950 IF home/4<>INT(home/4) THEN GO TO 660

960 IF home=4 THEN POKE 32425,0

970 IF home=8 THEN POKE 32450,0

980 IF home=12 THEN POKE 32469,0

985 IF home>36 THEN GO TO 450

990 LET a=RND*30

1000 LET a=a+1

1005 IF a>31 THEN LET a=0

1010 IF SCREEN$(10,a)="" THEN GO TO 1000

1020 IF SCREEN$(10,a+1) = "" THEN GO TO 1000

1030 PRINT PAPER 4; AT 10,a; "[OP]"

1035 RESTORE 920: FOR a=1 TO 8: READ b,c: BEEP b,c: NEXT a 1040 GO TO 450

1050 PRINT PAPER 8; INK 8; AT x2,y2; "[G]" 1060 LET x1=x2: LET y1=y2 1070 IF INKEY$ <> "1" THEN GO TO 1100 1080 BEEP .001,33

1090 LET x2=x2-2: LET score=score+5: PRINT AT 21,7; score 1100 LET y2=y2+(INKEY$="0" AND y2<>31)-(INKEY$="9" AND y2<>0) 1110 GO TO 670

СТРОКА 20. Эта строка не нужна в окончательной версии, так как она устанавливает верхнюю границу RAMTOP для БЕЙСИК-программы.

СТРОКИ 25 и 30. Это две строки подпрограммы, вызываемой в строках 700 и 730. Размещение ее в начальных строках необходимо для сокращения времени поиска при вызове этой подпрограммы, так как всегда поиск нужных подпрограмм начинается с начальных строк БЕЙСИКа. Машинные коды, соответствующие этим двум строкам, размещаются в участке памяти, где будет записана процедура HIT.

СТРОКА 40. Для того, чтобы ввести фрагменты программы в кодах с помощью РОКЕ требуется время. Поэтому в БЕЙСИК-программе и введена эта строка с сообщением о необходимости немного подождать. В программе, написанной полностью в кодах, давать такое сообщение, конечно, нет необходимости.

СТРОКИ 50... 140. Это строки для ввода через POKE процедуры "ROLL", обеспечивающей попиксельное смещение изображения на экране. Понятно, что для программы в машинных кодах эту операцию выполнять также не нужно, так как эти коды будут записаны в соответствующие адреса при загрузке программы в память (см. листинг процедуры ROLL в конце статьи).

СТРОКИ 150...270. Это первые строки, которые нуждаются в преобразовании для перехода к программе в машинных кодах. Здесь осуществляется запись в область UDG всех графических элементов пользователя, так как этот участок памяти занимает 158 байтов, то и в строках DATA записаны 168 чисел, определяющих форму UDG.

В дальнейшем, конечно, для задания UDG мы будем непосредственно записывать в участок памяти UDG значение этих 168 байтов. Сначала мы разместим данные, характеризующих форму UDG, начиная с адреса 24001, а затем перешлем их в участок памяти UDG, использовав команду LDIR. При этом в регистровую пару DE записывается начальный адрес участка UDG из системной переменной 5С7В (83675), а в регистровую пару HL начальный адрес данных, характеризующих форму UDG. Процедура пересылки, написанная в машинных кодах, размещается сразу же за данными 168 байтами. Вызов этой процедуры поэтому производится по команде RANDOMIZE USR 24169.

UDG-

графика.

5DC1H

DEFB

0F

12

22

7F

FF

FF

28

10

DEFB

80

40

20

FE

FE

FF

28

10

DEFB

7F

7F

7F

7F

7F

FF

15

08

DEFB

FF

FE

FE

FE

FF

FF

40

80

DEFB

00

F8

C4

C4

FE

FE

28

10

DEFB

18

18

24

7E

3C

5A

A5

42

DEFB

38

28

92

72

38

38

28

6C

DEFB

01

02

04

7F

7F

FF

14

08

DEFB

F0

48

44

FE

FF

FF

14

08

DEFB

00

1F

23

23

7F

7F

14

08

DEFB

7F

7F

7F

7F

FF

FF

02

01

DEFB

FE

FE

FE

FE

FE

FF

A8

10

DEFB

10

29

C7

00

26

00

00

00

DEFB

00

44

FF

44

44

FF

44

00

DEFB

00

22

55

8F

97

A3

A0

00

DEFB

00

44

AA

F1

E9

C5

05

00

DEFB

10

10

10

FE

3F

IF

0F

07

DEFB

00

00

00

00

1E

FF

FF

FF

DEFB

60

7C

54

78

7F

FF

FE

7C

DEFB

00

00

03

02

0F

3F

FF

00

DEFB

05

0C

96

F0

E0

55

FF

00

5E69

24169 LD DE,(5C7B) 24173 LD HL,5DC1 24175 LD BC,00AB 24179 LDIR 24181 JR,5EA2

СТРОКА 280. Сообщение, выводимое на экран по команде PRINT в этой строке, можно выводить на экран, используя процедуру ОЗУ, находящуюся по адресу 3252 (203СН). Машинные коды этой процедуры записаны в участке 5ЕА2... 5EAF, а сам текст сообщения - в участке 5Е77...5ЕА1 (Листинг-4).

Печать сообщения.

5E77H

DEFB

16

0B

03

44

5F

20

79

6F

DEFB

75

20

77

61

6E

74

20

69

DEFB

6E

73

74

72

75

63

74

69

DEFB

6F

6E

73

3F

16

0D

0B

28

DEFB

79

29

65

73

16

0F

0B

28

DEFB

6E

29

6F

5EA2

24225 LD A,02 24228 CALL 1601H 24231 LD DE,5E77H 24234 LD BC,002BH 24237 CALL 203CH

СТРОКИ 290 и 295. Эти строки необходимы, чтобы приостановить выполнение программы до тех пор, пока не будет нажата клавиша. Если будет нажата клавиша "y", то на экране появится инструкция по правилам игры. Если же будет нажата любая другая клавиша, то произойдет переход к адресу 608AH. Машинные коды, соответствующие этим строкам, записаны по адресу с 5ЕВ0Н по 5ЕВЕН (Лист.5)

Проверка нажатия клавиши "y".

24240 HALT

24241 BIT 5,(IY+01) 24245 JR Z,-07

24247 LD A,(5C08H) 24250 CP 79 24252 JP NZ,608AH

СТРОКА 300:1 CLS - Перевод этой команды в машинные коды мы уже разбирали (Листинг-6).

Очистка экрана.

5EBFH

24255 LD A,02 24257 CALL 1601H 24260 CALL 0D6BH 24263 JP 5F73H

СТРОКИ 300:2...350. Для вывода сообщений на экран снова будем использовать процедуру вывода на экран последовательности символов ПЗУ, коды которых записаны в участок памяти с именем DATA. Коды символов первого сообщения находятся в памяти с 5ЕСАН по 5F72H, а второго сообщения 5F84H...5FF9H. Процедуры же вывода PRINT DATA находятся соответственно 5F73H...5F83H и 5FFAH... 6002Н (Листинг_7).

В ячейках с 6003H по 600CH находятся машинные коды, реализующие команду PAUSE 0. Не забывайте, что бит 5 переменной 23611 (IY+1) должен быть сброшен (ожидание нажатия клавиши).

Печать сообщений, пауза.

5ECAH

DEFB 16

00

0B

4F

42

4A

45

43

DEFB 54

0D

0D

54

6F

20

67

75

DEFB 69

64

65

20

61

20

96

20

DEFB 61

63

72

6F

73

73

20

61

DEFB 20

72

6F

61

64

20

61

6E

DEFB 64

20

61

72

69

76

65

72

DEFB 2C

61

76

6F

69

64

69

6E

DEFB 67

20

90

91

20

92

93

94

DEFB 20

95

20

A0

A1

A1

A2

20

DEFB A3

A4

0D

0D

41

20

9E

9F

DEFB 20

70

61

74

72

6F

6C

73

DEFB 20

74

68

65

20

63

65

6E

DEFB 74

72

61

6C

20

69

73

6C

DEFB 61

6E

64

EE

0D

0D

54

68

DEFB 65

72

65

20

61

72

65

20

DEFB 34

20

48

4F

4D

45

53

20

DEFB 74

6F

20

62

65

20

66

69

DEFB 6C

6C

65

64

2E

20

69

2E

DEFB 65

2E

20

67

61

70

73

20

DEFB 69

6E

20

65

65

6E

63

65

DEFB 20

9D

9D

9D

20

9D

9D

9D

DEFB 0D

5F73H

24435

LD

A,02

24437

CALL

601H

24440

LD

DE

,5ECAH

24443

LD

BC

00A9H

24446

CALL

03CH

24449

JP

5FFAH

5FB4H

DEFB 0D

4F

6E

63

65

20

61

6C

DEFB 6C

20

34

20

48

4F

4D

45

DEFB 53

20

61

72

65

20

66

69

DEFB 6C

6C

65

64

20

74

68

65

DEFB 20

73

70

65

65

64

20

77

DEFB

59

6C

6C

20

69

6E

63

72

DEFB

65

61

73

65

2C

20

61

6E

DEFB

20

65

78

74

72

61

20

73

DEFB

70

69

64

65

72

20

59

73

DEFB

20

61

64

64

65

64

20

61

DEFB

6E

64

20

74

68

65

20

48

DEFB

4F

4D

45

53

20

77

69

6C

DEFB

6C

65

6D

70

74

79

16

12

DEFB

09

50

72

65

73

73

20

61

DEFB

6E

79

20

6B

65

79

5FFAH

24570 LD DE,5F84H 24573 LD BC,0076H 24576 CALL 203CH 24579 RES 5,(IY+01)

24583 HALT

24584 BIT 5,(IY+01) 24568 JR Z,-07

СТРОКА 370: 1 CLS. В участке памяти с 600E по 6012 записаны машинные коды процедуры очистки экрана. Здесь применяется другой способ, основанный на применении процедуры ПЗУ 0E44^ которая очищает столько строк экрана (считая снизу), сколько установлено в регистре B(Листинг_8).

Очистка экрана.

600EH

24590 LD B,18H 2459E CALL 0E44H 24595 JP 6076H

СТРОКИ 370:2...390. Коды символов, выводимых на экран, записаны в участке 6016Н... 6075Н, а сама же процедура печати находится в адресах - 6076Н... 607ЕН. Здесь опять же имеются машинные коды, реализующие команду PAUSE 0 (Листинг_9).

Печать сообщений, пауза.

6015H

DEFB

16

07

0B

43

4F

4E

54

52

DEFB

4F

4C

53

0D

0D

20

20

20

DEFB

20

20

20

5E

20

20

20

20

DEFB

20

20

20

20

20

20

20

20

DEFB

20

20

20

3C

30

3E

12

01

DEFB

16

0B

06

31

12

00

20

32

DEFB

20

33

20

34

20

35

20

36

DEFB

20

37

20

38

30

12

01

39

DEFB

12

00

20

12

01

30

12

00

DEFB

16

12

05

50

72

65

73

73

DEFB

20

61

6E

79

20

6B

65

79

DEFB

20

74

6F

20

50

4C

41

59

6076H

24694 LD DE,6016H 24897 LD BC,0060H 24700 CALL 203CH 24703 RES 5,(IY+01)

24707 HALT

24708 BIT 5,(IY+01) 24712 JR Z,-07

Строка 400. В первой главе обсуждался порядок перевода всех операторов этой строки в машинные коды. Вызов процедуры CLS здесь необходим для установки на экране соответствующих атрибутов, как и в БЕЙСИК-программе. Машинные коды записаны в

участке 608АН...609BH.

Установка атрибутов

608AH

24714 LD A,05

24716 CALL 229BH

24719 LD A,68H

24721 LD (5C8D),A

24724 LD A,02

24725 CALL 1601H

СТРОКА 410. В этой строке переменной hi, являющейся показателем достигнутого уровня, присваивается нулевое начальное значение. Полагая, что значение этой переменной не может быть больше 65535, выделим в буфере принтера 2 байта для хранения значения этой переменной. Соответствующие этому оператору машинные коды записаны в участке памяти 609СН ...60А1Н.

Инициализация переменной hi.

609CH

24732 LD HL,0000

24735 LD (5B00H),HL

24738 JR +25H

СТРОКА 420. Коды символов сообщения, выводимого на экран, записаны в адресах 60А4Н...60С8Н. Процедура печати - 60С9Н...60D6H.

Печать строки.

60A4H

DEFB

11

04

16

0A

00

20

20

20

DEFB

20

20

20

20

20

20

20

20

DEFB

20

20

20

20

9E

9F

20

20

DEFB

20

20

20

20

20

20

20

20

DEFB

20

20

20

20

20

60C9H

24777 LD A,02

24779 CALL 1601H 24782 LD DE,60A4H 24785 LD BC,0025H

24788 CALL 203CH

СТРОКА 430. В этой строке определяются исходные значения количества "жизней", занятых домов и достигнутого уровня. Эти значения также хранятся в буфере принтера по следующим адресам:

количество "жизней" - 5В02 достигнутый уровень - 5В03/4 количество домов - 5В05

Машинные коды, соответствующие этой строке, см. 60D7H...60E5H.

Инициализация переменных.

60D7H

24791 LD A,09 24793 LD(5B02H),A 24796 LD HL,0000 24799 LD (5B03H),HL

24802 XOR A

24803 LD (5B05),A

СТРОКА 440. Операторы этой строки обнуляют скорость перемещения и устанавливают команды RET в соответствующих ячейках подпрограммы LINE ROLL.

Машинные коды см. 60E6H...60F3H.

Коррекция процедуры ROLL.

60E6H

24806 LD A,C9H

24808 LD (7EA9H),A

24811 LD (7EC2H),A

24814 LD (7ED5H),A

24817 JP 6129H

СТРОКА 450. Коды символов этой строки и процедура печати:

Печать строки.

60F4H

DEFB

16

00

00

11

04

9D

9D

9D

DEFB

9D

11

07

20

11

04

9D

9D

DEFB

9D

9D

9D

9D

11

07

20

11

DEFB

04

9D

9D

9D

9D

9D

9D

9D

DEFB

11

07

20

11

04

9D

9D

9D

DEFB

9D

9D

9D

9D

11

07

20

11

DEFB

04

9D

9D

9D

9D

6129H

24873 LD A, 24875 CALL 1601H 24878 LD DE,60F4H 24881 LD BC,0035 24884 CALL 203CH

СТРОКА 455. В этой строке проверяется количество домов и, если оно равно нулю, то осуществляется перевод к строке 660. Для реализации этой строки в машинных кодах необходимо извлечь содержимое ячейки 5В05Н, где записано количество домов, записать это значение в регистр A и использовать для проверки на нулевое значение команду AND А. Если флаг нуля (ZERO) после этой операции не будет установлен, то осуществляется переход к процедуре PRINT DISPLAY. Если же этот флаг не включен, то эта процедура пропускается и начинается игра. Машинные коды, соответствующие этой строке, записаны в ячейках 6137H...6140K

Проверка переменной home.

6137H

24687 LD A,(5B05H)

24890 AND A

24891 JP NZ,641EH 24894 JP 63D2H

СТРОКИ 460...640. Машинные коды, соответствующие этим строкам, занимают большой объем памяти. Коды всех символов сообщений этих строк записаны в участке памяти 6141Н... 63D1H, а процедура печати - 63D2H...63DFH.

Инициализация экрана.

6141H

DEFB

11

04

10

05

8C

8C

8C

8C

DEFB

9C

9C

20

20

20

20

20

9C

DEFB

9C

9C

20

20

20

20

10

01

DEFB

8C

8C

8C

8C

8C

8C

8C

8C

DEFB

9C

9C

20

20

20

20

20

20

DEFB

A1

A2

20

20

20

20

20

00

DEFB

8C

8C

8C

8C

8C

8C

8C

8C

DEFB

9C

10

02

20

20

A3

A4

20

DEFB

A1

A1

A2

20

20

20

20

20

DEFB

8C

8C

8C

8C

11

05

10

00

DEFB

20

20

20

20

A3

A4

20

20

DEFB

20

A0

A1

A1

A1

A1

AE

20

DEFB

20

A0

A1

A1

A2

20

20

20

DEFB

20

20

20

A3

A4

20

20

20

DEFB

20

20

20

20

A0

A1

A1

A1

DEFB

A0

A1

A1

A1

A2

20

20

20

DEFB

20

A3

A4

20

20

20

20

20

DEFB

10

07

20

20

20

9C

9C

20

DEFB

20

A0

A1

A1

A3

20

20

20

DEFB

20

A3

A4

20

10

07

9C

9C

DEFB

20

9C

9C

9C

9C

9C

20

20

DEFB

A0

A1

A1

A2

20

20

20

20

DEFB

20

20

20

9C

20

20

20

20

DEFB

20

9C

9C

20

E0

20

20

20

DEFB

10

07

20

20

20

9C

9C

9C

DEFB

20

20

9C

9C

9C

9C

9C

20

DEFB

20

9C

9C

9C

20

20

20

80

DEFB

20

20

20

20

20

9C

9C

9C

DEFB

20

20

20

20

20

20

20

9C

DEFB

20

20

10

00

A4

20

20

20

DEFB

20

20

20

20

20

20

A3

A4

DEFB

07

2D

2D

2D

2D

2D

3D

2D

DEFB

07

2D

2D

2D

2D

2D

2D

2D

DEFB

20

20

20

20

20

A3

A4

20

DEFB

2D

2D

2D

2D

2D

2D

2D

2D

DEFB

2D

2D

2D

2D

2D

2D

2D

2D

DEFB

20

20

20

20

20

A3

A4

20

DEFB

2D

2D

2D

2D

2D

2D

2D

2D

DEFB

2D

2D

2D

2D

2D

ED

2D

2D

DEFB

20

20

20

A3

11

04

9D

9D

DEFB

2D

2D

2D

2D

2D

2D

2D

2D

DEFB

2D

2D

2D

2D

2D

2D

2D

2D

DEFB

9D

9D

9D

9D

9D

9D

9D

9D

DEFB

2D

10

05

20

90

92

20

20

DEFB

2D

10

06

9A

9B

20

20

20

DEFB

9D

9D

9D

9D

9D

9D

9D

9D

DEFB

20

20

90

91

20

20

20

E0

DEFB

97

98

20

20

97

98

20

95

DEFB

9D

9D

9D

9D

9D

9D

9D

9D

DEFB

90

91

20

20

90

91

20

20

DEFB

20

20

95

20

20

99

9A

9B

DEFB

9D

9D

9D

9D

9D

9D

11

00

DEFB

20

20

20

20

20

20

90

91

DEFB

9A

9B

20

20

20

95

20

20

DEFB

10

07

16

0B

00

9D

9D

9D

DEFB

20

20

20

10

07

3D

3D

3D

DEFB

20

20

99

11

04

10

00

9D

DEFB

9D

9D

9D

9D

9D

9D

9D

9D

DEFB

3D

3D

3D

3D

3D

3D

3D

3D

DEFB

9D

9D

9D

9D

9D

9D

9D

9D

DEFB

9D

9D

9D

9D

9D

9D

9D

9D

DEFB

3D

3D

3D

3D

3D

3D

3D

3D

DEFB

9D

9D

9D

9D

9D

9D

9D

9D

DEFB

9D

9D

9D

9D

9D

9D

9D

9D

DEFB

3D

3D

3D

3D

3D

3D

3D

3D

DEFB

9D

9D

9D

9D

9D

9D

9D

9D

DEFB

9D

9D

9D

9D

9D

10

03

80

DEFB

3D

3D

3D

3D

3D

10

04

98

DEFB

9D

9D

9D

9D

9D

9D

9D

11

DEFB

90

91

20

95

20

20

90

91

DEFB

20

20

20

20

20

97

98

20

DEFB

04

20

20

20

20

20

20

20

DEFB

20

20

92

93

92

93

94

20

DEFB

20

20

97

98

20

20

20

20

DEFB

20

20

20

20

20

20

20

20

DEFB

95

20

95

20

20

20

92

93

DEFB

20

20

20

97

98

20

20

20

DEFB

20

20

20

20

20

20

20

20

DEFB

94

20

20

20

20

20

20

10

DEFB

20

20

20

20

20

20

97

10

DEFB

20

20

20

20

20

20

20

20

63D2H

25554 LD A,02

25556 CALL 1601H

25559 LD DE,6141H 25562 LD BC,0291H 25565 CALL 203CH

СТРОКА 650. Для реализации этой строки в машинных кодах необходимо предварительно преобразовать число, записанное в ячейке 5В02Н. Для этого оно извлекается из этой ячейки, суммируется с числом 48 и результат записывается в ячейку 6402. Машинные коды этой операции 63Е0Н...63Е9Н. Коды символов сообщения для вывода на экран записаны в 63EAH...640FH, а процедура печати - 6410H...641EH.

Инициализация строки результата

63E0H

25568 LD A,(5B02H) 25571 ADD A,30 25573 LD (6401H),A 25576 JR +26

63EAH

DEFB

11

01

10

07

20

53

43

4F

DEFB

52

45

20

16

15

0B

20

4D

DEFB

45

4E

20

11

05

10

00

39

DEFB

11

01

10

07

20

48

49

2D

DEFB

53

43

4F

52

45

20

6410H

25616 LD A,02

25618 CALL 1601H

25621 LD DE,63E1H 25624 LD BC,0026H 25627 CALL 203CH

СТРОКА 660. В этой строке определяются исходные координаты положения человечка на экране x1 и y1, а также координаты его нового положения x2 и y2. Для программы в машинных кодах эти координаты хранятся также в буфере принтера: x1 - 5B06H x2 - 5B08H y1 - 5B07H y2 - 5B09H

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

Инициализация координат героя.

641FH

25630 LD HL,1014H

25633 LD (5B06H),HL

25636 LD (5B08H),HL

Из этого примера понятно, что использовать десятичную систему счисления для записи координат в регистровую пару HL не удобно, т.к. трудно будет представить положение объекта на экране.

СТРОКА 670. Поскольку здесь необходимо выводить на экран только один символ, то лучше использовать команду RST 10H.

Печать героя.

6427H

25639

LD A,02

25641

CALL 1601H

25644

LD A,11H

25646

RST 10H

25647

LD A,08

25649

RST 10H

25650

LD A,10H

25652

RST 10H

25653

LD A,08

25655

RST 10H

25656

LD A,16H

25658

RST 10H

25659

LD A,(5B06H)

25662

RST 10H

25663

LD A,(5B07H)

25666

RST 10H

25667

LD A,20H

25669

RST 10H

СТРОКА 680. В этой строке производится вызов процедуры ROLL, записанной в машинных кодах с адреса 7Е27Н. Код, соответствующий этой строке:

Вызов процедуры ROLL.

6446H

25670 CALL 7E27H

СТРОКА 690. в этой строке проверяется состояние символьной ячейки с координатами x2, y2. Для реализации этой строки в машинных кодах будем использовать процедуру SCREEN$, описанную в главе 8, передающую значение параметров исследуемой ячейки на стек калькулятора и затем в регистры A,B,C,D,E. Для определения состояния ячейки используем:

LD A,(DE)

CP 20Н

Помните, что для продолжения программы, после использования калькуляторного стека, необходимо очистить рабочий участок. Если в исследуемой ячейке не пробел, то осуществляется переход к процедуре HIT, которая начинается с адреса 6548Н. В БЕЙСИК-программе соответственно переход к строке 880. Машинные коды, соответствующие этой строке записаны в участке 6449K..645DH.

Проверка местоположения героя.

6449H

25673 LD BC,(5B08H)

25677 CALL 2538H

25680 CALL 2BF1H

25683 LD A,(DE)

25684 PUSH AF

25685 CALL 16BFH

25688 POP AF

25689 CP 20H 25691 JP NZ,6548H

СТРОКА 880. В этой строке проверяется: достиг ли человечек вершины экрана, т.е. дошел ли он до дома. В машинных кодах для этого записываем значение координаты x2 в регистр A:

LD A,(5B08)

и сравниваем это значение с нулем. Если это значение равно нулю, то выполняется переход к процедуре HOME, которая начинается с адреса 66А6Н. В Бейсик-программе соответственно осуществляется переход к строке 1050. Машинные коды, соответствующие этой строке 645ЕН...6465Н.

Проверка достижения "дома"

645EH

25694 LD A,(5B08H)

25697 CP 00

25699 JP Z,66A6H

СТРОКА 1050. Здесь также для вывода на экран одного символа в позицию с координатами x2, y2 лучше использовать команду RST 10H, как и в строке 670. Машинные коды - 6466Н... 6484Н.

Печать героя в новой координате

6466H

25702

LD A,02

25704

CALL 1601H

25707

LD A,11

25709

RST 10H

25710

LD A,08

25712

RST 10H

25713

LD A,10H

25715

RST 10H

25716

LD A,08

25718

RST 10H

25719

LD A,16H

25721

RST 10H

25722

LD A,(5B08H)

25725

RST 10H

25726

LD A,(5B09H)

25729

RST 10H

25730

LD A,96H

25733

RST 10H

СТРОКА 1060. Для реализации этой строки в машинных кодах достаточно переписать значение ячеек 5B08 и 5В09 в ячейки 5В06 и 5В07 соответственно.

Запоминание новой координаты.

6485H

25733 LD HL,(5B08H)

25736 LD (5B06H),HL

СТРОКА 1070. Чтобы улучшить работу програлмы в машинных кодах для проверки состояния клавиатуры и контроля нажатия клавиши лучше использовать не системную переменную LAST KEY, а непосредственно команду IN A,(C). Причем, чтобы проверить нажата ли клавиша "1", достаточно проверить состояние только клавиш "1"..."5" так, как это описано в главе 5. Машинные коды - 648ВН...6493Н.

Проверка нажатия клавиши "1".

648BH

25739 LD BC,F77EH 25742 IN A,(C) 25744 BIT 0,A 25746 JR NZ,+1C

СТРОКА 1080. Поскольку длительность и тональность звукового сигнала принципиального значения не имеют, то для реализации этой строки в машинных кодах достаточно только вызвать процедуру BEEP из ПЗУ - CALL 03B5H.

Генерация звукового сигнала.

6494H

25748 LD HL,0032H 25751 LD DE,0005H 25754 CALL 03B5H

СТРОКА 1090. Для записи этой строки в машинных кодах необходимо извлечь содержимое ячейки 5В08 и вычесть из этого значения число 2, а результат вновь записать в эту же ячейку. Значение текущего счета, записанное в ячейках 5В03/4, увеличивается на 5 и вновь записывается в эти ячейки. Машинные коды этих операций - 649DH...64AFH. Для вывода на экран текущего значения счета используются процедуры STACK ВС и PRINT VALUE ON STACK, но первоначально определяются параметры PRINT AT. Машинные коды -64В1Н...64С8Н.

Коррекция счета (score).

649D2H

25757

LD A,(5B08H)

25760

DEC A

25761

DEC A

25763

LD (5B08H),A

25765

LD HL,(5B03H)

25768

INC HL

25769

INC HL

25770

INC HL

25771

INC HL

25772

INC HL

25773

LD (5B03H),HL

25776

NOP

25777

LD A,02

25779

CALL 1601H

25782

LD A,16H

25785

LD A,15H

25787

RST 10H

25788

LD A,07

25790

RST 10H

25791

LD BC,(5B03H)

25795

CALL 2D2BH

25798

CALL 2DE3H

СТРОКА 1100. Опять же, для чтения состояния клавиатуры и установки значения y2 используем команду IN A,^). В программе в машинных кодах добавлена процедура, которой нет в БЕЙСИК программе. В участке памяти 64F3H...64F4H записаны машинные коды, которые составляют процедуру проверки нажатия клавиши "6". Если эта клавиша нажата, то осуществляется выход из программы. На этом главный цикл программы заканчивается.

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

Этот же эффект можно получить, если в главный цикл включить дополнительно процедуру музыкального сопровождения перемещения. Машинные коды этой процедуры 64F5H...650ВН. Завершающей командой главного цикла является команда JP 6427, обеспечивающая переход на начало главного цикла. В БЕЙСИК-программе это выполняется переходом к строке 670.

Опрос клавиатуры, музыка.

64C9H

25801

LD BC,EFFEH

25804

IN A,(C)

25806

BIT 0,A

25808

JR NZ,+0EH

25810

LD A,(5B09H)

25813

CP 1F

25815

JR Z,+01

25817

INC A

25818

LD (5B09H),A

25831

JP 64F5H

25834

BIT 1,A

25836

JR NZ,02

25838

LD A,(5B09H)

25831

CP 00

25833

JR Z,+01

25835

DEC A

25836

LD (5B09H),A

25839

JP 64F5H

64F3H

25843

BIT 4,A

25844

RET Z

64F5H

25845

LD B,0A

25847

LD DE,0078H

25850

LD HL,0001H

25853

PUSH HL

25854

PUSH DE

25855

PUSH BC

25856

CALL 03B5

25859

POP BC

25860

POP DE

25861

POP HL

25883

INC A

25864

LD L,A

25865

NOP

25866

DJNZ -0F

25868

JP 6427

Процедура HIT

СТРОКА 700. В этой строке вводится новая переменная a = x2. Для того, чтобы сохранить значение этой переменной, будем использовать свободную ячейку 5СВ0Н из области системных переменных. Переменная b цикла FOR/NEXT записывается в регистр B:

LD Б.19Н (25D)

и в ячейку 5СВ1Н для использования в следующей процедуре. Машинные коды, соответствующие этой строке - 6548Н...6561 H. Вызов процедуры, соответствующей БЕЙСИК-оператору GO SUB 35, выполняется командой CALL 650FH.

Непосредственно связаны с этой строкой строки 25 и 30 и мы рассмотрим их здесь совместно в едином блоке.

СТРОКА 25. Для перевода этой строки в машинные коды необходимо использовать калькуляторный стек, куда записывается число 0.1 и результат операции b-a. Вычитание проще выполнить, используя последовательность команд: LD HL,(5СB0Н) LD A,H SUB L

Затем, используя процедуру 2D28H переписываем значение со стека в регистр A и

вызываем процедуру ВЕЕР - CALL 03F8H. Машинные коды, соответствующие этой строке, 650F...6521.

СТРОКА 30. Для вывода символа на экран соответственно в позицию a,72 используем команды LD A,n и RST 10H. Машинные коды - 6522H...6547K

Расчет b-а, генерация звука.

650FH

25871 RST 28Н ;Калькулятор.

DEFB 34 EA 23 D7 0A 3D 38

25679 LD HL,(5CB0H)

25882 LD A,H

25883 SUB L

25884 CALL 2D2BH 25887 CALL 03F8H

Печать "героя"

6522H

25890 LD A,02 25892 CALL 1601H 25895 LD A,15H

25897 RST 10H

25898 LD A,01

25900 RST 10H

25901 LD A,11H

25903 RST 10H

25904 LD A,08

25906 RST 10H

25907 LD A,10H

25909 RST 10H

25910 LD A,68

25912 RST 10H

25913 LD A,16H

25915 RST 10H

25916 LD A,(5CB0H)

25919 RST 10H

25920 LD A,(5B09H)

25923 RST 10H

25924 LD A,96H

25925 RST 10H 25927 RET

Создание переменной "а".

6548H

25928 LD A,(5B08H) 25931 LD (5CB0H),A 25934 LD B,19H

25936 LD A,B

25937 PUSH BC

25938 LD (5CB1),A 25941 CALL 650FH 25944 CALL 650FH 25947 POP BC 25048 INC B

25949 LD A,B

25950 CP 23 25952 JR NZ,-11

СТРОКА 730. Поскольку переменная цикла этой строки у нас хранится в ячейке 5СВ0Н, то организовать цикл в машинных кодах не представляется особенно трудным. Для этого необходимо извлекать это значение из этой ячейки, увеличивать его на 2 при каждом проходе и сравнивать с числом 14Н (20D). Машинные коды - 6562Н......6573H

Цикл по "a".

6562H

25954

CALL 650FH

25957

CALL 650FH

25960

LD A,(5CB0H)

25963

INC A

25964

INC A

25965

LD (5CB0H),A

25968

CP 14H

25970

JR NZ,-12H

СТРОКА 740. В этой строке производится подсчет числа "жизней". Для реализации этой строки в машинных кодах необходимо извлекать значение из ячейки 5В02Н, уменьшать его на 1 и результат опять записывать в эту ячейку. Для вывода на экран этого значения необходимо первоначально установить необходимые параметры PRINT AT, a затем к числу, записанному в ячейке 5B02H добавить 30H(48D) для перевода его в код ASCII. Машинные коды 6574K..658EH.

Коррекция числа "жизней".

6574H

25972

LD A,(5B02H)

25975

DEC A

25976

LD (5B02H),A

25979

LD A,02

25981

CALL 1601H

25984

LD A,16H

25986

RST 10H

25987

LD A,16H

25989

RST 10H

25990

LD A,10H

25992

RST 10H

25993

LD A,(5B02H)

25996

ADD 30H

25998

RST 10H

СТРОКА 750. В этой строке переписывается значение переменной x2 так, чтобы x2 = 14Н (20D). Машинные коды 658FH...6593K

Коррекция переменной x2.

658FH

25999 LD A,14H

26001 LD (5B02H),A

СТРОКА 760. В этой строке выполняется условный переход. Если число "жизней" не равно 0, то выполняется возврат к началу главного цикла - строке 680. Для программы в машинных кодах это переход по адресу 6446. Машинные коды, соответствующие этой строке - 6594Н...659АН.

Проверка на конец "жизней".

6594H

26004 LD A,(5B02H)

25007 AND A

26008 JP NZ,5446H

Процедура END GAME

СТРОКА 770. В этой строке сравнивается достигнутый счет в этой игре с лучшим результатом прошлых игр. Если новый результат выше, то осуществляется переход к строке 790. Эту операцию легко выполнить для программы в машинных кодах, используя команду

SBC HL,DE

и проверяя значение флага переноса (CARRY). Если флаг будет включен после команды SBC, то выполняется переход по адресу 6611H. Машинные коды для этой строки -659ВН...65А6Н.

Проверка на новый рекорд.

659BH

26011 XOR A

26012 LD HL,(5B03H) 26015 LD DE,(5D00H) 26019 SBC HL,DE 25021 JR C,+6AH

СТРОКА 780. В этой строке устанавливается новое значение лучшего результата и это значение выводится на экран. В машинных кодах для выполнения этой операции достаточно переписать значения из ячеек 5В0З/4 в ячейки 5B00/1. Для вывода на экран используем процедуры STACK VALUE IN ВС и PRINT TOP VALUE ON CALCULATOR STACK, предварительно установив параметры PRINT AT. Машинные коды 65A7H...66C2H.

Коррекция рекорда.

65A7H

26023

LD HL,(5B03H)

25026

LD (5B00H),HL

26029

PUSH HL

26030

POP BC

26031

CALL 2D2BH

26034

LD A,02

26036

CALL 1601H

25039

LD A,16H

26041

RST 10H

26042

LD A,15H

26044

RST 10H

26045

LD A,1BH

25047

RST 10H

26046

CALL 2DE3H

26051

JR +4C

СТРОКИ 790 и 800. В этих строках печатаются сообщения. Коды символов находятся в 65С5Н...6610H, а сама процедура печати - 6611H...6619K

Печать сообщений.

65C5H

DEFB

12

01

11

07

16

0C

00

20

DEFB

20

20

20

20

20

20

20

20

DEFB

20

20

47

41

4D

45

20

20

DEFB

4F

56

45

52

20

20

20

20

DEFB

20

20

20

20

20

20

20

16

DEFB

02

00

12

00

20

20

41

6E

DEFB

6F

74

68

65

72

20

67

61

DEFB

6D

65

20

3F

20

28

79

29

DEFB

65

73

20

20

28

6E

29

6F

DEFB

20

20

20

20

6611H

26129 LD DE,65C5H 26132 LD BC,004CH 26135 CALL 203CH

СТРОКИ 840...850. В машинных кодах, соответствующих этим строкам, для проверки нажатой клавиши используется системная переменная LAST KEY, а после проверки осуществляется соответствующий переход. Если ни клавиша "y", ни клавиша "n" не будут нажаты, то осуществляется возврат к циклу ожидания нажатия клавиш.

Проверка нажатой клавиши.

661AH

26138

HALT

26139

BIT 5,(IY+01)

26143

JR Z,-07

36145

RES 5,(IY+01)

26149

LD A,(5TOBH)

26152

CP 6EH

26154

JR NZ,+03

26156

CALL 0000

26159

CP 79H

26161

JR NZ,-19

СТРОКА 860. Перед тем, как выполнится переход к началу главного цикла по команде JP 60C9H, переписывается значение лучшего результата (переменная hi) с помощью команд LD A,n : RST 10H.

Печать нового рекорда.

661AH

26163

LD A,02

26165

CALL 1601H

26168

LD A,11H

26170

RST 10H

26171

LD A,05

26173

RST 10H

26174

LD A,16H

26176

RST 10H

26177

LD A,15H

26179

RST 10H

26180

LD A,07

26182

RST 10H

26183

LD A,20H

26185

RST 10H

26186

LD A,20H

26188

RST 10H

26189

LD A,20H

26191

RST 10H

26192

LD A,20H

26194

RST 10H

26195

JP 60C9H

ПРОЦЕДУРА HOME

СТРОКА 890. Для вывода на экран здесь также используется процедура для печати символьной строки, но первоначально в данных этой строки переписываются значения x1 ,y1 ,x2 и y2. Коды символов сообщения при этом записаны в 669АН...66А5Н, перенос значений переменных x1 ,y1 ,x2 и y2 - в 66A6H..66В1 Н, а процедура печати - В 66В2Н... ...66BFH.

Печать "героя".

669AH

DEFB 11 08 10 08 08 16 02 04

DEFB 15 00 04 96

66A6H

26278

LD

HL,(5B06H)

26281

LD

(669F),HL

26284

LD

HL,(5B03H)

26287

LD

(66A3H),HL

26290

LD

A,02

26292

CALL 1601H

26295

LD

DE,669AH

26298

LD

BC,000C

26301 CALL 203CH

СТРОКА 900. Эта строка в программе в машинных кодах не нужна, т.к. расположенные здесь данные для музыки будут загружены непосредственно в память при загрузке машинного кода.

СТРОКИ 910...920. Здесь через CALL 566AH вызывается процедура для проигрыша торжественной мелодии. Сама мелодия расположена в адресах 6656Н...6669Н, процедура -в 666AH...6699^ а вызов выполняется из точки 66С0Н.

Музыка.

66Ш

26304 CALL 666AH 6656H

DEFB 00 00 00 00 00 00 ED 0B

DEFB ED 0B F0 10 EC 0B EC 10

DEFB EC 0B EC 10

666AH

26218 LD B,07

26220 LD HL,665CH

26223 LD A,(HL)

26224 LD(6678H),A 26227 INC HL 26226 PUSH BC

26229 PUSH HL

26230 RST 28H ;Калькулятор. DEFB 34 EC 4C CC CC CC 38

26238 POP HL

26239 LD A,(HL)

26240 PUSH HL

26241 CALL 2D28H 26244 CALL 03F8H

26247 POP HL

26248 POP BC

26249 INC HL

26250 DJNZ -1DH 26252 LD A,01 26254 CALL 3D28H 26257 LD A,14H 26259 CALL 2D28H 26262 CALL 03F8H 26265 RET

Печать новых значений.

СТРОКА 930. Изменение значения переменных home и score в машинных кодах см. 66С3H...66D7H, а вывод значения score на экран выполняется с использованием печати числа, находящегося на вершине стека калькулятора. Машинные коды 66D4Н...66Е9Н.

Коррекция переменных.

66C3H

26307

LD

A,(5B05H)

26310

INC

A

26311

LD

(5B05H),A

26314

LD

HL,(5B03H)

26317

LD

DE,0032H

26320

ADD

HL,DE

26321

LD

(5B03H),HL

66D4H

26324 PUSH HL 25325 LD A,02

25327

CALL 1601H

26330

LD A,16H

26332

RST 10H

26333

LD A,15H

26335

RST 10H

26336

LD A,07

26338

RST 10H

26339

POP BC

26340

CALL 2D2BH

26343

CALL 2DE3H

СТРОКА 950. В этой строке выполняется проверка: все ли 4 дома уже заняты. Если нет, то осуществляется переход к главному циклу. Программа в машинных кодах, выполняющая эту операцию, проще, чем строка BASIC-программы. Для этого достаточно записать в регистр A значение из ячейки 5В05Н и с помощью команды AND 4 маскировать все биты, кроме второго. Если в результате операции флаг нуля (ZERO) не будет установлен, то выполняется переход к главному циклу с помощью команды JP 641E.

Проверка 4-х домов.

66EAH

26346 LD A,(5B05H) 26349 AND 04 26351 JP NZ,641EH

СТРОКИ 960...980. Эти строки позволяют увеличить скорость игры, когда количество занятых домов достигает 4,8 или 12. Это достигается путем исключения команд RET из процедуры ROLL.

СТРОКА 985. В этой строке проверяется, выше ли число занятых домов, чем 36. Если это так, то пропускается процедура для добавления еще одного паука и осуществляется переход к главному циклу. Для реализации этого в машинных кодах достаточно вычесть от значения переменной "home" число 37. Если при этом флаг переноса (CARRY) не будет включен, то значит число занятых домов >= 37, и выполняется переход по команде JP NC 6129. Машинный код 6714Н...6718Н.

Изменение скорости игры.

66F2H

26354

XOR A

26355

LD A,(5B05H)

26358

CP 04

26360

JR NZ,+06

26362

XOR A

26363

LD(7EA9H),A

26366

JR +19

26368

CP 08

26370

JR NZ,+06

26372

XOR A

26373

LD (7EC2H),A

26376

JR +0F

26378

CP 0С

26380

JR NZ,+06

26382

XOR A

26383

LD (7ED5H),A

26386

JR +5

26368

SUB 25H

26390

JP NC,6129Н

СТРОКА 990. Работу со случайными числами мы уже обсуждали в четвертой главе, поэтому объяснять порядок преобразования этой строки БЕЙСИК-программы в машинные коды мы здесь не будем. Необходимо только отметить, что для получения случайного числа в этой программе вначале извлекается значение системной переменной SEED, а затем оно

изменяется по следующей программе:

LD A,C AND 1F SUB 2

Все операции выполняются с использованием кодов калькулятора. Машинные коды -6719Н...6740Н.

Генерация случайных чисел.

6718H

26393 LD BC,(5C76H) 26397 CALL 2D2BH 26400 RST 28; калькулятор. DEFB A1 0F 34 37 16 04 34 80 DEFB 41 00 00 80 33 02 A1 03 DEFB 31 38 26419 CALL 2DA2H 26422 LD (5С76Р)^

26426 LD A,C

26427 AND 1F 26429 SUB 02 26431 JR C,+05

СТРОКА 1000. Все, что необходимо сделать, это увеличить на 1 значение переменной "а". Машинный код - 6741Н.

СТРОКА 1005. В этой строке проверяется, не превышает ли значение переменной "а" величины 31. Если это так, то значение этой переменной обнуляется.

6741H

26433 INC A

26434 CP 20H 26436 JR NZ,+01 26438 XOR A

СТРОКА 1010. Для того, чтобы проверить свободна ли позиция экрана с координатами (10,а), используется процедура SCREEN$. Для этого первоначально в регистр B записывается значение переменной "а", а в регистр C - значение 0AH (10D), и вызываются процедуры STACK VALUE IN ВС и SCREEN$, a затем параметры со стека передаются в регистры A^^D^. Теперь выполняется проверка, SCREEN$(10,a) = 20Н. Если это так, то выполняется переход для проверки следующей позиции экрана по команде JR 6741. Машинные коды, соответствующие этой строке, 6747Н...675ЕН.

Поиск свободного знакоместа.

6747H

26439

PUSH AF

26440

LD B,A

26441

LD C,0A

26443

CALL 2538H

26446

CALL 2BF1H

26449

LD A,(DE)

26450

PUSH AF

26451

CALL 16BFH

26454

POP AF

26455

CP 20

26457

JR Z,+03

26459

POP AF

26460

JR -1D

26462

POP AF

СТРОКА 1020. Эта строка повторяет предыдущую, за исключением того, что значение переменной "а" увеличивается на 1 перед вызовом процедуры SCREEN$. Обратите внимание, что значение переменной "а" сохраняется перед вызовом процедуры SCREEN$ (PUSH AF), чтобы его можно было использовать в следующей процедуре. Машинные коды 675FH...6776K

Поиск свободного знакоместа.

675FH

26463

INC A

26464

PUSH AF

26465

LD B,A

26466

LD C,0A

26468

CALL 2538H

26471

CALL 2BF1H

26474

LD A,(DE)

26475

PUSH AF

26476

CALL 16BFH

26479

POP AF

26480

CP 20

26483

JR Z,+03

26484

POP AF

26485

JR -36H

СТРОКА 1030. Значение переменной "а" извлекается со стека и записывается в регистр A, а затем размещается в участке памяти с именем DATA для следующего вывода на экран процедурой PRINT DATA. Машинные коды 6777Н... 6792Н.

Печать добавочного паука.

6777H

26487 POP AF

26468 DEC A

26489 LD (6782H),A

26492 JR +07

DEFB 11 04 16 0A 19 9E 9F

26501 LD A,02

26503 CALL 1601H

26506 LD DE,677EH

26509 LD BC,0007

26512 CALL 203CH

СТРОКА 1039. Здесь повторно вызывается процедура, воспроизводящая фанфары по команде CALL 666А.

СТРОКА 1040. Это строка безусловного перехода в начало цикла. В машинных кодах это выполняется по команде JP 6129H.

Музыка и возврат.

6793H

26515 CALL 666AH

26518 JP 6129H

Как видите, выполнять перевод БЕЙСИК-программы в машинные коды не так уж сложно. Лучше использовать при написании программ в машинных кодах шестнадцатиричную систему счисления, т.к. она более наглядна, если выполняется запись чисел сразу же в регистровую пару.

Нам осталось только привести машинный код для скроллинга экрана вправо-влево. Это код процедуры ROLL.

Машинный код процедуры ROLL.

ORG 32244

32357

LD HL, 18496

RIGHT 32244

LD C, 8

32360

CALL RIGHT

L1 32246

PUSH HL

32363

LD HL, 18496

32247

LD DE,31

32366

CALL RIGHT

32250

ADD HL, DE

32369

JR L6

32251

LD A,(HL)

L5

32371

LD HL,18527

32252

SBC HL,DE

32374

CALL LEFT

32254

RRA

32377

LD HL,18527

32255

LD B, 32

32380

CALL LEFT

L2 32257

LD A,(HL)

32383

LD HL,18527

32258

RRA

32386

CALL LEFT

32259

LD (HL),A

L6

32389

LD HL, 18560

32260

INC HL

32392

CALL RIGHT

32261

DJNZ L2

32395

LD HL, 18560

32263

POP HL

32398

CALL RIGHT

32264

INC H

32401

LD HL, 18560

32265

DEC C

32404

CALL RIGHT

32266

JR NZ,L1

32407

LD HL,18624

32268

RET

32410

CALL RIGHT

32281

LD B, 32

32413

LD HL,20511

L4 32283

LD A,(HL)

32415

CALL LEFT

32284

RLA

32419

LD HL, 20575

32285

LD (HL),A

32422

CALL LEFT

32286

DEC HL

32425

RET

32287

DJNZ L4

32426

LD HL, 18560

32289

POP HL

32429

CALL RIGHT

32290

INC H

32432

LD HL,18624

32291

DEC C

32435

CALL RIGHT

32292

JR NZ,L3

32438

LD HL,20511

32294

RET

32441

CALL LEFT

32295

LD HL,16479

32444

LD HL, 20575

32298

CALL LEFT

32447

CALL LEFT

32301

LD HL,16512

32450

RET

32304

CALL RIGHT

32431

LD HL,16479

32307

LD HL,16512

32454

CALL LEFT

32310

CALL RIGHT

32457

LD HL, 16512

32313

LD HL,16607

32450

CALL RIGHT

32316

CALL LEFT

32463

LD HL, 18432

32319

LD HL,18432

32466

CALL RIGHT

32322

CALL RIGHT

32469

RET

32325

LD HL,18432

32470

LD HL,16479

32328

CALL RIGHT

32473

CALL LEFT

32331

LD HL,18432

32475

LD HL, 16607

32334

CALL RIGHT

32479

CALL LEFT

32337

LD A,(23673)

32482

LD HL, 18560

32340..

.32346 - NOP

32485

CALL RIGHT

32347

AND 02

32486

LD HL,18624

32349

JR Z, L5

32491

CALL RIGHT

32351

LD HL,18496

32494

RET

32354

CALL RIGHT




СОДЕРЖАНИЕ:


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

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



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

Похожие статьи:
Кeвин Mитник: Хaкeр-лeгeндa - Кoгдa я зaдymaл нaпиcaть жизнeoпиcaниe Mитникa и cтaл coбирaть maтeриaлы, я cтoлкнyлcя c oбычнoй прoблemoй любoгo иcтoрикa: иcтoчники прoтивoрeчaт дрyг дрyгy...
Разборки - Dimon про газету Optron.
Особое мнение - ряд вопросов, касающихся демостроения и прогнозы на будущее от Scratcher/E-mage.

В этот день...   4 июля