┌────────────────────────────────────────┐
│ Fast Memory Access (FMA). │
└────────────────────────────────────────┘
(c)VTS'99
Fast, а не Direct Memory Access - т.к.
работу с памятью осуществляет по-прежнему
старый добрый Z80.
Сей метод предлагается к использованию
в периферийных (равно как и любых других)
устройствах на Z80 для увеличения их про-
изводительности при работе с массивами па-
мяти (графика, например).
Итак, можно кидать память-память со
скоростью 10.5 тактов/ байт. Кхе-хе, уже
вижу ухмылки кодящей братии ;). Угу, енто
опять любимый стек. Правда, нормальный DMA
качает байт за 8 тактов (по крайней мере
8237, по Zilog информацией не располагаю),
но зато он бооольшой и прожорливый ;).
Правда, он еще умеет выкачивать и закачи-
вать данные извне, и немножко пошустрее. В
нашем случае можно где-то в памяти Z80
"прогрызть" дырку и подставить туда ре-
гистры этого самого "извне", и не оби-
жаться за скорость, близкую к IN/OUT (хотя
в турбе будет получше, т.к. IN/OUT работа-
ют в норме - я имею ввиду KAY).
Ну а теперь поконкретней.
Я думаю, общеизвестно, что за один
фрейм спектрумовский экран кидают так:
LD HL,XXXX ;10 тактов
PUSH HL ;11 тактов
LD HL,YYYY ---------
PUSH HL 21т./2байта
LD HL,ZZZZ (10.5т./байт)
PUSH HL ---------
.... 21*3072=64512т.
всего 3072 раза
XXXX, YYYY, ZZZZ - это экран.
Как видно, экранная информация через
каждые два байта прорежена другими двумя
байтами:
..E5 21 XX XX E5 21 YY YY E5 21 ZZ ZZ...
│ │
LD HL,XXXX PUSH HL
Чтобы подготовить такую кашу в обычной
памяти, нужно трудиться дольше одного
фрейма, посему требуется основательный
декрюнчинг и прорва памяти.
Но есть способ лучше! ( (с)реклама ) И
он требует железячного вмешательства. Зак-
лючается он в перепутывании разрядов адре-
са, к примеру, A14 и А1, можно еще и по
условию A15=1. Тогда получаем следующее:
┌─────────┐0000 ┌─────────┐0000
16k│сегмент 0│ 16k│сегмент 0│
├─────────┤4000 ├─────────┤4000
16k│сегмент 1│ 16k│сегмент 1│
├─────────┤8000 ╔═════════╗8000
16k│сегмент 2│ ║══ FMA ══╣
├─────────┤C000 32k╠═════════╣
16k│сегмент 3│ ╠══ AREA ═╣
└─────────┘FFFF ╚═════════╝FFFF
Т.е. 2'ой и 3'ий сегменты наложились
друг на друга через каждые два байта. И
если теперь во 2'ой сегмент записать под-
ряд кучу (16кб) E5 21 (а по адресу #BFFD
занести C9 - RET) и сделать call на #8001,
то на стек выгрузиться 16382 байта :-).
Остается только странички верхней памяти
щелкать...
Ну и под конец сосчитаем, насколько же
нас все-таки обходит 8237:
K(8237) = (10.5-8)*100/10.5 = 23.8%
Не так уж и много...
p.s.: Здесь описан только принцип, т.к.
применить его к центральному Z80 несколько
проблематично (и дело вовсе не в желе-
зе...). Т.е. это для ПЕРИФЕРИИ !!!
isdos 23-04-99 22:47msk