Плата центрального недопроцессора nedoCPU-32

8-битные микроконтроллеры PICmicro (ПИКи) от Microchip и совместимые, а также 16-битные PIC24 и 32-битные PIC32

Moderator: Shaos

User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Плата центрального недопроцессора nedoCPU-32

Post by Shaos »

т.е. по сути тут мы имеем 32 цвета, которые процессор современного телевизора умеет смешивать, если они попадаются в соседних строках - в результате получается 16x16=256 цветов (часть из которых повторяется, но не суть) - вот исходник генератора полной таблички цветов и фотка:

 исходник тут

Code: Select all

/*******************************************************************
 * 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);
              }
            }
    }

}

You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Плата центрального недопроцессора nedoCPU-32

Post by Shaos »

Вот восстановленные по фотке 32 основных цвета (могут быть большие погрешности):

Code: Select all

/* 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 будет выглядеть так:
You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Плата центрального недопроцессора nedoCPU-32

Post by Shaos »

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

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

Никакие дальнейшие мухляжи с color-burst-ом не помогли - видимо неточность длины строки играла какую-то немаловажную роль (что значит, что я случайно угадал с первоначальным числом)...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
JeNNeR
Fanat
Posts: 52
Joined: 18 Nov 2014 09:17
Location: Отсюда

Re: Плата центрального недопроцессора nedoCPU-32

Post by JeNNeR »

А возврат к предыдущим настройкам возвратил цвет? потому что вполне может быть, что пошел дымок гденть внутри телевизора, и это отразилось как исчезновение цвета... ???
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Плата центрального недопроцессора nedoCPU-32

Post by Shaos »

 исходник тут

Code: Select all

/*******************************************************************
 * 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 - это будет кул ;)
You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Плата центрального недопроцессора nedoCPU-32

Post by Shaos »

Путём сдвига color-burst-a получилось четыре набора цветов (правда там похоже одни и теже цвета перемежаются), причём последний color_burst(0x9) примерно (но не полностью) похож на CGA-трюк:

P.S. Интересно, что color_burst(0x3) примерно соответствует Tandy, а color_burst(0x6) - PCjr ;)
You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Плата центрального недопроцессора nedoCPU-32

Post by Shaos »

Вот ещё картинок с экрана ТВ ;)

P.S. причём TRON "широкоформатный" ;)
You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Плата центрального недопроцессора nedoCPU-32

Post by Shaos »

По умолчанию будет палитра из color_burst(0xC) - назовём её палитра номер 0:

Code: Select all

 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
You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Плата центрального недопроцессора nedoCPU-32

Post by Shaos »

Вот подсчитал среднеквадратичное отклонение стандартных EGA цветов от получившихся - результат не всегда совпадает с моим выбором (см.выше), но если выбрать следующий доступный цвет, то совпадает (за исключением коричневого EGA[6], которого у меня и близко нету):

Code: Select all

$ ./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: Select all

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-шных цветов получилась:
You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Плата центрального недопроцессора nedoCPU-32

Post by Shaos »

А теперь немножко пиара ;)

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
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Плата центрального недопроцессора nedoCPU-32

Post by Shaos »

Интересная особенность выяснилась - оказывается, если ставить опцию оптимизации -O2, то оно ругается в лог сборки:
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 даунгрейдилось, что опять же быстрее чем вообще без оптимизации - вот оно и срабатывало...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Плата центрального недопроцессора nedoCPU-32

Post by Shaos »

Ещё старых дософских картинок вам ;)
You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Плата центрального недопроцессора nedoCPU-32

Post by Shaos »

На только что купленном (и относительно дешёвом) LED TV от LG цвета выглядят несколько иначе - первое, что бросается в глаза - это намного более тёмный серый (две полоски 0101 и 1010), а также более тёмные magent-ы, зато тёмно-красный выглядит как красный:
You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Плата центрального недопроцессора nedoCPU-32

Post by Shaos »

В-принципе, цвета похожи на то, что должно быть (CGA/EGA) - вот так их показывали (согласно википедии) CGA-карочки на NTSC телевизорах (вместо коричневого на цвете номер 6 был тёмно-жёлтый):

Image

Сравнение цветов с двух ТВ (фотик немного увёл цвета, причём на втором ТВ сильнее, чем на первом) с тем, что должно быть (цвет 6 показан для обоих вариантов NTSC и RGBI):
You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Плата центрального недопроцессора nedoCPU-32

Post by Shaos »

Ещё скриншотов с ТВ ;)
You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net