📄 md.c
字号:
u8 g1p_md_get_max_difference(void)
{
xdata u8 tmp;
tmp = g1pMDreg_read(MD_DMAXH); // maximum difference for mean variant
tmp = g1pMDreg_read(MD_DMAXL); // maximum difference for mean
return tmp;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
void g1p_md_reg_set_area(BYTE ch)
{
BYTE bk, pos;
BYTE areas[2][4];
BYTE reg_base;
#ifdef DEBUG_G1PMD_AREA
printf("\n\rCH[%d]", (int)ch);
#endif
// convert 2 block position information (x,y) into 16 x 32 font based position information
for(bk=0;bk<2;bk++) // for two block
{
#ifdef DEBUG_G1PMD_AREA
printf("blk%d ", (int)bk);
#endif
for(pos=0;pos<4;pos++)
{
areas[bk][pos] = mdgv_md_areas[ch][bk][pos]; // X position
#ifdef DEBUG_G1PMD_AREA
printf("(%2d,", (int)areas[bk][pos]);
#endif
pos++;
areas[bk][pos] = g1p_conv_16x24_to_16x32(mdgv_md_areas[ch][bk][pos]); // Y position
#ifdef DEBUG_G1PMD_AREA
printf("%2d) ", (int)areas[bk][pos]);
#endif
}
}
// set the changed position information into G1P MD part
reg_base = ch*0x10;
// write first MD block of G1P
g1pMDreg_write(reg_base+0x00, areas[0][1]); // Y1
g1pMDreg_write(reg_base+0x01, areas[0][0]); // X1
g1pMDreg_write(reg_base+0x02, areas[0][3]); // Y2
g1pMDreg_write(reg_base+0x03, areas[0][2]); // X2
// write second MD block of G1P
g1pMDreg_write(reg_base+0x04, areas[1][1]); // Y3
g1pMDreg_write(reg_base+0x05, areas[1][0]); // X3
g1pMDreg_write(reg_base+0x06, areas[1][3]); // Y4
g1pMDreg_write(reg_base+0x07, areas[1][2]); // X4
}
///////////////////////////////////////////////////////////
// NTSC system (720x480)
// 16x24 font based: x(0~44) y(0~19)
// 16x32 font based: x(0~44) y(0~14)
//
// PAL system (720x576)
// 16x24 font based: x(0~44) y(0~23)
// 16x32 font based: x(0~44) y(0~17)
//
///////////////////////////////////////////////////////////
u8 g1p_conv_16x24_to_16x32(u8 y)
{
u8 r,m;
u8 pix_y;
u8 bottom_line;
bottom_line = gv_NTSC_PAL ? 17:14;
// the result pix_y will be close to 16 x 32 font based position
r = y % 4;
if(r==2) r = 1;
else if(r==3) r = 2;
else ;
m = y / 4;
pix_y = m * 3 + r;
if(pix_y > bottom_line)
pix_y = bottom_line;
return (u8)pix_y;
}
///////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
void g1p_md_enable(BOOL enable)
{
xdata BYTE i;
xdata BYTE mn; // mean
xdata BYTE mv; // mean variant
mdgv_md_active_ch_stat = 0;
for(i=0;i<4;i++)
{
mn = mv = 0; // default value
if(enable)
{
// if now enabling and the channel is enabled
mn = (mdgvp_md_sensitivity_level_set[mdgv_md_sensitivity_levels[i]]&0xF0)>>4;
mv = mdgvp_md_sensitivity_level_set[mdgv_md_sensitivity_levels[i]]&0x0F;
// set activation status for each channel
// if both mn and mv are zero -> the channel is disabled
if(mn+mv)
mdgv_md_active_ch_stat |= (0x01)<<i;
}
// write registers
g1pMDreg_write(i*0x10+0x08, mn);
g1pMDreg_write(i*0x10+0x09, mv);
}
mdgv_md_enabled = (mdgv_md_active_ch_stat==0)?0:1;
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
BOOL g1p_md_is_detected(u8 cmd)
{
static xdata u8 is_FirstMdDetected[4] = {1,1,1,1};
static xdata u16 s_blk_cnt[4] = {0,0,0,0};
static xdata u8 s_diff[4] = {0,0,0,0};
xdata u8 i;
xdata BYTE detected_ch_num; // 0,1,2,3
xdata WORD blk_cnt;
xdata BYTE max_diff;
if(cmd==MD_CLEAR_OLD_REG_V)
{
for(i=0;i<4;i++)
{
is_FirstMdDetected[i] = 1;
s_blk_cnt[i] = 0;
s_diff[i] = 0;
}
}
mdgv_channel_detected = 0;
blk_cnt = g1p_md_get_block_count(&detected_ch_num);
max_diff = g1p_md_get_max_difference();
if(is_FirstMdDetected[detected_ch_num])
{
is_FirstMdDetected[detected_ch_num] = 0; // At the first case, we just save the current MD reg values
#ifdef DEBUG_MD_DETECT
printf("\n\rG1PMD= blk[%04x] diff[%02x] ch[%02x]", blk_cnt, (u16)max_diff, (u16)detected_ch_num);
#endif
}
else // check the difference from the previous values
{
if((s_blk_cnt[detected_ch_num]!= blk_cnt)||(s_diff[detected_ch_num]!= max_diff))
{
mdgv_channel_detected = 0x01 << detected_ch_num;
#ifdef DEBUG_MD_DETECT
printf("\n\rG1PMD: blk[%04x] diff[%02x] ch[%02x]", blk_cnt, (u16)max_diff, (u16)detected_ch_num);
#endif
}
}
// update current blk_cnt number
s_blk_cnt[detected_ch_num] = blk_cnt;
s_diff[detected_ch_num] = max_diff;
return (mdgv_channel_detected==0)?0:1;
}
//==============================================================================
// Access G1P MD register
//==============================================================================
void g1pMDreg_write(u8 addr, u8 value)
{
MD_ADDRESS_REGISTER = addr;
MD_DATA_REGISTER = value;
}
u8 g1pMDreg_read(u8 addr)
{
u8 value;
MD_ADDRESS_REGISTER = addr;
value = MD_DATA_REGISTER;
return value;
}
#endif // G1PMD
#ifdef TW2804
//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
void tw2804_md_reg_set_area(BYTE ch)
{
BYTE i,j,x,y;
#ifdef VY_MD_DEBUG_AREA
WORD temp[2][4];
#endif
BYTE areas[2][4];
BYTE mask[3];
// convert coordination
for(i=0;i<2;i++)
{
for(j=0;j<4;j++)
{
#ifdef VY_MD_DEBUG_AREA
temp[i][j] = (mdgv_md_areas[ch][i][j]+((j&0x02)?1:0))*((j&0x01)?24:16)+((j&0x02)?-1:0);
#endif
areas[i][j] = ((mdgv_md_areas[ch][i][j]+((j&0x02)?1:0))*((j&0x01)?24:16)+((j&0x02)?-1:0))/((j&0x01)?(gv_NTSC_PAL?48:40):60);
}
}
#ifdef VY_MD_DEBUG_AREA
for(i=0;i<2;i++)
{
printf("\r\nch %d [%2u,%2u-%2u,%2u] -> [%3u,%3u-%3u,%3u] [%X,%X-%X,%X]",
(WORD)ch,(WORD)mdgv_md_areas[ch][i][0], (WORD)mdgv_md_areas[ch][i][1], (WORD)mdgv_md_areas[ch][i][2], (WORD)mdgv_md_areas[ch][i][3],
temp[i][0], temp[i][1], temp[i][2], temp[i][3], (WORD)areas[i][0], (WORD)areas[i][1], (WORD)areas[i][2], (WORD)areas[i][3]);
}
printf("\r\n 0 1 2 3 4 5 6 7 8 9 A B");
#endif
for(i=0;i<6;i++)
{ // process 2 rows at a time covers all 12 lines
// default = masking all blocks
mask[0] = mask[1] = mask[2] = 0xFF;
for(j=0;j<2;j++)
{ // process 2 rows at a time
// calculate row index
y = i*2 + j;
for(x=0;x<12;x++)
{ // sweep a row
if( (areas[0][0]<=x && x<=areas[0][2] && areas[0][1]<=y && y<=areas[0][3]) ||
(areas[1][0]<=x && x<=areas[1][2] && areas[1][1]<=y && y<=areas[1][3]))
{ // when a block should be enabled,
if(x<8)
{
mask[j] &= ~(0x01<<x);
}
else
{
mask[2] &= ~((j?0x10:0x01)<<(x-8));
}
}
}
}
#ifdef VY_MD_DEBUG_AREA
printf("\r\n %c %c %c %c %c %c %c %c %c %c %c %c",
(mask[0]&0x01)?'1':'0', // 0
(mask[0]&0x02)?'1':'0', // 1
(mask[0]&0x04)?'1':'0', // 2
(mask[0]&0x08)?'1':'0', // 3
(mask[0]&0x10)?'1':'0', // 4
(mask[0]&0x20)?'1':'0', // 5
(mask[0]&0x40)?'1':'0', // 6
(mask[0]&0x80)?'1':'0', // 7
(mask[2]&0x01)?'1':'0', // 8
(mask[2]&0x02)?'1':'0', // 9
(mask[2]&0x04)?'1':'0', // 10
(mask[2]&0x08)?'1':'0');// 11
printf("\r\n %c %c %c %c %c %c %c %c %c %c %c %c",
(mask[1]&0x01)?'1':'0', // 0
(mask[1]&0x02)?'1':'0', // 1
(mask[1]&0x04)?'1':'0', // 2
(mask[1]&0x08)?'1':'0', // 3
(mask[1]&0x10)?'1':'0', // 4
(mask[1]&0x20)?'1':'0', // 5
(mask[1]&0x40)?'1':'0', // 6
(mask[1]&0x80)?'1':'0', // 7
(mask[2]&0x10)?'1':'0', // 8
(mask[2]&0x20)?'1':'0', // 9
(mask[2]&0x40)?'1':'0', // 10
(mask[2]&0x80)?'1':'0');// 11
#endif
tw2804_write(MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch+MD_2804_MDMASK1+i*3, mask[0]);
tw2804_write(MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch+MD_2804_MDMASK1+i*3+1, mask[2]);
tw2804_write(MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch+MD_2804_MDMASK1+i*3+2, mask[1]);
}
}
///////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
void tw2804_md_enable(BOOL enable)
{
xdata BYTE ch;
xdata BYTE int_mask;
// clear interrupt if raised
tw2804_write(MD_2804_REG_IRQCLR,0x0F); // clear only MD interrupt
mdgv_md_active_ch_stat = 0;
if(enable)
{
for(ch=0;ch<4;ch++)
{
#ifdef VY_MD_DEBUG_REG_RW
printf("\r\n[ch %u]",(WORD)ch);
#endif
tw2804_write((BYTE)(MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch), (BYTE)mdgvp_md_sensitivity_level_set[mdgv_md_sensitivity_levels[ch]]);
#ifdef VY_MD_DEBUG_REG_RW
printf("\r\n Sensitivity at 0x%02X, 0x%02X - 0x%02X",
(WORD)MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch, (WORD)mdgvp_md_sensitivity_level_set[mdgv_md_sensitivity_levels[ch]], (WORD)tw2804_read(MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch) );
#endif
tw2804_write((BYTE)(MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch+MD_2804_MPERIOD), (BYTE)MD_MPERIOD);
#ifdef VY_MD_DEBUG_REG_RW
printf("\r\n Period at 0x%02X, 0x%02X - 0x%02X",
(WORD)MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch+MD_2804_MPERIOD, (WORD)MD_MPERIOD, (WORD)tw2804_read(MD_2804_REG_CH_BASE+MD_2804_CH_SPACE*ch+MD_2804_MPERIOD));
#endif
if(mdgv_md_sensitivity_levels[ch])
mdgv_md_active_ch_stat |= (0x01)<<ch;
}
}
tw2804_write(MD_2804_REG_IRQCLR,0x0F); // clear only MD interrupt
int_mask = tw2804_read(MD_2804_REG_IRQENA);
tw2804_write(MD_2804_REG_IRQENA, (mdgv_md_active_ch_stat&0x0F)|(int_mask&0xF0));
mdgvp_channel_enable_mask = mdgv_md_active_ch_stat;
#ifdef VY_MD_DEBUG_REG_RW
printf("\r\n[ENABLE - 0x%02X] 0x%02X - 0x%02X",
(WORD)tw2804_read(MD_2804_REG_IRQCLR), (WORD)mdgv_md_active_ch_stat, (WORD)tw2804_read(MD_2804_REG_IRQENA));
#endif
#ifdef DEBUG_MD
{
u8 tmp = tw2804_read(MD_2804_REG_IRQENA);
printf("\n\rMD: IRQENA = %c %c %c %c", (tmp&0x01)?'O':'x', (tmp&0x02)?'O':'x', (tmp&0x04)?'O':'x', (tmp&0x08)?'O':'x');
}
#endif
mdgv_md_enabled = enable; // Steve add
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
BOOL tw2804_md_is_detected(void)
{
xdata BYTE temp;
xdata BYTE int_mask;
#ifdef VY_MD_DEBUG_INT
static xdata BYTE counter=0;
#endif
mdgv_channel_detected = 0;
if(INT_2804 == HIGH)
{
#ifdef USE_4954_GP
temp = cs4954_read(0x0A);
#endif
mdgv_channel_detected = mdgv_md_active_ch_stat&(temp>>4);
// clear interrupt
tw2804_write(MD_2804_REG_IRQCLR,mdgv_channel_detected&0x0F);
if(mdgv_channel_detected)
{
mdgvp_channel_enable_mask &= ~mdgv_channel_detected;
// disable detected channel - enabled when recording completed
int_mask = tw2804_read(MD_2804_REG_IRQENA);
tw2804_write(MD_2804_REG_IRQENA, (mdgvp_channel_enable_mask&0x0F)|(int_mask&0xF0));
#ifdef VY_MD_DEBUG_INT
printf("\r\nINT[0x%02X] 4954[0x%02X] channel[0x%02X] [[0x%02X]]",
(WORD)counter++, (WORD)temp, (WORD)mdgv_channel_detected, (WORD)tw2804_read(MD_2804_REG_IRQENA) );
#endif
#ifdef DEBUG_MD
{
u8 tmp = tw2804_read(MD_2804_REG_IRQENA);
printf("\n\rMD: IRQENAi= %c %c %c %c",
(tmp&0x01)?'O':'x',
(tmp&0x02)?'O':'x',
(tmp&0x04)?'O':'x',
(tmp&0x08)?'O':'x'
);
}
#endif
return TRUE;
}
}
return FALSE;
}
#endif // TW2804
#endif //end of VY_MD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -