[<>]
~~TOC wide~~
FIXME
{{anchor:n108}}
====== 1.8 Возможность расширения программного обеспечения на MSX–компьютерах ======
\\
Удачное аппаратное и программное решение определили
\\ популярность MSX–компьютеров в нашей стране. Однако
\\ широкие возможности MSX практически не описаны в
\\ отечественной литературе.
—//В. Лашук//
В подготовке этого материала принимали непосредственное участие:
\\ В.С.Лашук (Владимирский государственный педагогический институт),
\\ Ю.В.Юзифович (учащийся 8–го класса, г.Куйбышев).
{{anchor:n1081}}
===== 1.8.1 Подробная карта памяти =====
\\
Самый простой способ заново сложить дорожную
\\ карту — это сложить ее по–другому.
—//Из дорожных правил Джоунса//
Каждый, кому приходится работать с большим объемом информации, неизбежно сталкивается с проблемой нехватки памяти. Обычно считается, что объем доступной для пользователя памяти на MSX–компьютерах (RAM) составляет всего 32 Кбайта. Однако оказывается, что действительный объем RAM гораздо больше: 64 Кбайта на компьютерах серии MSX-1 и 134 Кбайта на компьютерах
серии MSX-2 !
Вся память хранится в особых устройствах, называемых //слотами// ("slot"—"позиция", "поле", "участок"). На схеме изображена слотовая //карта// памяти компьютера серии MSX-1 (ROM локальной сети располагается в слоте 3-1 по адресам 4000h÷53FFh):
┌──────┬───────┬───────┬───────┬───────────────────────────────────────┐
│ │ │ │ │ С л о т 3 │
│Адреса│ Слот 0│ Слот 1│ Слот 2├─────────┬─────────┬─────────┬─────────┤
│ │ │ │ │ Слот 3-0│ Слот 3-1│ Слот 3-2│ Слот 3-3│
├──────┼───────┼───────┼───────┼─────────┼─────────┼─────────┼─────────┤
│ 0000h│ ROM │ │ │ │ │ │ │
│ │ BASIC │ │ │ │ │ RAM │ │
│ 3FFFh│ (16 │ │ │ │ │ │ │
│ │Кбайтов) │ │ │ │ │ │
├──────┼───────┼───────┼───────┼─────────┼─────────┼─────────┼─────────┤
│ 4000h│ ROM │ ROM │ ROM │ │ ROM │ │ │
│ │ BASIC │ диско-│ диско-│ │локальной│ │ │
│ │ (16 │ вода A│ вода B│ │ сети │ RAM │ │
│ │Кбайтов) (16 │ (16 │ │ (5 │ │ │
│ 7FFFh│ │Кбайтов)Кбайтов) │ Кбайтов)│ │ │
├──────┼───────┼───────┼───────┼─────────┼─────────┼─────────┼─────────┤
│ 8000h│ │ ROM │ ROM │ │ │ │ │
│ │ │дополн.│дополн.│ │ │ RAM │ │
│ BFFFh│ │дисков.│дисков.│ │ │ │ │
├──────┼───────┼───────┼───────┼─────────┼─────────┼─────────┼─────────┤
│ C000h│ │ │ │ │ │ RAM │ │
│ │ │ │ │ │ │(систем- │ │
│ │ │ │ │ │ │ ная об- │ │
│ FFFFh│ │ │ │ │ │ ласть) │ │
└──────┴───────┴───────┴───────┴─────────┴─────────┴─────────┴─────────┘
Итак, в MSX–компьютерах имеется //четыре// слота. В свою очередь, к каждому слоту можно подключить расширитель, который содержит до //четырех// новых (//вторичных//) слотов. Обозначение "слот 3-1" подразумевает, что мы рассматриваем "подключение" к первичному слоту с номером 3 вторичного слота с номером 1.
Каждый слот имеет свою //метку (указатель)//. Указатель слота — это двоичное число, биты которого имеют следующий смысл:
┌───┬───┬───┬───┬───┬───┬───┬───┐
│ ∗ │ 0 │ 0 │ 0 │ ∗ │ ∗ │ ∗ │ ∗ │
└─▲─┴───┴───┴───┴───▲───┴───▲───┘
│ │ └─ Номер первичного слота (2 бита)
│ └───────── Номер вторичного слота (2 бита)
├── 0, если вторичный слот отсутствует или его номер равен нулю;
└── 1 - можно использовать в любом случае.
Например, для слота 3-2 указатель будет таким:
&b 1 0 0 0 1 0 1 1
▲ ─▲─ ─▲─
│ │ │
не 0 2 3
Напомним Вам, что для вызова подпрограммы, написанной в машинных кодах и расположенной в некотором слоте, применяется команда ассемблера:
RST 30h [Указатель слота/Адрес подпрограммы]
На языке [[msx:basic:|]] эту команду можно "моделировать" следующим способом:
{{anchor:e1081-01}} \\ {{.examples:1081-01.bas|}} \\ [[+tab|wmsxbpge>1081-01.bas]]
10 CLEAR 200,&HF300:DEFUSR=&HF300
20 INPUT"Номер первичного слота";N1
30 INPUT"Номер вторичного слота";N2
40 POKE &HF300,&HF7 ' F7 - код команды RST 30h
50 POKE &HF301,&H80+N2*4+N1 ' Указатель слота
60 INPUT"Адрес ячейки";AD%
70 POKE &HF302,PEEK(VARPTR(AD%)):POKE &HF303,PEEK(VARPTR(AD%)+1)
80 POKE &HF304,&HC9: A=USR(A) 'Код команды RET и запуск программы
Покажем расположение памяти в слотах для компьютеров серии MSX-2:
* α) //учительский// компьютер
Слот 0 Слот 1 Слот 2 Слот 3-0 Слот 3-1 Слот 3-2 Слот 3-3
0000h┌───────┐┌────────┐┌────────┐┌───────┐┌────────┐┌───────┐
│ ROM ││ ││ ││ ROM ││ ROM ││ │
3800h│(16 Кб)││ ││ ││(16 Кб)││(16 Кб) ││ RAM │┌────────┐
│ BIOS ││ ││ ││ ││ ││(16 Кб)││ RAM │
│ BASIC ││ ││ ││PAINTER││ BASIC ││ ││ (2 Кб) │
4000h├───────┤├────────┤├────────┤├───────┤├────────┤├───────┤├────────┤
│ ROM ││ ││ ││ ││ ROM ││ ││ ROM │
│(16 Кб)││ ROM ││ ROM ││ ROM ││(16 Кб) ││ ││ (14 Кб)│
│ ││( 16 Кб)││( 16 Кб)││(16 Кб)││ ││ RAM ││Лок.сеть│
7800h│ ││ ││ ││ ││Дисковод││(16 Кб)│├────────┤
│ ││ Дополн.││ Дополн.││PAINTER││(BASIC, ││ ││ RAM │
│ ││дисковод││дисковод││ ││MSX-DOS)││ ││ (2 Кб) │
│ ││ ││ ││ ││ ││ ││Лок.сеть│
8000h├───────┤├────────┤┼────────┤├───────┤├────────┤├───────┤├────────┤
│ ││ ROM ││ ROM ││ ROM ││ ││ ││ ROM │
│ ││( 16 Кб)││( 16 Кб)││(16 Кб)││ ││ ││ (14 Кб)│
│ ││ ││ ││ ││ ││ RAM ││Лок.сеть│
B800h│ ││ Дополн.││ Дополн.││PAINTER││ ││(16 Кб)│├────────┤
│ ││дисковод││дисковод││ ││ ││ ││ RAM │
│ ││ ││ ││ ││ ││ ││ (2 Кб) │
C000h├───────┤├────────┤├────────┤├───────┤├────────┤├───────┤├────────┤
│ ││ ││ ││ ROM ││ ││ RAM ││ │
│ ││ ││ ││(16 Кб)││ ││(16 Кб)││ │
│ ││ ││ ││PAINTER││ ││ System││ │
│ ││ ││ ││ ││ ││ area ││ │
FFFFh└───────┘└────────┘└────────┘└───────┘└────────┘├───────┤└────────┘
│ RAM │
│(16 Кб)│
├───────┤
│ RAM │
│(16 Кб)│
├───────┤
│ RAM │
│(16 Кб)│
├───────┤
│ RAM │
│(16 Кб)│
└───────┘
Записав в соответствующий порт номер переключаемой страницы можно установить эту страницу для //доступа//, например:
|&hFB|──────▶|порт с адресом &hFC|
|&hFA|──────▶|порт с адресом &hFD|
|&hF9|──────▶|порт с адресом &hFE|
|&hF8|──────▶|порт с адресом &hFF|
В отключаемых страницах данные сохраняются!
Л о г и ч е с к и е с т р а н и ц ы
┌───────────────────────────────────┐
3 2 1 0 ◀── Номера логических страниц слота 3-2
&hFF &hFE &hFD &hFC ◀── Адрес порта, отвечающего за
логическую страницу слота 3-2
┌────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐
│ &hC000-│ &h8000-│ &h4000-│ &h0000-│ │ │ │ │
│ &hFFFF │ &hBFFF │ &h7FFF │ &h3FFF │ │ │ │ │
├ ─ ─ ─ ─│─ ─ ─ ─ │─ ─ ─ ─ │─ ─ ─ ─ │ ─ ─ ─ ─│─ ─ ─ ─ │ ─ ─ ─ ─│─ ─ ─ ─ ┤
│ Н о м е р а с т р а н и ц RAM с л о т а 3-2 │
│ &hF8 │ &hF9 │ &hFA │ &hFB │ &hFC │ &hFD │ &hFE │ &hFF │
└────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘
0 1 2 3 4 5 6 7
└───────────────────────────────────────────────────────────────────────┘
Ф и з и ч е с к и е с т р а н и ц ы с л о т а 3-2 и их н о м е р а
* β) //ученический// компьютер
Слот 0 Слот 1 Слот 2 Слот 3-0 Слот 3-1 Слот 3-2 Слот 3-3
0000h┌───────┐┌────────┐┌────────┐┌───────┐┌────────┐┌───────┐
│ ROM ││ ││ ││ ROM ││ ││ │
3800h│(16 Кб)││ ││ ││(16 Кб)││ ││ RAM │┌────────┐
│ BIOS ││ ││ ││ ││ ││(16 Кб)││ RAM │
│ BASIC ││ ││ ││ BASIC ││ ││ ││ (2 Кб) │
4000h├───────┤├────────┤├────────┤├───────┤├────────┤├───────┤├────────┤
│ ROM ││ ││ ││ ││ ││ ││ ROM │
│(16 Кб)││ ROM ││ ROM ││ ROM ││ ROM ││ ││ (14 Кб)│
│ ││( 16 Кб)││( 16 Кб)││(16 Кб)││ (16 Кб)││ RAM ││Лок.сеть│
7800h│ ││ ││ ││ ││ ││(16 Кб)│├────────┤
│ ││ Дополн.││ Дополн.││Система││Дисковод││ ││ RAM │
│ ││дисковод││дисковод││ CP/M ││ (BASIC,││ ││ (2 Кб) │
│ ││ ││ ││ ││MSX-DOS)││ ││Лок.сеть│
8000h├───────┤├────────┤┼────────┤├───────┤├────────┤├───────┤├────────┤
│ ││ ROM ││ ROM ││ ROM ││ ││ ││ ROM │
│ ││( 16 Кб)││( 16 Кб)││(16 Кб)││ ││ ││ (14 Кб)│
│ ││ ││ ││ ││ ││ RAM ││Лок.сеть│
B800h│ ││ Дополн.││ Дополн.││Система││ ││(16 Кб)│├────────┤
│ ││дисковод││дисковод││ CP/M ││ ││ ││ RAM │
│ ││ ││ ││ ││ ││ ││ (2 Кб) │
C000h├───────┤├────────┤├────────┤├───────┤├────────┤├───────┤├────────┤
│ ││ ││ ││ ROM ││ ││ RAM ││ │
│ ││ ││ ││(16 Кб)││ ││(16 Кб)││ │
│ ││ ││ ││ ││ ││ System││ │
│ ││ ││ ││Система││ ││ area ││ │
│ ││ ││ ││ CP/M ││ ││ ││ │
FFFFh└───────┘└────────┘└────────┘└───────┘└────────┘├───────┤└────────┘
│ RAM │
│(16 Кб)│
├───────┤
│ RAM │
│(16 Кб)│
├───────┤
│ RAM │
│(16 Кб)│
├───────┤
│ RAM │
│(16 Кб)│
└───────┘
Нумерация физических и логических страниц слота 3-2, а также адреса соответствующих портов в ученическом компьютере аналогичны учительскому компьютеру.
Таким образом, непосредственным сложением нетрудно получить, что общий объем памяти MSX–компьютеров составляет:
^ //Компьютер// ^ ROM ^ RAM ^
|MSX-1 (без дисководов)| 37 Кбайтов | 64 Кбайта |
|MSX-2 (ученический)| 92 Кбайта | 134 Кбайта |
|MSX-2 (учительский)| 156 Кбайтов | 134 Кбайта |
В слоте 0 располагаются подпрограммы BIOS, используемые как в компьютерах серии MSX-1, так и в компьютерах серии MSX-2. Дополнительные подпрограммы BIOS ("расширенный BIOS"),которые используются только в компьютерах серии MSX-2, располагаются:
* для учительского компьютера - в слоте 3-1,
* для ученического компьютера - в слоте 3-0.
{{anchor:n1082}}
===== 1.8.2 Работа со слотами =====
\\
— Боюсь, что эти подробности утомительны,
\\ но вам не разобраться в ситуации, если
\\ вы не будете в курсе моих затруднений.
—//А.Конан Дойль. Скандал в Богемии//
Все адресное пространство MSX—компьютера разобьем на //четыре// т.н. //логические// страницы (объемом по 16 Kбайтов каждая).
Пронумеруем их следующим образом:
^ Адреса | 0÷3FFFh | 4000h÷7FFFh | 8000h÷BFFFh | C000h÷FFFFh |
^ Логическая страница | 0 | 1 | 2 | 3 |
Заметим, что каждый слот также можно разбить на участки объемом по 16 Кбайтов каждый, которые мы будем называть //физическими// страницами памяти. Прежде чем начать работу с физической страницей памяти, ее необходимо //подключить// к некоторой логической странице адресного пространства, для чего выполнить следующие операции:
* α) указать компьютеру //номер// подключаемой логической страницы(тем самым мы присвоим физической странице некоторый начальный адрес). Заметим, что при включении компьютера некоторым физическим страницам памяти начальный адрес присваивается автоматически;
* β) указать //номера// первичного и вторичного слотов, которым принадлежит выбранная физическая страница памяти.
Номера первичных слотов записываются в порт ввода–вывода с адресом A8h, а номера вторичных слотов — в ячейку FFFFh рабочей области (слот 3-2).
Порт ввода–вывода A8h: (номера //первичных// слотов)
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
Старший ─▶│ ∗ │ ∗ │ ∗ │ ∗ │ ∗ │ ∗ │ ∗ │ ∗ │◀─ Младший
бит └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ бит
─────▲───── ─────▲───── ─────▲───── ─────▲─────
│ │ │ └───────┐
Номер слота, из которого Номер слота Номер слота Номер слота
процессор берет информа- для логичес- для логичес- для логичес-
цию при обращении к ло- кой страницы кой страницы кой страницы
гической странице 3 с номером 2 с номером 1 с номером 0
Ячейка памяти FFFFh: (номера //вторичных// слотов)
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
Старший ─▶│ ∗ │ ∗ │ ∗ │ ∗ │ ∗ │ ∗ │ ∗ │ ∗ │◀─ Младший
бит └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ бит
─────▲───── ─────▲───── ─────▲───── ─────▲─────
│ │ │ └───────┐
Номер слота, из которого Номер слота Номер слота Номер слота
процессор берет информа- для логичес- для логичес- для логичес-
цию при обращении к ло- кой страницы кой страницы кой страницы
гической странице 3 с номером 2 с номером 1 с номером 0
Например, если содержимое порта A8h равно &B11001001, а содержимое ячейки FFFFh равно &B01101100 , то в этом случае:
* логическая страница 3 рассматривается как участок памяти из слота 3-1,
* логическая страница 2 рассматривается как участок памяти из слота 0-2,
* логическая страница 1 рассматривается как участок памяти из слота 2-3, а
* логическая страница 0 рассматривается как участок памяти из слота 1-0.
Теперь ясно, что подпрограмма подключения памяти к адресному пространству выглядит следующим образом:
DI ; Запретить прерывания при работе с портами ввода–вывода
LD A, Номера первичных слотов
OUT (A8h),A
LD A, Номера вторичных слотов
LD (FFFFh),A
EI ; Разрешить системные прерывания
RET
Внимание! При чтении числа из ячейки FFFFh оно выводится в //инвертированном// виде.
{{anchor:e1082-01}} __//Пример 1//__. \\ {{.examples:1082-01.bas|}} \\ [[+tab|wmsxbpge>1082-01.bas]]
10 POKE &HFFFF, &B01101100
20 PRINT BIN$(PEEK(&HFFFF))
run
10010011
Ok
Теперь для того, чтобы узнать, какие вторичные слоты подключены к адресному пространству, необходимо инвертировать полученный результат (заменить нули — единицами, а единицы — нулями).
Отметим, что при включении компьютера в логические страницы 0 и 1 "помещаются" физические страницы памяти из слота 0, а в логические страницы 2 и 3 "помещаются" физические страницы памяти из слота 3-2.
Содержимое порта ввода-вывода с адресом A8h при этом становится равным &B11110000, а истинное содержимое ячейки памяти FFFFh становится равным &B10100000 (не забудьте про инвертирование!)
Если до выключения компьютера на странице 1 слота 3-2 создать идентификатор ROM и разместить на данной странице Вашу подпрограмму, то она будет "стартовать" при включении компьютера, т.к. первое обращение идет к этой странице.
{{anchor:e1082-02}} __//Пример 2//__. А теперь небольшой фрагмент на макроассемблере...\\ {{.examples:1082-02.asm|}}
DEFB 0FEH ; Программа запускается с адреса &H9000
DEFW START,KONEC+END-NACH,START
ORG 09000H
CLS EQU 00C3H ; Очистка экрана
KEYOFF EQU CLS+09H ; Отключение функциональных клавиш
FORCLR EQU 0F3E9H ; Адрес цвета изображения
COLOR EQU 0062H ; Установка цвета
CONSOL EQU 00A2H ; Вывод символа на консоль.
START: LD HL,PROM ; Адрес старта реставрируемой подпрограммы
PUSH HL ; Сохранили в стеке и при встрече RET
DI ; переходим на этот адрес.
LD A,0A8H ; Организация страниц RАМ и ROM:
LD (0FFFFH),A ; 0 страница (0000H-4000H)-BASIC (BIOS)
LD A,0FCH ; 1 страница (4000H-8000H)-СЛОТB 3-2
OUT (0A8H),A ; 2 страница (8000H-C000H)-СЛОТB 3-2
LD HL,KONEC+1 ; 3 страница (C000H-FFFFH)-СЛОТB 3-2
LD DE,NACH ; Пересылка подпрограммы на начало
LD BC,END-NACH; первой страницы слота 3-2
LDIR ;
KONEC: RET ;
;
ORG 04000H ;
;
NACH: DEFM "AB" ; Идентификатор псевдо-ROM
DEFW PROM ; Адрес старта подпрограммы
DEFS 12 ; Зарезервировано стандартом
PROM: XOR A ;
CALL CLS ;
CALL KEYOFF ; Установка цвета,CLS и KEYOFF
LD HL,FORCLR ; CLS:KEYOFF:COLOR 15,9,9
LD (HL),0FH ;
INC HL ;
LD (HL),09H ;
INC HL ;
LD (HL),09H ;
CALL COLOR ;
CALL INLINE ; Печать строки на мониторе
; ... Здесь может размещаться Ваша программа.
; ... Она будет работать даже при отключении
LABEL: JP LABEL ; компьютера с помощью кнопки "RESET"
INLINE: LD HL,STROKA ; Подпрограмма вывода символов на консоль
LD A,(HL) ;
LD C,A ;
OR A ;
RET Z ;
LD A,C ;
PUSH HL ;
CALL CONSOL ;
POP HL ;
INC HL ;
JR INLINE+3 ;
STROKA: DEFM "ВЫКЛЮЧИ КОМПЬЮТЕР НА МИНУТУ."
NOP
END: NOP
//Внимание// !
- Логическая страница с номером 3 ни при каких условиях не должна подвергаться изменениям, так как в ней расположены подпрограммы–ловушки и область системных переменных. Нарушение этого условия приведет к отказу системы от дальнейшего выполнения программы и ее сбросу.
- Если для физической страницы Вы используете начальный адрес 8000h, то прежде чем подключать ее к адресному пространству, позаботьтесь о перемещении программы на [[msx:basic:|]] и стека в "безопасное" место, каковым является логическая страница с номером 3. Для этого выполните программу:
10 POKE &HF676,1:POKE &HF677,&HC0:POKE &HC000,0:NEW
Существует еще один способ подключения физической страницы памяти к адресному пространству. Для этого воспользуйтесь подпрограммой BIOS с именем ''ENASLT'', расположенной в слоте 0 по адресу 0024h.
Обращение к ней выглядит следующим образом:
LD A, Указатель слота
LD HL,Начальный адрес (0000h,4000h или 8000h)
CALL ENASLT
RET
В качестве примера приведем программу подключения физической страницы из некоторого слота к логической странице 2 адресного пространства.
{{anchor:e1082-03}} __//Пример 3//__. \\ {{.examples:1082-03.bas|}} \\ [[+tab|wmsxbpge>1082-03.bas]]
10 DATA 3E,00 :'LD A, Указатель слота
20 DATA 21,00,80 :'LD HL,8000h ;Начальный адрес
30 DATA CD,24,00 :'CALL ENASLT
40 DATA C9 :'RET
50 CLEAR 200,&HF300:DEFUSR=&HF300
60 FOR T=0 TO 8:READ Z$:POKE &HF300+T,VAL("&h"+Z$):NEXT
70 INPUT"Номер первичного слота";N1
80 INPUT"Номер вторичного слота";N2
90 POKE &HF301,&H80+N2*4+N1 '◀── Указатель слота
120 A=USR(A)
Кстати, подобного эффекта можно достичь путем воздействия на ячейку памяти FFFFh в слоте 3-2:
* ''POKE &HFFFF,&H80'' — активизирован слот 3-0 (для учительского компьютера);
* ''POKE &HFFFF,&HA0'' — активизирован слот 3-2 (по умолчанию);
* ''POKE &HFFFF,&HB0'' — активизирован слот 3-3.
Итак, прежде чем работать с памятью, ее необходимо явно распределить в адресном пространстве компьютера !
Существует, однако, другой способ работы со слотами,заключающийся в использовании подпрограмм BIOS, расположенных в слоте 0. В этом случае проблема распределения памяти снимается с пользователя и целиком возлагается на систему.
Опишем работу с некоторыми из этих подпрограмм.
//Запись// числа в RAM любого слота осуществляется путем обращения к подпрограмме с именем ''WRSLT'' , расположенной по адресу 0014h.
{{anchor:e1082-04}} __//Пример 4//__. \\ {{.examples:1082-04.bas|}} \\ [[+tab|wmsxbpge>1082-04.bas]]
10 DATA 3E,00 :'F300 LD A, Указатель слота
20 DATA 21,00,00 :'F302 LD HL,Адрес ячейки
30 DATA 1E,00 :'F305 LD E, Число
40 DATA CD,14,00 :'F307 CALL WRSLT
50 DATA C9 :'F30A RET
60 CLEAR 200,&HF300:DEFUSR=&HF300
70 FOR T=0 TO 10:READ Z$:POKE &HF300+T,VAL("&h"+Z$):NEXT
80 INPUT"Номер первичного слота";N1
90 INPUT"Номер вторичного слота";N2
100 POKE &HF301,&H80+N2*4+N1 '◀── Указатель слота
110 INPUT"Адрес ячейки";AD%
120 POKE &HF303,PEEK(VARPTR(AD%)):POKE &HF304,PEEK(VARPTR(AD%)+1)
130 INPUT"Какое число запишете";Q%:POKE &HF306,Q%:A=USR(A)
//Чтение// числа из любой физической страницы, имеющей некоторый начальный адрес, осуществляется путем обращения к подпрограмме с именем ''RDSLT'', расположенной по адресу 000Ch.
{{anchor:e1082-05}} __//Пример 5//__. \\ {{.examples:1082-05.bas|}} \\ [[+tab|wmsxbpge>1082-05.bas]]
10 DATA 3E,00 :'F300 LD A,Указатель слота
20 DATA 21,00,00 :'F302 LD HL,Адрес читаемой ячейки
30 DATA CD,0C,00 :'F305 CALL RDSLT
40 DATA 32,10,F3 :'F308 ;Запись результата в доступную ячейку
;памяти (в нашем случае &HF310)
50 DATA C9 :'F30B RET
60 CLEAR 200,&HF300:DEFUSR=&HF300
70 FOR T=0 TO 11:READ Z$:POKE &HF300+T,VAL("&h"+Z$):NEXT
80 INPUT"Номер первичного слота";N1
90 INPUT"Номер вторичного слота";N2
100 POKE &HF301,&H80+N2*4+N1 '◀── Указатель слота
110 INPUT"Адрес ячейки";AD%
120 POKE &HF303,PEEK(VARPTR(AD%)):POKE &HF304,PEEK(VARPTR(AD%)+1)
130 A=USR(A):PRINT"Вот Ваше число:";PEEK(&HF310)
Посмотрев на схему расположения памяти в слотах, Вы можете заметить, что некоторые физические страницы памяти слота 3-2 в компьютерах серии MSX-2 не имеют //фиксированных// адресов. Пронумеруем все физические страницы слота 3-2 от 0 до 7 сверху вниз (в порядке следования на рисунке).
Любую из этих физических страниц можно подключить к любой логической странице адресного пространства.
При этом не рекомендуется изменять содержимое логической страницы с номером 3, так как это приводит к перезагрузке системы!
Подключить физические страницы слота 3-2 можно путем воздействия на порты ввода–вывода с адресами 252, 253, 254 и 255. При этом, если Вы используете порт с адресом 252+N, то процессор подключит распределяемую физическую страницу к логической странице с номером N.
Для подключения физической страницы к логической выполните команду
OUT 252+N1,&hF8+N2
,
где:
* ''N1'' — номер логической страницы,
* ''N2'' — номер физической страницы,
* ''&hF8'' — число, полученное при вычитании 256 - M ,
* ''M '' — число физических страниц в слоте 3-2.
Таким образом Вы получите доступ к //любой// ячейке памяти в слоте 3-2 (внимательно изучите //текст// на схеме расположения памяти в слотах)!
В заключение отметим, что для доступа к физическим страницам памяти, подключенным к адресному пространству,применяются оператор ''POKE'' и функция ''PEEK''. Кроме того, для работы с памятью компьютера серии MSX-2, подключенного к локальной сети, применяются операторы ''CALL POKE'' и ''CALL PEEK''.
Если адрес принадлежит отрезку [&h4000,&h7FFF], то операторы ''CALL POKE'' и ''CALL PEEK'' "работают" с памятью, которая находится в слоте 3-3 и отвечает за работу локальной сети. Во всех остальных случаях действие оператора ''CALL POKE'' совпадает с действием оператора ''POKE'', а действие оператора ''CALL PEEK'' совпадает с действием функции ''PEEK''.
\\
Следует стремиться увидеть в каждой вещи то, чего
\\ еще никто не видел, и над чем еще ни кто не думал.
—//Г.Лихтенберг//
\\
\\ То, что я понял,прекрасно, из этого я заключаю,
\\ что остальное, чего я не понял, тоже прекрасно.
—//Сократ//
{{anchor:n1083}}
===== 1.8.3. Создание новых операторов =====
В языке [[msx:basic:|]] допускается использование так называемых "встроенных" подпрограмм. Каждая из этих подпрограмм имеет свое имя. Для обращения к встроенным подпрограммам используется оператор:
CALL Имя подпрограммы [(Список параметров)]
,
где:
* ''CALL''("call"-"звать") — служебное слово, которое можно заменять знаком "_";
* список параметров — необязательный список,содержащий одно или несколько выражений, отделенных друг от друга запятыми.
Рассмотрим несколько встроенных подпрограмм, имеющих отношение к локальной вычислительной сети компьютеров MSX-1.
- Каждый из компьютеров локальной сети имеет номер, который можно узнать, выполнив в непосредственном режиме команду
CALL WHO
,
где ''WHO'' ("кто") — служебное слово.
- Скорость передачи информации по сети по умолчанию равна 2400 бод, однако ее можно регулировать оператором
{{anchor:call_comini}}
CALL COMINI
.
Максимальная скорость передачи при этом равна 4800 бит/с.
В общем случае оператор ''CALL COMINI'' производит инициализацию сети.
Информацию об аргументах подпрограммы ''COMINI'' можно получить командой
{{anchor:call_comhelp}}
CALL COMHELP
.
- {{anchor:call_com}} Имеется возможность обработки прерываний после поступления данных из локальной сети. Оператор перехода к подпрограмме обработки прерываний выглядит следующим образом:
CALL COM (["0:"],GOSUB номер строки)
.
Чтобы сделать эту обработку возможной, примените следующие операторы:
* {{anchor:call_comon}} ''CALL COMON'' — разрешает обработку прерываний;
* {{anchor:call_comoff}} ''CALL COMOFF'' — запрещает обработку прерываний;
* {{anchor:call_comstop}} ''CALL COMSTOP'' — временно приостанавливает обработку.
Важно отметить, что пользователь может создать //новый// , собственный оператор ''CALL'' .
В рабочей области RAM, начиная с адреса FCC9h, находится участок памяти, отвечающий за каждую //логическую// страницу памяти, находящуюся в некотором слоте, причем адрес байта памяти, непосредственно отвечающего за логическую страницу памяти, вычисляется по формуле:
FCC9h + 16·SLTNUM + 4·EXPSLT + PG
,
где:
* ''SLTNUM'' — номер базисного слота;
* ''EXPSLT'' — номер слота расширения (вторичного слота);
* ''PG'' — номер логической страницы памяти.
По этому адресу содержится информация о том, работу каких устройств могут поддерживать подпрограммы, заложенные в эту логическую страницу изготовителем аппаратуры или ее пользователем.
Эта информация кодируется следующим образом:
┌───┬───┬───┬───┬───┬───┬───┬───┐
│ ∗ │ ∗ │ ∗ │ ∗ │ ∗ │ ∗ │ ∗ │ ∗ │◀─ Младший бит
└───┴─▲─┴─▲─┴───┴───┴───┴───┴───┘
│ ├─ Если бит равен 1, то разрешена обработка операторов CALL
│ └─ Если бит равен 0, то запрещена обработка операторов CALL
├───── Если бит равен 1, то разрешена работа с нестандартными
│ файловыми устройствами (например, MEM: или COM:)
└───── Если бит равен 0, то запрещена работа с нестандартными
файловыми устройствами.
Приведем теперь пример программы, позволяющей "изготовить" //новые// операторы ''CALL''. После запуска этой программы с адреса 9000h становится возможным использование операторов
* ''CALL FATPRINT'' ("утолщение" символов),
* ''CALL SCRON'' (включение экрана дисплея),
* ''CALL SCROFF'' (выключение экрана дисплея).
Заметим, что число возможных подпрограмм для обработки нестандартных операторов ограничивается только размерами логической страницы!
\\
Читающий, если не усвоишь — перечти,
\\ переждав.
—//Е.Рерих. Живая вода//
Итак, смотрите:
\\ {{anchor:e1083-01}} __//Пример//__. \\ {{.examples:1083-01.asm|}}
;Выбор слота 3-2 для всех логических страниц памяти
9000: 3E AA LD A,AAh ;Выберем 2-й слот в качестве вто-
9002: 32 FF FF LD (FFFFh),A ; ричного для всех страниц
;
9005: F3 DI ;Запретим прерывания
9006: 3E FF LD A,FFh ;Выберем 3-й слот в качестве пер-
9008: D3 A8 OUT (A8h),A ; вичного для всех страниц
;Заполнение псевдо-ROM
900A: 21 20 90 LD HL,9020h ; Откуда берутся данные
900D: 11 00 40 LD DE,4000h ; Куда помещаются
9010: 01 00 01 LD BC,0100h ; Длина копируемого блока
9013: ED B0 LDIR ; Групповая пересылка
;Восстановление конфигурации BASIC
9015: 3E F0 LD A,F0h ;
9017: D3 A8 OUT (A8h),A ;
9019: FB EI ;Разрешим прерывания
;Заполнение буфера SLTATR
;(64 байта, начиная с адреса FCC9h)
901A: 3E 20 LD A,00100000b ; 5-й бит - разрешена обработка
; операторов расширения
; 6-й бит - запрещена обработка
; нестандартных устройств I/O
901C: 32 02 FD LD (FD02h),A ;Псевдо-ROM в слоте 3-2, страница 1
901F: C9 RET ;Возврат управления в BASIC
; Далее идет блок содержимого псевдо-ROM
;Заголовок псевдо-ROM ("карта ROM")
9020: 41 ; Код символа A
9021: 42 ; Код символа B
9022: 00 00 ; Адрес подпрограммы инициализации ROM
9024: 11 40 ; Адрес начала обработки операторов расширения
9026: 00 00 ; Адрес начала обработки нестандартных устройств I/O
9028: 00 00 ; Адрес текста на BASIC в ROM
902A-9030: 00 ; 7 байтов, зарезервированных стандартом
;Блок подпрограмм обработки операторов расширения
9031: 37 SCF ;Установим флаг C (необходим для
;генерации сообщения об ошибке)
9032: E5 PUSH HL ;
9033: 06 03 LD B,03 ;Будут обработаны только три первых
;оператора расширения в псевдо-ROM
9035: 21 51 40 LD HL,4051h ;Адрес блока идентификаторов
; операторов расширения
9038: E5 PUSH HL ;
9039: CD 38 40 CALL 4038h ;Переход на блок сравнения 2 имен
903C: E1 POP HL ;
903D: 30 09 JR NC,9048h ;Если имя не найдено, то переход на
; блок поиска адресов
903F: 11 10 00 LD DE,0010h ;Указатель на
9042: 19 ADD HL,DE ; следующее имя
9043: 10 F3 DJNZ 9038h ;Имена кончились?
9045: E1 POP HL ;Если имя не найдено, то возврат
9046: 37 SCF ; управления в BASIC с сообщением
9047: C9 RET ; "Syntax error"
;Блок поиска в таблице адресов
9048: 3E 03 LD A,03 ;Число подпрограмм в псевдо-ROM
904A: 90 SUB B ;
904B: 21 4B 40 LD HL,404Bh ;Начало таблицы адресов подпрограмм
944E: 87 ADD A,A ;Вычислим смещение
904F: 16 00 LD D,00 ;Вычислим положение
9051: 5F LD E,A ; адреса программы
9052: 19 ADD HL,DE ; в таблице
9053: 5E LD E,(HL) ;Помещаем адрес
9054: 23 INC HL ; перехода из
9055: 56 LD D,(HL) ; таблицы в регистр DE
9056: EB EX DE,HL ;Адрес -из регистра DE в регистр HL
9057: E9 JP (HL) ;Переход на выбранную подпрограмму
; расширения
;Сравнение вводимого имени оператора расширения
;с именем оператора в псевдо-ROM
9058: 11 89 FD LD DE,FD89h ;Начало области, в которой хранится
; имя набираемого оператора
905B: 1A LD A,(DE) ;
905C: A7 AND A ;Это 0?
905D: 28 07 JR Z,9066h ;Если да, то произошел конец набора
; оператора с клавиатуры
905F: BE CP (HL) ;Указатель на имя в псевдо-ROM
9060: 37 SCF ;Если имена различны, то выход в
9061: C0 RET NZ ; BASIC с сообщением
; "Syntax error"
9062: 23 INC HL ;
9063: 13 INC DE ;
9064: 18 F5 JR 905Bh ;Имя кончилось?
9066: BE CP (HL) ;Имя в псевдо-ROM тoжe кончилось?
9067: 37 SCF ;Если оно длиннее, чем набранное
9068: C0 RET NZ ; имя, то выход в BASIC с сообщени-
; ем "Syntax error"
9069: 3F CCF ;Имена совпали, возврат без сообще-
906A: C9 RET ; ния об ошибке
;Таблица адресов операторов расширения
906B: 81 40 ;Адрес подпрограммы CALL FATPRINT
906D: 9C 40 ;Адрес подпрограммы CALL SCRON
906F: A1 40 ;Адрес подпрограммы CALL SCROFF
;Блок имен операторов (по 16 символов на имя)
9071: 46 ;F
9072: 41 ;A
9073: 54 ;T
9074: 50 ;P
9075: 52 ;R
9076: 49 ;I
9077: 4E ;N
9078: 54 ;T
9079-9080: 00
9081: 53 ;S
9082: 43 ;C
9083: 52 ;R
9084: 4F ;O
9085: 4E ;N
9086-9090: 00
9091: 53 ;S
9092: 43 ;C
9093: 52 ;R
9094: 4F ;O
9095: 46 ;F
9096: 46 ;F
9097-90A0: 00
;Вот они! Наши операторы CALL !
90A1: CD 6F 00 CALL 006Fh ;Установка режима SCREEN 1
90A4: 21 00 01 LD HL,0100h ;
90A7: 01 57 07 LD BC,0757h ;
90AA: 07 RLCA ;
90AB: CD 4A 00 CALL 004Ah ;Чтение из видеопамяти
90AE: 57 LD D,A ;
90AF: 1F RRA ;Утолщение символа
90B0: B2 OR D ;
90B1: CD 4D 00 CALL 004Dh ;Запись в видеопамять
90B4: 0B DEC BC ;
90B5: 23 INC HL ;
90B6: 78 LD A,B ;
90B7: B1 OR C ;
90B8: 20 F1 JR NZ,90ABh ;
90BA: E1 POP HL ;
90BB: C9 RET ;Возврат в BASIC
90BC: CD 44 00 CALL 0044h ;Включение экрана дисплея
90BF: E1 POP HL ;
90C0: C9 RET ;
90C1: CD 41 00 CALL 0041h ;Выключение экрана дисплея
90C4: E1 POP HL ;
90C5: C9 RET ;
----
[<>]
{{tag>MSX msxbdpl}}