nedoPC.org

Electronics hobbyists community established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 28 Mar 2024 16:30



Reply to topic  [ 146 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7, 8 ... 10  Next
Плата центрального недопроцессора nedoCPU-32 
Author Message
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22412
Location: Silicon Valley
Reply with quote
т.е. по сути тут мы имеем 32 цвета, которые процессор современного телевизора умеет смешивать, если они попадаются в соседних строках - в результате получается 16x16=256 цветов (часть из которых повторяется, но не суть) - вот исходник генератора полной таблички цветов и фотка:
 исходник тут
Code:
/*******************************************************************
 * Modified by A.A.Shabarshin (March-April 2015)
 * Optimized, recalculated to 14.31818 MHz and added colors
 *
 * Original code was taken from "NTSC TV interface" examples:
 * http://hackaday.io/project/2032-pic32-oscilloscope
 * Bruce Land Cornell University
 * June 2014
 * "This code uses many cool ideas from
 * Programming 32-bit Microcontrollers in C: Exploring the PIC32
 * by Lucio Di Jasio"
 *
 * Uses two Compare units from one timer to do sync and video timing
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * VIDEO is PortA.1
 * SYNC  is PortB.1
 *
 */

#include <plib.h>
#include <xc.h> // need for pps
#include <stdio.h>
#include <stdlib.h>

#define NOBACKGROUND
#define NOFONT

#if 0
#define  SYS_FREQ 60000000
//                      8MHZ                          4MHz               60MHz            30   <-----<---    60MHz
#pragma config FNOSC = FRCPLL, POSCMOD = OFF, FPLLIDIV = DIV_2, FPLLMUL = MUL_15, FPBDIV = DIV_2, FPLLODIV = DIV_1
#else
#define  SYS_FREQ 57272720
//                     14.31818MHZ                      3.579545MHz      57.27272MHz      28.63636  <-----<--- 57.27272MHz
#pragma config FNOSC = PRIPLL, POSCMOD = HS, FPLLIDIV = DIV_4, FPLLMUL = MUL_16, FPBDIV = DIV_2, FPLLODIV = DIV_1
#endif
#pragma config FWDTEN = OFF
#pragma config FSOSCEN = OFF, JTAGEN = OFF

#define PITCH 23
#define OFFSET 96
#define TOFFSET (OFFSET/8)
#define DX (OFFSET+640)
#define DY (200)
#define SCREENSZ (DX*DY/32)
int screen_buffer[SCREENSZ] ;
volatile int *screen_buffer_addr = screen_buffer ;
volatile int *screen_ptr ;

// The DMA channels
#define DMAchn1 1
#define DMApri0 0

// video timing
#define line_cycles 1818 // 63.5 uSec at 28.6 MHz Fpb, prescaler=1
#define line_offset  159 // offset to start video screen
#define us_5_cycles  135 // 5 uSec at 28.6 MHz Fpb, prescaler=1

// video active lines -- 200 total
#define image_start 20
#define image_end (image_start+DY)
#define top 0
#define left 0
#define right 639
#define bottom 199

// Current line number which is modified
// by a state machine in the timer2 ISR
volatile int LineCount = 0 ;
// ISR driven 1/60 second time
volatile int time_tick_60_hz = 0 ;
// ISR driven seconds counter
volatile int time_seconds = 0;
// Absolute frame counter
volatile unsigned long time_frames = 0;

#ifndef NOFONT
#include "nedofont.h"
#endif
#ifndef NOBACKGROUND
#include "cgatrick.xbm"
#endif

#define WAIT 180 // wait 3 seconds before starting video

// == OC3 ISR ============================================
// VECTOR 14 is OC3 vector -- set up of ipl3 in main
// vector names from int_1xx_2xx.h
void __ISR(14, ipl3) OC3Handler(void) // 14
{
    if(time_frames>WAIT){
    // mPORTBSetBits(BIT_1);
    // Convert DMA to SPI control
    DmaChnSetEventControl(DMAchn1, DMA_EV_START_IRQ(_SPI1_TX_IRQ)); //
    //DmaChnEnable(DMAchn1);
    // clear the timer interrupt flag -- name from
    // http://people.ece.cornell.edu/land/courses/ece4760/PIC32/Microchip_stuff/32-bit-Peripheral-Library-Guide.pdf
    // Table 8.2
    mOC3ClearIntFlag();
   // mPORTBClearBits(BIT_1);  // for profiling the ISR execution time
    }
}

volatile short sound[]={
750,785,821,856,891,926,961,995,1028,1061,1093,1124,1155,1185,1213,1241,
1267,1292,1316,1339,1360,1380,1399,1416,1432,1446,1458,1469,1478,1486,1492,1496,
1499,1499,1499,1496,1492,1486,1478,1469,1458,1446,1432,1416,1399,1380,1360,1339,
1316,1292,1267,1241,1213,1185,1155,1125,1093,1061,1028,995,961,926,891,856,
821,785,750,714,678,643,608,573,538,504,471,438,406,375,344,314,
286,258,232,207,183,160,139,119,100,83,67,53,41,30,21,13,
7,3,0,0,0,3,7,13,21,30,41,53,67,83,100,119,
139,160,183,207,232,258,286,314,344,374,406,438,471,504,538,573,
608,643,678,714,749,785,821,856,891,926,961,995,1028,1061,1093,1124,
1155,1185,1213,1241,1267,1292,1316,1339,1360,1380,1399,1416,1432,1446,1458,1469,
1478,1486,1492,1496,1499,1499,1499,1496,1492,1486,1478,1469,1458,1446,1432,1416,
1399,1380,1360,1339,1316,1292,1267,1241,1213,1185,1155,1125,1093,1061,1028,995,
961,926,891,856,821,785,750,714,678,643,608,573,538,504,471,438,
406,375,344,314,286,258,232,207,183,160,139,119,100,83,67,53,
41,30,21,13,7,3,0,0,0,3,7,13,21,30,41,53,
67,83,100,119,139,160,183,207,232,258,286,314,344,374,406,438,
471,504,538,573,608,643,678,714
};


// == Timer 2 ISR =========================================
void __ISR(_TIMER_2_VECTOR, ipl2) Timer2Handler(void)
{
    //mPORTBSetBits(BIT_1); // for profiling the ISR execution time
    // update the current scanline number
    LineCount++ ;
/*
//    OpenOC5(OC_ON | OC_TIMER2_SRC | OC_CONTINUE_PULSE, line_offset+18+sound[LineCount], line_offset+12);
    if(LineCount >= image_start + 20 && LineCount < image_end - 100)
      OpenOC5(OC_ON | OC_TIMER2_SRC | OC_SINGLE_PULSE, line_offset+300, line_offset+200);
    else
      CloseOC5(); 
*/       
    // start the DMA byte blaster to the screen
    if (LineCount >= image_start && LineCount < image_end){
        if(time_frames>WAIT){
        // set the Chan1 DMA transfer parameters: source & destination address,
        // source & destination size, number of bytes per event
        // 32 bytes / line with 4 bytes per transfer (SPI in 32 bit mode)
        //screen_ptr = screen_buffer + ((LineCount - image_start)<<5) ;
        DmaChnSetTxfer(DMAchn1, (void*)screen_ptr, (void*)&SPI1BUF, 92, 4, 4);
        // IRO 17 is the output compare 3 interrupt (See datasheet table 7.1)
        DmaChnSetEventControl(DMAchn1, DMA_EV_START_IRQ(17)); //
        // turn it on for 32 bytes
        DmaChnEnable(DMAchn1);
        }
        // increment the image memory pointer for the next ISR pass
        screen_ptr += PITCH; // PITCH 32-bit words per line
    }
    // update the frame time_tick immediately after image is copied
    else if(LineCount==image_end)
    {
        // a general propose time base
        if((++time_tick_60_hz%60)==0) time_seconds++;       
    }
    // == SYNC state machine ====
    // begin long (Vertical) synch after line 247
    else if (LineCount==248) {OC2R = line_cycles - us_5_cycles ;}
    // back to regular sync after line 250
    // the first condition eliminates sync for one line (to avoid duplicate)
    else if (LineCount==250) {OC2R = 0 ;}
    else if (LineCount==251) {OC2R = us_5_cycles ;}
    // start new frame after line 262 and reset the image memory pointer
    else if (LineCount==263) {
        LineCount = 1;
        // reset for the next frame
        screen_ptr = screen_buffer_addr;
       
        time_frames++;
    }
   
    // clear the timer interrupt flag
    mT2ClearIntFlag();
    //mPORTBClearBits(BIT_1);  // for profiling the ISR execution time
}

//== plot a point =========================================================
//plot one point
//at x,y with color 1=white 0=black 2=invert
void video_pt(int x, int y, char c) {
   //calculate i based upon this and x,y
   // the word with the pixel in it
   //int i = (x/32) + y*PITCH
   x += OFFSET;
   if (c==1)
     screen_buffer[(x >> 5) + (y * PITCH)] |= 1<<(31-(x & 0x1f));
    else if (c==0)
     screen_buffer[(x >> 5) + (y * PITCH)] &= ~(1<<(31-(x & 0x1f)));
    else // c==2
     screen_buffer[(x >> 5) + (y * PITCH)] ^= 1<<(31-(x & 0x1f));
}

//==================================
//plot a line
//at x1,y1 to x2,y2 with color 1=white 0=black 2=invert
//NOTE: this function requires signed chars
//Code is from David Rodgers,
//"Procedural Elements of Computer Graphics",1985
void video_line(int x1, int y1, int x2, int y2, char c) {
   int e;
   signed int dx,dy,j, temp;
   signed char s1,s2, xchange;
        signed int x,y;

   x = x1;
   y = y1;

   //take absolute value
   if (x2 < x1) {
      dx = x1 - x2;
      s1 = -1;
   }

   else if (x2 == x1) {
      dx = 0;
      s1 = 0;
   }

   else {
      dx = x2 - x1;
      s1 = 1;
   }

   if (y2 < y1) {
      dy = y1 - y2;
      s2 = -1;
   }

   else if (y2 == y1) {
      dy = 0;
      s2 = 0;
   }

   else {
      dy = y2 - y1;
      s2 = 1;
   }

   xchange = 0;

   if (dy>dx) {
      temp = dx;
      dx = dy;
      dy = temp;
      xchange = 1;
   }

   e = ((int)dy<<1) - dx;

   for (j=0; j<=dx; j++) {
      video_pt(x,y,c);

      if (e>=0) {
         if (xchange==1) x = x + s1;
         else y = y + s2;
         e = e - ((int)dx<<1);
      }

      if (xchange==1) y = y + s2;
      else x = x + s1;

      e = e + ((int)dy<<1);
   }
}

//==================================
//return the value of one point
//at x,y with color 1=white 0=black
char video_state(int x, int y) {
    //The following construction detects exactly one bit at the x,y location
    return (screen_buffer[((x+OFFSET) >> 5) + (y * PITCH)] & (1<<(31-(x & 0x1f))))?1:0 ;
}

//==================================
// put a big character on the screen
// c is index into bitmap
void video_putchar(int x, int y, int c) {
#ifndef NOFONT
    x += TOFFSET;
    int j = (x>>2)+(y<<3)*PITCH;
    int shf = (3-(x&3))<<3;
    int msk = ~(255<<shf);
    unsigned char *ptr = font8x8[c-32];
    screen_buffer[j]=(screen_buffer[j] & msk)|(*(ptr++)<<shf);j+=PITCH;
    screen_buffer[j]=(screen_buffer[j] & msk)|(*(ptr++)<<shf);j+=PITCH;
    screen_buffer[j]=(screen_buffer[j] & msk)|(*(ptr++)<<shf);j+=PITCH;
    screen_buffer[j]=(screen_buffer[j] & msk)|(*(ptr++)<<shf);j+=PITCH;
    screen_buffer[j]=(screen_buffer[j] & msk)|(*(ptr++)<<shf);j+=PITCH;
    screen_buffer[j]=(screen_buffer[j] & msk)|(*(ptr++)<<shf);j+=PITCH;
    screen_buffer[j]=(screen_buffer[j] & msk)|(*(ptr++)<<shf);j+=PITCH;
    screen_buffer[j]=(screen_buffer[j] & msk)|(*ptr<<shf);
#endif
}

//==================================
// put a string of big characters on the screen
void video_string(int x, int y, char *str) {
   char i;
   for (i=0; str[i]!=0; i++) {
      video_putchar(x++,y,str[i]);
   }
}

int* xolinedirect(int y){return &screen_buffer[PITCH*y+(OFFSET>>5)];}

// ========================================================================
int   main(void)
{
    int* iptr;
    float f;
    unsigned short us;
    unsigned long i,j,n,m,stored,maxstored=0;
    // global time
    int time, seconds, x, y, k, c, *p;
    char time_string[10],str[32];

   // Configure the device for maximum performance but do not change the PBDIV
   // Given the options, this function will change the flash wait states, RAM
   // wait state and enable prefetch cache but will not change the PBDIV.
   // The PBDIV value is already set via the pragma FPBDIV option above..
   SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);

   
    //make sure analog is cleared
    //ANSELA =0;
    //ANSELB =0;

    // timer interrupt //////////////////////////
    // Set up timer2 on,  interrupts, internal clock, prescalar 1, toggle rate
    // 63.5 microSec
    OpenTimer2(T2_ON | T2_SOURCE_INT | T2_PS_1_1, line_cycles);
    // set up the timer interrupt with a priority of 2
    ConfigIntTimer2(T2_INT_ON | T2_INT_PRIOR_2);
    mT2ClearIntFlag(); // and clear the interrupt flag

    // Compare match setup //////////////////////
    //Set up compare match unit to produce sync pulses
    // 5 uSec low
    // or 63.5-5 = 58.5 microSec (2340 ticks) low
    // pulse duration will be controlled in Timer2 ISR
    // #define OpenOC2( config, value1, value2) ( OC2RS = (value1), OC2R = (value2), OC2CON = (config) )
    OpenOC2(OC_ON | OC_TIMER2_SRC | OC_CONTINUE_PULSE, line_cycles-1, us_5_cycles);
    // OC2 is PPS group 2, map to RPB1 (pin 5)
    PPSOutput(2, RPB1, OC2);

    // OC3 setup /////////////////////////////////
    // Compare unit for video timing,
    // using the interrupt flag to trigger the first DMA,
    // then use the ISR to change the DMA control to SPI
    // #define OpenOC2( config, value1, value2) ( OC2RS = (value1), OC2R = (value2), OC2CON = (config) )
    // Pulse needs to be TWO cycles long
    OpenOC3(OC_ON | OC_TIMER2_SRC | OC_CONTINUE_PULSE, line_offset+2, line_offset);
    // turn on ISR so that DMA can covert to SPI control
    ConfigIntOC3(OC_INT_PRIOR_1 | OC_INT_ON); //3 //
    mOC3ClearIntFlag(); // and clear the interrupt flag

    // OC4 setup /////////////////////////////////
    OpenOC4(OC_ON | OC_TIMER2_SRC | OC_CONTINUE_PULSE, line_offset+40, line_offset+112);
    // OC4 is PPS group 3, map to RPB13 (pin 24)
    PPSOutput(3, RPB13, OC4);

    // OC5 setup /////////////////////////////////
    OpenOC5(OC_ON | OC_TIMER2_SRC | OC_CONTINUE_PULSE, line_cycles-200, line_cycles-100);
    // OC5 is PPS group 3, map to RPA2 (pin 9)
    PPSOutput(3, RPA2, OC5);
   
    // SPI configure /////////////////////////////
    // SCK1 is pin 25 RB14
    // SDO1 is PPS group 2, map to RPA1 (pin 3)
    // SDI1 is PPS group 2, map to RPB8 (pin 17) ???
    // SS1 input is PPS group 1, map to RPB7 (pin 16) for framing
    // specify PPS group, signal, logical pin name
    PPSInput (1, SS1, RPB7);
    PPSOutput(2, RPA1, SDO1);
    // control sync for DAC
    mPORTBSetPinsDigitalOut(BIT_0|BIT_2|BIT_3);
    mPORTBSetBits(BIT_0);
    mPORTBClearBits(BIT_2);
    mPORTBClearBits(BIT_3);

    // divide Fpb by N, configure the I/O ports. 32 bit transfer
    SpiChnOpen(SPI_CHANNEL1, SPI_OPEN_ON | SPI_OPEN_MODE32 | SPI_OPEN_MSTEN , 2); // N=6

    //=== DMA Channel 1 ================================
    // Open DMA Chan1 and chain from channel zero
    DmaChnOpen(DMAchn1, DMApri0, DMA_OPEN_DEFAULT);

    // setup system wide interrupts  ///
    INTEnableSystemMultiVectoredInt();

#ifndef NOBACKGROUND
    iptr = (int*)cgatrick_bits;
    for(i=0;i<SCREENSZ;i++)
    {
        k = iptr[i];
        c = 0;
        n = 1;
        m = 0x80000000;
        for(j=0;j<32;j++)
        {
          if(!(k&n)) c|=m;
          n <<= 1;
          m >>= 1;
        }
        screen_buffer[i] = c;
    }
#endif

// generate color burst

 p = screen_buffer;
 for(y=0;y<200;y++)
 {
     p[0] = 0x00000CCC;
     p[1] = 0xCCCCCC00;
     p += PITCH;
 }

// generate color chart
   
 for(y=0;y<192;y++)
 {
   if((y%12)==11) continue; // black lines between colors
   p = xolinedirect(y+4);
   j = y/12;
   for(x=0;x<16;x++)
   {
      if(y&1)
           p[x+4] = (x<<28)|(x<<24)|(x<<20)|(x<<16)|(x<<12)|(x<<8)|(x<<4);//|x;
      else p[x+4] = (j<<28)|(j<<24)|(j<<20)|(j<<16)|(j<<12)|(j<<8)|(j<<4);//|j;
   }
 }
   
   
#if 1
    // Draw the screen boundaries
    video_line(left,top, right,top, 1); // top
    video_line(right,top, right,bottom, 1); // right
    video_line(right,bottom, left,bottom, 1); // bottom
    video_line(left,top, left,bottom ,1); // left
#endif
    // Draw a title
    video_string(0,0,"nedoPC-32-A");
   
    seconds = stored = n = x = y = 0;
    c = 32;
    k = 0;
    srand(11111);
    while(1)
    {       
            n++;
#if 0
            // random characters
            k = rand();
            video_putchar(k%80,2+((k>>6)&15),++c);
            if(c==255) c=31;
#endif
#if 0
            // random lines
            k = rand();
            c = k&511; k=8+((k>>8)%184);
            video_line(x,y,c,k,2);
            x = c; y = k;
#endif
#if 0
            // random pixels
            k = rand();
            video_pt(k%640,8+((k>>9)%184),2);
#endif
            if(time != time_tick_60_hz)
            {
                time = time_tick_60_hz ;
                stored = n;
                if(n>maxstored) maxstored=n;
                n = 0;               
           
              if(seconds != time_seconds)
              {
                seconds = time_seconds;
                sprintf(time_string, "%d:%d",seconds,stored);
                video_string(0, 24, time_string);

                if(seconds&1)
                    mPORTBClearBits(BIT_2);
                else
                    mPORTBSetBits(BIT_2);

                if(seconds&2)
                    mPORTBClearBits(BIT_3);
                else
                    mPORTBSetBits(BIT_3);
              }
            }
    }

}


Attachments:
File comment: NTSC colors generated by PIC32
xorya-colors.jpg
xorya-colors.jpg [ 92.78 KiB | Viewed 11311 times ]

_________________
:dj: https://mastodon.social/@Shaos
06 Apr 2015 18:22
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22412
Location: Silicon Valley
Reply with quote
Вот восстановленные по фотке 32 основных цвета (могут быть большие погрешности):
Code:
/* EVEN LINES: */

/* 0000 */ RGB(  0,  0,  0), /* #000000 H=... S=.. V=0 */
/* 0001 */ RGB( 22, 21,187), /* #1615BB H=240 S=89 V=73 */
/* 0010 */ RGB(112, 26, 48), /* #701A30 H=345 S=77 V=44 */
/* 0011 */ RGB(117, 17,197), /* #7511C5 H=273 S=91 V=77 */
/* 0100 */ RGB( 38, 68, 23), /* #264417 H=100 S=66 V=27 */
/* 0101 */ RGB( 76, 65, 72), /* #4C4148 H=... S=.. V=30 */
/* 0110 */ RGB(136, 50, 15), /* #88320F H=17  S=89 V=53 */
/* 0111 */ RGB(154, 59, 77), /* #9A324D H=344 S=68 V=60 */
/* 1000 */ RGB( 10, 54, 47), /* #0A362F H=170 S=81 V=21 */
/* 1001 */ RGB(  7, 44,195), /* #072CC3 H=228 S=96 V=76 */
/* 1010 */ RGB( 62, 71, 87), /* #3E4757 H=... S=.. V=34 */
/* 1011 */ RGB( 45, 50,182), /* #2D32B6 H=238 S=75 V=71 */
/* 1100 */ RGB(  9,112, 42), /* #09702A H=139 S=92 V=44 */
/* 1101 */ RGB( 14,112,113), /* #0E7071 H=181 S=88 V=44 */
/* 1110 */ RGB( 55,109, 33), /* #376D21 H=103 S=70 V=43 */
/* 1111 */ RGB(110,113,121), /* #6E7179 H=... S=.. V=47 */

/* ODD LINES: */

/* 0000 */ RGB(  0,  0,  0), /* #000000 H=... S=.. V=0 */
/* 0001 */ RGB( 12,115, 37), /* #0C7325 H=135 S=90 V=45 */
/* 0010 */ RGB(  7, 58,178), /* #073AB2 H=222 S=96 V=70 */
/* 0011 */ RGB( 10,135,107), /* #0A876B H=167 S=93 V=53 */
/* 0100 */ RGB( 85, 31,131), /* #551F83 H=272 S=76 V=51 */
/* 0101 */ RGB( 95, 80, 84), /* #5F5054 H=... S=.. V=37 */
/* 0110 */ RGB( 28, 41,222), /* #1C29DE H=236 S=87 V=87 */
/* 0111 */ RGB( 44,104,167), /* #2C68A7 H=211 S=74 V=65 */
/* 1000 */ RGB(115, 37, 19), /* #732513 H=11  S=83 V=45 */
/* 1001 */ RGB(105,107, 38), /* #696B26 H=62  S=64 V=42 */
/* 1010 */ RGB( 96, 79, 77), /* #604F4D H=... S=.. V=38 */
/* 1011 */ RGB( 70,151, 56), /* #469738 H=111 S=63 V=59 */
/* 1100 */ RGB(182, 33,105), /* #B62169 H=331 S=82 V=71 */
/* 1101 */ RGB(173, 93, 62), /* #AD5D3E H=17  S=64 V=68 */
/* 1110 */ RGB(142, 72,179), /* #8E48B3 H=279 S=60 V=70 */
/* 1111 */ RGB(153,136,119), /* #998877 H=... S=.. V=60 */


H - это Hue, который можно воспринимать как угол фазы (правда в GIMP он меньше фазы NTSC на 120 градусов), которых на удивление много разных (для бесцветных серо-белых тонов H указывать не стал):

000-009 градусов: 0
010-019 градусов: 3 - E0110, O1000, O1101
020-029 градусов: 0
030-039 градусов: 0
040-049 градусов: 0
050-059 градусов: 0
060-069 градусов: 1 - O1001
070-079 градусов: 0
080-089 градусов: 0
090-099 градусов: 0
100-109 градусов: 2 - E0100, E1110
110-119 градусов: 1 - O1011
120-129 градусов: 0
130-139 градусов: 1 - E1100, O0001
140-149 градусов: 0
150-159 градусов: 0
160-169 градусов: 1 - O0011
170-179 градусов: 1 - E1000
180-189 градусов: 1 - E1101
190-199 градусов: 0
200-209 градусов: 0
210-219 градусов: 1 - O0111
220-229 градусов: 2 - E1001, O0010
230-239 градусов: 2 - E1011, O0110
240-249 градусов: 1 - E0001
250-259 градусов: 0
260-269 градусов: 0
270-279 градусов: 1 - E0011, O0100, O1110
280-289 градусов: 0
290-299 градусов: 0
300-309 градусов: 0
310-319 градусов: 0
320-329 градусов: 0
330-339 градусов: 1 - O1100
340-349 градусов: 2 - E0010, E0111
350-359 градусов: 0

Отсюда видно, что разница между чётными и нечётными строками составляет полторы четвертушки, или примерно 135 градусов...

P.S. DOOM в этой новой 256-цветной палитре и размером 160x100 будет выглядеть так:


Attachments:
File comment: DOOM 160x100 scaled
Doom-160x100-scaled.gif
Doom-160x100-scaled.gif [ 26.83 KiB | Viewed 11303 times ]

_________________
:dj: https://mastodon.social/@Shaos
06 Apr 2015 23:13
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22412
Location: Silicon Valley
Reply with quote
Shaos wrote:
Отсюда видно, что разница между чётными и нечётными строками составляет полторы четвертушки, или примерно 135 градусов...


Я понял в чём проблема - я неправильно выбрал длину строки - надо заменить 1818 на 1820 и тогда строка будет составлять 227.5 циклов основной частоты цвета - как и положено по стандарту NTSC (тогда чётные и нечётные строки будут отличаться на 180 градусов, а не на 135)

P.S. Сделал 1820 циклов основной частоты в строке и цвет ИСЧЕЗ!!! :-?

Никакие дальнейшие мухляжи с color-burst-ом не помогли - видимо неточность длины строки играла какую-то немаловажную роль (что значит, что я случайно угадал с первоначальным числом)...

_________________
:dj: https://mastodon.social/@Shaos


07 Apr 2015 16:31
Profile WWW
Fanat
User avatar

Joined: 18 Nov 2014 09:17
Posts: 52
Location: Отсюда
Reply with quote
А возврат к предыдущим настройкам возвратил цвет? потому что вполне может быть, что пошел дымок гденть внутри телевизора, и это отразилось как исчезновение цвета... ???


07 Apr 2015 22:33
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22412
Location: Silicon Valley
Reply with quote
 исходник тут
Code:
/*******************************************************************
 * Modified by A.A.Shabarshin (March-April 2015)
 * Optimized, recalculated to 14.31818 MHz and added colors
 *
 * Original code was taken from "NTSC TV interface" examples:
 * http://hackaday.io/project/2032-pic32-oscilloscope
 * Bruce Land Cornell University
 * June 2014
 * "This code uses many cool ideas from
 * Programming 32-bit Microcontrollers in C: Exploring the PIC32
 * by Lucio Di Jasio"
 *
 * Uses two Compare units from one timer to do sync and video timing
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * VIDEO is PortA.1
 * SYNC  is PortB.1
 *
 */

#include <plib.h>
#include <xc.h> // need for pps
#include <stdio.h>
#include <stdlib.h>

#define NOBACKGROUND
#define NOFONT

#if 0
#define  SYS_FREQ 60000000
//                      8MHZ                          4MHz               60MHz            30   <-----<---    60MHz
#pragma config FNOSC = FRCPLL, POSCMOD = OFF, FPLLIDIV = DIV_2, FPLLMUL = MUL_15, FPBDIV = DIV_2, FPLLODIV = DIV_1
#else
#define  SYS_FREQ 57272720
//                     14.31818MHZ                      3.579545MHz      57.27272MHz      28.63636  <-----<--- 57.27272MHz
#pragma config FNOSC = PRIPLL, POSCMOD = HS, FPLLIDIV = DIV_4, FPLLMUL = MUL_16, FPBDIV = DIV_2, FPLLODIV = DIV_1
#endif
#pragma config FWDTEN = OFF
#pragma config FSOSCEN = OFF, JTAGEN = OFF

#define PITCH 23
#define OFFSET 96
#define TOFFSET (OFFSET/8)
#define DX (OFFSET+640)
#define DY (200)
#define SCREENSZ (DX*DY/32)
int screen_buffer[SCREENSZ] ;
volatile int *screen_buffer_addr = screen_buffer ;
volatile int *screen_ptr ;

// The DMA channels
#define DMAchn1 1
#define DMApri0 0

// video timing
#define line_cycles 1823 // 63.5 uSec at 28.6 MHz Fpb (it must be 227.5 cycles of subcarrier freq)
#define line_offset  168 // offset to start video screen (with color burst for color mode)
#define us_5_cycles  135 // 4.7 uSec at 28.6 MHz Fpb, prescaler=1

// video active lines -- 200 total
#define image_start 20
#define image_end (image_start+DY)
#define top 0
#define left 0
#define right 639
#define bottom 199

// Current line number which is modified
// by a state machine in the timer2 ISR
volatile int LineCount = 0 ;
// ISR driven 1/60 second time
volatile int time_tick_60_hz = 0 ;
// ISR driven seconds counter
volatile int time_seconds = 0;
// Absolute frame counter
volatile unsigned long time_frames = 0;

#ifndef NOFONT
#include "nedofont.h"
#endif
#ifndef NOBACKGROUND
#include "cgatrick.xbm"
#endif

#define WAIT 180 // wait 3 seconds before starting video

// == OC3 ISR ============================================
// VECTOR 14 is OC3 vector -- set up of ipl3 in main
// vector names from int_1xx_2xx.h
void __ISR(14, ipl3) OC3Handler(void) // 14
{
    if(time_frames>WAIT){
    // mPORTBSetBits(BIT_1);
    // Convert DMA to SPI control
    DmaChnSetEventControl(DMAchn1, DMA_EV_START_IRQ(_SPI1_TX_IRQ)); //
    //DmaChnEnable(DMAchn1);
    // clear the timer interrupt flag -- name from
    // http://people.ece.cornell.edu/land/courses/ece4760/PIC32/Microchip_stuff/32-bit-Peripheral-Library-Guide.pdf
    // Table 8.2
    mOC3ClearIntFlag();
   // mPORTBClearBits(BIT_1);  // for profiling the ISR execution time
    }
}

volatile short sound[]={
750,785,821,856,891,926,961,995,1028,1061,1093,1124,1155,1185,1213,1241,
1267,1292,1316,1339,1360,1380,1399,1416,1432,1446,1458,1469,1478,1486,1492,1496,
1499,1499,1499,1496,1492,1486,1478,1469,1458,1446,1432,1416,1399,1380,1360,1339,
1316,1292,1267,1241,1213,1185,1155,1125,1093,1061,1028,995,961,926,891,856,
821,785,750,714,678,643,608,573,538,504,471,438,406,375,344,314,
286,258,232,207,183,160,139,119,100,83,67,53,41,30,21,13,
7,3,0,0,0,3,7,13,21,30,41,53,67,83,100,119,
139,160,183,207,232,258,286,314,344,374,406,438,471,504,538,573,
608,643,678,714,749,785,821,856,891,926,961,995,1028,1061,1093,1124,
1155,1185,1213,1241,1267,1292,1316,1339,1360,1380,1399,1416,1432,1446,1458,1469,
1478,1486,1492,1496,1499,1499,1499,1496,1492,1486,1478,1469,1458,1446,1432,1416,
1399,1380,1360,1339,1316,1292,1267,1241,1213,1185,1155,1125,1093,1061,1028,995,
961,926,891,856,821,785,750,714,678,643,608,573,538,504,471,438,
406,375,344,314,286,258,232,207,183,160,139,119,100,83,67,53,
41,30,21,13,7,3,0,0,0,3,7,13,21,30,41,53,
67,83,100,119,139,160,183,207,232,258,286,314,344,374,406,438,
471,504,538,573,608,643,678,714
};


// == Timer 2 ISR =========================================
void __ISR(_TIMER_2_VECTOR, ipl2) Timer2Handler(void)
{
    //mPORTBSetBits(BIT_1); // for profiling the ISR execution time
    // update the current scanline number
    LineCount++ ;
/*
//    OpenOC5(OC_ON | OC_TIMER2_SRC | OC_CONTINUE_PULSE, line_offset+18+sound[LineCount], line_offset+12);
    if(LineCount >= image_start + 20 && LineCount < image_end - 100)
      OpenOC5(OC_ON | OC_TIMER2_SRC | OC_SINGLE_PULSE, line_offset+300, line_offset+200);
    else
      CloseOC5(); 
*/       
    // start the DMA byte blaster to the screen
    if (LineCount >= image_start && LineCount < image_end){
        if(time_frames>WAIT){
        // set the Chan1 DMA transfer parameters: source & destination address,
        // source & destination size, number of bytes per event
        // 32 bytes / line with 4 bytes per transfer (SPI in 32 bit mode)
        //screen_ptr = screen_buffer + ((LineCount - image_start)<<5) ;
        DmaChnSetTxfer(DMAchn1, (void*)screen_ptr, (void*)&SPI1BUF, 92, 4, 4);
        // IRO 17 is the output compare 3 interrupt (See datasheet table 7.1)
        DmaChnSetEventControl(DMAchn1, DMA_EV_START_IRQ(17)); //
        // turn it on for 32 bytes
        DmaChnEnable(DMAchn1);
        }
        // increment the image memory pointer for the next ISR pass
        screen_ptr += PITCH; // PITCH 32-bit words per line
    }
    // update the frame time_tick immediately after image is copied
    else if(LineCount==image_end)
    {
        // a general propose time base
        if((++time_tick_60_hz%60)==0) time_seconds++;       
    }
    // == SYNC state machine ====
    // begin long (Vertical) synch after line 247
    else if (LineCount==248) {OC2R = line_cycles - us_5_cycles ;}
    // back to regular sync after line 250
    // the first condition eliminates sync for one line (to avoid duplicate)
    else if (LineCount==250) {OC2R = 0 ;}
    else if (LineCount==251) {OC2R = us_5_cycles ;}
    // start new frame after line 262 and reset the image memory pointer
    else if (LineCount==263) {
        LineCount = 1;
        // reset for the next frame
        screen_ptr = screen_buffer_addr;
        // increment frame counter
        ++time_frames;
    }
   
    // clear the timer interrupt flag
    mT2ClearIntFlag();
    //mPORTBClearBits(BIT_1);  // for profiling the ISR execution time
}

//== plot a point =========================================================
//plot one point
//at x,y with color 1=white 0=black 2=invert
void video_pt(int x, int y, char c) {
   //calculate i based upon this and x,y
   // the word with the pixel in it
   //int i = (x/32) + y*PITCH
   x += OFFSET;
   if (c==1)
     screen_buffer[(x >> 5) + (y * PITCH)] |= 1<<(31-(x & 0x1f));
    else if (c==0)
     screen_buffer[(x >> 5) + (y * PITCH)] &= ~(1<<(31-(x & 0x1f)));
    else // c==2
     screen_buffer[(x >> 5) + (y * PITCH)] ^= 1<<(31-(x & 0x1f));
}

//==================================
//plot a line
//at x1,y1 to x2,y2 with color 1=white 0=black 2=invert
//NOTE: this function requires signed chars
//Code is from David Rodgers,
//"Procedural Elements of Computer Graphics",1985
void video_line(int x1, int y1, int x2, int y2, char c) {
   int e;
   signed int dx,dy,j, temp;
   signed char s1,s2, xchange;
        signed int x,y;

   x = x1;
   y = y1;

   //take absolute value
   if (x2 < x1) {
      dx = x1 - x2;
      s1 = -1;
   }

   else if (x2 == x1) {
      dx = 0;
      s1 = 0;
   }

   else {
      dx = x2 - x1;
      s1 = 1;
   }

   if (y2 < y1) {
      dy = y1 - y2;
      s2 = -1;
   }

   else if (y2 == y1) {
      dy = 0;
      s2 = 0;
   }

   else {
      dy = y2 - y1;
      s2 = 1;
   }

   xchange = 0;

   if (dy>dx) {
      temp = dx;
      dx = dy;
      dy = temp;
      xchange = 1;
   }

   e = ((int)dy<<1) - dx;

   for (j=0; j<=dx; j++) {
      video_pt(x,y,c);

      if (e>=0) {
         if (xchange==1) x = x + s1;
         else y = y + s2;
         e = e - ((int)dx<<1);
      }

      if (xchange==1) y = y + s2;
      else x = x + s1;

      e = e + ((int)dy<<1);
   }
}

//==================================
//return the value of one point
//at x,y with color 1=white 0=black
char video_state(int x, int y) {
    //The following construction detects exactly one bit at the x,y location
    return (screen_buffer[((x+OFFSET) >> 5) + (y * PITCH)] & (1<<(31-(x & 0x1f))))?1:0 ;
}

//==================================
// put a big character on the screen
// c is index into bitmap
void video_putchar(int x, int y, int c) {
#ifndef NOFONT
    x += TOFFSET;
    int j = (x>>2)+(y<<3)*PITCH;
    int shf = (3-(x&3))<<3;
    int msk = ~(255<<shf);
    unsigned char *ptr = font8x8[c-32];
    screen_buffer[j]=(screen_buffer[j] & msk)|(*(ptr++)<<shf);j+=PITCH;
    screen_buffer[j]=(screen_buffer[j] & msk)|(*(ptr++)<<shf);j+=PITCH;
    screen_buffer[j]=(screen_buffer[j] & msk)|(*(ptr++)<<shf);j+=PITCH;
    screen_buffer[j]=(screen_buffer[j] & msk)|(*(ptr++)<<shf);j+=PITCH;
    screen_buffer[j]=(screen_buffer[j] & msk)|(*(ptr++)<<shf);j+=PITCH;
    screen_buffer[j]=(screen_buffer[j] & msk)|(*(ptr++)<<shf);j+=PITCH;
    screen_buffer[j]=(screen_buffer[j] & msk)|(*(ptr++)<<shf);j+=PITCH;
    screen_buffer[j]=(screen_buffer[j] & msk)|(*ptr<<shf);
#endif
}

//==================================
// put a string of big characters on the screen
void video_string(int x, int y, char *str) {
   char i;
   for (i=0; str[i]!=0; i++) {
      video_putchar(x++,y,str[i]);
   }
}

void color_burst(char c)
{
 int y,*p = screen_buffer;
 for(y=0;y<200;y++)
 {
    p[0] = (c<<28)|(c<<24)|(c<<20)|(c<<16)|(c<<12)|(c<<8)|(c<<4)|c;
    p[1] = (c<<28);
    p += PITCH;
 }
}

int* xolinedirect(int y){return &screen_buffer[PITCH*y+(OFFSET>>5)];}

// ========================================================================
int   main(void)
{
    int* iptr;
    float f;
    unsigned short us;
    unsigned long i,j,n,m,stored,maxstored=0;
    // global time
    int time, seconds, x, y, k, c, *p;
    char time_string[10],str[32];

   // Configure the device for maximum performance but do not change the PBDIV
   // Given the options, this function will change the flash wait states, RAM
   // wait state and enable prefetch cache but will not change the PBDIV.
   // The PBDIV value is already set via the pragma FPBDIV option above..
   SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);

   
    //make sure analog is cleared
    //ANSELA =0;
    //ANSELB =0;

    // timer interrupt //////////////////////////
    // Set up timer2 on,  interrupts, internal clock, prescalar 1, toggle rate
    // 63.5 microSec
    OpenTimer2(T2_ON | T2_SOURCE_INT | T2_PS_1_1, line_cycles);
    // set up the timer interrupt with a priority of 2
    ConfigIntTimer2(T2_INT_ON | T2_INT_PRIOR_2);
    mT2ClearIntFlag(); // and clear the interrupt flag

    // Compare match setup //////////////////////
    //Set up compare match unit to produce sync pulses
    // 5 uSec low
    // or 63.5-5 = 58.5 microSec (2340 ticks) low
    // pulse duration will be controlled in Timer2 ISR
    // #define OpenOC2( config, value1, value2) ( OC2RS = (value1), OC2R = (value2), OC2CON = (config) )
    OpenOC2(OC_ON | OC_TIMER2_SRC | OC_CONTINUE_PULSE, line_cycles-1, us_5_cycles);
    // OC2 is PPS group 2, map to RPB1 (pin 5)
    PPSOutput(2, RPB1, OC2);

    // OC3 setup /////////////////////////////////
    // Compare unit for video timing,
    // using the interrupt flag to trigger the first DMA,
    // then use the ISR to change the DMA control to SPI
    // #define OpenOC2( config, value1, value2) ( OC2RS = (value1), OC2R = (value2), OC2CON = (config) )
    // Pulse needs to be TWO cycles long
    OpenOC3(OC_ON | OC_TIMER2_SRC | OC_CONTINUE_PULSE, line_offset+2, line_offset);
    // turn on ISR so that DMA can covert to SPI control
    ConfigIntOC3(OC_INT_PRIOR_1 | OC_INT_ON); //3 //
    mOC3ClearIntFlag(); // and clear the interrupt flag

    // OC4 setup /////////////////////////////////
    OpenOC4(OC_ON | OC_TIMER2_SRC | OC_CONTINUE_PULSE, line_offset+0, line_offset+72);
    // OC4 is PPS group 3, map to RPB13 (pin 24)
    PPSOutput(3, RPB13, OC4);

    // OC5 setup /////////////////////////////////
    OpenOC5(OC_ON | OC_TIMER2_SRC | OC_CONTINUE_PULSE, line_cycles-200, line_cycles-100);
    // OC5 is PPS group 3, map to RPA2 (pin 9)
    PPSOutput(3, RPA2, OC5);
   
    // SPI configure /////////////////////////////
    // SCK1 is pin 25 RB14
    // SDO1 is PPS group 2, map to RPA1 (pin 3)
    // SDI1 is PPS group 2, map to RPB8 (pin 17) ???
    // SS1 input is PPS group 1, map to RPB7 (pin 16) for framing
    // specify PPS group, signal, logical pin name
    PPSInput (1, SS1, RPB7);
    PPSOutput(2, RPA1, SDO1);
    // control sync for DAC
    mPORTBSetPinsDigitalOut(BIT_0|BIT_2|BIT_3);
    mPORTBSetBits(BIT_0);
    mPORTBClearBits(BIT_2);
    mPORTBClearBits(BIT_3);

    // divide Fpb by N, configure the I/O ports. 32 bit transfer
    SpiChnOpen(SPI_CHANNEL1, SPI_OPEN_ON | SPI_OPEN_MODE32 | SPI_OPEN_MSTEN , 2); // N=6

    //=== DMA Channel 1 ================================
    // Open DMA Chan1 and chain from channel zero
    DmaChnOpen(DMAchn1, DMApri0, DMA_OPEN_DEFAULT);

    // setup system wide interrupts  ///
    INTEnableSystemMultiVectoredInt();

#ifndef NOBACKGROUND
    iptr = (int*)cgatrick_bits;
    for(i=0;i<SCREENSZ;i++)
    {
        k = iptr[i];
        c = 0;
        n = 1;
        m = 0x80000000;
        for(j=0;j<32;j++)
        {
          if(!(k&n)) c|=m;
          n <<= 1;
          m >>= 1;
        }
        screen_buffer[i] = c;
    }
#endif

memset(screen_buffer,0,sizeof(screen_buffer));
color_burst(0xC);

// generate color chart
#if 0
 for(y=0;y<192;y++)
 {
   if((y%12)==11) continue; // black lines between colors
   p = xolinedirect(y+4);
   j = y/12;
   for(x=0;x<16;x++)
   {
      if(y&1)
       p[x+2] = (x<<28)|(x<<24)|(x<<20)|(x<<16)|(x<<12)|(x<<8)|(x<<4);//|x;
      else
       p[x+2] = (j<<28)|(j<<24)|(j<<20)|(j<<16)|(j<<12)|(j<<8)|(j<<4);//|j;
   }
 }
#else
 for(y=0;y<200;y++)
 {
   p = xolinedirect(y);
   p[0] = 0x00000000;
   p[1] = 0x00111111;
   p[2] = 0x11112222;
   p[3] = 0x22222233;
   p[4] = 0x33333333;
   p[5] = 0x44444444;
   p[6] = 0x44555555;
   p[7] = 0x55556666;
   p[8] = 0x66666677;
   p[9] = 0x77777777;
   p[10] = 0x88888888;
   p[11] = 0x88999999;
   p[12] = 0x9999AAAA;
   p[13] = 0xAAAAAABB;
   p[14] = 0xBBBBBBBB;
   p[15] = 0xCCCCCCCC;
   p[16] = 0xCCDDDDDD;
   p[17] = 0xDDDDEEEE;
   p[18] = 0xEEEEEEFF;
   p[19] = 0xFFFFFFFF;
 }

#endif   
 
#if 1
    // Draw the screen boundaries
    video_line(left,top, right,top, 1); // top
    video_line(right,top, right,bottom, 1); // right
    video_line(right-1,top, right-1,bottom, 1); // right
    video_line(right,bottom, left,bottom, 1); // bottom
    video_line(left,top, left,bottom ,1); // left
    video_line(left+1,top, left+1,bottom ,1); // left
#endif
    // Draw a title
    video_string(0,0,"nedoPC-32-A");
   
    seconds = stored = n = x = y = 0;
    c = 32;
    k = 0;
    srand(11111);
    while(1)
    {       
            n++;
#if 0
            // random characters
            k = rand();
            video_putchar(k%80,2+((k>>6)&15),++c);
            if(c==255) c=31;
#endif
#if 0
            // random lines
            k = rand();
            c = k&511; k=8+((k>>8)%184);
            video_line(x,y,c,k,2);
            x = c; y = k;
#endif
#if 0
            // random pixels
            k = rand();
            video_pt(k%640,8+((k>>9)%184),2);
#endif
            if(time != time_tick_60_hz)
            {
                time = time_tick_60_hz ;
                stored = n;
                if(n>maxstored) maxstored=n;
                n = 0;               
           
              if(seconds != time_seconds)
              {
                seconds = time_seconds;
                sprintf(time_string, "%d:%d",seconds,stored);
                video_string(0, 24, time_string);

                if(seconds&1)
                    mPORTBClearBits(BIT_2);
                else
                    mPORTBSetBits(BIT_2);

                if(seconds&2)
                    mPORTBClearBits(BIT_3);
                else
                    mPORTBSetBits(BIT_3);
              }
            }
    }

}


Методом научного тыка подобрал такую длину строки, при которой цвет не только появился, но и стал одинаковым для чётных и нечётных строк - и это число как ни странно 1823 (при этом правда у нас остаётся только 16 цветов, зато они без дырок)!

P.S. Цвет даже появился на "старом" цветном NTSC с электронно-лучевой трубкой (последний CRT TV системы NTSC, выпущенный в 2005 году под маркой "Sony Trinitron"), в отличие от всех предыдущих вариантов, когда цвет на нём не ловился - правда там есть какие-то мерцания, но я надеюсь их убрать путём аккуратного подбора резисторов (фотки с него не снимал - все нижеприведённые фотки сняты c SONY LCD TV)...

P.P.S. Надо попробовать color-burst подвигать, чтобы получить цвета, аналогичные CGA-composite - это будет кул ;)


Attachments:
File comment: NTSC color mixing (solid colors on diagonal)
IMG_0535_800x596.jpg
IMG_0535_800x596.jpg [ 163.8 KiB | Viewed 11290 times ]
File comment: NTSC color chart
IMG_0536_800x473.jpg
IMG_0536_800x473.jpg [ 43.27 KiB | Viewed 11290 times ]

_________________
:dj: https://mastodon.social/@Shaos
08 Apr 2015 06:09
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22412
Location: Silicon Valley
Reply with quote
Путём сдвига color-burst-a получилось четыре набора цветов (правда там похоже одни и теже цвета перемежаются), причём последний color_burst(0x9) примерно (но не полностью) похож на CGA-трюк:

P.S. Интересно, что color_burst(0x3) примерно соответствует Tandy, а color_burst(0x6) - PCjr ;)


Attachments:
File comment: Color chart 0
Photo0160.jpg
Photo0160.jpg [ 44.02 KiB | Viewed 11271 times ]
File comment: Color chart 1
Photo0161.jpg
Photo0161.jpg [ 41.49 KiB | Viewed 11271 times ]
File comment: Color chart 2
Photo0162.jpg
Photo0162.jpg [ 42.39 KiB | Viewed 11271 times ]
File comment: Color chart 3
Photo0163.jpg
Photo0163.jpg [ 43.2 KiB | Viewed 11271 times ]
File comment: CGA composite trick
CGA-composite.gif
CGA-composite.gif [ 8.77 KiB | Viewed 11271 times ]

_________________
:dj: https://mastodon.social/@Shaos
09 Apr 2015 17:53
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22412
Location: Silicon Valley
Reply with quote
Вот ещё картинок с экрана ТВ ;)

P.S. причём TRON "широкоформатный" ;)


Attachments:
File comment: TRON original with color burst
cgatrick_xbm015.gif
cgatrick_xbm015.gif [ 10.95 KiB | Viewed 11247 times ]
File comment: TRON
Photo0175.jpg
Photo0175.jpg [ 189.56 KiB | Viewed 11271 times ]
File comment: EYE
Photo0174.jpg
Photo0174.jpg [ 149.12 KiB | Viewed 11271 times ]
File comment: DOOM
Photo0168.jpg
Photo0168.jpg [ 213.57 KiB | Viewed 11271 times ]

_________________
:dj: https://mastodon.social/@Shaos
09 Apr 2015 19:07
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22412
Location: Silicon Valley
Reply with quote
По умолчанию будет палитра из color_burst(0xC) - назовём её палитра номер 0:
Code:
 0 - 4   4   12   #04040C H=... S=67  V=5   0000  [0] Black
 1 - 1   19  159  #01139F H=233 S=99  V=62  0001  [1] Blue
 2 - 70  2   172  #4602AC H=264 S=99  V=67  0010  [5] Magenta
 3 - 1   86  255  #0156FF H=220 S=100 V=100 0011  [9] Bright Blue
 4 - 102 15  15   #660F0F H=0   S=85  V=40  0100  [4] Red
 5 - 122 133 137  #7A8589 H=... S=11  V=54  0101  [7] White (Light Gray)
 6 - 249 49  131  #F93183 H=335 S=80  V=98  0110 [12] Bright Red
 7 - 219 118 254  #DB76FE H=285 S=54  V=100 0111 [13] Bright Magenta
 8 - 0   99  34   #006322 H=141 S=100 V=39  1000  [2] Green
 9 - 1   207 133  #01CF85 H=158 S=100 V=81  1001  [3] Cyan
10 - 127 133 125  #7F857D H=... S=6   V=52  1010  [8] Gray
11 - 15  188 253  #0FBCFD H=196 S=94  V=99  1011 [11] Bright Cyan
12 - 138 185 54   #8AB936 H=82  S=71  V=73  1100  [6] Brown (Dark Yellow)
13 - 102 253 90   #66FD5A H=116 S=64  V=99  1101 [10] Bright Green
14 - 253 182 74   #FDB64A H=36  S=71  V=99  1110 [14] Yellow
15 - 220 217 202  #DCD9CA H=... S=8   V=86  1111 [15] Bright White
Цвета из неё с некоторой натяжкой натягиваются на стандартные 16 цветов CGA/EGA (см. справа в каждой строке).

Палитра color_burst(0xC) - 0000 1100 1100 1100... будет палитрой номер 0 (Xorya composite см.выше).
Палитра color_burst(0x9) - 0001 1001 1001 1001... будет палитрой номер 1 (CGA composite).
Палитра color_burst(0x3) - 0011 0011 0011 0011... будет палитрой номер 2 (Tandy composite).
Палитра color_burst(0x6) - 0110 0110 0110 0110... будет палитрой номер 3 (PCjr composite).

Как видим фаза color burst сигнала между палитрами увеличивается на 90 градусов (четверть полного оборота).

P.S. Это значит, что можно писать код и отлаживаться в DOSBox, который умеет эмулировать color-burst-режимы работы CGA ;)

P.P.S. Вот примеры CGA-графики и Tandy-графики с http://nerdlypleasures.blogspot.com/201 ... phics.html


Attachments:
File comment: Tandy version
Photo0177.jpg
Photo0177.jpg [ 142.46 KiB | Viewed 11261 times ]
File comment: CGA version
Photo0176.jpg
Photo0176.jpg [ 148.41 KiB | Viewed 11261 times ]

_________________
:dj: https://mastodon.social/@Shaos
09 Apr 2015 19:34
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22412
Location: Silicon Valley
Reply with quote
Вот подсчитал среднеквадратичное отклонение стандартных EGA цветов от получившихся - результат не всегда совпадает с моим выбором (см.выше), но если выбрать следующий доступный цвет, то совпадает (за исключением коричневого EGA[6], которого у меня и близко нету):
Code:
$ ./test16colors
        EGA[0]  EGA[1]  EGA[2]  EGA[3]  EGA[4]  EGA[5]  EGA[6]  EGA[7]  EGA[8]  EGA[9]  EGA[10] EGA[11] EGA[12] EGA[13] EGA[14] EGA[15]
X[0]    13.266  158.101 166.481 229.207 166.481 229.207 185.097 282.977 135.834 268.647 273.662 358.624 273.662 358.624 362.396 430.176 [0]
X[1]    160.134 21.977  219.278 151.403 232.815 170.420 241.243 226.899 129.954 143.625 261.205 268.269 272.668 279.442 354.525 359.761 [1]
X[2]    185.709 70.057  250.416 182.011 198.967 100.040 215.576 195.520 121.173 118.334 267.961 266.689 220.642 219.096 325.274 324.227 [1] -> [5]
X[3]    269.113 120.921 268.481 119.507 317.777 207.803 305.920 206.983 189.623 84.006  254.002 188.725 305.642 254.002 349.252 305.085 [9]
X[4]    104.183 186.156 186.156 241.773 71.232  169.924 98.737  229.508 100.444 250.577 250.577 339.837 182.233 293.102 293.102 372.302 [4]
X[5]    226.588 183.472 187.142 131.689 196.881 145.196 152.895 69.007  79.856  132.654 137.684 173.715 150.655 184.166 187.822 215.632 [7]
X[6]    285.592 256.755 306.273 279.576 160.633 100.812 157.156 149.676 174.092 208.729 267.298 291.046 58.720  129.259 211.159 240.516 [12]
X[7]    355.529 262.566 339.383 240.252 284.326 152.908 260.780 110.277 218.188 138.007 255.511 191.640 175.915 48.847  220.513 141.655 [13]
X[8]    104.676 168.217 78.721  153.418 199.642 239.159 173.931 228.991 100.110 237.196 184.830 283.552 260.427 337.731 303.252 371.755 [2]
X[9]    246.047 210.283 138.054 52.335  298.495 269.776 247.253 176.915 155.705 191.896 108.000 155.705 285.839 307.057 262.914 285.839 [3]
X[10]   222.358 189.322 181.997 139.725 187.518 146.843 140.634 72.409  75.286  144.803 135.085 183.161 142.436 188.648 181.295 219.472 [7] -> [8]
X[11]   315.560 206.053 254.083 86.244  351.252 257.406 314.075 176.743 209.124 124.551 193.941 96.917  310.537 261.176 300.521 249.185 [3] -> [11]
X[12]   237.034 258.312 148.946 180.901 195.359 220.692 118.068 121.264 117.346 230.673 93.113  219.340 157.003 253.160 139.821 242.879 [10] -> [6]!
X[13]   287.251 284.276 159.352 153.925 277.007 273.922 202.356 133.839 168.932 236.089 17.833  165.886 227.284 280.817 153.095 225.029 [10]
X[14]   320.326 326.112 263.873 270.867 213.282 221.876 147.560 127.472 194.304 265.319 183.505 257.515 97.642  205.363 73.851  195.177 [14]
X[15]   369.179 310.665 302.346 227.229 300.654 224.973 246.431 75.717  222.122 196.107 182.642 149.927 179.828 146.485 127.898 74.014  [15]


P.S. Ещё можно попробовать посмешивать 2 цвета - может быть более похоже:
Code:
E[0]    #00
E[1]    #11
E[2]    #88
E[3]    #93 !
E[4]    #44
E[5]    #26 !
E[6]    #4E !
E[7]    #5F !
E[8]    #05 !
E[9]    #37 !
E[10]   #DD
E[11]   #FB !
E[12]   #6E !
E[13]   #77
E[14]   #EE
E[15]   #FF

Вот такая вот аппроксимация EGA-шных цветов получилась:


Attachments:
File comment: EGA approximation
EGA-approx.jpg
EGA-approx.jpg [ 143.31 KiB | Viewed 11264 times ]

_________________
:dj: https://mastodon.social/@Shaos
09 Apr 2015 20:14
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22412
Location: Silicon Valley
Reply with quote
А теперь немножко пиара ;)

http://dangerousprototypes.com/2015/04/09/xorlib-an-open-source-game-library-for-pic32s/

P.S. Влил весь PIC32-код в xorlib.c и разместил в git-репозитории https://github.com/shaos/xorlib

_________________
:dj: https://mastodon.social/@Shaos


09 Apr 2015 22:08
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22412
Location: Silicon Valley
Reply with quote
Интересная особенность выяснилась - оказывается, если ставить опцию оптимизации -O2, то оно ругается в лог сборки:
Quote:
cc1.exe: warning: Compiler option (Optimization level > 1) ignored because the free XC32 C compiler does not support this feature.
cc1.exe: note: Disable the option or visit http://www.microchip.com/MPLABXCcompilers to purchase a new MPLAB XC compiler license.
Однако программа всё равно начинает работать чуть более чем в 2 раза быстрее! :lol:

P.S. Может это 60-дневная PRO-evaluation включилась?...

P.P.S. На самом деле оно просто от -O2 до -O1 даунгрейдилось, что опять же быстрее чем вообще без оптимизации - вот оно и срабатывало...

_________________
:dj: https://mastodon.social/@Shaos


10 Apr 2015 14:13
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22412
Location: Silicon Valley
Reply with quote
Ещё старых дософских картинок вам ;)


Attachments:
Photo0178.jpg
Photo0178.jpg [ 121.68 KiB | Viewed 11227 times ]
Photo0179.jpg
Photo0179.jpg [ 111.95 KiB | Viewed 11227 times ]
Photo0180.jpg
Photo0180.jpg [ 119.79 KiB | Viewed 11227 times ]

_________________
:dj: https://mastodon.social/@Shaos
11 Apr 2015 02:49
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22412
Location: Silicon Valley
Reply with quote
На только что купленном (и относительно дешёвом) LED TV от LG цвета выглядят несколько иначе - первое, что бросается в глаза - это намного более тёмный серый (две полоски 0101 и 1010), а также более тёмные magent-ы, зато тёмно-красный выглядит как красный:


Attachments:
File comment: NTSC color chart on LG
IMG_0566_800x600.jpg
IMG_0566_800x600.jpg [ 50.88 KiB | Viewed 11199 times ]

_________________
:dj: https://mastodon.social/@Shaos
12 Apr 2015 16:38
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22412
Location: Silicon Valley
Reply with quote
В-принципе, цвета похожи на то, что должно быть (CGA/EGA) - вот так их показывали (согласно википедии) CGA-карочки на NTSC телевизорах (вместо коричневого на цвете номер 6 был тёмно-жёлтый):

Image

Сравнение цветов с двух ТВ (фотик немного увёл цвета, причём на втором ТВ сильнее, чем на первом) с тем, что должно быть (цвет 6 показан для обоих вариантов NTSC и RGBI):


Attachments:
File comment: SONY, LG and desired colors CGA/EGA
xorya-colors-ega.jpg
xorya-colors-ega.jpg [ 26.42 KiB | Viewed 11198 times ]

_________________
:dj: https://mastodon.social/@Shaos
12 Apr 2015 18:09
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22412
Location: Silicon Valley
Reply with quote
Ещё скриншотов с ТВ ;)


Attachments:
File comment: Shaos
Photo0169.jpg
Photo0169.jpg [ 108.59 KiB | Viewed 11465 times ]
File comment: Xorya
Photo0185.jpg
Photo0185.jpg [ 104.27 KiB | Viewed 11465 times ]
File comment: Gagarin
Photo0183.jpg
Photo0183.jpg [ 120.91 KiB | Viewed 11465 times ]

_________________
:dj: https://mastodon.social/@Shaos
13 Apr 2015 17:04
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 146 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7, 8 ... 10  Next

Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.