CODING - Процедура управления верхней памятью на разных машинах.
╔══════════════════════════════════════════════════════════════╗
│ C0DING │
╚══════════════════════════════════════════════════════════════╝
(C) PAUL FALCON
Вот хотел бы вам представить програмку, которая поможет "бо-
роться" с верхней памятью. То есть управлять ею на разных маши-
нах.
Программа при запуске сама определяет с каким компьютером она
работает. И выставляет переменные в соответствии с тестирова-
нием машины: какой компьютер, и сколько у него "мозгов" т.е. па-
мяти.
Для работы с программой достаточно обращения к трем процеду-
рам независимо от типа определенного компьютера.
Основную систему 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).
Пример : ....
LD C,8
CALL DEBUG
....
В данном примере будет удалена страница номер 8 из доступных
для переключения (для Scorp'a полезно, не убивается теневик).
Если эта процедура вам не пригодится, то можно смело выре-
зать ее из программы от метки DEBUG до ONPAGE.
Также количество страниц и их номера можно корректировать
прям в самой таблице (в конце программы) изначально в ней отсут-
ствуют 2 и 5 страницы.
Листание страниц по их логическому номеру, это процедура
ONPAGE.
Пример : ....
LD A,8
CALL ONPAGE
....
Данный пример включит с #C000 страницу, находящуюся но номе-
ру (в рег. А) от начала таблицы (в нашем случае будет включена
10 страница, если такая вообще здесь есть).
Листание страниц по их физическому номеру - это процедура
EX_RAM.
Пример : ....
LD A,8
CALL EX_RAM
....
С #C000 включится страница с номером (в рег. А). Т.е. реально
8 страница.
Вот собственно сама прога ...
; @ @ @ @@@ @@@
; @ @ @ @ @ @ @
; @ @ @ @ @ @ @ @@ @ @ @ @@ @ @@@
; @ @ @ @ @ @ @ @ @ @ @@ @ @ @ @
; @ @ @ @ @ @ @ @ @ @ @ @@ @@ @ @ @@
; @@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @
; @ @ @@@ @ @@@ @@ @ @ @ @ @ @@@@
;
; 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!
; (при использовании данной процедуры в
; своих программах ссылка на авторов
; практически обязательна (но ваше дело))
START ; начало начал ...
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)
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)
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)
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
IFDFD
; Проверка на наличие порта #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
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 ; нет порта или блокирован
; обнаружен порт #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
; определение реальных (!) страниц для данной машины
; страницы "фантомы" удалятся из логической таблицы
; на выходе:
; 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
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
V_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
; "выдирка" из таблицы страниц заданной страницы
; на входе:
; C - N страницы
; DE - конец таблицы (метка #FF)
; на выходе:
; DE - конец таблицы (возможно, уже новый)
DEBUG PUSH DE
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
; программа переключения страниц для различных типов машин
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)
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
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
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
TDK
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
Hу вот вроде и вся программа, если что, пишите на мой сете-
вой адрес в SpbZXNet (812/03.00).
Всего хорошего.
Paul Falcon (CREATOR)
SPbZXNet: 812/03.00
Другие статьи номера:
|
|
CODING - Процедура управления верхней памятью на разных машинах.
|
|
|
|
|