え~、ソフトウェアです。実は、7/20には、(シミュレーションでの)デバッグも終わっているのですが、完全に夏バテでその後の作業に手をつけられず3週間近くホッポリぱなし。
ソフトも公開して、これで「出来上がりませんでした」というわけにはいかんでしょうな…
だれか部屋の片付けを手伝ってください…(笑)
とりあえず、「夏休みの自由研究」ということで8月中の完成を目指すことにします。
ソースコードは最後にのせておきます。HITECH社のPICC(フリー版)用です。
----
[本日の御託]
インテルの「Nehalem」というプロジェクト名で呼ばれていた新しいプロセッサは「Core i7」と呼ばれるようになるようです。ま、ワタシ的には「Larrabee(ララビー)」の方が興味ありますね。
また、Atomのデュアルコア版は9月21日に発売が決まったようですが、肝心のコンパニオンチップはどうなのでしょう?Dual AtomのTPDは8Wとのことですが、現行のAtom(デスクトップ、230でTPD4W)用のマザーボードは945GCという激熱野郎が載っています。ちょっとTPDはすぐには見つけられませんでしたが、おそらく20W近いと思います。(サイテー)
G43+セレロン440あたりの方がトータルの性能・パワー比は優れてるなんてことになりかねません。
そういや、VIAのNano(Isaiah)なんてのもありますね。IBMの65nmプロセスとのことですが、性能はどうなのでしょう?Atomをやや下回る感じでしょうか?インテルが、AtomでOOEを止めたのに対し、こちらはOOE機能を追加。なんとも面白いものです。
//
// Video Line selector
// (c) 2008 B.O
//
#include
#define UNTIL(x) while( !(x))
//
// RA[4:0] --> targetline_in
// RA[5] --> OddEven_in
// RA[7,6] --> for osc
// RB0/INT --> HSYNC_bar_in used for interrupt
// RB1 --> VSYNC_bar_in
// RB2 --> OE_in
// RB3 --> Both_in
// RB4 --> TRIG_out
// RB5 --> LED0_out
// RB6 --> LED1_out
// RB7 --> spare (tentative out)
//
// alias
static volatile unsigned char targetline_in @((unsigned)&PORTA) ;
static volatile bit OddEvenSel_in @((unsigned)&PORTA*8)+5;
static volatile bit HSYNC_bar_in @((unsigned)&PORTB*8)+0;
static volatile bit VSYNC_bar_in @((unsigned)&PORTB*8)+1;
static volatile bit OE_in @((unsigned)&PORTB*8)+2;
static volatile bit BOTH_in @((unsigned)&PORTB*8)+3;
static volatile bit TRIG_bar_out @((unsigned)&PORTB*8)+4;
static volatile bit LED0_out @((unsigned)&PORTB*8)+5;
static volatile bit LED1_out @((unsigned)&PORTB*8)+6;
static volatile bit spare @((unsigned)&PORTB*8)+7;
// globals
static volatile short count , total, line , maxval, maxval_half,
maxval_half2, initialval, initialval2, target_line;
static bit prev_vsync, vsync ;
static bit blink ;
// constant
static const short target_line_offset = 0 ;
void interrupt isr(void)
{
// debug
spare = 1 ;
prev_vsync = vsync ;
vsync = VSYNC_bar_in ;
// manage count
if( (prev_vsync == 1) && ( vsync == 0 )) {
total = count ;
count = 0 ;
} // if
else {
count = count++ ;
}
// manage real line number in 'line'
// in case of VSYNC, aligning counter
if( (( BOTH_in == 1 )
&& (prev_vsync == 1) && ( vsync == 0 ))
||(( BOTH_in == 0 )
&& (prev_vsync == 1) && ( vsync == 0 )
&& ( OddEvenSel_in == OE_in ) ) ) {
if ( OE_in == 1 ) {
line = initialval ;
} // if
else {
line = initialval2 ;
} // else
}// if
// overflow control
else if((BOTH_in == 1) // in case of interlace, both fileds
&& ( ((OE_in == 1 ) && ( line >= maxval_half))
|| ((OE_in == 0 ) && ( line >= maxval_half2)) ) ) {
line = 1 ; // interlace both fiels overflow, line count
} // elseif
else if( line >= maxval ) { // in case of Odd or Even
line = 1 ;
} // else if
else {
line = line ++ ;
} // else
// update TRIG_bar
TRIG_bar_out = ( line == target_line ) ? 0 : 1 ;
// debug
spare = 0 ;
// To Do end of interrupt
INTF = 0 ;
}
void get_target_line(void)
{
target_line = target_line_offset + ( targetline_in & 0x1f);
}
void decode( short total_lines )
{
// decoder for maxval , initialval, D1,D2 ...
unsigned char reduced_total ;
reduced_total = (total_lines >> 5) & 0x3f ;
switch ( reduced_total ) {
case 0b001000 : // 'b00_1000 : // D1 480i
LED0_out = 1 ;
LED1_out = 0 ;
maxval = 525 ;
maxval_half = 525 / 2 + 1 ;
maxval_half2 = 525 / 2 ;
initialval = 6 ;
initialval2 = 5 ;
break ;
case 0b010000 : // 'b01_0000 : begin
//D_o <= 5'b0_0010 ; // D2 480p
LED0_out = 0 ;
LED1_out = 1 ;
maxval = 525 ;
maxval_half = 525 ;
maxval_half2 = 525 ;
initialval = 9 ;
initialval2 = 9 ;
break ;
case 0b010001 : // 'b01_0001 : begin // D3 1080i
LED0_out = 0 ;
LED1_out = 1 ;
maxval = 1125 ;
maxval_half = 1125 /2 + 1 ;
maxval_half2 = 1125 /2 ;
initialval = 3 ;
initialval2 = 2 ;
break ;
case 0b010111 : // 'b01_0111 : begin // D4 720p
LED0_out = 1 ;
LED1_out = 1 ;
maxval = 750 ;
maxval_half = 750 ;
maxval_half2 = 750 ;
initialval = 3 ;
initialval2 = 3 ;
break ;
case 0b100011 : // 'b10_0011 : begin // D5 1080p
LED0_out = 0 ;
LED1_out = 0 ;
maxval = 1125 ;
maxval_half = 1125 ;
maxval_half2 = 1125 ;
initialval = 3 ;
initialval2 = 3 ;
break ;
default : // begin
// D_o <= 5'b0_0000 ; // out of range
LED0_out = LED1_out = blink ;
maxval = 0 ;
maxval_half = 0 ;
initialval = 0 ;
initialval2 = 0 ;
break ;
}
}
void wait0( short delay)
{
short i ;
for( i = 0 ; i < delay ; i++ ) {
;
}
}
void
main(void)
{
short total_lines ;
// setup hardware
CMCON = 0x07 ;
TRISA = 0x3f ;
// RA5-0 for input
// RB0 --> HSYNC_bar_in
// RB1 --> VSYNC_bar_in
// RB2 --> OE_in
// RB3 --> Both_in
// RB4 --> TRIG_out
// RB5 --> LED0_out
// RB6 --> LED1_out
// RB7 --> spare tentative output
TRISB = 0x0f ; // 0000_1111
OPTION = 0x40 ; // 0100_0000
// setup for interrupt
INTF = 0 ;
INTE = 1 ;
// init globals
blink = 0 ;
count = 0 ;
total = 0 ;
decode( 0 ) ;
get_target_line() ;
// enable interrupt
GIE = 1 ;
while (1){
// debug
//spare = 1 ;
// WAIT
wait0( 2400 ) ;
// debug
//spare = 0 ;
GIE = 0 ;
total_lines = total ;
GIE = 1 ;
if( total_lines != 0 ) { // locked
GIE = 0 ;
total = 0 ;
GIE = 1 ;
}
decode( total_lines) ;
blink = !blink ;
get_target_line() ;
}
}