| 1 |
!!! THIS INFORMATION IS OBSOLETE !!! |
| 2 |
|
| 3 |
This document describes an initial improvement to the openMSX VDP LINE command |
| 4 |
timing. Later it has been improved further to be nearly identical to the real |
| 5 |
VDP. Those improvements are described in the 'vdp-vram-timing' document. |
| 6 |
|
| 7 |
So this document is only useful if you're interested in the historic |
| 8 |
development of openMSX. |
| 9 |
|
| 10 |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| 11 |
|
| 12 |
Speed-test for V99x8 LINE commands |
| 13 |
---------------------------------- |
| 14 |
|
| 15 |
This test is inspired by this forum topic: |
| 16 |
http://www.msx.org/forum/msx-talk/software-and-gaming/line |
| 17 |
and more in particular the post by NYYRIKKI on 09-08-2012, and the pictures he |
| 18 |
posted the next day. |
| 19 |
|
| 20 |
Very briefly his test draws in a loop lines (using the LINE command) from the |
| 21 |
center of the screen to each point along the edge of the screen. _While_ the |
| 22 |
command is executing the command engine COLOR register is changed rapidly. This |
| 23 |
results in color patterns that give an indication for how fast the LINE command |
| 24 |
is executing for different line directions (see the pictures in the forum). |
| 25 |
|
| 26 |
I took this test as a starting point and changed it in the following ways: |
| 27 |
a) Run in screen 8 instead of screen 5 |
| 28 |
b) Start drawing from pixel (0,0) instead of from the center |
| 29 |
c) Change the colors faster |
| 30 |
|
| 31 |
a) The color value of a pixel is an indication for how many times the color |
| 32 |
register has been changed (in my test it starts at 0 and increments by 1 each |
| 33 |
time). In screen 8 we see the lower 8 bits of this count, while in screen 5 we |
| 34 |
only have 4 bits. Even in screen 8 this counter will overflow (we actually need |
| 35 |
9 bits) but getting the actual count value is easier in screen 8. (As a |
| 36 |
verification we also did a few tests in screen 5 and those gave the exact same |
| 37 |
timing results as compared to screen 8.) |
| 38 |
|
| 39 |
b) When drawing from the top-left we can draw lines of length 256 pixels |
| 40 |
(longest axis) instead of only 128 pixels. This gives more accurate |
| 41 |
measurements. From NYYRIKKI's original pictures we can see the pattern has 8 |
| 42 |
axis of symmetry, so it's OK to only test one octet (only 1 direction in X/Y |
| 43 |
and also only X-major). |
| 44 |
|
| 45 |
c) NYYRIKKI's original test used OTIR to rapidly change the COLOR register, |
| 46 |
this takes 23 Z80 cycles per iteration. I use a long sequence of |
| 47 |
INC A ; OUT (#9B),A |
| 48 |
instructions, this only takes 17 cycles per change. Multiply this by 6 to get |
| 49 |
VDP ticks. |
| 50 |
|
| 51 |
At the bottom of this text you find the source code of my test program. |
| 52 |
|
| 53 |
|
| 54 |
We run this test program in 3 modes: |
| 55 |
1) display enabled, sprites enabled |
| 56 |
2) display enabled, sprites disabled |
| 57 |
3) display disabled, (sprite status doesn't matter) |
| 58 |
See 'line-speed.xcf.bz2' for the graphical output of these tests |
| 59 |
(enable/disable the different layers to see the different pictures). |
| 60 |
|
| 61 |
|
| 62 |
Next we fit this data on some timing model. This is the model we used: |
| 63 |
|
| 64 |
time-of-line-cmd = A * pixels-of-major-axis + B * pixels-of-minor-axis. |
| 65 |
|
| 66 |
With A and B (yet unknown) constants. (BTW the old timing model in openMSX |
| 67 |
had B==0). |
| 68 |
|
| 69 |
In the last column of the 3 pictures we can read an indication for the total |
| 70 |
time it took to draw this line. After taking overflow into account we can |
| 71 |
multiply this number by '17 * 6' to get (approximately) the time in VDP cycles |
| 72 |
it took to draw the LINE to that point. Note that we can only (easily) do this |
| 73 |
for the pixels in the last column because the pixels in the other columns are |
| 74 |
possibly overwritten by multiple LINE commands. |
| 75 |
|
| 76 |
So now we have 256 measurements to fit two parameters. When doing a |
| 77 |
least-squares-fit (actually a least-squares-fit with the additional constraint |
| 78 |
that the result must be integer) we get these results: |
| 79 |
|
| 80 |
display=on, sprites=on A = 135 B = 36 |
| 81 |
display=on, sprites=off A = 120 B = 30 |
| 82 |
display=off A = 109 B = 29 |
| 83 |
|
| 84 |
|
| 85 |
Next we change the implementation in openMSX for this timing model, and then we |
| 86 |
run the same tests we first ran on a real machine in openMSX (you can see those |
| 87 |
results also in 'line-speed.xcf.bz2). |
| 88 |
|
| 89 |
|
| 90 |
Compared to openMSX the real measurements show more irregularities. This means |
| 91 |
that the timing model is not yet complete. My current best guess is that these |
| 92 |
irregularities can be explained by fixed VRAM-access-slots for the different |
| 93 |
VDP subsystems. But very little information is known about such access-slots. |
| 94 |
|
| 95 |
|
| 96 |
Wouter |
| 97 |
|
| 98 |
|
| 99 |
|
| 100 |
;----------------------------------------------------------------------------- |
| 101 |
|
| 102 |
org #C000-7 |
| 103 |
|
| 104 |
db #fe |
| 105 |
dw start |
| 106 |
dw stop |
| 107 |
dw start |
| 108 |
|
| 109 |
start di |
| 110 |
|
| 111 |
ld a,2 |
| 112 |
out (#99),a |
| 113 |
ld a,15+128 |
| 114 |
out (#99),a ; Select S#2 |
| 115 |
WaitCE in a,(#99) |
| 116 |
rra |
| 117 |
jp c,WaitCE |
| 118 |
|
| 119 |
loop |
| 120 |
wait1 in a,(#99) |
| 121 |
and #40 |
| 122 |
jr z,wait1 ; wait if not inside vertical border |
| 123 |
wait2 in a,(#99) |
| 124 |
and #40 |
| 125 |
jr nz,wait2 ; wait if inside vertical border |
| 126 |
; at this point we're at the top of the display area |
| 127 |
|
| 128 |
ld a,36 |
| 129 |
out (#99),a |
| 130 |
ld a,17+128 |
| 131 |
out (#99),a ; Indirect access to R#32 and up |
| 132 |
ld hl,LineCmd |
| 133 |
ld bc,10*256+#9B |
| 134 |
otir |
| 135 |
|
| 136 |
ld a,44+128 |
| 137 |
out (#99),a |
| 138 |
ld a,17+128 |
| 139 |
out (#99),a ; Indirect access to CMD-CLR |
| 140 |
|
| 141 |
ld a,#70 |
| 142 |
out (#99),a |
| 143 |
ld a,46+128 |
| 144 |
out (#99),a ; start LINE cmd |
| 145 |
|
| 146 |
; Change command color register as fast as possible |
| 147 |
; 17 Z80 cycles per change |
| 148 |
xor a |
| 149 |
out (#9B),a ; 0x000 |
| 150 |
inc a |
| 151 |
out (#9B),a ; 0x001 |
| 152 |
[ repeated so that we have a sequence of 512 OUT instructions ] |
| 153 |
inc a |
| 154 |
out (#9B),a ; 0x1ff |
| 155 |
|
| 156 |
|
| 157 |
in a,(#99) |
| 158 |
rra |
| 159 |
jr nc,ok |
| 160 |
halt ; ERROR line cmd was not yet finished! |
| 161 |
ok |
| 162 |
ld hl,(LineCmd+6) ; ny |
| 163 |
ld a,h |
| 164 |
or a |
| 165 |
jr nz,break |
| 166 |
inc hl |
| 167 |
ld (LineCmd+6),hl |
| 168 |
jp loop |
| 169 |
|
| 170 |
break xor a |
| 171 |
out (#99),a |
| 172 |
ld a,15+128 |
| 173 |
out (#99),a ; Select S#0 |
| 174 |
|
| 175 |
ei |
| 176 |
ret |
| 177 |
|
| 178 |
LineCmd dw 0, 0 ; dx, dy |
| 179 |
dw 256, 0 ; nx, ny |
| 180 |
db 0 |
| 181 |
db 0 |
| 182 |
|
| 183 |
stop equ $ |