Нестандартная загрузка © Игорь Комаров, г. Иркутск,1995.
Продолжая тему процедур нестандартной загрузки блоков кодов с магнитофона, обратимся к загрузчикам, использующим процедуру ПЗУ с точкой входа #05A9. Мы уже рассказывали об этом (ZX-РЕВЮ-94, № 6, стр. 26-29). Там же пообещали в дальнейшем рассказать о нюансах использования этой процедуры.
Предоставляем слово нашему Иркутскому корреспонденту, приславшему емкое письмо, в котором раскрываются многие секреты.
Для начала предлагаю свою версию "линейного" загрузчика, загружающего картинку в экран по одной пиксельной линии последовательно сверху вниз.
Загрузчик работает с кодовыми файлами стандартной длины 6912 байтов, предварительно перекодированными соответствующим образом.
1 |
ORG |
50000 |
10 |
INC |
D |
2 |
ENT |
$ |
11 |
EX |
AF, AF |
3 LOOP |
LD |
IX,#4000 |
12 |
DEC |
D |
4 |
PUSH |
IX |
14 |
CALL |
#05 6A |
5 |
LD |
DE,32 |
15 |
POP |
DE |
6 |
SUB |
A |
16 |
LD |
B, 3 |
7 |
DEC |
A |
17 |
PUSH |
BC |
8 |
SCF |
|
18 |
LD |
B, 8 |
9 |
DI |
|
19 |
PUSH |
BC |
20 |
|
PUSH |
DE |
37 |
POP |
BC |
21 |
|
PUSH |
BC |
38 |
LD |
DE,32 |
22 |
|
JR |
K1 |
39 |
ADD |
IX, DE |
23 |
; |
|
|
40 |
DJNZ |
L2 |
24 |
L1 |
PUSH |
BC |
41 |
POP |
BC |
25 |
|
LD |
B, 8 |
42 |
LD |
DE,1792 |
26 |
L2 |
PUSH |
BC |
43 |
ADD |
IX, DE |
27 |
|
PUSH |
IX |
44 |
DJNZ |
L1 |
28 |
|
LD |
B, 8 |
45 ; |
|
|
29 |
L3 |
PUSH |
BC |
46 |
LD |
IX,#5800 |
30 |
|
LD |
DE,32 |
47 |
LD |
DE,#0300 |
31 |
|
CALL |
#05A9 |
48 |
CALL |
#05A9 |
32 |
K1 |
POP |
BC |
49 |
EI |
|
33 |
|
LD |
DE,224 |
50 |
RET |
C |
34 |
|
ADD |
IX, DE |
51 |
XOR |
A |
35 |
|
DJNZ |
L3 |
52 |
OUT |
(#FE),A |
36 |
|
POP |
IX |
53 |
JR |
LOOP |
Длина блока = 88 байтов:
C350 |
DD |
21 |
00 |
40 |
DD |
E5 |
11 |
20 |
44 |
C358 |
00 |
97 |
3D |
37 |
F3 |
14 |
08 |
15 |
4A |
C360 |
CD |
6A |
05 |
D1 |
06 |
03 |
C5 |
06 |
04 |
C368 |
08 |
C5 |
D5 |
C5 |
18 |
0F |
C5 |
06 |
84 |
C370 |
08 |
C5 |
DD |
E5 |
06 |
08 |
C5 |
11 |
A6 |
C378 |
20 |
00 |
CD |
A9 |
05 |
C1 |
11 |
E0 |
88 |
C380 |
00 |
DD |
19 |
10 |
F1 |
DD |
E1 |
C1 |
B9 |
C388 |
11 |
20 |
00 |
DD |
19 |
10 |
E2 |
C1 |
25 |
C390 |
11 |
00 |
07 |
DD |
19 |
10 |
D7 |
DD |
25 |
C398 |
21 |
00 |
58 |
11 |
00 |
03 |
CD |
A9 |
5E |
C3A0 |
05 |
FB |
D8 |
AF |
D3 |
FE |
18 |
A8 |
7B |
Программа "зациклена" и при любой ошибке начнет процесс загрузки сначала. Если Вам это не нужно, поставьте в строке 50 просто RET, а строки 51-53 удалите.
Некоторые комментарии. Строки 3-13 ответственны за то, чтобы "процесс пошел" (см. указанный номер РЕВЮ, стр. 27).
В строках 15-22 нам приходится хитрить - заносить необходимые для трех циклов данные на стек. Это нужно для того, чтобы "влезть в середину циклов", точнее, мы должны продолжить догрузку семи оставшихся линий (по 32 байта каждая) верхнего ряда знакомест.
Программа-шифратор на Бейсике, конвертирующая экран в блок для "линейной" загрузки, выглядит так:
0 REM KOMAPOB'95*RIPPER 1/1
5 LET l=16384: LET k=4E4: LOAD ""CODE 16384
10 FOR h=1 TO 3: FOR f=1 TO 8: FOR n=1 TO 8: FOR m=0 TO 31
20 POKE k,PEEK (l+m): POKE (l+m),0: LET k=k+1: NEXT m
30 LET l=l+256: NEXT n
40 LET l=l-2016: NEXT f
50 LET l=l+1792: NEXT h
60 FOR n=0 TO 767: POKE k,PEEK (22528+n): POKE (22528+n),7: LET k=k+1: NEXT n 70 BEEP 1,0: INPUT "Filename:"; a$ 80 SAVE a$ CODE 4E4,6912
Другой нестандартный экранный "лоадер" похож на загрузчик "по четвертям", с которым читатели РЕВЮ уже знакомы (см. 2Х-РЕВЮ-93, №11-12, стр.244). Отличие этого варианта в том, что экран разделен не на 4, а на 12
1 |
7 |
2 |
8 |
9 |
3 |
10 |
4 |
5 |
11 |
6 |
12 |
Признаюсь, что сама идея этого загрузчика была позаимствована у хакеров DJS & LAPTEV из "закрытой" ими игры BATMAN (+3 levels).
1 ORG 50000 5 LD DE,8
2 ENT $ 6 LD A, #FF
3 LD IX,#4000 7 SCF
4 PUSH IX 8 DI
9 |
INC |
D |
47 |
|
LD |
H, A |
10 |
EX |
AF,AF' |
48 |
|
LD |
DE,24 |
11 |
DEC |
D |
49 |
|
CALL |
ONE |
12 |
CALL |
#05 6A |
50 |
|
POP |
DE |
13 ; |
|
|
51 |
|
POP |
BC |
14 |
LD |
B, 8 |
52 |
|
DJNZ |
L1 |
15 |
LD |
DE,248 |
53 |
|
EI |
|
16 |
CALL |
K1 |
54 |
|
RET |
|
17 |
POP |
IX |
55 |
; |
|
|
18 |
LD |
B, 8 |
56 |
DATA |
LD |
B,8 |
19 |
CALL |
K2 |
57 |
L2 |
PUSH |
BC |
20 |
LD |
IX,#5800 |
58 |
|
PUSH |
IX |
21 |
LD |
DE,24 |
59 |
|
LD |
DE,248 |
22 |
CALL |
ONE |
60 |
|
CALL |
ONE |
23 ; |
|
|
61 |
|
POP |
IX |
24 |
LD |
B, 11 |
62 |
|
POP |
BC |
25 |
LD |
DE,ADDR |
63 |
K2 |
LD |
DE,32 |
26 L1 |
PUSH |
BC |
64 |
|
ADD |
IX, DE |
27 |
LD |
A,(DE) |
65 |
|
DJNZ |
L2 |
28 |
DEFB |
#DD |
66 |
|
RET |
|
29 |
LD |
L, A |
67 |
; |
|
|
30 |
INC |
DE |
68 |
ONE |
LD |
B,8 |
31 |
LD |
A, (DE) |
69 |
L3 |
PUSH |
BC |
32 |
DEFB |
#DD |
70 |
|
PUSH |
DE |
33 |
LD |
H, A |
71 |
|
LD |
DE, 8 |
34 |
INC |
DE |
72 |
|
CALL |
#05A9 |
35 |
PUSH |
DE |
73 |
|
POP |
DE |
36 |
PUSH |
IX |
74 |
|
POP |
BC |
37 |
CALL |
DATA |
75 |
K1 |
ADD |
IX,DE |
38 |
POP |
IX |
76 |
|
DJNZ |
L3 |
39 |
DEFB |
#DD |
77 |
|
RET |
|
40 |
LD |
A, H |
78 |
; |
|
|
41 |
RRCA |
|
79 |
ADDR |
DEFW |
#4010 |
42 |
RRCA |
|
80 |
|
DEFW |
#4808,#4818 |
43 |
RRCA |
|
81 |
|
DEFW |
#5000,#5010 |
44 |
AND |
#03 |
82 |
|
DEFW |
#4008,#4018 |
45 |
OR |
#58 |
83 |
|
DEFW |
#4800,#4810 |
46 |
DEFB |
#DD |
84 |
|
DEFW |
#5008,#5018 |
Длина блока = 150 байтов:
C350 |
DD |
21 |
00 |
40 |
DD |
E5 |
11 |
08 |
2C |
C358 |
00 |
3E |
FF |
37 |
F3 |
14 |
08 |
15 |
B3 |
C360 |
CD |
6A |
05 |
06 |
08 |
11 |
F8 |
00 |
76 |
C368 |
CD |
CB |
C3 |
DD |
E1 |
06 |
08 |
CD |
1F |
C370 |
B7 |
C3 |
DD |
21 |
00 |
58 |
11 |
18 |
2C |
C378 |
00 |
CD |
BF |
C3 |
06 |
0B |
11 |
D0 |
7C |
C380 |
C3 |
C5 |
1A |
DD |
6F |
13 |
1A |
DD |
3B |
C388 |
67 |
13 |
D5 |
DD |
E5 |
CD |
A9 |
C3 |
95 |
C390 |
DD |
E1 |
DD |
7C |
0F |
0F |
0F |
E6 |
7D |
C398 |
03 |
F6 |
58 |
DD |
67 |
11 |
18 |
00 |
19 |
C3A0 |
CD |
BF |
C3 |
D1 |
C1 |
10 |
DA |
FB |
29 |
C3A8 |
C9 |
06 |
08 |
C5 |
DD |
E5 |
11 |
F8 |
D2 |
C3B0 |
00 |
CD |
BF |
C3 |
DD |
E1 |
C1 |
11 |
52 |
C3B8 |
20 |
00 |
DD |
19 |
10 |
ED |
C9 |
06 |
5D |
C3C0 |
08 |
C5 |
D5 |
11 |
08 |
00 |
CD |
A9 |
B4 |
C3C8 |
05 |
D1 |
C1 |
DD |
19 |
10 |
F2 |
C9 |
E3 |
C3D0 |
10 |
40 |
08 |
48 |
18 |
48 |
00 |
50 |
E3 |
C3D8 |
10 |
50 |
08 |
40 |
18 |
40 |
00 |
48 |
E3 |
C3E0 |
10 |
48 |
08 |
50 |
18 |
50 |
00 |
00 |
BB |
Увы, этот загрузчик уже не является релоцируемым, как первый, поскольку содержит команды CALL, а также таблицу, размещенную в конце, из которой берет адреса начала загрузки данных для 11 оставшихся квадратов (кроме первого, хотя Вы и так уже все поняли; если Вы разобрались с "линейным" загрузчиком, то все остальное, как говорится дело техники).
Бейсик-шифратор для этого загрузчика немного сложнее: 0 REM KOMAPOB'95*RIPPER 1/12
10 LOAD ""CODE 16384 15 LET n=4E4
2 0 FOR q=1 TO 12: READ adr: READ attr 30 LET adr1=adr
40 FOR k=0 TO 7: FOR a=0 TO 7: FOR s=0 TO 7
45 POKE n,PEEK (adr+s): POKE (adr+s),0: LET n=n+1: NEXT s
50 LET adr=adr+256: NEXT a
55 LET adr1=adr1+32: LET adr=adr1: NEXT k
60 FOR j=0 TO 7: FOR c=0 TO 7
65 POKE n,PEEK (attr+c): POKE (attr+c),7: LET n=n+1: NEXT c 70 LET attr=attr+32: NEXT j 75 NEXT q
80 BEEP 1,0: INPUT "Filename:";a$ 90 SAVE a$ CODE 4E4,6912
100 DATA 16384,22528,16400,22544,18440,22792,18456,22808 110 DATA 20480,23040,20496,23056,16392,22536,16408,22552 120 DATA 18432,22784,18448,22800,20488,23048,20504,23064 Чтобы окончательно подтвердить слова ИНФОРКОМА о том, что с помощью процедуры с точкой входа #05A9 можно загружать что угодно и куда угодно и хоть тоннами, хоть килограммами, приведу еще один экранный загрузчик. Это "загрузчик наоборот", со старших адресов к младшим. Однако я счел не очень красивым грузить атрибуты вперед данных, поэтому сначала идет загрузка дисплейного файла, затем - файла атрибутов.
1 |
ORG |
50000 |
18 |
|
JR |
Z,ATTR |
2 |
ENT |
$ |
19 |
|
LD |
E, #01 |
3 |
LD |
IX,#57FF |
20 |
|
CALL |
#05A9 |
4 |
LD |
DE,#0001 |
21 |
|
JR |
L1 |
5 |
LD |
A, #FF |
22 |
; |
|
|
6 |
SCF |
|
23 |
ATTR |
LD |
IX,#5AFF |
7 |
DI |
|
24 |
L2 |
LD |
E, #01 |
8 |
INC |
D |
25 |
|
CALL |
#05A9 |
9 |
EX |
AF,AF' |
26 |
|
DEC |
IX |
10 |
DEC |
D |
27 |
|
DEC |
IX |
11 |
CALL |
#05 6A |
28 |
|
DEFB |
#DD |
12 ; |
|
|
29 |
|
LD |
A, H |
13 L1 |
DEC |
IX |
30 |
|
CP |
#57 |
14 |
DEC |
IX |
31 |
|
JR |
NZ, L2 |
15 |
DEFB |
#DD |
32 |
|
EI |
|
16 |
LD |
A, H |
33 |
|
RET |
|
17 |
CP |
#3F |
|
|
|
|
Длина блока = 55 байтов:
C350 |
DD |
21 |
FF |
57 |
11 |
01 |
00 |
3E |
B7 |
C358 |
FF |
37 |
F3 |
14 |
08 |
15 |
CD |
6A |
AC |
C360 |
05 |
DD |
2B |
DD |
2B |
DD |
7C |
FE |
8F |
C368 |
3F |
28 |
07 |
1E |
01 |
CD |
A9 |
05 |
33 |
C370 |
18 |
EF |
DD |
21 |
FF |
5A |
1E |
01 |
B0 |
C378 |
CD |
A9 |
05 |
DD |
2B |
DD |
2B |
DD |
A3 |
C380 |
7C |
FE |
57 |
20 |
F1 |
FB |
C9 |
00 |
E9 |
А вот Бейсик-шифратор экрана:
0 REM KOMAPOB'95*RIPPER 1/-1 5 LET k=4E4: LET l=22527: LOAD ""CODE 16384
10 FOR n=0 TO 6143: POKE k,PEEK (l-n): POKE (l-n),0: LET k=k+1: NEXT n 20 LET l=23295
30 FOR n=0 TO 767: POKE k,PEEK (l-n): POKE (l-n),0: LET k=k+1: NEXT n 35 BEEP 1,0: INPUT "Filename:";a$ 40 SAVE a$ CODE 4E4,6912 И, в заключение, хочу дать несколько вариантов изменений старого доброго загрузчика от BARBARIANS, с которого, в общем-то, и начались все разговоры о нестандартной загрузке.
1. Первый вариант взят из польской версии игры TRAP DOOR (by MAC & SLA).
FE8F |
LD |
A, R |
FE90 |
RLCA |
|
FE91 |
RLA |
|
FE92 |
RLCA |
|
FE93 |
AND |
#07 |
FE95 |
OR |
#08 |
FE97 |
OUT |
(#FE) |
2. А тут даже два варианта, оба позаимствованы у Н.Родионова из TANK и HEAD OVER HEELS. Один вариант использовался при "четвертичной" загрузке экрана:
SCF RET
LD |
A,(#FE9E) |
INC |
A |
AND |
#01 |
LD |
(#FE9E),A |
OR |
#08 |
OUT |
(#FE),A |
SCF |
|
RET |
|
DEFB |
0 |
Другой вариант можно было лицезреть при загрузке кодовых блоков:
LD |
A,(#FEAA) |
PUSH |
BC |
LD |
B, #07 |
AND |
#07 |
OR |
#08 |
OUT |
(#FE),A |
INC |
A |
DJNZ |
#FE95 |
LD |
A, #00 |
LD |
(#FEAA),A |
OR |
#08 |
OUT |
(#FE),A |
POP |
BC |
SCF |
|
RET |
|
DEFB |
0 |
FEAA
3. Такие эффекты при загрузке видели все, так как они "имеют место быть" в загрузчиках программ BOMB JACK, COMMANDO, INTERNATIONAL KARATE 2 и других.
FE8D
INC |
A |
XOR |
#20 |
AND |
#27 |
LD |
C, A |
AND |
#07 |
OR |
#08 |
OUT |
(#FE),A |
SCF |
|
RET |
|
4. Билл Гилберт в загрузчике для ROBOCOP^ делает следующий эффект:
LD |
A,(IX+3) |
XOR |
C |
NEG |
|
AND |
#07 |
OR |
#08 |
OUT |
(#FE),A |
SCF |
|
RET |
|
5. И, наконец, S.S.CAPITAN (не путать с героем "Санта-Барбары"!) в программе STREET'GRED FOOTBALL применяет такой эффект:
FE8F
LD |
A, R |
|
AND |
#07 |
|
OR |
#08 |
|
OUT |
(#FE) |
,A |
XOR |
#07 |
|
OUT |
(#FE) |
,A |
XOR |
#07 |
|
OUT |
(#FE) |
,A |
LD |
R, A |
|
SCF |
|
|
RET |
|
|