DEVICE ZXSPECTRUM128 INCLUDE "!AllConst.asm" INCLUDE "!ram8.asm" ORG #0000 ROMdisk equ #2500 ;#0000 *NOT USED* (#30 байт) ;#0030 rst #30 вызов процедуры из другого rom ;#0033 *NOT USED* (#05 байт) ;#0038 обработчик прерываний im 0/1 ;#0041 *NOT USED* (#25 байт) ;#0066 обработка NMI (зависание с желто-черным бордюром) ;#006F *NOT USED* (#01 байт) ;#0070 переменные ROM-disk ;#0073 загрузка блока из ROM-Disk ;не используется #00BF вероятно что-то для контроллера прерываний ;#00FF адрес п/п обработки прерываний im 2 ;#0101 номер текущего rom ;#0102 процедура обработки прерываний im 2 ;#010E вызов процедуры из другого rom ;не используется #0127 вызов процедуры из rom 2 call x0127: dw addr ;не используется #0146 работа с контроллером прерываний ;не используется #015F работа с контроллером прерываний ;не используется #0180 работа с контроллером прерываний ;не используется #018B работа с контроллером прерываний ;не используется #0193 работа с контроллером прерываний ;#01AF автостарт с дискеты ;#0229 вызов функции R8DOS ;#029C R8DOS #00(0) сброс контроллера ;#02BE код time-out ;без вызовов пока #02C8 уменьшение time-out на 1 для всех дисководов ;#02CA R8DOS #13(19) установка режима time-out для счетчика включения двигателя дисковода ;#02F6 проверка наличия диска в дисководе ;#0322 опрос Break и прерывание, если нажата ;#032B R8DOS #10(16) чтение/установка спецификации дискеты ;#0335 R8DOS #11(17) чтение кода спецификации дисковода ;#033A в hl адрес кода time-out для текущего дисковода ;#033F в hl адрес кода, определяющего номер дорожки в текущем дисководе ;#0344 в hl адрес кода, определяющего тип дискеты в текущем дисководе ;#0349 в hl адрес кода, определяющего тип текущего дисковода ;#0356 подготовка байта для выбора заданного дисковода ;#0366 проверка наличия образа в текущем дисководе ;#0394 проверка bit 7,(xFFDC) наличие подключенного образа к текущему дисководу ;#03A2 установка номера дорожки для позиционирования ;#03C5 R8DOS #01(1) выбор текущего дисковода ;#03E4 инициализация текущего дисковода при необходимости ;#042C позиционирование на заданную дорожку ;#0430 поиск дорожки ;#0434 поиск дорожки с проверкой ;#0438 выдача команды в порт #1F ВГ93 ;#0441 ожидание готовности ВГ93 ;#0457 R8DOS #02(2) позиционирование на заданный логический трек ;#04D1 ошибка. прерывание функции ;#0502 R8DOS #0E(14) физическое позиционирование на трек ;#0546 R8DOS #12(18) в hl адрес таблицы с количеством секторов на дорожке ;#054A ошибка. неверный номер сектора ;#054E R8DOS #04(4) повторить в случае ошибки функцию 5 (или 6) ;#0553 R8DOS #05(5) чтение группы секторов ;#0557 R8DOS #06(6) запись группы секторов ;#05D8 R8DOS #03(3) игнорирование ошибки и продолжение выполнения функции 5 (или 6) ;#0610 чтение сектора ;#063B чтение данных с дискеты в память ;#066B чтение сектора образа HDD в память ;#0694 чтение сектора с винчестера в буфер xEFF5 ;#06B4 запись сектора ;#0708 запись сектора на образ HDD ;#074C расчет смещения от начала образа в секторах (512b) ;#0768 чтение заголовка сектора с позиционированием на заданную дорожку ;#076D чтение заголовка сектора ;#077F R8DOS #0A(10) построение таблицы расположения секторов на дорожке, начиная от индексного маркера ;#0824 позиционирование на заданную дорожку c тайим-аутом ;#084F R8DOS #07(7) идентификация диска ;#08D4 R8DOS #08(8) идентификация диска для tr-dos ;#0922 R8DOS #09(9) установка рабочего буфера для функции 8 ;#092F вычисление размера таблицы секторов ;#0948 R8DOS #0B(11) форматирование дорожки ;#0B52 преобразование кода размера сектора в байтах в число ;#0B67 R8DOS #0F(15) замена идентификатора в таблице расположения секторов ;#0B94 R8DOS #0C(12) чтение дорожки ;#0B98 R8DOS #0D(13) запись дорожки ;#0C83 опрос Break. cy=1 не нажата ;#0C98 остановка контроллера ВГ93 ;#0CAD таблица адресоф функций R8DOS ;#0CFF установка переменных дисковой BIOS ;#0D51 определение наличия SMUC ;#0D62 определение наличия NVRAM ;#0DA5 cy=1, a=#01 !!!Not Used!!! ;#0DA9 cy=1, a=#02 !!!Not Used!!! ;#0DAD чтение всей памяти NVRAM в память #7530 ;#0DB6 чтение данных из NVRAM ;#0DC7 запись всей памяти NVRAM из памяти #7530 ;#0DD0 запись данных в NVRAM ;#0E72 что-то пишет в NVRAM ;#0F55 для сравнения чисел ;#0F59 для сравнения чисел ;#0F5D деление hl=dehl'/bc ;#0FB7 умножение dehl=de'hl' * bc ;#0FF3 инкремент dehl ;#1003 копирование из (hl) в (de) 4х байт ;#100F загрузка числа в регистры из памяти ;#101D сложение 4х байтного числа с двухбатным ;#1035 сравнение двух чисел в памяти по адресам в de и hl ;#1065 инициализация дисковода ;#107B инициализация дисковода и настройка на дискету ;#10A4 распознавание имени файла и занесение его в fcb ;#111E R8DOS #19(25) физический поиск файла, указанного в fcb, в каталоге диска ;#1125 R8DOS #1A(26) продолжает поиск файла, указанного в fcb. !!!ОШИБКА!!! маски, после первого поиска больше нету ;#114E загрузка дескриптора файла в буфер ;#1166 загрузка очередного дескриптора файла в буфер ;#11A7 получение адреса байта в буфере dma ;#11B0 R8DOS #1B(27) разбор спецификации файла и построение на ее основе блока управления (fcb) ;#11D4 открыть файл(для нужд монитора) для последующих операций с ним ;#11DB R8DOS #14(20) открыть файл для последующих операций с ним ;#11DF открыть файл для последующих операций с ним ;#1240 R8DOS #16(22) чтение очередного байта из файла. файл должен быть открыт как "логический". ;#128C R8DOS #17(23) запись байта в файл. Файл должен быть открыт как "логический" ;#12FF установка в fcb указателя в файле из bc ;#1307 R8DOS #15(21) закрыть файл, открытый функцией 20 ;#1360 R8DOS #1E(30) последовательное считывание заданного количества секторов ;#1365 R8DOS #1C(28) последовательное чтение очередного сектора из файла ;#1390 R8DOS #1F(31) последовательная запись заданного количества секторов ;#1395 R8DOS #1D(29) последовательная запись одного сектора из памяти ;#13D5 создание записи в каталоге диска (на основе fcb) ;#1405 установка нового значения указателя в файле ;#1407 R8DOS #20(32) установка нового значения указателя в файле ;#1472 чтение сектора в буфер dma ;#1484 сохранение буфера dma в файл ;#148D чтение секторов в буфер dma ;#1498 запись секторов из буфера dma ;#14A0 расчет адреса в файле на диске (дорожка и сектор) ;#14A6 расчет нового номера дорожки и сектора ;#14C0 R8DOS #18(24) удаление файла, адрес спецификации которого задан в регистрах hl ;#153D копирование дескриптора дисковода в буфер ;#1545 R8DOS #21(33) чтение из fcb в bc указателя файла ;#154C чтение из fcb в hl длины файла ;#1553 чтение из fcb в hl адреса буфера dma ;#155A чтение заголовка первого попавшегося сектора дисковода A ;#1567 чтение одного сектора нулевой дорожки в буфер (e - номер сектора) ;#1572 определение наличия interrupt controller ;#15C7 определение наличия последовательного порта/модема ;#16B9 работа с контроллером прерываний ;не используется #1738 работа с контроллером прерываний ;#1768 поиск раздела MFS ;#17BB чтение в буфер xEBF5 двух первых секторов раздела MFS/подраздела ;#17EF запись 2х секторов из буфера xEBF5 ;#1813 чтение сектора с винчестера ;#1829 запись сектора на винчестер ;#1848 расчет номера сектора на винчестере ;#187F R8DOS #23(35) подключение раздела к драйверу HDD ;#188A установка кода, определяющий тип дисковода без образа по номеру в С ;#189A подключить подраздел к драйверу (копирование дескриптора в рабочуюю область) ;#18C0 R8DOS #28(40) подключение раздела к драйверу HDD ;#1A0E расчет адреса кода, определяющие тип дисковода по номеру в С ;#1A19 завершение процедуры x18C0 R8DOS #28(40) ;#1A6A проверка совпадения имени ;#1A82 выделение из строки имени подраздела/образа (6 символов имя) ;#1A9F копирование имени подраздела/образа по адресу в de ;#1AB1 определение адреса начала записи для заданного дисковода в буфере xE5A9 ;#1ACC формирование текстовой строки - пути к примонтированному подразделу/образу ;#1B04 расчет адреса блока описателя заданного дисковода ;#1B18 установка признака подмонтированных дисков A/B в порту #7FBA ;#1B45 определение необходимости копирования памяти пользователя ;#1B54 сохранение описателя текущего дисковода в блоке xE9F5 (функция TR-DOS mirror) ;#1B7E R8DOS #24(36) прямое чтение секторов из подраздела жесткого диска ;#1BC0 R8DOS #25(37) прямая запись секторов в подраздел жесткого диска ;#1BFA ошибка #56. нет раздела MFS ;#1BFE R8DOS #26(38) Вернуть таблицу (каталог) подраздела ;#1C2D R8DOS #27(39) чтение/запись сектора (???ОШИБКА???) ;#1C70 бесконечное чтение порта bc ;#1C74 бесконечная запись в порт bc ;#1C78 загрузка в регистры кол-ва секторов, адреса LBA/CHS, типа устройства ;#1C86 чтение 512b данных в буфер адресуемый hl ;#1C98 запись 512b данных из буфер адресуемого hl ;#1CAC посылаем команду винчестеру ;#1CCA ожидание готовности HDD к передаче данных ;#1CE5 ожидание готовности HDD к принятию команды ;#1D04 ожидание готовности HDD ;#1D1B чтение сектора идентификации в буфер по адресу в ix ;#1D2A подсчет контрольной суммы и запись сектора из буфера xE5A9 на винчестер ;#1D45 запись сектора из буфера xE5A9 на винчестер по адресу в dehl ;#1D4A запись сектора из буфера ix на винчестер ;#1D4F запись сектора из буфера xE5A9 на винчестер ;#1D73 чтение сектора с винчестера в буфер xE5A9 ;#1D78 чтение сектора с винчестера в буфер ix ;#1D7D чтение сектора с винчестера в буфер xE5A9 ;#1DDF расчет и установка в переменных адреса LBA/CHS в зависимости от настроек ;#1E2A установка в переменных сектора номер 3 для винчестера ;#1E3D чтение сектора 3(сектор настроек) в буфер xE5A9 и проверка контрольной суммы ;#1E74 R8DOS #22(34) идентификация жесткого диска ;#1F08 проверка геометрии винчестера ;#1F2D расчет произведения головок и секторов ;#1F59 чтение ячейки CMOS ;#1F76 чтение из CMOS времени и даты, в случае готовности CMOS ;#1F8B проверка готовности CMOS ;#1F93 чтение из CMOS времени и даты ;#1FB2 запись в CMOS времени и даты ;#1FDD запись данных в ячейку CMOS ;#2010 запись в порт ;#2016 чтение порта ;#201C пауза 293t ;#2023 запись данных в ячейку CMOS. и запись контрольной суммы в ячейку #3F ;#2030 подсчет контрольной суммы CRC8 CMOS [#10..#3E] (#3F - контрольная сумма) ;#2047 определение наличия CMOS ;не используется #20EC работа с контроллером прерываний ??? ;#20F1 тестирование HDD (2. test) (тест на чтение/запись) ;#2105 тестирование HDD (1. test) (тест только на чтение) ;#21E5 подсчет контрольной суммы области памяти CRC16 ;#220F суммирование байта с контрольной суммой CMOS CRC8 ;#2222 данные для подсчета контрольной суммы ;#2223 данные для подсчета контрольной суммы ;#2422 определение наличия SMUC ;#2452 *** Not Used *** ;#2500 ROM-disk ;#3D00 ;#4000 ;АДРЕС: #0000 *NOT USED* (#30 байт) x0000 ds #30 ;АДРЕС: #0030 rst #30 вызов процедуры из другого rom x0030 jp x010E ;АДРЕС: #0033 *NOT USED* (#05 байт) x0033 ds #05 ;АДРЕС: #0038 обработчик прерываний im 0/1 x0038 push af ld a,#06 ld (#7530),a pop af ei ret ;АДРЕС: #0041 *NOT USED* (#25 байт) x0041 ds #25 ;АДРЕС: #0066 обработка NMI (зависание с желто-черным бордюром) x0066 ld a,#06 out (#FE),a xor a out (#FE),a jr x0066 ;АДРЕС: #006F *NOT USED* (#01 байт) x006F ds #01 ;АДРЕС: #0070 переменные ROM-disk x0070 db #25 ;смещение начала ром диска (в блоках по 256 байт) db #18 ;количество свободных секторов в странице db #00 ;=#00 каталог отсутсвует ;АДРЕС: #0073 загрузка блока из ROM-Disk INCLUDE "!RomDisk.asm" ;АДРЕС: #00AA *NOT USED* (#15 байт) x00AA ds #15 ;АДРЕС: #00BF вероятно что-то для контроллера прерываний x00BF db #93,#01 ds #04 db #8B,#01,#00,#CA,#00: jp x015F db #80,#01,#00,#D2,#00: jp x015F db #FB,#C9,#00,#DA,#00: jp x015F db #00,#00,#00,#E2,#00: jp x015F db #00,#00,#00,#EA,#00: jp x015F db #00,#00,#00,#F2,#00: jp x015F db #00,#00,#00,#FA,#00: jp x015F db #00,#00 ;АДРЕС: #00FF адрес п/п обработки прерываний im 2 x00FF dw x0102 ;АДРЕС: #0101 номер текущего rom x0101 db #07 ;АДРЕС: #0102 процедура обработки прерываний im 2 x0102 push hl ld a,#06 ld hl,x9C40 call x175D ;установка бордюра pop hl ei ret ;АДРЕС: #010E вызов процедуры из другого rom x010E push hl ld hl,(x0101) ex (sp),hl push hl ld hl,#0006 push af add hl,sp push de push bc ld e,(hl) inc hl ld d,(hl) ex de,hl ld c,(hl) inc hl ld b,(hl) inc hl ld a,(hl) jp xE3E9 ;АДРЕС: #0127 вызов процедуры из rom 2 call x0127: dw addr x0127 ld (xDE10),hl pop hl push de ld e,(hl) inc hl ld d,(hl) inc hl ex (sp),hl push hl ld hl,x0143 ;сюда вернемся ex (sp),hl push hl ld hl,xE42C ;п/п включения страницы для возврата ex (sp),hl ex de,hl push hl ld hl,(xDE10) jp xE478 ;включаем rom 2 x0143 inc sp x0144 inc sp ret ;АДРЕС: #0146 работа с контроллером прерываний x0146 ei nop push af push bc ld b,#0C call x1F59 ;чтение ячейки CMOS ld a,#02 ld (x7530),a ld bc,#7EBE ld a,#20 out (c),a pop bc pop af ei ret ;АДРЕС: #015F работа с контроллером прерываний x015F push af push bc ld b,#0C call x1F59 ;чтение ячейки CMOS ld a,#02 ld (#7530),a push hl ld a,#02 ld hl,#9C40 call x175D ;вызов процедуры из основной памяти pop hl ld bc,#7EBE ld a,#20 out (c),a pop bc pop af ei ret ;АДРЕС: #0180 работа с контроллером прерываний x0180 di halt push af ld a,#04 ld (#7530),a pop af ei ret ;АДРЕС: #018B работа с контроллером прерываний x018B push af ld a,#05 ld (#7530),a pop af ret ;АДРЕС: #0193 работа с контроллером прерываний x0193 push af push bc ld bc,#7EBE ld a,#0C out (c),a nop nop ld bc,#FFBA ld a,(xDFF0) and #F7 out (c),a ld (xDFF0),a pop bc pop af ei ret ;АДРЕС: #01AF автостарт с дискеты ;вх: 2-3,a =#11 -> вых: нажатие Enter и переход на rom 0: #259F ; =#10 -> вых: bc - длина бейсик-строки для автостарта ; =#0? -> вых: копирование строки автостарта по адресу в de и переход на rom 0: #1B11 x01AF ld a,(xDD7F+#01) ;регистр A пользователя and #0C cp #0C jr z,x01EC cp #08 jr z,x01E4 ;длина бейсик строки для дисковода автостарта ld hl,rom0_x1B11 ;п/п загрузки с диска ld (xDD6B),hl ;новый pc программы пользователя ld de,(xDD75) ;регистр de пользователя call x0207 ;bc - длина бейсик строки для автостарта ld hl,x0213 ldir ret z ;автостарт с дисковода A push af call x1B04 ;расчет адреса блока описателя заданного дисковода pop bc ;b - номер дисковода jr nz,x01D8 ;в дисководе образ диска res 1,b ;реальные диски только в дисководах A/B x01D8 ld a,"A" add a,b ld hl,(xDD75) ;регистр de пользователя ld de,#000F add hl,de ld (hl),a ;установим букву дисковода ret ;длина бейсик строки для дисковода автостарта x01E4 call x0207 ;bc - длина бейсик строки для автостарта ld (xDD77),bc ;регистр bc пользователя ret ;запуск с винчестера x01EC ld hl,rom0_x259F ld (xDD6B),hl ;новый pc программы пользователя bit 7,(iy+#1B) ret z ;проверка геометрии винчестера не пройдена bit 0,(iy+#1C) ret z ;autostart off ld a,#0D ld (#5C08),a ;код последней нажатой клавиши: enter ld hl,#5C3B set 5,(hl) ;устанавливается при нажатии на любую символьную клавишу ret ;вых: bc - длина бейсик строки для автостарта ; z - автостарт с дисковода A x0207 ld a,(iy-#23) ;номер диска автостарта or a ld bc,#000E ;для дисковода A ret z ld bc,#0016 ;для дисководов B/C/D ret x0213 db #F9 ;randomize db #C0 ;usr db #B0 ;val db '"15619"' ;"15619" db ":",#EA,":",#F7 ;:rem:run db '"A:boot"' ;АДРЕС: #0229 вызов функции R8DOS ;вх: c - номер функции x0229 push ix ld (xFFEF),a ld a,r push af ;сохраним флаг прерываний di ld a,c cp #14 jr nc,x0293 ld a,(xFFEF) ;для функций #00..#13 ld (xFFDE),sp push hl ld hl,xFFDC res 0,(hl) res 4,(iy+#0B) inc hl ld (hl),#FF ;код ошибки #FF ld hl,x0264 ;сюда вернемся x024E ex (sp),hl push hl push de ld l,c ld h,#00 add hl,hl ld de,x0CAD ;функции R8DOS add hl,de ld e,(hl) inc hl ld d,(hl) ex de,hl ;адрес п/п обработки заданной функции pop de ex (sp),hl ld ix,(xFFF0) ;!!!ОШИБКА, должно быть ld ix,(xDD6F) ret ;выход из функции по ошибке ;возврат из функций #00..#13 x0264 ld sp,(xFFDE) ;восстановим стэк ld (xFFEF),a ;временно сохраним регистр A push hl ld hl,xFFDC res 4,(hl) inc hl ld a,(hl) ;код ошибки cp #FF pop hl ex (sp),hl res 0,l ;сбросим флаг CY jr z,x027D ;нет ошибки x027B set 0,l ;установим флаг CY x027D ex (sp),hl pop af ld a,(xFFEF) ;восстановим A jp po,x0286 ;восстановим режим прерываний ei/di ei x0286 pop ix ret ;возврат из функций #14..#nn x0289 ld (xFFEF),a ex (sp),hl res 0,l ;сбросим флаг CY jr nc,x027D ;нет ошибки jr x027B ;была ошибка x0293 ld a,(xFFEF) ;для функций #14..#nn push hl ld hl,x0289 ;сюда вернемся jr x024E ;АДРЕС: #029C R8DOS #00(0) сброс контроллера x029C xor a call x033F ;hl адрес кода, определяющего номер дорожки в текущем дисководе ld (hl),a ;номер дорожки =#00 call x0394 ;bit 7,(xFFDC) ret nz ;к текущему дисководу подключен образ call x0C98 ;остановка контроллера ВГ93 out (#FF),a ;загрузка головки, сторона верхняя, метод записи call x0349 ;hl адрес кода, определяющего тип текущего дисковода ld a,(hl) and #03 ;скорость перемещения головки or #0C ;головку опустить, проверить номер дорожки out (#1F),a ;команда восстановления call x0441 ;ожидание готовности ВГ93 call x02F6 ;проверка наличия диска в дисководе in a,(#1F) ;читаем регистр состояния set 4,(hl) ;hl=xFFDC ;АДРЕС: #02BE код time-out ;вых: z код time-out текущего дисковода =#FF/#00 x02BE call x033A ;hl адрес кода time-out для текущего дисковода ld a,(hl) inc a ret z dec a ld (hl),#0A ret ;АДРЕС: #02C8 уменьшение time-out на 1 для всех дисководов ;вых: hl - адрес процедуры time-out x02C8 ld b,#00 ;АДРЕС: #02CA R8DOS #13(19) установка режима time-out для счетчика включения двигателя дисковода ;вх: b - байт установки time-out ; 3-0,b =0000 уменьшение time-out на 1 для всех дисководов ;вых: hl - адрес процедуры time-out x02CA ld hl,xFFD8 ;коды time-out для дисководов ld a,b and #0F jr nz,x02E3 ld b,#04 ;для всех дисководов x02D4 ld a,(hl) inc a jr z,x02DC ;(hl)=#FF dec a jr z,x02DC ;(hl)=#00 dec (hl) ;(hl)=(hl)-1 x02DC inc hl djnz x02D4 x02DF ld hl,x02C8 ret x02E3 ld a,b ld b,#04 x02E6 rra jr nc,x02F1 ;следующий дисковод ld c,#00 bit 3,a jr nz,x02F0 dec c x02F0 ld (hl),c ;#00/#FF x02F1 inc hl djnz x02E6 jr x02DF ;АДРЕС: #02F6 проверка наличия диска в дисководе x02F6 call x0322 ;опрос Break и прерывание, если нажата ld hl,xFFDC ld de,#0000 in a,(#1F) ;берем индексный сигнал для образца and #02 ld b,a call x0316 ;ждем изменения индексного сигнала ret nz ;индексный сигнал изменился call x0316 ;повторим еще раз ret nz ;индексный сигнал изменился x030C bit 0,(hl) ret nz call x0C98 ;остановка контроллера ВГ93 ld a,#01 jr x0328 ;ошибка. прерывание функции ;ждем изменения индексного сигнала x0316 in a,(#1F) and #02 cp b ret nz inc de ld a,e or d jr nz,x0316 ret ;АДРЕС: #0322 опрос Break и прерывание, если нажата x0322 call x0C83 ;опрос Break. cy=1 не нажата ret c ld a,#03 x0328 jp x04D1 ;ошибка. прерывание функции ;АДРЕС: #032B R8DOS #10(16) чтение/установка спецификации дискеты ;вх: a - спецификация диска ; b - режим: 0FFh - установка, другое - чтение. ; x032B call x0344 ;адрес кода, определяющего тип дискеты в текущем дисководе inc b jr nz,x0333 ;чтение ld (hl),a ;запись ret x0333 ld a,(hl) ret ;АДРЕС: #0335 R8DOS #11(17) чтение кода спецификации дисковода ;вых: a - код спецификации дисковода x0335 call x0349 ;адрес кода, определяющего тип текущего дисковода ld a,(hl) ret ;АДРЕС: #033A в hl адрес кода time-out для текущего дисковода x033A ld hl,xFFD8 jr x034C ;АДРЕС: #033F в hl адрес кода, определяющего номер дорожки в текущем дисководе x033F ld hl,xFFD4 jr x034C ;АДРЕС: #0344 в hl адрес кода, определяющего тип дискеты в текущем дисководе x0344 ld hl,xFFD0 ;коды, определяющие тип дискеты в дисководах jr x034C ;АДРЕС: #0349 в hl адрес кода, определяющего тип текущего дисковода x0349 ld hl,xFFCC ;коды, определяющие тип дисковода ;расчет адреса для текущего дисковода x034C push de ld de,(xFFCA) ;номер текущего дисковода ld d,#00 add hl,de pop de ret ;АДРЕС: #0356 подготовка байта для выбора заданного дисковода ;вых: a - байт x0356 ld a,(xFFCA) ;номер текущего дисковода call x0344 ;адрес кода, определяющего тип дискеты в текущем дисководе and #03 ;номер текущего дисковода or %00011100 ;загрузка головки, сторона верхняя ld c,a ld a,(hl) ;метод записи 0/1=FM/MFM and %01000000 or c ret ;АДРЕС: #0366 проверка наличия образа в текущем дисководе ;вых: nz - к текущему дисководу образ подключен ; z - к текущему дисководу образ не подключен x0366 call x0349 ;в hl адрес кода, определяющего тип текущего дисковода ld a,(hl) cp #FF jr z,x038C ;еще не инициалищирован bit 5,a jr z,x038C ;образ не подключен ;проверка наличия образа TR-DOS в текущем дисководе x0372 ld a,(xE590) and %11011111 cp #01 jr nz,x03DF ;нет подключенного образа TR-DOS. ошибка: нет диска в дисководе ld hl,xFFDC set 7,(hl) ;признак подключенного образа TR-DOS xor a ;cy=0 inc a ;nz ret ;установка дескриптора образа для текущего дисковода x0383 ld a,(xFFCA) ;номер текущего дисковода rst #30 dw rom2_x2C4D ;копирование дескриптора дисковода в буфер xE590, db #02 ;если к нему примонтирован образ jr x0372 ;проверка наличия образа TR-DOS в текущем дисководе ;для дисководов C/D возможна работа только с образами x038C ld a,(xFFCA) ;номер текущего дисковода bit 1,a ret z ;дисковод A/B jr x03DF ;ошибка: нет диска в дисководе ;АДРЕС: #0394 проверка bit 7,(xFFDC) наличие подключенного образа к текущему дисководу x0394 push hl ld hl,xFFDC bit 7,(hl) pop hl ret ;текущий дисковод инициализирован x039C ld hl,xFFDC set 6,(hl) ret ;АДРЕС: #03A2 установка номера дорожки для позиционирования x03A2 ld a,(xFFDC) bit 6,a ret nz ;дисковод инициализирован push hl push de push bc call x0366 ;проверка наличия образа в текущем дисководе jr nz,x03BE ;к текущему дисководу образ подключен ld b,#10 call x0356 ;подготовка байта для выбора заданного дисковода xor b out (#FF),a call x033F ;hl адрес кода, определяющего номер дорожки в текущем дисководе ld a,(hl) out (#3F),a ;установим номер дорожки x03BE call x039C ;текущий дисковод инициализирован pop bc pop de pop hl ret ;АДРЕС: #03C5 R8DOS #01(1) выбор текущего дисковода ;вх: a - номер дисковода [0..3] x03C5 and #03 ld (xFFCA),a ;номер текущего дисковода ld hl,xFFDC res 6,(hl) res 7,(hl) call x0349 ;hl адрес кода, определяющего тип текущего дисковода bit 5,(hl) ;образ на текущем дисководе? jr nz,x0383 ;к дисководу подключен образ. установка дескриптора образа для текущего дисковода bit 1,a ret z ;дисковод A/B xor a ld (xE590),a ;текущий дисковод без образа x03DF ld a,#01 ;дисководы C/D только с образами могуть быть jp x04D1 ;ошибка #01 нет диска в дисководе. прерывание функции ;АДРЕС: #03E4 инициализация текущего дисковода при необходимости x03E4 ld hl,xFFDC bit 6,(hl) ret nz ;дисковод уже инициализирован ld hl,x039C ;адрес возврата push hl ld hl,xFFDC ;!!!ЛИШНЕЕ call x0366 ;проверка наличия образа в текущем дисководе ret nz ;к текущему дисководу подключен образ call x0356 ;подготовка байта для выбора заданного дисковода out (#FF),a ;выбор дисковода call x0349 ;hl адрес кода, определяющего тип текущего дисковода ld a,(hl) inc a ret nz ;уже инициализирован push hl call x0824 ;позиционирование на заданную дорожку c тайим-аутом ld ix,xFFDC set 0,(ix+0) xor a ;дорожка 0 call x042C ;позиционирование на заданную дорожку ld a,#32 ;дорожка #32(50) call x042C ;позиционирование на заданную дорожку ld a,#02 ;дорожка #02 call x042C ;позиционирование на заданную дорожку res 0,(ix+0) pop hl bit 2,a ;регистр состояния. потеря данных res 6,(hl) jr nz,x0427 ;потеря данных set 6,(hl) ;80 дорожек на дисководе x0427 ld a,(hl) and %11000011 ld (hl),a xor a ;уходим на нулевую дорожку ;АДРЕС: #042C позиционирование на заданную дорожку ;вх: a - номер дорожки ;вых: a - регистр состояния x042C call x033F ;hl адрес кода, определяющего номер дорожки в текущем дисководе ld (hl),a ;номер дорожки ;АДРЕС: #0430 поиск дорожки ;вх: a - номер дорожки ;вых: a - регистр состояния x0430 ld b,#18 ;команда поиска jr x0436 ;АДРЕС: #0434 поиск дорожки с проверкой ;вх: a - номер дорожки ;вых: a - регистр состояния x0434 ld b,#1C ;команда поиска x0436 out (#7F),a ;запись в регистр данных ;АДРЕС: #0438 выдача команды в порт #1F ВГ93 ;вх: b - команда для ВГ93 ;вых: a - регистр состояния x0438 call x0349 ;hl адрес кода, определяющего тип текущего дисковода ld a,(hl) and #03 ;время перемещения на шаг or b out (#1F),a ;выдаем команду в порт ;АДРЕС: #0441 ожидание готовности ВГ93 ;вых: a - регистр состояния x0441 ld de,26300 ;количество попыток x0444 in a,(#FF) ;ожидание сигнала INTRQ rlca jr nc,x044C in a,(#1F) ;чтение регистра состояния ret x044C call x0322 ;опрос Break и прерывание, если нажата dec de ld a,e or d jr nz,x0444 ;повторим jp x030C ;превышено кол-во попыток ;АДРЕС: #0457 R8DOS #02(2) позиционирование на заданный логический трек ;вх: d - номер дорожки x0457 push de call x03E4 ;инициализация текущего дисковода при необходимости pop de call x0394 ;проверка bit 7,(xFFDC) jr z,x046D ;реальная дискета ;подключен образ диска x0461 call x033F ;hl адрес кода, определяющего номер дорожки в текущем дисководе ld (hl),d ld a,d cp #A0 ;не больше 160 ld a,#05 ;код ошибки: ошибка позицирования (не соответствует номер дорожки) ret c jr x04D1 ;ошибка. прерывание функции ;реальная дискета x046D call x0356 ;подготовка байта для выбора заданного дисковода call x0344 ;hl адрес кода, определяющего тип дискеты в текущем дисководе ld e,(hl) call x0349 ;hl адрес кода, определяющего тип текущего дисковода bit 5,e jr z,x0483 ;диск 40 дорожек bit 6,(hl) jr nz,x0492 ;дисковод на 80 дорожек x047F ld a,#08 ;код ошибки: ошибка позицирования, не соответствие типов (попытка использовать 80 дорожечный диск на 40 дорожечном дисководе) jr x04D1 x0483 bit 6,(hl) jr z,x0492 ;дисковод на 40 дорожек ;дисковод на 80 дорожек sla d ;определение стороны диска и номера физической дорожки bit 7,e jr z,x0492 ;односторонняя дискета bit 1,d jr z,x0492 ;верхняя сторона dec d x0492 bit 7,e jr z,x04A0 ;односторонняя дискета bit 7,(hl) jr z,x047F ;ошибка позицирования, не соответствие типов (попытка использовать двустронний диск на одностороннем дисководе) srl d jr nc,x04A0 res 4,a ;нижняя головка x04A0 out (#FF),a call x0768 ;чтение заголовка сектора с позиционированием на заданную дорожку ld a,#06 ;код ошибки: ошибка позицирования (не считался адресной маркер дорожки/сектора) jp c,x04D1 ld a,(ix+0) ;номер дорожки в заголовке call x033F ;hl адрес кода, определяющего номер дорожки в текущем дисководе cp (hl) ;сравнение с заданным push hl push de call nz,x029C ;R8DOS #00(0) сброс контроллера pop de pop hl ld a,(hl) ;номер дорожки bit 2,e jr z,x04BF sla a ;диск 40 работает на дисководе 80 x04BF cp d ret z out (#3F),a ;установим номер дорожки ld a,d bit 2,e jr nz,x04EC ;диск 40 работает на дисководе 80 ld (hl),a call x0434 ;поиск дорожки с проверкой bit 4,a ;ошибка позиционирования? ret z ;нет ошибки x04CF ld a,#05 ;код ошибки: ошибка позицирования (не соответствует номер дорожки) ;АДРЕС: #04D1 ошибка. прерывание функции ;вх: a - код ошибки x04D1 ld (xFFDD),a ;код ошибки дискового интерпретатора ld a,#D0 out (#1F),a ;команда прерывания call x04DE jp x0264 ;проверка кода time-out для текущего дисковода x04DE push hl push af call x033A ;в hl адрес кода time-out для текущего дисковода ld a,(hl) inc a jr z,x04E9 ld (hl),#00 x04E9 pop af pop hl ret ;диск 40 работает на дисководе 80 x04EC srl d ld (hl),d push de call x0430 ;поиск дорожки pop de call x0768 ;чтение заголовка сектора с позиционированием на заданную дорожку ld a,#06 ;код ошибки: ошибка позицирования (не считался адресной маркер дорожки/сектора) jr c,x04D1 ld a,(ix+0) ;номер дорожки cp d ret z jr x04CF ;ошибка позицирования (не соответствует номер дорожки) ;АДРЕС: #0502 R8DOS #0E(14) физическое позиционирование на трек ;вх: d - номер физической дорожки [0...х] ; a - номер стороны: 0/1 - нижняя/верхняя x0502 and #01 ld e,a ;номер стороны push de call x03A2 ;установка номера дорожки для позиционирования call x0394 ;проверка bit 7,(xFFDC) наличие подключенного образа к текущему дисководу jr z,x0517 ;образ не подключен pop de ld a,d sla a add a,e ld d,a ;логический номер дорожки jp x0461 ;проверка номера дорожки образа x0517 call x0824 ;позиционирование на заданную дорожку c тайим-аутом call x0356 ;подготовка байта для выбора заданного дисковода pop de rrc e ld hl,xFFDC set 4,(hl) jr nc,x052B ;нижняя сторона res 4,a res 4,(hl) x052B out (#FF),a ld a,d call x0344 ;hl адрес кода, определяющего тип дискеты в текущем дисководе bit 2,(hl) jp z,x042C ;позиционирование на заданную дорожку ;диск 40 работает на дисководе 80 call x033F ;hl адрес кода, определяющего номер дорожки в текущем дисководе ld a,(hl) sla a out (#3F),a ld (hl),d ld a,d sla a jp x0430 ;поиск дорожки ret ;!!!ЛИШНЕЕ!!! ;АДРЕС: #0546 R8DOS #12(18) в hl адрес таблицы с количеством секторов на дорожке x0546 ld hl,(xFFC8) ret ;АДРЕС: #054A ошибка. неверный номер сектора x054A ld a,#07 jr x04D1 ;АДРЕС: #054E R8DOS #04(4) повторить в случае ошибки функцию 5 (или 6) x054E call x0824 ;позиционирование на заданную дорожку c тайим-аутом jr x05A8 ;АДРЕС: #0553 R8DOS #05(5) чтение группы секторов ;вх: hl - адрес буфера ; d[0...x] - номер логического трека (первого обрабатываемого сектора) ; e[0...х] - номер первого обрабатываемого сектора ; b - количество секторов в операции ; x0553 ld a,#80 ;признак чтения jr x0559 ;АДРЕС: #0557 R8DOS #06(6) запись группы секторов ;вх: hl - адрес буфера ; d[0...x] - номер логического трека (первого обрабатываемого сектора) ; e[0...х] - номер первого обрабатываемого сектора ; b - количество секторов в операции ; x0557 ld a,#A0 ;признак записи x0559 ld (xFFE1),a push bc push de push hl call x0344 ;hl адрес кода, определяющего тип дискеты в текущем дисководе ld a,(hl) and #03 ;код размера сектора в байтах push af ld c,a call x0B52 ;преобразование кода размера сектора в байтах в число ld (xFFED),bc ;размер сектора в байтах pop af bit 6,(hl) jr nz,x0575 ;метод записи MFM add a,#04 x0575 ld b,#00 ld c,a ld hl,(xFFC8) ;адрес таблицы количеством секторов на дорожке add hl,bc ld a,(hl) ld (xFFE0),a ;количество секторов на дорожке dec a cp e jr c,x054A ;ошибка. неверный номер сектора call x03E4 ;инициализация текущего дисковода при необходимости call x0824 ;позиционирование на заданную дорожку c тайим-аутом pop hl pop de pop bc x058D ld (xFFE2),hl ld (xFFE4),de ld a,b ld (xFFE6),a call x0457 ;позиционирование на заданную дорожку jr x05A8 x059D ld a,b ld (xFFE6),a ld (xFFE2),hl ld (xFFE4),de ;головка спозицонирована на заданную дорожку x05A8 ld a,(xFFCB) ld b,a ;число попыток считывания при ошибке x05AC ld de,(xFFE4) ;дорожка и сектор call x0322 ;опрос Break и прерывание, если нажата ld hl,(xFFE2) ;адрес для чтения push bc ld bc,(xFFED) ;размер сектора в байтах push de ld a,(xFFE1) ;=#80/#A0 чтение/запись группы секторов bit 5,a push af call nz,x06B4 ;запись сектора pop af call z,x0610 ;чтение сектора pop de ld c,a and #1F ld a,c pop bc jr z,x05EB ;прочиталось без ошибки djnz x05AC ;ошибка. повторим чтение ld a,#04 ;код ошибки: ошибка при чтении или записи сектора функциями 5 или 6 x05D5 jp x04D1 ;прервем функцию ;АДРЕС: #05D8 R8DOS #03(3) игнорирование ошибки и продолжение выполнения функции 5 (или 6) x05D8 call x0824 ;позиционирование на заданную дорожку c тайим-аутом call x0344 ;hl адрес кода, определяющего тип дискеты в текущем дисководе ld a,(hl) and #03 ld c,a ;код размера сектора call x0B52 ;преобразование кода размера сектора в байтах в число ld hl,(xFFE2) add hl,bc ;пропускаем сектор jr x05F1 ;проверка защиты от записи x05EB bit 6,a ;защита записи? ld a,#02 ;код ошибки: попытка записи на защищенную дискету jr nz,x05D5 ;ошибка. если была запись. при чтении не устанавливается ;расчет номера следующего сектора x05F1 ld de,(xFFE4) ;дорожка и сектор для чтения/записи inc e ld a,e push hl ;следующий адрес в памяти ld hl,(xFFE0) ;количество секторов на дорожке cp l pop hl jr c,x0609 ;дорожка еще не кончилась ld e,#00 ;нулевой сектор, следующая дорожка inc d ld a,(xFFE6) ;количество секторов для чтения/записи ld b,a djnz x058D ;следующий сектор ret ;завершили чтение/запись ;дорожка еще не кончилась x0609 ld a,(xFFE6) ld b,a djnz x059D ret ;завершили чтение/запись ;АДРЕС: #0610 чтение сектора ;вх: de - дорожка и сектор ; hl - адрес для чтения ; bc - размер сектора в байтах ; a - команда =#80/#A0 чтение/запись группы секторов ;вых: nz - ошибка чтения ; a - регистр состояния ; hl - следующий адрес в памяти x0610 ld d,a bit 5,(iy+#0B) jr z,x0635 ;вызов функции из монитора call x1B45 ;определение необходимости копирования памяти пользователя jr nc,x0635 ;копировать не надо push hl ld hl,xEBF5 ;читаем в буфер в ram 8 push bc call x0635 ;читаем сектор ld b,a ;регистр состояния and #1F ld a,b pop bc pop hl ret nz ;была ошибка чтения ld de,xEBF5 ;буфер в память пользователя ex de,hl rst #30 dw rom2_x0749 ;восстановление области памяти из ram 8 db #02 xor a ret x0635 ld a,(xFFDC) rlca jr c,x066B ;это образ на HDD ;АДРЕС: #063B чтение данных с дискеты в память ;вх: hl - адрес в памяти ; d - команда ; e - номер сектора ;вых: a - регистр состояния ; hl - следующий адрес в памяти x063B call x0648 ;чтение данных в память ld a,b or a ld a,#01 ;код ошибки: нет диска в дисководе jp z,x04D1 ;нет готовности in a,(#1F) ret ;чтение данных в память ;вх: hl - адрес в памяти ; d - команда ; e - номер сектора ;вых: b=#00 нет готовности ; hl - следующий адрес в памяти x0648 ld a,e inc a out (#5F),a ;регистр сектора ld a,d out (#1F),a ;регистр команд ld bc,#047F x0652 in a,(#FF) ;чтение системного регистра and #C0 jr nz,x0667 ;есть готовность inc de ld a,d or e jr nz,x0652 ;ожидаем готовность djnz x0652 ret ;чтение сектора x0660 in a,(#FF) and #C0 jr z,x0660 ;ждем готовности ret m ;сигнал окончания выполнения команды x0667 ini ;читаем байт с дискеты jr x0660 ;АДРЕС: #066B чтение сектора образа HDD в память ;вх: hl - адрес в памяти ; d - команда ; e - номер сектора ;вых: hl - следующий адрес в памяти ; bc=#0100 x066B push hl call x074C ;расчет смещения от начала образа в секторах (512b) push bc inc hl ;+1 сервисный сектор bit 4,(iy+#0B) jr z,x0682 ;сектор с HDD еще не прочитан push hl ;расчет смещения от начала образа в секторах (512b) ld bc,(xE5A7) ;смещение предыдущего сектора от начала образа в секторах (512b) or a sbc hl,bc pop hl jr z,x0685 ;сектор уже в памяти, не читаем x0682 call x0694 ;чтение сектора с винчестера в буфер xEFF5 x0685 pop bc ;#0000/#0100 смещение в секторе pop de ;адрес в памяти куда читать ld hl,xEFF5 add hl,bc ;какую половину копировать ld bc,#0100 ldir ;копируем из буфера в память ex de,hl inc b xor a ret ;АДРЕС: #0694 чтение сектора с винчестера в буфер xEFF5 ;вх: hl - смещение от начала образа в секторах (512b) x0694 ld a,(xE590) and #DF cp #01 ld a,#21 ;код ошибки: jp nz,x04D1 ld (xE5A7),hl ;смещение от начала образа в секторах (512b) ld de,xEFF5 ;адрес буфера для чтения ex de,hl call x1813 ;чтение сектора с винчестера ld a,#04 jp c,x04D1 ;ошибка. прерываем функцию set 4,(iy+#0B) ;сектор прочитан ret ;АДРЕС: #06B4 запись сектора ;вх: de - дорожка и сектор ; hl - адрес для чтения ; bc - размер сектора в байтах ; a - команда =#80/#A0 чтение/запись группы секторов ;вых: nz - ошибка записи ; a - регистр состояния ; hl - следующий адрес в памяти x06B4 ld d,a bit 5,(iy+#0B) jr z,x06D2 ;вызов функции из монитора call x1B45 ;определение необходимости копирования памяти пользователя jr nc,x06D2 ;копировать не надо push de ld de,xEBF5 ;буфер в ram 8 rst #30 dw rom2_x0753 ;сохранение области памяти в ram 8 db #02 pop de push hl ld hl,xEBF5 ;буфер с данными пользователя call x06D2 pop hl ret x06D2 ld a,(xFFDC) rlca jr c,x0708 ;это образ на HDD. запись сектора на образ HDD call x06E5 ;запись сектора ld a,b or a ld a,#01 ;код ошибки: нет диска в дисководе jp z,x04D1 ;прерывание функции in a,(#1F) ;регистр состояния ret ;запись сектора ;вх: hl - адрес для чтения ; e - номер сектора ; d - команда =#80/#A0 чтение/запись группы секторов ;вых: b=#00 нет готовности x06E5 ld a,e inc a out (#5F),a ;регистр сектора ld a,d out (#1F),a ;регистр команд (команда запись сектора) ld bc,#047F x06EF in a,(#FF) ;чтение системного регистра and #C0 jr nz,x0704 ;есть готовность к приему данных inc de ld a,d or e jr nz,x06EF ;ожидаем готовность djnz x06EF ret ;передача данных сектора x06FD in a,(#FF) and #C0 jr z,x06FD ;ждем готовности ret m ;сигнал окончания выполнения команды x0704 outi ;запись байта на дискету jr x06FD ;АДРЕС: #0708 запись сектора на образ HDD ;вх: hl - адрес в памяти ; e - номер сектора ;вых: hl - следующий адрес в памяти ; bc=#0100 x0708 ld a,(xE590) cp #01 ld a,#21 jp nz,x04D1 ;образ не подключен/защита от записи push hl call x074C ;расчет смещения от начала образа в секторах (512b) push bc inc hl ;+1 сервисный сектор bit 4,(iy+#0B) ;сектор еще не записан jr z,x0729 ;читаем сектор с HDD. нужно чтобы записать сектор 256b push hl ;расчет смещения от начала образа в секторах (512b) ld bc,(xE5A7) ;смещение предыдущего сектора от начала образа в секторах (512b) or a sbc hl,bc pop hl jr z,x072E ;этот сектор уже прочитан x0729 push hl ;смещение от начала образа в секторах (512b) call x0694 ;чтение сектора с винчестера в буфер xEFF5 pop hl x072E pop bc ;#0000/#0100 смещение в секторе ex (sp),hl ;адрес в памяти ld de,xEFF5 ;буфер куда прочитали сектор ex de,hl add hl,bc ;смещение в секторе ex de,hl ld bc,#0100 ldir ;коприруем данные в буфер pop de ;смещение от начала образа в секторах (512b) push hl ;следующий адрес в памяти ld hl,xEFF5 call x1829 ;запись сектора на винчестер pop hl ld a,#00 ret nc ;нет ошибок ld a,#04 ;код ошибки: ошибка при чтении или записи сектора функциями 5 или 6 jp x04D1 ;АДРЕС: #074C расчет смещения от начала образа в секторах (512b) ;вх: e - номер сектора ;вых: hl - смещение от начала образа в секторах (512b) ; bc - #0000/#0100 смещение в секторе x074C call x033F ;hl адрес кода, определяющего номер дорожки в текущем дисководе ld l,(hl) ;номер дорожки ld h,#00 add hl,hl add hl,hl add hl,hl add hl,hl ;номер дорожки *16 ld a,l add a,e ld l,a jr nc,x075C inc h x075C srl h rr l ;(trk * 16 + sec)/2 ld bc,#0000 ;первая половина сектора HDD ret nc ld bc,#0100 ;вторая половина сектора HDD ret ;АДРЕС: #0768 чтение заголовка сектора с позиционированием на заданную дорожку ;вх: e - номер сектора ;вых: cy=1 была ошибка при чтении ; ix - адрес буфера с прочитанныи загловком x0768 push de call x0824 ;позиционирование на заданную дорожку c тайим-аутом pop de ;АДРЕС: #076D чтение заголовка сектора ;вых: cy=1 была ошибка при чтении ; ix - адрес буфера с прочитанныи загловком x076D push de ld hl,xFFE9 ;куда читаем ld d,#C0 ;чтение адреса push hl call x063B ;чтение данных в память pop ix pop de and #1F ret z ;ошибок нет scf ret ;АДРЕС: #077F R8DOS #0A(10) построение таблицы расположения секторов на дорожке, начиная от индексного маркера ;вх: hl - адрес таблицы ;вых: таблица заголовков секторов, находящихся на дорожке x077F call x03A2 ;установка номера дорожки для позиционирования bit 5,(iy+#0B) jr z,x07AB ;функция вызвана из монитора ld bc,#012C call x1B45 ;определение необходимости копирования памяти пользователя jr nc,x07AB ;копировать не надо push hl ld hl,xEBF5 push hl call x07AB inc hl pop bc or a sbc hl,bc ld a,h or l ld c,l ld b,h ;длина таблицы pop de ret z ;таблица пустая ld hl,xEBF5 rst #30 dw rom2_x0749 ;восстановление области памяти из ram 8 db #02 ret ;формирование таблицы секторов x07AB call x0394 ;проверка bit 7,(xFFDC) наличие подключенного образа к текущему дисководу jr z,x07CF ;реальная дискета ; для образа диска push hl call x033F ;hl адрес кода, определяющего номер дорожки в текущем дисководе ld e,(hl) srl e pop hl ld a,#01 x07BA ld (hl),#00 ;информация о секторе достоверна inc hl ld (hl),e ;Физический номер дорожки (0..х) inc hl ld (hl),#00 ;сторона 0 inc hl ld (hl),a ;Номер сектора (1..х) inc hl ld (hl),#01 ;Код длины сектора =#01 - 256b inc hl inc a cp #11 jr c,x07BA ld (hl),#FE ret ; для реальной дискеты x07CF ld (xFFE2),hl ld (hl),#FE inc hl inc hl inc hl ld (xFFE4),hl ld (hl),#00 ;номер сектора 0 ld a,#3C ;максимальное количество секторов ld (xFFE6),a call x0824 ;позиционирование на заданную дорожку c тайм-аутом x07E4 call x0322 ;опрос Break и прерывание, если нажата in a,(#1F) bit 1,a jr z,x07E4 ;ожидание индексного импульса x07ED call x076D ;чтение заголовка сектора ;ix - адрес буфера с прочитанныи загловком ld hl,(xFFE2) ld (hl),#00 jr nc,x07F9 ;ошибок не было ld (hl),#FF ;сбой чтения x07F9 inc hl ld de,(xFFE4) ld a,(de) cp (ix+#02) ;номер сектора jr z,x0820 ;конец дорожки push ix ;копируем в таблицу pop de ex de,hl ld bc,#0004 ldir ex de,hl ld (hl),#FE ld (xFFE2),hl ld a,(xFFE6) dec a ret z ld (xFFE6),a call x0322 ;опрос Break и прерывание, если нажата jr x07ED x0820 dec hl ld (hl),#FE ret ;АДРЕС: #0824 позиционирование на заданную дорожку c тайим-аутом x0824 push hl ld hl,xFFDC bit 4,(hl) jr nz,x084D ;выход bit 7,(hl) jr nz,x084D ;выход set 4,(hl) call x033F ;hl адрес кода, определяющего номер дорожки в текущем дисководе ld a,(hl) out (#3F),a ;номер дорожки nop out (#7F),a ;номер дорожки ld b,#18 ;позиционирование на заданную дорожку call x0438 ;выдача команды в порт #1F ВГ93 call x02BE ;проверка байта time-out jr nz,x084D ;задержка не нужна ld hl,15010 ;задержка 390277t x0848 dec hl ld a,h or l jr nz,x0848 x084D pop hl ret ;АДРЕС: #084F R8DOS #07(7) идентификация диска x084F call x03E4 ;инициализация текущего дисковода при необходимости call x0349 ;hl адрес кода, определяющего тип текущего дисковода ld a,(hl) or #C0 ld (hl),a call x0394 ;bit 7,(xFFDC) jr z,x0868 ;образ не подключен call x0344 ;hl адрес кода, определяющего тип дискеты в текущем дисководе ld (hl),#A1 ;%10100001 ld d,#02 jp x0457 ;R8DOS #02(2) позиционирование на заданный логический трек ;реальный дисковод x0868 call x0344 ;hl адрес кода, определяющего тип дискеты в текущем дисководе ld (hl),#A0 push hl call x029C ;R8DOS #00(0) сброс контроллера ld a,#02 call x042C ;позиционирование на заданную дорожку call x0768 ;чтение заголовка сектора с позиционированием на заданную дорожку ;ix - адрес буфера с прочитанныи загловком pop hl jr nc,x088D ;ошибки не было set 6,(hl) ;метод записи MFM push hl call x0356 ;подготовка байта для выбора заданного дисковода out (#FF),a ;выбор дисковода call x0768 ;чтение заголовка сектора с позиционированием на заданную дорожку pop hl ld a,#09 ;код ошибки: неформатированная дискета jp c,x04D1 ;ошибка. прерывание функции ; установка длины сектора в переменной x088D ld a,(ix+3) ;код длины сектора and #03 ld c,a ;код длины сектора ld a,(hl) and #FC or c ld (hl),a ;установим код длины сектора в переменной ; коррекция номера дорожки для 40 дорожечного дисковода ld d,(ix+#00) ;номер дорожки push hl call x0349 ;hl адрес кода, определяющего тип текущего дисковода bit 6,(hl) ld e,(hl) jr nz,x08A6 ;80 дорожек в дисководе srl d x08A6 pop hl res 2,(hl) ;hl адрес кода, определяющего тип дискеты в текущем дисководе srl d jr nc,x08BB res 5,(hl) ;40 дорожек на дискете bit 6,e ;код, определяющий тип текущего дисковода jr z,x08BB ;дисковод на 40 дорожек set 2,(hl) ;диск 40 работает на дисководе 80 push hl call x033F ;hl адрес кода, определяющего номер дорожки в текущем дисководе dec (hl) pop hl x08BB call x0356 ;подготовка байта для выбора заданного дисковода res 4,a ;сторона 0 out (#FF),a push hl call x0768 ;чтение заголовка сектора с позиционированием на заданную дорожку pop hl jr nc,x08CC ;ошибок не было res 7,(hl) ;односторонняя дискета ret x08CC ld a,(ix+#01) ;номер стороны or a ret nz res 7,(hl) ;односторонняя дискета ret ;АДРЕС: #08D4 R8DOS #08(8) идентификация диска для tr-dos, аналогична функции #18 ; интерпретатора системных функций. Перед вызовом необходимо ; установить рабочий буфер, размером не менее 256 байт, используя функцию 9 x08D4 call x084F ;R8DOS #07(7) идентификация диска call x0344 ;hl адрес кода, определяющего тип дискеты в текущем дисководе ld a,(hl) and %01000011 dec a ld a,#10 jp nz,x04D1 ;ошибка #10. дискета не соответствует формату tr-dos ld de,#0008 ld b,#01 ld hl,(xFFE7) ;адрес рабочего буфера для функции ld a,h or l ld a,#12 jp z,x04D1 ;ошибка #12. не открыт рабочий буфер call x0553 ;R8DOS #05(5) чтение служебного сектора ld ix,(xFFE7) ;адрес рабочего буфера для функции ld de,#00E1 add ix,de ;начало служебной информации ld a,#10 cp (ix+#06) ;идентификационный код TR-DOS (#10) jp nz,x04D1 ;ошибка #10. дискета не соответствует формату tr-dos call x0349 ;hl адрес кода, определяющего тип текущего дисковода ld e,(hl) call x0344 ;hl адрес кода, определяющего тип дискеты в текущем дисководе inc a res 7,(hl) ;односторонняя дискета bit 2,(ix+#02) ;тип дискеты jr z,x0918 ;односторонняя set 7,(hl) ;двухсторонняя x0918 res 5,(hl) ;40 дорожек на диске bit 0,(ix+#02) ;кол-во дорожек ret nz ;40 дорожек set 5,(hl) ;80 дорожек ret ;АДРЕС: #0922 R8DOS #09(9) установка рабочего буфера для функции 8 ;вх: hl - адрес рабочего буфера ;вых: d - версия компиляции монитора ; c - число компиляций монитора ; b - месяц компиляции монитора ; e - год компиляции монитора x0922 ld (xFFE7),hl ld (xFFF0),hl ld de,#6161 ld bc,#0705 ret ;АДРЕС: #092F вычисление размера таблицы секторов ;вх: hl - адрес таблицы секторов ;вых: bc - размер таблицы сеторов x092F push hl push hl x0931 ld a,(hl) cp #FE jr z,x093F ;конец таблицы секторов ld a,#05 ;следующий сектор add a,l ld l,a jr nc,x0931 inc hl ;!!!ОШИБКА??? должно быть inc h jr x0931 x093F inc hl pop bc or a sbc hl,bc ld c,l ld b,h ;размер таблицы секторов pop hl ret ;АДРЕС: #0948 R8DOS #0B(11) форматирование дорожки, на которой находится ; магнитная головка дисковода. Форматирование производится согласно ; таблице секторов. Данные из таблицы напрямую переносятся на ; дискету, никаких проверок на их корректность не производится, ; заканчивает таблицу идентификационный байт, больший 128. Размер ; сектора выбирается согласно байту +4, заполняется сектор ; константой #00/#FF. После записи очередного сектора в байт по ; адресу, содержащемуся в регистре DE, записывается число 2Ch, а ; значение DE увеличивается на единицу. ;вх: b =#00/#40 - режим FM/MFM ; hl - таблица расположения секторов ; de - адрес рабочего буфера (6 - 7 килобайт) x0948 call x03A2 ;установка номера дорожки для позиционирования ld (xDDA7),de ;сохраним de ld e,b bit 5,(iy+#0B) jr z,x0969 ;функции вызываются из монитора call x092F ;вычисление размера таблицы секторов call x1B45 ;определение необходимости копирования памяти пользователя jr nc,x0969 ;память копировать не надо push de ld de,xEBF5 push de rst #30 dw rom2_x0753 ;сохранение области памяти в ram 8 db #02 pop hl pop de ;форматирование дорожки x0969 ld b,e call x0394 ;проверка bit 7,(xFFDC) наличие подключенного образа к текущему дисководу jr z,x09B2 ;реальная дискета ; образ диска tr-dos push hl call x0344 ;hl адрес кода, определяющего тип дискеты в текущем дисководе ld (hl),b ld hl,xE6A9 ;очистка буфера ld (hl),#00 ld de,xE6A9+1 ld bc,#00FF ldir pop hl ld de,(xDDA7) x0986 ld a,(hl) cp #FE ret z ;конец таблицы секторов or a jr nz,x09A1 ;сектор не прочитан inc hl inc hl inc hl push de ld e,(hl) dec e ;логический номер сектора push hl ld hl,xE6A9 call x0708 ;запись сектора на образ HDD pop hl pop de dec hl dec hl dec hl jr nc,x09A5 ;ошибок не было x09A1 ld a,#2B ;ошибка jr x09A7 x09A5 ld a,#2C ;ошибок не было x09A7 ld (de),a inc de ld a,#05 add a,l ld l,a jr nc,x0986 inc h jr x0986 ; реальная дискета x09B2 ld de,(xDDA7) push de push hl call x0344 ;hl адрес кода, определяющего тип дискеты в текущем дисководе ld (hl),b push bc call x0824 ;позиционирование на заданную дорожку call x0322 ;опрос Break и прерывание, если нажата pop bc pop hl exx ex (sp),hl ;hl' - адрес рабочего буфера exx ld c,#7F ld e,#C0 ld a,#F0 ;команда: запись дорожки bit 6,b jp nz,x0AAC ;режим MFM ;запись дорожки в режиме FM ;вх: c=#7F ; e=#C0 ; a=#F0 out (#1F),a ;команда запись дорожки ; индексное поле ld d,#4E ld b,#50 call x0A98 ;запись #50 байт #4E (послеиндексный промежуток) ld d,#00 ld b,#0C call x0A98 ;запись #0C байт #00 (синхропромежуток) ld d,#F6 ld b,#03 call x0A98 ;запись #03 байт #F6 (запись C2 - синхронизирующий AM) ld d,#FC call x0AA3 ;запись байта #FC (индексная метка) ; секторы x09EF ld d,#4E ld b,#32 call x0A98 ;запись #32 байт #4E (первый пробел) ld d,#00 ld b,#0C call x0A98 ;запись #0C байт #00 (синхропромежуток) ld d,#F5 ld b,#03 call x0A98 ;запись A1 - синхроимпульс ld d,#FE call x0AA3 ;запись байта #FE (адресная метка идентификатора) inc hl ld d,(hl) call x0AA3 ;запись номера дорожки inc hl ld d,(hl) call x0AA3 ;запись номера головки (сторона) inc hl ld d,(hl) call x0AA3 ;запись номера сектора inc hl ld d,(hl) call x0AA3 ;запись кода длины сектора ld d,#F7 call x0AA3 ;запись байта #F7 (2 байта контрольной суммы) ld d,#4E ld b,#16 call x0A98 ;запись #16 байт #4E (второй пробел) ld d,#00 ld b,#0C call x0A98 ;запись #0C байт #00 (синхропромежуток) ld d,#F5 ld b,#03 call x0A98 ;запись A1 - синхроимпульс ld d,#FB call x0AA3 ;запись байта #FB (адресная метка данных) ld d,#00 ld b,c call x0A98 ;запись #7F байт #00 (данные сектора) call x0AA3 ;запись байта #00 (данные сектора) ld a,(hl) or a jr z,x0A61 ;длина сектора 128 байт ld b,c call x0A98 ;запись #7F байт #00 (данные сектора) call x0AA3 ;запись байта #00 (данные сектора) ld a,(hl) dec a jr z,x0A61 ;длина сектора 256 байт call x0A98 ;запись #100 байт #00 (данные сектора) ld a,(hl) rrca jr nc,x0A61 ;длина сектора 512 байт call x0A98 ;запись #100 байт #00 (данные сектора) call x0A98 ;запись #100 байт #00 (данные сектора) x0A61 ld d,#F7 call x0AA3 ;запись байта #F7 (2 байта контрольной суммы) ld d,#4E ld b,#09 call x0A98 ;запись #09 байт #4E (третий пробел) inc hl call x0AA3 ;запись байта #4E exx ld (hl),#2C ;признак записи сектора inc hl exx call x0AA3 ;запись байта #4E ld a,(hl) rlca jp nc,x09EF ;повторим, если не конец call x0A8E ;запись байта #4E до конца дорожки in a,(#1F) exx pop hl exx bit 6,a ret z ;выход без ошибок ld a,#02 jp x04D1 ;ошибка: защита от записи ;запись чисел D в порт C до конца дорожки ;вх: e - маска для регистра состояния ; d - байт для записи ; c - порт x0A8E in a,(#FF) and e jr z,x0A8E ret m out (c),d jr x0A8E ;запись B чисел D в порт C ;вх: e - маска для регистра состояния ; d - байт для записи ; c - порт ; b - количество байт для записи x0A98 in a,(#FF) and e jr z,x0A98 ret m out (c),d djnz x0A98 ret ;запись числа D в порт C ;вх: e - маска для регистра состояния ; d - байт для записи ; c - порт x0AA3 in a,(#FF) and e jr z,x0AA3 ret m out (c),d ret ;запись дорожки в режиме MFM ;вх: c=#7F ; e=#C0 ; a=#F0 x0AAC out (#1F),a ;команда запись дорожки ; индексное поле ld d,#FF ld b,#28 call x0A98 ;запись #28 байт #FF ld d,#00 ld b,#06 call x0A98 ;запись #06 байт #00 ld d,#FC call x0AA3 ;запись байта #FC ; секторы x0AC1 ld d,#FF ld b,#0C call x0A98 ;запись #0C байт #FF ld d,#00 ld b,#06 call x0A98 ;запись #06 байт #00 (пробел) ld d,#FE call x0AA3 ;запись байта #FE (адресная метка индексных данных) inc hl ld d,(hl) call x0AA3 ;запись номера дорожки inc hl ld d,(hl) call x0AA3 ;запись номера головки (сторона) inc hl ld d,(hl) call x0AA3 ;запись номера сектора inc hl ld d,(hl) call x0AA3 ;запись кода длины сектора ld d,#F7 call x0AA3 ;запись байта #F7 (2 байта контрольной суммы) ld d,#FF ld b,#0B call x0A98 ;запись #0B байт #FF ld d,#00 ld b,#06 call x0A98 ;запись #06 байт #00 (второй пробел) ld d,#FB call x0AA3 ;запись байта #FB (адресная метка данных) ld d,#FF ld b,c call x0A98 ;запись #7F байт #FF (данные сектора) call x0AA3 ;запись байта #FF (данные сектора) ld a,(hl) or a jr z,x0B25 ;длина сектора 128 байт ld b,c call x0A98 ;запись #7F байт #FF (данные сектора) call x0AA3 ;запись байта #FF (данные сектора) ld a,(hl) dec a jr z,x0B25 ;длина сектора 256 байт call x0A98 ;запись #100 байт #FF (данные сектора) ld a,(hl) rrca jr nc,x0B25 ;длина сектора 512 байт call x0A98 ;запись #100 байт #FF (данные сектора) call x0A98 ;запись #100 байт #FF (данные сектора) x0B25 ld d,#F7 call x0AA3 ;запись байта #F7 (2 байта контрольной суммы) ld d,#FF ld b,#05 call x0A98 ;запись #05 байт #FF (третий пробел) inc hl call x0AA3 ;запись байта #FF exx ld (hl),#2C ;признак записи сектора inc hl exx call x0AA3 ;запись байта #FF ld a,(hl) rlca jp nc,x0AC1 ;повторим, если не конец call x0A8E ;запись байта #FF до конца дорожки in a,(#1F) exx pop hl exx bit 6,a ret z ;выход без ошибок ld a,#02 jp x04D1 ;ошибка: защита от записи ;АДРЕС: #0B52 преобразование кода размера сектора в байтах в число ;вх: c[0..3] - код размера сектора в байтах ;вых: bc - размер сектора в байтах x0B52 ld a,c and #03 ld b,a inc b ld c,#01 x0B59 sla c djnz x0B59 ld b,c srl b ld c,#00 srl b rr c ret ;АДРЕС: #0B67 R8DOS #0F(15) замена идентификатора в таблице расположения секторов ;вх: hl - адрес таблицы секторов ; e - заменяемый идентификатор ; d - устанавливаемый идентификатор ; x0B67 bit 5,(iy+#0B) jr z,x0B8F ;замена идентификаторов в таблице секторов call x092F ;bc - размер таблицы секторов call x1B45 jr nc,x0B8F ;вся таблица в пределах [#4000..#BFFF] push hl ;замена с переносом в буфер push bc push de ld de,xE5A9 ;буфер push de rst #30 dw rom2_x0753 ;сохранение области памяти в ram 8 db #02 pop hl pop de call x0B8F ;замена идентификаторов в таблице секторов pop bc pop de ld hl,xE5A9 rst #30 dw rom2_x0749 ;восстановление области памяти из ram 8 db #02 ret x0B8F push hl pop ix jr x0BF5 ;замена идентификаторов в таблице секторов ;АДРЕС: #0B94 R8DOS #0C(12) чтение дорожки. Порядок считывания определяется ; содержимым таблицы расположения секторов. Считанные сектора ; помещаются в буфер дорожки, никаких разделителей между ними не ; ставится. Сектора со значением идентификационного байта #FF или ; #FC не считываются, но в буфере для них пропускается ; соответствующее длине (байт +4) место. Если сектор не может быть ; считан, то соответствующий идентификатор в таблице заменяется на ; #FD. Идентификатор успешно считанного сектора заменяется на #FC, ; а по окончании операции все идентификаторы #FC автоматически ; переводятся в #00 ;вх: hl - адрес таблицы секторов ; de - адрес буфера дорожки x0B94 ld a,#80 jr x0B9A ;АДРЕС: #0B98 R8DOS #0D(13) последовательная запись. Порядок записи определяется ; содержимым таблицы расположения секторов. Сектора, для которых значение ; идентификационного байта #FF или #FC не записываются, а в буфере ; пропускается соответствующее длине такого сектора (байт + 4) место. ; Если сектор не может быть записан, то соответствующий идентификатор в ; таблице заменяется на #FD. По окончании записи все идентификаторы #FC ; автоматически переводятся в #00. ;вх: hl - адрес таблицы секторов ; de - адрес буфера дорожки x0B98 ld a,#A0 x0B9A ld (xFFE1),a ld (xFFE2),de ld (xFFE4),de call x03A2 ;установка номера дорожки для позиционирования bit 5,(iy+#0B) jr z,x0C08 ;вызов из монитора call x092F ;вычисление размера таблицы секторов call x1B45 ;определение необходимости копирования памяти пользователя jr nc,x0C08 ;копировать не надо push hl ld de,xE5A9 push bc push de rst #30 dw rom2_x0753 ;сохранение области памяти в ram 8 db #02 pop hl call x0C08 ;чтение/запись дорожки pop bc pop de ld hl,xE5A9 rst #30 dw rom2_x0749 ;восстановление области памяти из ram 8 db #02 ret ;завершение. дорожка прочитана x0BCE pop ix pop bc ld hl,xFFDD ld a,(hl) ;код ошибки inc a jr z,x0BEC ;ошибок не было ld (hl),#FF ld de,(xFFE4) ;начало буфера дорожки ld (xFFE2),de ld a,(xFFDC) rlca jr c,x0BEA ;подключен образ, повторять нет смысла djnz x0C12 ;повторим попытку x0BEA ld (hl),#14 x0BEC call x033F ;hl адрес кода, определяющего номер дорожки в текущем дисководе ld a,(hl) out (#3F),a ld de,#00FC ;замена идентификаторов в таблице секторов ;вх: ix - адрес таблицы секторов ; e - заменяемый идентификатор ; d - устанавливаемый идентификатор x0BF5 ld bc,#0005 x0BF8 ld a,(ix+0) cp #FE ret z ;конец таблицы cp e jr nz,x0C04 ;слезующий сектор ld (ix+0),d ;заменяем идентификатор x0C04 add ix,bc jr x0BF8 ;чтение/запись дорожки ;вх: hl - адрес таблицы секторов ; de - адрес буфера дорожки x0C08 push hl call x0824 ;позиционирование на заданную дорожку c тайм-аутом pop ix ;адрес таблицы секторов ld a,(xFFCB) ;количество попыток считывания при ошибке ld b,a x0C12 push bc push ix x0C15 ld a,(ix+0) inc ix cp #FC jr z,x0C6F ;сектор не читаем. пропускаем место для него cp #FF jr z,x0C6F ;сектор не читаем. пропускаем место для него cp #FE jr z,x0BCE ;конец таблицы call x0322 ;опрос Break и прерывание, если нажата ld a,(ix+0) out (#3F),a ;номер дорожки ld c,(ix+3) ;код длины сектора ld a,(xFFDC) rlca jr nc,x0C3E ;реальная дискета ld a,c cp #01 ld a,#FD jr nz,x0C67 ;на образе сектор может быть только 256 байт x0C3E call x0B52 ;преобразование кода размера сектора в байтах в число ld hl,(xFFE2) ;адрес в буфере дорожки ld a,(ix+2) ;номер сектора dec a ld e,a push de ld a,(xFFE1) bit 5,a push af call nz,x06B4 ;запись сектора pop af call z,x0610 ;чтение сектора pop de bit 6,a ;защита от записи push af ;!!!ОШИБКА!!! при записи состояние регистра ld a,#02 ;состояния не сохраняется jp nz,x04D1 ;ошибка. прерывание функции pop af and #1F ld a,#FC ;признак успешной операции jr z,x0C6C ;!!!ОШИБКА!!! при операции записи будет всегда z x0C67 ld (xFFDD),a ;код ошибки ld a,#FD x0C6C ld (ix-1),a x0C6F ld c,(ix+3) ;код размера сектора call x0B52 ;преобразование кода размера сектора в байтах в число ld hl,(xFFE2) ;адрес в буфере дорожки add hl,bc ld (xFFE2),hl ld bc,#0004 ;следующая запись в таблице секторов add ix,bc jr x0C15 ;АДРЕС: #0C83 опрос Break. cy=1 не нажата x0C83 push hl ld hl,x0C96 ;адрес возврата push hl ld hl,rom3_x3D30 ;включение rom 7 push hl ld hl,rom5_x0110 ;опрос Break. cy=1 не нажата x0110 push hl ld hl,xFFEF ld (hl),#C9 ;ret jp (hl) x0C96 pop hl ret ;АДРЕС: #0C98 остановка контроллера ВГ93 ;вых: a - значение выведенное в порт #FF x0C98 call x0356 ;подготовка байта для выбора заданного дисковода and %11111011 out (#FF),a ;сброс ВГ93 nop nop nop or #04 out (#FF),a ;загрузка головки, сторона верхняя, метод записи push af ld a,#D0 out (#1F),a ;команда прерывания pop af ret ;АДРЕС: #0CAD таблица адресоф функций R8DOS x0CAD dw x029C ;#00(0) сброс контроллера dw x03C5 ;#01(1) выбор текущего дисковода dw x0457 ;#02(2) позиционирование на заданный логический трек dw x05D8 ;#03(3) игнорирование ошибки и продолжение выполнения функции 5 (или 6) dw x054E ;#04(4) повторить в случае ошибки функцию 5 (или 6) dw x0553 ;#05(5) чтение группы секторов dw x0557 ;#06(6) запись группы секторов dw x084F ;#07(7) идентификация диска dw x08D4 ;#08(8) идентификация диска для tr-dos dw x0922 ;#09(9) установка рабочего буфера для функции 8 dw x077F ;#0A(10) построение таблицы расположения секторов на дорожке, начиная от индексного маркера dw x0948 ;#0B(11) форматирование дорожки dw x0B94 ;#0C(12) чтение дорожки dw x0B98 ;#0D(13) запись дорожки dw x0502 ;#0E(14) физическое позиционирование на трек dw x0B67 ;#0F(15) замена идентификатора в таблице расположения секторов dw x032B ;#10(16) чтение/установка спецификации дискеты dw x0335 ;#11(17) чтение кода спецификации дисковода dw x0546 ;#12(18) в hl адрес таблицы с количеством секторов на дорожке dw x02CA ;#13(19) установка режима time-out для счетчика включения двигателя дисковода dw x11DB ;#14(20) открыть файл для последующих операций с ним dw x1307 ;#15(21) закрыть файл, открытый функцией 20 dw x1240 ;#16(22) чтение очередного байта из файла. файл должен быть открыт как "логический". dw x128C ;#17(23) запись байта в файл. Файл должен быть открыт как "логический" dw x14C0 ;#18(24) удаление файла, адрес спецификации которого задан в регистрах hl dw x111E ;#19(25) физический поиск файла, указанного в fcb, в каталоге диска dw x1125 ;#1A(26) !!!ОШИБКА!!! маски, после первого поиска больше нету dw x11B0 ;#1B(27) разбор спецификации файла и построение на ее основе блока управления (fcb) dw x1365 ;#1C(28) последовательное чтение очередного сектора из файла dw x1395 ;#1D(29) последовательная запись одного сектора из памяти dw x1360 ;#1E(30) последовательное считывание заданного количества секторов dw x1390 ;#1F(31) последовательная запись заданного количества секторов dw x1407 ;#20(32) установка нового значения указателя в файле dw x1545 ;#21(33) чтение из fcb в bc указателя файла dw x1E74 ;#22(34) идентификация жесткого диска dw x187F ;#23(35) подключение раздела к драйверу HDD dw x1B7E ;#24(36) прямое чтение секторов из подраздела жесткого диска dw x1BC0 ;#25(37) прямая запись секторов в подраздел жесткого диска dw x1BFE ;#26(38) Вернуть таблицу (каталог) подраздела dw x1C2D ;#27(39) чтение/запись сектора (???ОШИБКА???) dw x18C0 ;#28(40) подключение раздела к драйверу HDD ;АДРЕС: #0CFF установка переменных дисковой BIOS x0CFF ld bc,#FFBA ld a,%11110111 ;запрет прерываний от PIC ld (xDFF0),a out (c),a ;регистр данных ld bc,#7FBA ;регистр виртуальных дисководов ld a,#FF ld (xDFEE),a out (c),a ld hl,x0D1F ld de,xFFC0 ld bc,#0032 ldir ret ;переменные дисковой BIOS x0D1F db #1A,#0F,#08,#04 ;MFM максимальное число секторов на дорожке для сектора 128/256/512/1024 db #16,#10,#09,#05 ;FM максимальное число секторов на дорожке для сектора 128/256/512/1024 dw #FFC0 ;адрес таблицы с количеством секторов на дорожке db #00 ;номер текущего дисковода: 0 - дисковода А, 1 - В db #03 ;число попыток считывания при ошибке, начальное значение 3 db #C0,#C0,#C0,#C0 ;коды, определяющие тип дисковода (спецификацию) A/B/C/D db #A1,#A1,#A1,#A1 ;коды, определяющие тип дискеты в дисководе А/B/C/D db #00,#00,#00,#00 ;текущий номер дорожки для дисковода A/B/C/D db #FF,#FF,#FF,#FF ;код time-out для дисковода А/B/C/D db #00 ;флаги R8DOS db #FF ;код ошибки дискового интерпретатора ds #11,0 ;прочие переменные db #C9 ;ret для вызова п/п опроса Break из rom 5 dw #0000 ;адрес рабочего буфера для функции 8 ;АДРЕС: #0D51 определение наличия SMUC ;вых: cy=1 SMUC не найден x0D51 ld bc,#00FE call x0E01 jr c,x0DA1 ;SMUC не найден ld l,a inc bc call x0E01 jr c,x0DA1 ld h,a ret ;АДРЕС: #0D62 определение наличия NVRAM x0D62 call x0D51 ;определение наличия SMUC ret c ;если SMUC отсутствует. то и NVRAM тоже call x0DE8 jr c,x0DA1 ;NVRAM не найден sbc hl,de jr z,x0D8E x0D6F rst #30 dw rom4_x0378 ;запись переменных в NVRAM db #04 ld bc,#0000 ld a,#61 call x0E4B ;запись числа в A в ячейку NVRAM в BC jr c,x0DA1 call x0DE8 jr c,x0DA1 call x0E72 jr c,x0DA1 call x0D9A ld a,#33 ;сообщение: NVRAM checksum error scf ret x0D8E ld bc,#0000 call x0E01 jr c,x0DA1 ;NVRAM не найден cp #61 jr nz,x0D6F ;контрольное значение не совпадает. перезаписываем переменные x0D9A set 5,(iy+#1A) ld a,#27 ;сообщение: NVRAM found ret x0DA1 ld a,#26 ;сообщение: NVRAM not found scf ret ;АДРЕС: #0DA5 cy=1, a=#01 !!!Not Used!!! x0DA5 ld a,#01 scf ret ;АДРЕС: #0DA9 cy=1, a=#02 !!!Not Used!!! x0DA9 ld a,#02 scf ret ;АДРЕС: #0DAD чтение всей памяти NVRAM в память #7530 x0DAD ld hl,#7530 ld de,#0800 ld bc,#0000 ;АДРЕС: #0DB6 чтение данных из NVRAM ;вх: hl - адрес куда читать ; de - сколько читать ; bc - адрес в NVRAM для чтения x0DB6 call x0E01 jr c,x0DC4 ld (hl),a inc hl inc bc dec de ld a,e or d jr nz,x0DB6 ret ;ошибки чтения NVRAM x0DC4 ld a,#69 ;сообщение: NVRAM R/W error ret ;АДРЕС: #0DC7 запись всей памяти NVRAM из памяти #7530 x0DC7 ld hl,#7530 ld de,#0800 ld bc,#0000 ;АДРЕС: #0DD0 запись данных в NVRAM ;вх: hl - адрес откуда записывать ; de - сколько читать ; bc - адрес в NVRAM для записи x0DD0 ld a,(hl) call x0E4B ;запись одной ячейки NVRAM jr c,x0DC4 inc hl inc bc dec de ld a,e or d jr nz,x0DD0 call x0DE8 jr c,x0DC4 call x0E72 jr c,x0DC4 ret x0DE8 ld de,#FFFF ld bc,#0000 x0DEE call x0E01 ret c call x220F ;суммирование байта с контрольной суммой CRC8 inc bc ld a,#FE cp c jr nz,x0DEE ld a,#00 cp b jr nz,x0DEE ret x0E01 push bc exx ex (sp),hl exx push hl push de push af call x0F42 call x0E91 jr nz,x0E41 call x0EB1 call x0EF7 call x0EDE jr nz,x0E41 call x0F2C call x0EA5 set 0,d call x0EF7 call x0EDE jr nz,x0E41 call x0EB8 call x0EDE x0E31 call x0F1C call x0F3E pop af ld a,d or a x0E3A pop de pop hl exx ex (sp),hl exx pop bc ret x0E41 call x0F1C call x0F3E pop af scf jr x0E3A ;запись числа в A в ячейку NVRAM в BC x0E4B push bc exx ex (sp),hl ;адрес в NVRAM exx push hl push de push af ld e,a call x0F42 call x0E91 jr nz,x0E41 call x0EB1 call x0EF7 call x0EDE jr nz,x0E41 ld d,e call x0EF7 call x0EDE jr nz,x0E41 ld d,e jr x0E31 ;АДРЕС: #0E72 что-то пишет в NVRAM x0E72 ld bc,#00FE ld a,e call x0E4B ;запись числа в A в ячейку NVRAM в BC ret c inc bc ld a,d call x0E4B ;запись числа в A в ячейку NVRAM в BC ret c push bc exx ex (sp),hl exx push hl push de push af call x0F42 call x0E91 jr nz,x0E41 jr x0E31 x0E91 ld l,#C8 x0E93 call x0F2C call x0EA5 call x0EF7 call x0EDE ret z dec l jr nz,x0E93 scf ret x0EA5 push af exx ld a,h exx and #07 rlca or %10100000 ld d,a pop af ret x0EB1 push af exx ld a,l exx ld d,a pop af ret x0EB8 push hl ld l,#08 and %10111111 or %00010000 out (c),a x0EC1 call x0F52 or %01000000 out (c),a nop nop in h,(c) sla h sla h rl d call x0F52 and %10111111 out (c),a dec l jr nz,x0EC1 pop hl ret x0EDE or %00010000 out (c),a call x0F52 or %01000000 out (c),a push hl in l,(c) call x0F52 and %10111111 out (c),a bit 6,l pop hl ret x0EF7 push hl ld l,#08 and %10111111 out (c),a x0EFE push bc pop bc and %11101111 rl d jr nc,x0F08 or %00010000 x0F08 out (c),a push bc pop bc or %01000000 out (c),a call x0F52 and %10111111 out (c),a dec l jr nz,x0EFE pop hl ret x0F1C and %11101111 out (c),a call x0F52 or %01000000 out (c),a call x0F52 jr x0F4A x0F2C or %01010000 out (c),a call x0F52 and %11101111 out (c),a call x0F52 and %10111111 jr x0F4C x0F3E or %00100000 jr x0F4A x0F42 ld bc,#FFBA ld a,(xDFF0) and #DF ;%11011111 x0F4A or #50 ;%01010000 x0F4C ld (xDFF0),a out (c),a ret x0F52 push bc pop bc ret x0F55 db #00,#08,#00,#00 ;для сравнения чисел x0F59 db #00,#02,#00,#00 ;для сравнения чисел ;АДРЕС: #0F5D деление de'hl'=de'hl'/bc ;вх: de'hl' - делимое ; bc - делитель ;вых: de'hl' - значение ; hl остаток от деления ; x0F5D ld hl,#0000 push hl ld e,l ld d,h exx ld b,#20 x0F66 xor a rl l rl h rl e rl d exx rl l rl h rl e rl d rla or a sbc hl,bc ex (sp),hl ex de,hl sbc hl,de ex de,hl ex (sp),hl exx sbc a,#00 jr nz,x0FAD x0F87 inc l djnz x0F66 inc sp inc sp exx ret x0F8E xor a rl l rl h rl e rl d exx rl l rl h rl e rl d rla add hl,bc ex (sp),hl ex de,hl adc hl,de ex de,hl ex (sp),hl exx sbc a,#00 jr z,x0F87 x0FAD djnz x0F8E exx add hl,bc jr nc,x0FB4 inc de x0FB4 inc sp inc sp ret ;АДРЕС: #0FB7 умножение dehl=de'hl' * bc ;вх: de'hl' - первый множитель ; bc - второй множитель ;вых: dehl - значение ; x0FB7 ld hl,#0000 push hl ld e,l ld d,h exx ld b,#20 x0FC0 exx xor a rl l rl h rl e rl d exx rl l rl h rl e rl d jr nc,x0FED exx add hl,bc ld a,e adc a,#00 ld e,a ld a,d adc a,#00 ld d,a exx jr nc,x0FED ld l,a adc a,#00 ld l,a ld h,a adc a,#00 ld h,a jr nc,x0FED inc de x0FED djnz x0FC0 exx inc sp inc sp ret ;АДРЕС: #0FF3 инкремент dehl ;вх: dehl - число ;вых: dehl=dehl + 1 ; x0FF3 ld c,#00 ld a,l add a,#01 ld l,a ld a,h adc a,c ld h,a ld a,e adc a,c ld e,a ld a,d adc a,c ld d,a ret ;АДРЕС: #1003 копирование из (hl) в (de) 4х байт x1003 push bc push hl push de ld bc,#0004 ldir pop de pop hl pop bc ret ;АДРЕС: #100F загрузка числа в регистры из памяти ;вх: hl - адрес откуда грузим ;вых: dehl - число x100F push hl pop bc ld a,(bc) ld l,a inc bc ld a,(bc) ld h,a inc bc ld a,(bc) ld e,a inc bc ld a,(bc) ld d,a ret ;АДРЕС: #101D сложение 4х байтного числа с двухбайтным ;вх: de - адрес 2х байтного числа ; hl - адрес 4х байтного числа ;вых: по адресу hl сумма этих чисел x101D ex de,hl push bc xor a ld b,#02 x1022 ld a,(de) adc a,(hl) ld (de),a inc hl inc de djnz x1022 ld a,(de) adc a,#00 ld (de),a inc hl inc de ld a,(de) adc a,#00 ld (de),a pop bc ret ;АДРЕС: #1035 сравнение двух чисел в памяти по адресам в de и hl ;вх: de - адрес 4х байтного числа e9e7 ; hl - адрес 4х байтного числа e9eb ;вых: nz,c,m - (hl)<(de) ; nz,nc,p - (hl)>(de) ; z,nc,p - (hl)=(de) ; x1035 push bc ex de,hl inc hl inc hl inc hl inc de inc de inc de ld a,(de) or a jp m,x1048 ;(de) отрицательное xor (hl) jp m,x1060 ;(hl) отрицательное jr x104C x1048 xor (hl) jp m,x105B ;(de) отрицательное, (hl) положительное ;сравнение чисел с одинаковым знаком x104C ld b,#04 x104E ld a,(de) cp (hl) jr c,x105B ;(de)<(hl) jr nz,x1060 dec hl dec de djnz x104E xor a pop bc ret ;nz,c,m - (de вх)>(hl вх) x105B xor a sub #01 pop bc ret ;nz,nc,p - (de вх)<(hl вх) x1060 xor a add a,#01 pop bc ret ;АДРЕС: #1065 инициализация дисковода x1065 ld hl,#0000 ld (xDFFE),hl ld (xE000),hl ld a,(xFFCA) ;номер текущего дисковода x1071 ld c,#01 call x0229 ;R8DOS #01(1) xor a ld c,a jp x0229 ;R8DOS #00(0) ;АДРЕС: #107B инициализация дисковода и настройка на дискету ;вых: b - код, определяющий тип дискеты в дисководе ; a - код ошибки x107B call x1065 ;инициализация дисковода jr c,x1097 ;ошибка ld hl,xE5A9 ld (xFFE7),hl ;;адрес рабочего буфера для функции 8 ld c,#08 ;идентификация диска call x0229 ;R8DOS #08(8) push af call x0344 ;hl адрес кода, определяющего тип дискеты в текущем дисководе ld b,(hl) ld hl,#0000 ld (xFFE7),hl ;адрес рабочего буфера для функции 8 pop af x1097 ret nc ld a,(xFFDD) ;код ошибки дискового интерпретатора cp #10 scf ld a,#3F ;дискета не соответствует формату TR-DOS ret z ld a,#50 ;HDD не вышел в готовность ret ;АДРЕС: #10A4 распознавание имени файла и занесение его в fcb ;вх: ix - адрес буфера для fcb ; hl - адрес строки, содержащей имя и тип файла в asciz ;вых: nz - успешно ; z - ошибка ; a=#44(68) - несуществующий номер устройства ; a=#45(69) - ошибка в имени файла ; x10A4 ld a,(xFFCA) ld (ix+#18),a ;номер текущего дисковода ;выделение дисковода из строки ld c,(hl) inc hl ld a,":" cp (hl) jr nz,x10CB ;дисковод не указан ld a,c cp "A"-1 jr c,x10BA ;не буква and #5F sub #11 x10BA sub #30 jr nc,x10C2 x10BE ld a,#44 ;несуществующий дисковод or a ret x10C2 cp #04 jr nc,x10BE ;несуществующий дисковод ld (ix+#18),a ;номер дисковода inc hl inc hl x10CB ld (ix+#08),"C" ;тип файла по умолчанию dec hl ;распознаем имя и расширение файла push ix pop de ld bc,#0009 x10D6 rst #30 dw rom2_x0D46 ;проверка символа в (hl) #2C/#3B/#00/#0D db #02 jr z,x1102 ;символ конца имент cp #2E ;. jr nz,x10E7 ;допустимый в имени символ inc hl call x110F ;проверка символа расширения файла jr z,x10F7 ;допустимый символ расширения dec hl ;иначе распознаем точку как символ имени файла x10E7 ldi jp pe,x10D6 x10EC rst #30 ;имя и расширение заполнено dw rom2_x0D42 ;проверка символа в (hl) #20/#2C/#3B/#00/#0D db #02 scf ccf ret z ;конец строки x10F3 ld a,#45 ;ошибка в имени файла or a ret x10F7 ld (ix+#08),a call x1102 ;заполнение остатка имени пробелами jr nz,x10F3 ;пустое имя. ошибка в имени файла inc hl jr x10EC ;проверка остатка строки x1102 ld a,#09 cp c jr z,x10F3 ;пустое имя. ошибка в имени файла x1107 dec c ;заполнение остатки мени пробелами ret z ld a," " ld (de),a inc de jr x1107 ;проверка символа расширения файла x110F ld a,(hl) cp #23 ;# ret z and %11011111 cp #43 ;C ret z cp #42 ;B ret z cp #44 ;D ret ;АДРЕС: #111E R8DOS #19(25) физический поиск файла, указанного в fcb, в каталоге диска ;вх: ix - адрес буфера fcb (в имени файла допустимы заменители '?') ;вых: cy=1, если были ошибки, код ошибки возвращается в аккумуляторе или флаге Z ; a=#50(80) - ошибка диска ; cy=0, z - файл не найден ; cy=0, nz - файл найден и скопирован в fcb ; x111E call x153D ;копирование дескриптора дисковода в буфер call x107B ;инициализация дисковода ret c ;ошибка ;АДРЕС: #1125 R8DOS #1A(26) продолжает поиск файла, указанного в fcb !!!ОШИБКА!!! маски, после первого поиска больше нету ;вх: ix - адрес буфера fcb (в имени файла допустимы заменители '?') ;вых: cy=1, если были ошибки, код ошибки возвращается в аккумуляторе или флаге Z ; a=#50(80) - ошибка диска ; cy=0, z - файл не найден ; cy=0, nz - файл найден и скопирован в fcb ; x1125 push hl x1126 pop hl call x1166 ;загрузка очередного дескриптора файла в буфер ld (ix+#19),c ret c ;ошибка загрузки: a=#50 ret z ;конец каталога. файл не найден ;сравнение имени файла с маской поиска push hl push ix pop de ld b,#09 x1135 ld a,(de) cp "?" jr z,x113D cp (hl) jr nz,x1126 ;не совпало, следующее имя файла x113D inc hl inc de djnz x1135 pop hl ;файл найден. копируем дескриптор в fcb x1142 push hl ld bc,#0010 push ix pop de ldir pop hl inc b ;флаг nz ret ;АДРЕС: #114E загрузка дескриптора файла в буфер ;вх: c - номер файла на диске ;вых: cy=1 -> a=#50 ошибка чтения диска ; hl - адрес дескриптора файла в буфере ; c - номер этого файла на диске [#00..#7F] x114E ld hl,xDFFE ld a,c and %01110000 rrca rrca rrca rrca ld (hl),a ;номер сектора inc hl inc a ld (hl),a ;номер следующего сектора inc hl ld a,c and #0F dec a ld (hl),a ;номер записи в секторе dec hl ld a,(hl) jr x1177 ;АДРЕС: #1166 загрузка очередного дескриптора файла в буфер ;вых: cy=1 -> a=#50 ошибка чтения диска ; cy=0, z - конец каталога. файл не найден ; cy=0, nz - дескриптор найден ; hl - адрес дескриптора файла в буфере ; c - номер этого файла на диске [#00..#7F] x1166 ld hl,xDFFE ld a,(hl) inc a inc hl cp (hl) inc hl jr z,x1182 ;сектор уже загружен ld (hl),#FF ;сброс номера дескриптора файла cp #09 ret nc ;выход. конец каталога dec hl ld (hl),a ;номер следующего сектора x1177 inc hl push hl ld e,a dec e ;e - номер сектора call x1567 ;чтение одного сектора нулевой дорожки в буфер pop hl ld a,#50 ret c ;ошибка x1182 ld a,(hl) inc a cp #10 jr c,x118D ;следующий номер дескриптора файла в загруженном секторе dec hl ;нет больше записей в загруженном секторе dec hl inc (hl) jr x1166 ;грузим следующий сектор x118D ld (hl),a ;номер дескриптора файла в загруженном секторе [#0..#F] rlca rlca rlca rlca ld hl,xE5A9 ;буфер загруженного сектора call x11AB ;hl=hl+a*#10 (адрес дескриптора файла) ld a,(xDFFE) ;номер загруженного сектора [#01..#10] rlca rlca rlca rlca ld c,a ld a,(xE000) ;номер дескриптора файла в загруженном секторе [#0..#F] or c ld c,a ;номер дескрптора файла на диске [#00..#7F] inc a ;установка флага nz ret ;АДРЕС: #11A7 получение адреса байта в буфере dma ;вх: c - смещенеи в буфере x11A7 call x1553 ;чтение из fcb в hl адреса буфера dma ld a,c x11AB add a,l ld l,a ret nc inc h ret ;АДРЕС: #11B0 R8DOS #1B(27) разбор спецификации файла и построение на ее основе блока управления (fcb) ;вх: hl - адрес строки имени файла в asciz ; ix - адрес буфера создаваемого fcb ; de - адрес буфера dma ; b - способ открытия ;вых: cy=1, если были ошибки, код ошибки возвращается в аккумуляторе: ; a=#4A(74) - неверный тип файла ; a=#44(68) - несуществующий номер устройства ; a=#45(69) - ошибка в имени файла ; ix - адрес буфера fcb ; x11B0 push bc ;очищаем блок fcb push ix ex (sp),hl ld b,#1C xor a x11B7 ld (hl),a inc hl djnz x11B7 pop hl pop bc ld (ix+#15),e ;адрес буфера ld (ix+#16),d ld (ix+#17),b ;способ открытия ld a,#03 ;проверка типа открытия файла and b ld a,#4A ccf ret z call x10A4 ;распознавание имени файла и занесение его в fcb scf ret nz ;ошибка распознавания or a ret ;АДРЕС: #11D4 открыть файл(для нужд монитора) для последующих операций с ним x11D4 ld de,xE8A9 ;адрес буфера dma ld ix,xE7A9 ;адрес буфера для fcb ;АДРЕС: #11DB R8DOS #14(20) открыть файл для последующих операций с ним ;вх: ix - адрес буфера для fcb ; hl - адрес строки, содержащей имя и тип файла в asciz ; de - адрес буфера dma ; b - способ открытия ; 2,b =1 обмен целыми секторами "физический" файл ; (если сброшен - обмен будет вестись байтами "логический" файл) ; 1,b =1 файл для записи ; 0,b =1 файл для чтения ; 0-1,b=11 файл для модификации ;вых: cy=1, если были ошибки, код ошибки возвращается в аккумуляторе: ; a=#47(71) - нельзя открыть существующий файл только для записи ; a=#48(72) - нельзя создать файл только для чтения ; a=#49(73) - нет места на диске ; a=#4A(74) - неверный тип файла ; a=#44(68) - несуществующий номер устройства ; a=#45(69) - ошибка в имени файла ; cy=0 - успешно ; bc - длина файла в байтах ; x11DB call x11B0 ;разбор спецификации файла ret c ;ошибка ;АДРЕС: #11DF открыть файл для последующих операций с ним x11DF call x111E ;поиск файла на диске по имени в fcb ret c ;ошибка чтения диска jr z,x1200 ;файл не найден bit 0,(ix+#17) ;файл найден ld a,#47 scf ret z ;нельзя открыть существующий файл только для записи xor a bit 2,(ix+#17) jr nz,x11FB ;обмен секторами ld c,(ix+#0B) ld b,(ix+#0C) ;bc - длина файла ret x11FB ld c,a ld b,(ix+#0D) ;bc - длина файла (кратна сектору) ret x1200 bit 1,(ix+#17) ;файл не найден ld a,#48 scf ret z ;нельзя создать файл только для чтения call x107B ret c ;ошибка чтения/записи ld a,(xE5A9+#E4) ;xE68D количество файлов на дискете ld (ix+#19),a ;номер файла на дискете cp #80 ld a,#49 ccf ret c ;нет места на диске ld bc,(xE5A9+#E5) ;xE68E кол-во свободных секторов ld a,c or b ld a,#49 ccf ret z ;нет места на диске ld a,b or a jr z,x1228 ld c,#FF x1228 ld (ix+#1B),c ;максимальный объем файла в секторах ld hl,(xE5A9+#E1) ;xE68A номер первой свободной дорожки и сектора ld (ix+#0E),l ;сектор ld (ix+#0F),h ;дорожка ld a,b or a jr nz,x123C ld b,c ld c,#00 ;максимальный размер файла в байтах ret x123C ld bc,#FFFF ;!!!ОШИБКА!!! должно быть ld bc,#FF00 ret ;АДРЕС: #1240 R8DOS #16(22) чтение очередного байта из файла. файл должен быть открыт как "логический". ;вх: ix - адрес буфера fcb ;вых: cy=1 были ошибки ; a - код ошибки возвращается в аккумуляторе ; a - очередной считанный байт (при cy=0) x1240 ld c,(ix+#17) bit 0,c ld a,#4A scf ret z ;ошибка. файл открыт на запись bit 2,c call x1545 ;чтение из fcb в bc указателя файла jr nz,x125E ;файл открыт как физический (чтение целых секторов) call x154C ;чтение из fcb в hl длины файла or a sbc hl,bc jr z,x125A jr nc,x125E x125A scf ;ошибка. конец файла ld a,#46 ret x125E ld a,c or a jr nz,x126C ;указатель не в начале сектора ld a,b cp (ix+#0D) jr nc,x125A ;ошибка. конец файла call x1472 ;чтение сектора в буфер dma ret c ;ошибка чтения x126C call x11A7 ;получение адреса байта в буфере dma ld a,(hl) ld (ix+#1A),a ld a,#FF cp c jr nz,x1287 ;еще не конец сектора ld a,(ix+#17) bit 1,a jr z,x1287 ;файл открыт для чтения bit 7,a jr z,x1287 ;файл не был изменен call x1484 ;сохранение буфера dma в файл ret c ;ошибка записи x1287 ld a,(ix+#1A) jr x12FE ;установка в fcb нового указателя в файле из bc ;АДРЕС: #128C R8DOS #17(23) запись байта в файл. Файл должен быть открыт как "логический" ;вх: ix - адрес буфера fcb ; a - байт для записи ;вых: cy=1 были ошибки ; a - код ошибки возвращается в аккумуляторе x128C ld (ix+#1A),a call x1545 ;чтение из fcb в bc указателя файла ld e,(ix+#17) bit 1,e ld a,#4A ;!!!ОШИБКА!!! не устанавливается cy ret z ;ошибка. файл открыт на чтение bit 0,e jr z,x12B8 ;файл открыт только на запись bit 2,e ;обмен целыми секторами "физический" файл jr nz,x12B8 ;запись байта в файл call x154C ;чтение из fcb в hl длины файла or a sbc hl,bc jr z,x12AC ;ошибка #46. конец файла jr nc,x12B8 ;запись байта в файл x12AC bit 7,e jr z,x12B4 ;изменение в файле не было call x1484 ;сохранение буфера dma в файл ret c ;ошибка записи ;код ошибки #46. конец файла x12B4 ld a,#46 scf ret ;запись байта в файл x12B8 ld a,c or a jr nz,x12EA ;указатель не в начале сектора bit 0,e jr nz,x12DB ;файл открыт для модификации ld a,b cp (ix+#1B) jr nc,x12D3 ;попытка записи после конца файла ld a,(ix+#0D) cp #FF jr nz,x12E7 ;увеличение размена файла на один сектор call x1329 ;создание записи в каталоге диска ret c ;ошибка записи jr x12B4 ;ошибка #46. конец файла ;ошибка #49. попытка записи после конца файла x12D3 call x1329 ;создание записи в каталоге диска ret c ld a,#49 ;ошибка #49. попытка записи после конца файла scf ret x12DB ld a,b cp (ix+#0D) jr nc,x12B4 ;ошибка #46. конец файла call x1472 ;чтение сектора в буфер dma ret c ;ошибка чтения jr x12EA x12E7 inc (ix+#0D) ;увеличим размер файла в секторах x12EA call x11A7 ;получение адреса байта в буфере dma ld a,(ix+#1A) ld (hl),a ;запись файла в буфер set 7,(ix+#17) ;файл был изменен, но не сохранен ld a,c cp #FF jr nz,x12FE ;установка в fcb нового указателя в файле из bc call x1484 ;сохранение буфера dma в файл ret c ;ошибка записи x12FE inc bc ;АДРЕС: #12FF установка в fcb указателя в файле из bc x12FF ld (ix+#13),c ld (ix+#14),b or a ret ;АДРЕС: #1307 R8DOS #15(21) закрыть файл, открытый функцией 20. При закрытии ; файла происходит дозапись (при необходимости) информации из ; открытых буферов ;вх: ix - адрес буфера fcb ;вых: cy=1 - были ошибки ; a - код ошибки x1307 call x1545 ;чтение из fcb в bc указателя файла ld a,c or b jr z,x130F ;файл пустой dec bc x130F call x12FF ;установка в fcb указателя в файле из bc ld a,(ix+#17) bit 1,a ret z ;файл только для чтения bit 7,a jr z,x1320 ;не сохраненных изменений нет call x1484 ;сохранение буфера dma в файл ret c ;была ошибка x1320 bit 0,(ix+#17) ret nz ;файл для модификации call x1545 ;чтение из fcb в bc указателя файла inc bc ;создание записи в каталоге диска ;вх: bc - длина файла в байтах x1329 call x1440 ;сохранение из bc в fcb длины файла в байтах и секторах call x13D5 ;создание записи в каталоге диска (на основе fcb) ret c call x107B ;чтение в буфер служебного сектора ret c ld a,(xE5A9+#E4) ;xE68D inc a ld (xE5A9+#E4),a ;xE68D количество файлов +1 ld hl,(xE5A9+#E5) ;xE68E ld c,(ix+#0D) ld b,#00 or a sbc hl,bc ld (xE5A9+#E5),hl ;xE68E оставшееся свободное место в секторах ld b,c call x14A6 ;расчет нового номера дорожки и сектора ld (xE5A9+#E1),de ;xE68A первая свободная дорожка и сектор ld de,#0008 ;запишем служебный сектор ;запись буфера на диск (d - дорожка, e - сектор) x1354 ld hl,xE5A9 x1357 ld bc,#0106 call x0229 ld a,#50 ret ;АДРЕС: #1360 R8DOS #1E(30) последовательное считывание заданного количества ; целых секторов. Функция 30 (R_MS) подобна многократному ; выполнению функции #1C(28), с той лишь разницей, что значение, ; указанное в поле dma не изменяется. В случае ошибки полагается, ; что все сектора не считались ;вх: ix - адрес буфера fcb ; b - число считываемых секторов ;вых: cy=1 если были ошибки ; a - код ошибки x1360 ld (ix+#1A),b jr x1369 ;АДРЕС: #1365 R8DOS #1C(28) последовательное чтение очередного сектора из файла, ; содержимое сектора размещается в памяти с адреса, указанного полем ; dma в блоке управления файлом (fcb). Для обеспечения максимальной ; скорости выполнения операции Файл должен быть открыт как ; "физический". Если файл был в режиме "логический" и если ; предварительно был считан байт (т. е. счетчик указывает не на ; границу целого сектора) подфункцией будет "пересчитан" текущий ; сектор. Максимальный номер сектора - 254. ;вх: ix - адрес буфера fcb ;вых: cy=1 если были ошибки ; a - код ошибки x1365 ld (ix+#1A),#01 x1369 bit 0,(ix+#17) ld a,#4A scf ret z ;ошибка. файл открыт на запись call x1545 ;чтение из fcb в bc указателя файла ld c,#00 ld a,b add a,(ix+#1A) jp c,x12B4 ;ошибка #46. конец файла dec a cp (ix+#0D) jp nc,x12B4 ;ошибка #46. конец файла call x148D ;чтение секторов в буфер dma ret c ;ошибка чтения x1388 ld a,b add a,(ix+#1A) ld b,a jp x12FF ;установка в fcb нового указателя в файле из bc ;АДРЕС: #1390 R8DOS #1F(31) последовательная запись заданного количества ; секторов. Подфункция 31 (W_MS) подобна многократному выполнению ; подфункции #1D(29), с той лишь разницей, что значение, указанное ; в поле dma не изменяется. В случае ошибки полагается, что все ; сектора, принимавшие участие в операции получили случайные ; значения. ;вх: ix - адрес буфера fcb ; b - число записываемых секторов ;вых: cy=1 если были ошибки ; a - код ошибки x1390 ld (ix+#1A),b jr x1399 ;АДРЕС: #1395 R8DOS #1D(29) последовательная запись одного сектора из памяти с ; адреса, указанного полем dma в блоке управления файлом (fcb), в ; файл ;вх: ix - адрес буфера fcb ;вых: cy=1 если были ошибки ; a - код ошибки x1395 ld (ix+#1A),#01 x1399 ld e,(ix+#17) bit 1,e ld a,#4A ret z ;!!!ОШИБКА!!! cy не установлен call x1545 ;чтение из fcb в bc указателя файла ld c,#00 ld a,b add a,(ix+#1A) jp c,x12B4 ;ошибка #46 конец файла dec a bit 0,e jr nz,x13BA ;файл открыт на модификацию cp (ix+#1B) jp nc,x12D3 ;ошибка #49. попытка записи после конца файла jr x13C0 x13BA cp (ix+#0D) jp nc,x12B4 ;ошибка #46. конец файла x13C0 call x1498 ;запись секторов из буфера dma ret c ;ошибка записи bit 0,(ix+#17) jr nz,x1388 ;файл для модификации ld a,(ix+#0D) add a,(ix+#1A) ld (ix+#0D),a ;новый размер файла jr x1388 ;АДРЕС: #13D5 создание записи в каталоге диска (на основе fcb) x13D5 call x153D ;копирование дескриптора дисковода в буфер ld b,#04 ld d,#00 ld e,(ix+#19) ;номер файла на диске x13DF sla e rl d djnz x13DF ;de - адрес дескриптора в каталоге диска push de ld e,d call x1567 ;чтение одного сектора нулевой дорожки в буфер (e - номер сектора) pop de ld a,#50 ret c ;ошибка чтения push de ld d,#00 ld hl,xE5A9 add hl,de ;адрес дескриптора в буфере ex de,hl ld bc,#0010 push ix pop hl ldir ;копируем дескриптор файла из fcb в буфер pop de ld e,d ld d,#00 jp x1354 ;запись буфера на диск (дорожка 0, e - сектор) ;АДРЕС: #1405 установка нового значения указателя в файле ;вх: ix - адрес буфера fcb ; bc - новое значение указателя ;вых: cy=1 - если были ошибки ; a - код ошибки x1405 ld e,c ld d,b ;АДРЕС: #1407 R8DOS #20(32) установка нового значения указателя в файле ;вх: ix - адрес буфера fcb ; de - новое значение указателя ;вых: cy=1 - если были ошибки ; a - код ошибки x1407 call x1545 ;чтение из fcb в bc указателя файла ld a,(ix+#17) bit 0,a jr nz,x1419 ;файл для чтения ex de,hl add hl,bc ex de,hl jr nc,x1419 ;нет переполнения ld a,#46 ;ошибка #46 конец файла ret x1419 bit 1,a jr z,x144F ;файл только для чтения ld a,d cp b jr z,x142D ;новый указатель в пределах текущего сектора bit 7,(ix+#17) jr z,x142D ;не сохраненных изменений в файле нет push de call x1484 ;сохранение буфера dma в файл pop de ret c ;ошибка записи x142D bit 0,(ix+#17) jr nz,x144F ;файл открыт на модификацию ld a,d cp (ix+#1B) ;максимальный объем файла в секторах jp nc,x12B4 ;ошибка #46 конец файла ld b,d ld c,e call x12FF ;установка в fcb указателя в файле из bc inc bc ;сохранение из bc в fcb длины файла в байтах и секторах x1440 ld (ix+#0B),c ld (ix+#0C),b ;длина файла в байтах ld a,c or a jr z,x144B inc b x144B ld (ix+#0D),b ;длина файла в секторах ret ;файл только для чтения x144F bit 2,(ix+#17) jr z,x145E ;обмен байтами "логический" файл ld a,d cp (ix+#0D) jp nc,x12B4 ;ошибка #46. конец файла jr x146A x145E call x154C ;чтение из fcb в hl длины файла push de ex de,hl or a sbc hl,de pop de jp nc,x12B4 ;ошибка #46. конец файла x146A ld c,e ld b,d ;новый указатель call x12FF ;установка в fcb указателя в файле из bc ld a,c or a ret z ;АДРЕС: #1472 чтение сектора в буфер dma x1472 push bc call x14A0 ;расчет адреса в файле на диске (дорожка и сектор) ld bc,#0105 ;запись/чтение сектора x1479 call x0229 pop bc ld a,#50 res 7,(ix+#17) ret ;АДРЕС: #1484 сохранение буфера dma в файл ;вх: bc - указатель из fcb x1484 push bc call x14A0 ;расчет адреса в файле на диске (дорожка и сектор) ld bc,#0106 jr x1479 ;запись сектора ;АДРЕС: #148D чтение секторов в буфер dma ;вх: bc - указатель в файле x148D push bc call x14A0 ;расчет адреса в файле на диске (дорожка и сектор) ld c,#05 x1493 ld b,(ix+#1A) jr x1479 ;чтение секторов ;АДРЕС: #1498 запись секторов из буфера dma x1498 push bc call x14A0 ;расчет адреса в файле на диске (дорожка и сектор) ld c,#06 jr x1493 ;АДРЕС: #14A0 расчет адреса в файле на диске (дорожка и сектор) ;вх: bc - указатель в файле ;вых: d - дорожка ; e - сектор x14A0 call x153D ;копирование дескриптора дисковода в буфер call x1553 ;чтение из fcb в hl адреса буфера dma ;АДРЕС: #14A6 расчет нового номера дорожки и сектора ;вх: b - кол-во секторов ;вых: d - новый номер дорожки ; e - новый номер сектора x14A6 ld a,b and #F0 rrca rrca rrca rrca add a,(ix+#0F) ;+номер начальной дорожки файла ld d,a ;новый номер дорожки ld a,b and #0F add a,(ix+#0E) ;+номер первого сектора файла bit 4,a jr z,x14BC inc d x14BC and #0F ld e,a ;новый номер сектора ret ;АДРЕС: #14C0 R8DOS #18(24) удаление файла, адрес спецификации которого задан в регистрах hl ;вх: ix - адрес буфера для fcb ; hl - имя и тип в asciz ;вых: cy=1 - были ошибки ; a - код ошибки x14C0 ld b,#01 call x11B0 ;R8DOS #1B(27) разбор спецификации файла и построение на ее основе блока управления (fcb) ret c ;были ошибки call x111E ;R8DOS #19(25) физический поиск файла, указанного в fcb, в каталоге диска ret c ;были ошибки ld a,#48 ;ошибка #48 файл не найден scf ret z push hl ld hl,xE6A9 ld bc,#0105 ld de,#0008 call x0229 ;чтение служебного сектора pop hl ld a,#50 ret c ;ошибка #50. диск не вышел в готовность ld a,(xE6A9+#E4) dec a cp (ix+#19) jr z,x14FD ;этот файл последный на диске ld hl,xE6A9+#F4 inc (hl) ;количество удаленных файлов +1 ld (ix+#00),#01 ;признак удаленного файла call x13D5 ;создание записи в каталоге диска (на основе fcb) ret c ;ошибка записи x14F4 ld hl,xE6A9 ld de,#0008 jp x1357 ;запись служебного сектора на диск ;удаляемый файл последний в каталоге x14FD ld hl,xE6A9+#E4 dec (hl) ;количество файлов -1 ld e,(ix+#0D) ld d,#00 ;объем удаляемого файла в секторах ld hl,(xE6A9+#E5) ;количество свободных секторов add hl,de ld (xE6A9+#E5),hl ;новое количество свободных секторов ld l,(ix+#0E) ld h,(ix+#0F) ld (xE6A9+#E1),hl ;номер первой свободной дорожки и сектора ld (ix+#00),#00 ;признак удаленного файла call x13D5 ;создание записи в каталоге диска (на основе fcb) ret c ;ошибка записи ld c,(ix+#19) ld a,c or a jr z,x14F4 ;файл первый на диске dec c ld (ix+#19),c call x114E ;загрузка дескриптора файла в буфер ret c ;ошибка чтения call x1142 ;копируем дескриптор в fcb ld a,(ix+#00) cp #02 jr nc,x14F4 ;файл существует. запись служебного сектора на диск ld hl,xE6A9+#F4 ;файл удален dec (hl) jr x14FD ;АДРЕС: #153D копирование дескриптора дисковода в буфер x153D ld a,(ix+#18) ;номер дисковода rst #30 dw rom2_x2C4D ;копирование дескриптора дисковода в буфер xE590, db #02 ;если к нему примонтирован образ ret ;АДРЕС: #1545 R8DOS #21(33) чтение из fcb в bc указателя файла ;вх: ix - адрес буфера fcb ;вых: bc - текущее значение указателя x1545 ld c,(ix+#13) ld b,(ix+#14) ret ;АДРЕС: #154C чтение из fcb в hl длины файла x154C ld l,(ix+#0B) ld h,(ix+#0C) ret ;АДРЕС: #1553 чтение из fcb в hl адреса буфера dma x1553 ld l,(ix+#15) ld h,(ix+#16) ret ;АДРЕС: #155A чтение заголовка первого попавшегося сектора дисковода A x155A xor a call x1071 ;инициализация дисковода A call x0394 ;проверка bit 7,(xFFDC) наличие подключенного образа к текущему дисководу ret nz ;к дисководу A подключен образ ld a,#C4 out (#1F),a ;чтение заголовка сектора ret ;АДРЕС: #1567 чтение одного сектора нулевой дорожки в буфер (e - номер сектора) x1567 ld d,#00 ;дорожка 0 ld hl,xE5A9 ;буфер ld bc,#0105 jp x0229 ;R8DOS #05(5) ;АДРЕС: #1572 определение наличия interrupt controller x1572 ld bc,#FFBA ld a,(xDFF0) ;состояние порта #FFBA and #F7 out (c),a ld (xDFF0),a ld bc,#7EBE ld a,#F3 out (c),a nop ld b,#7F ld a,#C5 out (c),a nop ld a,#01 out (c),a nop nop in a,(c) or a jr z,x15A1 cp #01 jr z,x15A5 x159D ld a,#24 ;сообщение: interrupt controller not found scf ret x15A1 set 4,(iy+#1B) x15A5 ld b,#7E ld a,#F2 out (c),a nop ld b,#7F ld a,#C5 out (c),a nop ld a,#FF out (c),a nop nop in a,(c) cp #FF jr nz,x159D set 4,(iy+#1A) xor a ld a,#25 ;сообщение: interrupt controller found ret ;АДРЕС: #15C7 определение наличия последовательного порта/модема ;#28 modem not found ;#29 modem found ;#2A serial port not found x15C7 ld bc,#FFBA ld a,(xDFF0) ;состояние порта #FFBA or %00000110 and %01111110 out (c),a push bc ld b,#0F djnz $ pop bc or %00000001 ld (xDFF0),a ;состояние порта #FFBA out (c),a ld b,#6B djnz $ ld hl,xEA9D xor a or (hl) jr nz,x15F6 ld de,x169A ;сброс модема push hl ex de,hl ld bc,#0007 ldir pop hl x15F6 call x1601 ret c set 5,(iy+#1A) ld a,#29 ;сообщение: modem found ret ; передача команды модему x1601 ld bc,#7AFE ;hl=xEA9D in a,(c) cp #FF jr nz,x160E x160A ld a,#2A ;сообщение: serial port not found scf ret x160E ld a,(hl) bit 6,a jr z,x1647 and #1F or #80 ld b,#7B out (c),a nop in e,(c) cp e jr nz,x160A ;нет порта inc hl ld a,(hl) dec hl and #0F cp #0C jr c,x162C ld a,#05 x162C add a,a ld e,a ld d,#00 push hl ld hl,x16A1 add hl,de ld b,#78 ld a,(hl) out (c),a inc hl ld a,(hl) inc b out (c),a pop hl ld a,(hl) and #1F ld b,#7B out (c),a x1647 bit 5,(hl) jr z,x1658 inc hl ld a,(hl) dec hl and #F0 rlca rlca rlca rlca ld b,#79 out (c),a x1658 or a bit 7,(hl) ret z inc hl x165D inc hl ld a,(hl) or a ret z cp #7C jr nz,x166D ld a,#0D call x1673 ;передача команды модему (в com порт) ret c ld a,#0A x166D call x1673 ;передача команды модему (в com порт) ret c jr x165D ; передача команды модему (в com порт) x1673 push hl push af ld hl,#0814 ;счетчик попыток ld bc,#00FE x167B push bc ld b,#05 in a,(c) pop bc bit 5,a jr nz,x1692 djnz x167B dec hl ld a,h or l jr nz,x167B pop af pop hl ld a,#28 ;modem not found scf ret x1692 pop af ld b,#78 out (c),a or a pop hl ret x169A db %11100011,#05,"ATZ",#7C,#00 ;команда сброса модема x16A1 db #10,#04 ;#00 db #00,#03 ;#01 db #80,#01 ;#02 db #C0,#00 ;#03 db #60,#00 ;#04 db #30,#00 ;#05 db #18,#00 ;#06 db #0C,#00 ;#07 db #06,#00 ;#08 db #03,#00 ;#09 db #02,#00 ;#0A db #01,#00 ;#0B ;АДРЕС: #16B9 работа с контроллером прерываний x16B9 ld hl,x1764 ld de,#9C40 ld bc,#0003 ldir di ld a,#01 ld hl,#9C40 call x175D ;вызов процедуры из основной памяти ld bc,#FFBA ld a,(xDFF0) and #F7 out (c),a ld (xDFF0),a ld bc,#7EBE ld a,#1A out (c),a nop ld b,#7F ld a,#F8 out (c),a nop ld a,#FE out (c),a nop ld b,#0A ld a,#26 ;%00100110 call x1FDD ;запись данных в ячейку CMOS ld b,#0B ld a,#D6 ;%11010110 call x1FDD ;запись данных в ячейку CMOS ld b,#0B ld a,#56 ;%01010110 call x1FDD ;запись данных в ячейку CMOS xor a ld i,a im 2 xor a ld (#7530),a ld bc,#FFBA ld a,(xDFF0) or #08 out (c),a ld (xDFF0),a ei x171A halt ld a,(#7530) or a jr z,x171A di ld a,#05 ld hl,x9C40 call x175D ;вызов процедуры из основной памяти ld bc,#FFBA ld a,(xDFF0) and #F7 out (c),a ld (xDFF0),a ret ;АДРЕС: #1738 работа с контроллером прерываний x1738 di ld bc,#7FBE ld a,#00 out (c),a ld bc,#FFBA ld a,(xDFF0) or #08 out (c),a ld (xDFF0),a xor a ld i,a im 2 x1752 ei ld a,(xDFF0) bit 3,a jr nz,x1752 ret jr $ ;вызов процедуры из основной памяти ;вх: hl - адрес процедуры x175D push hl ld hl,rom3_x3D30 ex (sp),hl push hl ret ;установка бордюра x1764 out (#FE),a ret db #00 ;АДРЕС: #1768 поиск раздела MFS ;вых: cy=1 раздел не найден ; dehl=#00000000 ; cy=0 раздел найден ; bc - адрес дескриптора раздела MFS в буфере ; dehl - смещение первого сектора раздела x1768 push ix call x1791 ;hl=de=#0000 (нулевой сектор) ld (iy+#31),#01 ;число передаваемых секторов данных при операциях чтения/записи (=#00->=#100) call x1D73 ;чтение нулевого сектора с винчестера в буфер xE5A9 jp c,x178E ;ошибка чтения call x1797 ;поиск раздела MFS в MBR jr c,x178E ;раздел не найден ld l,(ix+#08) ld h,(ix+#09) ld e,(ix+#0A) ld d,(ix+#0B) ;dehl - смещение первого сектора радела push ix pop bc pop ix ret x178E pop ix scf ;hl=de=#0000 x1791 ld hl,#0000 ld e,l ld d,l ret ;поиск раздела MFS в MBR ; cy=1 раздел MFS не найден x1797 ld hl,(xE5A9+#1FE) ;xE7A7 ld de,#AA55 ;сигнатура (55h AAh) or a sbc hl,de jr nz,x17B7 ;сигнатура отсутствует: MBR отсутствует x17A2 ld b,#04 ld ix,xE5A9+#1BE ;xE767 начало дескрипторов разделов HDD x17A8 ld a,#53 ;код типа раздела MFS cp (ix+#04) jr nz,x17B0 ret x17B0 ld de,#0010 add ix,de ;дескриптор следующего раздела djnz x17A8 x17B7 ld a,#63 scf ret ;АДРЕС: #17BB чтение в буфер xEBF5 двух первых секторов раздела MFS/подраздела ;вх: dehl - смещение в секторах (512b) от начала винчестера до нужного сектора ;вых: cy=1 была ошибка x17BB push ix push de push hl call x1DDF ;расчет и установка в переменных адреса LBA/CHS в зависимости от настроек ld ix,xEBF5 ;грузим первый сектор раздела MFS call x1D78 ;чтение сектора с винчестера в буфер ix pop hl pop de jr c,x17EB ;ошибка загрузки call x0FF3 ;инкремент dehl call x1DDF ;расчет и установка в переменных адреса LBA/CHS в зависимости от настроек ld ix,xEBF5+#200 ;грузим втоорой сектор раздела MFS call x1D78 ;чтение сектора с винчестера в буфер ix jr c,x17EB ;ошибка загрузки ld hl,(xEBF5+#3FE) ;xEFF3 сравнение ситгнатуры ld de,#AA54 sbc hl,de ld a,#63 jr nz,x17EB ;сигнатуры нет pop ix ret x17EB scf ;ошибка pop ix ret ;АДРЕС: #17EF запись 2х секторов из буфера xEBF5 ;вх: dehl - смещение в секторах (512b) от начала винчестера до нужного сектора x17EF push ix push de push hl call x1DDF ;расчет и установка в переменных адреса LBA/CHS в зависимости от настроек ld ix,xEBF5 ;буфер call x1D4A ;запись сектора из буфера ix на винчестер pop hl pop de jr c,x17EB ;ошибка call x0FF3 ;инкремент dehl call x1DDF ;расчет и установка в переменных адреса LBA/CHS в зависимости от настроек ld ix,xEBF5+#200 ;вторй сектор call x1D4A ;запись сектора из буфера ix на винчестер jr c,x17EB ;ошибка pop ix ret ;АДРЕС: #1813 чтение сектора с винчестера ;вх: hl - адрес буфера для чтения ; de - смещение от начала образа в секторах (512b) +1 ;вых: hl - адрес буфера для чтения ; cy=1 были ошибки. код ошибки в A x1813 push hl call x1848 ;расчет номера сектора на винчестере ;dehl - смещение в секторах (512b) от начала винчестера до нужного сектора jr c,x1827 ;ошибка: адрес за пределами образа диска call x1DDF ;расчет и установка в переменных адреса LBA/CHS в зависимости от настроек ex (sp),ix call x1D78 ;чтение сектора с винчестера в буфер ix pop ix ret nc ;ошибок не было ld a,#04 ret x1827 pop hl ;ошибка: адрес за пределами образа диска ret ;АДРЕС: #1829 запись сектора на винчестер ;вх: hl - адрес буфера для записи ; de - смещение от начала образа в секторах (512b) ;вых: hl - адрес буфера для записи ; cy=1 были ошибки. код ошибки в A x1829 ld a,(xE590) and %00100000 jr nz,x1844 ;защита от записи push hl ;адрес буфера для записи call x1848 ;расчет номера сектора на винчестере jr c,x1827 ;ошибка: адрес за пределами образа диска call x1DDF ;расчет и установка в переменных адреса LBA/CHS в зависимости от настроек ex (sp),ix ;адрес буфера для записи call x1D4A ;запись сектора из буфера ix на винчестер pop ix ret nc ;нет ошибок записи ld a,#04 ;код ошибки: ошибка при чтении или записи сектора функциями 5 или 6 ret x1844 ld a,#02 ;код ошибки: попытка записи на защищенную дискету scf ret ;АДРЕС: #1848 расчет номера сектора на винчестере ;вх: de - смещение от начала образа до нужного сектора в секторах (512b) ;вых: cy=1 ошибка: адрес за пределами образа диска ; =0 dehl - смещение в секторах (512b) от начала винчестера до нужного сектора x1848 ld (xE9E7),de ;смещение до нужного сектора ld de,xE9EB ;адрес числа push de ld hl,xE590+#01 ;смещение образа от начала HDD call x1003 ;копирование из (hl) в (de) 4х байт pop hl ld de,xE9E7 call x101D ;(hl)=(hl)+(de) сложение 4х байтного числа с двухбайтным ld de,xE9E7 ld hl,xE590+#05 ;смещение от начала HDD до последнего(служебного) сектора образа push hl call x1003 ;копирование из (hl) в (de) 4х байт pop de ld hl,xE9EB ;смещение в секторах (512b) от начала винчестера до нужного сектора call x1035 ;сравнение двух чисел jr z,x1873 ;(hl)=(de) jp p,x187B ;(hl)>(de) ошибка x1873 ld hl,xE9EB ;(hl)<(de) call x100F ;загрузка числа в регистры из памяти or a ret x187B ld a,#22 ;код ошибки: адрес за пределами образа диска scf ret ;АДРЕС: #187F R8DOS #23(35) подключение раздела к драйверу HDD ;вх: 1-0,a - номер дисковода ; 2,a =0 ; 6,a =1 отключить подраздел от драйвера ; 5,a =1 подключить подраздел к драйверу (копирование дескриптора в рабочуюю область) ; 7,a =1 автоподключение, т. е. подключить то, что задано в секторе автонастроек ; 3,a =1 подключение по имени, адрес имени в памяти в DE ; 4,a =1 вернуть в память (по HL) дескриптор текущего подключенного к драйверу раздела ;вых: cy=1 ошибка ; cy=0 ошибок не было ; 4,(hl) =1 x187F call x18C0 ;вых: при 4,a=1 -> hl=xE5A5 ;вых: при 4,a=0 -> hl=как при входе ret c ;были ошибки push af ld c,#11 set 4,(hl) ;!!!ОШИБКА!!! портится память pop af ret ;АДРЕС: #188A установка кода, определяющий тип дисковода без образа по номеру в С x188A xor a ld (xE590),a ;реальный дисковод ld e,#C0 bit 1,c jr z,x1895 ;это дисковод A/B ld e,a x1895 call x1A0E ;hl адрес кода, определяющий тип дисковода по номеру в С ld (hl),e ret ;АДРЕС: #189A подключить подраздел к драйверу (копирование дескриптора в рабочуюю область) ;вх: de - адрес дескриптора дисковода x189A bit 5,(iy+#1C) jp nz,x1B00 ;ошибка #67. нет винчестера ld hl,xE590 ;описатель текущего дисковода push hl push bc ex de,hl ld bc,#0015 bit 5,(iy+#0B) jr z,x18B6 ;функция вызывается из монитора ;вызов пользователем rst #30 dw rom2_x0753 ;сохранение области памяти в ram 8 db #02 jr x18B8 ;функция вызывается из монитора x18B6 ldir x18B8 pop bc pop hl ld a,(hl) or a ret nz ;выход без ошибок jp x1983 ;ошибка #66. путь не найден ;АДРЕС: #18C0 R8DOS #28(40) подключение раздела к драйверу HDD ;вх: 1-0,a - номер дисковода ; 2,a =0 ; 6,a =1 отключить подраздел от драйвера ; 5,a =1 подключить подраздел к драйверу (копирование дескриптора в рабочуюю область) ; 7,a =1 автоподключение, т. е. подключить то, что задано в секторе автонастроек ; 3,a =1 подключение по имени, адрес имени в памяти в DE ; 4,a =1 вернуть в память (по HL) дескриптор текущего подключенного к драйверу раздела ;вых: cy=1 ошибка x18C0 bit 7,(iy+#1B) jp z,x1BFA ;ошибка #56 нет раздела MFS push hl push af push hl ld hl,x1A19 ex (sp),hl ;адрес возврата ld c,a bit 6,c jr nz,x188A ;отключить подраздел от драйвера bit 5,c jr nz,x189A ;подключить подраздел к драйверу (копирование дескриптора в рабочуюю область) bit 7,c jr nz,x1901 ;автоподключение, т. е. подключить то, что задано в секторе автонастроек bit 3,c ret z ;переход на x1A19 ;подключение по имени, адрес имени в памяти в de ld a,e or d jr z,x18FD ;;ошибка #45. неверный путь push bc ex de,hl ld de,xE7C7 ld bc,#0014 bit 5,(iy+#0B) jr z,x18F6 ;;функция вызывается из монитора rst #30 dw rom2_x0753 ;сохранение области памяти в ram 8 db #02 jr x18F8 x18F6 ldir x18F8 xor a ld (de),a pop bc jr x190E ;анализ имени и подключение ;ошибка #45. неверный путь x18FD ld a,#45 scf ret ;автоподключение, т е. подключить то, что задано в секторе автонастроек ;вх: 1-0,c - номер дисковода x1901 push bc call x1E3D ;чтение сектора 3(сектор настроек) в буфер xE5A9 и проверка контрольной суммы pop bc ret c ;ошибка чтения ld de,xE7C7 call x1ACC ;формирование текстовой строки - пути к примонтированному подразделу/образу ret c ;ошибка чтения x190E ld hl,xE7C7+#01 ld a,":" cp (hl) jr nz,x192C ;это подраздел ; это образ диска dec hl ld a,(hl) and #5F sub #41 jr c,x18FD ;не буква диска. ошибка #45. неверный путь cp #04 jr nc,x18FD ;не буква диска. ошибка #45. неверный путь ld b,a ld a,c and #F0 or b ld c,a ;новый дисковод inc hl inc hl jr x192F ;hl начало имени подраздела ; это подраздел x192C ld hl,xE7C7 x192F ld a,(hl) cp #5C ;"\" jr nz,x1935 inc hl ; формирование строки с именами для поиска в каталоге x1935 ld de,xE7DB ;буфер для имени подраздела и образа push bc call x1A82 ;выделение из строки имени подраздела/образа (6 символов имя) call x1A82 ;выделение из строки имени подраздела/образа (6 символов имя) pop bc ; поиск имени подраздела в каталоге ld de,xEBF5 ;буфер с каталогом x1943 push bc push de rst #30 dw rom5_x2620 ;формирование в буфере xEBF5 списка подразделов MFS/образов db #05 pop de pop bc ret c ;ошибка чтения res 7,c ;7,=0 поиск имени x194E push bc ld bc,xEBF5 ;определение номера текущей записи ld l,e ld h,d sbc hl,bc ld b,#04 x1958 srl h ;hl=hl/#10 rr l djnz x1958 ;l - номер записи в каталоге pop bc ld a,(xDD89) ;всего записей cp l jr z,x1983 ;конец каталога. ошибка #66. путь не найден jr c,x1983 ;конец каталога. ошибка #66. путь не найден ld hl,xE7DB ;тут имя подраздела и образа call x1A6A ;проверка совпадения имени jr nz,x19C1 ;не совпало ; имя совпало ld a,(de) and #DF cp #01 jr nz,x19D8 ;это не TR-DOS. формирование описателя текущего дисковода ld a,(xE7DB+#06) cp " " jr nz,x1987 ;есть имя образа ld a,(de) or #10 ld (de),a jr x19D8 ;формирование описателя текущего дисковода ;ошибка #66. путь не найден x1983 ld a,#66 scf ret ; поиск имени образа в каталоге x1987 push de push bc ld bc,#0010 ex de,hl ld de,xE81B ldir ;сохраним запись подраздела в буфере rst #30 dw rom5_x25EB ;формирование в буфере xEBF5 списка образов коллекции db #05 pop bc pop de ret c ;ошибка чтения set 7,c ;в буфере каталог коолекции образов push bc push de ld de,xEBF5 ;адрес каталога коллекции ld c,#01 x19A2 ld a,(xDD89) ;количество образов в каталоге cp c jr c,x19BF ;каталог закончился ld a,(de) and #01 cp #01 jr nz,x19B7 ;это не образ диска. следующая запись ld hl,xE7DB+#06 ;имя образа call x1A6A ;проверка совпадения имени jr z,x19CF ;есть совпадение x19B7 inc c ld hl,#0010 add hl,de ex de,hl jr x19A2 ;продолжим поиск x19BF pop de ;конец каталога образов pop bc x19C1 ld a,e add a,#10 ld e,a jr nc,x19C8 inc d ;de=de+#10 x19C8 bit 7,c jr z,x194E ; jp x1943 ;7,c =1 в буфере каталог коолекции образов, читать MBR не надо ;имя образа найдено x19CF pop hl pop bc ld a,(de) and #20 ;сохраним признак защиты от записи or #01 jr x19D9 ;формирование описателя текущего дисковода x19D8 ld a,(de) x19D9 ld (xE590),a ;код подраздела в описателе текущего дисковода ex de,hl ld de,xE590+#01 inc hl call x1003 ;копирование из (hl) в (de) 4х байт ld de,xE590+#05 call x1003 ;копирование из (hl) в (de) 4х байт push de ld de,#0005 add hl,de pop de ex de,hl push bc rst #30 dw rom5_x3052 ;сложение двух 4х байтных чисел db #05 ld hl,xE590+#05 rst #30 dw rom5_x302A ;декремент (hl)=(hl)-1 db #05 pop bc ld a,(xE590) ;!!!ОШИБКА!!! перед сравнением надо сделать and #DF cp #01 ;иначе диски с защитой от записи не будут видны jr z,x1A07 ;это TR-DOS образ, без защиты от записи or a ret x1A07 call x1A0E ;hl адрес кода, определяющий тип дисковода ld (hl),#E0 ;%11100000 or a ret ;АДРЕС: #1A0E расчет адреса кода, определяющие тип дисковода по номеру в С x1A0E ld a,c and #03 ld c,a ld b,#00 ld hl,xFFCC add hl,bc ret ;завершение процедуры x18C0 R8DOS #28(40) ;cy=1 была ошибка x1A19 push af jr nc,x1A20 ;нет ошибки xor a ld (xE590),a ;была ошибка. образ не подключен x1A20 ld a,c and #03 ld (xFFCA),a ;текущий дисковод bit 4,(iy+#1C) call z,x1B54 ;1/0 TRDOS mirror on/off call x1B04 ;расчет адреса блока описателя заданного дисковода ;сохранение описателя текущего дисковода в блоке xE9F5 ld de,xE590 ;описатель текущего дисковода ex de,hl ld bc,#0009 ldir push hl ld hl,xE7DB ;имена подраздела/образа push hl ld bc,#000C push bc ldir ;копирование имен подраздела/образа в описатель текущего дисковода pop bc pop hl pop de ldir ;копирование в блок описаний дисководов call x1B18 ;установка признака подмонтированных дисков A/B в порту #7FBA pop af pop de pop hl ret c ;была ошибка ;вернуть в память (по HL) дескриптор текущего подключенного к драйверу раздела bit 4,d ret z ld de,xE590 ex de,hl ld bc,#0015 bit 5,(iy+#0B) jr z,x1A66 ;функция вызывается из монитора rst #30 dw rom2_x0749 ;восстановление области памяти из ram 8 db #02 jr x1A68 x1A66 ldir x1A68 or a ret ;АДРЕС: #1A6A проверка совпадения имени ;вх: de - адрес в каталоге ; hl - адрес имени для поиска ;вых: z - имя совпало x1A6A push bc push de ld bc,#000A ;приращение в записи до имени ex de,hl add hl,bc ld bc,#0600 x1A74 ld a,(de) cp (hl) jr z,x1A79 inc c x1A79 inc hl inc de djnz x1A74 ld a,c ;c=0 сть совпадение or a pop de pop bc ret ;АДРЕС: #1A82 выделение из строки имени подраздела/образа (6 символов имя) ;вх: de - буфер приемник ; hl - адрес строки x1A82 ld b,#06 x1A84 ld a,(hl) cp #5C ;"\" jr z,x1A97 ;конец имени or a jr z,x1A98 ;конец строки ld (de),a inc hl inc de djnz x1A84 ld a,(hl) cp #5C ;"\" ret nz ;не маркер конца имени inc hl ;следующий символ ret x1A97 inc hl x1A98 ld a," " ld (de),a inc de djnz x1A98 ret ;АДРЕС: #1A9F копирование имени подраздела/образа по адресу в de ;вх: de - адрес буфера ; hl - адрес пути примонтированного подраздела/образа ; b - смещение в пути до имени x1A9F ld a,l add a,b ld l,a jr nc,x1AA5 inc h x1AA5 ld b,#06 x1AA7 ld a,(hl) cp #21 ret c ld (de),a inc hl inc de djnz x1AA7 ret ;АДРЕС: #1AB1 определение адреса начала записи для заданного дисковода в буфере xE5A9 ;вх: a - номер дисковода для монтирования образа ;вых: hl - адрес буфера ; a - первый байт буфера со сброшенным битом защиты от записи x1AB1 push de and #03 ld hl,x1AC8 add a,l ld l,a jr nc,x1ABC inc h x1ABC ld l,(hl) ld h,#00 ld de,xE5A9 add hl,de ld a,(hl) and #DF pop de ret x1AC8 db #00,#16,#2C,#42 ;АДРЕС: #1ACC формирование текстовой строки - пути к примонтированному ; подразделу/образу. вида X:part\disk,#00 либо part,#00 ;вх: de - адрес буфера для текcтовой строки ; 0-1,c - номер дисковода x1ACC ld a,c call x1AB1 ;hl адрес начала пути к примонтированному образу ld (de),a ;a - первый байт пути со сброшенным битом защиты от записи and #DF jp z,x1B00 ;ошибка #67. к дисководу образ не примонтирован cp #01 jr z,x1AE1 ;это образ диска ;для подраздела ld b,#0A call x1A9F ;копирование имени подраздела по адресу в de jr x1AFC ;для образа диска x1AE1 ld a,c and #03 add a,#41 ld (de),a ;буква дисковода inc de ld a,":" ld (de),a inc de ld b,#0A push hl call x1A9F ;копирование имени подраздела по адресу в de pop hl ld a,#5C ;"\" ld (de),a inc de ld b,#10 call x1A9F ;копирование имени образа по адресу в de x1AFC ex de,hl xor a ld (hl),a ret ;ошибка #67. к дисководу образ не примонтирован x1B00 ld a,#67 scf ret ;АДРЕС: #1B04 расчет адреса блока описателя заданного дисковода ;вх: a - номер дисковода ;вых: hl - адрес блока описателя текущего дисковода ; a - первый байт описателя ; nz - это образ диска x1B04 ld l,a rlca rlca ld h,a rlca rlca add a,h add a,l ;a=a*#15 ld hl,(xE9F3) add a,l ld l,a jr nc,x1B14 inc h x1B14 ld a,(hl) ;hl адрес блока описателя заданного дисковода and #DF ret ;АДРЕС: #1B18 установка признака подмонтированных дисков A/B в порту #7FBA x1B18 ld a,(xFFCA) ;номер текущего дисковода bit 1,a ret nz ;это дисковод C/D ld c,a ld e,a call x1A0E ;расчет адреса кода, определяющие тип дисковода по номеру в С ld bc,#7FBA bit 0,e ld d,(iy-#26) jr z,x1B37 ;дисковод A set 6,d ;для дисковода B bit 5,(hl) jr z,x1B3F ;образ не подключен res 6,d ;образ подключен jr x1B3F x1B37 set 7,d ;для дисковода A bit 5,(hl) ;образ не подключен jr z,x1B3F res 7,d ;образ подключен x1B3F ld (iy-#26),d out (c),d ret ;АДРЕС: #1B45 определение необходимости копирования памяти пользователя ;вх: hl - адрес начала блока памяти ; bc - размер блока памяти ;вых: cy=1 блок памяти попадает на системные области ; =0 блок памяти в пределах [#4000..#BFFF] x1B45 ld a,h cp #40 ret c push hl dec bc add hl,bc ;адрес конца таблицы inc bc ld a,h pop hl ret c cp #C0 ccf ret ;АДРЕС: #1B54 сохранение описателя текущего дисковода в блоке xE9F5 (функция TR-DOS mirror) x1B54 bit 5,(iy+#0B) ret z ;функции вызываются из монитора push af ld hl,(xE9F3) ;адрес блока описателей дисковода push hl ld hl,xE9F5 ld (xE9F3),hl ;начало блока call x1B04 ;расчет адреса блока описателя заданного дисковода ld de,xE590 ;описатель текущего дисковода ex de,hl ld bc,#0009 ldir ;тип и адрес подраздела/образа в секторах ld hl,xE7DB ld bc,#000C ;имена подраздела/образа ldir pop hl ld (xE9F3),hl pop af ret ;АДРЕС: #1B7E R8DOS #24(36) прямое чтение секторов из подраздела жесткого диска ;вх: hl - адрес в памяти, куда считывать ; de - начальный номер сектора (считая с 1!) ; b - число секторов (размер сектора 512 байт!) ;вых: cy=1 - ошибки x1B7E bit 7,(iy+#1B) jr z,x1BFA ;ошибка. нет раздела MFS ld a,(xE590) ;код типа примонтированного подраздела/образа or a jr z,x1BBC ;ошибка. образ не примонтирован ld a,b or a ret z ;0 секторов. нечего читать ;читаем сектора x1B8D push hl push de push bc call x1B9D ;чтение одного сектора pop bc pop de pop hl ret c ;были ошибки inc h inc h inc de djnz x1B8D ret ;чтение одного сектора x1B9D ld bc,#0200 call x1B45 ;определение необходимости копирования памяти пользователя jp nc,x1813 ;чтение сектора с винчестера push hl ld hl,xEBF5 ;читаем в буфер в ram 8 call x1813 ;чтение сектора с винчестера pop hl ret c ;ошибки ld de,xEBF5 ex de,hl ld bc,#0200 rst #30 dw rom2_x0749 ;копируем в память пользователя db #02 xor a ret ;ошибка #67. к дисководу образ не примонтирован x1BBC scf ld a,#67 ret ;АДРЕС: #1BC0 R8DOS #25(37) прямая запись секторов в подраздел жесткого диска ;вх: hl - адрес в памяти, откуда записывать ; de - начальный номер сектора (считая с 1!) ; b - число секторов (размер сектора 512 байт!) ;вых: cy=1 - ошибки x1BC0 bit 7,(iy+#1B) jr z,x1BFA ;ошибка. нет раздела MFS ld a,(xE590) ;код типа примонтированного подраздела/образа or a jr z,x1BBC ;ошибка. образ не примонтирован ld a,b or a ret z ;0 секторов. нечего записывать ;записываем сектора x1BCF push hl push de push bc call x1BDF ;запись одного сектора pop bc pop de pop hl ret c ;были ошибки inc h inc h inc de djnz x1BCF ret ;запись одного сектора x1BDF ld bc,#0200 call x1B45 ;определение необходимости копирования памяти пользователя jp nc,x1829 ;запись сектора на винчестер push de ld de,xEBF5 ;буфер для записи ld bc,#0200 rst #30 dw rom2_x0753 ;копируем область пользователя в буфер для записи db #02 pop de ld hl,xEBF5 jp x1829 ;запись сектора на винчестер ;АДРЕС: #1BFA ошибка #56. нет раздела MFS x1BFA ld a,#56 scf ret ;АДРЕС: #1BFE R8DOS #26(38) Вернуть таблицу (каталог) подраздела ;вх: hl - адрес буфера для таблицы (1024) ;вых: cy=1 - ошибки ;вых: de - количество подразделов ; x1BFE bit 7,(iy+#1B) jr z,x1BFA ;ошибка. нет раздела MFS push hl call x1C21 ;чтение в буфер xEBF5 катлога раздела MFS pop hl ret c ;ошибка push hl ld de,xEBF5 ;буфер с каталогом ex de,hl ld bc,#0400 rst #30 dw rom2_x0749 ;копируем в память пользователя db #02 rst #30 dw rom5_x271A ;подсчет количества подразделов в MFS db #05 ld de,(xDD89) ;количество подразделов pop hl xor a ret ;чтение в буфер xEBF5 катлога раздела MFS x1C21 res 6,(iy+#1C) call x1768 ;поиск раздела MFS ret c ;ошибка call x17BB ;чтение в буфер xEBF5 двух первых секторов раздела MFS/подраздела ret ;АДРЕС: #1C2D R8DOS #27(39) чтение/запись сектора (???ОШИБКА???) ;вх: a =#90/#94 запись сектора ; =#50/#54 чтение сектора ; hl - адрес начала данных 512b ;вых: cy=1 - ошибки ; x1C2D bit 7,(iy+#1B) jr z,x1BFA ;ошибка. нет раздела MFS ld c,a and #FB ;%11111011 cp #90 jr z,x1C42 cp #50 jr z,x1C56 ld a,#56 ;ошибка. нет раздела MFS scf ret ;запись сектора x1C42 ld de,xE5A9 ld bc,#0200 rst #30 dw rom2_x0753 ;копируем область пользователя в буфер для записи db #02 ld de,(xDD7B) ;регистр de' пользователя ???ОШИБКА??? ld hl,(xDD7B) ;регистр de' пользователя ???ОШИБКА??? jp x1D45 ;запись сектора из буфера xE5A9 на винчестер по адресу в dehl ;чтение сектора x1C56 push hl ld de,(xDD7B) ;регистр de' пользователя ???ОШИБКА??? ld hl,(xDD7B) ;регистр de' пользователя ???ОШИБКА??? call x1D73 ;чтение сектора с винчестера в буфер xE5A9 pop hl ret c ;ошибки ld de,xE5A9 ex de,hl ld bc,#0200 rst #30 dw rom2_x0749 ;копируем в память пользователя db #02 xor a ret ;АДРЕС: #1C70 бесконечное чтение порта bc x1C70 in a,(c) jr x1C70 ;АДРЕС: #1C74 бесконечная запись в порт bc x1C74 out (c),a jr x1C74 ;АДРЕС: #1C78 загрузка в регистры кол-ва секторов, адреса LBA/CHS, типа устройства ;вх: hl - адрес откуда грузим в регистры 6 байт x1C78 ld bc,#F8BE x1C7B ld a,(hl) inc hl inc b out (c),a ld a,b cp #FE ret z jr x1C7B ;АДРЕС: #1C86 чтение 512b данных в буфер адресуемый hl ;вх: hl - адрес буфера для чтения данных x1C86 push hl ld c,#BE ld de,#D8F8 xor a x1C8D ld b,e ;порт #F8BE регистр данных (младшая часть) ini ld b,d ;порт #D8BE регистр данных (старшая часть) ini dec a jr nz,x1C8D pop hl ret ;АДРЕС: #1C98 запись 512b данных из буфер адресуемого hl ;вх: hl - адрес буфера для записи данных x1C98 push hl ld c,#BE ld de,#D9F9 ;команда outd вначале делает dec b xor a x1C9F ld b,d ;порт #D8BE регистр данных (старшая часть) inc hl outd ld b,e ;порт #F8BE регистр данных (младшая часть) outi inc hl dec a jr nz,x1C9F pop hl ret ;АДРЕС: #1CAC посылаем команду винчестеру ;вх: a - команда винчестеру ;вых: cy=1 HDD не вышел в готовность ; =0 команда загружена в регистр ; d - регистр состояния x1CAC ld e,a ld c,#BE call x1D04 ;ожидание готовности HDD ret c ;ошибка: hdd не вышел в готовность ld b,#FE ld a,(xE049) ;тип адресации LBA/CHS и выбор винчестера master/slave out (c),a ld hl,xE044 call x1C78 ;загрузка в регистры кол-ва секторов, адреса LBA/CHS, типа устройства call x1CE5 ;ожидание готовности HDD к принятию команды ret c ;ошибка: hdd не вышел в готовность ld bc,#FFBE out (c),e ret ;АДРЕС: #1CCA ожидание готовности HDD к передаче данных ;вх: c - младший байт порта ;вых: cy=1 HDD не вышел в готовность ; =0 HDD готов к передаче данных ; d - регистр состояния x1CCA call x1D04 ;ожидание готовности HDD ret c ;ошибка: hdd не вышел в готовность bit 3,d ret nz ;винчестер готов к передаче данных ;ждем готовности к передаче данных ld hl,#C350 x1CD4 ld bc,#FFBE in d,(c) bit 3,d ret nz ;винчестер готов к передаче данных dec hl ld a,h or l jr nz,x1CD4 ld a,#62 scf ret ;АДРЕС: #1CE5 ожидание готовности HDD к принятию команды ;вх: c - младший байт порта ;вых: cy=1 HDD не вышел в готовность ; =0 HDD готов к принятию команды ; d - регистр состояния x1CE5 call x1D04 ;ожидание готовности HDD ret c ;ошибка: hdd не вышел в готовность bit 6,d ret nz ;выход. винчестер готов принять команду ;ждем готовности принять команду ld hl,#14E6 or a x1CF0 ld bc,#FFBE in d,(c) bit 6,d ret nz ;выход. винчестер готов принять команду dec a jr nz,x1CF0 dec hl ld a,h or l jr nz,x1CF0 ld a,#61 scf ret ;АДРЕС: #1D04 ожидание готовности HDD ;вх: c - младший байт порта ;вых: cy=1 HDD не вышел в готовность ; =0 HDD готов ; d - регистр состояния x1D04 ld hl,#4FD3 ;количество попыток x1D07 xor a ld b,#FF x1D0A in d,(c) ;читаем регистр состояния bit 7,d ret z ;HDD готов dec a ;HDD занят jr nz,x1D0A ;повторяем попытки dec hl ld a,h or l jr nz,x1D07 ld a,#60 ;HDD не вышел в готовность scf ret ;АДРЕС: #1D1B чтение сектора идентификации в буфер по адресу в ix ;вх: ix - адрес буфера для чтения сектора идентификации x1D1B ld hl,xE04A ld b,(hl) ;сохраним код команды винчестера: чтение сектора push bc ld (hl),#EC ;команда идентификации push hl call x1D78 ;чтение сектора идентификации в ix pop hl pop bc ld (hl),b ret ;АДРЕС: #1D2A подсчет контрольной суммы и запись сектора из буфера xE5A9 на винчестер x1D2A call x1E2A ;установка в переменных - сектора номер 3 для винчестера ld hl,#4155 ;сигнатура сектора с примонтированными образами ld (xE5A9+#1FE),hl ld de,xE5A9 ;адрес начала памяти ld bc,#01FC ;размер области памяти call x21E5 ;подсчет контрольной суммы области памяти CRC16 ld (xE5A9+#1FC),hl ;контрольная сумма ld (iy+#31),#01 ;количество секторов jr x1D4F ;запись сектора из буфера xE5A9 на винчестер ;АДРЕС: #1D45 запись сектора из буфера xE5A9 на винчестер по адресу в dehl ;вх: dehl - смещение в секторах (512b) от начала винчестера до нужного сектора ;вых: cy=1 ошибки x1D45 call x1DDF ;расчет и установка в переменных адреса LBA/CHS в зависимости от настроек jr x1D4F ;запись сектора из буфера xE5A9 на винчестер ;АДРЕС: #1D4A запись сектора из буфера ix на винчестер ;вх: ix - адрес буфера для записи сектора x1D4A push ix pop hl jr x1D52 ;АДРЕС: #1D4F запись сектора из буфера xE5A9 на винчестер x1D4F ld hl,xE5A9 x1D52 ld b,(iy+#39) ;количество дополнительных попыток записи сектора x1D55 push bc ld a,(xE04B) ;код команды винчестера call x1D60 ;запись сектора на винчестер pop bc ret nc ;нет ошибок djnz x1D55 ;еще раз попытаемся записать ;запись сектора на винчестер ;вх: a - команда винчестеру ; hl - адрес буфера для записи данных ;вых: cy=1 были ошибки ; hl - не изменяется x1D60 push hl call x1CAC ;посылаем команду винчестеру pop hl jr c,x1DB3 ;ошибка push hl call x1CCA ;ожидание готовности HDD к передаче данных pop hl jr c,x1DB3 ;ошибка call x1C98 ;запись 512b данных из буфер адресуемого hl jr x1D9F ;проверка на ошибки и выход ;АДРЕС: #1D73 чтение сектора с винчестера в буфер xE5A9 ;вх: dehl - смещение в секторах (512b) от начала винчестера до нужного сектора x1D73 call x1DDF ;расчет и установка в переменных адреса LBA/CHS в зависимости от настроек jr x1D7D ;АДРЕС: #1D78 чтение сектора с винчестера в буфер ix ;вх: ix - адрес буфера для чтения сектора x1D78 push ix pop hl jr x1D80 ;АДРЕС: #1D7D чтение сектора с винчестера в буфер xE5A9 x1D7D ld hl,xE5A9 x1D80 ld b,(iy+#39) ;количество дополнительных попыток чтения сектора x1D83 push bc ld a,(xE04A) ;код команды винчестера call x1D8E ;чтение сектора с винчестера pop bc ret nc djnz x1D83 ;чтение сектора с винчестера ;вх: a - команда винчестеру ;вх: hl - адрес буфера для чтения данных ;вых: cy=1 были ошибки ; hl - не изменяется x1D8E push hl call x1CAC ;посылаем команду винчестеру pop hl jr c,x1DB3 ;ошибка push hl call x1CCA ;ожидание готовности HDD к передаче данных pop hl jr c,x1DB3 ;ошибка call x1C86 ;чтение 512b данных в буфер адресуемый hl ;проверка на ошибки и выход x1D9F ld bc,#FFBE in a,(c) ld d,a ;регистр состояния and %01110001 xor %01010000 ret z ;выход при готовности винчестера и отсутствии ошибок ld b,#F9 ;#F9BE in a,(c) ;читаем код ошибки ld (xFFDD),a ;сохраняем ld a,#57 ;код ошибки драйвера x1DB3 call x1DB8 ;програмный сброс винчестера scf ret ;програмный сброс винчестера x1DB8 push af push bc ld bc,#FFBA ld a,(xDFF0) push af or #80 out (c),a ;активация регистра Device Control push bc ld bc,#FEBE ld a,%00001100 out (c),a ;програмный сброс винчестера call x201C ;пауза 293t xor a out (c),a ;завершаем програмный сброс винчестера pop bc pop af and #7F out (c),a ;активация регистра головки ld (xDFF0),a pop bc pop af ret ;АДРЕС: #1DDF расчет и установка в переменных адреса LBA/CHS в зависимости от настроек ;вх: dehl - смещение в секторах (512b) от начала винчестера до нужного сектора ;вых: (xE046) параметры LBA/CHS в зависимости от настроек x1DDF exx ld hl,xE030 bit 4,(iy+#35) jr z,x1DEA ;master HDD inc hl ;slave HDD x1DEA bit 2,(hl) jr nz,x1E10 ;LBA on ;LBA off. преобразование адреса LBA в C/H/S ld bc,(xE5A5) ;head*sector (секторов на цилиндре) call x0F5D ;деление de'hl'=de'hl'/bc exx ld (xE047),hl ;номер цилиндра ld c,(iy-#1F) ;значение sector HDD ld b,#00 call x0F5D ;деление de'hl'=de'hl'/bc inc l ld (iy+#32),l exx ld a,(iy+#35) and #B0 ;%10110000 or l ld (iy+#35),a ;головка ret ;LBA on x1E10 exx ld (iy+#32),l ld (iy+#33),h ld (iy+#34),e ld a,d and #0F ld d,a ;старший полубайт ld a,(iy+#35) and #B0 ;%10110000 or d or #40 ld (iy+#35),a ret ;АДРЕС: #1E2A установка в переменных сектора номер 3 для винчестера x1E2A ld hl,#0000 ld (xE047),hl ld (iy+#32),#03 ld a,(iy+#35) and #F0 ld (iy+#35),a ret ;АДРЕС: #1E3D чтение сектора 3(сектор настроек) в буфер xE5A9 и проверка контрольной суммы ;вых: cy=1 были ошибки x1E3D call x1E2A ;установка в переменных сектора номер 3 для инчестера ld (iy+#31),#01 ;кол-во секторов =1 call x1D7D ;чтение сектора с винчестера в буфер xE5A9 ret c ;ошибка ld hl,(xE5A9+#1FE) ld de,#4155 ;сигнатура sbc hl,de ld a,#63 scf ret nz ;сигнатура отсутствует ld de,xE5A9 ;начало области памяти push de ld bc,#01FC ;размер области памяти call x21E5 ;подсчет контрольной суммы области памяти CRC16 ld bc,(xE5A9+#1FC) xor a sbc hl,bc pop hl ret z ;контрольная сумма совпала ld b,a ;контрольная сумма не совпадает x1E68 ld (hl),a ;очищаем буфер inc hl djnz x1E68 x1E6C ld (hl),a inc hl djnz x1E6C ld a,#63 scf ret ;АДРЕС: #1E74 R8DOS #22(34) идентификация жесткого диска ;вх: ix - адрес буфера для загрузки сектора идентификации ; 0,e =1 принудительно инициализировать переменные геометрии винчестра ;вых: cy=1 ошибки x1E74 xor a ld (xFFDD),a ;код ошибки дискового интерпретатора ld bc,#FFBA ld hl,xDFF0 ld a,(hl) or #81 ld (hl),a out (c),a ;device control/alt status push bc ld bc,#FEBE xor a out (c),a ;сброс pop bc ld a,(hl) and #7F or #01 ld (hl),a out (c),a ;вернем регистр команд djnz $ ;задержка ld bc,#FFBE in a,(c) ;регистр состояния xor #FF jr z,x1ECC ;прочитано #FF. нет винчестера set 7,(iy+#1A) ;признак наличия HDD bit 0,e jr nz,x1EAD bit 1,(iy+#1C) ;автоопределение HDD при старте включено jr nz,x1EFA ;читать сектор идентификации не надо ;чтение сектора идентификации и установка переменных геометрии винчестера x1EAD ld hl,#4FD3 call x1D07 ;ожидание готовности HDD ld b,#FC ;bc=#FCBE регистр цилиндра xor a x1EB6 out (c),a nop in d,(c) cp d jr nz,x1ECC ;значения не совпадают. винчестера нет dec a jr nz,x1EB6 ;повторим 256 раз ld hl,xE044 ;адрес переменной откуда грузим call x1C78 ;загрузка в регистры кол-ва секторов, адреса LBA/CHS, типа устройства call x1D04 ;ожидание готовности HDD jr nc,x1ED4 ;в готовность вышел ;винчестер не найден x1ECC res 7,(iy+#1A) ld a,#56 scf ret x1ED4 call x1D1B ;чтение сектора идентификации в буфер по адресу в ix ld a,#57 ret c ;ошибка #57. не прочитался сектор идентификации push ix pop hl xor a or (hl) inc hl or (hl) inc hl jr z,x1F04 ;ошибка в секторе идентификации ld c,(hl) inc hl ld b,(hl) inc hl ld (xDFF2),bc ;количество цилиндров inc hl inc hl ld a,(hl) ld (iy-#20),a ;количество головок ld de,#0006 add hl,de ld a,(hl) ld (iy-#1F),a ;количество секторов x1EFA call x1F2D ;расчет произыедения головок и секторов call x1F08 ;проверка геометрии винчестера jr z,x1F04 ;проверка геометрии винчестера не пройдена or a ret ;ошибка #58. ошибка в секторе идентификации x1F04 ld a,#58 scf ret ;АДРЕС: #1F08 проверка геометрии винчестера x1F08 res 7,(iy+#1B) ld a,(xDFF2) ;ицлиндров (младший байт) or (iy-#21) ret z ;ноль цилинлров xor a or (iy-#20) ret z ;ноль головок xor a or (iy-#1F) ret z ;ноль секторов ld hl,(xE5A5) ld a,l or h ret z ;нулевое произведение головок и секторов bit 7,(iy+#1A) ret z ;винчест не найден set 7,(iy+#1B) ret ;АДРЕС: #1F2D расчет произведения головок и секторов x1F2D xor a ld c,(iy-#20) ;головок ld b,a exx ld l,(iy-#1F) ;секторов ld h,a ld e,a ld d,a exx call x0FB7 ;умножение dehl=de'hl' * bc ld (xE5A5),hl ;произведение head * sectors ret ;АДРЕС: #1F41 ошибка HDD. вывод сообщения об ошибке в нижней строке монитора ;вх: a - код ошибки, если =#00 -> d - параметр ошибки чтения/записи x1F41 bit 5,(iy+#0B) jr z,x1F49 ;функции вызываются из монитора scf ret x1F49 push af ld a,(xFFDD) ld (xDDA7),a ;сохраним код ошибки дискового интерпретатора ld a,d ld (xDDA7+#01),a ; pop af rst #30 dw rom2_x3870 ;печать сообщения и продолжение работы текущего меню монитора db #02 ;АДРЕС: #1F59 чтение ячейки CMOS ;вх: b - адрес в CMOS ;вых: a - значение ; x1F59 push bc push bc x1F5B ld bc,#FFBA ld a,(xDFF0) and #7F ;7,=0 регистр адреса CMOS ld (xDFF0),a call x2010 ;запись в порт pop af ld b,#DF call x2010 ;запись в порт ld b,#DF call x2016 ;чтение порта pop bc ret ;АДРЕС: #1F76 чтение из CMOS времени и даты, в случае готовности CMOS ; x1F76 ld hl,xDFF6 ld b,#0C call x1F59 ;читаем регистр C cmos bit 4,a ret z ;еще не обновился call x1F8B ;bit 7 регистра A cmos ret nz ;cmos обновляется set 0,(iy+#1A) jr x1F98 ;;читаем секунды/минуты/часы ;АДРЕС: #1F8B проверка готовности CMOS ;вых: nz - cmos обновляется ; x1F8B ld b,#0A call x1F59 ;читаем регистр A cmos bit 7,a ret ;АДРЕС: #1F93 чтение из CMOS времени и даты ;вх: hl - адрес куда читать (6 байт) ; x1F93 call x1F8B ;проверка готовности cmos jr nz,x1F93 ;cmos обновляется, ждём ;читаем секунды/минуты/часы x1F98 ld bc,#0003 x1F9B call x1F59 ld (hl),a inc hl inc b inc b dec c jr nz,x1F9B ;читаем число/месяц/год inc b ld c,#03 x1FA8 call x1F59 ld (hl),a inc hl inc b dec c jr nz,x1FA8 ret ;АДРЕС: #1FB2 запись в CMOS времени и даты ;вх: hl - адрес откуда писать (6 байт) ; x1FB2 ld b,#0B ;регистр B ld a,#9E ;%10011110 call x1FDD ;запрет обновления cmos ld bc,#0003 x1FBC ld a,(hl) ;запись секунд/минут/часов inc hl call x1FDD inc b call x1FDD inc b dec c jr nz,x1FBC inc b ld c,#03 x1FCC ld a,(hl) ;запись число/месяц/год inc hl call x1FDD inc b dec c jr nz,x1FCC ld a,%00101010 ;регистр A cmos call x1FDD inc b ld a,%01011110 ;разрешенеи обновления cmos ;АДРЕС: #1FDD запись данных в ячейку CMOS ;вх: b - адрес в CMOS ; a - новое значение ячейки ; x1FDD push bc push af push bc ld bc,#FFBA ld a,(xDFF0) and #7F call x2010 ;запись в порт pop af ld b,#DF call x2010 ;выбираем адрес ld b,#FF ;режим записи данных ld a,(xDFF0) or #80 call x2010 ;запись в порт pop af ;запись данных в ячейку ld b,#DF call x2010 ;запись в порт ld b,#FF ld a,(xDFF0) and #7F ld (xDFF0),a call x2010 ;режим чтения cmos pop bc ret ;АДРЕС: #2010 запись в порт ;вх: bc - адрес порта ; a - значение ; x2010 call x201C ;пауза 293t out (c),a ret ;АДРЕС: #2016 чтение порта ;вх: bc - адрес порта ;вых: a - значение ; x2016 call x201C ;пауза 293t in a,(c) ret ;АДРЕС: #201C пауза 293t ; x201C push bc ld b,#14 djnz $ pop bc ret ;АДРЕС: #2023 запись данных в ячейку CMOS. и запись контрольной суммы в ячейку #3F ;вх: a - значение ячейки ; b - номер ячейкм x2023 call x1FDD ;запись данных в ячейку CMOS push bc call x2030 ;подсчет контрольной суммы CRC8 CMOS [#10..#3E] (#3F - контрольная сумма) ld a,e call x1FDD ;запись контрольной суммы pop bc ret ;АДРЕС: #2030 подсчет контрольной суммы CRC8 CMOS [#10..#3E] (#3F - контрольная сумма) ;вых: e - контрольная сумма ; b=#3F x2030 push de ld de,#FFFF ld b,#10 x2036 call x1F59 ;чтение ячейки CMOS call x220F ;суммирование байта с контрольной суммой CMOS CRC8 inc b ld a,#3F cp b jr nz,x2036 ld a,e add a,d pop de ld e,a ret ;АДРЕС: #2047 определение наличия CMOS ;вых: cy=1 были ошибки ; a=#5A - checksum error ; a - номер сообщения для вывода x2047 ld b,#3F ;номер ячейки call x1F59 ;чтение ячейки CMOS ld d,a ld a,#55 call x1FDD ;запись данных в ячейку CMOS call x1F59 ;чтение ячейки CMOS cp #55 jr nz,x2065 ;CMOS отсутствует ld a,#AA call x1FDD ;запись данных в ячейку CMOS call x1F59 ;чтение ячейки CMOS cp #AA jr z,x2069 ;CMOS найден x2065 ld a,#5B ;сообщение: CMOS not found scf ret ;CMOS найден. определяем размер CMOS x2069 ld b,#7F call x1F59 ;чтение ячейки CMOS ld e,a ld a,#55 call x1FDD ;запись данных в ячейку CMOS ld b,#3F call x1F59 ;чтение ячейки CMOS cp #AA jr nz,x2087 ;64 байт ld b,#7F ld a,e call x1FDD ;запись данных в ячейку CMOS set 6,(iy+#1B) ;CMOS 128 байт x2087 ld b,#3F ld a,d call x1FDD ;запись данных в ячейку CMOS set 6,(iy+#1A) ;CMOS обнаружен ;подсчет контрольной суммы CMOS [#10..#3E] (#3F - контрольная сумма) call x2030 ;подсчет контрольной суммы CRC8 CMOS [#10..#3E] (#3F - контрольная сумма) ld a,e cp d jr z,x20C2 ;контрольная сумма совпала ; контрольная сумма не совпала. перезапись CMOS x2098 ld hl,#0705 ;день и месяц: 5 июля ld (xDFF9),hl ld (iy-#19),#61 ;год: 1997 ld (iy-#1C),#0C ;час: 12 ld hl,xDFF6 call x1FB2 ;запись в CMOS времени и даты rst #30 dw rom4_x0398 ;запись переменных в CMOS db #04 ld b,#0E ld a,#61 ;признак записи в CMOS переменных call x1FDD ;запись данных в ячейку CMOS call x2030 ;подсчет контрольной суммы CRC8 CMOS [#10..#3E] (#3F - контрольная сумма) ld a,e call x1FDD ;запись данных в ячейку CMOS ld a,#5A ;сообщение: CMOS checksum error scf ret ; контрольная сумма совпала x20C2 ld b,#0D ;регистр #D call x1F59 ;чтение ячейки CMOS bit 7,a jr z,x2098 ;пропадало питание. перезапись CMOS inc b call x1F59 ;чтение ячейки CMOS cp #61 jr nz,x2098 ;переменные не были сохранены. перезапись CMOS ld hl,xDFF6 call x1F93 ;чтение из CMOS времени и даты ld hl,#0040 bit 6,(iy+#1B) jr z,x20E5 ;CMOS 64 байта ld hl,#0080 x20E5 ld (xDDA7),hl ;для печати размера CMOS xor a ld a,#5C ;сообщение: _число_ bytes CMOS found ret ;АДРЕС: #20EC работа с контроллером прерываний ???? x20EC di ld a,#0F scf ret ;АДРЕС: #20F1 тестирование HDD (2. test) (тест на чтение/запись) x20F1 ld hl,xEBF5+#200 ;заполним буфер значениями xor a ld b,a x20F6 ld (hl),a inc a inc hl djnz x20F6 x20FB ld (hl),a inc a inc hl djnz x20FB ld hl,x217B ;адрес п/п тестирования сектора на чтение/запись jr x2108 ;АДРЕС: #2105 тестирование HDD (1. test) (тест только на чтение) x2105 ld hl,x2172 ;адрес п/п тестирования сектора на чтение x2108 ld (xE338),hl ld (iy+#01),#00 rst #30 dw rom5_x30C6 ;печать окна для тестирования HDD db #05 ld hl,(xDFF2) ;значение Cylinders HDD ld de,#0000 exx ld bc,(xE5A5) ;head * sector активного HDD call x0FB7 ;умножение dehl=de'hl' * bc (кол-во секторов на HDD) push de push hl xor a ld l,a ld h,a ld e,a ld d,a push de push hl x212A ld hl,#0000 add hl,sp ex de,hl ;de адрес стэка ld hl,#0004 add hl,sp call x1035 ;сравнение двух чисел в памяти по адресам в de и hl jp p,x214C ;еще не конец винчестера call x2169 ;печать текущего номера цилиндра pop hl pop hl pop hl pop hl rst #30 dw rom2_x3807 ;пауза 40416t db #02 rst #30 dw rom6_x074A ;ожидание действий пользователя (опрос управления, вывод часов) db #06 rst #30 dw rom5_x0EB5 ;печать текущего меню монитора (без возврата) db #05 x214C pop hl pop de push de push hl ld bc,x215A ;адрес п/п перехода к следующему сектору push bc ld bc,(xE338) ;адрес п/п тестирования сектора push bc ret ;переход к следующему сектору x215A pop hl pop de ld a,l and #3F call z,x2169 ;печать текущего номера цилиндра call x0FF3 ;инкремент dehl push de push hl jr x212A ;печать текущего номера цилиндра x2169 push de push hl rst #30 dw rom5_x3163 ;печать текущего номера цилиндра db #05 pop hl pop de ret ;тестирование одного сектора на чтение x2172 call x1D73 ;чтение сектора с винчестера в буфер xE5A9 ret nc ;нет ошибок x2176 rst #30 dw rom5_x30F3 ;печать кода ошибки винчестера db #05 ret ;тестирование одного сектора на чтение/запись x217B call x1D73 ;чтение сектора с винчестера в буфер xE5A9 jr c,x2176 ;ошибка чтения. печать кода ошибки винчестера ld hl,xE5A9 ;сохраним прочитанный сектор ld de,xEBF5 ld bc,#0200 ldir push ix ld ix,xEBF5+#200 call x1D4A ;запись сектора из буфера ix на винчестер jr c,x21C6 ;ошибка записи ld ix,xE5A9 call x1D78 ;чтение сектора с винчестера в буфер ix jr c,x21C6 ;ошибка чтения call x21BF ;запись изначальных данных сектора pop ix jr c,x2176 ;ошибка записи. печать кода ошибки винчестера ld hl,xE5A9 ld bc,#0000 x21AC ld a,c cp (hl) call nz,x21CF ; inc c inc hl djnz x21AC x21B5 ld a,c cp (hl) call nz,x21CF ; inc c inc hl djnz x21B5 ret ;запись сектора из буфера xEBF5 на винчестер x21BF ld ix,xEBF5 jp x1D4A ;запись сектора из буфера ix на винчестер ;ошибка чтения/записи x21C6 push af call x21BF ;запись сектора из буфера xEBF5 на винчестер pop af pop ix jr x2176 ;печать кода ошибки винчестера x21CF pop de pop ix push ix push de push hl push bc ld b,(hl) ld de,xE5A9 or a sbc hl,de rst #30 dw rom5_x3135 ;печать сообщения об ошибке несовпадения данных при чтении/записи на HDD db #05 pop bc pop hl ret ;АДРЕС: #21E5 подсчет контрольной суммы области памяти CRC16 ;вх: bc - размер области памяти ; de - адрес начала памяти ;вых: hl - контрольная сумма x21E5 ld hl,#FFFF ld a,c or b ret z push ix push de pop ix ex de,hl x21F1 ld hl,x2222 ld a,(ix+0) inc ix xor e add a,l ld l,a jr nc,x21FF inc h x21FF ld a,d xor (hl) ld e,a inc hl xor a xor (hl) ld d,a dec bc ld a,c or b jr nz,x21F1 pop ix ex de,hl ret ;АДРЕС: #220F суммирование байта с контрольной суммой CMOS CRC8 ;вх: a - значение ; de - контрольная сумма ;вых: de - контрольная сумма (новое значение) x220F push hl ld hl,x2222 xor e add a,l ld l,a jr nc,x2219 inc h x2219 ld a,d xor (hl) ld e,a inc hl xor a xor (hl) ld d,a pop hl ret ;АДРЕС: #2222 данные для подсчета контрольной суммы ;АДРЕС: #2223 данные для подсчета контрольной суммы x2222 INCBIN "prof_roms/rom7_data4CRC.bin" ;АДРЕС: #2422 определение наличия SMUC ;вых: cy=1 SMUC не найден ; =0 SMUC обнаружен ; d - номер версии ; e - номер ревизии x2422 ld de,#FFFF call x0D51 ;определение наличия SMUC jr c,x2441 ;не найден ld bc,#5FBA in a,(c) inc a jr z,x2441 ;версии нет. не найден dec a call x2443 ;преобразование версии/ревизии в число ld d,a ld bc,#5FBE in a,(c) call x2443 ;преобразование версии/ревизии в число ld e,a ret x2441 scf ret ;преобразование версии/ревизии в число x2443 ld b,a rrca rrca rrca and #01 ld c,a ld a,b rlca rlca rlca or c and #07 ret ;неиспользуемая область x2452 ds #AE,0 ;not used ;АДРЕС: #2500 ROM-disk x2500 INCBIN "prof_roms/rom7_ROMdisk.bin" SAVEBIN "../Build/scorp/NewROM7.bin",#0000,#4000