Из журнала Deja Vu #06, Кемерово, 01.10.98 Автор: Card!nal/PGC/BD __________________________________________ Сверхбыстрое форматирование дисков на Speccy - это реальность. - Что-то ты сегодня неважно выглядишь. - Да моча в голову ударила :-( - А почему синяк под глазом? - А ты думал, горшок мимо пролетел? (вместо эпиграфа) Привет, уважаемые читатели Deja Vu! С вами опять я. На этот раз я расскажу вам о быстром форматировании TR DOS дисков. На страницах Ревюшек неоднократно появлялись статейки, в которых люди высказывали раз- личные идеи на счет форматирования дорожки за один оборот. Предположений было много, но все они сводились к одному - нужно фор- матировать дорожку не полностью, а чуть- -чуть не доходить до конца и прерывать вы- полнение операции "запись дорожки". После этого должно остаться время на перепозици- онирование головки дисковода, и прежде,чем текущая дорожка закончится,т.е. до прихода индексного импульса, нужно все успеть под- готовить для форматирования следующей до- рожки. Но вся загвоздка в том,что прервать форматирование практически невозможно. А почему? - спросите вы. Потому что для за- писи дорожки обычно используется подпрог- рамма по адресу #3FCA в ПЗУ TR DOS. Вот ее листинг, HL указывает на данные: #3FCA IN A,(#FF) AND #C0 JR Z,#3FCA RET M OUTI JR #3FCA Из него видно,что, действительно, выход осуществляется по приходу индексного им- пульса. Но в ПЗУ TR DOS есть еще одна под- программа записи данных на диск. Находится она по адресу #20AF: #20AF LD B,1 #20B1 IN A,(#FF) AND #C0 JR Z,#20B1 RET M OUT (C),D DJNZ #20B1 RET Вот ее мы и возьмем на вооружение.Здесь сразу видно, что выход возможен не только по приходу индексного импульса, но и когда регистр B станет равен нулю. Но прежде,да- вайте немного посчитаем. Дисковод крутит диски со скоростью 300об/мин. На один обо- рот диска уходит 0.2 секунды. На одной до- рожке располагается, примерно,6150 байтов, значит на запись одного байта должно быть потрачено не более 0.2*50*70000/6150=113.8 тактов. Но т.к. есть тормозные Спектрумы, то будем считать, что предел 100 тактов. Итак, чтобы воспользоваться процедурой по адресу #20B1, нужно максимально ускорить процесс вызова этой процедуры с нужными данными в регистре D. Один несознательный пипл утверждал, что это невозможно, но он был неправ. Сделать это можно, примерно, так: LD HL,#3D2F LD (STACK1+1),SP LD SP,ADRTAB LD C,#7F FAQ POP DE LD B,E JP (HL) STACK LD A,#D0 ;принудительное прерывание LD C,#1F JP (HL) STACK1 LD SP,0 RET Формат таблицы ADRTAB таков: ADRTAB DEFB COUNTER ;сколько байтов записывать DEFB BYTE ;байт для записи DEFW #20B1 DEFW FAQ ;метка FAQ ... и так далее... заканчивается таблица так: DEFB COUNTER DEFB BYTE ;последний байт для записи DEFW #20B1 DEFW STACK DEFW #2A53 DEFW STACK1 Скорость работы процедуры = 92 такта, как видите, вполне хватает времени, чтобы успеть выдать следуюций байт для записи его на диск. К тому же на дорожку записы- ваются не все 6150 байтов, а только 5980. После записи последнего сектора с конт- рольной суммой, форматирование дорожки об- рывается. Можно еще ускорить процедуру,ес- ли в HL занести #3D30 вместо #3D2F. Ско- рость при этом увеличится на 4 такта и со- ставит 88 тактов. Правда кое-кто утвержда- ет, что на некоторых Спектрумах на перек- лючение страничек ПЗУ требуется парочка- -другая тактов процессора. Я хорошо пред- ставляю себе как происходит, грубо говоря, переключение ПЗУ. ПЗУ'шка TR DOS включает- ся, когда на шине адреса появляются адреса #3D00 - #3DFF, кроме того,в это время дол- жно быть подключено ПЗУ BASIC-48, а не BA- SIC-128, иначе TR DOS не подключится. Всем этим занимаются микросхемы,и по-моему так- ты процессора здесь не причем. Мое мнение, что к TR DOS можно спокойно обращаться и по #3D30. Все должно работать. Я лично не слышал, что у кого-то не работали игры: DOUBLE XINOX; 48 утюгов (crack by MAFIA) или там ZX-FORMAT'ы. А ведь в этих прог- раммах во всю используется #3D30. Сам ви- дел. Я изменю свое мнение,если мне докажут (а лучше покажут) обратное. Но я отвлекся. Конечно, перед вызовом этой программы надо раскрутить дисковод, спозиционировать го- ловку, подправить значения в таблице (но- мера секторов и дорожек),а после этого еще и смочь прочесть регистр состояния ВГ'шки (вдруг диск заклеен). Полностью программу форматирования я не привожу,вы все найдете в исходнике этого форматера в Приложении журнала под именем FASTFORM.H в формате ассемблера ALASM. Еще скажу, что табличка ADRTAB не очень большая,чуть меньше 1.5Kb. Про другие мелочи я говорить не буду, вы сами все поймете, загрузив исходник с под- робными комментариями. Попробуйте отформа- тировать диск,а потом проверить его на ка- чество RDS'кой.Желательно использовать ка- чественные дискеты. Ведь фактической про- верки качества формата не делается,но зато скорость высокая - 32 секунды! Напоследок хочу сказать одно пояснение на несколько другую тему. Некоторые,опять- -таки несознательные элементы,пытаются за- пудрить мозги, говоря следующее. Мол, на Scorp'е можно напрямую обращаться к регис- трам ВГ. А для этого надо занести в порт #1FFD единицу, чтобы подключить страницу ОЗУ вместо ПЗУ и свободно программировать ВГ'шку. А я заявляю,что таким образом дос- туп к регистрам ВГ напрямую невозможен. Сам проверял различными способами. Хочется пожелать, что идею надо сначала проверить на деле прежде, чем так говорить. Но зато на Scorp'е можно без проблем читать ре- гистр состояния контроллера. Видимо разра- ботчики учли этот факт и по адресу #3FF3 прошили команды: IN A,(C):RET. У меня все. Bye. ;============================================================== ;¦ СУПЕР БЫСТРЫЙ ФОРМАТЕР. ¦- ;¦ ВОЗМОЖНОСТЬ ФОРМАТИРОВАНИЯ В ЛЮБОМ НАПРАВЛЕНИИ (ОТ НАЧАЛЬ- ¦- ;¦ НЫХ ТРЕКОВ К КОНЕЧНЫМ И НАОБОРОТ) ¦- ;¦ СКОРОСТЬ ФОРМАТИРОВАНИЯ ДИСКА = 32 СЕКУНДЫ!!! (РЕКОРД!) ¦- ;¦ ФОРМАТЕР УВЕРЕННО РАБОТАЕТ НА КАЧЕСТВЕННЫХ ДИСКОВОДАХ И ¦- ;¦ ДИСКЕТАХ. ¦- ;¦ ¦- ;¦ ORIGINAL IDEA, CODING BY Card!nal/PGC/BDA ¦- ;¦ REALISE DATE: 15.08.1998. ¦- ;¦ ¦- ;¦ SPECCY RULEZ FOREVER!!! ¦- ;==============================================================- ; -------------------------------------------------------------- ADRFMT EQU #20B1 ;ПОДПРОГРАММА В TR_DOS ORG #6000 FORM_T DI LD (ERROR+1),SP LD A,#10 ;ВКЛЮЧАЕМ 0-УЮ СТРАНИЦУ LD BC,#7FFD ;НА ВСЯКИЙ СЛУЧАЙ OUT (C),A LD A,159 ;НАЧАЛЬНЫЙ TRACK LD (TRK),A CALL SET_TAB ;ТАБЛИЧКА СМЕЩЕНИЯ СЕКТОРОВ CALL DECRFMT ;ТАБЛИЧКА ФОРМАТИРОВАНИЯ XOR A ;НОМЕР ДРАЙВА (0=A, 1=B, 2=C, 3=D) LD (DRIVE),A CALL INITDR ;ИНИЦИАЛИЗИРУЕМ ДИСКОВОД FFF LD B,160 ;КОЛ. ТРЕКОВ FORM_T1 PUSH BC CALL USTA_N ;МЕНЯЕМ TRK И SECTOR В ТАБЛИЧКЕ LD A,5 LD (COUNTER+1),A CALL FORMAT ;ФОРМАТИРУЕМ ТРЕК СОБСТВЕННО... POP BC LD HL,TRK DEC (HL) ;СЛЕД. TRACK DJNZ FORM_T1 CALL SAVECAT ;ЗАПИСЫВАЕМ КАТАЛОГ XOR A ERROR LD SP,0 ;ЕСЛИ ПРИ ВЫХОДЕ BORDER СТАЛ КРАСНЫМ, OUT (254),A ;ЗНАЧИТ ПРОИЗОШЛА ОШИБКА (ЗАЩИТА ЗАПИСИ ;НАПРИМЕР...) RET INITDR LD A,(DRIVE) OR #3C LD B,A LD C,#FF CALL TO_DOS LD C,#1F LD A,8 LD IX,#2F65 CALL DOS LD D,H ;ПАУЗА НА РАСКРУТКУ ДИСКА LD E,L LD BC,0 LDIR LDIR LDIR RET DECRFMT LD HL,ADRTAB LD DE,FMT_T LD A,54 LD (FMT_T2),A LD B,5 CALL LL1 LD C,15 DECRFM1 LD DE,FMT_T1 LD B,15 CALL LL1 DEC C JR NZ,DECRFM1 LD A,8 LD (FMT_T2),A LD DE,FMT_T1 LD B,15 CALL LL1 DEC HL DEC HL LD (HL),.STACK INC HL LD (HL),'STACK INC HL LD (HL),#53 INC HL LD (HL),#2A INC HL LD (HL),.STACK1 INC HL LD (HL),'STACK1 RET LL1 LD A,(DE) LD (HL),A INC DE INC HL LD A,(DE) LD (HL),A INC DE INC HL LD (HL),#B1 INC HL LD (HL),#20 INC HL LD (HL),.FAQ INC HL LD (HL),'FAQ INC HL DJNZ LL1 RET FMT_T DEFB 80,#4E,12,0,3,#F6,1,#FC,10,#4E FMT_T1 DEFB 12,0,3,#F5,1,#FE,1,0,1,0,1,1,1,1,1,#F7,22,#4E,12,0 DEFB 3,#F5,1,#FB,0,0,1,#F7 FMT_T2 DEFB 54,#4E USTA_N LD A,(TRK) LD H,0 LD L,A ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL LD DE,ADRSEC ADD HL,DE EX DE,HL LD HL,ADRTAB+#31 RRA LD (L_US+1),A LD LX,16 L_US LD (HL),0 LD BC,12 ADD HL,BC LD A,(DE) INC A LD (HL),A INC DE LD BC,78 ADD HL,BC DEC LX JR NZ,L_US RET SET_TAB LD HL,ADRSEC XOR A LD DE,#A60F ;D=166 > MAX TRACKS L_ST1 LD B,16 L_ST LD (HL),A INC HL INC A AND E DJNZ L_ST SUB 2 ;СМЕЩЕНИЕ СЕКТОРОВ = 2 AND E DEC D JR NZ,L_ST1 RET FORMAT LD B,0 TRK EQU $-1 LD D,B SRL B LD C,#7F CALL TO_DOS LD A,#3C BIT 0,D JR Z,$+4 LD A,#2C OR 0 DRIVE EQU $-1 LD B,A LD C,#FF CALL TO_DOS LD BC,#181F CALL TO_DOS LD IX,ADRFMT-2 ;ЖДЕМ ВЫПОЛНЕНИЯ КОМАНДЫ LD D,#18 ;ХОТЯ ЕСТЬ, КОНЕЧНО, ПРОЦЕДУРКА В DOS LD C,#1F ;ПО АДРЕСУ #3EF5, НО ОНА РАЗРЕШАЕТ WAIT CALL DOS ;ПРЕРЫВАНИЯ ПРИ СВОЕЙ РАБОТЕ, ЧТО В AND #80 ;НЕКОТОРЫХ СЛУЧАЯХ НЕ СОВСЕМ УДОБНО:-( JR Z,WAIT LD BC,#F01F CALL TO_DOS LD HL,#3D2F LD (STACK1+1),SP LD SP,ADRTAB LD C,#7F FAQ POP DE ;А ЭТО И ЕСТЬ СВЕРХСКОРОСТНАЯ ПРОГРАММА LD B,E ;ЗАПИСИ ДАННЫХ НА ДИСК JP (HL) STACK LD A,#D0 ;ПРИНУДИТЕЛЬНОЕ ПРЕРЫВАНИЕ LD C,#1F JP (HL) STACK1 LD SP,0 CALL REG_1F CALL #1F54 ;BREAK KEY LD A,2 JP NC,ERROR BIT 6,B JP NZ,ERROR LD A,B AND #7C RET Z COUNTER LD A,5 ;ПРОИЗОШЛА ОШИБКА (!!!?), ХМММ... DEC A ;ПЫТАЕМСЯ ОТФОРМАТИРОВАТЬ TRACK ЕЩЕ РАЗ LD (COUNTER+1),A;(А ВСЕГО ПОПЫТОК ПЯТЬ!) LD A,2 JP NZ,FORMAT JP ERROR ;GAME OVER TO_DOS LD IX,#2A53 LD A,B DOS PUSH IX JP #3D2F REG_1F LD A,(#5D0E) ;ПРОЦЕДУРА ЧТЕНИЯ LD (ST1+1),A ;РЕГИСТРА СОСТОЯНИЯ ВГ93. LD A,(#5D0C) ;ВЗЯТА ИЗ РЕВЮШКИ, ЦОПИРИХТ РОЩИН И.:-) LD (ST2+1),A LD A,(#5CB6) LD (ST3+1),A LD A,(#5D1F) LD (ST4+1),A LD A,(#5D3A) LD (ST5+1),A LD A,(#5D17) LD (ST6+1),A LD HL,(#5D1A) LD (ST7+1),HL LD HL,(#5D1C) LD (ST8+1),HL LD HL,(#5CF8) LD (ST9+1),HL LD A,#FF LD (#5D0C),A LD (#5D1F),A DEC A LD (#5D0E),A LD A,#F4 LD (#5CB6),A LD HL,S_SPEC LD (#5D1A),HL LD HL,0 ADD HL,SP LD DE,-12 ADD HL,DE LD (#5D1C),HL LD BC,#003F CALL TO_DOS LD BC,#0A5F CALL TO_DOS LD D,1 LD IX,#3F33 CALL DOS E_1F PUSH BC LD A,(TRK) SRL A LD B,A LD C,#3F CALL TO_DOS POP BC ST1 LD A,0 LD (#5D0E),A ST2 LD A,0 LD (#5D0C),A ST3 LD A,0 LD (#5CB6),A ST4 LD A,0 LD (#5D1F),A ST5 LD A,0 LD (#5D3A),A ST6 LD A,0 LD (#5D17),A ST7 LD HL,0 LD (#5D1A),HL ST8 LD HL,0 LD (#5D1C),HL ST9 LD HL,0 LD (#5CF8),HL RET S_SPEC POP BC LD HL,(#5D1C) LD DE,12 ADD HL,DE LD SP,HL JR E_1F ADRTAB DEFS 1474 ;ТАБЛИЦА ФОРМАТА ДОРОЖКИ ADRSEC DEFS 2656 ;ТАБЛИЧКА СЕКТОРОВ ;--------------------------------------------------------------- SAVECAT LD A,(FFF+1) DEC A LD L,A LD H,0 ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL LD (BUFCAT1),HL LD HL,BUFCAT LD DE,#0008 LD BC,#0106 JP #3D13 BUFCAT DEFS #E1 DEFB 0,1,#16,0 BUFCAT1 DEFB 0,0,#10,0 DEFS 12 DEFB "PLAYGEAR",0,0,0