Files
Sprinter-SDCC/docs/part2/BIOS functions.a80
T
snark13 c71e249a4e Add full compiler toolchain, libc, examples and reference docs
First substantive commit: the entire Sprinter C compiler tree on top of
the bare README+gitignore initial commit.

What's in here:
  bin/sprinter-cc        — driver script invoking SDCC + linker + mkexe
  libc/                  — Sprinter-specific libc layer over ESTEX/BIOS
                           (conio, gfx, io, mem, stdio + headers)
  runtime/               — crt0 variants (default/small/banked/minimal)
                           + heap + bank trampolines
  toolchain/             — mkexe (SprintEXE packer, C + tests)
  examples/              — 30 demo programs (gfx, file I/O, env, time, …)
  lib/Makefile           — builds the libc archive (sprinter.lib)
  docs/                  — converted Sprinter manuals + asm reference samples
  third_party/           — solid-c reference compiler dump + sdcc setup script
  release_docs/          — packaging / release notes

gitignore overhaul:
  • Drop dangerous blanket patterns: *.asm (would hide docs/samples/*.asm)
    and *.exe (case-insensitive match was hiding third_party/solid-c/*.EXE
    on macOS APFS).  Replaced with examples/*/*.{asm,exe,…} and lib/*.lib.
  • Restore tracking of toolchain/mkexe/tests/{one,big}.bin — those are
    INPUT fixtures, not build outputs.
  • Collapse the duplicated SDCC/C/Sdcc sections into one section per
    concern (build outputs / vendored / OS-junk).
  • Add .sprinter-cc-*/, build/ (catches lib/build/ too), .claude/.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-03 16:13:21 +03:00

1387 lines
83 KiB
Plaintext
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
; Sprinter.
; Функции BIOS.
; Вызов функций производится через вход в TR-DOS #3D13. Номер команды
; задается в регистре C. Установленный на выходе флаг C означает завершение
; работы функции с ошибкой.
; При работе части функций биоса необходимо что бы стек находился в
; области #8000..#BFFF, так как они используют для своей работы переключение
; страниц PAGE1 и PAGE3. Для устранения каких либо неприятностей связанных со
; стеком его следует всегда устанавливать в этот диапазон при вызове функций
; биоса Спринтера.
; Вызов функций биос так же может быть осуществлен через вход по
; RST #18 при подключенном системном ПЗУ, а так же через RST 8 при
; подключенном ОЗУ в нулевой банке путем установки на адрес RST 8 небольшой
; программы, переключающейся в ПЗУ биоса
; Для подключения системного ПЗУ можно воспользоваться такой
; последовательностью команд:
DI
LD A,0
OUT (#7C),A
; после этого в 0-м адресе будет включена ПЗУ биоса
; и программа может вызывать функции через RST #18,
; просто заменяя этим вызовом вызов CALL #3D13
; * Обычные функции TR-DOS в этот момент недоступны
; Чтобы вернуться к обычному ПЗУ следует выполнить программу:
LD A,0
OUT (#3C),A
; Вызов из ОЗУ осуществляется через RST 8. При этом на адресе 8 должна
; располагаться такая программа:
PUSH AF
LD A,0
OUT (#7C),A ; в этом месте вместо ОЗУ подключится ПЗУ биоса и
; программа уйдет в него.
POP AF ; На эту команду происходит возврат при таком
; вызове биоса.
RET
; Оптимизация кода в этом месте недопустима. Вместо LD A,0 можно установить
; две команды XOR A и DI
; Далее вызов функций осуществляется аналогично RST #18, но следует помнить,
; что адресное пстранство 0000..#3FFF во время работы биоса занято ПЗУ и в нем
; не могут располагаться данные для работы функций.
; Вызов новых функций через #3D13 автоматически отключает прерывания.
; После исполнения функции программа должна включить их при необходимости.
; Если необходимо что бы прерывания были включены все время, следует
; использовать режим IM 2, с таблицей, стеком и обработчиком расположенным в
; области #8000..#BFFF и пользоваться вызовом через RST #18 или RST 8
; В этом случае прерывания в биосе не отключаются.
; В ближайшее время в описание биоса будут добавлены функции работы с FDD и
; CD-ROM
; * В данный момент они имеются, но предполагается их серьезная переделка.
; Некоторые функции зарезервированы для дальнейшего развития. Так же не
; описана часть графических функций, так как они в данный момент подвергаются
; серьезным переделкам.
;==============================================================================
; 1. Работа с памятью.
;==============================================================================
EMM:
.GetMemSize: ; определение объемов ОЗУ
LD C,#C0 ; функция номер #C0
RST ToBIOS ; HL - общий объем памяти в страницах по 16kb
; BC - объем свободной памяти в страницах по 16kb
;
.InitMem: ; инициализация распределения памяти
; стирается вся информация о выделенных ранее блоках
; ОЗУ. Устанавливаются как занятые блоки с
; системной информацией, а так же первые 256kb ОЗУ ;!FIXIT
LD C,#C1 ; номер функции
RST ToBIOS ; выходных параметров нет
;
.GetMem: ; выделение блока ОЗУ
LD B,num_pages ; запрашиваемое число страниц ОЗУ
LD C,#C2 ; номер функции
RST ToBIOS ; NC -> А - идентификатор блока
; CF -> A=1 - нет памяти
;
.FreeMem: ; освободить блок ОЗУ
LD A,id_blk ; идентификатор блока
LD C,#C3 ; номер функции
RST ToBIOS ; NC - нормальное завершение
; CF - неверный идентификатор блока
; правильность идентификатора отслеживается не всегда
;
.GetMemPage: ; получить физический номер страницы из блока
LD A,id_blk ; идентификатор блока
LD B,page ; логическая страница в блоке
LD C,#C4 ; номер функции
RST ToBIOS ; NC -> А - физический номер страницы
; CF -> А=0 - нет такого блока, A=FF - конец блока
;
.GetMemBlkPages:; получить список физических страниц блока
LD A,id_blk ; идентификатор блока
LD HL,bufer ; буфер длиной 256 байт для размещения списка
; буфер должен быть длиной на единицу больше числа
; страниц в блоке
LD C,#C5 ; номер функции
RST ToBIOS ; NC -> HL - тот же буфер, B - число страниц в блоке,
; данные по адресу HL - список физических страниц по
; порядку. Список заканчивается байтом FF
; CF -> неверный идентификатор блока. Старая
; информация в буфере может быть затерта
;
.GetBanksPorts: ; Получение адресов портов окон
LD A,win_num ; номер окна проецирования 0,1,2 или 3
LD C,#C6 ; номер функции
RST ToBIOS ; NC -> C - 8-мибитный адрес порта, B - номер
; подключенной в данный момент страницы ОЗУ
; CF -> ошибка номера окна
; Функция фактически не используется в данный момент. Адреса портов окон
; не изменялись с самого начала разработки компьютера и, надеюсь, не будут
; меняться. Для соблюдения приличий программисту следует хотя бы один раз
; вызвать эти функции и сравнить адреса портов с теми, что используются в
; программе и, если они не совпадают, выдать соответствующее предупреждение.
; В данный момент эти порты таковы: PAGE0=#82, PAGE1=#A2, PAGE2=#C2, PAGE3=#E2
;
.GetMemPageNext:; получить следующую страницу блока по предыдущему
LD A,page ; физическая страница блока
LD C,#C7 ; номер функции
RST ToBIOS ; NC -> A - следующая физическая страница блока
; A=FF - индицирует конец блока
; CF -> ошибка номера страницы
; Информация о распределении памяти хранится в виде RAM Allocation Table,
; похожей на дисковый FAT. Поэтому нахождение физического номера следующей
; страницы по предыдущему физическому номеру происходит значительно быстрее,
; чем поиск по увеличенному на единицу логическому номеру.
;
.MergeMemBlocks:; слияние блоков
LD A,id_blk1 ; блок номер 1
LD B,id_blk2 ; блок номер 2
LD C,#9E ; номер функции
RST ToBIOS ; NC -> A - блок результата
; CF -> ошибка, неверный номер блока
;
.DivMemBlocks ; разделение блока
LD A,id_blk1 ; блок
LD B,len_blk ; новая длина блока
LD C,#9D ; номер функции
RST ToBIOS ; NC -> A - блок результата, B - блок остатка
; CF -> ошибка, неверный номер блока
;
;==============================================================================
; 2. Работа с блоками как с RAM-Disk-ами
;==============================================================================
.GetMemRMD: ; Получить блок памяти N bytes для RAM-Disk'а
LD A,ram_disk ; номер RAM-Disk-а 0..15
LD B,ram_blocks; число необходимых блоков
LD C,#92 ; номер функции
RST ToBIOS ; NC -> L, A - КЛЮЧ RAM-Disk'а
; CF -> ошибка,
; A - код ошибки: 1 - нет памяти
; 2 - RAM-Disk занят
;
.FreeMemRMD: ; Освободить блок памяти для RAM-Disk'а
LD A,ram_disk ; номер RAM-Disk'а 0..15
LD C,#93 ; номер функции
RST ToBIOS ; NC - нормальное завершение
; CF - ошибка, А=0 - нет такого блока, A=2 - ошибка цепочки
;
.GetMemPageRMD: ; Получить физический номер страницы RAM-Disk'а
LD A,ram_disk ; номер RAM-Disk'а 0..15
LD B,page ; логическая страница RAM-Disk'а
LD C,#94 ; номер функции
RST ToBIOS ; NC -> А - физический номер страницы
; CF -> А=0 - нет такого блока, A=FF - конец блока
;
.CheckInit: ; Если обнаружен первый старт, то инициализация всей памяти, системных переменных
LD C,#97 ; номер функции
RST ToBIOS ;
;
RAMD_CALC_PAGE: ; Вычисление страницы и адреса в RAM-Disk по абсолютному номеру сектора
LD A,ram_disk ; номер RAM-Disk'а 0..15
LD DE,sector ; абсолютный номер сектора
LD C,#98 ; номер функции
RST ToBIOS ; A - страница, HL - адрес в странице
;
.FullInit: ; инициализация всей памяти, системных переменных
LD C,#9F ; номер функции
RST ToBIOS ;
;
BLK_RD_WR: ; чтение/запись из/в блок(а) памяти секторами
; по 256 байт (в случае с ROM диском можно по 512)
LD HL,bufer ; адрес буфера данных
LD DE,sector ; абсолютный номер сектора (считать по 256b сектор)
LD B,sec_num ; число секторов
LD A,id_blk ; идентификатор блока (для rom disk размер сектора: 1 - 256b, 2 - 512 b)
LD A',command ; команда 0 - чтение, #FF - запись, #46 чтение из ROM-Disk
LD C,#C8 ; номер функции
RST ToBIOS ; NC -> нормальное завершение
; CF -> ошибка идентификатора
;
BLK_TO_RAMD: ; назначить блок памяти RAM-Disk-у
; любой блок памяти может содержать данные
; RAM-Disk-а в формате TR-DOS для подключения этих
; данных в качестве диска и служит эта функция
LD A,ram_disk ; номер RAM-Disk-а 0..15 - соответствует
; RAM-Disk-ам от e: до t:
LD B,id_blk ; идентификатор блока
LD C,#C9 ; номер функции
RST ToBIOS ; NC -> нормальное завершение
; CF -> ошибка: неверный номер RAM-Disk-а или RAM-Disk занят
;
RAMD_CLEAR: ; освободить RAM-Disk
; освобождение RAM-Disk-а не есть освобождение
; блока ОЗУ. Это просто отключение блока ОЗУ от
; RAM-Disk-а
LD A,ram_disk ; номер RAM-Disk-а - 0..15
LD C,#CA ; номер функции
RST ToBIOS ; NC -> нормальное завершение, B - идентификатор
; блока отключенного от RAM-Disk-а
; CF -> ошибка: неверный номер RAM-Disk-а или
; RAM-Disk был свободен
;
GET_RAMD_ST: ; получение идентификатора блока, назначенного на
; RAM-Disk
LD A,ram_disk ; номер RAM-Disk-а 0..15
LD C,#CE ; номер функции
RST ToBIOS ; NC -> A - идентификатор блока.
; A=0 - блок не назначен.
; CF -> ошибка номера RAM-Disk-а
;
GET_RAMD_NUM: ; получить номер RAM-Disk-а (0..15) по его block id
LD A,id_blk ; идентификатор блока
LD C,#9B ; номер функции
RST ToBIOS ; NC -> A - номер RAM-Disk-а (0..15).
; CF -> ошибка в идентификаторе блока или биос ниже 2.55
;
; [x] 4/11/23
SWAP_RAM_DRIVES:; поменять местами ID RAM драйвов (ZX/Sp)
LD B,func ; 0 - swap to Sp, #FF - swap to ZX, #FE - no swap, only get info
LD C,#9C ; номер функции
RST ToBIOS ; A - current RAM Drives set
;==============================================================================
; 3. Управление назначением на дисководы
;==============================================================================
; Каждый из 4-х дисководов TR-DOS может быть переназначен для работы
; с RAM-Disk-ами, винчестером и реальными дисководами.
SET_DISK_REDIR: ; установить на текущий драйв переназначение (старая функция для TR-DOS!)
LD E,drv_type ; физический тип и номер устройства
LD C,#99 ;
RST ToBIOS ; NC -> нормальние завершение.
;
GET_DISK_REDIR: ; получить тип назначения на текущий драйв (старая функция для TR-DOS!)
LD C,#9A ; номер функции
RST ToBIOS ; NC -> нормальние завершение. A - тип назначения
; A=0..3 - назначен реальный дисковод A:, B:, C:, D:
; A=4..19 - назначен RAM-Disk, A = ram_disk + 4
; A=#40..#4F - назначен винчестер (#40+hdd_drive)
;
RAMD_TO_DRV: ; назначение RAM-Disk на дисковод.
LD A,ram_disk ; номер RAM-Disk-а
LD B,drive ; номер дисковода 0..3 - соответствует дисководам
; A:, B:, C:, D:
LD C,#CB ; номер функции
RST ToBIOS ; NC -> нормальние завершение
; CF -> ошибка: неверный номер драйва или рамдиска
;
FDD_TO_DRV: ; назначение реального дисковода
LD А,disk_drive; номер физического дисковода 0..3
LD B,drive ; номер драйва 0..3
; Номер физического дисковода и номер драйва должны
; совпадать, так как компьютер не имеет
; электрической схемы переключения дисководов на
; разные буквы. В будущих версиях железа, возможно,
; это появится.
LD C,#CC ; номер функции
RST ToBIOS ; NC -> нормальние завершение
; CF -> ошибка: неверный номер драйва или дисковода
;
HDD_TO_DRV: ; назначение винчестера на дисковод
LD A,hdd_drive ; Номер винчестера.
; различных разделов и master/slave
LD B,drive ; номер драйва 0..3
LD C,#CD ; номер функции
RST ToBIOS ; NC -> нормальние завершение
; CF -> ошибка: неверный номер драйва или винчестера
;
GET_DRV_ST: ; получить тип назначения на драйв ; !TODO проверить
LD A,drive ; номер драйва 0..3
LD C,#CF ; номер функции
RST ToBIOS ; NC -> нормальние завершение. A - тип назначения
; A=0..3 - назначен реальный дисковод A:, B:, C:, D:
; A=4..19 - назначен RAM-Disk, A = ram_disk + 4
; A=#40..#4F - назначен винчестер (#40+hdd_drive)
; CF -> ошибка номера драйва
;
;==============================================================================
; 4. Функции управления железом и определение версии.
;==============================================================================
;!TODO
FN_SEND_BYTE
LD C,#E8
RST ToBIOS
;
;!TODO
FN_RESEIVE_B
LD C,#E9
RST ToBIOS
;
;!TODO
FN_KBD_OUT
LD C,#EA
RST ToBIOS
;
FN_CRIPT
LD B,func ; 1: HL - ROM_NUMBER part1
; A - ROM_NUMBER part2
; BC - BoardID start
; DE - BoardID end
; [x] 28/01/2024
; ; 2: HL - адрес буфера для названия чипа (текст). максимум 5 байтов, заканчиваются нулём
LD HL,buff ; CF = 0:
; ; A: 0 - K30, 1 - K50, остальное в резерве на будущее
; ; DE: версия битстрима
LD C,#ED
RST ToBIOS
;
RST_CONF.AY8910:; переключение в конфигурацию Spectrum. AY8910
LD C,#EE ; номер функции
RST ToBIOS ; NC -> нормальное завершение
; CF -> функция не исполнена, фатальная ошибка
; машину следует перезапустить по RESET
;
FN_VERSION: ; выдача информации о версии биоса и железа
LD HL,bufer ; буфер, куда будет помещена ASCIIZ строка с
; названием и номером версии, конец строки отмечен
; нулем.
LD C,#EF ; номер функции
RST ToBIOS ; NC -> HL - тот же буфер с записанной строкой:
; "название прошивки | Sprinter | версия_конфы"
; A - число полей строки в буфере HL
; DE - версия биоса
; BC - версия железа (;!TODO тут выдаётся CONFIG_BYTE)
; BC=#FFFF - not identifyed
; BC=#FFFE - Sprinter-1
; BC=#FFFD - Sprinter-2
; BC=#FFFC - Spectrum + AY8910
; BC=#FFFB - Game-1
; BC=#FFFA - Video-1
; BC=#FFF9 - DooM
; BC=#FEFF - Sprinter 2000
; Иные значения BC - новые прошивки
; версия железа выдается только
; в биосах версий 1.16 и выше
; CF -> ошибка. Очень старая версия, не имеющая
; данной функции
;!!!!! Старая версия выдавала:
; ; L - первые 4 бита - биты порта All_Mode.
; ; в FN есть такой код:
;
; LD A,%0000'1101 ; нужные биты для порта All_Mode
; AND L
; SUB %0000'1101
; JR Z,InitVM1
; IN A,(SCREEN_SWITCH)
; PUSH AF
; LD C,BIOS.RST_CONF.SP97_2
; RST ToBIOS
; SUB A
; OUT (BORDER),A
; POP AF
; OUT (SCREEN_SWITCH),A
;
;!FIXIT
RST_CONF.SP97_1:; переключение в конфигурацию Sprinter-1. SPRINTER_1
LD C,#F0 ; номер функции
RST ToBIOS ; NC -> нормальное завершение
; CF -> функция не исполнена, фатальная ошибка
; машину следует перезапустить по RESET
;
;!FIXIT
RST_CONF.SP97_2:; переключение в конфигурацию Sprinter-2. SPRINTER_2
LD C,#F1 ; номер функции
RST ToBIOS ; NC -> нормальное завершение
; CF -> функция не исполнена, фатальная ошибка
; машину следует перезапустить по RESET
;
RST_CONF.CUSTOM:; переключение конфигурации пользователя. SPRINTER_ALL
LD A,page_cnf ; страница с файлом прошивки для ПЛМ EPF10K10
; страница не может иметь номер больше 127
; Файл прошивки, естественно должен быть уже
; загружен в эту страницу
LD B,ramblk ; [x] при A = #FE перезаливка конфы с возвратом. B указывает на RAM Block ID с битстримом для загрузки, если B=0, то загрузка из ROM
; [x] при A = #FD происходит реинит. Аксель включается и тд... можно напихать туда ещё что-нибудь
; [x] при A = #FC софт-ресет с возвратом
; [x] при A = #FB установка перехватчика софт-ресета, DE - адрес процедуры
; [x] при A = #FA установка перехватчика хард-ресета, DE - адрес процедуры, B - RAM_BLK_ID с конфой, либо 0, если из пзу
LD C,#F3 ; номер функции
RST ToBIOS ; NC -> нормальние завершение
; CF -> функция не исполнена, фатальная ошибка
; машину следует перезапустить по RESET
;
; ; [x] free zx pages
GOTO_SPEC: ; Вход в режим спектрума
; Вход: D: 0 - BASIC 128, 1 - BASIC 48, 2 - TR-DOS 128,
; 3 - EXPANSION. C закрытыми 128-ми портами:
; 4 - TR-DOS, 5 - BASIC 48
; E: значение для SYS_PORT/CNF_PORT
; L: Block_ID.vROM
; H: Block_ID.vRAM
; B: Port All Mode
;A [1..0]: 1 - int scorp, 2 - int pent, 3 - int ZX
; A'[2]: 0 - set default palette, 1 - don't change palette
; A'[7]: 0 - 320, 1 - 312 строк
LD C,#FB
RST ToBIOS
;
REINIT: ; [x] Сброс, перезагрузка, рестарт, очистка памяти с восстановлением ZX pages ; [ ] free zx pages!
LD B,res_type ; 1 - рестарт, 2 - soft reset, 3 - hard reset. 4 - clear RAM except zx pages
LD C,#FD ; номер функции
RST ToBIOS ; CF -> функция не исполнена, возможные причины:
; - некорректное значение res_type
; - одна из ZX страниц занята (при res_type=4),
; тогда под zx отдастся только часть страниц
; - старая версия BIOS
;
;[x]
FN_SYNC: ; установка синхронизации, очистка режима экрана, установка задержек
; функция может быть отнесена и к группе функций
; вывода на экран, так как полностью очищает
; страницы режима экрана. На всем экране остается
; только бордюр
LD A,sync_mode ; режим синхронизации
; Reg A bit7 = 0 - режим очистки экрана и установки INT:
; A = 0: режим по умолчанию - используется для очистки
; страниц режима (отключения вывода всех окон)
; A = 1: режим Scorpion - 312 строк в экране,
; положение INT-а, как в Scorpion-256
; A = 2: режим Pentagon - 320 строк в экране,
; положение INT-a как в Pentagon-128
; A = 3: режим Spectrum
; положение INT-a как в оригинальном ZX Spectrum
; A = 4: установка INT из настроек пользователя в CMOS
; A = 5: установка INT из таблицы пользователя
; указатель в IX, данные в SLOT1..2
;
; Reg A bit7 = 1 - режим установки вертикальной синхронизации и/или wait:
; bit1,bit0:
; %00 - синхра выставляется из системной переменной
; %01 - синхра выставляется из CMOS
; %10 - синхра 320 lines 49 Hz
; %11 - синхра 312 lines 50 Hz
; bit2:
; %0 - игнорировать bit1..bit0
; %1 - не игнорировать bit1..bit0
; bit3:
; %0 - no waits (port all_mode bit2 set)
; %1 - original waits (port all_mode bit2 res)
; bit4:
; %0 - игнорировать bit3
; %1 - не игнорировать bit3
; bit5,bit6 - reserved ;!TODO use for HOLD port?
;
LD C,#F2 ; Номер функции
RST ToBIOS ; NC -> нормальное завершение
; CF -> неверный номер режима синхронизации
; изменение режима синхронизации может привести к временному сбою
; синхронизации монитора.
; !TODO подробное описание
DCP_CONFIG: ; [x] функция управления дешифратором портов.
;A - если ноль, то вызов функции переинициализации портов PORTS_INIT
;HL - адрес
;DE - маска - 0 изменяемые биты, 1 неизменяемые
;B - порт
;C - #F4 номер функции
; Функция позволяет открывать/закрывать дополнительные порты компьютера.
;
; Функции SET_PORTS и READ_PORTS позволяют иметь доступ
; к любым портам компьютера независимо от того, открыты они или нет.
; С помощью этих функций возможно прочитать содержимое портов 1FFD и
; 7FFD, например, а так же установить нужные значения в закрытые системные
; порты. Порты User-а позволят эмулировать некоторые устройства,
; отсутствующие в Спринтере, а так же могут дать особый способ
; передачи данных между программами, минуя ОЗУ.
;
SET_PORTS: ; глобальная установка портов.
LD A,port_num ; внутренний номер порта
; F0..FF - страницы Scorpion 0..15, подключаемые в
; адрес #C000, страница именно та, которая
; подключена в данный момент через 7FFD,1FFD
; E0=EXPANSION, Е1=TR-DOS, E2=BASIC-128, E3=BASIC-48
; E4=EXPANSION',Е5=TR-DOS',E6=BASIC-128',E7=BASIC-48'
; E8=RAM0, E9=RAM1, EA=RAM2, EB=SYS0, EC=CASH
; ED,EE - reserv, EF=SYS1
; C0=COPY_1FFD, C1=COPY_7FFD, C2=COPY_BRD, C3-reserv
; C4-reserv, C5=COPY_V_MODE, C6=COPY_SYS, C7-reserv
; C8..CF - альтернативный набор для C0..C7
; D0..DF-reserv - доп. страницы для Pentagon-512
; 80..BF-user_ports!
; 00..7F-внешние порты, использовать не рекомендуется
LD B,port_data ; данные, записываемые во внутренний порт
LD C,#F8 ; номер функции
RST ToBIOS ; B - предыдущее содержание порта
;
; [x] 26/01/2024 добавлена.
READ_PORTS: ; глобальное чтение портов
LD A,port_num ; внутренний номер порта
LD C,#F9 ; номер функции
RST ToBIOS ; B - содержание порта
;
; [x] 26/01/2024 процедура дублирует функционал SET_PORTS. Убрана.
;WRITE_PORTS: ; глобальная запись портов
; LD A,port_num ; внутренний номер порта
; LD B,data_port ; записываемые данные
; LD C,#FA ; номер функции
; RST ToBIOS ;
;;;
CMOS_RD: ; читать из регистра CMOS
LD D,cmos_reg ; номер регистра CMOS
LD C,#F6 ; номер функции
RST ToBIOS ; NC - часы есть
; CF - часов нет
; A - значение ячейки
;
CMOS_WR: ; писать в регистр CMOS
LD D,cmos_reg ; номер регистра CMOS
LD A,Value ; значение
LD C,#F7 ; номер функции
RST ToBIOS ; NC - часы есть
; CF - часов нет
; Функции CMOS_RD,CMOS_WR работают всегда. Если в машине нет микросхемы CMOS,
; она эмулируется. Наличие микросхемы определяется функцией CMOS_TEST.
;
CMOS_TEST: ; проверить наличие CMOS
LD C,#F5 ; номер функции
RST ToBIOS ; NC - часы есть
; CF - часов нет
;
FN_TURBO: ; функция управления турбо режимом и плотностью ВГ93
LD A,turbo_mode; режим турбо: 2 - off, 3 - on
; плотность ВГ93: 18 - 720, 19 - 1440
LD C,#8F ; номер функции
RST ToBIOS ; NC -> исполнение
; CF -> неверный режим турбо
; * переключение режима турбо может не произойти, если прошивка не
; поддерживает это переключение. При этом ошибки не происходит.
;
;==============================================================================
; 5. Функции печати и управления режимом экрана.
;==============================================================================
;!TODO Графические функции
;-----------------------;
;PIC_FN0 ; #A0 ОТКРЫТИЕ ОКНА
;PIC_FN1 ; #A1 ВЫВЕСТИ ТОЧКУ
;PIC_FN2 ; #A2 ВЫВОД ЛИНИИ COPY
;PIC_FN3 ; #A3 ВЫВОД ЛИНИИ FILL
;PIC_FN4 ; #A4 ВЫВОД ПАЛИТРЫ ;!FIXIT установка палитры
;PIC_FN5 ; #A5 УСТАНОВКА SCREEN_SWITCH
;PIC_FN6 ; #A6 A - page_pal, E - номер палитры, B - тип палитры
;PIC_FN7 ; #A7 Рисование линии одного цвета
;PIC_FN8 ; #A8 Рисование разноцветной линии
;-----------------------;
WIN_OPEN: ; функция открытия окна.
LD IX,win_descriptor ; описатель окна
; IX - 32-хбайтовый описатель окна
; (IX+0) - горизонтальный размер окна в знакоместах
; (IX+1) - вертикальный размер в знакоместах
; (IX+2) - положение окна по горизонтали на экране
; (IX+3) - положение окна по вертикали на экране
; (IX+4) - режим знакоместа
; bit4=1 - text_mode bit4=0 - graf_mode
; bit5=0 - 16, bit5=1 - 8 точек в знакоместе
; graf_mode
; bit7..6 - номер палитры
; bit3..0 - не существенны
; text_mode
; bit7..6,3..0 - номер знакогенератора
; исключение: bit7..6=B"11" -> бордер
; (IX+5) - дополнительный режим знакоместа
; bit0=1 - указывает на включение спектрумовской
; адресации экрана
; (IX+6) - положение по X в поле графики (по знакоместам)
; (IX+7) - положение по Y в поле графики (по знакоместам)
; разъяснения о положении в поле графики - ниже
; (IX+8..31) - зарезервировано (переменные окна)
LD E,win_flag ; флаги окна:
; бит 0 - указывает какую страницу режима включать
; после исполнения функции. bit0=0 - экран 0, bit0=1 - экран 1
; бит 4 - указывает на какой странице режима
; открывать окно. bit4=1 - экран 0, bit4=0 - экран 1
;LD HL,win_place ; HL - место на экране по знакоместам (копия в IX+2,3),
; в новых версиях биоса значение HL не существенно
LD C,#B0 ; номер функции
RST ToBIOS ; NC -> A - номер окна
; CF -> ошибка слишком много окон
LD (id_win),A ; сохранить идентификатор окна
; * При открытии окна описатель копируется в системную страницу ОЗУ и
; программа может не сохранять его.
; ** В данный момент идентификатор окна всегда равен 0
; Видео-ОЗУ Спринтера можно представить как одно сплошное поле графики
; размером 1024 точки по горизонтали на 256 точек по вертикали
; Положение в поле графики показывает где будет находиться в этом поле
; верхний левый угол окна. Положение исчисляется в знакоместах. Т.е.
; Если указано положение по X - 2, по Y - 6, это означает, что верхний угол
; окна будет расположен по координатам X=16, Y=48 в поле графики видео-ОЗУ
; Таким образом, если, например, открыть два окна в разных местах, но с
; одинаковыми координатами в поле графики, на экране окажутся два
; идентичных окна, данные в которые будут попадать одновременно.
; Знакогенераторы текстовых режимов так же располагаются в видео-ОЗУ и
; имеют конкретные адреса в поле графики. При необходимости иметь на экране
; как графическое, так и текстовое изображение надо следить, что бы
; данные графических окон не попадали в поле графики, где расположены
; знакогенераторы
; При использовании какого либо знакогенератора, он занимает часть поля
; графики по координатам
; (координаты в знакоместах, т.е. в значениях байта IX+6 описателя окна)
; X = (8 * ( bit3..0 режима ))..(8 * ( bit3..0 режима ) + 7)
; По Y занимаются все положения.
; Таким образом, при использовании нескольких знакогенераторов сначала
; следует использовать знакогенераторы с номерами меняющимися в Bit7..6,
; так как они попадают в одни и те же координаты поля графики
; При открытии графических окон следует помнить, что в этот момент
; информация текстового экрана находящаяся в этом месте будет утеряна.
; При открытии текстового окна изменяется информация только в поле графики
; знакогенератора соответствующему этому текствовому экрану. Если эта
; информация и информация графического окна не пересекались, то при
; повторном открытии графического экрана, на нем автоматически
; восстановится графическая картинка
;
WIN_CLOSE: ; закрытие окна
LD A,(id_win) ; идентификатор окна (пока должен быть 0)
LD C,#B1 ; номер функции
RST ToBIOS ; NC -> успешное завершение
; CF -> ошибка - неверный идентификатор
; Окно с номером 0 никогда не закрывается и попытка
; закрытия приводит к ошибке
LP_OPEN_S: ; Открытие стандартных окон.
LD E,win_flag ; флаги окна
; bit 0 определяет страницу режима, которая будет
; открыта после исполнения функции
LD B,win_type ; тип открываемого окна:
; 0 - спектрумовское окно 32x24
; 1 - текстовое окно 64x24
; 2 - текстовое окно 40x32
; 3 - текстовое окно 80x32
; 4 - спектрумовское окно, HL - положение окна
; 5 - текстовое окно 64x24, HL - положение окна
; 6 - текстовое окно 40x32, HL - положение окна
; 7 - текстовое окно 80x32, HL - положение окна
; 8 - графическое окно 0, HL - положение окна
; 9 - графическое окно 1, HL - положение окна
LD HL,win_place; положение окна для 4..9 типов
LD C,#80 ; номер функции
RST ToBIOS ; выполнить функцию
; ** Функция старая, использовать не рекомендуется.
; Далее, в функциях запоминания, восстановления, перемещения и стирания
; подразумеваются локальные окна в смысле "окно в окне". Идентификатор окна
; относится к глобальному окну, отнисительно которого адресуются локальные
;
WIN_COPY: ; копирование данных текстового окна в память
; запоминание окна
LD A,(id_win) ; идентификатор глобального окна (пока должен быть 0)
LD H,ver_size ; HL - размер локального окна вертикаль/горизонталь
LD L,hor_size ; размер в символах
LD D,ver_place ; DE - положение локального окна в глобальном окне
LD E,hor_place ; положение по горизонтали в символах
LD IX,bufer ; адрес буфера для запоминания данных локального окна. (для режиима 80x32)
LD B,bufer_page; страница буфера данных окна (только SLOT3 или SLOT2)
; адрес буфера указывается для окна #C000
; если адрес указан с #8000, номер страницы буфера
; не действителен
LD C,#B2 ; номер функции
RST ToBIOS ; NC -> нормальное завершение
; CF -> ошибка - неверный идентификатор окна
; при работе этой функции через RST #18 или RST 8, обязательна установка
; DI, так как функция пользуется стеком для ускорения своей работы.
;
WIN_RESTORE: ; копирование данных из памяти в текстовое окно
; восстановление окна
LD A,(id_win) ; идентификатор глобального окна (пока должен быть 0)
LD H,ver_size ; HL - размер локального окна вертикаль/горизонталь
LD L,hor_size ; размер в символах
LD D,ver_place ; DE - положение локального окна
LD E,hor_place ; положение по горизонтали в символах
LD IX,bufer ; адрес буфера данных для локального окна
LD B,bufer_page; страница буфера данных окна (только SLOT3 или SLOT2)
; адрес буфера указывается для окна #C000
; если адрес указан с #8000, номер страницы буфера
; не действителен.
LD C,#B3 ; номер функции
RST ToBIOS ; NC -> нормальное завершение
; CF -> ошибка - неверный идентификатор окна
; при работе этой функции через RST #18 или RST 8, обязательна установка
; DI, так как функция пользуется стеком для ускорения работы.
; Данные для функций WIN_COPY_WIN и WIN_RESTORE_WIN имеют одинаковую
; структуру В данный момент эта структура похожа на структуру текстового
; экрана IBM, т.е. данные идут в формате sym1,atr1,sym2,atr2,.. сплошным
; массивом. Сначала данные для первой строки, затем сразу для второй и т.д.
WIN_GET_SYM: ; взять символ с экрана
LD A,(id_win) ; идентификатор окна (пока должен быть 0)
LD DE,place ; положение символа: D - вертикаль, E - горизонталь
LD C,#B4 ; номер функции
RST ToBIOS ; NC -> нормальное завершение
; L - символ, H - атрибут, B - знакогенератор
; CF -> ошибка неверный идентификатор окна
;
WIN_PUT_SYM: ; положить символ на экран
LD A,(id_win) ; идентификатор окна (пока должен быть 0)
LD DE,place ; положение символа: D - вертикаль, E - горизонталь
LD B,sym_zg ; знакогенератор
LD L,symbol ; символ
LD H,atribute ; атрибут символа
LD C,#B5 ; номер функции
RST ToBIOS ; NC -> нормальное завершение
; CF -> ошибка неверный идентификатор окна
;
;
WIN_GET_ZG: ; получить знакогенератор
LD DE,zg_buff ; указатель на 2Kb буфер для знакогенератора
LD C,#B8 ; номер функции
RST ToBIOS ; NC -> завершение
;
;
WIN_SET_ZG: ; установка знакогенератора
LD A,sym_zg ; системный номер знакогенератора
LD DE,zg_form ; указатель на 2Kb данных знакогенератора
; Данные знакогенератора должны располагаться в таком виде, в каком они
; выглядели бы как набор символов на спектрумовском экране при переносе 2Kb
; LDIR-om в адрес #4000
; * В будущем возможно изменение этого расположения на обычное
LD C,#B6 ; номер функции
RST ToBIOS ; NC -> завершение
; CF -> ошибка (старая версия, нет функции)
;
WIN_MOVE: ; перемещение окна (Внимание! использует как буфер страницу #FF)
LD A,(id_win) ; идентификатор глобального окна (пока должен быть 0)
LD H,ver_size ; HL - размер локального окна вертикаль/горизонталь
LD L,hor_size ; размер в символах
LD D,ver_place ; DE - положение локального окна
LD E,hor_place ; положение по горизонтали в символах
LD IX,new_place; новое положение локального окна
LD C,#B7 ; номер функции
RST ToBIOS ; NC -> нормальное завершение
; CF -> ошибка - неверный идентификатор окна
; при работе этой функции через RST #18 или RST 8, обязательна установка
; DI, так как функция пользуется стеком для ускорения работы.
; Даллее следуют функции печати для работы с _текущим_ глобальным окном.
; В данный момент текущим всегда является последнее открытое окно
; На графическом экране функция не работает
;
LP_PRINT_ALL: ; печать символов с атрибутом
LD A,symbol ; символ
LD E,atribute ; атрибут
LD B,num_sym ; число выводимых символов
LD C,#81 ; номер функции
RST ToBIOS ; на экран выводится строка из B одинаковых
; символов
; регистры HL,IX - сохраняются
;
LP_PRINT_SYM: ; Вывод символов на экран с текущего
; знакоместа без атрибута
LD A,symbol ; символ
LD B,num_sym ; число выводимых символов
LD C,#82 ; номер функции
RST ToBIOS ; на экран выводится строка из B одинаковых символов
; атрибут остается тот, который был на экране
; регистры HL,IX - сохраняются
;
LP_PRINT_ATR: ; печать атрибутов
LD E,atribute ; атрибут
LD B,num_sym ; число выводимых символов
LD C,#83 ; номер функции
RST ToBIOS ; на экран выводится строка из B одинаковых
; атрибутов. Символы не меняются.
; регистры HL,IX - сохраняются
;
LP_SET_PLACE: ; Установка текущего знакоместа в окне
LD E,hor_place ; номер символа по горизонтали
LD D,ver_place ; номер символа по вертикали
; ** Превышение границ приводит не к ошибке, а к
; переустановке сначала, за вычетом полного
; размера окна
LD C,#84 ; номер функции
RST ToBIOS ; позиция печати устанавливается в соответстии с
; регистром DE
; портятся только альтернативные регистры и те,
; что как параметры на входе
LP_PRINT_LINE: ; Вывод строки символов на экран с текущего
; знакоместа
LD HL,line_adr ; адрес строки. Должен быть между #4000 и #BFFF
LD E,atribute ; атрибут, с которым будет выведена строка
LD B,num_sym ; длина выводимой строки
LD C,#85 ; номер функции
RST ToBIOS ; "исполнение желаний"
;
LP_PRINT_LINE2: ; Вывод строки символов на экран с текущего
; знакоместа без атрибутов
LD HL,line_adr ; адрес строки. Должен быть между #4000 и #BFFF
LD B,num_sym ; длина выводимой строки
LD C,#86 ; номер функции
RST ToBIOS ; строка будет выведена без изменения атрибутов в
; месте печати
;
LP_PRINT_LINE3: ; Вывод строки символов длиной B на экран с текущего
; знакоместа до разделителя D. После разделителя
; выводятся пробелы что бы вывести B символов.
LD HL,line_adr ; адрес строки. Должен быть между #4000 и #BFFF
LD E,atribute ; атрибут, с которым будет выведена строка
LD D,delimiter ; разделитель
LD B,num_sym ; длина выводимой строки
LD C,#87 ; номер функции
RST ToBIOS ; символы из (HL) выводятся на экран, пока не
; встретится символ равный D, далее печатаются
; пробелы, как дополнение строки до B символов
;
LP_PRINT_LINE4: ; Вывод строки символов длиной B на экран с текущего
; знакоместа до разделителя D. После разделителя
; выводятся пробелы что бы вывести B символов.
; Без атрибутов.
LD HL,line_adr ; адрес строки. Должен быть между #4000 и #BFFF
LD D,delimiter ; разделитель
LD B,num_sym ; длина выводимой строки
LD C,#88 ; номер функции
RST ToBIOS ; символы из (HL) выводятся на экран, пока не
; встретится символ равный D, далее печатаются
; пробелы, как дополнение строки до B символов
; атрибуты не изменяются
;
LP_CLS_WIN: ; очистка экрана
LD DE,place ; положение локального окна (глобальное = текущее)
LD H,ver_size ; HL - размер локального окна вертикаль/горизонталь
LD L,hor_size ; размер в символах
LD B,atribute ; атрибут очистки
LD C,#89 ; номер фунции
RST ToBIOS ; выполнение. Произворится выводом пробелов с
; заданным атрибутом
;
LP_SCROLL_UD: ; Скроллинг части глобального окна вверх/вниз
LD B,scrollType; тип скроллинга 1 - вверх/ 2 - вниз
LD D,beg_line ; начальная строка скроллинга
LD E,num_lines ; число скроллируемых строк
LD C,#8A ; номер функции
RST ToBIOS ; выполнение. Скроллируются полные строки
; глобального окна
;
LP_PRINT_LINE5: ; Вывод строки символов на экран с текущего
; знакоместа до разделителя после разделителя
; вывод останавливается
LD HL,line_adr ; адрес строки. Должен быть между #4000 и #BFFF
LD D,stop_symb ; символ конца строки
LD E,atribute ; атрибут, с которым будет выведена строка
LD B,num_sym ; максимальная длина выводимой строки
LD C,#8B ; номер функции
RST ToBIOS ; символы из (HL) выводятся на экран, пока не
; встретится символ равный D или количество
; символов не превысило B. Далее происходит
; возврат
;
LP_PRINT_LINE6: ; Вывод строки символов на экран с текущего
; знакоместа до разделителя после разделителя
; вывод останавливается, без атрибутов
LD HL,line_adr ; адрес строки. Должен быть между #4000 и #BFFF
LD D,stop_symb ; символ конца строки
LD B,num_sym ; максимальная длина выводимой строки
LD C,#8C ; номер функции
RST ToBIOS ; символы из (HL) выводятся на экран, пока не
; встретится символ равный D или количество
; символов не превысило B. Далее происходит
; возврат. Атрибуты не выводятся
;
; HL -> адрес следующий после конца строки
;
LP_CLS_WIN2: ; очистка экрана, указанием символа заполнения
LD DE,place ; положение локального окна (глобальное = текущее)
LD H,ver_size ; HL - размер локального окна вертикаль/горизонталь
LD L,hor_size ; размер в символах
LD A,symbol ; символ очистки
LD B,atribute ; атрибут очистки
LD C,#8D ; номер фунции
RST ToBIOS ; Выполнение. Произворится выводом пробелов с
; заданным атрибутом и символом
;
LP_GET_PLACE: ; получить текущее положение вывода на экран
; в глобальном окне
LD C,#8E ; номер функции
RST ToBIOS ; в регистр DE будут положены координаты,
; в которых будет напечатан следующий символ
; D - вертикаль, E - горизонталь
;
LP_PR_LINE_DIR ;!TODO недоделана. Печать "в консоль" строки до
; разделителя с автоскроллом и с учётом управляющих
; символов: BELL, Backspace, TAB, CR, LF, FF, VT.
LD DE,place ; положение символа в окне
LD HL,text ; строка для печати. должна находиться в банках 1..2
LD B,delimiter ; разделитель
LD C,#E0 ; номер фунции
RST ToBIOS ; Выполнение.
;..............................................................................
; Графические функции
; координаты считаются от верхнего левого угла экрана
;..............................................................................
PIC_POINT: ; установить точку
LD DE,Y_coord ; координата по вертикали
LD HL,X_coord ; координата по горизонтали
LD A,(id_win) ; идентификатор граф. окна (пока должен быть 0)
LD B,color ; цвет точки
LD C,#A1 ; номер функции
RST ToBIOS ; поставить точку
; В действительности ставить точки на экране с помощью функции биоса,
; слишком медленно. Для этого лучше пользоваться прямым выводом данных
; на графический экран. Устройство экрана и способы прямого вывода
; графических данных описаны в файле архитектуры Спринтера.
;
PIC_SET_PAL: ; установка палитры
LD HL,pal_data ; данные палитры:
; список цветов по четыре байта B,G,R,Y
LD E,beg_color ; начальный цвет
LD D,num_colors; количество устанавливаемых цветов
LD B,pal_mask ; маска при установке палитры. Для нормального
; режима должнa быть FF
LD A,page_pal ; номер палитры (0..15, 8..15 резервные)
LD C,#A4 ; номер функции
RST ToBIOS ; установка палитры
; данные палитры должны представлять собой список приблизительно такого вида:
DB blue1,green1,red1,0
DB blue2,green2,red2,0
;.....................
DB blueN,greenN,redN,0
; N = num_colors. Значение num_colors равное 0 соответствует 256-ти цветам
; при записи в видео-ОЗУ все данные предварительно проходят функцию AND со
; значением pal_mask
; Страницы палитры 0..3 соответствуют графическим режимам. Для вывода в
; соответствующей палитре нужно задать соответствующее значение bit7..6 в
; байте режима знакоместа
; Страницы 4..7 соответствуют текстовому режиму и режиму "Спектрум"
; В странице 4 задается цвет paper для каждого атрибута. В странице 5
; задается цвет ink для каждого атрибута.
; В странице 6 задается цвет paper, которым он будет моргать в режиме flash
; В странице 7 задается цвет ink, которым он будет моргать в режиме flash
; Таким образом, для каждого из 256-ти атрибутов задается четыре цвета
; если цвета 4,5 совпадают с цветами 6,7 то режим flash оказывается
; отключенным. Для его включения в спектрумовском режиме надо поменять
; местами цвета 6 и 7. Если надо включить flash в режим IBM-CGA, следует
; установить цвета 6 и 7 одинаковыми и равными цвету 4
; по сути режим flash всегда включен и на экране постоянно меняются цвета
; paper с 4-го на 6-й, а цвета ink с 5 на 7-й. Если эти пары цветов для
; атрибута знакоместа устанавливаются одинаковыми, то flash в этом месте
; не виден.
; Используя подобное задание цветов текстового режима можно легко добиться
; совместимости по цветам как со Спектрумом, так и с IBM
;
;[x] новое?
PIC_GET_PAL: ; получение установленной палитры
LD HL,pal_data ; буфер для палитры:
; список цветов по четыре байта B,G,R,Y
LD E,beg_color ; начальный цвет
LD D,num_colors; количество цветов
LD A,page_pal ; #80 + номер палитры (0..15, 8..15 резервные)
LD C,#A4 ; номер функции (такой же как и для PIC_SET_PAL)
RST ToBIOS ; получение палитры
;
SET_PAL_INIT: ; установка внутренней палитры.
LD A,PAL_PAGE ; страница палитры (для графической)
LD E,PAL_N ; номер палитры (для графической)
LD B,type ; 3 - установка CGA палитры
; 2 - установка спектрумовской палитры
; 1 - установка графической палитры
LD C,#A6 ; номер функции
RST ToBIOS ; установка палитры
;==============================================================================
; Функции работы с винчестером разделяются на две группы:
; 1. функции с номeрами #4x работают в более простом режиме и
; используются в TR-DOS. Эти функции находят только один
; винчестер и работают только с его первым разделом. Если есть
; master, то функции используют его, если master-а нет, то
; определяется slave, если нет ни того ни другого, выдается ошибка.
; Функцию подготовки #43 не требуется исполнять перед
; операциями #44, #45 и #46!
; При исполнении функции 43h производится вся подготовка к
; операциям чтения/записи вычисление цилиндров/головок/секторов и
; занесение их в регистры винчестера далее программа может сама
; только подать команду читать/писать и самостоятельно производить
; считывание/запись данных в винчестер. Команда удобна для работы
; программ в реальном времени, когда необходимо кроме
; чтения/записи данных производить какие либо иные действия.
; Страница буфера для функций #44..#46 имеет значение только при
; попадании адресов чтения/записи в диапазон #C000..#FFFF. Кроме
; того, при попадании межсекторного промежутка на адрес 0 при
; наличии несчитанных/незаписанных секторов, производится
; автоматическое переключение страницы ОЗУ по RAM Allocation Table
; и продолжение чтения/записи с адреса #C000, что позволяет
; непрерывно писать/читать до 128kb прямо в выделенный блок ОЗУ.
; 2. Функции с номерами #5x более сложны, используются в Estex и
; работают с обоими винчестерами, со всеми разделами, а так же с
; дисководами, RAM-Disk-ами и CD-ROM-ами.
; В этих функциях в регистре A обычно задается номер и тип
; устройства:
; бит 0..3 - номер устройства
; бит 4..7 - тип устройства:
; 0 - дисковод
; 6 - ram-disk
; 8 - HDD
; C - CD-ROM
; остальные номера резервные
; А так же задаются страшая часть номера сектора в регисте HL,
; младшая часть номера сектора в регистре IX. Обратить внимание,
; на другой порядок расположения абсолютного номера сектора в
; регистрах HL и IX по сравнению с фунциями #4x!
;==============================================================================
; 6. Работа с винчестером и дисками MS-DOS. Функции 4x
;==============================================================================
; [x] 27/01/2024 адаптирована для корректной работы с FN_HDD_PART
HDD_INIT: ; инициализация винчестера. Портит значение PORT_Y
LD C,#40 ; номер функции
RST ToBIOS ; NC -> нормальное завершение
; CF -> винчестер не найден
;
; !FIXIT пока работает только с одним каналом (по-старому)
HDD_RECAL: ; рекалибровка винчестера
LD C,#41 ; номер функции
; * Функция зарезервирована для дальнейшего использования ; !TODO
;
; [x] 28/01/2024 работает со всеми каналами IDE и Master/Slave
HDD_TEST_IDE: ; Тест наличия интерфейса IDE
LD C,#42 ; номер функции
RST ToBIOS ; NC -> нормальние завершение
; в регистре B информация о наличии устройств
; bit0=1 - есть устройство "Primary master"
; bit1=1 - есть устройство "Primary slave"
; bit2=1 - есть устройство "Secondary slave"
; bit3=1 - есть устройство "Secondary slave"
; CF -> ошибка, аппаратная неисправность
;
HDD_PREPARE: ; подготовка винчестера к операции чтения/записи
LD A,bufer_page; страница буфера, если адрес в окне #C000
LD IX,sec_high ; абсолютный номер сектора старшая часть
LD DE,sec_low ; абсолютный номер сектора младшая часть
LD HL,bufer_adr; адрес буфера данных
LD B,sec_num ; число секторов
LD C,#43 ; номер функции
RST ToBIOS ; При исполнении производится вся подготовка к
; операциям чтения/записи вычисление
; цилиндров/головок/секторов и занесение их в регистры винчестера
; далее программа может сама только подать команду читать/писать и
; самостоятельно производить считывание/запись данных в винчестер.
; Команда удобна для работы программ в реальном времени, когда необходимо
; кроме чтения/записи данных производить какие либо иные действия.
; На выходе в окне 3 стоит страница из A если H >= #С0.
; Остаётся только начать читать с портов HDD
;
; [x] 27/01/2024 теперь работает с любым разделом HDD
HDD_READ_BPB: ; читать BPB. Портит значение PORT_Y
LD C,#44 ; номер функции
LD HL,bufer_adr; адрес буфера для BPB
LD A,bufer_page; страница буфера, если адрес в окне #C000
RST ToBIOS ; NC -> нормальное завершение
; CF -> ошибка
;
HDD_READ: ; читать сектора с винчестера. Портит значение PORT_Y
LD A,bufer_page; страница буфера, если адрес в окне #C000
; в A может быть BlockID, тогда будет читаться далее
; в следующие страницы с адреса #C000
LD IX,sec_high ; абсолютный номер сектора старшая часть
LD DE,sec_low ; абсолютный номер сектора младшая часть
LD HL,bufer_adr; адрес буфера данных
LD B,sec_num ; число читаемых секторов
LD C,#45 ; номер команды
RST ToBIOS ; NC -> нормальное завершение
; CF -> ошибка
; ** При попадании межсекторного промежутка на адрес 0
; производится автоматическое переключение страницы ОЗУ по
; RAM Allocation Table.
;
HDD_WRITE: ; писать сектора на винчестер
LD A,bufer_page; страница буфера, если адрес в окне #C000
LD HL,bufer_adr; адрес буфера данных
LD B,sec_num ; число записываемых секторов
LD DE,sec_low ; абсолютный номер сектора младшая часть
LD IX,sec_high ; абсолютный номер сектора старшая часть
LD C,#46 ; номер команды
RST ToBIOS ; NC -> нормальное завершение
; CF -> ошибка
; ** При попадании межсекторного промежутка на адрес 0
; производится автоматическое переключение страницы ОЗУ по RAM
; Allocation Table.
;
; !FIXIT использовать в HDD_TO_DRV
; [x] 07/01/2024
HDD_PART: ; настройка канала IDE, master/slave, раздела HDD. Портит значение PORT_Y
LD A,hdd_part ; bit0 - master/slave, bit1: Primary/Secondary, bit2..3: использующийся раздел в MBR
LD C,#47
RST ToBIOS
;
HDD_READ_NEXT: ; Читать следующий сектор (только LBA!). Портит значение PORT_Y
LD A,bufer_page; страница буфера, если адрес в окне #C000
LD B,sec_num ; число читаемых секторов
LD HL,bufer_adr; адрес буфера данных
LD DE,add_par ; прибавляется к номеру предыдущего прочитанного сектора
LD C,#48 ; номер команды
RST ToBIOS ; NC -> нормальное завершение
; CF -> ошибка
;
;==============================================================================
; 7. Работа с винчестером и дисками MS-DOS. Функции 5x
;==============================================================================
; !TODO
LD C,#50 ; зарезервирована
;
DRV_RESET: ; Сброс контроллера и настройка на диск
LD A,drv_type ; бит 0..3 - номер устройства
; бит 4..7 - тип устройства
; 0 - дисковод
; 6 - ram-disk
; 8 - HDD
; C - CD-ROM
; остальные номера резервные
LD C,#51 ;
RST ToBIOS ; NC - нормальное завершение
; CF - нет диска или нет устройства
;
DRV_READ_LONG: ; чтение с устройства
LD A,drv_type ; бит 0..3 - номер устройства
; бит 4..7 - тип устройства
; 0 - дисковод
; 6 - ram-disk
; 8 - HDD
; C - CD-ROM
EX AF,AF' ;
LD A,Mem_BLK ; страница, куда читать если буфер в SLOT3
EX AF,AF' ;
LD HL,sec_h ; старшая часть номера сектора
LD IX,sec_l ; младшая часть номера сектора
LD B,n_sec ; количество секторов
LD DE,bufer_adr; адрес буфер для чтения
LD C,#52 ;
RST ToBIOS ; NC - нормальное завершение
; CF - ошибка чтения или нет устройства
;
; !TODO расписать
DRV_WRITE_LONG:
LD C,#53 ; Long write
;
DRV_VERIFY: ; проверка секторов
LD A,drv_type ; бит 0..3 - номер устройства
; бит 4..7 - тип устройства
; 0 - дисковод
; 6 - ram-disk ; !FIXIT
; 8 - HDD
; C - CD-ROM
LD HL,sec_h ; страшая часть номера сектора
LD IX,sec_l ; младшая часть номера сектора
LD B,n_sec ; количество секторов
LD C,#54 ;
RST ToBIOS ; NC - нормальное завершение
; CF - проверка с ошибкой или нет устройства
;
DRV_READ: ; чтение с устройства
LD A,drv_type ; бит 0..3 - номер устройства
; бит 4..7 - тип устройства
; 0 - дисковод
; 6 - ram-disk
; 8 - HDD
; C - CD-ROM
LD HL,sec_h ; старшая часть номера сектора
LD IX,sec_l ; младшая часть номера сектора
LD B,n_sec ; количество секторов
LD DE,bufer_adr; адрес буфер для чтения
LD C,#55 ;
RST ToBIOS ; NC - нормальное завершение
; CF - ошибка чтения или нет устройства
;
DRV_WRITE: ; запись на устройства
LD A,drv_type ; бит 0..3 - номер устройства
; бит 4..7 - тип устройства
; 0 - дисковод
; 6 - ram-disk
; 8 - HDD
; C - CD-ROM
LD HL,sec_h ; страшая часть номера сектора
LD IX,sec_l ; младшая часть номера сектора
LD B,n_sec ; количество секторов
LD DE,bufer_adr; адрес буфер для записи
LD C,#56 ;
RST ToBIOS ; NC - нормальное завершение
; CF - ошибка записи или нет устройства
;
DRV_DETECT: ; определение параметров устройства
LD A,drv_type ; бит 0..3 - номер устройства
; бит 4..7 - тип устройства
; 0 - дисковод
; 6 - ram-disk
; 8 - HDD
; C - CD-ROM
LD C,#57 ;
RST ToBIOS ; NC - нормальное завершение
; A - для FDD bit7: 720/1.44
; для HDD и CD: drive type
; CF - нет устройства или нет носителя
;
DRV_GET_PAR: ; получить параметры носителя
LD A,drv_type ; бит 0..3 - номер устройства
; бит 4..7 - тип устройства
; 0 - дисковод
; 6 - ram-disk
; 8 - HDD
; C - CD-ROM
LD C,#58 ;
RST ToBIOS ; NC - нормальное завершение
; L - число секторов (на целиндр)
; H - число головок
; DE - количество цилиндров
; IX - размер сектора в байтах
; B - доп. параметры:
; FDD: бит7 - тип 720/1.44
; HDD: бит0 - канал IDE 0/1
; бит6 - CHS/LBA
; RMD: ramdrive block id ; [x]
;
; если в HL,DE все FF - устройства нет
; CF - нет устройства
;
DRV_SET_PAR: ; установить параметры носителя
LD A,drv_type ; бит 0..3 - номер устройства
; бит 4..7 - тип устройства
; 0 - дисковод
; 6 - ram-disk
; 8 - HDD
; C - CD-ROM
LD L,n_secs ; L - число секторов (на целиндр)
LD H,n_heads ; H - число головок
LD DE,n_cyls ; DE - количество цилиндров
LD IX,sec_size ; IX - размер сектора в байтах
LD B,ext_par ; B - доп. параметры
; для дискет бит7 - тип 720/1.44
LD C,#59 ;
RST ToBIOS ; NC - нормальное завершение
;
DRV_VERSION: ; получить версию драйвера дисковой подсистемы
LD C,#5A ;
RST ToBIOS ; CF - старая версия BIOS
; NC - нормальное завершение
; DE - номер версии.
;
; !TODO
LD C,#5B ; зарезервирована
;
; !TODO
LD C,#5C ; зарезервирована
;
; !TODO
LD C,#5D ; зарезервирована
;
DRV_EXTENDED: ; расширенный набор подфункций, может отличаться для разных устройств
LD B,sub_func ; номер подфункции
LD C,#5E ; зарезервирована
RST ToBIOS ; NC - нормальное завершение
; Подфункции:
; Для CD-ROM:
; 0 - Eject
; 1 - Close tray
;
DRV_LIST: ; !TODO добавить описание и поддержку RAM DRIVE в этой функции
LD C,#5F ;
RST ToBIOS ;
;
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░;
;██████████████████████████████████████████████████████████████████████████████████████████████████████████████;