ZX-Ревю 1996 №1-2 1996 г.

Авторская разработка - простой транслирующий драйвер видеопроцессора.


АВТОРСКАЯ РАЗРАБОТКА

© С. Веремеенко, г. Екатеринбург.

ПРОСТОЙ ТРАНСЛИРУЮЩИЙ ДРАЙВЕР ВИДЕОПРОЦЕССОРА.

Вашему вниманию предлагался простой драйвер видеопроцессора, описание которого приведено в ZX РЕВЮ 1995/6. Основная цель этой статьи - познакомить читателей с методикой создания драйверов и на конкретном примере показать некоторые приёмы программирования на Ассемблере 6502. Поэтому программа написана нарочито "дубово", время для изысков пока не пришло.

Практически этот драйвер может использоваться для встраивания в прикладные программы, написанные на Ассемблере, не требующие анализа коллизии спрайтов. С применением этого драйвера написана программа "VIDEOART", представляющая собой редактор пейзажей. Драйвер DRIVT имеет и некоторые другие ограничения. Не поддерживаются многофазные спрайты, нет абсолютной адресации экранов, не реализована очередь команд, нет команд блочного ввода информации и т.д.

Однако он обладает неоспоримым достоинством, которое в данном случае явилось решающим. Его минимальный объём позволяет опубликовать листинг с подробными комментариями.

Для тех, кто по какой либо причине не сможет его ассемблировать, приведён шестнадцатеричный дамп.

Драйвер DRIVT имеет всего 15 команд. 14 из них двухбайтные и в особых комментариях не нуждаются. Они вызываются из ассемблера последовательностью команд:

LD A,COM ; команда (#00-#0D)

OUT (#7F) , A

LD A,ARG ; аргумент

OUT (#7F) , A

Эту последовательность удобно оформить в виде макроса COMV MAC

LD А,=0

OUT (#7F) , A

LD A, =1

OUT (#7F) , A

ENDM

Команда

LD A,#FF

OUT (#7F) , A

является однобайтной и называется "выполнение спрайта". Дело в том, что все команды меняющие координаты спрайта на экране или его атрибуты, запоминаются видеопроцессором, но не выполняются, пока не подана эта команда. Если бы команды управления спрайтами выполнялись сразу, то возникал бы эффект "дробления" спрайта, состоящего из нескольких элементов, при его движении. Такой подход не является оптимальным, но он позволяет простым способом достичь достаточно качественного управления спрайтами.

Особой является команда DREG1 (код #01). Как известно, при записи в регистр 2001h кода #00 появляется возможность ускорить процесс записи информации в видеоОЗУ в несколько сотен раз, но экран при этом гаснет. В DRIVT эта возможность реализована. Вы можете, не гася экран (команда DREG1, #1E), вводить информацию со скоростью 400 Бод, или, погасив его (команда DREGl, #00), увеличить эту скорость до 80-200 тысяч Бод. Поскольку процесс ввода синхронизирован сигналом WAIT, никаких искусственных задержек в программу вводить не нужно. Видеопроцессор сам примет ровно столько информации, сколько способен в текущем режима

Достоинство обоих режимов можно совместить, если реализовать очередь команд, но для такого простого драйвера это нецелесообразно.

001е******************************************************** 0 02;* * 003;* (С) С. Веремеенко *

004;* Драйвер видеопроцессора DRIVT *

005;* *

006е********************************************************

007

008

REG0

EQU

00h

; копия регистра 2000h

009

REG1

EQU

01h

; копия регистра 2001h

010

RG5L

EQU

02h

; горизонтальный скроллинг

011

RG5H

EQU

03h

; вертикальный скроллинг

012

RG6L

EQU

04h

; текущий адрес VRAL, мл. байт

013

RG6H

EQU

05h

; текущий адрес VRAM, ст. байт

014

COM

EQU

0 6h

; буфер команды

015

DATA

EQU

07h

; буфер данных

016

NUMSP

EQU

0 8h

; номер элемента спрайта

017

REG11

EQU

0 9h

; временная копия REG1

018

FCOM

EQU

10h

; семафор команды

019

FUSE

EQU

11h

; семафор исполнения

020

FWRV

EQU

12h

; семафор записи

021

ADRL

EQU

2 0h

; адрес записи VRAM, L-байт

022

ADRH

EQU

21h

; адрес записи VRAM, Н-байт

023

024

025

026

ORG

0F800h

027

028

BEGIN

SEI

; запрет маскируемых прерываний

029

CLD

; двоичный режим

030

LDA

; #00h

031

STA

6000h

; снятие WAIT ZX-SPECTRUM

032

STA

2 0 0 0h

; запрет немаскируемых прерываний

033

STA

2 0 01h

; гашение экрана

034

L0

LDA

2 0 02h

; пауза 2 0 mS для установки

035

BPL

L0

; начального состояния

036

L1

LDA

2 0 02h

; видеопроцессора, эмуляция

037

BMI

LI

; сигнала "RESET"

038

039

LDA

#3Fh

040

STA,

2 0 0 6h

041

LDA

#0F0h

042

STA

2006H

; адрес ВидеоОЗУ 03FF0h

043

LDA

#0Dh

044

STA

2007h

; чёрный фон

045

046

LDX

#0FFh

047

TXS

; указатель стека 01FFh

048

049

LDA

#2 0h

050

STA

2 0 0 6h

051

LDA

#00h

; 2 000h - адрес

052

STA

2006

; нулевого экрана

L4

Все экраны очищены

2006h 2006h

TYA

L2 STA 0,Y

I NY BNE L2

; Нулевая страница ОЗУ (0000h-00FFh) обнулена

L3

0200h,Y ; запись 00h по адресу 0200h+Y

STA I NY

BNE L3

; Вторая страница ОЗУ (0200h-02FFh), в которой размещён ; буфер спрайтов, обнулена

LDA #8 0h ; разрешение немаскируемых

STA 2 000h ; прерываний

LOOP CLI ; разрешение маскируемых

JMP LOOP ; прерываний и "теневая"

; задача - пустой цикл. Приём команды идёт по маскируемому ; прерыванию, выполнение в необходимых случаях ; по немаскируемому.

053

054

055

056

057

058

059

060 061 062

063

064

065

066

067

068

069

070

071

072

073

074

075

076

077

078

079

080 081 082

083

084

085

086

087

088

089

090

#10h #00h #00h 2007h

L4

L4

16 страниц по 256 байт

это объём 4 экранов

заполняющий байт

запись 00h в видеоОЗУ

инкремент младшего байта счётчика

LDX LDY LDA STA I NY BNE DEX BNE

; декремент счетчика страниц заполнены 0 0h

; X и Y равны нулю, поэтому ; адрес видеоОЗУ - 0000h

STY STY

; А=Y=0 0h

; запись 0 0h по адресу 0 0h+Y ; инкремент указателя

команда 0FFh - выполнение спрайта,

091

USSPT LDA

#0FFh

; семафор FUSE устанавливаем

092

STA

FUSE

; в 0FFh

093

LDA

REG0

; текущее значение per. 2 000h

094

ORA

#8 0h

; 7 бит устанавливаем в 1

095

STA

2 0 0 0h

; временно разрешаем

096

; немаскируемые прерывания, если они были запрещены.

097

USS LDA

FUSE

; ожидаем пока семафор не

098

BNE

USS

; будет сброшен в процедуре

099

; немаскируемого прерывания,

100

LDA

REG0

; восстановление режима

101

STA

2 0 0 0h

; регистра 2000h

102

STA

6000h

; сброс WAIT ZX-SPEGTRUM

103

RTI

; возврат в цикл LOOP

104

FCOM ARGL 6000h USSPT #0Fh

СОМ #FFh FCOM 6000h - приём команды от ZX-SPECTRUM семафор команды. Если он не равен 00h - аргумент команда от ZX-SPECTRUM если D7=1, то исполнение ограничение количества команд до 16 сохранение команды ожидаем аргумент

105

106

107

108

109

110 111 112

113

114

115

116

117

118

119

120 121 122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

Маскируемое прерывание

INTER

LDX BNE LDA BMI AND

STA LDA STA STA RTI

Её код в ячейке СОМ ARGL LDA #00h ; восстановление семафора

FCOM ; команды

СОМ ; код команды в аккумуляторе

А ; удваиваем его

; и заносим в Y TABL,Y ; младший байт адреса из TABL JM+1 ; модификация адреса в

; команде перехода. Некрасиво ; но экономно. TABL+1,Y ; старший байт адреса из TABL JM+2 ;еще одна модификация

60 0 0h ; аргумент в аккумуляторе

; дублируем его в X JM JMP 0 ; адрес перехода берется из

;TABL и заносится в аргумент ; команды JMP до того как она выполнится.

Аргумент команды.

LDA STA LDA ASL TAY LDA STA

LDA STA LDA TAX JMP

сброс WAIT

возврат из прерывания

14 0 TABL

DEFW

DREGO

; 00h,

установка регистра 2000h

141

DEFW

DREG1

; 01h,

установка регистра 2001h

142

DEFW

DRGX

; 02h,

горизонтальный скроллинг

143

DEFW

DRGY

; 03h,

вертикальный

скроллинг

144

DEFW

DRG6L

; 04h,

младший байт

регистра 2006h

145

DEFW

DRG6H

; 05h,

старший байт

регистра 2006h

146

DEFW

ADRLV

; 0 6h,

младший байт

адреса видео

147

DEFW

ADRHV

; 07h,

старший байт

адреса видео

148

DEFW

DATAV

; 08h,

данные видео

149

DEFW

XSPRT

; 0 9h,

Х-координата

блока спрайта

150

DEFW

YSPRT

; 0Ah,

Y-координата

блока спрайта

151

DEFW

ZSPRT

; 0Bh,

код блока спрайта

152

DEFW

ASPRT

; 0Ch,

атрибут блока

спрайта

153

DEFW

NSPRT

; 0Dh,

номер элемента спрайта

154

DEFW

REZ

; 0Eh,

резерв

155

DEFW

REZ

; 0Fh,

резерв

156

157

REZ

STA

6000h

;

сброс WAIT без выполнения

158

RTI

;

команды

159

160

DREGO

STA

REGO

;

копия 2 000h

161

STA

2 0 0 0h

;

непосредственное выполнение

162

STA

6000h

163

RTI

164

165

DREG1

STA

REG1

аргумент в REG1

166

LDRG

CMP

REG11

ждем, пока REG 1 и REG11

167

BNE

LDRG

не сравняются

168

CMP

#00h

если регистр 2001h

169

BEQ

DR11

установлен в 00h, то ...

170

LDA

REGO

иначе восстановление

171

STA

2 0 0 0h

;

регистра 2000h

172

STA

6000h

173

RTI

174

175

DR11

LDA

#00h

;

... запрет немаскируемого

176

STA

2 0 0 0h

;

прерывания

177

STA

6000h

178

RTI

179

180

DRGX

STA

RG5L

;

загрузка регистра горизонтального

181

STA

6000h

;

скроллинга. Исполнение в

182

RTI

;

немаскируемом прерывании

183

184

DRGY

STA

RG5H

;

вертикальный скроллинг организован

185

STA

6000h

;

аналогично горизонтальному

186

RTI

187

188

DRG6L

STA

RG6L

;

установка текущего состояния

189

STA

6000h

;

регистра 2006h

190

RTI

;

младший байт

191

192

DRG6H

STA

RG6H

;

то же, старший байт

193

STA

6000h

194

RTI

195

196

ADRHV

STA

ADRH

;

адрес видеоОЗУ

197

STA

6000h

;

старший байт

198

RTI

199

200

ADRLV

STA

ADRL

;

адрес видеоОЗУ

201

STA

6000h

;

младший байт

202

RTI

203

204

DATAV

LDA

REG1

;

если регистр 2001h установлен

205

BEQ

PTV1

;

в 00h, непосредственное выполнение

206

LDA

REG0

;

иначе временное разрешение

207

ORA

#8 0h

;

немаскируемых прерываний

208

STA

2 0 0 0h

209

STX

DATA

загружаемые данные

210

LDA

0FFh

установка семафора

211

STA

FWRV

212

DTV

LDA

FWRV

ожидание сброса семафора

213

BNE

DTV

214

LDA

REGO

восстановление

215

STA

2 0 0 0h

регистра 2000h

216

STA

6000h

217

RTI

218

219

DTV1

LDA

ADRH

установка адреса

220

STA

2 00 6b

видеоОЗУ

221

LDA

ADRL

222

STA

2 0 0 6h

223

STX

2007h

загрузка данных

224

LDA

RG6H

постановление текущего

225

STA

2 0 0 6h

адреса видеоОЗУ

226

LDA

RG6L

227

STA

2 0 0 6h

228

STA

6000h

229

RTI

230

231

232

*

команды

управления

спрайтами *

233

234

235

NSPRT

AND

#3Fh

ограничение номера спрайта

236

STA

NUMSP

от 0 до 63

237

STA

6000h

238

RTI

239

240

XSPRT

LDA

NUMSP

номер спрайта

241

ASL

A

умножаем

242

ASL

A

на четыре

243

TAY

и загружаем в Y

244

TXA

аргумент в аккумуляторе

245

STA

02 03h,Y

загружаем его в 0203h+Y

246

STA

6000h

247

RTI

248

249

YSPRT

LDA

NUMSP

аналогично XSPRT

250

ASL

A

251

ASL

A

252

TAY

253

TXA

254

STA

02 0 0h,Y

255

STA

6000h

256

RTI

257

258

ZSPRT

LDA

NUMSP

аналогично XSPRT

259

ASL

A

260

ASL

A

261

TAY

262

TXA

263

STA

02 01h,Y

264

STA

6000h

265

RTI

266

267

ASPRT

LDA

NUMSP ; аналогично XSPRT

268

ASL

A

269

ASL

A

270

TAY

271

TXA

272

STA

02 02h,Y

273

STA

6000h

274

RTI

275

276

;

**

277

*

;

немаскируемое прерывание, выполнение команды

*

278

;

**

279

280

NINT

SEI

; запрет маскируемого, прерывания

281

PHA

; аккумулятор в стек

282

TXA

283

PHA

; X в стек

284

TYA

285

PHA

; Y в стек

286

287

LDA

FWRV ; проверка семафора FWRV

288

BNE

WRVID ; запись в видеоОЗУ

289

LDA

FUSE ; проверка семафора FUSE

290

BEQ

EXIN ; если нет, то конец

291

292

LDA

#00h ; установка параметров

293

STA

2 0 03h ; контроллер ПДП

294

LDA

#02h ; и его

295

STA

4 014h ; запуск

296

LDA

#60h ; сброс семафора

297

STA

FUSE

298

JMP

EXIN ; и выход

299

300

WRVID

LDA

ADRH ; установка адреса записи

301

STA

2 0 0 6h ; в видеоОЗУ

302

LDA

ADRL

303

STA

2 0 0 6h

304

LDA

DATA ; запись в видеоОЗУ

305

STA

2007h

306

LDA

#0 0h ; сброс семафора FWRV

307

STA

FWRV

308

309

EXIN

LDA

RG5H ; выполнение скроллинга

310

STA

2005h

311

LDA

RG5L

312

STA

2005h

313

LDA

RG6H

; восстановление текущего

314

STA

2 0 0 6h

; адреса видеоОЗУ

315

LDA

RG6L

316

STA

2 0 0 6h

317

LDA

REG1

; копирование REG1

318

STA

REG11

; в REG11

319

STA

200 1h

; и запись в регистр 2001h

320

PLA

321

TYA

; Y из стека

322

PLA

323

TXA

; X из стека

324

PLA

; аккумулятор из стека

325

CLI

; разрешение маскируемого прерывания

326

RTI

; выход из процедуры

327

328

DEFS

0FFFAh-$

32 9 ; эта команда обеспечивает правильную установку системных

33 0 ; векторов при произвольном (в разумных пределах) ORG

331

332 NMI DEFW NINT

333 START DEFW BEGIN

334 IRQ DEFW INTER

Исправьте неточности!

В схеме видеопроцессора (ZX РЕВЮ 95/6, стр. 7).

1. Ламели разъема X1.1 и XL2 должны быть пронумерованы сверху вниз от 1 до 30.

2. У дешифраторов 1533ИД4 номера выводов 1 и 2 нужно поменять местами. Знак инверсии стоит правильно.

3. В разрыв шины 82 (идет от D6 к D2) нужно поставить инвертор.

4. Выводы 2 и 4 микросхемы D5 надо соединить с "землей" через конденсаторы n16. _5. На шину питания поставить блокировочные конденсаторы 47М и 4 шт. 68n._




СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Проходилка - обещаный разбор игры PIJAMARAMA (MICRO-GEN'87).
ХАЛЯВE-БОЙ! - TАХ-О-PНОNE.
Огни саламандры - Работа над игрой идет полным ходом...
РЕМОНТ - Продолжаем ремонтировать Пентагоны...
Реклама - Реклама и объявления ...

В этот день...   21 ноября