-
Notifications
You must be signed in to change notification settings - Fork 0
/
MAIN.MAC
2116 lines (2056 loc) · 59.7 KB
/
MAIN.MAC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
.TITLE LODEMZ
.MCALL .EXIT,.TTYIN,.TTINR
.ASECT
.=001000
START::
BIS #010000, @#44 ; Disable Ctrl-C
MOV SP, STACK ; Сохраняем начальное значение SP
; Переходим к главному меню
Z01060:
; Формирование экрана главного меню
Z01064:
CLR Z11306
CLR Z11304
MOV #1, MENUP ; Начальный пункт меню
MENUDR: ; Рисуем экран меню
MOV #MENUSC, R1 ; Строка главного меню
CALL PRINT
MOV #VERSTR, R1 ; Строка ревизии/даты из VERSIO.MAC
CALL PRINT
CALL HLINES ; Нарисовать горизонтальные линии
MOV #MENUS2, R1 ; начало строк меню
MOV #44, R2 ; верхняя строка меню
MOV #4, R5 ; количество пунктов меню
10$: ; Цикл рисования пунктов меню
MOV #33, R0 ; Esc
CALL TTYOUT
MOV #131, R0 ; Курсор в позицию
CALL TTYOUT
MOV R2, R0 ; строка
CALL TTYOUT
MOV #51, R0 ; колонка
CALL TTYOUT
CALL PRINT
INC R2
SOB R5, 10$ ; повторяем
MOV #MENUL2, R1 ; Курсор в позицию
CALL PRINT
MOV LEVEL, R4
CALL Z20074 ; вывести номер уровня -- двузначное число
MOV #MENUL3, R1 ; Курсор в позицию
CALL PRINT
MOV SPEED, R4
CALL Z20074 ; вывести скорость -- двузначное число
CALL SPRSDR ; Нарисовать спрайты
; Помещаем курсор к текущему пункту меню
MENUPO: MOV #33, R0 ; Esc
CALL TTYOUT
MOV #131, R0 ; Курсор в позицию
CALL TTYOUT
MOV MENUP, R0
ADD #43, R0 ; строка
CALL TTYOUT
MOV #47, R0 ; колонка
CALL TTYOUT
Z01404: CALL WTKEY ; Ожидание нажатия клавиши
; Сюда приходим после нажатия клавиши в меню
Z01406: CMPB R0, #15 ; Enter?
BEQ MENU1 ; Да => начинаем игру
CMPB R0, #40 ; Пробел?
BEQ MENU1 ; Да => начинаем игру
; Выбор пункта меню нажатием цифры 1..4
Z01504: CMP R0, #61 ; Меньше '1'?
BMI Z01404
CMP R0, #65 ; Больше '4'?
BPL Z01404
SUB #60, R0 ; Оставляем только 01..04
ASL R0 ; R0 * 2 -> R0
JMP @MENUGO(R0) ; Переходим к коду выбранного пункта меню
; 1 - GAME
MENU1:
GAME:
; Вычисляем и прописываем задержку (скорость 5 => задержка 027000, 9 => 007000, 1 => 047000)
MOV #10., R0 ;
SUB SPEED, R0 ; 10. - SPEED -> R0
ASH #11., R0
ADD #3000, R0
MOV R0, @#<Z16212 + 2>
; Переходим к игре
CALL Z14600
BR Z01060
; 2 - LEVEL
MENU2: MOV LEVEL, R0
CMP R0, #10. ; стартовый уровень >= 10. ?
BPL $21 ; да => переходим
INC LEVEL
BR $22
$21: MOV #1, LEVEL ; сбрасываем уровень в 1
$22: MOV #MENUL2, R1 ; Курсор в позицию где номер уровня
CALL PRINT
MOV LEVEL, R4
CALL Z20074 ; вывести номер уровня -- двузначное число
BR MENUPO ; возвращаем курсор и продолжаем
; 3 - SPEED
MENU3: MOV SPEED, R0
CMP R0, #9. ; скорость > 9. ?
BPL $31 ; да => переходим
INC SPEED
BR $32
$31: MOV #1, SPEED ; сбрасываем скорость в 1
$32: MOV #MENUL3, R1 ; Курсор в позицию где номер уровня
CALL PRINT
MOV SPEED, R4
CALL Z20074 ; вывести скорость -- двузначное число
BR MENUPO ; возвращаем курсор и продолжаем
; 4 - EXIT
MENU4: ; Выход, завершение работы
FINISH:
MOV STACK, SP ; Восстанавливаем стек
MOV #EXITSC, R1 ; Строка очистки экрана перед выходом
CALL PRINT
.EXIT
EXITSC: ; Строка очистки экрана перед выходом
.BYTE 14 ; Очистить экран
.ASCII /BYE!/
.BYTE 0
.EVEN
MENUGO: .WORD 0
.WORD MENU1
.WORD MENU2
.WORD MENU3
.WORD MENU4
MENUS2:
.ASCIZ /1 GAME/
.ASCIZ /2 LEVEL/
.ASCIZ /3 SPEED/
.ASCIZ /4 EXIT/
.EVEN
MENUL2: ; Строка для установки курсора к месту номера начального уровня игры
.BYTE 33,131,45,61 ; Курсор в позицию
.BYTE 0
MENUL3: ; Строка для установки курсора к месту скорости
.BYTE 33,131,46,61 ; Курсор в позицию
.BYTE 0
.EVEN
; Образ демо-лабиринта, который показывается в меню
SPRDAT: .BYTE 3,3,3,7,0,5,0
.BYTE 0,0,0,0,7,2,2,2
.BYTE 6,0,4,0,7,6,0,0
.BYTE 2,2,2,2,7,1,1
.EVEN
; Переменные, добавленные при портировании
STACK: .WORD 40000 ; Начальное значение SP
MENUP: .WORD 1 ; Текущий пункт меню
LEVEL: .WORD 1 ; Уровень с которого начинаем игру
SPEED: .WORD 4 ; Скорость игры 1..9
;
; Блок переменных
;
.=001700
Z01700::
.WORD 10 ;
Z01702: .WORD 0 ; Количество людей??? очищается, инкрементируется
Z01704: .WORD 0 ; Адрес в образе лабиринта, инициализируется 011410
Z01706: .WORD 0 ; Адрес текущего слова для текущего лабиринта
Z01710: .WORD 1 ; Номер лабиринта; инициализируется из 001770
Z01712: .WORD 0 ; Счетчик строк при рисовании лабиринта: инициализируется 20., декрементируется
Z01714: .WORD 0 ; Адрес начала текущего лабиринта -- определения в виде триплетов; инициализируется 023640 + 240. * (N - 1)
Z01716: .WORD 0 ; ??? адрес куда пишем по 5 слов, инициализируется 022070, для элемента 4 -- чертей
Z01720: .WORD 0 ; Адрес в растре: инициализируется 043202, добавляется по 640.
; в игровой логике: инициализируется 024000, сравнивается с 024000
Z01722: .WORD 0 ; Адрес блока спрайтов ??? инициализируется 012600, 013160
Z01724: .WORD 0 ; Адрес блока спрайтов ??? инициализируется 013660, 013704
; Запись текущего игрового объекта, из 5-ти слов, копируется из 011100
Z01726: .WORD 0 ; Адрес в растре
Z01730: .WORD 0 ; Адрес в образе лабиринта
Z01732: .WORD 1 ; Направление движения??? 0/1/2/3; 2 -- падаем
Z01734: .WORD 1 ; Фаза состояния??? 0/1/2/3/4
Z01736: .WORD 0 ; Смещение по высоте ??? если не 0 то спрайт выводится выше на 5 строк
;
Z01740: .WORD 0 ; адрес следующей свободной записи для зарастающей стены ??? начало массива = 011200, размер записи -- 3 слова
Z01742: .WORD 66 ; код клавиши "вправо"
Z01744: .WORD 64 ; код клавиши "влево"
Z01746: .WORD 70 ; код клавиши "вверх"
Z01750: .WORD 62 ; код клавиши "вниз"
Z01752: .WORD 40 ; код клавиши "вырыть яму"
Z01754: .WORD 0 ; ??? проверяется на 0; связано с опросом клавиатуры
Z01756: .WORD 0 ; Количество жизней: инициализируется 10., декрементируется
Z01760: .WORD 0 ; ??? инициализируется 1, очищается, инкрементируется, проверяется на 0, сравнивается с Z01762
Z01762: .WORD 0 ; Количество чертей; не больше 20.
Z01764: .WORD 0 ; ??? адрес <22070 + 10. * N>
Z01766: .WORD 0 ; Количество сундуков осталось; когда доходит до 0 появляется выход
Z01770: .WORD 1 ; Номер текущего уровня
Z01772: .WORD 31 ; 25. -- всего уровней
Z01774: .WORD 0 ; 011410 + байтовое значение -- адрес в образе лабиринта где будет выход
Z01776: .WORD 0 ; Текущее количество очков
MENUSC: ; Строка подготовки экрана меню
.BYTE 33,100 ; Переход в режим "Немига"
.BYTE 14 ; Clear screen
.BYTE 05 ; Гашение на 1/3 яркости
.BYTE 20,40,57 ; Курсор в позицию
.ASCII /L O D E R U N N E R/
.BYTE 20,61,42 ; Курсор в позицию
.ASCII /BK version Markov A (Action)/<15><12>
.ASCII / NEMIGA port 2016 Nikita Zimin/<15><12>
.ASCII / / ; Курсор в позицию для написания ревизии и даты
.BYTE 06,27 ; Переход в режим VT-52
.BYTE 0
.INCLUDE /VERSIO.MAC/
.EVEN
; Подпрограмма: показ демо-лабиринта
SPRSDR:
MOV #SPRDAT, R4 ; Начало массива элементов для рисования примера
MOV #151350, R3 ; адрес на экране
MOV #30., R5
10$: CLR R2
MOVB (R4)+, R2 ; берём элемент
MOV #Z13540, R1 ; Начало таблицы спрайтов
TST R2
BEQ 30$
20$: ADD #40., R1 ; Переход к следующему спрайту
SOB R2, 20$
30$: ; Получили адрес спрайта в R1
MOV #10., R2
40$: MOV R3, @#177572
MOV (R1)+, @#177570
INC R3 ; ко второму слову
MOV R3, @#177572
MOV (R1)+, @#177570
ADD #63., R3 ; next line
SOB R2, 40$
SUB #638., R3 ; минус 10. строк, плюс 16 пикселей вправо
BIT #7, R5 ; строка из 8-ми элементов закончилась?
BNE 50$ ; нет => переходим
ADD #<640.-16.>, R3 ; переходим к следующей строке
50$: SOB R5, 10$ ; продолжаем цикл
RETURN
; Подпрограмма: Ожидание символа с клавиатуры: R0 = полученный символ
WTKEY: .TTYIN ; символ в R0
CMPB R0, #33
BNE 2$
.TTYIN
BIS #15400,R0 ; #33 в верхний байт
2$: RETURN
; Подпрограмма: Получение символа с клавиатуры: флаг C сброшен = есть симовл, R0 = полученный символ
GETKEY: .TTINR ; есть символ?
BCS 3$ ; нет символа => выходим
CMPB R0, #33 ; Esc ?
BNE 1$
.TTYIN
BIS #15400,R0 ; #33 в верхний байт
1$: CLC ; сбросить флаг C -- клавиша есть
2$: RETURN
3$: CLR R0 ; возвращаем пустой код клавиши
SEC ; признак того что клавиши нет
RETURN
; Подпрограмма: Вывод символа на экран: R0 = символ
TTYOUT: TSTB @#177564 ; Источник канала 0 готов?
BPL TTYOUT ; нет => ждём
MOVB R0, @#177566 ; передаём символ в канал 0
RETURN
; Подпрограмма: Печать строки: R1 = адрес строки, строка завершается 0; портит R0
PRINT:
PR0: MOVB (R1)+, R0 ; Конец строки?
BEQ PR2 ; да => завершаем
PR1: TSTB @#177564 ; Источник канала 0 готов?
BPL PR1 ; нет => ждём
MOV R0, @#177566 ; передаём символ в канал 0
BR PR0
PR2: RETURN
GAMESC: ; Строка подготовки игрового экрана
.BYTE 33,100 ; Переход в режим "Немига"
.BYTE 14 ; Clear screen
.BYTE 05 ; Гашение на 1/3 яркости
.BYTE 20,40,57 ; Курсор в позицию
.ASCII /L O D E R U N N E R/
.BYTE 20,66,50 ; Курсор в позицию
.ASCII /SCORE LIVES LEVEL /
.BYTE 06,27 ; Переход в режим VT-52
.BYTE 0
.EVEN
.=004030
; Подпрограмма подготовки экрана: очистка, рисование рамки
Z04030: MOV #GAMESC, R1 ; Строка для подготовки игрового экрана
CALL PRINT
MOV Z01770, R4 ; берём номер текущего уровня
CALL Z20074 ; вывести номер уровня -- двузначное число
CALL LIVESP ; вывести количество жизней
CALL Z20236 ; вывести число очков
; Рисование прямоугольной рамки игрового поля
Z04036:
; Draw left/right lines
MOV #143501, R1 ; Начало игровой области экрана минус одна строка
MOV #143576, R2 ; R1 + 60. + 1
MOV #202., R5 ; Number of lines
1$: MOV R1, @#177572
MOV #0400, @#177570 ; Left part
ADD #64., R1 ; Next line
MOV R2, @#177572
MOV #100000, @#177570 ; Right part
ADD #64., R2 ; Next line
SOB R5, 1$
HLINES: ; Вход: рисование только горизонтальных линий; используется в главном меню
; Draw top/bottom lines
MOV #143502, R1
MOV #174602, R2 ; R1 + 100*201.
MOV #60., R5 ; Сколько слов нужно изменить = 240./4
2$: MOV R1, @#177572
MOV #177400, @#177570
INC R1
MOV R2, @#177572
MOV #177400, @#177570
INC R2
SOB R5, 2$
Z04156: RETURN
; .=005000
Z05000::
; NOP
CLR Z01702 ; Очищаем количество людей???
CLR Z01762 ; Очищаем количество чертей
CLR Z01766 ; Очищаем количество сундуков
MOV #Z22070, 001716 ; Начало массива чертей
MOV #<Z24220 - 240.>, R1
MOV Z01710, R0 ; Номер лабиринта
Z05034: ADD #000360, R1 ; 240. байт занимает один лабиринт
SOB R0, Z05034 ; повторяем пока не найдём нужный лабиринт
MOV R1, Z01714 ; Сохраняем адрес начала текущего лабиринта
MOV #Z11410, Z01704 ; Адрес начала образа лабиринта
MOV R1, Z01706 ; Сохраняем адрес текущего лабиринта
MOV #143602, Z01720 ; начальное значение (потом будем добавлять по 800.)
MOV #000024, Z01712 ; 20. строк
; Цикл по строкам
Z05074: MOV Z01720, R3
MOV #6, R5 ; 6 слов по 5 триплетов = 30 элементов в строке
; Цикл по R5 -- по словам
Z05104: MOV Z01706, R1 ; Получаем адрес откуда читаем лабиринт
MOV (R1), R0 ; Читаем очередное слово
MOV #5, R4 ; 5 -- количество триплетов в слове
; Цикл по R4 -- по триплетам в слове
Z05116: MOV R0, R2
BIC #107777, R2 ; оставить только биты 12-14 -- верхний триплет
MOV #000014, R1 ; 12. раз
Z05130: ROR R2 ; повторить битовый сдвиг вправо
SOB R1, Z05130 ; в итоге оставленные биты передвинуты в 0-2 биты
; Дальше рисуем элемент для прочитанного триплета
MOV Z01704, R1 ; Получаем адрес в образе лабиринта
CMP R2, #6 ; R2 = 6 ? сундук?
BNE Z05160 ; нет => переходим
; R2 = 6 -- сундук
BR Z05456
;
Z05150: MOVB R2, (R1)
Z05152: BR Z05270
;
Z05154: INC Z01766 ; количество сундуков
Z05160: MOVB R2, (R1)
CMP R2, #000004 ; R2 = 4 ? это чёрт?
BNE Z05240 ; Нет => переходим
; R2 = 4 -- чёрт
CMP Z01762, #000024 ; чертей меньше 20. ?
BMI Z05210 ; да => переходим
Z05200: CLR R2
; NOP
MOVB R2, (R1)
Z05206: BR Z05270
; Сохраняем чёртика
Z05210: INC Z01762 ; чертей на один больше
MOV Z01716, R2 ; Адрес 5-словной записи объекта
MOV R3, (R2)+ ; сохраняем адрес в растре
MOV R1, (R2)+ ; сохраняем адрес в образе лабиринта
CLR (R2)+
CLR (R2)+
CLR (R2)+
MOV R2, Z01716 ; Сохраняем новый адрес
BR Z05422
; R2 != 4
Z05240: BR Z05430
; Создаём человечка: подготовка объекта из 5-ти слов по 011100
Z05242: MOV #Z11100, R2 ; Адрес игровой записи
MOV R3, (R2)+ ; Адрес в растре
MOV R1, (R2)+ ; Адрес в образе лабиринта
CLR (R2)+
CLR (R2)+
CLR (R2)+
MOV #000005, R2 ; 5 -- человечек
MOVB R2, (R1) ; пишем в образ лабиринта
; NOP
; Переходим к следующему триплету
Z05270: CLC ; Сдвигаем на три разряда влево
ROL R0 ; <
ROL R0 ; <
ROL R0 ; <
CALL Z16712
; Получаем адрес спрайта по индексу R2
Z05304: MOV #Z13540, R1 ; Начало таблицы спрайтов
TST R2
BEQ Z05322
Z05314: ADD #40., R1 ; Переход к следующему спрайту
SOB R2, Z05314
; Приступаем к рисованию спрайта; R1 = адрес спрайта в 10 слов -- 8x10 цветных пикселей
Z05322: MOV #000012, R2 ; Повторить для 10. строк
Z05326: MOV R3, @#177572
MOV (R1)+, @#177570 ; записываем 8 цветных пикселей в растр
INC R3 ; ко второму слову
MOV R3, @#177572
MOV (R1)+, @#177570 ; записываем 8 цветных пикселей в растр
ADD #63., R3 ; плюс 64. -- переход к следующей строке растра
SOB R2, Z05326 ; продолжаем цикл по строкам
SUB #638., R3 ; минус 638. -- возвращаемся на 10. строк назад, плюс 8 цветных пикселей вперёд
DEC R4 ; Уменьшаем счётчик триплетов
BNE Z05116 ; Если не последний триплет, то переходим
ADD #000002, Z01706 ; инкремент адреса откуда читаем -- к следующему слову
DEC R5 ; цикл по словам
BNE Z05104 ; переход если не закончили
; Закончили рисовать строку лабиринта
Z05360: ADD #640., Z01720 ; добавляем 640. -- плюс 10. строк растра
DEC Z01712 ; Продолжаем цикл по строкам
BNE Z05074 ; по значению (001712)
; Закончили рисовать лабиринт -- дальше подготовка выхода из лабиринта
Z05374: MOV Z01710, R2 ; Берём номер лабиринта
ADD #Z11000, R2 ; Добавляем адрес 011000
MOVB (R2), R3 ; и получаем оттуда байт
ADD #Z11410, R3 ; Добавляем адрес начала образа лабиринта
MOV R3, Z01774 ; и сохраняем -- адрес выхода в лабиринте
RETURN
;
Z05422: MOV #000004, R2
BR Z05270 ; Переходим к следующему триплету, спрайт и продолжаем
; R2 != 4
Z05430: CMP R2, #000005
BNE Z05270 ; Переходим к следующему триплету, спрайт и продолжаем
; R2 = 5 -- человек
Z05436: TST Z01702 ; Количество человеков нулевое?
BEQ Z05450 ; да => переходим
CLR R2
BR Z05150
;
Z05450: INC Z01702 ; теперь есть один человек
BR Z05242 ; Создаём человечка
; R2 = 6 -- сундук
Z05456: TST Z11306
BEQ Z05154
TSTB (R1)
Z05466: BNE Z05154
CLR R2
BR Z05270
; Подпрограмма вывода игрового объекта: R2 = адрес в растре, R3 = адрес в образе лабиринта
Z05500: CMP Z01720, #024000 ; Начинаем с поиска игровых объектов
BEQ Z05526 ; таких не было => выводим новый
MOV #024000, R4
Z05514: CMP (R4)+, R3 ; это он?
BEQ Z05602 ; да => выходим
CMP R4, Z01720 ; перебрали все?
BNE Z05514 ; нет => продолжаем
Z05526: MOVB (R3), R5 ; получаем номер спрайта
MOV #Z13540, R4 ; Начало таблицы спрайтов, по 10. слов на спрайт
TSTB R5 ; спрайт #0 ?
BEQ Z05546 ; да => переходим
Z05540: ADD #40., R4 ; плюс 20.*2 -- следующий спрайт
SOB R5, Z05540 ; повторяем
Z05546: MOV #000012, R5 ; 10 раз
Z05552: MOV R2, @#177572 ; адрес для вывода пикселей
MOV (R4)+, @#177570 ; выводим 8 цветных пикселей
INC R2
MOV R2, @#177572
MOV (R4)+, @#177570 ; выводим 8 цветных пикселей
ADD #63., R2 ; плюс одна строка растра
SOB R5, Z05552 ; повторяем
SUB #640., R2 ; возвращаем адрес растра обратно на 10. строк вверх
MOV Z01720, R4 ; Теперь запоминаем что объект выводился
MOV R3, (R4) ; сохраняем адрес в образе лабиринта
ADD #000002, Z01720
Z05602: RETURN
;
Z05604: JMP Z17700
; Вывод поверх следующего элемента
Z05610: INC R2 ; плюс 8 пикселей в растре
INC R2
INC R3 ; к следующему элементу
CALL Z05500 ; Вывод игрового объекта
DEC R2 ; минус 8 пикселей в растре
DEC R2
MOV #000012, R5 ; 10. раз
Z05632: MOV R2, @#177572
BIS (R0)+, @#177570 ; выводим поверх
INC R2 ; ко второму слову
MOV R2, @#177572
BIS (R0)+, @#177570 ; выводим поверх
INC R2
MOV R2, @#177572
BIS (R0)+, @#177570 ; выводим поверх
INC R2 ; ко второму слову
MOV R2, @#177572
BIS (R0)+, @#177570 ; выводим поверх
ADD #61., R2 ; следующая строка растра - 8 пикселей
SOB R5, Z05632 ; повторяем
Z05644: RETURN
;
Z05646: JMP Z17726
; Вывод поверх предыдущего элемента
Z05652: DEC R2 ; минус 8 пикселей в растре
DEC R2
DEC R3 ; к предыдущему элементу
CALL Z05500 ; Вывод игрового объекта
MOV #000012, R5 ; 10 раз
Z05670: MOV R2, @#177572 ; адрес для вывода пикселей
BIS (R0)+, @#177570 ; выводим поверх
INC R2 ; ко второму слову
MOV R2, @#177572 ; адрес для вывода пикселей
BIS (R0)+, @#177570 ; выводим поверх
INC R2
MOV R2, @#177572
BIS (R0)+, @#177570 ; выводим поверх
INC R2 ; ко второму слову
MOV R2, @#177572
BIS (R0)+, @#177570 ; выводим поверх
ADD #61., R2 ; следующая строка растра - 8 пикселей
SOB R5, Z05670 ; повторяем
Z05702: RETURN
; Подпрограмма вывода ???; R2 = адрес в растре, R0 = адрес спрайта
Z05704: CMP R0, #SPRITE ; R0 < 012000 ? спрайт чёртик на лестнице?
BMI Z05740 ; да => вывод всего на 5 строк растра ниже
ADD #640., R2 ; плюс 10 строк в растре
CALL Z05500 ; Вывод игрового объекта
SUB #640., R2 ; минус 10 строк в растре
SUB #000036, R3 ; минус одна строка в образе лабиринта
CALL Z05500 ; Вывод игрового объекта
BR Z05770
Z05740: ADD #320., R2 ; плюс 5 строк в растре
CALL Z05500 ; Вывод игрового объекта
SUB #640., R2 ; минус 10 строк в растре
SUB #000036, R3 ; минус одна строка в образе лабиринта
CALL Z05500 ; Вывод игрового объекта
ADD #320., R2 ; плюс 5 строк в растре
Z05770: MOV #000012, R5 ; 10 раз
Z05774: MOV R2, @#177572
BIS (R0)+, @#177570 ; рисуем поверх
INC R2 ; к следующему слову
MOV R2, @#177572
BIS (R0)+, @#177570 ; рисуем поверх
ADD #63., R2 ; следующая строка растра
SOB R5, Z05774 ; повторяем
Z06004: RETURN
; Подпрограмма вывода ???; R2 = адрес в растре, R0 = адрес спрайта
Z06006: CMP R0, #SPRITE ; R0 < 012000 ? спрайт чёртик на лестнице?
BMI Z06046 ; да => вывод всего на 5 строк выше
SUB #640., R2 ; минус 10 строк растра
CALL Z05500 ; Вывод игрового объекта
ADD #640., R2 ; плюс 10 строк растра
ADD #000036, R3 ; плюс одна строка в образе лабиринта
; NOP
; NOP
CALL Z05500 ; Вывод игрового объекта
BR Z06076
Z06046: SUB #320., R2 ; минус 5 строк растра
CALL Z05500 ; Вывод игрового объекта
ADD #640., R2 ; плюс 10 строк растра
ADD #000036, R3 ; плюс одна строка в образе лабиринта
CALL Z05500 ; Вывод игрового объекта
SUB #320., R2 ; минус 5 строк растра
Z06076: MOV #000012, R5 ; 10 раз
Z06102: MOV R2, @#177572
BIS (R0)+, @#177570 ; рисуем поверх
INC R2 ; к следующему слову
MOV R2, @#177572
BIS (R0)+, @#177570 ; рисуем поверх
ADD #63., R2 ; следующая строка растра
SOB R5, Z06102 ; повторяем
Z06112: RETURN
; Подпрограмма ??? игровая логика; R0 = адрес в образе лабиринта
Z06114: CMP R1, #000001
BNE Z06130
CALL Z06152
BR Z06150 ; на выход
Z06130: CMP R1, #000003
BNE Z06144
CALL Z06152
BR Z06150 ; на выход
Z06144: CALL Z16366
Z06150: RETURN
; Подпрограмма ??? игровая логика; R0 = адрес в образе лабиринта
Z06152: ADD #000036, R0 ; к следующей строке лабиринта
TSTB (R0) ; пустой элемент ?
BNE Z06172 ; нет => переходим
MOV #000002, Z01732 ; состояние -- падаем
BR Z06334 ; на выход
Z06172: CMPB (R0), #000007 ; под нами лестница ?
BNE Z06214 ; нет => переходим
MOV #000002, R4
CALL Z06460
TST R5
BNE Z06334 ; на выход
Z06214: SUB #000036, R0 ; возвращаемся к текущему элементу лабиринта
CMPB (R0), #000007 ; лестница ?
BNE Z06254 ; нет => переходим
SUB #000036, R0 ; к предыдущей строке лабиринта
CMPB (R0), #000007 ; лестница ?
BNE Z06254 ; нет => переходим
MOV #000004, R4
CALL Z06460
TST R5
BNE Z06334 ; на выход
Z06254: JMP Z17404
;
Z06260: INC R0
CMP R1, #000001
BEQ Z06274
SUB #000002, R0
Z06274: CMPB (R0), #000001
BMI Z06332 ; R1->R3 и выход
CMPB (R0), #000002
BHI Z06332 ; R1->R3 и выход
CMP R1, #000001
BNE Z06324 ; #1->R3 и выход
MOV #000003, R3
BR Z06334 ; на выход
Z06324: MOV #000001, R3
BR Z06334 ; на выход
Z06332: MOV R1, R3
Z06334: RETURN
;
Z06336: JMP Z16422
;
Z00634: CALL Z16556
Z06352: .WORD 504
;
Z06354: MOV #3, R5
Z06360: CALL Z16556
Z06364: .WORD 504
;Z06366: NOP
;Z06370: NOP
;Z06372: NOP
;Z06374: NOP
;Z06376: NOP
;Z06400: NOP
;Z06402: NOP
Z06404: CMP R1, #000002
BNE Z06420
ADD #000037, R0 ; к следующей строке +1 элемент
BR Z06424
Z06420: SUB #000035, R0 ; к предыдущей строке +1 элемент
Z06424: CMPB (R0), #000007 ; лестница ?
BNE Z06436 ; нет => переходим
MOV R1, R3
BR Z06456
Z06436: CMP R1, #000002
BNE Z06452
MOV #000004, R3
Z06450: BR Z06456
Z06452: MOV #000002, R3
Z06456: RETURN
; Подпрограмма ??? (выбор направления); R0 = адрес в образе лабиринта; R4 = направление?
Z06460: MOV Z11102, R2
CALL Z06572 ; получаем в R2 колонку, в R3 строку
MOV R3, R5 ; запоминаем строку
MOV R2, Z01706 ; сохраняем колонку
MOV R0, R2
CALL Z06572 ; получаем в R2 колонку, в R3 строку
CMP R3, R5 ; строка меньше?
BMI Z06520 ; да => переходим
CMP R4, #000004
BEQ Z06562
BR Z06532
Z06520: CMP R3, R5 ; на той же строке?
BEQ Z06532 ; да => переходим
CMP R4, #000002
BEQ Z06562
Z06532: CMP R2, Z01706 ; колонка меньше? мы слева?
BMI Z06550 ; да => переходим
CMP R4, #000003
BEQ Z06562
BR Z06556
Z06550: CMP R4, #000001
BEQ Z06562
Z06556: JMP Z23150
Z06562: JMP Z23202
;Z06566: NOP
Z06570: RETURN
; Подпрограмма: R2 = адрес в образе лабиринта; возвращает в R2 колонку, в R3 строку.
Z06572: CLR R3
SUB #Z11410, R2 ; убираем адрес начала лабиринта, оставляя индекс
Z06600: INC R3
CMP R2, #000036 ; R2 < 30. ?
BMI Z06570 ; переход на RETURN
SUB #000036, R2 ; минус 30. -- к предыдущей строке лабиринта
Z06614: BR Z06600
; Подпрограмма ??? R0 = адрес блока спрайтов
Z06616: MOV Z01730, R3 ; Адрес в образе лабиринта
MOV Z01726, R2 ; Адрес в растре
CALL Z20376
; NOP
; NOP
ADD #320., R2 ; ниже на 5 строк растра
MOV #000012, R5 ; 10. раз
Z06646: MOV R2, @#177572 ; адрес для вывода пикселей
MOV (R0)+, @#177570 ; выводим 8 цветных пикселей
INC R2 ; ко второму слову
MOV R2, @#177572 ; адрес для вывода пикселей
MOV (R0)+, @#177570 ; выводим 8 цветных пикселей
ADD #63., R2 ; плюс одна строка растра
SOB R5, Z06646 ; повторяем
SUB #640., R2 ; возвращаемся на 10. строк выше
MOV R2, Z01726 ; сохраняем новый адрес в растре
INC Z01736
CMP Z01736, #000002
BNE Z06760 ; не равно => переход на RETURN
; R2 = 30.
Z06702: CLR Z01736
MOV Z01730, R2 ; берём адрес в образе лабиринта
ADD #000036, Z01730 ; добавляем 30. -- к следующей строке
ADD #000074, R2 ; плюс 60. -- на две строки вниз
BR Z06762
Z06730: TST Z01760
BNE Z06744
CMPB (R2), #000010
BEQ Z06756
Z06744: CLR Z01732
CLR Z01734
BR Z06760
Z06756: CLRB (R2)
Z06760: RETURN
Z06762: TSTB (R2)
BEQ Z06760
CMPB (R2), #000006
BEQ Z06760
Z06774: BR Z06730
;Z06776: .WORD 0 ; ???
;
; Подпрограмма -- игровая логика для человечка; по адресу 001726 игровой объект из 5-ти слов
Z07000: MOV #Z13160, Z01722 ; адрес блока спрайтов
MOV #Z13704, Z01724 ; адрес блока спрайтов
MOV #024000, Z01720
MOV Z01732, R0 ; берём состояние объекта
CMP R0, #000001
BNE Z07040
Z07034: JMP Z07776
;
Z07040: CMP R0, #000002 ; падаем ?
BNE Z07062 ; нет => переходим
MOV Z01724, R0 ; адрес блока спрайтов
CALL Z06616
JMP Z07776
Z07062: JMP Z16336
Z07070: NOP;STUB MOV 177714, R0
TST R0
BR Z07104
Z07100: JMP Z07776
Z07104: CMP R0, Z01752 ; код клавиши "вырыть яму" ?
BNE Z07266 ; нет => переходим
MOV Z01730, R1 ; берём адрес в образе лабиринта
ADD #000036, R1 ; к следующей строке лабиринта
CMPB (R1), #2 ; под нами 2 - кирпичная стена ?
BNE Z07266 ; нет => переходим
BR Z07170
;
Z07132: .TTINR ; Нажата клавиша?
BCS Z07262 ; нет => переходим
CMPB R0, Z01752 ; код клавиши "вырыть яму" ?
BNE Z07262 ; нет => переходим
MOV Z01730, R1 ; берём адрес в образе лабиринта
ADD #000036, R1 ; к следующей строке лабиринта
CMPB (R1), #000002 ; под нами 2 - кирпичная стена ?
BNE Z07262 ; нет => переходим
Z07170: CMP Z01740, #Z11270 ; уже слишком много вырытых ям?
BHI Z07262
JMP Z16252
Z07204: NOP
CALL Z17014
CALL Z17102
MOV #000012, R5 ; 10. раз
Z07222: MOV R2, @#177572
CLR @#177570 ; очищаем 8 пикселей
INC R2
MOV R2, @#177572
CLR @#177570 ; очищаем 8 пикселей
ADD #63., R2 ; к следующей строке растра
SOB R5, Z07222 ; повторяем
MOVB #000010, (R1) ; сохраняем временный тип "вырезанная" стена
MOV Z01740, R3 ; берём адрес свободной записи под яму
MOV R1, (R3)+ ; сохраняем адрес в лабиринте
SUB #640., R2 ; на 10. строк выше
MOV R2, (R3)+ ; сохраняем адрес в растре
MOV Z11310, (R3)+ ; сохраняем время зарастания ямки
MOV R3, Z01740 ; запоминаем адрес следующей свободной записи
Z07262: CALL Z17502 ; получить нажатую клавишу и сохранить если нужно
Z07266: MOV Z01730, R1 ; берём адрес в образе лабиринта
ADD #000036, R1 ; добавляем 30. -- к следующей строке
JMP Z16300
Z07302: CMPB (R1), #000010 ; 8. -- "вырезанная" кирпичная стена ?
BNE Z07336
; Вход: переходим сюда когда под игровым объектом пусто -- проваливается
Z07310: MOV #000002, Z01732 ; состояние -- падаем
CALL Z23052
MOV Z01724, R0 ; адрес блока спрайтов
CALL Z06616
JMP Z07776
Z07336: MOV Z01730, R1 ; берём адрес в образе лабиринта
CMP R0, Z01744 ; код клавиши "влево" ?
BNE Z07570 ; нет => переходим
; Вход -- движение игрового объекта влево
Z07350: DEC R1 ; ячейка слева
CMPB (R1), #000001 ; сплошная стена?
BMI Z07366
CMPB (R1), #000003
BMI Z07560
Z07366: CMP Z01734, #000003 ;
BEQ Z07452 ;
TST Z01736
BEQ Z07452
Z07404: JMP Z14572
Z07410: CMP Z01734, #000003
BNE Z07430
CLR Z01734
JMP Z16204
Z07430: JMP Z14572
;
Z07434: SUB Z01736, R5
MOV R5, Z01736
Z07444: BR Z07452
Z07446: JMP Z16250
;
Z07452: MOV Z01730, R3 ; берём адрес в образе лабиринта
MOV Z01726, R2 ; берём адрес в растре
CALL Z15672 ; R0 -> R5; адрес блока спрайтов из Z01722 + 120. -> R0
MOV Z01736, R5
TST R5
BEQ Z07504
Z07476: ADD #80., R0 ; плюс 40. TODO тут не уверен
SOB R5, Z07476
Z07504: CALL Z05646
INC Z01736
CMP Z01736, #000003
BNE Z07546
SUB #2, Z01726 ; на 16 цветных пикселей левее
DEC Z01730 ; адрес в лабиринте -- к предыдущему элементу
CLR Z01732
CLR Z01736
Z07546: MOV #000003, Z01734
JMP Z07776
Z07560: JMP Z07410
;
Z07564: JMP Z07776
; Продолжение анализа нажатой клавиши (не "влево")
Z07570: CMP R0, Z01742 ; код клавиши "вправо" ?
BNE Z07772 ; нет => переходим
; Вход -- движение игрового объекта вправо
Z07576: INC R1 ; ячейка справа
CMPB (R1), #000001
BMI Z07614
CMPB (R1), #000003
BMI Z07636
Z07614: CMP Z01734, #000001
BEQ Z07676
TST Z01736
BEQ Z07676
JMP Z14572
Z07636: CMP Z01734, #000001
BNE Z07656
CLR Z01734
JMP Z16204
Z07656: JMP Z14572
;
Z07662: .WORD 172052
;
Z07670: BR Z07676
Z07672: JMP Z16270
;
Z07676: MOV Z01730, R3 ; берём адрес в образе лабиринта
MOV Z01726, R2 ; берём адрес в растре
MOV Z01722, R0 ; адрес блока спрайтов??
MOV Z01736, R5
TST R5
BEQ Z07730
Z07722: ADD #80., R0 ; плюс 40. TODO тут не уверен
SOB R5, Z07722
Z07730: CALL Z05604
INC Z01736
CMP Z01736, #000003
BEQ Z07762
Z07750: MOV #000001, Z01734
JMP Z07776
Z07762: CLR Z01732
JMP Z14044
;
Z07772: JMP Z14066 ; к продолжению анализа нажатой клавиши
;
Z07776: RETURN
; Обработка нажатия СБРОС
Z10076: CLR Z11314 ; очищаем сохранённую клавишу
Z10102: JMP Z15636 ; минус одна жизнь
;
Z10106: TST Z11110
BNE Z10120
MOV R0, Z11314 ; сохраняем нажатую клавишу
Z10120: RETURN
; Движение вниз
Z10122: ADD #000036, R1 ; следующая строка лабиринта
CMPB (R1), #000003 ; верёвка?
BNE Z10140 ; нет => переходим
JMP Z14376
Z10140: JMP Z14362
Z10144: SUB #000002, R0
CMPB (R0), #000001
BMI Z10164
CMPB (R0), #000003
BMI Z10212
Z10164: MOV #000003, R4
CALL Z06460
TST Z01704
BNE Z10206
Z10202: MOV R4, R3
Z10204: RETURN
Z10206: TST R5
BNE Z10204
Z10212: ADD #000037, R0 ; следующая строка лабиринта + 1 место
CMPB (R0), #000006 ; 6 - сундук?
BMI Z10250
MOV #2, R4
CALL Z06460
TST Z01704
BNE Z10244
BR Z10202
Z10244: TST R5
BNE Z10204
Z10250: SUB #000036, R0 ; предыдущая строка лабиринта
CMPB (R0), #000007 ; 7 - лестница?
BNE Z10316
Z10274: MOV #4, R4
CALL Z06460
TST Z01704
BEQ Z10202
TST R5
BNE Z10204
Z10316: TST Z01704
BEQ Z10334
CLR Z01704
Z10330: JMP Z17410
;
Z10334: MOV Z01730, R0 ; берём адрес в образе лабиринта
Z10340: JMP Z06260
; .=010700
Z10700: ; Блок из двух спрайтов -- чёртик на лестнице
.WORD 007403,140300,007403,140300,006003,140060,007417,170360,001403,140300
.WORD 001403,140300,001417,140300,000014,030000,000074,030000,000000,036000
.WORD 001403,140360,001403,140360,006003,140060,007417,170360,007417,170360
.WORD 001417,170300,001403,140300,000014,030000,006014,030060,006014,000000
Z10750: ; Спрайт -- выход из лабиринта
.WORD 177777,177777,140300,001403,147717,171763,146314,031463,147717,141703
.WORD 146314,031463,146314,031463,147717,171763,140300,001403,177777,177777
; Номера ячеек выхода из лабиринта
; .=011000
Z11000::
.BYTE 25, 24, 01, 02, 17, 01, 27, 24, 20, 00
.BYTE 22, 35, 05, 15, 34, 16, 02, 30, 14, 34
.BYTE 34, 34, 33, 34, 35
.EVEN
; Подпрограмма ???
Z11040: INC Z01714 ;
TST Z01754
BEQ Z11056
;
Z11056: RETURN
; Подпрограмма ???
Z11066: CLR Z01714
Z11072: JMP Z17004
; .=011100
Z11100::
.BLKW 5 ;TODO: Уточнить, неясно сколько нужно
Z11102 = Z11100 + 2
Z11104 = Z11100 + 4
Z11106 = Z11100 + 6
Z11110 = Z11100 + 10 ; если 0, то нажатая клавиша сохраняется в Z11314
; Проигрывание мелодии: R2 = адрес блока
Z11112: NOP ;TSTB 177660
BPL Z11126
Z11120: NOP ;TST 177662
RETURN
Z11126: MOV (R2)+, R4
MOV (R2)+, R3
Z11132: CALL Z17200