64ce6339eb
- docs/new/ — сводные справочники (архитектура, BIOS, DSS, память, графика, акселератор, IRQ, порты, ввод, звук, известные баги); - docs/Original/ — первоисточники, из которых они собраны (BIOS, Estex DSS, мануалы, описание акселератора), + Форум.doc/.docx в reference; - libbgi/common/gfx_scroll_h.c — обход бага скролла при ширине >256 (правка автора: шаг банды 255 и продвижение указателей на cw; старый вариант с 256 оставлен закомментированным с TODO); - удалён applications/PoP/roomtest/hang_variants.png — рабочая раскладка из разбора позы виса, в репозитории ей не место. Большие архивы (docs/extra ~568 МБ, docs/sources с вложенными git-репо ~68 МБ) в коммит НЕ включены — см. обсуждение. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1170 lines
53 KiB
Markdown
1170 lines
53 KiB
Markdown
# Программирование Спринтера
|
||
|
||
## Оглавление:
|
||
|
||
- Экран и палитра
|
||
- Шрифты
|
||
- Память
|
||
- Файлы
|
||
- Звук
|
||
- ISA-8 слоты
|
||
- Summary
|
||
- More information
|
||
- Акселератор компьютера Sprinter
|
||
- Прерывания
|
||
- IDE контроллер
|
||
- FDD контроллер
|
||
- Клавиатура
|
||
- Коды ошибок DSS
|
||
|
||
### Экран и палитра
|
||
|
||
Функции для работы с экраном:
|
||
|
||
Сейчас DOS поддерживает четыре режима экрана.
|
||
|
||
Два текстовых:
|
||
|
||
40x32 символов c 16 цветами (режим 02h);
|
||
80x32 символов c 16 цветами (режим 03h);
|
||
|
||
и два графических:
|
||
|
||
320x256 точек с 256 цветами (режим 81h);
|
||
640x256 точек с 16 цветами (режим 82h);
|
||
|
||
Основным режимом является текстовый режим 80x32 (03h), если
|
||
ваша программа работает в другом режиме, то вам следует перед
|
||
переключением режима получить номер текущего режима функцией
|
||
51h GETVMOD и сохранить его, а перед завершением программы
|
||
восстановить его.
|
||
|
||
Например:
|
||
|
||
```asm
|
||
LD C,51h ;получить режим экрана
|
||
RST 10h
|
||
LD C,A ;поместить номер режима экрана в регистр C
|
||
PUSH BC ;и сохранить на стеке (B - страница, C - режим)
|
||
...
|
||
... ;ваша программа
|
||
...
|
||
POP BC ;взять со стека режим экрана
|
||
LD A,C ;поместить номер режима экрана в регистр A
|
||
LD C,50h ;установить режим экрана
|
||
RST 10h
|
||
LD C,41h ;завершить программу.
|
||
RST 10h
|
||
```
|
||
|
||
DSS имеет функции вывода на текстовый экран символов и символьных
|
||
строк. Для графических режимов требуются собственные процедуры
|
||
вывода на экран. Например, при завершении программы вы можете
|
||
выдать строку на текстовый экран:
|
||
|
||
```asm
|
||
LD HL,STRING ;указатель на строку символов
|
||
LD C,5Ch ;вывод строки символов
|
||
RST 10h
|
||
|
||
STRING DB "Thank you for using my program..." ;текстовая строка
|
||
DB 13,10 ;символы возврата каретки и перевода строки
|
||
DB 0 ;символ конца строки
|
||
```
|
||
|
||
Для вывода на графический экран, вам необходимо подключить
|
||
видео память в одно из трех окон памяти 04000h-07FFFh,
|
||
08000h-0BFFFh, 0C000h-0FFFFh. Это осуществляется выводом
|
||
значения 50h в соответствующий порт 0A2h, 0C2h или 0E2h в
|
||
зависимости от окна памяти. При подключении обратите
|
||
внимание на то, чтобы стек вашей программы не попадал в
|
||
это адресное пространство.
|
||
|
||
Например, если вам нужно поставить точку на экране, то
|
||
подпрограмма для режима 81h будет выглядеть так:
|
||
|
||
```asm
|
||
; HL - горизонтальная координата
|
||
; DE - вертикальная координата
|
||
|
||
IN A,(0E2h) ;считать из порта номер страницы подключенной в
|
||
;третье окно памяти
|
||
LD C,A ;запомнить в регистре C
|
||
LD A,50h ;страница видео памяти
|
||
OUT (0E2h),A ;подключение видео памяти
|
||
LD A,E ;поместить вертикальную координату в регистр A.
|
||
OUT (89h),A ;выдать в порт
|
||
LD DE,0C000h ;адрес начала третьего окна памяти
|
||
ADD HL,DE ;получить адрес точки (адрес начала окна +
|
||
;горизонтальная координата)
|
||
LD A,255 ;цвет выводимой точки (от 0 до 255)
|
||
LD (HL),A ;вывод точки на экран
|
||
LD A,C ;вспомнить номер страницы памяти
|
||
OUT (0E2h) ;подключить страницу памяти вместо страницы видео
|
||
;памяти
|
||
```
|
||
|
||
Перед выводом точек следует установить необходимые цвета в
|
||
палитре. Различные режимы вывода на экран задаются номером
|
||
видео страницы от 50h до 5Fh. Подробнее о режимах вывода вы
|
||
можете прочитать в описании архитектуры компьютера.
|
||
|
||
**50h (80) SETVMOD (Выбор режима экрана)**
|
||
|
||
входные данные:
|
||
A - режим экрана
|
||
02h - текстовый 40x32x16 цветов
|
||
03h - текстовый 80x32x16 цветов
|
||
81h - графический 320x256x256 цветов
|
||
82h - графический 640x256x16 цветов
|
||
B - страница экрана 0/1
|
||
C - 50h
|
||
выходные данные:
|
||
A - код ошибки, если CF=1
|
||
|
||
Функция устанавливает режим экрана. Седьмой бит режима экрана
|
||
установлен для графических режимов и сброшен для текстовых.
|
||
Существуют два текстовых режима и два графических.
|
||
|
||
**51h (81) GETVMOD (Получить текущий режим экрана)**
|
||
|
||
входные данные:
|
||
C - 51h
|
||
выходные данные:
|
||
A - текущий режим экрана
|
||
B - страница экрана 0/1
|
||
|
||
Функция возвращает текущий режим экрана и номер страницы экрана.
|
||
|
||
|
||
Q:
|
||
Здравствуйте. А как с палитрами??? Как загрузить произвольную
|
||
палитру (отдельный цвет). Желательно с исходником.
|
||
Почему системная палитра выглядит по разному в эмуляторе и реальном
|
||
Спринтере.
|
||
|
||
A:
|
||
Пример из исходников Антона Енина (
|
||
|
||
```asm
|
||
;[]=======================================================================[]
|
||
; palette from Flex Navigator
|
||
CustomPalette:
|
||
db 0x00, 0x00, 0x00, 0x00 ; Black 00
|
||
db 0x00, 0x00, 0xFF, 0x00 ; B.Red 01
|
||
db 0x00, 0x80, 0x00, 0x00 ; Green 02
|
||
db 0x00, 0xFF, 0xFF, 0x00 ; B.Yellow 03
|
||
db 0x80, 0x00, 0x00, 0x00 ; Blue 04
|
||
db 0xFF, 0xFF, 0x00, 0x00 ; Invert bg 05
|
||
db 0x80, 0x00, 0x00, 0x00 ; Invert fg 06
|
||
db 0x80, 0x80, 0x80, 0x00 ; BlackGray 07
|
||
db 0xC0, 0xC0, 0xC0, 0x00 ; HighGray 08
|
||
db 0x80, 0x00, 0x00, 0x00 ; Panel 09
|
||
db 0xFF, 0xFF, 0x00, 0x00 ; Files 0A
|
||
db 0x00, 0xFF, 0xFF, 0x00 ; Select Files 0B
|
||
db 0x00, 0xFF, 0xFF, 0x00 ; InvSel Files 0C
|
||
db 0xC0, 0xC0, 0xC0, 0x00 ; Reserved 0D
|
||
db 0xFF, 0xFF, 0xFF, 0x00 ; White 0E
|
||
db 0xFF, 0xFF, 0xFF, 0x00 ; White 0F
|
||
|
||
;[]=======================================================================[]
|
||
;[]=======================================================================[]
|
||
; set requist video mode 640x256x16
|
||
SetVideoMode:
|
||
|
||
ld c, 0x51 ; save previos vmode
|
||
rst 0x10
|
||
ld (vmode + 1), a
|
||
ld a, b
|
||
ld (vscrn + 1), a
|
||
sub a
|
||
call CrearVideoRam
|
||
ld bc, 0x0050 ; set 640x256x16
|
||
ld a, 0x82
|
||
rst 0x10
|
||
ld hl, CustomPalette
|
||
ld de, 0x1000
|
||
ld bc, 0xFFA4
|
||
sub a
|
||
rst 0x08 ; load palette
|
||
ret
|
||
|
||
;[]=======================================================================[]
|
||
```
|
||
|
||
```asm
|
||
;Установить 5-й цвет \"средне-зеленым\"
|
||
LD HL,COLOUR
|
||
LD DE,#0105
|
||
LD BC,#FFA4
|
||
XOR A
|
||
RST #08
|
||
|
||
; B G R
|
||
COLOUR DB #00,#80,#00,#00
|
||
|
||
;Изменить все 256 цветов в палитре
|
||
LD HL,COLOURS
|
||
LD DE,#0000
|
||
LD BC,#FFA4
|
||
XOR A
|
||
RST #08
|
||
|
||
;Параметры цвета
|
||
; B G R
|
||
COLOUR DB #00,#80,#00,#00
|
||
|
||
;Палитра
|
||
COLOURS DB #00,#00,#00,#00 ;Colour 0
|
||
DB #00,#00,#80,#00 ;Colour 1
|
||
DB #00,#80,#00,#00 ;Colour 2
|
||
DB #00,#80,#80,#00 ;Colour 3
|
||
...
|
||
DB #FF,#FF,#FF,#00 ;Colour 255
|
||
```
|
||
|
||
Как я понял, сейчас есть проблема с выводом на экран.
|
||
Попробую расписать схему видео-вывода на словах.
|
||
|
||
Режим адресации. Задается номером страницы.
|
||
Если номер 5Xh - адресация графическая.
|
||
Если номер не 5Xh - адресация спектрумовская, и она включена все время,
|
||
даже если в соседней странице включился номер 5Xh.
|
||
|
||
Спектрумовская адресация, это доступ к видеопамяти на запись в адресах
|
||
4000h..5FFFh или в 4000h - 7FFFh, в зависимости от состояния порта
|
||
PORT_Y (89h).
|
||
|
||
Бит 6 = 1 - отключает вывод в спектрумовское окно памяти.
|
||
Бит 7 = 1 - расширяет спектрумовское окно с 8Kb до 16Kb
|
||
|
||
Бит 4..0 - пределяет 8kb банк спектрумовского режима.
|
||
|
||
Эти банки располагаются "вертикально", т.е. такой банк соответствует
|
||
32-м последовательным точкам на графической линии и 256-ти линиям.
|
||
|
||
Сначала я чаще всего использовал окно 4000h..7FFFh для работы с
|
||
графикой, поэтому получилось так, что графическая адресация перекрывала
|
||
спектрумовскую при включении в порт A2h значения 5Xh, а выше 8000h
|
||
использовалось программой, потом, когда стали использовать для вывода на
|
||
экран страницу 0C000h, получилось так, что в странице 4000h оставалась
|
||
открыта видеопамять со спектрумовской адресацией, а порт 89h
|
||
используется и там и там, но с разным назначением.
|
||
|
||
Т.е. после открытия страницы 0C000h для графики остается открытой и
|
||
спектрумовский способ адресации видеопамяти в странице 4000h..7FFFh.
|
||
P.S. Надеюсь, что не запутал все окончательно...
|
||
|
||
### Шрифты
|
||
|
||
#### *Несколько наборов шрифтов одновременно*
|
||
|
||
Вот ответ, полученный от Ivan Mak.
|
||
|
||
=== Cut ===
|
||
|
||
Через Bios:
|
||
|
||
IX - 32-хбайтовый описатель окна
|
||
|
||
(искать в описании, здесь только только самое важное)
|
||
|
||
(IX+4) - режим знакоместа
|
||
bit4=1 - text_mode
|
||
bit5=0 - 16, bit5=1 - 8 точек в знакоместе (80/40 символов)
|
||
bit7..6,3..0 - номер знакогенератора
|
||
|
||
исключение: bit7..6=B"11" - бордер
|
||
|
||
...
|
||
|
||
Он же (IX+4) - номер используемого знакогенератора в
|
||
этом окне, он же регистр B в функциях B4,B5
|
||
Функция B0 открытие окна использует описатель, в котором указан
|
||
знакогенератор, открытый для всех символов данного окна. Он может
|
||
быть перебит прямой записью в видео-память или фунцией B5,
|
||
которая пишет символ со знакогенератором. При использовании
|
||
функции B0 четвертый бит регистра E определяет, какая страница
|
||
режима будет использоваться. Для работы с двумя страницами надо
|
||
открывать окно два раза со значениями 0 и 1 в 4-м бите рег.E
|
||
|
||
---
|
||
|
||
**0B4h (180) WIN_GET_SYM Взять символ с экрана**
|
||
|
||
Значение регистров на входе:
|
||
C=0B4h
|
||
A - идентификатор окна (д.б. 0)
|
||
DE - положение символа в окне:
|
||
D - вертикаль, E - горизонталь
|
||
Значение регистров на выходе:
|
||
NC - нормальное завершение
|
||
L - символ,
|
||
H - атрибут,
|
||
B - знакогенератор
|
||
CF - ошибка неверный идентификатор окна
|
||
|
||
**0B5h (181) WIN_PUT_SYM Положить символ на экран**
|
||
|
||
Значение регистров на входе:
|
||
C=0B5h
|
||
A - идентификатор окна
|
||
DE - положение символа в окне:
|
||
D - вертикаль, E - горизонталь
|
||
L - символ,
|
||
H - атрибут символа
|
||
B - знакогенератор
|
||
Значение регистров на выходе:
|
||
NC - нормальное завершение
|
||
CF - ошибка неверный идентификатор окна
|
||
|
||
**0B6h (182) WIN_SET_ZG Установка знакогенератора**
|
||
|
||
Значение регистров на входе:
|
||
C=0B6h
|
||
A - системный номер знакогенератора
|
||
DE - указатель на 2Kb данных знакогенератора
|
||
Значение регистров на выходе:
|
||
NC - нормальное завершение
|
||
CF - ошибка (старая версия, нет функции)
|
||
|
||
**0B8h (184) WIN_GET_ZG Получение знакогенератора**
|
||
|
||
Значение регистров на входе:
|
||
C=0B8h
|
||
DE - адрес, куда будет загружено 2kb знакогенератора
|
||
Значение регистров на выходе:
|
||
NC - нормальное завершение
|
||
CF - ошибка (старая версия, нет функции)
|
||
|
||
Функция копирует имеющийся знакогенератор из ПЗУ
|
||
|
||
---
|
||
|
||
Для работы напрямую, окна должны быть открыты биосом,
|
||
знакогенераторы установлены. Вывод символов осуществляется
|
||
в графическом режиме адресации, через страницу 50h. В порт
|
||
89h записывается номер символа, адрес в линии определяет
|
||
строку. В этот адрес записывается четыре байта, определяющих
|
||
символ, атрибут и знакогенератор.
|
||
|
||
Bytes:
|
||
byte0 - знакогенератор/режим то же, что в (IX+4)
|
||
byte1 - символ
|
||
byte2 - атрибут
|
||
byte3 - reserved (заполнить нулями)
|
||
|
||
Port_Y - номер линии засылаемый в порт 89h
|
||
линия 1+S S=0..79 - номер символа в строке для экрана 0
|
||
линия 128+S S=0..79 - номер символа в строке для экрана 1
|
||
(S=0 - выводит символ слева)
|
||
|
||
Adress: в линии 768+N*4 - N - номер строки экрана 0..31.
|
||
Адрес одинаков для обоих экранов.
|
||
(N=0 выводит символ сверху)
|
||
|
||
В режиме 40 символов, номера строк через один: 1,3,5\...79
|
||
|
||
Экраны переключаются нулевым битом порта 0C9h
|
||
|
||
---
|
||
|
||
Текстовый экран устроен на удивление просто: в области описания
|
||
экрана в текстовом режиме на один символ отводится 4 байта (номер
|
||
знакогенератора, код символа, атрибут и один неиспользуемый байт),
|
||
причем надо обратить внимание на то, что в этом режиме экран "повернут
|
||
на бок". Что-бы вывести символ на экран, надо в Port_Y (0x89) записать
|
||
128+номер символа в строке (от 0 до 79), затем к адресу начала экранной
|
||
страницы прибавить 768 (для первого экрана), после чего мы получим адрес
|
||
байта, в котором хранится номер знакогенератора для вывода символа
|
||
(поменяйте его, если это необходимо), увеличиваем адрес на один и туда
|
||
записываем уже код самого символа, а в следующий байт - атрибут этого
|
||
символа. Что-бы перейти на следующую строку текстового экрана, надо
|
||
прибавить к адресу начала экранной страницы число 4*номер строки.
|
||
Используя акселератор (команду копирования вертикальной линии) можно
|
||
очень быстро выводить текст строки на экран.
|
||
|
||
Остается только добавить что прямой доступ к области описания экрана не
|
||
рекомендован разработчиками, т.к. есть веротяность потери совместимости
|
||
со следующими моделями, где символы могут описываться подругому. Но если
|
||
вам необходима большая скорость вывода на экран в текстовом режиме и вы
|
||
готовы после выпуска программы вносить в неё изменения для обеспечения
|
||
совместимости со следующими моделями, либо выложить исходники программы,
|
||
что-бы желающие могли их исправить при необходимости, то, мне кажется
|
||
можно использовать прямой доступ.
|
||
|
||
### Память
|
||
|
||
В конфигурации спринтер по #0000...#3FFF, при работе ДСС находится
|
||
сама ДСС с её Резетами, то есть чтобы использывать когда сюда
|
||
подставленна страница пользователя резеты не доступны!.
|
||
|
||
Это так в нижних 16K находится DSS / BIOS в остальных 48К
|
||
приложение, но с определенными особенностями. Стек не должен быть
|
||
выше #BFFF при вызове DSS и ниже #8000 при вызове некоторых
|
||
функций BIOS.
|
||
|
||
В следующих версиях DSS планируется снятие ряда ограничений на стек
|
||
и расположения данных при вызове ее функций.
|
||
|
||
Q: Теперь адресса #4000..#7FFF, #8000..#BFFF, #C000..#FFFF, когда ДСС
|
||
передаёт управление эти программам, какие банки там нахадятся по
|
||
умолчанию?
|
||
|
||
A: В зависимости от адреса загрузки и размера приложения DSS выделяет
|
||
необходимое число страниц памяти. Так при размере меньше 16К будет
|
||
выделена одна страница, при размере больше 16К - две, и т.д. В окна с
|
||
"неиспользуемым" адресном пространством будет подключатся
|
||
специальная страница #FF. Если приложению требуется памяти больше чем
|
||
зарезервировано в exe-файле, оно должно выделить себе дополнительный
|
||
блок памяти самостоятельно.
|
||
|
||
|
||
Q: Теперь память можно челкать по портам #7FFD,1FFD или нет?
|
||
И если да, то как типа in #&7FFD,(номер страницы).
|
||
|
||
Напрямую память можно счелкать через 4 порта памяти:
|
||
|
||
#82 - #0000-#3FFFF
|
||
#A2 - #4000-#7FFFF
|
||
#C2 - #8000-#BFFFF
|
||
#E2 - #C000-#FFFFF
|
||
|
||
Записывая физический номер страницы в порт. Список номеров
|
||
физических страниц для выделенного блока памяти можно получить
|
||
через BIOS.
|
||
|
||
Q: Также хотеловсь бы увидет пример по использывани ф-ии
|
||
38х Setwin!
|
||
|
||
A: SETWIN работает с логичискими страницами.
|
||
|
||
**38h (56) SETWIN (Подключение страницы памяти)**
|
||
|
||
входные данные:
|
||
A - идентификатор блока памяти
|
||
B - номер страницы в блоке (0,1,2\...)
|
||
H - биты 6 и 7 задают номер окна, в которое будет подключена страница
|
||
C - 38h
|
||
выходные данные:
|
||
A - номер страницы, если CF=0
|
||
A - код ошибки, если CF=1
|
||
|
||
Функция вычисляет физический номер страницы в блоке памяти и
|
||
подключает её в окно адресного пространства в зависимости от
|
||
значения регистра HL. То есть, если HL указывает на адрес в
|
||
пределах от 04000h до 07FFFh, то страница подключается в первое
|
||
окно, от 08000h до 0BFFFh - второе окно, от 0C000h до 0FFFFh -
|
||
третье.
|
||
|
||
На выходе в регистре A содержится физический номер страницы,
|
||
которая была подключена до выполнения функции.
|
||
|
||
```asm
|
||
; Выделить блок памяти 32К и подключить его страницы в #8000 и #C000 окна:
|
||
;
|
||
|
||
LD C,#3D ;GETMEM
|
||
LD B,2 ;BLOCK 32K
|
||
RST #10 ;SYSTEM CALL
|
||
JR C,ERROR ;MEMORY ALLOCATION ERROR
|
||
LD (MEMHND),A ;SAVE MEMORY HANDLE
|
||
;
|
||
LD HL,#8000 ;FRAME ADDRESS
|
||
LD C,#38 ;SETMEM
|
||
LD B,0 ;FIRST MEMORY PAGE
|
||
LD A,(MEMHND) ;MEMORY HANDLE
|
||
RST #10 ;SYSTEM CALL
|
||
JR C,ERROR ;MEMORY ALLOCATION ERROR
|
||
;
|
||
LD HL,#C000 ;FRAME ADDRESS
|
||
LD C,#38 ;SETMEM
|
||
LD B,1 ;SECOND MEMORY PAGE
|
||
LD A,(MEMHND) ;MEMORY HANDLE
|
||
RST #10 ;SYSTEM CALL
|
||
JR C,ERROR ;MEMORY ALLOCATION ERROR
|
||
;
|
||
```
|
||
|
||
|
||
Q:
|
||
Во! Пасибо большое? А еслищёлкать портами то есть возможномть что
|
||
программа будет совместима с будущей версией ПЗУ/АЛТЕРЫ/ДСС/ПЛАТЫ?
|
||
|
||
A:
|
||
Да, в любом случае будет возможность запуска программ в той
|
||
конфигурации для которой она была написана. Что-то вроде режима
|
||
совместимости. Но если для программы не критично работа напрямую
|
||
через порты, лучше пользоваться SETWIN как более универсальный.
|
||
|
||
> Так при размере меньше 16К будет выделена одна страница, при
|
||
> размере больше 16К - две, и т.д. В окна с "неиспользуемым" адресном
|
||
> пространством будет подключатся специальная страница #FF.
|
||
|
||
Q:
|
||
Какие физические номера этих страниц к приме 1,2,3,,,256!
|
||
|
||
A:
|
||
Это можно узнать через функцию BIOS, эти номера будут разными в
|
||
зависимости от того сколько памяти было выделено другим приложениям.
|
||
|
||
Q:
|
||
Денис а такой вариант выделения памяти будет работать?
|
||
|
||
```asm
|
||
START
|
||
ORG #4000
|
||
NOP
|
||
ORG #8000
|
||
NOP
|
||
ORG #C000
|
||
NOP
|
||
```
|
||
|
||
Дальше нужный орг и прога!
|
||
|
||
A:
|
||
Да, если конечно будет записан код от #4000 до конца программы, а не
|
||
от последнего ORG, как это делают некоторые ассемблеры.
|
||
Еще одно замечание, для DSS1.xx exe-файлы могут начинаться с #4100,
|
||
но после запуска можно использовать память с #4000.
|
||
|
||
|
||
Q:
|
||
В документации по спринтеру, есть такая фраза:
|
||
#82 - PAGE0 - страница ОЗУ, подключаемая вместо ПЗУ через порт #1FFD.
|
||
Что-бы это значило?
|
||
|
||
```asm
|
||
ld a, номер_подключаемой_страницы
|
||
out (#82),a
|
||
ld a, _что?_
|
||
out (#1ffd),a
|
||
```
|
||
|
||
A:
|
||
|
||
```asm
|
||
LD A,1 ;RAM #0000-#3FFF
|
||
LD BC,#1FFD
|
||
OUT (C),A
|
||
;
|
||
LD A,0 ;ROM #0000-#3FFF
|
||
LD BC,#1FFD
|
||
OUT (C),A
|
||
```
|
||
|
||
Fast-RAM включается подобно КЭШ-памяти в 'Пентагоне\'.
|
||
Включение/выключение происходит с помощью кода:
|
||
|
||
```asm
|
||
DI
|
||
IN A,(#FB) ; включить Fast-RAM - 16к в 0-е окно
|
||
; (в адреса #0000..#3FFF)
|
||
... ; your programm
|
||
IN A,(#7B) ; выключить Fast-RAM
|
||
EI
|
||
```
|
||
|
||
Если надо использовать прерывания, программа должна установить
|
||
свой обработчик в адрес #0038.
|
||
Следует иметь в виду, что Fast-RAM может быть использована другими
|
||
программами, т.е. при запуске некоего процесса через DSS содержание
|
||
Fast-RAM может не сохраниться.
|
||
|
||
Перед вызовом функций DSS и BIOS Fast-RAM надо отключать.
|
||
|
||
### Файлы
|
||
|
||
Q:
|
||
И ещё вопрос по функции 16h подскажите плз намера атрибутов в
|
||
частномти можно ли узнать размер файла этой функцией?
|
||
|
||
Размер файла можно узнать с помощью функции 15h.
|
||
|
||
A:
|
||
|
||
**15h (21) MOVE_FP (Перемещение указателя в файле)**
|
||
|
||
входные данные:
|
||
A - файловый манипулятор
|
||
HL:IX - смещение указателя в файле
|
||
B - способ перемещения
|
||
B=0 от начала файла
|
||
B=1 от текущего значения указателя
|
||
B=2 от конца файла
|
||
C - 15h
|
||
выходные данные:
|
||
A - код ошибки, если CF=1
|
||
HL:IX - новое значение указателя
|
||
HL:IX интерпретируется как 32-битное число. Если число меньше 65536,
|
||
регистр HL содержит 0. Возможны следующие способы перемещения указателя:
|
||
B=0 Смещение считается от начала файла, если HL:IX=0, указатель
|
||
устанавливается на начало файла.
|
||
B=1 Смещение считается от текущего значения указателя.
|
||
B=2 Смещение считается от конца файла, если HL:IX=0, после перемещения
|
||
HL:IX получится длина файла в байтах.
|
||
|
||
Атрибуты файла:
|
||
|
||
Каждый бит байта атрибутов задаёт определённый атрибут файла.
|
||
Атрибуты файлов можно изменять специальной функцией ДОС.
|
||
|
||
бит 0 - Только для чтения
|
||
бит 1 - Скрытый
|
||
бит 2 - Системный
|
||
бит 3 - Метка тома
|
||
бит 4 - Каталог
|
||
бит 5 - Архивный
|
||
бит 6 - Не используется
|
||
бит 7 - Не используется
|
||
|
||
- Атрибут "только для чтения". При значении 1 из файла можно читать,
|
||
но в него нельзя писать и его нельзя стереть.
|
||
- Атрибут "скрытый". При значении 1 файл невиден для обычных операций
|
||
ДОС.
|
||
- Атрибут "системный". Указывает, что файл является системным.
|
||
- Атрибут "метка тома". В старых версиях MS-DOS использовался для
|
||
задания метки диска.
|
||
- Атрибут "каталог". При значении 1 идентифицирует файл как каталог,
|
||
подчинённый данному каталогу или элементы "." и "..".
|
||
- Атрибут "архивный". Этот бит устанавливается при операциях записи в
|
||
файл.
|
||
Его могут использовать утилиты создающие архивные копии для сохранения
|
||
изменённых файлов.
|
||
|
||
### Звук
|
||
|
||
Звук через COVOX-Blaster (COVOX с буферным ОЗУ)
|
||
|
||
CBL=COVOX-Blaster
|
||
|
||
Порт управления: 004Eh (**16-bit port!!!**, писать только
|
||
через OUT (c),reg)
|
||
|
||
```asm
|
||
; bit 7 - COVOX-Blaster on (если 0 то обычный режим COVOX)
|
||
; bit 6 - STEREO-mode on
|
||
; bit 5 - 16bit-mode on
|
||
; bit 4 - Interrupt on - включение прерываний
|
||
; bits 3..0 - частота
|
||
;
|
||
; 0 16khz -- mono/stereo -- это старые режимы -- не использовать!
|
||
; 1 22khz -- mono/stereo -- это старые режимы -- не использовать!
|
||
; 2 reserved
|
||
; 3 reserved
|
||
; 4 reserved
|
||
; 5 reserved
|
||
; 6 reserved
|
||
; 7 reserved
|
||
;
|
||
; 8 7.8125 KHz -- mono/stereo 8/16 bit
|
||
; 9 10.9375 KHz -- mono/stereo 8/16 bit
|
||
; A 15.625 KHz -- mono/stereo 8/16 bit
|
||
; B 21.875 KHz -- mono/stereo 8/16 bit
|
||
; C 31.25 KHz -- mono/stereo 8/16 bit
|
||
; D 43.75 KHz -- mono/stereo 8/16 bit
|
||
; E 54.6875 KHz -- mono/stereo 8/16 bit
|
||
; F 109.375 KHz -- mono/stereo 8/16 bit
|
||
```
|
||
|
||
Порт 0FEh - биты запроса прерываний от CBL
|
||
|
||
bit 7 - запрос данных для CBL
|
||
bit 5 - синхронизация экрана (кадровый импульс, 4мс длиной, 20мс период)
|
||
|
||
Запись данных в COVOX-Blaster производится с помощью акселератора,
|
||
записью в страницу ОЗУ 0FDh (просто записать блок 128/256 байт с
|
||
адреса 0C000h) или через порт 4Fh командами OTIR блок записываемых
|
||
данных по запросу. Для 8 бит режима - 128 байт; для 16 бит - 256 байт
|
||
|
||
Самый простой пример:
|
||
|
||
```asm
|
||
Test:
|
||
LD BC,04Eh
|
||
LD A,8Bh ; включить 8 бит 22khz mono
|
||
OUT (C),A ; - CBL - включен!
|
||
INC C
|
||
LD HL,Sample
|
||
OTIR ; загрузить все 256 байт
|
||
RET
|
||
|
||
Sample:
|
||
DB 80h,81,82h,... ; (256 отсчетов звука с нулем на уровне 80h)
|
||
```
|
||
|
||
Должен пищать одну ноту (если в Sample записать синус, то должно
|
||
чисто звучать).
|
||
|
||
Запрос данных в бите 7 порта FE появляется для каждых 128 байт (256
|
||
в режиме 16 бит). Его следует проверять, если его не оказалось, то
|
||
прерывание экранное, а не от CBL.
|
||
|
||
При выставленных прерываниях от CBL, стоит использовать режим IM 2,
|
||
иначе, будет часто вызываться DOS-овая процедура прерываний и могут
|
||
появиться тормоза на высоких частотах.
|
||
|
||
В режиме 8 бит сэмплы должны иметь уровень нуля на 80h, 16 бит
|
||
сэмплы - уровень нуля - 0000h
|
||
Stereo-сэмплы - должны иметь чередующиеся отсчеты левого и правого
|
||
канала.
|
||
|
||
```asm
|
||
mono_8bit:
|
||
|
||
DB 80h,81h,7Fh....
|
||
|
||
mono_16bit:
|
||
DW 0,1000,-1000...
|
||
|
||
stereo_8bit:
|
||
DB 80h,80h,81h,80h,7Fh,80h...
|
||
; здесь один канал играет, второй молчит
|
||
|
||
stereo_16bit:
|
||
DW 0,0,1000,0,-1000,0...
|
||
; аналогично, один канал играет, второй молчит
|
||
```
|
||
|
||
(При тестировании 16 бит режима следует помнить, что звук с
|
||
амплитудой в единицы почти не слышен)
|
||
|
||
P.S. Формат данных выбран так, что бы из WAV-файлов данные в CBL
|
||
пересылать простой операцией блочной пересылки.
|
||
|
||
### ISA-8 слоты
|
||
|
||
#### Summary
|
||
|
||
This article describe ISA-8 interaction.
|
||
|
||
#### More information
|
||
|
||
If you want to interaction with ISA devices, you have to make following
|
||
steps:
|
||
1) send 10h value to port 1FFDh(system port);
|
||
2) send control byte to port 0E2h(third memory window port);
|
||
control byte:
|
||
```
|
||
D7...should be 1
|
||
D6...should be 1
|
||
D5...should be 0
|
||
D4...should be 1
|
||
D3...should be 0
|
||
D2...specify number of ISA slot
|
||
D1...specify access mode (0 - ISA memory, 1 - ISA ports)
|
||
D0...should be 0
|
||
```
|
||
The read/write signals are forming from read/write signals
|
||
memory range 0C000h-0FFFFh. And the address lines A13...A0
|
||
has taken from processor data-BUS. The other ISA-signals
|
||
such as RESET, AEN, A19...A14 can be set in port 9FBDh.
|
||
And default value is 00h.
|
||
```
|
||
port 9FBDh:
|
||
D7...RESET
|
||
D6...AEN
|
||
D5...A19
|
||
D4...A18
|
||
D3...A17
|
||
D2...A16
|
||
D1...A15
|
||
D0...A14
|
||
```
|
||
|
||
```asm
|
||
|
||
ISA_DIR EQU 9FBDh
|
||
SC_PORT EQU 1FFDh
|
||
PAGE3 EQU 0E2h
|
||
|
||
SAVE_PAGE DB 0 ;variable for previous status of third memory port
|
||
|
||
RESET_ISA: ; reset ISA device
|
||
LD C, ISA_DIR
|
||
LD A,0C0h
|
||
OUT (C),A
|
||
CALL Pause_10ms
|
||
LD A,0
|
||
OUT (C),A
|
||
RET
|
||
|
||
Pause_10ms:
|
||
LD HL,10000
|
||
|
||
Loop:
|
||
DEC HL
|
||
LD A,H
|
||
XOR L
|
||
JR NZ,Loop
|
||
RET
|
||
|
||
OPEN_ISA_PORTS: ; open access to ISA
|
||
LD BC,SC_PORT
|
||
LD A,10h
|
||
OUT (C),A
|
||
IN A,(PAGE3) ; read value from memory port
|
||
LD (SAVE_PAGE),A ; save previous status of memory port
|
||
LD A,0D2h ; control byte for (first (upper) ISA slot)
|
||
OUT (PAGE3), A ; opening ISA port address space
|
||
LD C,ISA_DIR
|
||
LD A,0 ; high ISA addresses RESET and AEN signals.
|
||
OUT (C),A
|
||
RET
|
||
|
||
CLOSE_ISA_PORTS: ; close access to ISA
|
||
LD A,(SAVE_PAGE)
|
||
OUT (PAGE3),A ; restore value of memory port
|
||
LD BC,SC_PORT
|
||
LD A,0
|
||
OUT (C),A ;
|
||
RET
|
||
|
||
WRITE_ISA_PORT:
|
||
LD HL,ADRESS_PORT+0C000h ; ISA port address + 0C000h offset 3 memory page
|
||
LD A,DATA_OUT ; data for writing
|
||
LD (HL),A ; write data to port which pointered HL
|
||
RET
|
||
|
||
READ_ISA_PORT:
|
||
LD HL, ADRESS_PORT+0C000h ; ISA port address + 0C000h offset 3 memory page
|
||
LD A,(HL) ; read data from port which pointered HL
|
||
RET
|
||
|
||
```
|
||
|
||
When you work with ISA, the access to third memory page are disabled. If
|
||
you want to address ISA-memory more than 3FFFh, you should specify high
|
||
bits in port 9FBDh.
|
||
|
||
### Акселератор компьютера Sprinter.
|
||
|
||
Акселератор предназначен для ускорения операций по пересылке блоков
|
||
данных в ОЗУ и видео-ОЗУ.
|
||
|
||
Акселератор позволяет:
|
||
|
||
- быстро заполнять горизонтальную или вертикальную линию длиной до 256
|
||
точек одним цветом (в режиме 640x256 - одинарную/двойную горизонтальную
|
||
линию длиной до 512 точек)
|
||
- быстро копировать горизонтальную или вертикальную линию длиной до 256
|
||
точек (в режиме 640x256 - горизонтальную линию до 512 точек)
|
||
- проводить быстрые операции AND, OR, XOR с блоками памяти.
|
||
|
||
**Акселератор не может работать с блоками данных ПЗУ и Быстрого-ОЗУ.**
|
||
|
||
ОЗУ акселератора является частью внутреннего ОЗУ ППЛМ.
|
||
Операции по пересылке данных производятся путем записи блока данных в
|
||
это внутреннее ОЗУ, а затем копировании его в нужное место ОЗУ из ОЗУ
|
||
акселератора.
|
||
Блок данных, записываемый в ОЗУ акселератора может иметь различную
|
||
длинну из диапазона 1..256 байт.
|
||
После одной записи копирование может производиться несколько раз и,
|
||
таким образом, можно производить заполнение экрана текстурами.
|
||
Для заполнения экрана одним цветом используется другой режим
|
||
акселератора. В нем вместо копируемого блока данных из внутреннего ОЗУ
|
||
производится запись данных с шины процессора, которые в этот момент не
|
||
изменяются.
|
||
|
||
Управление акселератором производится непосредственно из программы.
|
||
Для этого изпользуются команды процессора, которые, фактически, являются
|
||
операциями типа NOP.
|
||
|
||
```asm
|
||
LD B,B - выключить акселетарор.
|
||
LD D,D - включить акселератор в режим приема байта размера блока
|
||
далее следует команда типа LD A,dat, где dat и будет новым
|
||
размером блока. Если размер блока был установлен ранее,
|
||
его можно не устанавливать.
|
||
LD C,C - Операция Fill - заполнение одним байтом. Последующая
|
||
команда типа LD (HL),A приведет к заполнению указанного
|
||
ранее количества байт значением A
|
||
LD E,E - Операция Fill для графического экрана - заполнение
|
||
вертикальных линий.
|
||
LD H,H - rezerved
|
||
LD L,L - копирование блока. Последующая команда типа LD A,(HL)
|
||
приведет к заполнению ОЗУ акселератора данными из адреса (HL),
|
||
а команда типа LD (DE),A приведет к перезаписи данных из ОЗУ
|
||
акселератора в ОЗУ или видео-ОЗУ.
|
||
LD A,A - копирование блока для графического экрана подобна команде
|
||
LD L,L, но работает с вертикальными линиями экрана.
|
||
```
|
||
|
||
Пример использования акселератора:
|
||
|
||
```asm
|
||
; Считаем, что экранная страница уже открыта по адресу #C000
|
||
LD HL,#C040 ; адрес начала линии первого экрана
|
||
LD DE,#C180 ; адрес начала линии второго экрана
|
||
LD BC,#140 ; длина экрана по горизонтали
|
||
DI ; запретить прерывания для работы с акселератором
|
||
LD D,D ; включить акселератор на установку размера блока
|
||
LD A,0 ; установить размер блока - 256 байт
|
||
LD A,A ; установить акселератор на копирование
|
||
; вертикальных линий.
|
||
LDIR ; копировать
|
||
LD B,B ; выключить акселератор
|
||
EI ; включить прерывания
|
||
```
|
||
|
||
Эта часть программы произведет копирование всего содержимого первого
|
||
экрана на другой. Время исполения составляет примерно 26 милисекунд.
|
||
Дополнительные функции акселератора (AND, OR, XOR) работают таким же
|
||
образом.
|
||
Для выполнения логических функций используются команды XOR (HL); OR
|
||
(HL); AND (HL).
|
||
|
||
Пример кодирования блока в 256 байт.
|
||
```asm
|
||
LD HL,ADRES_1
|
||
LD DE,XOR_DAT
|
||
DI
|
||
LD D,D
|
||
LD A,0 ; число байт, которые надо закодировать
|
||
LD L,L
|
||
LD A,(DE) ; взять блок данных в ОЗУ акселератора
|
||
XOR (HL) ; произвести операцию XOR с данными акселератора
|
||
LD (HL),A ; запомнить в ОЗУ результат операции
|
||
LD B,B
|
||
EI
|
||
```
|
||
|
||
Скорость работы акселератора ограничивается только физической
|
||
скоростью работы основного ОЗУ. Определить примерное время работы
|
||
команды с акселератором можно по такой формуле:
|
||
|
||
Время работы = время работы команды без акселератора + время работы акселератора
|
||
|
||
Время работы акселератора = число пересылаемых байт /7 микросекунд
|
||
Во время работы акселератора необходимо отключать прерывания, так как в
|
||
этот момент изменяется система команд процессора и программа на
|
||
прерывании не сможет работать корректно.
|
||
|
||
### Прерывания
|
||
|
||
Кадровые и клавиатурные прерывания приходят с вектором 0FFh, отличать по
|
||
биту приема байта в порте клавиатуры, не пришел, значит экран. Возможно,
|
||
конечно, совпадение но это исключительно редкий случай.
|
||
|
||
От мыши прерывания не приходят. Сделать можно, но сейчас их нет. Кстати
|
||
и различие от экранных прерываний **можно** (и, видимо, надо будет в
|
||
новой версии) сделать пожестче через прошивку в ПЛМ.
|
||
|
||
От ISA и других внутренных портов процессора прерывания приходят с
|
||
другим вектором (настраивается в портах), поэтому в режиме IM 2 они
|
||
легко различаются.
|
||
|
||
### IDE контроллер
|
||
|
||
Доступ к поpтам осуществляется пpи неактивном Beta-Disk интеpфейсе.
|
||
Со схемой без поллитpы не pазобpаться, пpивожу поpты как есть:
|
||
|
||
поpт pегистp накопителя
|
||
|
||
---- блок командных регистров ----
|
||
xx50 0 (data)
|
||
0051 1 (error/feature)
|
||
0052 2 (sector count)
|
||
0053 3 (sector number)
|
||
0054 4 (cylinder low)
|
||
0055 5 (cylinder high)
|
||
4052 6 (device/head)
|
||
4053 7 (status/command)
|
||
|
||
---- блок управляющих регистров ----
|
||
4054 16 (alternate status/control)
|
||
4055 17 ?
|
||
|
||
Пpи записи в поpт нужно его адpес увеличить на 0x100.
|
||
|
||
Пpи чтении pегистpа данных пpи a8=0 выpабатывается стpоб чтения и
|
||
младшая часть (D0-D7) шины данных накопителя выдаётся на шину
|
||
спектpума, а стаpшая сохpаняется в теневом pегистpе.
|
||
Пpи a8=1 читается теневой pегистp (D8-D15).
|
||
|
||
Пpи записи pегистpа данных когда a8=0 байт сохpаняется в теневом
|
||
pегистpе и стpоб записи для накопителя не выpабатывается. Пpи
|
||
записи pегистpа данных когда a8=1 выpабатывается стpоб записи
|
||
для накопителя и байт с шины спектpума выдаётся на D8-D15 шины
|
||
накопителя, на D0-D7 выдаётся содеpжимое теневого pегистpа.
|
||
|
||
Контроллер имеет общий теневой регистр для записи и чтения.
|
||
|
||
вот мои раскопки на эту тему от 13.10.2003:
|
||
|
||
регистр команд | регистр состояния - 4153h запись, 4053h чтение
|
||
регистр накопителя | головки - 4152h запись, 4052h чтение
|
||
регистр циллиндра (старший байт) - 0155h запись, 0255h чтение
|
||
регистр циллиндра (младший байт) - 0154h запись, 0254h чтение
|
||
регистр данных - 0150h запись, 0050h чтение
|
||
|
||
Верна информация.
|
||
С одним добавлением. Доступ открыт в режиме Sprinter-ZX,
|
||
а в режимах Pentagon, Scorpion и т.п. - закрыт!
|
||
|
||
### FDD контроллер
|
||
|
||
0Fh Command/Status register
|
||
3Fh Track register
|
||
5Fh Sector register
|
||
FFh Drive Control register
|
||
|
||
In Spectrum configuration the port 0Fh also mapped to 1Fh for TRDOS
|
||
compatibility.
|
||
But I would recommend to you don\'t use direct port access for it.
|
||
A Sprinter have BIOS functions for reading/writing any disk sectors.
|
||
|
||
for example:
|
||
|
||
At first, make reset disk and to set required parameters.
|
||
```asm
|
||
INIT_DISK:
|
||
LD D,n ; drive number 0-FDD A, 1-FDD B, 80h-HDD C\...
|
||
LD C,#51 ; reset disk
|
||
RST #08 ; BIOS call
|
||
;
|
||
LD D,n ; drive number
|
||
LD E,n ; sectors per track.
|
||
PUSH DE
|
||
LD A,D
|
||
LD C,#58 ; get disk parameters
|
||
RST #08 ; BIOS call
|
||
LD A,H
|
||
POP HL
|
||
PUSH HL
|
||
LD H,A
|
||
POP AF
|
||
LD IX,256 ; sector size
|
||
LD C,#59 ; set disk parameters
|
||
RST #08 ; BIOS call
|
||
RET
|
||
```
|
||
|
||
And next to use BIOS fn. 055h for reading.
|
||
```asm
|
||
DRV_READ: ; reading from disk
|
||
LD A,drv_type ; bit 0..3 - drive number
|
||
; bit 4..7 - drive type
|
||
; 0 - FDD
|
||
; 6 - ram-disk (reserved)
|
||
; 8 - HDD
|
||
; C - CD-ROM (reserved)
|
||
LD HL,sec_h ; sector number (high)
|
||
LD IX,sec_l ; sector number (low)
|
||
; (HL:IX - 32bit sector number, like LBA)
|
||
LD B,n_sec ; sectors count
|
||
LD DE,bufer_adr ; memory address for reading
|
||
LD C,#55 ;
|
||
RST #08 ; CF=0 - read OK
|
||
; CF=1 - read error
|
||
```
|
||
|
||
# Клавиатура
|
||
|
||
|
||
It's possible by DSS function 36h (K_SETUP). Sprinter has two keyboard
|
||
layouts (standard and alternative) which can be switched by [CTRL] +
|
||
[SPACE]. Each layout includes four keyboard modes. You can reload all
|
||
of them.
|
||
|
||
```asm
|
||
LD HL,LAYOUT
|
||
LD A,0 ;LAYOUT FOR NORMAL MODE
|
||
LD BC,#0036
|
||
RST #10
|
||
|
||
Esc EQU #1B
|
||
Bcs EQU #08
|
||
Tab EQU #09
|
||
Cps EQU #00
|
||
Spc EQU #20
|
||
Ent EQU #0D
|
||
|
||
;Normal mode (without CAPS and SHIFT not pressed)
|
||
DB "`",Esc,"1","2","3","4","5","6","7","8","9","0","-","=",Bcs
|
||
DB Tab,"q","w","e","r","t","y","u","i","o","p","[","]"
|
||
DB Cps,"a","s","d","f","g","h","j","k","l",";","'",Ent
|
||
DB #00,"z","x","c","v","b","n","m",#2C,".","/",#00,#5C
|
||
DB #00,#00,Spc,#00,#00
|
||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||
|
||
;SHIFT mode (without CAPS and SHIFT are pressed)
|
||
DB "~",Esc,"!","@","#","$","%","^","&","*","(",")","_","+",Bcs
|
||
DB Tab,"Q","W","E","R","T","Y","U","I","O","P","{","}"
|
||
DB Cps,"A","S","D","F","G","H","J","K","L",":",#22,Ent
|
||
DB #00,"Z","X","C","V","B","N","M","<",">","?",#00,"|"
|
||
DB #00,#00,Spc,#00,#00
|
||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||
|
||
;CAPS mode (with CAPS and SHIFT not pressed)
|
||
DB "`",Esc,"1","2","3","4","5","6","7","8","9","0","-","=",Bcs
|
||
DB Tab,"Q","W","E","R","T","Y","U","I","O","P","[","]"
|
||
DB Cps,"A","S","D","F","G","H","J","K","L",";","'",Ent
|
||
DB #00,"Z","X","C","V","B","N","M",#2C,".","/",#00,#5C
|
||
DB #00,#00,Spc,#00,#00
|
||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||
|
||
;CAPS+SHIFT mode (with CAPS and SHIFT are pressed)
|
||
DB "~",Esc,"!","@","#","$","%","^","&","*","(",")","_","+",Bcs
|
||
DB Tab,"q","w","e","r","t","y","u","i","o","p","{","}"
|
||
DB Cps,"a","s","d","f","g","h","j","k","l",":",#22,Ent
|
||
DB #00,"z","x","c","v","b","n","m","<",">","?",#00,"|"
|
||
DB #00,#00,Spc,#00,#00
|
||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||
DB #00,#00,#00,"/","*","-","+",Ent,#00
|
||
DB #00,#00,#00,#00,#00,#00,#00,#00,#00,#00
|
||
```
|
||
---
|
||
|
||
Прерывания от клавиатуры выставляют бит 0 в порте 19h, им и отличаются
|
||
от прерываний экрана. Конечно, возможны случайные совпадения, когда
|
||
прерывание от клавиатуры пришло одновременно с экранным, но это очень
|
||
маловероятно. От других устройств прерывание может придти, но так же с
|
||
некими признаками в портах (но это только в случае, если программа эти
|
||
порты настроила и использует для себя)
|
||
|
||
### Коды ошибок DSS
|
||
|
||
This is a list of DSS error numbers.
|
||
|
||
00h (00) - Success
|
||
01h (01) - Invalid function
|
||
02h (02) - Invalid drive number
|
||
03h (03) - File not found
|
||
04h (04) - Path not found
|
||
05h (05) - Invalid handle
|
||
06h (06) - Too many open files
|
||
07h (07) - File exist
|
||
08h (08) - File read only
|
||
09h (09) - Root overflow
|
||
0Ah (10) - No free space
|
||
0Bh (11) - Directory not empty
|
||
0Ch (12) - Attempt to remove current directory
|
||
0Dh (13) - Invalid media
|
||
0Eh (14) - Invalid operation
|
||
0Fh (15) - Directory exist
|
||
10h (16) - Invalid filename
|
||
11h (17) - Invalid EXE-file
|
||
12h (18) - Not supported EXE-file
|
||
13h (19) - Permission denied
|
||
14h (20) - Not ready
|
||
15h (21) - Seek error
|
||
16h (22) - Sector not found
|
||
17h (23) - CRC error
|
||
18h (24) - Write protect
|
||
19h (25) - Read error
|
||
1Ah (26) - Write error
|
||
1Bh (27) - Drive failure
|
||
1Ch (28) - Unknown error : 28
|
||
1Dh (29) - Unknown error : 29
|
||
1Eh (30) - No free memory
|
||
1Fh (31) - Invalid memory block
|
||
20h (32) - Unknown error : 32
|