Этюды.
© 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
& я, и там (внимание!) другая нумерация
страничек.
Сайт управляется системой
uCoz