ZX Review
#7-8-9-10
08 ноября 1997 |
|
Этюды - Обращение к диску в режиме IM 2. Работа с диском нестандартного формата.
(c) Лабутин Д., Нижегородская обл, г.Дзержинск Вы уже писали в ZX РЕВЮ-95 N5 на стр.53 о том, что можно ра- ботать с режимом прерываний IM 2 и при этом обращаться к диску. Этот способ мне не подошел, т.к., работая в режиме 128 Кб, программу обработки прерываний с адреса 65129 или 65524 распола- гать нельзя, т.к. страницы там постоянно меняются, а другого подходящего значения регистра I я не подобрал. Тогда я придумал другой способ. Все обращения к диску (CALL #3D13 или подобные) заменяем на CALL DOS. Подпрог- рамма DOS выглядит так: 140. DOS PUSH AF LD A,1 LD (FLAG),A POP AF CALL #3D13 PUSH AF XOR A LD (FLAG),A POP AF RET FLAG DEFB 0 А подпрограмма обработки пре- рываний выглядит так: IM2 PUSH AF LD A,(FLAG) OR A JR Z,IM21 POP AF PUSH HL LD HL,#3D2F EX (SP),HL PUSH AF PUSH BC IM21 ............... ;сохранение регистров CALL PROG ;обработка прерывания ............... ;восстановление регистров POP BC POP AF RET 2 Прим.ред.: Идея хорошая, только вы не учли того, что ПЗУ TR-DOS вызывает ПЗУ бейсика даже при выполнении таких простых операций, как чтение группы секторов. Для этого используется подпрограмма по адресу #5CC2, состоящая только из одной команды RET. На стек помещается адрес подпрограм- мы, в регистры загружаются параметры, и делается JP #5CC2. Возврат из подпрограм- мы происходит по адресу #3D2F. Чтобы ваш метод заработал, надо по адресу #5CC2 раз- местить JP на следующую подпрограмму: 140. POP HL ;берем адрес вызываемой подпрограммы PUSH AF ;сохраняем AF SUB A ;работает ПЗУ бейсика LD (FLAG),A POP AF ;восстановление AF PUSH HL ;сохраняем адрес вызываемой подпрограммы LD HL,L1 ;помещаем на стек новый адрес возврата ;из подпрограммы EX (SP),HL ;и восстанавливаем адрес подпрограммы PUSH HL ;помещаем на стек адрес подпрограммы LD HL,(23810);восстанавливаем HL RET ;переходим на подпрограмму L1 PUSH AF ;сохраняем AF LD A,#01 ;работает ПЗУ TR-DOS LD (FLAG),A POP AF ;восстановление AF RET ;возврат в ПЗУ TR-DOS 2 Пару слов по поводу восстановления HL. Подпрограмма вызова ПЗУ бейсика использует переменные 23810 и 23812 для сохранения HL и DE соответственно, следовательно, при вызове #5CC2 в этих переменных будут ко- пии этих регистров. Этот факт и использо- ван в приведенной подпрограмме. Корр.: Я сейчас пишу графи- ческую адвентюру (конечно, не я один, но я программирую), и в один момент понял, что дискеты в 640 Кб недостаточно для графики. Тогда я решил перейти на нестан- дартный формат. На одной дорож- ке 5 секторов по 1024 байта. По- лучается дискета размером в 800 Кб. Точно не помню, в какой про- грамме я отформатировал дискету, дав секторам номера 1, 2, 3, 4, 5. Казалось, что дело сделано, но не тут-то было - пятый сектор не читается. Можно сделать сле- дующее: 140. LD E,0 ;или 1,2,3 LD C,5 LD B,1 LD D,5 ;или любая ;дорожка LD HL,40000 CALL #3D13 Но если попробовать: LD BC,#0105 LD HL,40000 LD DE,#0504 CALL #3D13 2 то сектор не читается. Тут я вспомнил, что в IS DOS на дорож- ке 5 секторов по килобайту. Про- анализировав содержимое дорожки дискеты, отформатированной под IS DOS, я очень удивился. Там сектора имеют номера 1, 2, 3, 4, 9. Почему 9, а не 5? Отформати- ровав подобным образом дискету, у меня больше не стало подобных проблем. Я написал следующий загрузчик: 140. DOSLOAD PUSH BC PUSH DE PUSH HL LD A,E CP 4 JR NZ,DOSLD1 LD E,8 DOSLD1 LD B,1 CALL #3D13 POP HL INC H INC H INC H INC H POP DE INC E LD A,E CP 5 JR NZ,DOSLD2 INC D LD E,0 DOSLD2 POP BC DJNZ DOSLOAD LD (#5CF4),DE RET 2 Перед вызовом: HL = адрес загрузки, B = кол-во секторов (по 1024 байта), C = 5 - чтение, 6 - запись, D = дорожка, E = сектор (от 0 до 4). Но загрузка шла очень медленно, и я располо- жил сектора на дорожке в следую- щем порядке: 1, 4, 2, 9, 3, и скорость увеличилась в 2 раза. Может быть, эта информация ко- му-нибудь пригодится, и кто-ни- будь сможет обьяснить, почему нужно использовать девятый сек- тор, а не пятый. Прим ред.: Странная история. Девятый сектор, или пятый, да хоть 130-ый, все должно работать. Возможно, у Дмитрия не- достаток в форматирующей программе. Дмит- рий, попробуйте отформатировать диск так, как вы хотели той же программой, а затем посмотрите его при помощи функции Analyse Track программ ADS или RDS. Скорее всего, вы найдете ответ на свой вопрос. Теперь о том, почему в IS-DOS использован девятый сектор. Это необходимо для осуществления автозагрузки системы. Принцип такой. Пе- ред любой операцией с диском TR-DOS загру- жает девятый сектор нулевой дорожки в спе- циально выделяемый для этого буфер по ад- ресу #5D25. Буфер имеет длину 257 байтов. Почему не 256 - сказать могут только соз- датели TR-DOS. За этим буфером будет ле- жать область описателей каналов. TR-DOS не может прочитать часть сектора, она грузит его целиком, какой бы длины он ни был. В результате сектор длиной больше, чем 256 байтов, затирает собой описатели каналов. Но TR-DOS об этом не знает и пытается идентифицировать диск. Первым делом она проверяет в этом секторе байт со смещением 231, и если он не равен 16, то происходит немедленное прерывание операции с выдачей сообщения Disc Error. Выдача сообщения идет через канал K. Вот тут-то и срабаты- вает механизм автозагрузки. Достаточно в ячейки со смещением #0101 и #0102 записать адрес вашего загрузчика, который разме- щается в том же секторе. Загрузчик запус- тится, а там уж делайте, что хотите. * * *
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября