; 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 (старое поведение от Sp97) ; страница не может иметь номер больше 127 (старое поведение от Sp97) ; Файл прошивки, естественно должен быть уже ; загружен в эту страницу 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 ; ZX_MEMORY_MANAGER:; Выделение/освобождение/инит страниц спектрума ;вход: рег B: ; FN 0x ; 0 - зарезервировано ; 1 - выделение памяти Pentagon 48k. 3 страницы ; 2 - выделение памяти Pentagon 128k. 2+6 страницы ; 3 - выделение памяти Pentagon 512k. 2+30 страницы ; 4 - выделение памяти Scorpion 256k. 2+6+8 страницы ; 5..15 - зарезервированы ; FN 1x ; 16 - получить рамблоки инициализированных vROM и VRAM ; 17..31 - зарезервированы ; ; FN 2x..3x зарезервировано ;!TODO ; ; FN 4x ; 64 - освободить рамблоки vROM и vRAM ; 65 - освободить рамблок vRAM ; 66 - освободить рамблок vROM ; 65..127 - зарезервированы ; FN 8x ; 128 - инициализировать свой набор страниц vROM ; ; рег HL: при рег B[7]=1 адрес списка страниц (11 шт): ; byte1 - RAM block ID, byte2..11 - страницы для vROM - ZXSlot: 1,2,3(=0),расширенная ;выход: CF = 0: HL - номера рамблоков для режимов 0..16. H=vRAM, L=vROM ; CF = 1: A - номер ошибки ; ;если стэк находится в третьем слоте, то вызов с выключенными прерываниями LD C,#FC 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 ; Печать "в консоль" строки до разделителя с автоскроллом ; и с учётом управляющих символов: BELL, Backspace, TAB, CR, LF, FF, VT. .spets EQU spets1*256 + spets2 LD A,attrib ; атрибуты выводимого символа если CF' SCF ; XY-mode EX AF,AF' SCF ; выводить символ с атрибутами LD A,scroll ; если !=0 то без скролла EX AF,AF' LD HL,text ; строка для печати. должна находиться в банках 1..2 ;!TODO есть ограничение на банку? LD DE,place ; место символа в окне, если CF=1 LD IY,.spets ; два спец.символа для выхода с CF=1. Должны быть равны B, если не нужны LD B,color ; цвет консоли (используется при скролле и очистке окна) 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 - нормальное завершение: ; A' - последняя страница рамблока в которую читали ;!FIXIT пока только для ATA и ATAPI ; 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 ; B - для HDD и CD: ; bit0=1 removable, bit1=1 drive changed, bit7..2 reserved ; [ ] ; 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 - нормальное завершение ; [ ] A - HDD_INIT_TABLE.RemovableMedia ; L - число секторов (на целиндр) ; [ ] для ATAPI HL:DE - размер носителя в секторах ; H - число головок ; DE - количество цилиндров ; IX - размер сектора в байтах ; B - доп. параметры: ; FDD: бит7 - тип 720/1.44 ; IDE: бит0 - канал IDE 0/1 ; бит6 - CHS/LBA ; RMD: ramdrive block id ; [x] ; ; ATAPI: CF' = 1, A' = номер ошибки ; ; если в 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 ; для ATAPI только параметр B работает - установить HDD_INIT_TABLE.MediaParameters ; [ ] media changed 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 ; 2 - ATAPI_REQUEST_SENSE. ; вход: A' - страница буфера, если буфер в третьем слоте DRV_LIST: ; !TODO добавить описание и поддержку RAM DRIVE в этой функции LD C,#5F ; RST ToBIOS ; ; ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░; ;██████████████████████████████████████████████████████████████████████████████████████████████████████████████;