AOH :: PALTIMNG.TXT
PAL Timings
|
The memory accesses of the MOS 6569 VIC-II and MOS 8566 VIC-IIe
Video Interface Controller
Marko MM-dkelM-d
3rd June, 1994
This document is based on my screen size measurements in Sweden at
Peter Andersson's place, on Pasi Ojala's inaccurate timing diagrams in
his article "Missing cycles" in the C=Hacking net magazine, Volume 1,
Issue 3, and from the output data of Andreas Boose's program, which
determines which addresses are being read by the video chip by reading
non-connected address space, i.e. some byte in the area $DE00--$DFFF
when the I/O is switched on. When reading such addresses, the data
bus will reflect the data read by the video chip on the previous Phi-1
cycle. This fact was discovered by me when I visited Andreas in late
March 1994. Alas, this does not work reliably on all Commodore 64's
or 128's. Some data bits will stay on the logical '1' or '0' level
when reading from $DE00--$DFFF on some units. One C64 succeeded to
execute a program in $DE00--$DE7F several seconds, but jammed as I
turned the disk drive off. These tricks require very good RF
protection in the computer.
If you are interested in this topic, read the C=Hacking article if
you haven't read it by now. Although the article is inaccurate and
contains some errors, it tells you the idea of the video timing and
gives a rough picture of what is going on in the computer.
If you have anything to add or correct, please exchange your ideas
with Andreas Boose <Boose@Unixserv.RZ.FH-Hannover.DE>, as I don't have
direct access to Internet until August 1994. You can write to me at the
address <Marko.Makela@FTP.FUNET.FI>, but I can only reply after a delay
of one month or so, and I probably won't be able to measure or verify
anything.
These results have been measured on two Commodore 64's, on a
Commodore 128D (flat C128 board in plastic case, floppy controller
on separate board) and on a 128DCR (128D in metal housing with only
one board inside). I don't know the revision numbers of the 8566 chips
in the C128's, but the video chips measured on the C64's include a
ceramic 6569R1, a ceramic 6569R3 and a plastic 6569R3. These results
were equal on all chips, but the whole timing is not. There are some
differences at least in the sprite timing on the 6569R1.
Bad scan line, no sprites:
1 2 3 4 5 6
123456789012345678901234567890123456789012345678901234567890123
[ { } ]
3-4-5-6-7-rrrrrgggggggggggggggggggggggggggggggggggggggg--0-1-2- Phi-1 6569R3
cccccccccccccccccccccccccccccccccccccccc Phi-2 6569R3
xxxxxxxxxxxXXX========================================xxxxxxxxx Phi-2 6510
Normal scan line, no sprites:
1 2 3 4 5 6
123456789012345678901234567890123456789012345678901234567890123
[ { } ]
3-4-5-6-7-rrrrrgggggggggggggggggggggggggggggggggggggggg--0-1-2- Phi-1 6569R3
Phi-2 6569R3
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Phi-2 6510
Overscan raster line (vertical border) or blanked screen, no sprites:
1 2 3 4 5 6
123456789012345678901234567890123456789012345678901234567890123
[ { } ]
3-4-5-6-7-rrrrr++++++++++++++++++++++++++++++++++++++++--0-1-2- Phi-1 6569R3
Phi-2 6569R3
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Phi-2 6510
Bad scan line, at least the sprites 3--7 active on the current scan
line and the sprites 0--2 on the following scan line:
1 2 3 4 5 6
123456789012345678901234567890123456789012345678901234567890123
[ { } ]
3s4s5s6s7srrrrrgggggggggggggggggggggggggggggggggggggggg--0s1s2s Phi-1 6569R3
ssssssssss cccccccccccccccccccccccccccccccccccccccc ssssss Phi-2 6569R3
==========xXXX========================================***====== Phi-2 6510
Normal scan line, no sprites on the current scan line but at least the
sprites 1 and 2 active on the following scan line:
1 2 3 4 5 6
123456789012345678901234567890123456789012345678901234567890123
[ { } ]
3-4-5-6-7-rrrrrgggggggggggggggggggggggggggggggggggggggg--0-1s2s Phi-1 6569R3
ssss Phi-2 6569R3
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxXXX==== Phi-2 6510
Two successive overscan raster lines (vertical border),
sprites 1, 3 and 7 active on the latter:
1 2 3 4 5 6
123456789012345678901234567890123456789012345678901234567890123
[ { } ]
3-4-5-6-7-rrrrr++++++++++++++++++++++++++++++++++++++++--0-1s2- Phi-1 6569R3
ss Phi-2 6569R3
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxXXX==** Phi-2 6510
3s4-5-6-7srrrrr++++++++++++++++++++++++++++++++++++++++--0-1-2- Phi-1 6569R3
ss ss Phi-2 6569R3
==xxxXXX==xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Phi-2 6510
Note: The left edge of the diagrams is the start of the raster line,
as indicated by the Raster Counter register ($D012/$D011).
Legend: [ left edge of the overscan screen (sprite co-ordinate $1E0 at
the beginning of this cycle)
{ left edge of the text screen (at the beginning of this cycle)
} right edge of the text screen (at the end of this cycle)
] right edge of the overscan screen (a bit after the end of this cycle)
- idle bus cycle (reads from the last byte of the video bank,
e.g. (video bank base address) + $3FFF)
+ idle bus cycle (just like '-', but reads from
(video bank base address) + $39FF if ECM ($D011 bit 6) is selected)
0 pointer fetch for sprite 0
1 pointer fetch for sprite 1
2 pointer fetch for sprite 2
3 pointer fetch for sprite 3
4 pointer fetch for sprite 4
5 pointer fetch for sprite 5
6 pointer fetch for sprite 6
7 pointer fetch for sprite 7
r memory refresh cycle
g graphics fetch
c character pointer and/or color data fetch
x processor executes instructions (BA high, AEC high)
X bus request pending, bus still available (BA low, AEC high);
processor may execute write cycles, stops on the next read cycle.
* bus request pending, bus still available (BA low, AEC high);
processor is blocked because it would like to read something.
= bus unavailable (BA low, AEC low);
processor is blocked because it would like to read something.
If you have played with your monitor's picture size controls, which
are hidden under the cover in most units, you know that the full
overscan screen is far bigger than 320x200 points. At the very left
edge (horizontal sprite co-ordinate $1D8), there is an
eight-pixels-wide vertical bar of color 8 (dark brown). It is
neighbored by a white two-pixels-wide bar, which covers the horizontal
co-ordinates $1E0 and $1E1.
The area between the horizontal co-ordinates $1E2 and $17C,
inclusive, can be controlled by programming means (usually by changing
the border color, or by removing the borders and putting sprites to
the overscan area). On all revisions of the 6569, the raster lines
range from $0 to $137, inclusive. The lines $10 to $12B are visible.
The default text screen resides in the horizontal co-ordinate range
$18--$157 and the raster line range $33--$F9, inclusive.
So, the full overscan area is 411 * 284 points big. In my notes I
have written that the horizontal resolution would be 411.5 points.
Maybe the rightmost point was half of the normal width, or I counted
the border color. You know, the colors change eight and a half pixels
after the beginning of the write cycle to a VIC-II register. Newer
video chips, whose type number is something else than 6569 or 6567,
draw a randomly colored, mostly light gray point whenever you change a
color while it is being used for drawing something. You can note this
with a loop like FORA=1TO1E37:POKE53281,0:NEXT. If you see flickering
points on the screen, you have a flaky video chip. Such chips are used
on the Commodore 128 and on the newest generation of the Commodore 64.
Note that the vertical sprite co-ordinates always are one smaller
than the raster lines. This is because the video chip fetches the
sprite data for the next scan line right after displaying the
characters or graphics for the current line, and the raster line does
not change until the data for the fourth sprite is being fetched.
The character pointers will be fetched one cycle before the image
data of the first scan line of a text line, or "bad line". This is
natural, since otherwise the video chip would not know where to fetch
the images. Similarly, the image data will be fetched one cycle
before it gets displayed, as the graphics cannot be drawn while
waiting for the data to come from the memory chips.
The sprites are buffered, too. If you place the sprite 0 to the
very right border of the overscan area, its right edge gets distorted.
No wonder, since the video chip is fetching the graphics data for the
sprite 0 at the very right edge of the screen.
Note that the sprite data will be fetched even outside the overscan
screen, also while the electron gun is returning from the bottom of
the screen to the top, if the horizontal sprite co-ordinate matches
with the lowmost eight bits of the Raster Counter register. Due to
this, if you use vertical sprite co-ordinates 0 to 55, inclusive, the
sprite data will be fetched twice per frame. If you open the vertical
borders and put a sprite to the very bottom of the screen, you will be
able to see it at the top border, too. In addition to that, if you
expand the sprite vertically, you will be able to see the top part of
the sprite at the bottom of the screen, the bottom part at the top of
the screen, and the whole sprite near the top of the screen.
If you open the vertical borders by switching to 24 line mode while
the video chip is drawing the 25th text line (and by switching back to
25 line mode after the video chip has passed the point where it would
turn the border on), you will be able to display sprites and also
other graphics in it. Just write a value to the last byte of the
video bank (by default $3FFF), and the video chip will put the data as
graphics on the screen. The graphics is always black, or so we have
been told. (If you find a way to change its color, please tell me
how.) If you fiddle with the $D011 register near the bottom border,
you might be able to use the colors of the last text row.
If you select Enhanced Color Mode (ECM) together with Bitmap Mode
(BMM), you will get a black screen as a result. The video chip will
read the data for a bitmap screen but AND the address with $B9FF. The
AND is because the Enhanced Color Mode. This mode lets you to use 64
different characters, while the two topmost character code bits are
used for background color selection. When loading the character
images, these two bits must be masked off, that's why the character
generator address gets ANDed by $B9FF. When the video chip is drawing
the border (or if the screen is disabled), the '+' cycles will be
fetched from $39FF also in this hybrid mode (ECM + BMM).
The Multicolor Mode (MCM) offers more illegal display modes. The
combination ECM + BMM + MCM produces the same results than ECM + BMM,
but ECM + MCM is something revolutionary, although it produces a black
screen, too. In this mode, the '+' cycles are just like in plain ECM,
but the graphics fetches are totally different. The text matrix data
does not count at all in this mode, although it should be a text mode!
The address bits A13--A11 are the character generator base address, as
always with text modes. The bits A10--A9 are 0, just like in the ECM
mode. The text matrix base address bits will show up at A8--A5, and
the bits A4--A3 seem to be always 0. The three lowmost address bits
will tell you which scan line of a character would be drawn if it was
a text mode. On a bad line, it should be 0 (this cannot be measured
without extra hardware), and on other lines it ranges from 1 to 7. It
seems that the CSG or MOS Technologies engineers designed this mode
for testing the video chip.
All these illegal display modes have bad lines, so there is no real
advantage of using them in a program except if you want to confuse
someone who tries to examine your $DE00 program. ($DE00 programs are
programs that run on the unconnected I/O area. The video chip will
fetch the program data for the processor, which makes it hard to do
branches and stuff like that.)
There are still two interesting modes left. The 8566 (PAL) and the
8564 (NTSC), the video chips designed for the Commodore 128, have a
'test' bit in the register $30, bit 1. When this bit is turned on,
the computer will output no valid video signal. I couldn't measure
this mode with Andreas Boose's program, as it disables any VIC-IIe
interrupts. There should also be a 'reset' bit (register $16, bit 5)
on some video chips, but I haven't encountered any function in this
bit so far. These modes should be analyzed thoroughly, as they can
reveal something.
Finally a word about the memory refresh. Dynamic memory arrays are
divided to rows and columns of memory cells. The memories need to be
periodically refreshed, and this will be accomplished by refreshing
each memory row periodically by reading its contents. As the eight
lowmost system address bus bits are connected to the row address of
the memory chips, and the eight highmost to the column address, the
video chip will need to vary the eight lowmost address bits while
refreshing the memory. The column address could be random, but it is
the last page of the current video bank. The row address is regular,
too. The first address to be refreshed on a given raster line is
(start address of video bank) OR $3F00 OR ($FF AND (-1-5*rasterline)),
and the refresh counter is decreasing. For instance, if using the default
video bank (starting at 0), the video chip will read from $3FF1, $3FF0,
$3FEF, $3FEE and $3FED on the raster lines $36 and $136.
Notes:
On the NTSC systems, there must be far more differences between the
MOS 6567 chip revisions. I have tested a 6567R8, which was dated in
late 1984. Note the high revision number; the newest 6569 I have seen
is R5. Unlike the latter 6567's, my chip had 64 cycles per raster
line and 262 lines. Usually the 6567's have 65 cycles per line and
263 lines, which makes the frame rate nearer the specification, 60
Hz. The system clock runs at 14318181/14 Hz on NTSC and 17734472/18 Hz
on PAL systems, and the dot clock is eight times that. Thus, the
frame rate on my chip was 14318181 Hz / 14 / 64 / 262 = 60.9928 Hz.
The picture could not be displayed on a multi-norm television, but a
PAL television showed it in black and white, although the line
transformer was screaming pain.
The 6567R8 had an error (or feature) in the vertical sprite
co-ordinate register: when moving the sprite vertically in the bottom
border, increasing the vertical co-ordinate always by one, the sprite
jumped several lines at some value which I have forgotten.
Credits:
Peter Andersson <PAnd@Kullmar.SE>
Peter invited me to his place in January 1994 to help him with his
C64 emulator project (for 386 compatible processors using protected
mode). The emulator is still not ready, as the source code got lost
with a hard drive crash, but if it would be, nobody would use the
current emulators whose emulation -- to put nicely -- suck.
Peter's monitor had good picture size controls that let me to
measure the overscan screen size reliably.
Andreas Boose <Boose@Unixserv.RZ.FH-Hannover.DE>
If he wouldn't have asked me how to write data to the memory
places 0 and 1, this information would never have been discovered,
at least not without logic analyzators and other expensive things.
Andreas wrote a very good program that can be used for measuring
the video timing. When he wrote the program, I did not have
access to any 8-bit Commodore, and even if I would have had, it
would have been extremely difficult for me to synchronize such
routine to the screen.
John West <John@UCC.GU.UWA.Edu.AU>
John pointed out that the video chip reads from $39FF in the border
if using the ECM. He also said that the colors change one cycle
after writing to a color register (VIC-II registers $20--$2F).
Appendixes:
Here are a couple of programs written by Andreas Boose. All of them
are designed for PAL systems (63 cycles/line, 312 lines/frame), but
feel free to NTSC fix them. If you fix any of them, please send the
program to me <Marko.Makela@FTP.FUNET.FI>. Also, it would be nice if
someone would test the NTSC video chips and report the differences.
There are at least two fundamentally different versions of the NTSC
video chips. The older chips have 64 cycles/line and 262 lines/frame,
and the newer have 65 cycles/line and 263 lines/frame. So, please
specify the video chip type (6567 or 8564) and revision (the number
after the letter R, like 6567R8), if you provide me with test results
of NTSC video chips.
First, here is the Turbo Assembler source code for the timing
measurement program:
.SETPC $C000
.PROGRAM"OBJ"
+VALUE = $02
+TAB = $F7
+CNTZY = $F9
+HELPBYTE = $FB
+BASEVEC = $FC
+JOB = $FE
+BASEPAGE = $4000
+TABBEG = $8000
+ZEILE = 47
LDA #$7F
STA $DC0D
STA $DD0D
STA $DD05
STA $DD04
LDA #<IRQ1
STA $0314
LDA #>IRQ1
STA $0315
LDA $D012
BNE *-3
LDA #$3B
STA $D011
LDA #ZEILE
STA $D012
LDA $D019
STA $D019
LDA #$81
STA $D01A
LDA #<BASEPAGE
STA BASEVEC
LDA #>BASEPAGE
STA BASEVEC+1
LDY #0
LDX #$40
+L06 LDA BASEVEC+1
+L05 STA (BASEVEC),Y
INY
BNE L05
INC BASEVEC+1
DEX
BNE L06
LDA #<TABBEG
STA TAB
LDA #>TABBEG
STA TAB+1
LDA ANFTAB
STA CNTZY
LDA ANFTAB+1
STA CNTZY+1
+L02 JSR SETTIME
JSR GETADR
LDA #<$D012
LDX #>$D012
LDY #$00
JSR GETDATA
LDA #<$DD04
LDX #>$DD04
LDY #$FF
JSR GETDATA
INC CNTZY
BNE L01
INC CNTZY+1
+L01 LDA CNTZY
CMP ENDTAB
BNE L02
LDA CNTZY+1
CMP ENDTAB+1
BNE L02
LDA #0
STA $D01A
LDA $D019
STA $D019
LDA #<$EA31
STA $0314
LDA #>$EA31
STA $0315
LDA #$81
STA $DC0D
LDA #$1B
STA $D011
RTS
+SETTIME LDA CNTZY
AND #7
STA HELPBYTE
LDX #7
+L04 TXA
ASL
TAY
LDA #$24
DEC HELPBYTE
BMI L03
LDA #$EA
+L03 STA DELAY1,Y
DEX
BNE L04
LDA CNTZY+1
STA HELPBYTE
LDA CNTZY
ROR HELPBYTE
ROR
ROR HELPBYTE
ROR
ROR HELPBYTE
ROR
STA DELAY8+1
RTS
+GETDATA STA LOAD+1
STX LOAD+2
TYA
LDY #1
STY JOB
LDY JOB
BNE *-2
EOR VALUE
JMP WRITE
+GETADR LDA #<$DE00
STA LOAD+1
LDA #>$DE00
STA LOAD+2
LDA #1
STA JOB
LDY JOB
BNE *-2
LDX VALUE
STX BASEVEC+1
+L07 TYA
STA (BASEVEC),Y
INY
BNE L07
INY
STY JOB
LDY JOB
BNE *-2
LDA VALUE
JSR WRITE
TXA
+L09 STA (BASEVEC),Y
INY
BNE L09
+WRITE STA (TAB),Y
INC TAB
BNE *+4
INC TAB+1
RTS
+ANFTAB .W 0
+ENDTAB .W 1023
+IRQ1 LDA #<IRQ2
STA $0314
LDA #6
STA $DD00
LDX $D012
INX
INX
STX $D012
DEC $D019
CLI
LDX #$0A
DEX
BNE *-1 M-
NOP
NOP
NOP
NOP
JMP $EA81
+IRQ2 LDA #<IRQ1
STA $0314
DEC $D019
PHA
PLA
LDY #$11
LDA $D012
CMP $D012
BNE *+2 ;7
STY $DD0E ;4
DEC $D020
LDX #8 ;1
DEX ;10*5
BNE *-1 ;
NOP
NOP
+DELAY8 LDX #0 ;2
BIT $FF ;3
DEX ;2
BPL *-3 ;2
+DELAY1 BIT $EA ;8*3 =
BIT $EA
BIT $EA
BIT $EA
BIT $EA
BIT $EA
BIT $EA
BIT $EA
+LOAD LDA $DE00 ;4 162
STA VALUE
LDA #0
STA JOB
+YY LDA #$3B
STA $D011
LDA #ZEILE
STA $D012
INC $D020
LDA #7
STA $DD00
JMP $EA81
The results will be copied to memory starting from $8000. There are
four bytes of data for each sample. The two first bytes tell the
address which the video chip was reading, the third byte is the raster
line, and the fourth byte is a timer value, so that you can see the cycle
counts for DMA.
Here is an uuencoded binary of the above program:
begin 644 obj
M`,"I?XT-W(T-W8T%W8T$W:DCC10#J<&-%0.M$M#0^ZD[C1'0J2^-$M"M&="-
M&="I@8T:T*D`A?RI0(7]H`"B0*7]D?S(T/OF_<K0]*D`A?>I@(7XK1_!A?FM
M(,&%^B"HP"#HP*D2HM"@`"#4P*D$HMV@_R#4P.;YT`+F^J7YS2'!T-NE^LTB
MP=#4J0"-&M"M&="-&="I,8T4`ZGJC14#J8&-#=RI&XT1T&"E^2D'A?NB!XH*
MJ*DDQOLP`JGJF6W!RM#OI?J%^Z7Y9OMJ9OMJ9OMJC6?!8(U^P8Y_P9B@`83^
MI/[0_$4"3!;!J0"-?L&IWHU_P:D!A?ZD_M#\I@*&_9B1_,C0^LB$_J3^T/RE
M`B`6P8J1_,C0^Y'WYO?0`N;X8```_P.I18T4`ZD&C0#=KA+0Z.B.$M#.&=!8
MH@K*T/WJZNKJ3('JJ2.-%`/.&=!(:*`1K1+0S1+0T`",#MW.(-"B",K0_>KJ
MH@`D_\H0^R3J).HDZB3J).HDZB3J).JM`-Z%`JD`A?ZI.XT1T*DOC1+0[B#0
(J0>-`-U,@>KJ
`
end
In the beginning of this document I hinted that you could execute
programs in the I/O1 and I/O2. Here are two programs that demonstrate
this. Both use the addresses $DE00--$DE7F (so that they work also
with Andreas Boose's I/O devices installed), and the program "de00all"
runs all the time on that address range. If these programs do not
work on your computer, make sure you don't have any memory devices in
these addresses. If you haven't customized your computer, then you
have bad luck: your computer is not $DE00-compatible. That's normal,
of the 6 computers I have tested only 2 are $DE00-compatible. You
could try to put your computer in a metal box or something, so that
it wouldn't pick any noise to the data lines when reading the weak
signals from the open address space.
begin 644 de00all.prg
M`,!X&*D&C0#=J3N-$="I&(T8T*D`A?>I8(7XH@"@![V.P)'WB!#[I?=I"(7W
MD`+F^.C@*-#GQOB@]ZFAD??F^*;XX'_0U8W_?ZGJC?A_H@>]@<"=^$>]B<"=
M6W_*$/&I8(W/?JFUC?]^C3=_J0"-P0&IWHW"`:+`FJD@S1+0T/M,`-Z:8.JE
MM0"EM:7JI;7JJ0"BT)H`K`'<`,#O\/Y(J0&-(-``3`#>J:&-^4<`J:&-_$<`
$HL#J`*7J
`
end
begin 644 de00int.prg
M`,`@&.6I?XT-W*D_C10#J<"-%0.B'XH*"@JHO93`F0%`RA#RK1+0T/NI.XT1
MT*DOC1+0K1G0C1G0J8&-&M!,/,"I88T4`ZD&C0#=KA+0Z.B.$M#.&=!8H@K*
MT/WJZNKJ3('JJ3^-%`/.&="I+XT2T"3_K1+0S1+0T`"B$,K0_>KJ(`#>J3N-
E$="B4,K0_:D'C0#=3('JJ0"Z`*P!W`#`[_#^2*D!C2#0`)H`8.KJ
`
end
Finally, I will include my addresses here so that you can contact
me. If you are on the net but write a snail mail letter, please
include your E-mail address to your letter, so that I could answer you
electronically if possible. I will be in Germany between 4th of June
1994 and will be back on the net on 2st of August. My address
Marko.Makela@FTP.FUNET.FI should work all the time, I just cannot read
the E-mail too often. In contrary to that, the address
Marko.Makela@Helsinki.FI will be deleted in the future, so please do
not use it, at least not after August 1994.
Snail mail (Germany, valid until July 30th, 1994):
Marko MM-dkelM-d
AnschM-|tzstraM-_e 15, Zimmer I/209
D-23562 LM-|beck
Snail mail (Finland, valid all the time, but not read until 2st of August):
Marko MM-dkelM-d
Sillitie 10 A
FIN-01480 Vantaa
In case you are not using the ISO 8859-1 character set, you may want to
know that the letter M-d represents an adiaeresis, an a with two little points
on top of it. Similarly, M-| is an udiaeresis, an u with two points on it.
The points are just like the point over the lower case i and j letters, but
there are two of them, and they are placed horizontally. The M-_ character is
the German sharp s and looks like the lower case Greek beta character. If
you don't know how to write it, write two s characters on its place.
Make REAL money with your website!
The entire AOH site is optimized to look best in Firefox® 2.0 on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2008 AOH
We do not send spam. If you have received spam bearing an artofhacking.com email address, please forward it with full headers to abuse@artofhacking.com.
