Хотим мы этого, или не хотим, но самым хардверным артефактом в PMG является жесткая зависимость от GTIA. По факту - от устанавливаемого нами вертикального Разрешения PMG.
Для двойного разрешения, поток обработки задерживается на время одной линии сканирования и при тех же входных данных, GTIA прорисовывает строку дважды.
Все вертикальные координаты должны быть сокращены вдвое, иначе, изображения уйдут за экран. Также, изменяется структура памяти.
Из чего исходить?
Из жесткой связки - Вертикальное разрешение-Распределение памяти...
Именно поэтому, во всех руководствах нам рекомендуют:
1. Сначала, выделить область PMG для конкретного разрешения.
Вот код на PL65, который правильно устанавливает соотношения. Фактически, это - программа инициализации глобальных данных.
Код:
!- Globals ----------
BYTE pmRes,pmZone,plOffs,vPos
! Resolution may be Single=1 or Double=2 lines
PROC pmSetMem(pmRes)
BEGIN
IF pmRes=1 THEN
pmZone=RAMTOP-16
plOffs=$0400
plAddr=pmZone*$0100+plOffs
ELSE
pmZone=RAMTOP-8
plOffs=$0200
plAddr=pmZone*$0100+plOffs
vPos=vPos/2
ENDIF
END
2. Затем, установить требуемые режимы DMA
Стандартные установки реализуют DMA-чтение DL и PF, в режиме Нормальной ширины экрана.
Фактически, нам нужно задать Разрешение PMG и к стандартным установкам (SDMCTL=34) добавить чтение Игроков, Ракет, или обоих.
Порядок инициализации - несущественен, так как оверлей прорисовывается не средствами ANTIC, а средствами GTIA. Я это - к тому, что пока не включена трансляция GTIA, на экран ничего не выводится.
Для отрисовки курсора нам нужен один Игрок P0.
Осталось инициализировать DMA-чтение Игроков с заданным разрешением (SDMCTL=58) и, затем, дополнительные параметры отображения. (цвета, ширину и пр.).
Код:
PROC pmSetDma()
CONST mask=%00011000 ! (SGL=16)+(PLDMA=8)
BEGIN SDMCTL=SDMCTL+mask END
Вот рабочий код Демки на PL65:
Код:
!====================================!
! PMGR.PRG !
!------------------------------------!
! Evgeny Zolotarev,(aka 576XE), 2018 !
!====================================!
!= Global Data ======================!
!====================================!
!- Equates --------------------------!
BYTE RAMTOP=$6A,COLPF2=$02C6
BYTE PMBASE=$D407,SDMCTL=$022F,GRACTL=$D01D
BYTE HPOSP0=$D000,SIZEP0=$D008,PCOLR0=$02C0
!- Player Bitmap --------------------!
BYTE PLAYER[8]
DATA
%10000000,
%01100000,
%01111000,
%00111110,
%00111100,
%00011100,
%00010010,
%00000001;
!- Program Variables ---------------!
BYTE pmZone,hPos,vPos
INT p0offs,p0addr
!= Procedures & Functions ===========!
!====================================!
!- Main Procedure -------------------!
MAIN()
BEGIN
GRACTL=0 ! На всякий случай...
hPos=126 HPOSP0=hPos
PCOLR0=52 COLPF2=128 SIZEP0=0
pmZone=RAMTOP-16 p0offs=1024
p0addr=pmZone*256+p0offs
FILL(p0addr,256,0) ! Очистка p0zone
vPos=128 MOVE(.PLAYER,8,p0addr+vPos) ! Прорисовка в нужном месте
PMBASE=pmZone ! Доложили ANTICу
SDMCTL=58 ! Добавили plDma+SLR
GRACTL=2 ! Транслируем Игроков без Ракет
END
!====================================!
!------- >>> End Of File <<< --------!
Вскоре напишем на Ассемблере
zen