Этюды. © Alone Coder 1.Обмен содержимого двух областей памяти. Процедурка меняет местами два куска па- мяти,расположенные по круглым адресам. Па- раметры: HL=addr1, D='addr2, B='size. EXCH LD E,L LD C,(HL) LD A,(DE) LD (HL),A LD A,C LD (DE),A INC L JR NZ,EXCH INC H INC D DJNZ EXCH RET 2.Копирование между страничками. Очень удобная процедурка для сохранения STS (или Real Commander) в другой странич- ке, если ваша программа портит page 7. Параметры: HL=addr, D=page from, E=page to. Копируется всё вплоть до адреса #ffff. COPPG LD BC,32765 COPpg OUT (C),D LD A,(HL) OUT (C),E LD (HL),A INC L JR NZ,COPpg INC H JR NZ,COPpg RET Если скорость не важна, можно заменить окончание цикла на ... INC HL INC H DEC H JR NZ,COPpg RET Чтобы ограничить копируемый фрагмент, можно использовать цикл по LX: ... INC L JR NZ,COPpg INC H DEC LX JR NZ,COPpg RET Можно короче,но медленнее: ... INC HL LD A,H CP ... JR NZ,COPpg RET 3.Чтение с диска в виртуальное адресное пространство. Во многих системных программах может использоваться виртуальное адресное прост- ранство, обычно занимающее 4 странички и адресующееся через подпрограммы чтения и записи байта,параметром которых служит ви- ртуальный адрес от 0 до #ffff. Допустим,у нас есть процедурка нахожде- ния номера следующей странички этого адре- сного пространства по номеру предшествую- щей. Пускай она называется "NXTPAG". Пусть также номер первой используемой странички равен 16. Попробуем написать загрузку фай- ла длиной до #ff секторов от начала этой области (или по крайней мере с "круглого" адреса в ней): [Программа NXTPAG.H] LD A,16 EX AF,AF' ;A'=FIRST PAGE (порядок страниц 0,3,6,1!) LD HL,#C000 ;HL=ADDRESS (должен делиться на 256) LD DE,#100 ;DE=TRACK & SECTOR LD B,100 ;B=sectors LD C,5 LDNXPAG PUSH BC EX AF,AF' PUSH AF CALL OUTME LD A,B ADD A,H LD A,B JR NC,$+5 XOR A SUB H LD B,A LD (LDNXPGA+1),A CALL #3D13 ;TR-DOS LD HL,#C000 POP AF CALL NXTPAG ;NEXT PAGE CALCULATED POP BC LD DE,(23796) ;NEXT TRACK & SECTOR EX AF,AF' LD A,B LDNXPGA SUB 64 LD B,A JR NZ,LDNXPAG RET ;ЖЕЛАТЕЛЬНО ВСЕ ОБРАЩЕНИЯ К ВЕРХНЕЙ ПАМЯТИ ;ПРОИЗВОДИТЬ ЧЕРЕЗ ЭТУ ПРОЦЕДУРКУ: OUTME PUSH BC LD BC,32765 ; LD (PG),A ;(если IM 2) OUT (C),A POP BC RET ;CALCULATE NEXT PAGE: NXTPAG ADD A,3 AND 23 RET В данном случае процедура записи той же области памяти на диск полностью эквивале- нтна, меняется только регистр C. Если нужно грузить не с начала памяти,а с другого адреса (обязательно круглого!), то достаточно вставить в начало вышеприве- дённой процедурки вычисление странички и адреса в ОЗУ, соответствующего заданному виртуальному. 4.Чтение-запись в виртуальное адресное пространство с точностью до байта. Сложности начинаются тогда,когда требу- ется грузить блок по виртуальному адресу с точностью до байта. Для этого придётся ос- вободить область памяти #bf00-#bfff (это потребуется для загрузки дробных секторов: всех,пересекающих страничку,и последнего). Алгоритмы Load и Save теперь сильно отли- чаются. Более того,они такие сложные,что я до сих пор не уверен, что в программе нет глюков ;(. Смотри сорс LOADSAVE.H... Он вытащен из пока не дописанного "Программатора" by Tot & я, и там (внимание!) другая нумерация страничек.