(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