Адрес #1EC2. Выполнение команды FORMAT. Установите #5D11 и #5C3B. Используется также с адреса #1EDD (повторение форматирования; установите #5CDD).
#1EC2 LD HL,#FFFF
LD (#5CD7),HL ;дорожки не проверять
LD (#5CD9),HL ;форматировать одну сторону диска
LD (#5CD1),HL ;ошибку при чтении адресного маркера игнорировать
CALL #42B ;следующий символ ENTER?
JP Z,#1D1A ;если да, то ошибка
CALL #1DDF ;прием имени диска на стек калькулятора
CALL #1D75 ;если идет проверка на синтаксис, то возврат
CALL #1C57 ;установка имени диска
#1EDD CALL #3200 ;выбор быстрого или обычного формата
AND #80 ;дисковод 40-дорожечный?
LD A,#28 ;форматировать 40 дорожек
JR Z,#1EE8 ;если дисковод 80-дорожечный,
LD A,#50 ;то форматировать 80 дорожек
#1EE8 LD (#5CD7),A ;установка количества дорожек
CALL #3D98 ;восстановление
CALL #1FF6 ;выбор нижней стороны диска
CALL #3EA0 ;задержка в 3135098 тактов
LD E,1 ;форматирование дорожки с номером 1
CALL #1FFD
CALL #1FEB ;выбор верхней стороны диска
LD E,0 ;форматирование дорожки с номером 0
CALL #1FFD
LD A,(#5CDD) ;форматировать только одну сторону диска
CP "$"
JR Z,#1F1B ;если да, то форматирование диска
CALL #1FF6 ;выбор нижней стороны диска
CALL #3EA0 ;задержка в 3135098 тактов
CALL #3EB5 ;чтение адресного маркера
LD A,H ;номер дорожки - 1?
CP 1
JR NZ,#1F1B ;если нет, то форматирование диска
LD A,#80 ;форматировать обе стороны диска
LD (#5CDA),A
#1F1B CALL #20BD ;форматирование диска
LD HL,#5D25 ;адрес начала буфера
LD (HL),0 ;очистка первого байта
LD DE,#5D26 ;адрес второго байта буфера
LD BC,#FF ;осталось очистить #FF байтов
LDIR ;очистка буфера
LD BC,#5CD7 ;адрес переменной с количеством дорожек
LD DE,#5CDA ;адрес переменной с количеством сторон
LD A,(BC) ;форматировали 80 дорожек?
CP #50
JR Z,#1F49 ;если да, то диск 80-дорожечный
LD A,(DE) ;форматировали 2 стоpоны?
CP #80
JR Z,#1F42 ;если да, то диск 40-дорожечный двухстоpонний
LD A,#19 ;диск 40-дорожечный односторонний
LD HL,#270 ;свободно #270 сектора
JR #1F55 ;создание описателя диска
#1F42 LD A,#17 ;диск 40-дорожечный двухсторонний
#1F44 LD HL,#4F0 ;свободно #4F0 сектора
JR #1F55 ;создание описателя диска
#1F49 LD A,(DE) ;форматировали 2 стороны?
CP #80
LD A,#18 ;если нет, то диск 80-дорожечный односторонний
JR NZ,#1F44
LD A,#16 ;иначе диск 80-дорожечный двухсторонний
LD HL,#9F0 ;свободно #9F0 сектора
#1F55 LD (#5E08),A ;установка типа диска
LD (#5E0A),HL ;установка количества свободных секторов
LD A,1 ;первая свободная дорожка - 1
LD (#5E07),A
LD A,#10 ;признак принадлежности диска к TR-DOS
LD (#5E0C),A
LD HL,#5E0F ;9 байтов #20 с адреса #5E0F
LD DE,#5E10
LD BC,8
LD (HL),#20
LDIR
LD HL,#5CDD ;установка имени диска
LD DE,#5E1A
LD BC,8
LDIR
CALL #1FEB ;выбор верхней стороны диска
LD B,1 ;записать 1 сектор
LD DE,8 ;сектор 8 дорожки 0
LD HL,#5D25 ;из буфера
CALL #1E62 ;запись сектора
LD A,(#5CD6) ;берем количество дефектных секторов
PUSH AF ;сохраняем его
XOR A ;расширение - CHR$ 0
CALL #32C4 ;установка расширения и очистка низа экрана
LD HL,(#5E0A) ;берем количество свободных секторов
LD (#5CD7),HL ;сохраняем его
LD HL,#5CDD ;печать имени диска
RST #18
LD A,#D ;перевод строки
RST #10
LD HL,(#5CD7) ;восстановление количества свободных секторов
POP AF ;восстановление количества дефектных секторов
PUSH HL ;сохранение количества свободных секторов
LD D,0 ;перевод количества дефектных секторов в
LD E,A ;двухбайтную форму
SBC HL,DE ;вычисление количества хороших секторов
LD B,H ;переброска его в BC
LD C,L
CALL #1DA9 ;печать его
LD A,"/" ;печать "/"
RST #10
POP BC ;восстановление количества свободных секторов
CALL #1DA9 ;печать его
JP #326B ;запрос повтора форматирования
----------------------------------------------------------------
Адрес #1FB9. Таблица секторов для форматирования обычного диска. Используется также с адреса #1FBA для проверки дорожки.
#1FB9 DB 1
#1FBA DB 9,2,#A,3,#B,4,#C,5,#D,6,#E,7,#F,8,#10,1
----------------------------------------------------------------
Адрес #1FCA. Определение количества дорожек дисковода. Вход: установите время перемещения головки дисковода. Выход: в #5CD7 и регистре A будет количество дорожек дисковода.
#1FCA CALL #3E08 ;берем время перемещения головки
OR #11 ;позиционирование на дорожку #32
LD B,A
LD A,#32
CALL #3E44
LD A,2 ;затем на дорожку 2
CALL #3E44
CALL #3DFD ;задержка в 725779 тактов
IN A,(#1F) ;головка в исходном положении?
AND 4
LD A,#50 ;если нет, то у дисковода 80 дорожек
JR Z,#1FE7
LD A,#28 ;иначе 40
#1FE7 LD (#5CD7),A ;установка количества дорожек
RET ;возврат
----------------------------------------------------------------
Адрес #1FEB. Выбор верхней стороны диска. Установите #5D16. Используется также с адреса #1FF0 (загрузка системного регистра, код - в аккумуляторе). Вы можете также использовать с адреса:
#1FF3 для прямого вывода в порт #FF.
#1FEB LD A,(#5D16) ;берем копию системного регистра
OR #3C ;формат MFM, верхняя сторона, выключение сброса и готовности
#1FF0 LD (#5D16),A ;запоминаем копию системного регистра
#1FF3 OUT (#FF),A ;установка системного регистра
RET ;возврат
----------------------------------------------------------------
Адрес #1FF6. Выбор нижней стороны диска. Установите #5D16.
#1FF6 LD A,(#5D16) ;берем копию системного регистра
AND #6F ;формат MFM, нижняя сторона, выключение сброса и готовности
JR #1FF0 ;установка системного регистра
----------------------------------------------------------------
Адрес #1FFD. Форматирование дорожки. В регистр Е поместите ее номер и спозиционируйте головку дисковода. Из переменных установите #5CD8, #5CE6, #5CE8 и обнулите #5CD6. Используется также с адреса #1FC9 (проверка дорожки; установите #5CD8, #5CE8 и обнулите #5CD6 и спозиционируйте головку).
#1FFD DI ;запрет прерываний
LD A,#F4 ;запись дорожки
OUT (#1F),A
LD HL,(#5CE6) ;берем адрес таблицы секторов для форматирования
LD C,#7F ;адрес регистра данных
#2007 LD B,#A ;#A раз #4E (первый пробел)
LD D,#4E
CALL #20B1 ;запись байта заданное число раз
LD B,#C ;синхропромежуток
LD D,0
CALL #20B1
LD B,3 ;синхроимпульс
LD D,#F5
CALL #20B1
LD D,#FE ;1 раз #FE (адресная метка идентификатора)
CALL #20AF ;запись байта 1 раз
LD D,E ;номер дорожки
CALL #20AF
LD D,0 ;номер стороны (в TR-DOS всегда 0)
CALL #20AF
LD D,(HL) ;номер сектора из таблицы
CALL #20AF
LD D,1 ;длина сектора - #100 байтов
CALL #20AF
LD D,#F7 ;запись контрольной суммы
CALL #20AF
LD B,#16 ;второй пробел
LD D,#4E
CALL #20B1
LD B,#C ;синхропромежуток
LD D,0
CALL #20B1
LD B,3 ;синхроимпульс
LD D,#F5
CALL #20B1
LD D,#FB ;адресная метка данных
CALL #20AF
LD B,0 ;данные (#100 нулей)
LD D,0
CALL #20B1
LD D,#F7 ;запись контрольной суммы
CALL #20AF
LD B,#3C ;третий пробел
LD D,#4E
CALL #20B1
LD A,(HL) ;берем адрес номера следующего сектора
INC HL
CP #10 ;конец таблицы?
JR NZ,#2007 ;если нет, то форматирование следующего сектора
LD B,0 ;пробел до конца дорожки
CALL #20B1
JP M,#2076
CALL #20B1
#2076 IN A,(#1F) ;берем состояние контроллера
AND #40 ;запись запрещена?
JP NZ,#3F39 ;если да, то сообщение READ ONLY
#207D LD A,(#5CD8) ;дорожку проверять?
OR A
RET NZ ;если нет, то возврат
Внимание!!! Перед возвратом или выходом по ошибке надо разрешать прерывания.
LD C,#7F ;адрес регистра данных
LD A,E ;установка номера дорожки
OUT (#3F),A
LD HL,(#5CE8) ;берем адрес таблицы секторов для проверки
#208A LD B,3 ;3 попытки
LD A,(HL) ;берем номер сектора из таблицы
OUT (#5F),A ;установка сектора
PUSH HL ;сохранение адреса таблицы секторов
#2090 DI ;запрет прерываний
LD A,#80 ;чтение сектора
OUT (#1F),A
PUSH BC ;сохранение количества попыток
CALL #3FE5 ;чтение данных по адресу из HL (в пзу, не страшно)
IN A,(#1F) ;все в порядке?
AND #7F
POP BC ;восстановление счетчика попыток
JR Z,#20A6 ;если все в порядке, то следующий сектор
DJNZ #2090 ;следующая попытка
LD HL,#5CD6 ;есть 1 битый сектор
INC (HL)
#20A6 POP HL ;восстановление адреса таблицы секторов
LD A,(HL) ;берем номер текущего сектора
INC HL ;берем адрес номера следующего сектора
CP 1 ;конец таблицы?
JR NZ,#208A ;если нет, то повтор
EI ;разрешение прерываний
RET ;возврат
[свернуть]