Spectrofon #22
20 июля 1997

Система - программа управления «верхней» памятью.

<b>Система</b> - программа управления «верхней» памятью.
(C) PAUL FALCON, 1997

   Хотел  бы  вам  представить  программу,
которая поможет "бороться" с  верхней  па-
мятью.  То есть  управлять  ею  на  разных
машинах.

   Программа при запуске сама определяет с
каким компьютером она работает. И  выстав-
ляет переменные в соответствии с  тестиро-
ванием машины: какой компьютер, и  сколько
у него "мозгов" т.е. памяти.

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

   Основную систему 55-65% писал мой  друг
Юра Ковалевский.  Я  переработал,  добавил
еще машин для определения, написал 45-35%

   Hу теперь техническая информация,  соб-
ственно, что и как:

   Данные по определенной машине  находят-
ся в переменной (IY+118) (23728) и  распо-
ложение ее битов следующее:

 0 = 1 есть порт #7FFD  SPECTRUM 128K
 1 = 1 есть порт #1FFD  SCORPION или KAY
 2 = 1 есть порт #DFFD  PROFI
 3 = 1 есть порт #FFF7  TURBO 2+
 4 = 1 есть порт #FDFD  ATM TURBO
 5 = 1 действуют 6 и 7 bit  #7FFD
 6
 7 = 1 по адресу 8 байт #C3 (SCORPION)

   Соответствия по  значению,  т.е.  какое
значение будет иметь  переменная  (IY+118)
при определении того или иного компьютера:

 0      SPECTRUM    48K
 1      SPECTRUM    128K
 32+1   SPECTRUM    256K - 512K
 2      KAY         48K
 2+1    KAY         256K - 1024к
 4      PROFI       48K
 4+1    PROFI       256K - 1024K
 8      TURBO 2+    48K
 8+1    TURBO 2+    128K - 1024K
 16     ATM TURBO   48K
 16+1   ATM TURBO   128K - 512K
 128    SCORPION    48K
 128+1  SCORPION    128K
 128+2  SCORPION    256K - 1024K


   Количество реально  существующих  стра-
ниц заносится в переменную (IY+119)(23729).

   Управление программой настолько просто,
что надо знать всего три процедурки:

   Если при определении какой либо  машины
надо исключить несколько страниц, то здесь
поможет процедура DEBUG, в регистре C ука-
зывается номер удаляемой из таблицы  стра-
ницы. Делать это надо сразу после  опреде-
ления машины и  после  определения  памяти
(после CALL VIRT).

Пример:   C0....
              LD   C,8
              CALL DEBUG
              ....

   В данном примере будет удалена  страни-
ца номер 8 из доступных  для  переключения
(для Scorp'a полезно, не  убивается  тене-
вик).

   Если эта процедура вам  не  пригодится,
то можно смело вырезать ее из программы от
метки DEBUG до ONPAGE.

   Также количество страниц  и  их  номера
можно корректировать прямо в самой таблице
(в конце программы), изначально в ней  от-
сутствуют 2 и 5 страницы.

   Листание страниц по их логическому  но-
меру - процедура  ONPAGE.

Пример:   C0....
              LD   A,8
              CALL ONPAGE
              ....

   Данный пример включит с #C000 страницу,
находящуюся но номеру (в рег.  А) от нача-
ла таблицы (в нашем случае будет  включена
10 страница, если такая вообще здесь есть).

   Листание страниц по их физическому  но-
меру - это процедура  EX_RAM.

Пример:   C0....
              LD   A,8
              CALL EX_RAM
              ....

   С #C000 включится страница с номером  в
рег. А Т.е. реально 8 страница.

C0;   @  @ @ @@@ @@@
;  @ @ @ @  @  @ @
;  @ @ @ @  @  @ @  @@  @  @  @ @@ @ @@@
;  @ @ @ @  @  @ @  @  @ @ @@ @ @  @ @
;  @ @ @ @  @  @ @  @  @ @ @ @@ @@ @ @ @@
;  @@@ @ @  @  @ @  @  @ @ @  @ @  @ @  @
;  @ @ @@@  @  @@@  @@  @  @  @ @  @ @@@@
;
;  VERSION 5.5. IMPROVED.
;
;
; AUTOCONFIG PAGEMAKER FOR MACHINES:
;
;      TURBO 2+ (48K - 1024K) V6.00 - V7.1
;      ATM TURBO (48K - 512K) V4.10 - V5.20
;      SCORPION (48K - 1024K)
;      PROFI (48K - 1024K)
;      SPECTRUM (128K - 512K)  6 & 7 BIT #7FFD
;
; THE SHAREWARE PRODUCT FOR FREE USING!
; (при использовании данной процедуры в
; своих программах ссылка на авторов
; практически обязательна (но ваше дело))

C0START                      ; начало начал ...
        XOR     A
        LD      (IY+118),A ; тип компьютера
        INC     A
        LD      (IY+119),A ; число доступных страниц
        DI

; проверим (.) 'RST 8' в ROM 48 (если ZS-256,там #C3)

        LD      BC,#7FFD
        LD      A,#10
        OUT     (C),A
        LD      A,(#0008)
        CP      #C3
        JR      NZ,ITURBO  ; не ZS-256

; это наверно SCORPION

        SET     7,(IY+118)

ITURBO

; проверка наличия диспетчера RAM/ROM
; берем 2 байта из 0-го сегмента (там ROM48)

C0        LD      HL,(1111)

; дублируем ROM48 в 3-м сегменте (#C000-#FFFF)

        LD      BC,#FFF7
        LD      A,%00011111
        CALL    OUTC_A

; берем 2 байта 3-го сегмента (если TURBO 2+, там ROM48)

        LD      DE,(#C000+1111)
        AND     A
        SBC     HL,DE      ; сравниваем с байтами 0-го сегмента

; восстанавливаем диспетчер

        LD      BC,#FFF7
        LD      A,#FF
        CALL    OUTC_A
        JR      NZ,IDFFD   ; это не TURBO 2+

; обнаружен диспетчер RAM/ROM (TURBO 2+)

        SET     3,(IY+118)

C0        JR      I7FFD

; PROFI ?

IDFFD   LD      HL,#80
        LD      DE,#1000
        LD      BC,#DFFD

; проверка на порт #DFFD  bit 4
; (проверяем подключение RAM вместо ROM)

        OUT     (C),D      ; включаем 0-й сегмент RAM
                           ; вместо ПЗУ
                           ; пробуем отключить ROM
        NOP
        LD      A,(HL)     ; читаем байт
        INC     (HL)       ; меняем его
        CP      (HL)       ; сравниваем с прочитанным
        LD      (HL),A     ; восстанавливаем байт
        OUT     (C),E      ; восстанавливаем ROM
        JR      Z,I1FFD    ; нет порта #DFFD

; есть порт #DFFD (PROFI)

C0        SET     2,(IY+118)
        JR      I7FFD

; проверка на порт #1FFD  bit 0
; (проверка на подключение RAM вместо ROM)

I1FFD   LD      DE,#1110
        LD      B,#1F
        OUT     (C),D      ; включаем 8 сегмент RAM
        NOP
        LD      A,(HL)     ; читаем байт
        INC     (HL)       ; меняем его
        CP      (HL)       ; сравниваем с прочитанным
        LD      (HL),A     ; восстанавливаем байт
        OUT     (C),E      ; ставим ROM на место
        JR      Z,IFDFD    ; нет порта #1FFD

; есть порт #1FFD (SCORPION или KAY)

        XOR     A
        OUT     (C),A
        SET     1,(IY+118)
        JP      I7FFD

C0IFDFD
; Проверка на наличие порта #FDFD (АТМ-1)

        LD      B,C
        LD      HL,#FFFF
        OUT     (C),D
        NOP
        LD      B,#7F
        OUT     (C),D
        NOP
        LD      (HL),D
        LD      B,C
        OUT     (C),E
        NOP
        LD      B,#7F
        OUT     (C),D
        NOP
        LD      (HL),E
        LD      B,C
        OUT     (C),D
        NOP
        LD      B,#7F
        OUT     (C),D
        NOP

C0        LD      A,(HL)
        CP      D
        JR      NZ,I7FFD   ; нет такого слова

; однако есть порт  #FDFD

        SET     4,(IY+118)

; наличие порта (#7FFD)
; (проверка на переключение ROM48<->ROM128)

I7FFD   LD      HL,#80
        LD      DE,#1000
        LD      BC,#7FFD
        OUT     (C),D      ; ROM 1, однозначно!
        NOP
        LD      A,(HL)     ; байт ROM 48
        OUT     (C),E      ; ROM 0
        NOP
        CP      (HL)       ; байт из ROM 128
        OUT     (C),D      ; ROM 1
        NOP
        JR      Z,SIZED    ; нет порта или блокирован

C0; обнаружен порт #7FFD

        SET     0,(IY+118)

; определить объем памяти

SIZED
        CALL    VIRT       ; DE - конец таблицы (метка #FF)
        LD      A,(IY+119) ; SPECTRUN 256K-512K ?
        CP      #08
        JR      C,ENDING
        LD      A,(IY+118)
        CP      #01
        JR      NZ,ENDING
        SET     5,(IY+118) ; крутой SPECCY 256K - 512K
ENDING
        LD A,#00           ; страница после выхода из программы
        CALL EX_RAM        ; в порте #7FFD на SPECTRUM 128K .
        EI                 ; для нормального выхода .
        RET

; определение реальных (!) страниц для данной машины
; страницы "фантомы" удалятся из логической таблицы
; на выходе:

C0; DE - конец таблицы (метка #FF)
; переменная PAGE - доступное число страниц

VIRT    LD      IX,#C000

; заполнить страницы их номерами со спасением содержимого байт
; в точках проверки (#C000)

        LD      HL,DOOM+63
        LD      B,64
V_R11   LD      A,B
        DEC     A          ; NN стр. 63,62,61,60...1,0
        CALL    EX_RAM
        LD      C,(IX+0)
        LD      (HL),C     ; спасти содержимое байта
        LD      (IX+0),A   ; занести туда номер страницы
        DEC     HL
        DJNZ    V_R11

; исключить из таблицы не найденные страницы

        PUSH    AF
        LD      A,61
        LD      (IY+119),A

C0        POP     AF
        LD      DE,TABL_PG
V_R20   LD      A,(DE)
        CP      #FF
        JR      Z,V_R30    ; конец таблицы
        CALL    EX_RAM
        CP      (IX+0)     ; срав. номер стр. с содержимым байта
        JR      Z,V_R22    ; страница реально существует

; такой страницы по жизни  HET !!!

        PUSH    DE
        LD      HL,TABL_PG+62
        AND     A
        SBC     HL,DE
        PUSH    HL
        POP     BC         ; объем сдвига таблицы
        PUSH    DE
        POP     HL
        INC     HL
        LDIR
        DEC     (IY+119)   ; -1 доступная страница
        POP     DE
        DEC     DE

C0V_R22   INC     DE
        JR      V_R20

; восстанавливаем содержимое байт (#C000) на страницах

V_R30   LD      B,64
        LD      HL,DOOM
V_R31   LD      A,64
        SUB     B          ; NN стр. 0,1,2,3,4...62,63
        CALL    EX_RAM
        LD      A,(HL)
        LD      (IX+0),A   ; спасти содержимое байта
        INC     HL
        DJNZ    V_R31
        RET

; "выбоpка" из таблицы страниц заданной страницы
; на входе:
; C - N страницы
; DE - конец таблицы (метка #FF)
; на выходе:
; DE - конец таблицы (возможно, уже новый)

DEBUG   PUSH    DE

C0        POP     HL
NO_PG1  DEC     DE
        LD      A,(DE)
        CP      #FF
        JR      Z,NO_PG2   ; HE найдена удаляемая страница!!!
        CP      C
        JR      NZ,NO_PG1

;DE - на номере удаляемой страницы
;HL - на метке конца таблицы (#FF)

        SBC     HL,DE
        PUSH    HL
        POP     BC
        PUSH    DE
        POP     HL
        INC     HL
        LDIR
        DEC     (IY+119)   ; -1 доступная страница
        DEC     HL
        DEC     HL
NO_PG2  EX      DE,HL
        RET

C0; программа переключения страниц для различных типов машин

ONPAGE
        PUSH    BC         ; A - логический номер страницы
        PUSH    HL
        LD      C,A
        LD      B,#00
        LD      HL,TABL_PG
        ADD     HL,BC
        LD      A,(HL)     ; физический номер страницы
        POP     HL
        POP     BC

EX_RAM  DI                 ; A - физический номер страницы
        PUSH    HL
        PUSH    AF
        PUSH    BC
        BIT     1,(IY+118)
        JR      NZ,ZS256   ; SCORPION   (#1FFD)
        BIT     2,(IY+118)
        JR      NZ,PROFI   ; PROFI      (#DFFD)
        BIT     3,(IY+118)
        JR      NZ,TURBO_2 ; TURBO 2+   (#FFF7)
        BIT     4,(IY+118)

C0        JR      NZ,ATM1    ; ATM TURBO  (#FDFD)
        BIT     0,(IY+118)
        JR      NZ,SPECCY  ; SPECTRUM 128K-512K (#7FFD)
        BIT     7,(IY+118)
        JR      NZ,SPECCY  ; SCORPION 128K (#7FFD)
        JR      TDK

; для TURBO 2+ (поддерживает 128K-1024K)

TURBO_2 PUSH    AF
        PUSH    IX
        AND     %00011000
        CPL
        LD      BC,#FFF7
        CALL    OUTC_A
        POP     IX
        POP     AF
        JP      SPECCY

; ATM TURBO V4.10 - 5.20 (поддерживает 256K - 512K)

ATM1    LD      BC,#FDFD
        PUSH    AF
        RRCA

C0        RRCA
        RRCA
        AND     %00000011
        JR      HOME

; для PROFI (поддерживает 256K-1024K)

PROFI   LD      BC,#DFFD
        PUSH    AF
        RRCA
        RRCA
        RRCA
        AND     %00000111
        JR      HOME

; для SCORPION или KAY (поддерживает 512K-1024K нестандартно)

ZS256   PUSH    AF
        LD      B,A
        AND     %00001000
        RLCA
        LD      C,A
        LD      A,B
        AND     %00110000

C0        RLCA
        RLCA
        ADD     A,C
        LD      BC,#1FFD
HOME    OUT     (C),A
        NOP
        POP     AF

; для SPECTRUM 128K (поддерживает 256K-512K  нестандартно!)

SPECCY  LD      B,A
        AND     %00011000
        RLCA
        RLCA
        RLCA
        LD      C,A
        LD      A,B
        AND     %00000111
        ADD     A,C
        OR      #10        ; ROM 48
        LD      BC,#7FFD
        OUT     (C),A
        NOP

C0TDK
        POP     BC
        POP     AF
        POP     HL
        RET

OUTC_A  LD      IX,#2A53
        PUSH    IX
        JP      #3D2F

        DEFB    #FF
TABL_PG DEFB    00,01,03,04,06,07
        DEFB    08,09,10,11,12,13,14,15
        DEFB    16,17,18,19,20,21,22,23
        DEFB    24,25,26,27,28,29,30,31
        DEFB    32,33,34,35,36,37,38,39
        DEFB    40,41,42,43,44,45,46,47
        DEFB    48,49,50,51,52,53,54,55
        DEFB    56,57,58,59,60,61,62,63
        DEFB    #FF
DOOM    DEFS    64,0
────────────────────────────────────────────────────────────────
   Всего хорошего.         Paul Falcon
                   SPbZXNet: 812/03.00



Другие статьи номера:

Дебют - не много найдется игр, для написания которых понадобилась бы целых три года, Bloodwych одна из них.

Обзор - новые игры: Mystery of Arkham Manor, Magic Stripes, Satan II.

Зеркало - "Среди богов: Odin (Thor)" интервью с Стивеном Ветериллом, история компании.

Премьера - нашумевшая игра Doom, новая версия коммандера SW-Commander.

Экспертиза - подробное описание игры "Spooked".

Конструктор - описание программы для создания 3D игр "3D-Construction Kit".

Система - программа управления «верхней» памятью.

Штурм - фирменная инструкция к игре "War in the Middle Earth" ("Война в Сpедиземье").


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

Похожие статьи:
wArЫz! - BlackCrown #5, SlangPro_demo, SpaceCrusade, Rainbow_demo.
Почта - Интересная статья - о заковыристом втором коде в "Звездном наследии".
Вечный думатель - Издательства в условиях рынка.

В этот день...   6 мая