Из журнала Adventurer #4, Рыбинск, 18.08.1996 +---------------+ +-----+-+ Дисковые +-+-----+ ----+ ----+---=============---+---- +---- +-----+-+ загрузчики +-+-----+ +---------------+  Nicolas Viper От редакции: эта статья готовилась как продолжение материала о дисковых загруз- чиках для журнала "Эльдорадо". Но так как это издание прекратило свою деятельность, Condor Soft любезно предоставил эти мате- риалы для ADVENTURER'а. А я, Nicolas Viper, снова с Вами. Извините меня, что использую журнал для личных целей, но если я еще услышу, что меня называют - Николас Вампир - обижусь и уйду на "Dendy". Уж если хотите знать, то "Viper", кроме всего прочего перево- дится как и "Adder" - гадюка (зоол.). Еще раз дико извиняюсь, но мы отвлеклись. Надеюсь, вы не забыли мой нудный монолог во втором номере журнала "Эльдорадо" ? Вы ведь помните - я обещал расска- зать о том, как сделать музыку во время загрузки (и не только музыку), наподобие того, как это делается в "INSULT", "BATTLE COMMAND" и т.д. Конечно, мое из- ложение страдает некоторой громоздкостью, но ведь если не я, то кто же еще ?! Не гениальный ли наш Nicodim ? Надо сказать, что в прошлый раз я, фактически, всего лишь пересказал книгу Родионова и Ларченко "ZX-Spectrum & TR- DOS для пользователей и программистов". От себя я добавил только описание некото- рых процедур ПЗУ ДОС. Сделал я это с од- ной целью - подготовить Вас, дорогие чи- татели, к этой статье. В целом, программа, занимающаяся ЭТИМ, схожа с той, которую мы рассматри- вали в прошлый раз (взятую из "ZX-Ревю" N4 за 1995). Но здесь есть проблема номер раз: Необходимо, чтобы прерывания были все время разрешены, а процедура по адре- су #2F1B, к которой обращается наш "loader" их запрещает (и правильно дела- ет). Поэтому заменяем в программе: ... LD IX,#2F1B CALL DOS ... на: ... CALL LOA_COM ... Т.е. вместо ПЗУ ДОС вызываем свою процедуру, которую добавляем в конце: LOA_COM LD A,E ;преобразуем ном. INC A ;сектора и посы- LD C,#5F ;лаем его в порт LD IX,#2A53 ;#5F (рег.секто- CALL DOS ;ра) TRY_1 ; PUSH HL ;сохраняем на PUSH DE ;случай ошибки ; LD A,#80 ;#80-чт. сектора LD C,#1F ;пишем в рег.ко- LD IX,#2A53 ;манд CALL DOS ; LD C,#7F ;#7F-рег. данных LD IX,#3FE5 ;чте CALL DOS ; ние { Проверка правильности чтения (ППЧ) } POP DE \ POP HL } (*) RET / Несложно заметить, что эта процедура - переделка процедуры ПЗУ ДОС по адресу #2F1B. Кусок помеченный, как (*), скорее всего, войдет в процедуру ППЧ. Здесь встает самая наиофигеннейшая (во завернул!) проблема - "контроль пра- вильности чтения". Полагаться в этом деле на ДОС по-моему нельзя, т.к. там просто не предусмотрен, например, вариант, когда процедура по адресу #3FE5 (см. выше) м.б. прервана в начале, середине или в конце своей работы. Короче, я хочу сказать, что делать ЭТО придется вручную, т.е. либо записы- вать на сектор 254-255 байт, а 1-2 отво- дить под контрольные суммы (сокращенно "КС"), либо грузить их ("КС") в начальном этапе загрузки, когда Вы еще пользуетесь #3D13, а потом в процедуре ППЧ посчитать "КС" (звучит уморительно, не правда ли ?) и сверить со считанной или табличной. Как посчитать "КС" ? Это нетрудно. Обычный метод - проксорить все байты друг с другом - полученное число и есть "КС". В общем, абсолютно точных рецептов я Вам не дам. Если захотите, то в следующем номере я дам ПОЛНЫЙ листинг рабочей про- цедуры, набитой и проверенной лично мной. Под конец, пример программы обра- ботки прерываний: ORG #FEFE JP IM2_COM ... CALL MUS_INIT ;б.к. DI ;это установка LD A,#FD ;2-ых прерываний LD I,A ;(вдруг Вы не LD HL,#FD00 ;знаете, как это LD DE,#FD01 ;делать). LD BC,256 LD (HL),#FE LDIR IM 2 EI ... Здесь ваш (наш) загрузчик. ... В конце добавляем: ... IM2_COM LD (STACK),SP PUSH AF ... PUSH ... CALL MUS_PLY ;играет музыка ; LD HL,(STACK) ;смотрим, куда INC HL ;же мы возвра- LD A,(HL) ;щаемся? CP #40 ; JR NC,RETRAM ;в ОЗУ LD A,#C3 ;в ПЗУ LABEL1 LD (CHANGE),A ; POP ... ;код #C3 - JP ... POP AF CHANGE NOP ;тут ставим JP DEFW #3D2F ; или RET RETRAM LD A,#C9 ;код RET JR LABEL1 STACK DEFW 0 ------------------------------- От редакции: Ниже приведен текст загруз- чика из журнала "Эльдорадо" N2, на кото- рый ссылается автор данной статьи. Вход- ные данные : HL - адрес загрузки, DE - дорожка и сектор, B - число секторов. ORG 50000 DRIVER DI LD IX,#2F65 ;(12133) Подпрограмма CALL DOS ;инициализации. L1 PUSH DE ;Сохраняем DE и BC. PUSH BC ; OR A ;Переводим из логи- LD A,D ;ческого номера до- RRA ;рожки в физический. LD C,A ;(обсудим позже) LD A,#3C ;#3C=%00111100 JR NC,L2 ;#2C=%00101100 LD A,#2C ; ^сторона. ; L2 LD IX,#2F4D ;Подпрограмма уста- CALL DOS ;новки на дорожку. ;(12109) POP BC ;Восстанавливаем POP DE ; BC и DE. M2 PUSH HL ;Сохраняем PUSH DE ; регистры. PUSH BC ; LD IX,#2F1B ;(12059) Собственно CALL DOS ;чтение. POP BC ;Восстанавливаем POP DE ; регистры. POP HL ; INC H ;Поскольку считаем, ;что длина сектора ;256 байт. INC E ;Следующий сектор. LD A,15 ;15=%00001111 AND E ;Если E=16, то E=0, LD E,A ;флаг Z=1 и переход JR Z,L5 ;на следующую дорож- DJNZ M2 ;ку, иначе просто ;следующий сектор. JR EXIT ;На выход. L5 INC D ;Следующая дорожка. DJNZ L1 ; EXIT EI ; RET ;Выход. ; DOS ;На стеке - адрес ;возврата. PUSH IX ;На стеке - адрес ;вызываемой процеду- ;ры. JP #3D2F ;(15663) Подключает- ;ся ПЗУ ДОС, а там находится: #3D2F NOP #3D30 RET. По RET управление передаёт- ся нужной Вам подпрограмме ПЗУ ДОС, а она вернётся в точку, откуда вызывали процедуру "DOS". Надеюсь, Вы поняли, что к чему и Вам не понадобится следующая статья, чтобы написать свой крутой загрузчик. Еще хотелось бы сказать несколько слов: Те из Вас, кто набил и опробовал загрузчик наверное заметили, что он ужас- но медлителен, даже при запрещенных пре- рываниях. Это говорит лишь об одном - ищите и дерзайте! НИКОГДА НЕ БОЙТЕСЬ ЭКСПЕРИМЕН- ТИРОВАТЬ! В разумных пределах, конечно! * * * Из журнала Adventurer #6, Рыбинск, 30.03.1997 Мы продолжаем цикл статей, посвящен- ных дисковым загрузчикам. Слово нашему корреспонденту.  Nicolas Viper "Чем ленивее человек, тем больше любой его поступок похож на подвиг." Народная мудрость Задержка великовата, ну а кому нынче легко ? Доставайте свои мозги из баночек с растворами, протрите, у кого запыли- лись, и вникайте. Прежде всего необходимо заметить, что утверждение, будто в проверке пра- вильности чтения (далее: ППЧ) ДОС нам по- мочь не может оказалось НЕВЕРНЫМ. Только, в свою очередь, мы должны помочь ему. Взгляните на листинг: ORG 40000 DI ;Инсталляция: LD HL,#FD00 ;-Пре LD A,H ; ры LD DE,#FD01 ; ва LD BC,256 ; ний LD (HL),#FE LDIR LD I,A IM 2 CALL MUSRUN ;-Музыки EI LD DE,#0100 ;-Откуда, LD HL,16384 ; куда и LD B,27 ; сколько будем CALL LOADER ; грузить JP MUSRUN ; Music off + RET *************** ГРУЗИМ ***************** LOADER LD IX,#2F65 ;Раскрутка CALL DOS L1 PUSH DE PUSH BC LD A,D OR A RRA LD C,A LD A,#3C JR NC,L2 LD A,#2C L2 LD IX,#2F4D ;Ставим череп на CALL DOS ;дорогу POP BC POP DE PUSH HL PUSH DE PUSH BC CALL LOA_COM POP BC POP DE POP HL ;Пересчет: INC H ;- адреса LD A,E ;- сек INC A ; то AND 15 ; ра LD E,A JR NZ,L5 ;- дороги INC D L5 DJNZ L1 ;Новый сектор DI ;Выход IM 1 EI RET Эта часть не поменялась со времен первого пришествия. А вот самое важное: LOA_COM LD C,#5F ;Пересчет номера LD A,E ;сектора, засыл- INC A ;ка в регистр LD IX,#2A53 ;сектора ВГ-шки CALL GODOS TRY1 PUSH HL ;На стек PUSH DE TRYMET XOR A ;Ошибок нет LD (ERRFLG+1),A ;(пока :) LD B,A ;B=0 LD C,#1F ;Команда LD A,#80 ;"чтение LD IX,#2A53 ; сектора" CALL DOS LD C,#7F ;Чтение сектора LD IX,#3FE5 CALL GODOS POP DE ;Взяли со стека POP HL ERRFLG LD A,0 ;Проверка на OR A ;ошибки во время JR NZ,TRY1 ;чтения. (под- LD D,1 ;робнее описано LD IX,#2F2F ;ниже) JP GODOS DOS HALT GODOS PUSH IX JP #3D2F IMCOM ;Словили преры- LD (STACK),SP ;вание PUSH IX PUSH HL ;Тут тоже в PUSH DE ;двух словах PUSH AF ;не опишешь :) PUSH BC ;Ищите подроб- CALL MUSIC ;ности ниже. LD HL,(STACK) LD E,(HL) INC HL LD D,(HL) LD A,D CP #40 JR NC,RETOS CP #3F JR NZ,PA_CNT POP BC PUSH BC LD A,B LD (ERRFLG+1),A PA_CNT LD HL,0-#2F3A OR A ADC HL,DE JR Z,RTBR LD A,#C3 POPALL LD (CHANGE),A POP BC POP AF POP DE POP HL POP IX EI CHANGE JP #3D2F RETOS LD A,#C9 JR POPALL RTBR LD SP,(STACK) POP AF EI JP TRYMET STACK DW 0 ORG #C000 INSERT "MUSIC" ORG #FEFE JP IMCOM MUSRUN EQU #C000 MUSIC EQU #C006 По адресу #2F2F в TR-DOS: #2F2F IN A,(#1F) AND #7F RET Z DEC D PUSH HL PUSH DE JR NZ,#2EXX ;Неважно куда HALT ;) Ловим! Кратенько: По поводу IMCOM : задача этой процедуры - проверить, когда пришло прерывание. Возможны варианты: - в ОЗУ. Тогда нам все по барабану - иг- раем музыку и вертаемся. - в ПЗУ (считаем, что это ДОС!!! По-идее, мы в СОС не попадаем). Тогда тоже ва- рианты: - Схватили с адреса #2F3A - это зна- чит, что мы словили HALT (см. выше), что, в свою очередь, говорит о том, что при чтении произошла одна из "стан- дартных" ошибок - потеря данных, не- совпадение контрольных сумм и т.п. - ...с адреса #3FXX (XX - любое значе- ние) - опять-таки, по идее, мы там мо- жем перехватить только процедуру чте- ния сектора. Это значит, что, увы, у нас неопределенное положение - надо закончить процедуру, но из-за задержки на проигрывание мелодии и т.п. мы упустили время и чтение придется пов- торить. При возникновении ошибки, мы кладем по адресу (ERRFLG + 1) НЕ ноль - это го- ворит, что необходимо перечитать сектор (см. с метки ERRFLG). Все остальное не так сложно и было расписано раньше. Пишите, если что не так, в редакцию или мыльте мне: nicky#univ.uniyar.ac.ru Хотя, судя по предыдущим публикаци- ям, вы, дорогие читатели, все равно не обратили на данную процедуру никакого внимания - глюков в ней было полно, а никто так и не написал: "...из-за этого Вашего #@$&$-го прога я себе дискету ис- портил, любимую!" -------------------------