📄 video.htm
字号:
xchange = 0;
if (dy>dx)
begin
temp = dx;
dx = dy;
dy = temp;
xchange = 1;
end
e = (dy << 1) - dx;
for (j=0; j<=dx; j++)
begin
video_pt(x,y,c) ;
if (e>=0)
begin
if (xchange==1) x = x + s1;
else y = y + s2;
e = e - (dx << 1);
end
if (xchange==1) y = y + s2;
else x = x + s1;
e = e + (dy << 1);
end
end
</PRE>
<P align=left><U>Draw a character</U></P>
<P align=left>Three character generators were written. Each will be described
below. The 5x7 and 3x5 character sets have limited string-to-video abilities.
</P>
<OL>
<LI>
<P align=left><I>8x8 Character Generator</I>. A simple character generator
reads a bitmap stored in flash and copies it into the <CODE>screen</CODE>
array. The first few entries of the <CODE>bitmap</CODE> array are shown below,
corresponding to the characters 0, 1 and 2. You can discern the character
shape by squinting at the 1/0 table.</P><PRE>flash char bitmap[13][8]={
//0
0b00000000,
0b00111000,
0b01000100,
0b01000100,
0b01000100,
0b01000100,
0b01000100,
0b00111000,
//1
0b00000000,
0b00010000,
0b00110000,
0b01010000,
0b00010000,
0b00010000,
0b00010000,
0b01111100,
//2
0b00000000,
0b00011100,
0b00100010,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00111110,
</PRE>
<P align=left>The actual character generator is shown below. It is limited to
drawing characters which are aligned on byte boundaries. The desired character
is simply copied into the <CODE>screen</CODE> array, and is therefore
fast..</P><PRE>// put a character on the screen
// x-cood must be on divisible by 8
// c is index into bitmap for one character
void video_putchar(char x, char y, char c)
begin
i=((int)x >> 3) + ((int)y << 3) ;
screen[i] = bitmap[c][0];
screen[i+8] = bitmap[c][1];
screen[i+16] = bitmap[c][2];
screen[i+24] = bitmap[c][3];
screen[i+32] = bitmap[c][4];
screen[i+40] = bitmap[c][5];
screen[i+48] = bitmap[c][6];
screen[i+56] = bitmap[c][7];
end
</PRE>
<LI><I>3x5 Character Generator.</I> This very small font is hard to read for
letters, but works well for numbers. The character generator places characters
only on x coordinates which are divisible by 4. The character generator and
string functions are shown below. <PRE>
// put a small character on the screen
// x-cood must be on divisible by 4
// c is index into bitmap
void video_smallchar(char x, char y, char c)
begin
char mask;
i=((int)x >> 3) + ((int)y<< 3) ;
if (x == (x & 0xf8)) mask = 0x0f;
else mask = 0xf0;
screen[i] = (screen[i] & mask) | (smallbitmap[c][0] & ~mask);
screen[i+8] = (screen[i+8] & mask) | (smallbitmap[c][1] & ~mask);
screen[i+16] = (screen[i+16] & mask) | (smallbitmap[c][2] & ~mask);
screen[i+24] = (screen[i+24] & mask) | (smallbitmap[c][3] & ~mask);
screen[i+32] = (screen[i+32] & mask) | (smallbitmap[c][4] & ~mask);
end
// put a string of small characters on the screen
// x-cood must be on divisible by 4
void video_putsmalls(char x, char y, char *str)
begin
char i ;
for (i=0; str[i]!=0; i++)
begin
if (str[i]>=0x30 && str[i]<=0x39)
video_smallchar(x,y,str[i]-0x30);
else video_smallchar(x,y,str[i]-0x40+12);
x = x+4;
end
end
</PRE>
<P></P>
<LI><I>5x7 Character Generator.</I> This font is quite readable, but the
character generator is slow because it plots the characters as an array of
points, rather than just copying them into the screen array. <PRE>// put a big character on the screen
// c is index into bitmap
void video_putchar(char x, char y, char c)
begin
char j;
for (j=0;j< 7;j++)
begin
v1 = bitmap[c][j];
video_pt(x, y+j, (v1 & 0x80)==0x80);
video_pt(x+1, y+j, (v1 & 0x40)==0x40);
video_pt(x+2, y+j, (v1 & 0x20)==0x20);
video_pt(x+3, y+j, (v1 & 0x10)==0x10);
video_pt(x+4, y+j, (v1 & 0x08)==0x08);
end
end
// put a string of big characters on the screen
void video_puts(char x, char y, char *str)
begin
char i ;
for (i=0; str[i]!=0; i++)
begin
if (str[i]>=0x30 && str[i]<=0x39)
video_putchar(x,y,str[i]-0x30);
else video_putchar(x,y,str[i]-0x40+9);
x = x+6;
end
end
</PRE></LI></OL>
<P align=left><B>Example Programs</B></P>
<P align=left>For the newest version go to the bottom of the page in the
<B>Optimization and Bug Fixes</B> section.</P>
<P align=left>The <A
href="http://instruct1.cit.cornell.edu/courses/ee476/video/video2.c">first
code</A> produces a checker board pattern to check for accuracy and stability of
the displayed raster. The pattern is hard-coded.</P>
<P align=left><A
href="http://instruct1.cit.cornell.edu/courses/ee476/video/Image12.jpg"><IMG
height=96 src="Video.files/Image12small.jpg" width=128 border=0></A></P>
<P align=left>The <A
href="http://instruct1.cit.cornell.edu/courses/ee476/video/video3.c">second test
program</A> content consists of points, lines, and text. The lines are
hard-coded, and the point drawing stuff is minimal. The vertical and horizontal
lines were hard-coded to the edges of the display region. A bouncing ball (the
two dots in the lower center, just above the 6) tests for correct write/erase of
a point. The 8x8 character generator supports bitmap characters, which are
defined in flash memory. The number at the bottom is an elapsed time in
seconds.</P>
<P align=left><A
href="http://instruct1.cit.cornell.edu/courses/ee476/video/Image01.jpg"><IMG
height=96 src="Video.files/Image01small.jpg" width=128 border=0></A></P>
<P align=left>The <A
href="http://instruct1.cit.cornell.edu/courses/ee476/video/videoDLA.c">third
program</A> computes a <A
href="http://www.google.com/search?hl=en&q=diffusion%2Blimited%2Baggregation">diffusion-limited
aggregation</A> (DLA). This was a test of dynamics in the code and required a
better version of a function to write/erase a point and a function to read back
a point from video memory. The algorithm releases a particle at the edge of the
region, which then diffuses randomly until it hits a seed particle in the center
of the screen. A new particle is then released and the process repeated. This
example took 5547 seconds to compute. The current free particle can be seen in
the lower-right of the screen.</P>
<P align=left><A
href="http://instruct1.cit.cornell.edu/courses/ee476/video/ImageDLA.jpg"><IMG
height=96 src="Video.files/ImageDLAsmall.jpg" width=128 border=0></A> </P>
<P align=left>The <A
href="http://instruct1.cit.cornell.edu/courses/ee476/video/videoKal.c">fourth
program</A> implements a fast line generator and cleans up the point, character,
and read-back primitives to be more consistent. It uses the line generator to
draw a 4-fold symmetric kalidoscope pattern. </P>
<P align=left><A
href="http://instruct1.cit.cornell.edu/courses/ee476/video/kaldi.jpg"><IMG
height=96 src="Video.files/kaldismall.jpg" width=128 border=0></A></P>
<P align=left>The <A
href="http://instruct1.cit.cornell.edu/courses/ee476/video/videotxt2.c">fifth
program</A> implements the very small (3x5) font and a limited string-to-video
abilty for the 3x5 and 5x7 fonts. The rectangle at the lower left is an animated
"fuel gauge". The animated "stick figure" suggests how to do sprite
animation.</P>
<P align=left><A
href="http://instruct1.cit.cornell.edu/courses/ee476/video/text2.jpg"><IMG
height=96 src="Video.files/text2small.jpg" width=128 border=0></A> </P>
<P align=left><B>Adding Sound</B> </P>
<P align=left>Since most TVs have a sound input, it would be nice to be able to
generate some sound from the program. Two modifications of the video program are
necessary to generate sound on the Mega163. (Note that sound on the Mega32 is
much easier, see the next section.) First, a bit needs to be toggled in the the
interrupt which handles the sync generation. Care must be taken to make all
conditionals use the same number of cycles, to avoid video jitter. Second, to
save a few microseconds, loading resisters for video playback on each line has
to be converted to assembler. This <A
href="http://instruct1.cit.cornell.edu/courses/ee476/video/videosnd.c">example</A>
produces a two-octave scale, playing 4 notes/second. The accuracy of the tones
is about 1%, which is good enough for sound effects, but will drive some people
out of the room. This version of the video program is portable across compiler
versions and is compatable with <FONT color=#ff0000>CodeVision version
1.23.7</FONT>.</P>
<P align=left>The following Matlab code generates the required counts, assuming
that the sync interrupt will toggle a bit. The first column of the output is the
frequency of the note. The second column is the note duration in units of 63.625
microseconds. The third is the relative error. Between C3 and C6, all note
frequencies are within 1% error except for F5 which is flat by 2%.</P>
<P align=left>The output port pin should be connected to ground by a 5 Kohm
resistor. The TV should be connected across the resistor. The resistor is
necessary because the TV is AC coupled and will slowly charge up and cut off the
audio.</P>
<P align=left><PRE> %Generate counts for notes c3 to c6
%in units of 63.625 microseconds
fmax = 1/63.625e-6;
notes=[130.8 146.8 164.8 174.6 196 220 246.9 ...
261.6 293.7 329.6 349.2 392 440 493.9 523.3 ...
587.3 659.3 698.5 784 880 987.8 1046.5];
r = (fmax./notes);
for i=1:length(r)
fprintf(1,'%6.1f%6.1f%10.4f\n',notes(i),round(r(i)),(r(i)-round(r(i)))/r(i));
end
%frequency, count, relative error
130.8 120.0 0.0013 C3
146.8 107.0 0.0006
164.8 95.0 0.0039
174.6 90.0 0.0002
196.0 80.0 0.0024
220.0 71.0 0.0062
246.9 64.0 -0.0054
261.6 60.0 0.0013 C4
293.7 54.0 -0.0091
329.6 48.0 -0.0066
349.2 45.0 0.0002
392.0 40.0 0.0024
440.0 36.0 -0.0078
493.9 32.0 -0.0056
523.3 30.0 0.0012 C5
587.3 27.0 -0.0089
659.3 24.0 -0.0068
698.5 23.0 -0.0222 F5 2% error!
784.0 20.0 0.0024
880.0 18.0 -0.0078
987.8 16.0 -0.0056
1046.5 15.0 0.0012 C6
</PRE>
<P><B>Optimization and Bug fixes</B>
<P><A
href="http://instruct1.cit.cornell.edu/courses/ee476/video/Video32v3.c">Mega32
with sound</A> 5 May 2003 <FONT color=#ff0000>Current Version</FONT>
<P><IMG height=263 src="Video.files/Mega32.jpg" width=300>
<P>Changes/improvements/bugs:
<UL>
<LI>Uses timer 0 for tone generation </LI></UL>
<P><A
href="http://instruct1.cit.cornell.edu/courses/ee476/video/Video32v2.c">Mega32
version</A> 27 March 2003
<P>Changes/improvements/bugs:
<UL>
<LI>Draws 128x100 raster, filling whole screen
<LI>ASM macros make video bit-blasting much shorter and more readable.
</LI></UL>
<P><A
href="http://instruct1.cit.cornell.edu/courses/ee476/video/VideoOpt32.c">Mega32
version</A>. 5 March 2003
<P>Changes/improvements/bugs:
<UL>
<LI>Draws 128x100 raster, assuming a clock speed of 16 MHz.
<LI>All video generation is moved to ISR to make main loop cleaner
<LI>Screen position is more easily controlled by <CODE>delay_us()</CODE>
calls.
<LI>MCUSR modified for sleep enable bit position change.
<LI>Line time is now 1018 clock cycles.
<LI>A bug in the line routine limits the x coordinate to the range 0-126.
<LI>A CodeVision bug requires that you turn off the <CODE>chip
signature</CODE> check </LI></UL>
<P><A
href="http://instruct1.cit.cornell.edu/courses/ee476/video/vidopt1.c">Newest
Mega163 version.</A> 28 Feb 2003
<P>Bug fixes:
<UL>
<LI>Fixed a bug in the line generator which caused jagged lines when the line
was long and slope shallow.
<LI>Changed a conditional limit so that the <CODE>colon</CODE> character
prints correctly.
<LI>Turned off automatic register allocation at the beginning of the program.
<LI>Removed the requirement for unchecking the <CODE>signed char</CODE> box in
the compiler. </LI></UL>
<P>Optimization:</P>
<UL>
<LI>Address computation at the start of each line is in ASM.
<LI>Point drawing routine is converted to ASM, for about a 2 times speedup.
<LI>Better use of register variables in the big character routine. </LI></UL>
<HR>
<P><FONT size=-1>Copyright Cornell University Jan 2003</FONT></P>
<P> </P></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -