(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