📄 videodla.c
字号:
//video gen and DLA
//D.5 is sync:1000 ohm + diode to 75 ohm resistor
//D.6 is video:330 ohm + diode to 75 ohm resistor
#include <Mega163.h>
#include <stdio.h>
#include <stdlib.h>
//cycles = 63.625 * 8 Note NTSC is 63.55
//but this line duration makes each frame exactly 1/60 sec
//which is nice for keeping a realtime clock
#define lineTime 509
#define begin {
#define end }
#define ScreenTop 30
#define ScreenBot 230
#define T0reload 256-60
//NOTE that the first line of CHARs must be in registers!
char syncON, syncOFF, v1, v2, v3, v4, v5, v6, v7, v8;
int i,LineCount, time;
//Define application globals here:
char ballx, bally, dx, dy;
char screen[800], t, ts[10];
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,
//3
0b00000000,
0b00011100,
0b00100010,
0b00000010,
0b00011100,
0b00000010,
0b00100010,
0b00011100,
//4
0b00000000,
0b00001110,
0b00010010,
0b00100010,
0b00111111,
0b00000010,
0b00000010,
0b00000010,
//5
0b00000000,
0b00111100,
0b00100000,
0b00100000,
0b00011100,
0b00000010,
0b00000010,
0b00111100,
//6
0b00000000,
0b00010000,
0b00100000,
0b00100000,
0b00111100,
0b00100010,
0b00100010,
0b00011100,
//7
0b00000000,
0b00111111,
0b00000001,
0b00000001,
0b00000010,
0b00000010,
0b00000100,
0b00000100,
//8
0b00000000,
0b00011110,
0b00100001,
0b00100001,
0b00011110,
0b00100001,
0b00100001,
0b00011110,
//9
0b00000000,
0b00011110,
0b00100001,
0b00100001,
0b00011110,
0b00000001,
0b00000001,
0b00000010,
//C
0b00000000,
0b00011110,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00011110,
//U
0b00000000,
0b01000010,
0b01000010,
0b01000010,
0b01000010,
0b01000010,
0b01000010,
0b00111100,
//E
0b00000000,
0b00111111,
0b00100000,
0b00100000,
0b00111111,
0b00100000,
0b00100000,
0b00111111};
//==================================
//This is the sync generator. It MUST be entered from
//sleep mode to get accurate timing of the sync pulses
//At 8 MHz, all of the sync logic fits in the 5 uSec sync
//pulse
interrupt [TIM1_COMPA] void t1_cmpA(void)
begin
//start the Horizontal sync pulse
PORTD = syncON;
//count timer 0 at 1/usec
TCNT0=0;
//update the curent scanline number
LineCount ++ ;
//begin inverted (Vertical) synch after line 247
if (LineCount==248)
begin
syncON = 0b00100000;
syncOFF = 0;
end
//back to regular sync after line 250
if (LineCount==251)
begin
syncON = 0;
syncOFF = 0b00100000;
end
//start new frame after line 262
if (LineCount==263)
begin
LineCount = 1;
end
//end sync pulse
PORTD = syncOFF;
end
//==================================
// put a character on the screen
// x-cood must be on divisible by 8 x position
// c is index into bitmap
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
//==================================
//plot one point
//at x,y with color 1=white 0=black 2=invert
void video_pt((char x, char y, char c)
begin
//The following odd construction
//sets/clears exactly one bit at the x,y location
i=((int)x>>3) + ((int)y<<3) ;
if (c==1) screen[i] = screen[i] | 1<<(7-(x & 0x7));
if (c==0) screen[i] = screen[i] & ~(1<<(7-(x & 0x7)));
if (c==2) screen[i] = screen[i] ^ (1<<(7-(x & 0x7)));
end
//==================================
//return the value of one point
//at x,y with color 1=white 0=black 2=invert
char video_set((char x, char y)
begin
//The following construction
//detects exactly one bit at the x,y location
i=((int)x>>3) + ((int)y<<3) ;
return ( screen[i] & 1<<(7-(x & 0x7)));
end
//==================================
// set up the ports and timers
void main(void)
begin
//init timer 1 to generate sync
OCR1A = lineTime; //One NTSC line
TCCR1B = 9; //full speed; clear-on-match
TCCR1A = 0x00; //turn off pwm and oc lines
TIMSK = 0x10; //enable interrupt T1 cmp
//init ports
DDRD = 0xf0; //video out and switches
//D.5 is sync:1000 ohm + diode to 75 ohm resistor
//D.6 is video:330 ohm + diode to 75 ohm resistor
//init timer 0 to 1/uSec
TCCR0 = 2;
//initialize synch constants
LineCount = 1;
syncON = 0b00000000;
syncOFF = 0b00100000;
//=============================================
// Put application initializtion here
//=============================================
//Print "CU-ECE476"
video_putchar(0,2,10);
video_putchar(1*8,2,11);
video_putchar(2*8,2,12);
video_putchar(3*8,2,10);
video_putchar(4*8,2,12);
video_putchar(5*8,2,4);
video_putchar(6*8,2,7);
video_putchar(7*8,2,6);
//make a dash
video_pt(16,6,1);
//side lines
for (i=0;i<799;i=i+8)
begin
screen[i]= screen[i] | 0b10000000;
screen[i+7]= screen[i+7] | 0b00000001;
end
//top line & bottom lines
for (i=0;i<8;i++)
begin
screen[i]=0b11111111;
screen[i+792]=0b11111111;
screen[i+88]=0b11111111;
screen[i+712]=0b11111111;
end
//init random num gen
srand(1);
//initial aggregation point to middle of screen
ballx=32;
bally=50;
video_pt(ballx,bally,1);
//Now set up first diffusion particle
ballx=35;
bally=50;
video_pt(ballx,bally,1);
//init software timer
t=0;
time=0;
//enable sleep mode
MCUCR = 0b01000000;
#asm ("sei");
//The following loop executes once/video line during lines
//1-230, then does all of the frame end processing
//DON't mess with this loop until you get the the applications note
while(1)
begin
//precompute pixel index for next line
if (LineCount<ScreenBot && LineCount>=ScreenTop)
begin
//left-shift 3 would be individual lines
// <<2 means line-double the pixels
//The 0xfff8 truncates the odd line bit
i=(LineCount-ScreenTop)<<2 & 0xfff8;;
end
//stall here until next line starts
//sleep enable; mode=idle
//use sleep to make entry into sync ISR uniform time
#asm ("sleep");
//Put code here to execute once/line
//During the active portion of a line;
//--TCNT1 goes from about 130 to about 480
//--Usable lines 1 to about 240
if (LineCount<ScreenBot && LineCount>ScreenTop)
begin
//load the pixels into registers
v1 = screen[i];
v2 = screen[i+1];
v3 = screen[i+2];
v4 = screen[i+3];
v5 = screen[i+4];
v6 = screen[i+5];
v7 = screen[i+6];
v8 = screen[i+7];
//now blast them out to the screen
PORTD.6=v1 & 0b10000000;
PORTD.6=v1 & 0b01000000;
PORTD.6=v1 & 0b00100000;
PORTD.6=v1 & 0b00010000;
PORTD.6=v1 & 0b00001000;
PORTD.6=v1 & 0b00000100;
PORTD.6=v1 & 0b00000010;
PORTD.6=v1 & 0b00000001;
PORTD.6=v2 & 0b10000000;
PORTD.6=v2 & 0b01000000;
PORTD.6=v2 & 0b00100000;
PORTD.6=v2 & 0b00010000;
PORTD.6=v2 & 0b00001000;
PORTD.6=v2 & 0b00000100;
PORTD.6=v2 & 0b00000010;
PORTD.6=v2 & 0b00000001;
PORTD.6=v3 & 0b10000000;
PORTD.6=v3 & 0b01000000;
PORTD.6=v3 & 0b00100000;
PORTD.6=v3 & 0b00010000;
PORTD.6=v3 & 0b00001000;
PORTD.6=v3 & 0b00000100;
PORTD.6=v3 & 0b00000010;
PORTD.6=v3 & 0b00000001;
PORTD.6=v4 & 0b10000000;
PORTD.6=v4 & 0b01000000;
PORTD.6=v4 & 0b00100000;
PORTD.6=v4 & 0b00010000;
PORTD.6=v4 & 0b00001000;
PORTD.6=v4 & 0b00000100;
PORTD.6=v4 & 0b00000010;
PORTD.6=v4 & 0b00000001;
PORTD.6=v5 & 0b10000000;
PORTD.6=v5 & 0b01000000;
PORTD.6=v5 & 0b00100000;
PORTD.6=v5 & 0b00010000;
PORTD.6=v5 & 0b00001000;
PORTD.6=v5 & 0b00000100;
PORTD.6=v5 & 0b00000010;
PORTD.6=v5 & 0b00000001;
PORTD.6=v6 & 0b10000000;
PORTD.6=v6 & 0b01000000;
PORTD.6=v6 & 0b00100000;
PORTD.6=v6 & 0b00010000;
PORTD.6=v6 & 0b00001000;
PORTD.6=v6 & 0b00000100;
PORTD.6=v6 & 0b00000010;
PORTD.6=v6 & 0b00000001;
PORTD.6=v7 & 0b10000000;
PORTD.6=v7 & 0b01000000;
PORTD.6=v7 & 0b00100000;
PORTD.6=v7 & 0b00010000;
PORTD.6=v7 & 0b00001000;
PORTD.6=v7 & 0b00000100;
PORTD.6=v7 & 0b00000010;
PORTD.6=v7 & 0b00000001;
PORTD.6=v8 & 0b10000000;
PORTD.6=v8 & 0b01000000;
PORTD.6=v8 & 0b00100000;
PORTD.6=v8 & 0b00010000;
PORTD.6=v8 & 0b00001000;
PORTD.6=v8 & 0b00000100;
PORTD.6=v8 & 0b00000010;
PORTD.6=v8 & 0b00000001;
PORTD.6=0 ;
end
//=============================================
// Put application code here
//=============================================
//The following code executes during the vertical blanking
//Code here can be as long as 63 uSec/line
//For a total of 30 lines x 63.5 uSec/line x 8 cycles/uSec
// Every 60 uSec or so, you should insert a "sleep"
//command so that the timer 1 ISR happens at a regular interval,
//but it may not matter to most TVs
if (LineCount==231)
begin
//erase old point
video_pt(ballx,bally,0);
//get new x
ballx = ballx + dx ;
dx=(rand()>16300)?1:-1;
if (ballx>60) dx = -1;
if (ballx<4) dx = 1;
//get new y
bally = bally + dy ;
dy=(rand()>16300)?1:-1;
if (bally>86) dy = -1;
if (bally<14) dy = 1;
// write new point
video_pt(ballx,bally,1);
//detect a "hit" on an existing point
//If hit, make a new point
if (video_set(ballx-1,bally) |
video_set(ballx+1,bally) |
video_set(ballx,bally-1) |
video_set(ballx,bally+1) |
video_set(ballx-1,bally-1) |
video_set(ballx+1,bally-1) |
video_set(ballx-1,bally+1) |
video_set(ballx+1,bally+1) )
begin
//release new particles only from the corners
ballx = (rand()>16300)?5:60;
bally = (rand()>16300)?20:85;
video_pt(ballx,bally,1);
end
if (t++ > 59)
begin
t=0;
time++;
//print the time
sprintf(ts,"%06i",time);
video_putchar(0,90,ts[0]-0x30);
video_putchar(1*8,90,ts[1]-0x30);
video_putchar(2*8,90,ts[2]-0x30);
video_putchar(3*8,90,ts[3]-0x30);
video_putchar(4*8,90,ts[4]-0x30);
video_putchar(5*8,90,ts[5]-0x30);
end
end //line 231 and end application code
end //while
end //main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -