ZX-Ревю 1996 №9 1995 г.

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


(c) Д.Юркиев, 1996
     Предлагаю процедуру очистки экрана эффектом отключения телевизора. Как
уже говорилось выше, эта программа очищает экран по знакоместам, хотя лучше
было бы очистить его по линиям. Поэтому те, кому интересно могут
поэкспериментировать.

 10         ORG     40000
 20         LD      B,5
 30         CALL    SNEG
 40         LD      HL,0
 50         LD      (VAR),HL
 60         LD      HL,22528
 70         LD      DE,23264
 80         LD      B,11
 90 L0      PUSH    BC
 00         PUSH    HL
110         PUSH    DE
120         LD      B,32
130 L1      LD      (HL),0
140         XOR     A
150         LD      (DE),A
160         INC     HL
170         INC     DE
180         DJNZ    L1
190         LD      B,1
200         CALL    SNEG
210         POP     DE
220         POP     HL
230         LD      B,32
240 L2      DEC     DE
250         DJNZ    L2
260         LD      BC,32
270         ADD     HL,BC
280         POP     BC
290         DJNZ    L0
300         LD      HL,22880
310         LD      DE,22911
320         LD      B,16
330 L4      PUSH    BC
340         LD      B,1
350 L3      PUSH    BC
360         LD      (HL),0
370         PUSH    HL
380         LD      BC,32
390         ADD     HL,BC
400         LD      (HL),0
410         POP     HL
420         XOR     A
430         LD      (DE),A
440         PUSH    DE
450         LD      A,32
460         ADD     A,E
470         LD      E,A
480         XOR     A
490         LD      (DE),A
500         POP     DE
510         POP     BC
520         DJNZ    L3
530         INC     HL
540         DEC     DE
550         LD      B,1
560         CALL    SNEG
570         POP     BC
580         DJNZ    L4
590         LD      HL,16384
600         LD      DE,16385
610         LD      BC,6144
620         LD      (HL),0
630         LDIR
640         RET
650 SNEG    PUSH    HL
660         PUSH    DE
670         LD      HL,(VAR)
680 L5      PUSH    BC
690         PUSH    HL
700         LD      DE,16384
710         LD      BC,6144
720         LDIR
730         POP     HL
740         LD      BC,20
750         ADD     HL,BC
760         POP     BC
770         DJNZ    L5
780         LD      (VAR),HL
790         POP     DE
800         POP     HL
810         RET
820 VAR     DEFW    0

9C40: 06 05 CD AE 9C 21 00 00 :1F
9C48: 22 CB 9C 21 00 58 11 E0 :D7
9C50: 5A 06 0B C5 E5 D5 06 20 :FC
9C58: 36 00 AF 12 23 13 10 F8 :29
9C60: 06 01 CD AE 9C D1 E1 06 :D2
9C68: 20 1B 10 FD 01 20 00 09 :76
9C70: C1 10 E0 21 60 59 11 7F :27
9C78: 59 06 10 C5 06 01 C5 36 :4A
9C80: 00 E5 01 20 00 09 36 00 :61
9C88: E1 AF 12 D5 3E 20 83 5F :DB
9C90: AF 12 D1 C1 10 E8 23 1B :B5
9C98: 06 01 CD AE 9C C1 10 DB :FE
9CA0: 21 00 40 11 01 40 01 00 :F0
9CA8: 18 36 00 ED B0 C9 E5 D5 :B2
9CB0: 2A CB 9C C5 E5 11 00 40 :D8
9CB8: 01 00 18 ED B0 E1 01 14 :00
9CC0: 00 09 C1 10 EE 22 CB 9C :AD
9CC8: D1 E1 C9 00 00 00 00 00 :DF
*****************************************************************************
(c) Старков Павел, 1996

     Автор прислал две процедуры, одна из которых производит очистку экрана
оригинальным способом, а другая - вывод картинки на экран тем же способом. Для
второй процедуры необходимо загрузить картинку с адреса BUFF.
     А теперь предлагаем листинг программы очистки экрана.

  10         ORG     30000
  20         CALL    INIT
  30 PRN1    LD      DE,22527
  40         LD      HL,BUFF+6143+640
  50         LD      B,212
  60 LOOP2   PUSH    BC
  70         PUSH    HL
  80         PUSH    DE
  90         LD      BC,256+32
 100 L2      PUSH    BC
 110 L3      PUSH    HL
 120         PUSH    DE
 130         PUSH    BC
 140         LD      BC,32
 150         LDDR
 160         POP     BC
 170         POP     DE
 180         POP     HL
 190         CALL    DWN_D
 200         LD      A,D
 210         CP      88
 220         POP     IX
 230         JR      NC,EXT
 240         PUSH    IX
 250         DJNZ    L3
 260         ADD     HL,BC
 270         POP     BC
 280         INC     B
 290         LD      A,D
 300         CP      88
 310         JR      C,L2
 320 EXT     POP     DE
 330         LD      A,D
 340         AND     7
 350         JR      NZ,PASS3
 360         LD      A,D
 370         RRCA
 380         RRCA
 390         RRCA
 400         AND     3
 410         OR      88
 420         PUSH    DE
 430         LD      D,A
 440         PUSH    DE
 450         POP     HL
 460         DEC     DE
 470         LD      (HL),71
 480         LD      BC,31
 490         LDDR
 500         POP     DE
 510 PASS3   POP     HL
 520         CALL    UP_D
 530         LD      A,D
 540         CP      64
 550         JR      NC,L7
 560         CALL    DWN_D
 570 L7      LD      BC,32
 580         AND     A
 590         SBC     HL,BC
 600         POP     BC
 610         LD      A,B
 620         CP      140
 630         JR      C,PASS1
 640         HALT
 650 PASS1   DJNZ    LOOP2
 660         RET
 670 INIT    XOR     A
 680         OUT     (254),A
 690         LD      DE,BUFF+1
 700         LD      HL,BUFF
 710         LD      (HL),A
 720         LD      BC,639
 730         LDIR
 740         LD      HL,16384
 750         LD      B,192
 760 L1      PUSH    HL
 770         PUSH    BC
 780         LD      BC,32
 790         LDIR
 800         POP     BC
 810         POP     HL
 820         CALL    DWN_H
 830         DJNZ    L1
 840         RET
 850 DWN_H   INC     H
 860         LD      A,H
 870         AND     7
 880         RET     NZ
 890         LD      A,L
 900         ADD     A,32
 910         LD      L,A
 920         RET     C
 930         LD      A,H
 940         SUB     8
 950         LD      H,A
 960         RET
 970 DWN_D   INC     D
 980         LD      A,D
 990         AND     7
1000         RET     NZ
1010         LD      A,E
1020         ADD     A,32
1030         LD      E,A
1040         RET     C
1050         LD      A,D
1060         SUB     8
1070         LD      D,A
1080         RET
1090 UP_D    DEC     D
1100         LD      A,D
1110         AND     7
1120         CP      7
1130         RET     NZ
1140         LD      A,E
1150         SUB     32
1160         LD      E,A
1170         RET     C
1180         LD      A,D
1190         ADD     A,8
1200         LD      D,A
1210         RET
1220 BUFF    DEFS    6784

7530: CD 9A 75 11 FF 57 21 6B :74
7538: 90 06 D4 C5 E5 D5 01 20 :B7
7540: 01 C5 E5 D5 C5 01 20 00 :1B
7548: ED B8 C1 D1 E1 CD CC 75 :E3
7550: 7A FE 58 DD E1 30 0C DD :6C
7558: E5 10 E7 09 C1 04 7A FE :EF
7560: 58 38 DE D1 7A E6 07 20 :9B
7568: 15 7A 0F 0F 0F E6 03 F6 :78
7570: 58 D5 57 D5 E1 1B 36 47 :B7
7578: 01 1F 00 ED B8 D1 E1 CD :31
7580: DB 75 7A FE 40 30 03 CD :FD
7588: CC 75 01 20 00 A7 ED 42 :35
7590: C1 78 FE 8C 38 01 76 10 :87
7598: A2 C9 AF D3 FE 11 ED 75 :6B
75A0: 21 EC 75 77 01 7F 02 ED :7D
75A8: B0 21 00 40 06 C0 E5 C5 :9E
75B0: 01 20 00 ED B0 C1 E1 CD :52
75B8: BD 75 10 F2 C9 24 7C E6 :B0
75C0: 07 C0 7D C6 20 6F D8 7C :22
75C8: D6 08 67 C9 14 7A E6 07 :C6
75D0: C0 7B C6 20 5F D8 7A D6 :ED
75D8: 08 57 C9 15 7A E6 07 FE :EF
75E0: 07 C0 7B D6 20 5F D8 7A :3E
75E8: C6 08 57 C9 00 00 00 00 :4B

     А теперь программа вывода картинки на экран. Если сравнить эти программы,
то можно заметить, что они довольно схожи.

  10         ORG     30000
  20         CALL    INIT
  30 PRN1    LD      DE,22527
  40         LD      HL,BUFF+6143+576+768
  50         LD      B,192+18
  60 LOOP2   PUSH    BC
  70         PUSH    DE
  80         PUSH    HL
  90         LD      A,B
 100         LD      BC,256+32
 110         CP      193
 120         JR      NC,L2
 130         LD      A,D
 140         CPL
 150         AND     7
 160         JR      NZ,L2
 170         LD      A,D
 180         RRCA
 190         RRCA
 200         RRCA
 210         AND     3
 220         PUSH    DE
 230         PUSH    HL
 240         PUSH    BC
 250         LD      D,A
 260         LD      HL,BUFF
 270         ADD     HL,DE
 280         OR      88
 290         LD      D,A
 300         LD      BC,32
 310         LDDR
 320         POP     BC
 330         POP     HL
 340         POP     DE
 350 L2      PUSH    BC
 360 L3      PUSH    HL
 370         PUSH    DE
 380         PUSH    BC
 390         LD      BC,32
 400         LDDR
 410         POP     BC
 420         POP     DE
 430         POP     HL
 440         CALL    UP_D
 450         LD      A,D
 460         CP      64
 470         POP     IX
 480         JR      C,EXT
 490         PUSH    IX
 500         DJNZ    L3
 510         AND     A
 520         SBC     HL,BC
 530         POP     BC
 540         INC     B
 550         LD      A,D
 560         CP      64
 570         JR      NC,L2
 580 EXT     POP     HL
 590         LD      BC,32
 600         AND     A
 610         SBC     HL,BC
 620         POP     DE
 630         POP     BC
 640         LD      A,B
 650         CP      193
 660         JR      NC,PASS3
 670         CALL    UP_D
 680         LD      A,B
 690 PASS3   CP      65
 700         JR      NC,PASS1
 710         HALT
 720 PASS1   DJNZ    LOOP2
 730         RET
 740 INIT    XOR     A
 750         OUT     (254),A
 760         LD      HL,22528
 770         LD      DE,22529
 780         LD      BC,767
 790         LD      (HL),A
 800         LDIR
 810         LD      HL,BUFF
 820         LD      DE,16384
 830         LD      BC,6144
 840         LDIR
 850         LD      DE,BUFF
 860         LD      BC,768
 870         LDIR
 880         LD      HL,16384
 890         LD      B,192
 900 L1      PUSH    HL
 910         PUSH    BC
 920         LD      BC,32
 930         LDIR
 940         POP     BC
 950         POP     HL
 960         CALL    DWN_H
 970         DJNZ    L1
 980         PUSH    DE
 990         POP     HL
1000         INC     DE
1010         LD      (HL),B
1020         LD      BC,575
1030         LDIR
1040         LD      HL,16384
1050         LD      DE,16385
1060         LD      (HL),B
1070         LD      BC,6143
1080         LDIR
1090         INC     DE
1100         INC     HL
1110         LD      BC,767
1120         LD      (HL),71
1130         LDIR
1140         RET
1150 DWN_H   INC     H
1160         LD      A,H
1170         AND     7
1180         RET     NZ
1190         LD      A,L
1200         ADD     A,32
1210         LD      L,A
1220         RET     C
1230         LD      A,H
1240         SUB     8
1250         LD      H,A
1260         RET
1270 UP_D    DEC     D
1280         LD      A,D
1290         AND     7
1300         CP      7
1310         RET     NZ
1320         LD      A,E
1330         SUB     32
1340         LD      E,A
1350         RET     C
1360         LD      A,D
1370         ADD     A,8
1380         LD      D,A
1390         RET
1400 BUFF    DEFS    7488

7530: CD A3 75 11 FF 57 21 56 :68
7538: 93 06 D2 C5 D5 E5 78 01 :10
7540: 20 01 FE C1 30 1F 7A 2F :8D
7548: E6 07 20 19 7A 0F 0F 0F :8A
7550: E6 03 D5 E5 C5 57 21 17 :BC
7558: 76 19 F6 58 57 01 20 00 :22
7560: ED B8 C1 E1 D1 C5 E5 D5 :6C
7568: C5 01 20 00 ED B8 C1 D1 :FA
7570: E1 CD 06 76 7A FE 40 DD :A4
7578: E1 38 0E DD E5 10 E7 A7 :74
7580: ED 42 C1 04 7A FE 40 30 :D1
7588: DC E1 01 20 00 A7 ED 42 :B1
7590: D1 C1 78 FE C1 30 04 CD :CF
7598: 06 76 78 FE 41 30 01 76 :E7
75A0: 10 99 C9 AF D3 FE 21 00 :28
75A8: 58 11 01 58 01 FF 02 77 :58
75B0: ED B0 21 17 76 11 00 40 :C1
75B8: 01 00 18 ED B0 11 17 76 :81
75C0: 01 00 03 ED B0 21 00 40 :37
75C8: 06 C0 E5 C5 01 20 00 ED :BB
75D0: B0 C1 E1 CD F7 75 10 F2 :D2
75D8: D5 E1 13 70 01 3F 02 ED :B5
75E0: B0 21 00 40 11 01 40 70 :28
75E8: 01 FF 17 ED B0 13 23 01 :48
75F0: FF 02 36 47 ED B0 C9 24 :6D
75F8: 7C E6 07 C0 7D C6 20 6F :68
7600: D8 7C D6 08 67 C9 15 7A :67
7608: E6 07 FE 07 C0 7B D6 20 :A1
7610: 5F D8 7A C6 08 57 C9 00 :25
*******************************************************************************
(c) Андрияшкин Александр, 1996

     Александр предлагает программу печати текста:
     1. Кусок программы:
INC  HL        [6 тактов]
DEC  BC        [6 тактов]
LD   A,B       [4 такта]
OR   C         [4 такта]
JR   NZ,LOOP   [7/12 тактов]

   Можно заменить на аналогичный:

CPI            [16 тактов]
JP   PE,LOOP   [10 тактов]

  Он короче на 1 байт и работает быстрее.

     2. В следующей конструкции содержимое аккумулятора будет уменьшаться до
тех пор, пока не станет равно MIN, дальнейшего уменьшения не последует.
CP   MIN+1
CCF
SBC  A,0
     И, в итоге, он приводит программу печати текста в окне путем скроллинга
этого окна снизу вверх на один пиксел. Отличие ее в том, что она не требует
специального буфера.

 10         ORG     40000
 20 START   LD      HL,TXT
 30         PUSH    HL
 40 M1      LD      C,8
 50 M2      LD      B,20          ; ширина окна в знакоместах
 60         PUSH    BC
 70         LD      B,#63         ; высота окна в пикселах
 80         LD      HL,#4806      ; адрес левого верхнего угла
 90 M3      PUSH    BC
100         LD      D,H
110         LD      E,L
120         INC     H
130         LD      A,H
140         AND     7
150         JR      NZ,$+12
160         LD      A,L
170         SUB     #E0
180         LD      L,A
190         JR      NC,$+6
200         LD      A,H
210         SUB     8
220         LD      H,A
230         LD      BC,20         ; ширина окна в знакоместах
240         PUSH    HL
250         LDIR
260         POP     HL
270         POP     BC
280         DJNZ    M3
290         EX      DE,HL
300         POP     BC
310         POP     HL
320         PUSH    HL
330 M4      PUSH    HL
340         PUSH    DE
350         LD      A,(HL)
360         INC     A
370         ADD     A,A
380         LD      H,0
390         LD      L,A
400         ADD     HL,HL
410         ADD     HL,HL
420         LD      DE,FONT-256
430         ADD     HL,DE
440         LD      A,L
450         SUB     C
460         JR      NC,$+3
470         DEC     H
480         LD      L,A
490         LD      A,(HL)
500         POP     DE
510         LD      (DE),A
520         POP     HL
530         INC     HL
540         INC     DE
550         DJNZ    M4
560         LD      B,4           ; скорость перемещения
570 M6      HALT
580         LD      A,#BF
590         IN      A,(#FE)
600         RRCA
610         JR      NC,EXIT
620         DJNZ    M6
630         DEC     C
640         JR      NZ,M2
650         LD      A,(HL)
660         OR      A
670         EX      (SP),HL
680         JR      NZ,M1
690 EXIT    POP     HL
700         RET
710 TXT     DEFM    "                    "
720         DEFM    "     Written by     "
730         DEFM    "    Andrijashkin    "
740         DEFM    "       @ 1996       "
750         DEFM    "                    "
760         DEFB    0
770 FONT    EQU     15616

     Чтобы процедура работала хорошо, надо, чтобы длина текста была кратна
ширине окна (в данном случае 20), и после этого был байт 0.

9C40: 21 A1 9C E5 0E 08 06 14 :4F
9C48: C5 06 63 21 06 48 C5 54 :9A
9C50: 5D 24 7C E6 07 20 0A 7D :7D
9C58: D6 E0 6F 30 04 7C D6 08 :A7
9C60: 67 01 14 00 E5 ED B0 E1 :DB
9C68: C1 10 E3 EB C1 E1 E5 E5 :0F
9C70: D5 7E 3C 87 26 00 6F 29 :E0
9C78: 29 11 00 3C 19 7D 91 30 :E1
9C80: 01 25 6F 7E D1 12 E1 23 :16
9C88: 13 10 E4 06 04 76 3E BF :A8
9C90: DB FE 0F 30 0A 10 F6 0D :61
9C98: 20 AC 7E B7 E3 20 A5 E1 :BE
9CA0: C9 20 20 20 20 20 20 20 :E5
9CA8: 20 20 20 20 20 20 20 20 :44
9CB0: 20 20 20 20 20 20 20 20 :4C
9CB8: 20 20 57 72 69 74 74 65 :13
9CC0: 6E 20 62 79 20 20 20 20 :45
9CC8: 20 20 20 20 20 41 6E 64 :17
9CD0: 72 69 6A 61 73 68 6B 69 :C1
9CD8: 6E 20 20 20 20 20 20 20 :C2
9CE0: 20 20 20 20 40 20 31 39 :C6
9CE8: 39 36 20 20 20 20 20 20 :B3
9CF0: 20 20 20 20 20 20 20 20 :8C
9CF8: 20 20 20 20 20 20 20 20 :94
9D00: 20 20 20 20 20 00 00 00 :3D

     Также, Александр предлагает в процедурах печати, при расчете
адреса шаблона буквы, заменить первый ADD HL,HL на ADD A,A. При этом экономится
11-4=7 тактов. Но при этом не будут использоваться символы с кодом больше 127.
То же можно сделать и со второй командой ADD HL,HL, сократив число символов до
64.
     Если в программе строки с 70 по 280 выделить в подпрограмму и вызывать ее
два раза, то можно получить скроллинг букв двойной высоты.
*********************************************
(c) Колотов Сергей, г.Шадринск

   В ZX РЕБЮ 96/4-5, читая раздел "Этюды", я наткнулся на процедуры опроса 
клавиш. Принцип, использованный  А. Шокало  совсем неплох, но сами программы 
вызвали у меня внутренний протест. "Слишком много лишних байтов!" - подумал я и 
сел за компьютер.
   Вскоре новые процедурки уже были  написаны и отлажены. Принцип работы остался
прежним, а вот размер  значительно  уменьшился. Итак, "свежие" процедуры:
Listing 1. Клавиатурные процедурки.

REDEF   ;ждет нажатия на любую клавишу
        ;на выходе:
        ; B=старший байт порта клавиатуры
        ; A=маска нажатой клавиши (бит установлен в 1)
        LD      BC,#FEFE ;адрес порта опроса клавиатуры
LP_DEF  RRC     B        ;"пробегаем" все полуряды
        IN      A,(C)    ;считываем данные из порта
        CPL              ;инвертируем все биты
        AND     #1F      ;отбрасываем 3 ненужных бита
        JR      Z,LP_DEF ;если нет нажатий, то продолжить
        RET              ;возврат из процедуры
;
TRANSF  ;декодирует данные REDEF в код символа
        ;на входе:
        ; B=старший байт порта клавиатуры
        ; A=маска нажатой клавиши (бит установлен в 1)
        ;на выходе:
        ; A=код клавиши (C.S.=#E3, S.S.=#0E, ENTER=#0D)
        LD      H,B     ;H=порт клавиатуры
        LD      B,#04   ;определяем
LPTR1   RRA             ; порядковый
        JR      C,GOTR1 ; номер
        DJNZ    LPTR1   ; клавиши
GOTR1   LD      A,B     ; в полуряде
        ADD     A,A     ;умножаем
        ADD     A,A     ; его
        ADD     A,A     ; на 8
        LD      B,#07   ;определяем
LPTR2   RR      H       ; порядковый
        JR      NC,GOTR2; номер
        DJNZ    LPTR2   ; полуряда
GOTR2   ADD     A,B     ;прибавляем K аккумулятору
        ADD     A,#05   ;смещение
        LD      L,A     ; в таблице
        LD      H,#02   ;адрес таблицы в пзу: #0205
        LD      A,(HL)  ;A=код клавиши из таблицы
        RET             ;выход из процедуры

   Метка REDEF. Ожидается  нажатие  любой клавиши (кроме RESET, естественно), и  
результат работы помещается в регистры  A  и B (как не вспомнить: "сидели на 
трубе!"). Регистр B  содержит  старший  байт  адреса порта клавиатуры (полуряд),  
а в аккумуляторе находится маска нажатой клавиши (соответствующий бит включен). 
Длина процедуры 13 байт.
   Метка TRANSF - перекодировка в код символа. Результаты предыдущей процедуры  
перерабатываются и, в соответствии с таблицей
из ПЗУ (адрес таблицы #0205),  код  символа помещается в аккумулятор. То есть 
A=(#30..#39, #41..#5A) - цифры и прописные английские буквы. Следует также  
отметить, что несимвольным клавишам присвоены  следующие коды: SPACE - #20, 
CAPS SHIFT - #E3,  SYMBOL SHIFT - #0E, ENTER - #0D. Длина процедуры 28 байт.

   В ZX РЕВЮ 96/3 на стр. 51  опубликована статья Владимира Зореева с 
доработанной им процедурой печати спрайта Вадима Бодрова (ZX РЕВЮ 95/4, стр. 15).  
Да, я  согласен, что скорость  увеличилась,  но  можно  еще быстрее. А насчет 
"оригинального  алгоритма, придуманного мной" - как пишет  Владимир, так даже и 
не знаю, что сказать...
   Абсолютно такие же алгоритмы можно найти практически в любой игре или 
программе, использующей спрайтовую (растровую) графику. Примеры же программ, 
основанных на данном методе, можно встретить и в широко распространенных 
изданиях "Инфоркома". Например, ZX FORUM'94 - там стрелка выводится именно  
таким  способом.  Или все то же ZX РЕВЮ 95/5 - в статье на стр. 29 "Процедура 
печати 42 символов в строке" использует ту же технику. Похоже, вновь "изобретен 
велосипед".
   Перейдем от грустного к более  приятному - к новой процедуре, работающей 
быстрее предыдущей. Спрайты, смещение которых  относительно байта равно 0 
печатаются  вообще отдельной подпрограммкой и появляются на экране практически  
мгновенно.  Объем расходуемой памяти немного увеличился,  но на притягательность 
любой графической программы влияет прежде всего скорость вывода на экран, так 
что это не так уж и страшно. Вдобавок, процедуру можно вызывать как  из бейсика, 
так и из машинных кодов, что  более актуально. Длина процедуры 220 байт.

Listing 2. Быстрый вывод спрайта

;      SPRITE OUTPUT 2.3
;      (C)SERZHSOFT'1996
;DEF FN M(X,Y,L,H,A,O)=USR 65005
;
        ORG     65005   ;адрес ассемблирования
;
DEF_FN  ;точка входа из бейсика по DEF FN
        LD      IX,(#5C0B)      ;IX=адрес параметров DEF FN
        LD      D,(IX+4)        ;X-координата спрайта
        LD      E,(IX+12)       ;Y-координата спрайта
        LD      B,(IX+20)       ;ширина спрайта в байтах
        LD      C,(IX+28)       ;высота спрайта в пикселях
        LD      L,(IX+36)       ;адрес спрайта
        LD      H,(IX+37)       ; в памяти
        LD      A,(IX+44)       ;режим вывода на экран
;
PUTSPR  ;точка входа из маш. кодов
        ;D: X-координата, е: Y-координата
        ;B: ширина, C: высота
        ;HL: адрес спрайта
        ;A: режим вывода (0=OR, 1=XOR, 2=AND)
        EX      AF,AF'  ;альтернативный аккумулятор
        XOR     A       ; обнуляется -
        EX      AF,AF'  ; это будет маска для сдвига
        CP      1       ;проверка:
        LD      A,180   ; если A<1 (т.е. A=0), то
        JR      C,GOPS1 ; A=180 (OR H) и переход
        LD      A,172   ;если A=1, то
        JR      Z,GOPS1 ; A=172 (XOR H) и переход
        LD      A,164   ;если A>1, то A=164 (AND H)
        EX      AF,AF'  ;раз AND, значит необходимо
        CPL             ; AF'=255, что и
        EX      AF,AF'  ; выполняем (A=0, CPL => A=255)
GOPS1   LD      (MODE_1),A      ;исправляем
        INC     A               ; необходимые
        LD      (MODE_2),A      ; команды вывода
        INC     A               ; в зависимости
        LD      (MODE_5),A      ; от режима (OR, XOR, AND)
        EX      AF,AF'          ;A=маска сдвига
        LD      (MODE_0+1),A    ;поместили "куда надо"
        AND     D               ;операция "и" с X-коорд.
        AND     #07             ;теперь A=0..7: смещение
        LD      (MODE_4+2),A    ; в таблице TBL_OR
        LD      A,D     ;координата X
        AND     #07     ;позиция первого бита в байте экрана
        EX      AF,AF'  ;запомнили в AF'
        PUSH    HL      ;пихнули адрес спрайта на стек
        LD      A,#BF   ;максимальная Y-координата
        SUB     E       ;отсчет координат
        LD      E,A     ; снизу-вверх
        LD      A,E     ;------------------------
        RRA             ; расчет адреса в экране
        SCF             ;    по координатам:
        RRA             ;
        RRA             ;на входе:
        AND     #5F     ; D=X-координата
        LD      H,A     ; E=Y-координата
        XOR     D       ;
        AND     #07     ;на выходе:
        XOR     D       ; HL=адрес в экране
        RRCA            ;
        RRCA            ;D,E  не меняются
        RRCA            ;
        LD      L,A     ;используется
        LD      A,E     ; аккумулятор
        XOR     H       ;
        AND     #07     ;
        XOR     H       ;
        LD      H,A     ;------------------------
        EX      AF,AF'          ;вспомнили позицию бита
        JR      Z,NOSHFT        ;если =0, то переход
        LD      (JUMPER+1),A    ;поместили в JR для прыжка
        LD      IX,TBL_OR       ;IX=адрес таблицы TBL_OR
MODE_4  LD      A,(IX+0)        ;байт со смещением 0..7 из
        LD      (MODE_3+1),A    ; таблицы (для OR)
        POP     IX      ;IX=адрес начала спрайта
        EX      DE,HL   ;DE=адрес байта в экране
LPPS1   PUSH    BC      ;сохранили ширину и высоту
        LD      A,E     ;сохранили регистр E
        EX      AF,AF'  ; в AF'
LPPS2   LD      L,(IX+0);L=байт спрайта
MODE_0  LD      H,#00   ;H=0 для OR, XOR; H=255 для AND
JUMPER  JR      $       ;прыжок через лишние ADD HL,HL'ы
        ADD     HL,HL   ;-------------
        ADD     HL,HL   ;
        ADD     HL,HL   ;сдвиг байта
        ADD     HL,HL   ; спрайта
        ADD     HL,HL   ; нужное
        ADD     HL,HL   ; число раз
        ADD     HL,HL   ;
        ADD     HL,HL   ;-------------
        LD      A,(DE)  ;взяли байт с экрана
MODE_1  OR      H       ;OR, XOR или AND
        LD      (DE),A  ;поставили назад
        INC     E       ;следующий байт экрана
        LD      A,L     ;дополнили регистр L нужными
MODE_3  OR      #00     ; включенными битами (как-будто
        LD      L,A     ; не ADD HL,HL'ы, A RLC HL'ы)
        LD      A,(DE)  ;байт с экрана
MODE_2  OR      L       ;OR,XOR или AND
        LD      (DE),A  ;поместили обратно
        INC     IX      ;следующий байт спрайта
        DJNZ    LPPS2   ;повторять "ширина" раз
        EX      AF,AF'  ;восстановили
        LD      E,A     ; регистр E
        INC     D       ;следующая линия экрана
        LD      A,D     ;если мл. 3 бита регистра D
        AND     #07     ; равны нулю, то
        JR      Z,GOPS3 ; переход на корректировку
GOPS2   POP     BC      ;восстановили ширину и высоту
        DEC     C       ;повторять цикл
        JP      NZ,LPPS1; "высота" раз
        RET             ;выход из процедуры
GOPS3   LD      A,E     ;--------------------
        ADD     A,#20   ;
        LD      E,A     ;корректировка DE
        JR      C,GOPS2 ; для перехода на
        LD      A,D     ; линию ниже
        SUB     #08     ; (в экране)
        LD      D,A     ;
        JP      GOPS2   ;--------------------
;
NOSHFT  ;вывод спрайта по байтам (X-координата кратна 8)
        POP     DE      ;DE=адрес спрайта в памяти
LPPS3   PUSH    BC      ;сохранили ширину и высоту
        LD      A,L     ;запомнили
        EX      AF,AF'  ; регистр L в AF'
LPPS4   LD      A,(DE)  ;взяли байт спрайта
MODE_5  OR      (HL)    ;OR, XOR или AND
        LD      (HL),A  ;поместили на экран
        INC     DE      ;следующий байт спрайта
        INC     L       ;следующий байт экрана
        DJNZ    LPPS4   ;цикл "ширина" раз
        EX      AF,AF'  ;восстановили
        LD      L,A     ; регистр L
        INC     H       ;перешли к следующей линии экрана
        LD      A,H     ;если младшие 3 бита регистра H
        AND     #07     ; равны нулю, то
        JR      Z,GOPS5 ; перейти на корректировку
GOPS4   POP     BC      ;вспомнили ширину и высоту
        DEC     C       ;повторили
        JP      NZ,LPPS3; "высота" раз
        RET             ;выход из процедуры
GOPS5   LD      A,L     ;-------------------
        ADD     A,#20   ;
        LD      L,A     ;корректировка HL
        JR      C,GOPS4 ; для перехода
        LD      A,H     ; на линию ниже
        SUB     #08     ; (в экране)
        LD      H,A     ;
        JP      GOPS4   ;-------------------
;
;таблица для наложения на байты после их сдвига
;(для имитации команд "RLC HL" через ADD HL,HL)
TBL_OR  DB      #00,#7F,#3F,#1F,#0F,#07,#03,#01
;
;END OF SPRITE OUTPUT 2.3


Listing 3. Дамп процедуры SPRITE OUTPUT

FDED: DD 2A 0B 5C DD 56 04 DD :6C
FDF5: 5E 0C DD 46 14 DD 4E 1C :DA
FDFD: DD 6E 24 DD 66 25 DD 7E :2C
FE05: 2C 08 AF 08 FE 01 3E B4 :DF
FE0D: 38 09 3E AC 28 05 3E A4 :45
FE15: 08 2F 08 32 72 FE 3C 32 :62
FE1D: 7A FE 3C 32 A0 FE 08 32 :D9
FE25: 66 FE A2 E6 07 32 58 FE :9E
FE2D: 7A E6 07 08 E5 3E BF 93 :0F
FE35: 5F 7B 1F 37 1F 1F E6 5F :E6
FE3D: 67 AA E6 07 AA 0F 0F 0F :10
FE45: 6F 7B AC E6 07 AC 67 08 :E1
FE4D: 28 4C 32 68 FE DD 21 C1 :16
FE55: FE DD 7E 00 32 77 FE DD :30
FE5D: E1 EB C5 7B 08 DD 6E 00 :BA
FE65: 26 00 18 FE 29 29 29 29 :43
FE6D: 29 29 29 29 1A B4 12 1C :0B
FE75: 7D F6 00 6F 1A B5 12 DD :13
FE7D: 23 10 E2 08 5F 14 7A E6 :6B
FE85: 07 28 06 C1 0D C2 5F FE :A5
FE8D: C9 7B C6 20 5F 38 F4 7A :BA
FE95: D6 08 57 C3 88 FE D1 C5 :A7
FE9D: 7D 08 1A B6 77 13 2C 10 :B6
FEA5: F9 08 6F 24 7C E6 07 28 :C8
FEAD: 06 C1 0D C2 9C FE C9 7D :21
FEB5: C6 20 6F 38 F4 7C D6 08 :8E
FEBD: 67 C3 AE FE 00 7F 3F 1F :6E
FEC5: 0F 07 03 01 FD FD FD FD :D1

   Работая на ассемблере уже несколько лет, я долгое время так и не знал 
принципа работы (стыдобушка!) команды DAA (#27). Но вот недавно, загрузив 
непревзойденный STS, я наконец детально разобрался в алгоритме работы этой 
операции, чем и делюсь с теми, кто по каким-то причинам до сих пор этого не 
сделал.
   На работу команды влияют флаги C,H,N, а также содержимое регистра A. 
Алгоритм:
 1. Если флаг N выключен (равен 0), то в последующих шагах выполняется операция
   сложения. Если же включен (равен 1), то операция вычитания.
 2. Если аккумулятор больше #90 или флаг C включен, то к аккумулятору 
    прибавляется (вычитается) #60. Здесь не случайно написано "или". Если и 
    A>#90, и  CF=1, то сложение (вычитание) #60  происходит всего лишь один раз.
 3. Если младший полубайт больше #9  или флаг H включен, то аналогично п.2 к 
    аккумулятору прибавляется (вычитается) #06. Здесь также работает принцип 
    OR.

   И еще, в  копилку  эффективных  приемов программирования...
   Как-то раз, программируя на ассемблере, я столкнулся с одной проблемой. Шла 
интенсивная работа с экраном  и  использовалось большое количество мелких  
вложенных  циклов. Регистров катастрофически не хватало, а использовать стек не 
представлялось возможным - он был переустановлен на данные.
Но выход я все-таки нашел.
   Было решено, что один регистр будет отвечать сразу за несколько переменных  
циклов. Вот как это, примерно, выглядело:
          ...
          LD   A,%00000101
   ;биты:         xxxyyzzz
   LP1    OR   %00010000
   LP2    OR   %10000000
   LP3    EX   AF,AF'
          ...
          EX   AF,AF'
          SUB  %00100000
          JR   NC,LP3
          AND  %00011111
          SUB  %00001000
          JR   NC,LP2
          AND  %00000111
          SUB  %00000001
          JR   NC,LP1
          ...
   Говоря нормальным языком, под  переменные каждого цикла отводилось по  
нескольку бит регистра A. В вышеприведенном примере аккумулятор разбивался на 
три части:  биты 0,1,2; 3,4; 5,6,7. А число циклов было соответственно 6, 3, 5.  
Чем больше порядковый номер битов, тем вложенней цикл.  Значения, задаваеммые  
командами  LD A,...; OR ... должны быть на единицу меньше числа выполняемых 
циклов. В самом внешнем цикле вместо SUB ... можно написать DEC A с последующей 
проверкой  флага Z.  Но  в  этом случае в команде LD A,... необходимо задавать 
реальное число циклов, а не уменьшенное на 1. Командами  AND ... сбрасываются
все биты, отвечающие за "вышестоящие" циклы.
***************************************************************************

(c) Евгений Куликаев, р.п. Муромцево,'96

    Представляю на суд читателей ZX Ревю
три свои программы.
    Первая  производит   очистку  экрана
оригинальным  способом, как бы расщепляя
его, задвигая при этом вверх и вниз. Сам
экран располагается с адреса  BUFF и пе-
реносится самой  программой. После появ-
ления  картинки  на  экране, нужно нажать
SPACE  для  продолжения.  Для  изменения
скорости расползания необходимо изменить
шаг, т.е. на сколько линий  раздвигается
экран за один проход.Все строки, которые
нужно изменить выделены в листинге.Длину я старался  сделать как можно меньше,
но получилась 171 байт.

(C) Program 'Crawl' by E.Kulikaev '96.

1          ORG  40000
2          ENT  $
3   BUFF   EQU  30000
4          LD   HL,BUFF
5          LD   DE,16384
6          LD   BC,6144
7          LDIR
8   PAU    LD   A,#7F
9          IN   A,(#FE)
10         RRA
11         JR   C,PAU
12  SCR1   LD   B,24/2

;--------------------------
; Сколько  раз  происходит
; скролинг. Рассчитываемое
; по  формуле  24/(шаг/8)
; число,должно быть целым.
;--------------------------

13  LSCR   PUSH BC
14         LD   HL,22527-95

;--------------------------
; Адрес 16-ой снизу линии
; экрана.
;--------------------------

15         LD   DE,22527-31
16         LD   B,192-16

;--------------------------
;Кол-во скроллируемых вниз
;линий.
;--------------------------

17  SD     PUSH DE
18         PUSH HL
19         LD   C,32
20  SD1    LD   A,(DE)
21         XOR  (HL)
22         AND  %10101010
23         XOR  (HL)
24         LD   (DE),A
25         INC  DE
26         INC  HL
27         DEC  C
28         JR   NZ,SD1
29         POP  DE
30         CALL L_UP
31         EX   DE,HL
32         POP  DE
33         CALL L_UP
34         DJNZ SD
35         LD   HL,16384
36         LD   C,16

;--------------------------
; Кол-во очищаемых сверху
; линий.
;--------------------------

37  SD3    PUSH HL
38         LD   B,32
39  SD2    LD   A,(HL)
40         AND  %10101010
41         LD   (HL),A
42         INC  HL
43         DJNZ SD2
44         POP  DE
45         CALL L_DE
46         EX   DE,HL
47         DEC  C
48         JR   NZ,SD3
49         LD   HL,16384+64

;--------------------------
; Адрес 16-ой линии экрана
; сверху.
;--------------------------

50         LD   DE,16384
51         LD   B,192-16

;--------------------------
;Кол-во скроллируемых вверх
;линий экрана.
;--------------------------

52  SU     PUSH DE
53         PUSH HL
54         LD   C,32
55  SU1    LD   A,(DE)
56         XOR  (HL)
57         AND  %01010101
58         XOR  (HL)
59         LD   (DE),A
60         INC  DE
61         INC  HL
62         DEC  C
63         JR   NZ,SU1
64         POP  DE
65         CALL L_DE
66         EX   DE,HL
67         POP  DE
68         CALL L_DE
69         DJNZ SU
70         LD   HL,22527-95

;--------------------------
; Адрес 16-ой линии экрана
; снизу.
;--------------------------

71         LD   C,17

;--------------------------
;Кол-во очищаемых внизу ли-
;ний.
;--------------------------

72  SU3    PUSH HL
73         LD   B,32
74  SU2    LD   A,(HL)
75         AND  %01010101
76         LD   (HL),A
77         INC  HL
78         DJNZ SU2
79         POP  DE
80         CALL L_DE
81         EX   DE,HL
82         DEC  C
83         JR   NZ,SU3
84         POP  BC
85         DJNZ LSCR
86         RET
87  L_DE   INC  D
88         LD   A,D
89         AND  7
90         RET  NZ
91         LD   A,E
92         ADD  A,32
93         LD   E,A
94         RET  C
95         LD   A,D
96         SUB  8
97         LD   D,A
98         RET
99  L_UP   DEC  D
100        LD   A,D
101        AND  7
102        CP   7
103        RET  NZ
104        LD   A,E
105        SUB  32
106        LD   E,A
107        RET  C
108        LD   A,D
109        ADD  A,8
110        LD   D,A
111        RET

    Вторая  программа  выводит  на экран
картинку, размещенную с адреса BUFF. Она
прорисовывается  линией  атрибутов, закручивающейся по часовой  стрелке. 
Процедуру печати  линии я взял из книги 'Элементарная графика',изд."ИНФОРКОМ",
немного ее переделав. Все  регулируемые  параметры  показаны в
листинге программы. Ее  длинна 278 байт,
но  эффект  довольно  интересный, и может
применяться (с небольшими переделками) в других целях.

(C) Program 'Clock' by E.Кulikaev '96.

1          ORG  40000
2          ENT  $
3   BUFF   EQU  30000
4          LD   HL,22528
5          LD   DE,22529
6          LD   BC,767
7          LD   (HL),L
8          LDIR
9          LD   HL,BUFF
10         LD   DE,16384
11         LD   BC,6144
12         LDIR
13         LD   DE,0
14         LD   B,31
15  L1     CALL LINE
16         INC  D
17         CALL LINE1
18         DJNZ L1
19         LD   B,23
20  L2     CALL LINE
21         INC  E
22         CALL LINE1
23         DJNZ L2
24         LD   B,31
25  L3     CALL LINE
26         DEC  D
27         CALL LINE1
28         DJNZ L3
29         LD   B,23
30  L4     CALL LINE
31         DEC  E
32         CALL LINE1
33         DJNZ L4
34         CALL LINE
35         RET
36  LINE   PUSH DE
37         PUSH BC
38         PUSH DE
39  ZAMP   LD   BC,3000
40  PAU    DEC  BC
41         LD   A,B
42         OR   C
43         JR   NZ,PAU
44         LD   DE,#100C
45         LD   (COORD),DE
46         CALL PLOT
47         POP  DE
48         LD   HL,(COORD)
49         EXX
50         PUSH HL
51         EXX
52         LD   BC,#0101
53         LD   A,D
54         SUB  H
55         JP   NC,CONT_1
56         LD   B,#FF
57         NEG
58  CONT_1 LD   D,A
59         LD   A,E
60         SUB  L
61         JR   NC,CONT_2
62         LD   C,#FF
63         NEG
64  CONT_2 LD   E,A
65         LD   A,D
66         CP   E
67         JR   NC,CONT_3
68         LD   L,D
69         LD   (SIGN),BC
70         XOR  A
71         LD   B,A
72         JR   CONT_4
73  CONT_3 OR   D
74         JR   Z,FINISH
75         LD   L,E
76         LD   E,D
77         LD   (SIGN),BC
78         LD   C,0
79  CONT_4 LD   H,E
80         LD   A,E
81         RRA
82  REPEAT ADD  A,L
83         JR   C,CONT_5
84         CP   H
85         JR   C,CONT_6
86  CONT_5 SUB  H
87         LD   D,A
88         EXX
89         LD   DE,(SIGN)
90         JR   CONT_7
91  CONT_6 LD   D,A
92         PUSH BC
93         EXX
94         POP  DE
95  CONT_7 LD   HL,(COORD)
96         LD   A,E
97         ADD  A,L
98         LD   E,A
99         LD   A,D
100        INC  A
101        ADD  A,H
102        JR   C,CONT_8
103        JR   Z,FINISH
104 CONT_9 DEC  A
105        LD   D,A
106        LD   (COORD),DE
107        CALL PLOT
108        EXX
109        LD   A,D
110        DEC  E
111        JR   NZ,REPEAT
112        JR   FINISH
113 CONT_8 JR   Z,CONT_9
114 FINISH EXX
115        POP  HL
116        EXX
117        POP  BC
118        POP  DE
119        RET
120 SIGN   DEFW 0
121 COORD  DEFW 0
122 PLOT   LD   A,E
123        AND  #18
124        SRL  A
125        SRL  A
126        SRL  A
127        OR   #58
128        LD   H,A
129        LD   A,E
130        AND  7
131        OR   A
132        RRA
133        RRA
134        RRA
135        RRA
136        ADD  A,D
137        LD   L,A
138        PUSH HL
139        LD   DE,22528
140        OR   A
141        SBC  HL,DE
142        LD   DE,BUFF+6144
143        ADD  HL,DE

;---------------------------
; В строках 139-143 происхо-
; дит расчет адреса в  атри-
; бутах выводимой картинки.
;---------------------------

144        LD   A,(HL)
145        POP  HL
146 ZAM    NOP
147        NOP
;---------------------------
; Сюда программа вставляет
; команду LD A,атрибут, нуж-
; ную для прорисовки выводя-
; щей линии.
;---------------------------

148        LD   (HL),A
149        RET
150 LINE1  LD   HL,256*63+62

;---------------------------
; Если  вы  хотите  изменить
; цвет линии, поменяйте чис-
; ло 63 на нужный атрибут.
;---------------------------

151        LD   (ZAM),HL
152        LD   HL,1
153        LD   (ZAMP+1),HL
154        CALL LINE
155        LD   HL,0
156        LD   (ZAM),HL
157        LD   HL,3000

;---------------------------
; Изменить скорость вывода
; можно изменив величину
; паузы.
;---------------------------

158        LD   (ZAMP+1),HL
159        RET

    Третья программа увеличивает изображение в центре экрана на весь экран. 
Я не стал  учитывать и  атрибуты,  так как программа бы выросла почти в два 
раза, а она и так 133 байта. Программа не использует дополнительных буферов,
поэтому увеличение  проходит в два этапа, так как иначе затирается еще  не  
увеличенная часть центральной области.

(C) Program 'Zoom' by E.kulikaev '96.

1          ORG  40000
2          ENT  $
3          LD   HL,16384
4          LD   DE,16384+201

;---------------------------
; В DE адрес левого верхнего
; угла центральной области
; экрана.
;---------------------------

5          LD   B,48

;---------------------------
; Высота увеличиваемой обл.
;---------------------------

6   L1     PUSH DE
7          CALL DOUB
8          CALL L_DE
9          PUSH DE
10         PUSH BC
11         LD   BC,32
12         LDIR
13         POP  BC
14         POP  DE
15         CALL L_DE
16         EX   DE,HL
17         POP  DE
18         CALL L_DE
19         DJNZ L1
20         LD   HL,22527-31
21         LD   DE,22527-214

;---------------------------
; Адрес левого нижнего угла
; центральной обл.
;---------------------------

22         LD   B,48

;---------------------------
; Высота нижней части обл.
;---------------------------

23  R1     PUSH DE
24         CALL DOUB
25         CALL L_UP
26         PUSH DE
27         PUSH BC
28         LD   BC,32
29         LDIR
30         POP  BC
31         POP  DE
32         CALL L_UP
33         EX   DE,HL
34         POP  DE
35         CALL L_UP
36         DJNZ R1
37         RET
38  DOUB   PUSH HL
39         LD   C,16
40  L2     PUSH BC
41         LD   A,(DE)
42         LD   BC,#0402
43  L3     PUSH BC
44  L4     RLA
45         PUSH AF
46         RL   (HL)
47         POP  AF
48         RL   (HL)
49         DJNZ L4
50         INC  HL
51         POP  BC
52         DEC  C
53         JR   NZ,L3
54         INC  DE
55         POP  BC
56         DEC  C
57         JR   NZ,L2
58         POP  HL
59         PUSH HL
60         POP  DE
61         RET
62  L_DE   INC  D
63         LD   A,D
64         AND  7
65         RET  NZ
66         LD   A,E
67         ADD  A,32
68         LD   E,A
69         RET  C
70         LD   A,D
71         SUB  8
72         LD   D,A
73         RET
74  L_UP   DEC  D
75         LD   A,D
76         AND  7
77         CP   7
78         RET  NZ
79         LD   A,E
80         SUB  32
81         LD   E,A
82         RET  C
83         LD   A,D
84         ADD  A,8
85         LD   D,A
86         RET
         ********************************************************

(c) Старков Павел, 1996.

      Предлагаю вниманию читателей процедуру выгрузки/загрузки, не
использующую системные переменные. С ее помощью на диск можно записать кодовый
блок в виде файла. Драйвер записи/чтения сектора был взят из ZX РЕВЮ 95/4.
      Чтобы записать кодовый блок, нужно вызвать процедуру SAVE. При этом в
регистровой паре HL - адрес начала файла в памяти, в DE - длина файла, а с
метки DATA должно находиться имя файла (8 байтов) и байт расширения файла.
      При загрузке нужно вызвать процедуру LOAD. При этом, с метки DATA должны
находиться аналогичные данные, что и при записи. Если при вызове процедуры
загрузки в регистре A - 0, то стартовый адрес и длина файла будет взята из
каталога, а если A не равен 0, то в регистре HL - адрес, в DE - длина файла.
      Если при выходе из SAVE или LOAD, в регистре A содержится 0, то процедура
отработала успешно, если не равно 0 - ошибка.
      При работе с модулем существует несколько проблем:

      1. Если в записываемый блок попадают ячейки #5C00-5C01 и #5CFE-5D01, то
их содержимое будет записано неверно, т.к. процедура записи во время работы
использует эти ячейки, восстанавливая их при выходе. Чтобы эти ячейки записать
правильно, надо сначала перебросить записываемый блок в другую область памяти
и записывать его оттуда.

      2. Если при записи диск будет неотформатирован или защищен от записи,
программа попытается выдать сообщение Retry, Abort, Ignore, но если системные
переменные уничтожены, то последствия будут печальны.

      3. Если при загрузке не будет читаться какой-нибудь сектор, то программа
зависнет.

      В остальном программа работает устойчиво. Весь модуль вместе с
переменными занимает 476 байт + буфер длиной 256 байт, расположенный следом за
программой.

     10         ORG     50000
     20 SAVE    LD      (START),HL
     30         LD      (LEN),DE
     40         CALL    ON_DSK
     50         LD      DE,8
     60         CALL    LOADL
     70         LD      A,(BUFF+228)
     80         CP      128
     90         RET     NC
    100         LD      HL,(BUFF+225)
    110         LD      (SECTRK),HL
    120         LD      HL,(LEN)
    130         PUSH    AF
    140         LD      C,H
    150         INC     L
    160         DEC     L
    170         JR      Z,S1
    180         INC     C
    190 S1      LD      B,0
    200         LD      A,C
    210         LD      (LENSEC),A
    220         LD      HL,(BUFF+229)
    230         POP     AF
    240         AND     A
    250         SBC     HL,BC
    260         RET     C
    270         PUSH    HL
    280         LD      (NUM1+1),A
    290         LD      D,B
    300         LD      B,A
    310         AND     15
    320         ADD     A,A
    330         ADD     A,A
    340         ADD     A,A
    350         ADD     A,A
    360         LD      E,A
    370         LD      HL,BUFF
    380         ADD     HL,DE
    390         PUSH    HL
    400         LD      A,B
    410         AND     240
    420         RRA
    430         RRA
    440         RRA
    450         RRA
    460         LD      E,A
    470         LD      (SYSTRK+1),DE
    480         CALL    LOADL
    490         POP     DE
    500         LD      HL,DATA
    510         LD      BC,16
    520         LDIR
    530         LD      A,(NUM1+1)
    540         CPL
    550         AND     15
    560         PUSH    AF
    570         JR      Z,S9
    580         XOR     A
    590         LD      (DE),A
    600 S9      LD      DE,(SECTRK)
    610         LD      HL,(START)
    620         LD      A,(LENSEC)
    630         LD      B,A
    640         LD      C,6
    650         CALL    DRIVER
    660         POP     AF
    670         PUSH    DE
    680         PUSH    AF
    690         LD      DE,(SYSTRK+1)
    700         CALL    SAVEL
    710         POP     AF
    720         JR      NZ,S3
    730 SYSTRK  LD      DE,0
    740         INC     E
    750         CALL    LOADL
    760         XOR     A
    770         LD      (BUFF),A
    780         DEC     E
    790         CALL    SAVEL
    800 S3      LD      DE,8
    810         CALL    LOADL
    820         POP     HL
    830         LD      (BUFF+225),HL
    840         POP     HL
    850         LD      (BUFF+229),HL
    860 NUM1    LD      A,0
    870         INC     A
    880         LD      (BUFF+228),A
    890         LD      DE,8
    900         CALL    SAVEL
    910         XOR     A
    920         RET
    930 LOAD    LD      (LENSEC),A
    940         LD      (START),HL
    950         LD      (LEN),DE
    960         CALL    ON_DSK
    970         LD      DE,8
    980         CALL    LOADL
    990         LD      A,(BUFF+228)
   1000         LD      (NUM1+1),A
   1010         LD      DE,0
   1020 LOAD0   CALL    LOADL
   1030         LD      DE,BUFF
   1040         LD      IX,NUM1+1
   1050         LD      B,16
   1060 LOAD1   PUSH    DE
   1070         LD      HL,DATA
   1080         LD      C,9
   1090 LOAD2   LD      A,(DE)
   1100         CP      (HL)
   1110         JR      Z,LOAD3
   1120         POP     DE
   1130         DEC     (IX+0)
   1140         RET     Z
   1150         LD      HL,16
   1160         ADD     HL,DE
   1170         EX      DE,HL
   1180         DJNZ    LOAD1
   1190 IS_TRK  LD      DE,0
   1200         JR      LOAD0
   1210 LOAD3   INC     DE
   1220         INC     HL
   1230         DEC     C
   1240         JR      NZ,LOAD2
   1250         POP     IX
   1260         LD      HL,(START)
   1270         LD      BC,(LEN)
   1280         LD      A,(LENSEC)
   1290         AND     A
   1300         JR      NZ,LOAD6
   1310         LD      L,(IX+9)
   1320         LD      H,(IX+10)
   1330         LD      C,(IX+11)
   1340         LD      B,(IX+12)
   1350 LOAD6   LD      E,(IX+14)
   1360         LD      D,(IX+15)
   1370 LOAD5   INC     B
   1380         DEC     B
   1390         JR      Z,LOAD8
   1400         PUSH    BC
   1410 LOAD7   LD      C,5
   1420         CALL    DRIVER
   1430         POP     BC
   1440         INC     C
   1450         DEC     C
   1460         RET     Z
   1470         LD      DE,(IS_TRK+1)
   1480 LOAD8   PUSH    HL
   1490         CALL    LOADL
   1500         POP     DE
   1510         LD      BC,(LEN)
   1520         LD      B,0
   1530         LD      HL,BUFF
   1540         LDIR
   1550         LD      A,B
   1560         RET
   1570 LOADL   LD      C,5
   1580         JR      CONT2
   1590 SAVEL   LD      C,6
   1600 CONT2   LD      B,1
   1610         LD      HL,BUFF
   1620 DRIVER  BIT     0,C
   1630         JR      NZ,M1
   1640         EXX
   1650         PUSH    HL
   1660         LD      HL,(#5C00)
   1670         LD      DE,(#5CFE)
   1680         LD      BC,(#5D00)
   1690         EXX
   1700         XOR     A
   1710         LD      (#5C00),A
   1720 M1      DI
   1730 L1      PUSH    DE
   1740         PUSH    BC
   1750         LD      A,D
   1760         OR      A
   1770         RRA
   1780         LD      C,A
   1790         LD      A,#3C
   1800         JR      NC,L2
   1810         LD      A,#2C
   1820 L2      LD      IX,#2F4D
   1830         CALL    DOS
   1840         POP     BC
   1850         POP     DE
   1860 L3      BIT     0,C
   1870         JR      NZ,M2
   1880         LD      A,E
   1890         LD      (#5CFF),A
   1900         LD      (#5D00),HL
   1910 M2      PUSH    HL
   1920         PUSH    DE
   1930         PUSH    BC
   1940         LD      IX,#2F1B
   1950         BIT     0,C
   1960         JR      NZ,M3
   1970         LD      IX,#3F0A
   1980 M3      CALL    DOS
   1990         POP     BC
   2000         POP     DE
   2010         POP     HL
   2020         INC     H
   2030         INC     E
   2040         BIT     4,E
   2050         JR      NZ,L5
   2060         BIT     0,C
   2070         JR      NZ,M4
   2080         LD      A,E
   2090         LD      (#5CFF),A
   2100 M4      DJNZ    L3
   2110         JR      EXIT
   2120 L5      LD      E,0
   2130         INC     D
   2140         DJNZ    L1
   2150 EXIT    LD      (IS_TRK+1),DE
   2160         BIT     0,C
   2170         RET     NZ
   2180         EXX
   2190         LD      (#5D00),BC
   2200         LD      (#5CFE),DE
   2210         LD      (#5C00),HL
   2220         POP     HL
   2230         EXX
   2240         RET
   2250 ON_DSK  DI
   2260         LD      IX,#2F65
   2270 DOS     PUSH    IX
   2280         JP      #3D2F
   2290 DATA    DEFM    "FileNameC"
   2300 START   DEFW    0
   2310 LEN     DEFW    0
   2320 LENSEC  DEFB    0
   2330 SECTRK  DEFW    0
   2340 BUFF    DEFS    256

***************************************



СОДЕРЖАНИЕ:


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

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



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

Похожие статьи:
Обзор - обзор новых игрушек: Gloc R360, Match of the day, Mutant fortness.
B.B.S. Новости - О работе B.B.S.'ок.
Премьера - радиолюбителям: программа для пакетной радио связи RTTY.
Реклама - Реклама и объявления ...
23 Things Which You Can Do If A Program Crashes

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