void CheckEraseToPageBounds(uint16_t currentAddress){ //checks if the remaining pages in the block are erased //if the remaineder of the 4k block is not erased it is set to zero uint8_t numPagesToCheck; uint16_t next4KBoundary; numPagesToCheck = 0x10 - (currentAddress & 0x00F); next4KBoundary = (currentAddress & 0xFFF0) + 0x0010; if (next4KBoundary > 0x3FF0){ next4KBoundary = 0; } for(uint8_t i = 0; i < numPagesToCheck; i++){ while(VerifyWriteReady() == false){ } if(FlashGetByte((currentAddress + i),0) != 0xFF){ for(uint8_t i = 0; i < numPagesToCheck; i++){ while(VerifyWriteReady() == false){ } ClearPage(currentAddress + i); } currentRecordAddress = next4KBoundary; return; } } currentRecordAddress = currentAddress; }
void ClearScreen(unsigned char color){ unsigned char page; for( page = 0; page < 8; page++){ GotoXY(0, page * 8); ClearPage(page, color); } }
/** Parse a teletext page * \param filename - Name of the teletext file * \return true if there is an error */ uint8_t ParsePage(PAGE *page, char *filename) { FILE *file; char *str; const unsigned char MAXLINE=80; char line[MAXLINE]; // printf("[Parse page]Started looking at %s\n",filename); // open the page file=fopen(filename,"r"); if (!file) { printf("[Parse page]Failed to open tti page\n"); //put_rc(res); return 1; } // Shouldn't we clear the page at this point? ClearPage(page); // page->filesize=(unsigned int)file.fsize; // Not sure that Pi needs this // Read a line // printf("[ParsePage]Ready to parse\n"); while (!feof(file)) { str=fgets(line,MAXLINE,file); if (!str) break; // Ooops, no more data /* debug for (i=0;i<16;i++) printf("%02x ",str[i]); printf("[ParsePage]Parsing a line %s\n",str); printf("\n"); */ if (ParseLine(page,str)) { fclose(file); return 1; } // printf("[ParsePage] chewing next line\n"); } // printf("[ParsePage] mag=%d page=%X, subpage=%X\n",page->mag,page->page,page->subpage); // delay(1000); fclose(file); // printf("[Parse page]Ended\n"); return 0; }
CHallQueFrontView::~CHallQueFrontView() { ClearPage(); if(g_pBackDC) { DeleteObject(g_pBackDC->GetSafeHdc()); delete g_pBackDC; g_pBackDC = NULL; } theApp.m_pView = NULL; if(m_pWaringDlg) { m_pWaringDlg->DestroyWindow(); delete m_pWaringDlg; m_pWaringDlg = NULL; } if(m_pShowPageDlg) { m_pShowPageDlg->DestroyWindow(); delete m_pShowPageDlg; m_pShowPageDlg = NULL; } }
/**************************************************************************** REMARKS: Does a simple overlay buffer static video capture test. The overlay will show what is coming in via the video capture engine. ****************************************************************************/ static int staticTest( GA_videoFuncs *video, GA_videoCaptureFuncs *capture, GA_captureInputTypes input, GA_captureStandardTypes standard, GA_VideoCaptureInf *captureInfo) { int key,x,y,width = DEF_WIDTH,height = DEF_HEIGHT; int centerX, centerY; ibool done = false,freezeInput = false,newFreezeInput = false; GA_captureBuf *captureBuf = NULL; GA_buf *primaryVideo = NULL; int outputHead = init.GetActiveHead(); char str[80]; /* Draw background for video overlay */ SetActivePage(0); ClearPage(0); moire(defcolor); if (maxX >= 479) gmoveto(80,80); else gmoveto(8,40); gprintf("Video capture static test"); y += 16; displaymodeInfo(); gprintf("Press any key to continue"); if (EVT_getch() == 0x1B) return 0x1B; /* Use larger overlay window for higher resolutions */ if (modeInfo.XResolution >= 1280) { width *= 2; height *= 2; } else if (modeInfo.XResolution <= DEF_WIDTH) { width /= 2; height /= 2; } /* Allocate the source video buffer */ if ((captureBuf = capture->AllocCaptureBuffer(width,height,captureInfo->VideoFormat,1)) == NULL) { displayError("Unable to allocate video capture buffer!"); return 0x1B; } primaryVideo = captureBuf->VideoBuffers; centerX = (maxX - primaryVideo->Width)/2; centerY = (maxY - primaryVideo->Height)/2; /* Set up for single buffer video overlay */ SetActiveBuffer(primaryVideo); ClearVideoBuffer(primaryVideo); /* Set the video output window */ x = centerX; y = centerY; if (!video->SetVideoOutput(0,outputHead,primaryVideo, 0,0,primaryVideo->Width,primaryVideo->Height, x,y,primaryVideo->Width,primaryVideo->Height,0)) { displayError("Unable to set video output window!"); return 0x1B; } /* Set up the video capture and start it */ capture->SetVideoInput(captureBuf,input,standard,0,false); capture->StartLiveVideo(captureBuf); /* Now loop around and display the video capture */ sprintf(str,"%d x %d %d bit %s overlay",primaryVideo->Width,primaryVideo->Height, primaryVideo->BitsPerPixel,displayFormat(primaryVideo->Format)); if (width < DEF_WIDTH) WriteText(8,60,displayFormat(primaryVideo->Format),defcolor); else WriteText(8,80,str,defcolor); while (!done) { if (handleKeypress(&key,&newFreezeInput)) break; if (freezeInput != newFreezeInput) { freezeInput = newFreezeInput; if (freezeInput) capture->FreezeLiveVideo(captureBuf,gaCaptureFieldAny); else capture->StartLiveVideo(captureBuf); } } SetActivePage(0); video->DisableVideoOutput(0); capture->FreeCaptureBuffer(captureBuf); return key; }
/**************************************************************************** REMARKS: Displays the menu of DDC tests and allows the DDC functionality to be tested. ****************************************************************************/ void DDCCITests( GC_devCtx *gc) { int choice,err = ddcOk; GA_SCIFuncs sci; /* For NonVGA controllers we need to run this test in graphics modes * to ensure that we are running on the proper controller hardware * that we support DPMS on (ie: the Windows driver hardware). */ SetGraphicsMode(gc); /* Allow a 1.5 second delay before trying to do DDC/CI communications */ _OS_delay(1500000); /* Initialise DDC/CI communications */ sci.dwSize = sizeof(sci); if (!GA_queryFunctions(dc,GA_GET_SCIFUNCS,&sci) || (err = MCS_begin(dc)) != ddcOk) { RestoreMode(gc); GC_clrscr(gc); if (err == ddcNotAvailable) GC_printf(gc,"DDC/CI not supported by monitor!\n\n"); else GC_printf(gc,"DDC monitor not connected!\n\n"); GC_printf(gc,"Press any key to continue"); EVT_getch(); return; } /* Display menu information on screen */ for (;;) { ClearPage(0); gmoveto(40,40); gprintf("DDC/CI support active:"); gnewline(); gprintf("Enter function to test:"); gprintf(" [0] - Is Control Supported"); gprintf(" [1] - Enable Control"); gprintf(" [2] - Get Control Value"); gprintf(" [3] - Set Control Value"); gprintf(" [4] - Reset Control"); gprintf(" [5] - Get Timing Report"); gprintf(" [6] - Save Current Settings"); gprintf(" [7] - Get Self Test Report"); gprintf(" [8] - Get Capabilities String"); gprintf(" [Esc] - Quit"); gprintf("Which: "); /* Loop around trying the different DPMS states */ choice = EVT_getch(); if (choice == 0x1B || tolower(choice) == 'q') break; gnewline(); switch (choice) { case '0': testMCS_isControlSupported(gc); break; case '1': testMCS_enableControl(gc); break; case '2': testMCS_getControlValue(gc); break; case '3': testMCS_setControlValue(gc); break; case '4': testMCS_resetControl(gc); break; case '5': testMCS_getTimingReport(); break; case '6': testMCS_saveCurrentSettings(); break; case '7': testMCS_getSelfTestReport(); break; case '8': testMCS_getCapabilitiesString(); break; } } /* Close the DDC/CI communications channel */ MCS_end(); /* Restore text mode for NonVGA controllers */ RestoreMode(gc); }
/* Command interpreter for VBIT, The leading SO and trailing carriage return are already removed The X command returns 2 Other good commands return 0 and bad commands return 1. Also after a P command if selecting a single page fails, the page is created and 8 is the return code */ static int vbit_command(char *Line) { static uint8_t firstLine=true; static uint16_t SRAMAddress; // The address pointer into the FIFO serial ram unsigned char rwmode; unsigned char returncode=0; int pagecount; uint8_t directorySteps; int8_t sign; // 1=plus -1=minus char ch; unsigned char valid; long n; unsigned char i; char str[80]; char *ptr; char *dest; str[0]='O'; str[1]='K'; str[2]='\0'; // char data[80]; // This stuff is to do with locating pages in the display list (Directory command) // (also shared with ee/ea command for uploading pages) NODEPTR np; DISPLAYNODE node; PAGEINDEXRECORD ixRec; uint16_t charcount; uint8_t res; DWORD fileptr; // Used to save the file pointer to the body of the ttx file PAGE page; // ee/ea specific variable static DWORD StartOfPage; DWORD EndOfPage; // Records the start and end of the new page PAGEINDEXRECORD pageindex; uint16_t ix; char packet[45]; static uint8_t row; // Teletext row counter for JA/JZ/JW command // tba // Read, Update or not switch (Line[2]) { case 'R' : rwmode=CMD_MODE_READ; break; case 'U' : rwmode=CMD_MODE_WRITE;break; default: rwmode=CMD_MODE_NONE; } /* Is there actually any data */ if (*Line==0) returncode=1; else switch (Line[1]) { case 'b': // Dump the current page dumpPage(); break; case 'C': // Create magazine lists // TODO: Kill video // TODO: C<pages to pre-allocate> // this would speed up the process immensely // It only needs to be approximate as FatFS will extend the file as needed. cli(); pagecount=300; for (i=1;i<=1;i++) // TODO: Do we need more lists? Probably can find a way around it. SDCreateLists(i,pagecount); sei(); break; case 'D': // Directory - D[<F|L>][<+|->][<n>] // Where F=first, L=Last, +=next, -=prev, n=number of pages to step (default 1) //xprintf(PSTR("D Command needs to be written")); // It would probably be a good idea to save the seek pointer // do the reading required // and then reset it. This would save memory. // If the ee command is active, don't allow D to mess the page variable. if (firstLine) { returncode=1; // ee command is busy. break; } directorySteps=0; sign=1; for (i=2;Line[i];i++) { ch=Line[i]; // xprintf(PSTR("Processing Line[%d]=%c\n\r"),i,Line[i]); switch (ch) { case 'F' : ; // Set the first item DirectoryFirst(); break; case 'L' : ; // Set the last item DirectoryLast(); break; case '+' : ; // Next item directorySteps=1; sign=1; // xprintf(PSTR("D+ not implemented")); break; case '-' : ; // Previous item directorySteps=1; sign=-1; // xprintf(PSTR("D- not implemented")); break; default: // Number of steps (TODO: Extend to a generic decimal) if (ch>='0' && ch <='9') { directorySteps=ch; } Line[i]=0;// Force this to be the last option break; // Break because this must be the last option } // Find the page if (LocatePage(directorySteps*sign)==NULLPTR) { // Probably want to set an error value as we failed to iterate // But I don't think that we return anything different. // We rely on TED scheduler to remember the count returned by the P command and NOT overrun } // TODO: Work out what to do with the rest of the parameters np=GetNodePtr(¤tPage); // TODO: Handle sub pages GetNode(&node,np); // Instead treat the page like a single page f_lseek(&listFIL,(node.pageindex)*sizeof(PAGEINDEXRECORD)); // Seek the page index f_read(&listFIL,&ixRec,sizeof(PAGEINDEXRECORD),&charcount); // and read it // Now seek the actual page that we are referencing res=f_open(&PageF,"pages.all",FA_READ); // Now look for the relevant page f_lseek(&PageF,ixRec.seekptr); // Seek the actual page // Now we have the page, we need to seek through it to get // the data while (PageF.fptr<(ixRec.seekptr+ixRec.pagesize)) { fileptr=PageF.fptr; // Save the file pointer in case we found "OL" f_gets(str,sizeof(str),&PageF); if (str[0]=='O' && str[1]=='L') { f_lseek (&PageF, fileptr); // Step back to the OL line break; } if (ParseLine(&page, str)) { xprintf(PSTR("[insert]file error handler needed:%s\n"),str); // At this point we are stuffed. f_close(&PageF); returncode=1; break; // what else should we do if we get here? } } // bb mpp qq cc tttt ssss n xxxxxxx // Leading zeros rely on PRINTF_LIB_FLOAT in makefile!!! sprintf_P(str,PSTR("%02X %03X %02d %02X %04X 0000 %1d 00000000"), 3, // seconds (hex) 0x100+(currentPage/2), // mpp page.subpage, // ss page.control, // S page.time, // Cycle time (secs) (currentPage>>8)+1); // Mag f_close(&PageF); } // str[0]=0; // might return the directory paramaters here break; case 'E' : // EO, ES, EN, EP, EL, EM - examine switch (Line[2]) { case 'M': // EM - Return Miscellaneous flags { // These are BFLSU. The code below is not correct n = ini_getl("service", "serialmode", 0, inifile); if (n) xputs(PSTR("20")); else xputs(PSTR("00")); break; } break; default: returncode=1; case 'O': // EO - Output dataline actions set by QO // 18 characters on a line, but odd ignores last action n = ini_gets("service", "outputodd", "111Q2233P445566778", str, sizearray(str), inifile); n = ini_gets("service", "outputeven", "111Q2233P445566778", str, sizearray(str), inifile); xprintf(PSTR("%s"),str); break; } break; // E commands case 'e' : // ea or ee : Upload page(s). // These pages add the lines at the end of the page file, and patch the index. // Warning. "page" is shared with the directory command // directory calls are blocked until you do ee. switch (Line[2]) { case 'a' : // Add a page, line at a time. passBackspace=true; if (firstLine) { firstLine=false; ClearPage(&page); // Clear out our Page object res=f_open(&PageF,"pages.all",FA_READ| FA_WRITE); // Ready to write // TODO: check the value of res //xprintf(PSTR("Size of pages.all=%ul\n\r"),PageF.fsize); /* Move to end of pages.all to append data */ res=f_lseek(&PageF, PageF.fsize); //xprintf(PSTR("lseek res=%d\n\r"),res); StartOfPage=PageF.fptr; // We need the Start Of Page for the index } // uh fellows, Although we get \r => Ctrl-P, we need to map it to 0x8d which is the file format. for (ptr=&Line[4];*ptr;ptr++) if (*ptr==0x10) *ptr=0x8d; f_puts(&Line[4],&PageF); // The rest of the line is the file contents f_putc('\n',&PageF); // Add the LF that the interpreter strips out xprintf(PSTR("Now writing:%s\n\r"),&Line[4]); // Don't unencode the line, pages.all should follow MRG \r => ctrl-P substitutions // Probably can ignore Viewdata escapes. // Write the rest of the line to pages.all // Parse the line so we have all the page details so we know where to put it in the array/node if (ParseLine(&page, &Line[4])) { xprintf(PSTR("Your page sucks. Unable to parse this nonsense\n\r")); returncode=1; // failed // TODO: implement the break // break; } break; // a case 'e' : // We finished. End the update passBackspace=false; EndOfPage=PageF.fptr; f_close(&PageF); // We are done with pages.all // We need to refresh the transmission file object so close and re-open it f_close(&pagefileFIL); res=f_open(&pagefileFIL,"pages.all",FA_READ); // Only need to open this once! // Or are we all done? We need to write the page to Pmpp.TTI so that we can rebuild the index later pageindex.seekptr=StartOfPage; pageindex.pagesize=(uint16_t)(EndOfPage-StartOfPage); // Warning! 16 bit file size limits to about 50 subpages. xprintf(PSTR("seek %ld size %d \n\r"),pageindex.seekptr,pageindex.pagesize); // 1: Append pages.idx with the file start/end (append pageindex) f_close(&listFIL); // TODO: Perhaps we should check that this is actually opened first? res=f_open(&listFIL,"pages.idx",FA_READ| FA_WRITE); // Ready to write // TODO: check the value of res ix=listFIL.fsize; // This is the address in the file res=f_lseek(&listFIL, ix); // Locate the end of the file // Now append the page index f_write(&listFIL,&(pageindex.seekptr),4,&charcount); // 4 byte seek pointer f_write(&listFIL,&(pageindex.pagesize),2,&charcount); // 2 byte file size // Now restore the file to the previous opened readonly state f_close(&listFIL); res=f_open(&listFIL,"pages.idx",FA_READ); // 2: Add the page to the page array. (Or we could rebuild just by doing a restart) ix=ix/sizeof(pageindex); xprintf(PSTR("New page mag=%d page=%02X --> added at ix=%d\n\r"),page.mag,page.page,ix); LinkPage(page.mag, page.page, page.subcode, ix); // TODO: // 3: Add the page to the node list. (ditto) // TODO: firstLine=true; // and reset ready for the next file break; // e default: str[0]=0; returncode=1; } break; // e commands case 'G': /* G - Packet 8/30 format 1 [p830f1]*/ if (rwmode==CMD_MODE_NONE) { str[0]=0; returncode=1; break; } /* C, L N, T, D */ switch (Line[3]) { case 'C' : /* Code. 1=format 1 */ //xputs(PSTR("GUC command not implemented. Why would we need it\n")); // It should always default to 0 /** Where is the initial page done? The code below is wrong */ //SetInitialPage(pkt830,str1,str2); // nb. Hard coded to 100 break; case 'D' : /* up to 20 characters label*/ if (rwmode==CMD_MODE_READ) { n = ini_gets("p830f1", "label", "VBITFax ", str, sizearray(str), inifile); xprintf(PSTR("%s"),str); } if (rwmode==CMD_MODE_WRITE) { n = ini_puts("p830f1", "label", &Line[4], inifile); SetStatusLabel(pkt830,&Line[4]); } break; case 'L' : /* Link */ xputs(PSTR("GUL command\n")); /* Alrighty. The MAG is already in the MRAG. All we actually need is ppssss where pp=hex page number and ssss=hex subcode */ n = ini_gets("p830f1", "initialpage", "003F7F", str, MAXSTR, inifile); break; case 'N' : /* Net IC */ if (rwmode==CMD_MODE_READ) { n = ini_gets("p830f1", "nic", "fa6f", str, sizearray(str), inifile); xprintf(PSTR("%s"),str); } if (rwmode==CMD_MODE_WRITE) { n = ini_puts("p830f1", "nic", &Line[4], inifile); SetNIC1(pkt830,&Line[4]); } break; case 'T' : /* Time */ xputs(PSTR("GUT command\n")); i2c_init(); break; default: str[0]=0; returncode=1; } break; case 'H': // H or HO. Set header if (Line[3]=='\0' || Line[5]=='\0') // Don't get confused by checksums { strcpy_P(str,PSTR(" ")); strncat(str,g_Header,32); // Just readback the header. TODO. Get the correct length str[40]=0; } else { strncpy(g_Header,&Line[9],32); // accept new header //g_Header[32]=0; // Make sure it is capped n = ini_puts("service", "header", g_Header, inifile); // Save this value back to the INI file. } break; case 'I': // III or I2 // I20xnnmm if (Line[2]=='2') // SAA7113 I2C. value. 0xnnmm where nn=address mm=value to write { strcpy_P(str,PSTR("Setting SAA7113 I2C register\n")); ptr=&Line[3]; xatoi(&ptr,&n); xprintf(PSTR("Blah=%04X\n"),n); i2c_SetRegister((n>>8)&0xff,n&0xff); xprintf(PSTR("Done\n")); } break; case 'J' : // J<h>,DATA - Send a packet to SRAM address // Probably want a whole family of J commands. // JA<h> - Set the address pointer to SRAM page <h> where <h> is 0..d // JW<data> - Write a complete 45 byte packet to the current address and increment // JR<data> - Read back the next block of data and increment the pointer. // [JT<h> - Retransmit page <h> immediately. (can't work. You must Tx the parent page) ] // JT<mpp> - Transmit page <mpp> immediately. (probably need to set a flag in the magazine stream // to insert the page in the next transmission slot switch (Line[2]) { case 'A': // eg. JA,0 - Set to the start of //xprintf(PSTR("JA set SRAM address (page level)\n")); Line[2]='0';Line[3]='x'; ptr=&Line[2]; xatoi(&ptr,&n); //xprintf(PSTR("JA page=%X SRAMPAGECOUNT=%X SRAMPAGEBASE=%X\n"),n,SRAMPAGECOUNT,SRAMPAGEBASE); if (n>=SRAMPAGECOUNT) // Make sure the page is in range returncode=1; else { n=SRAMPAGEBASE+n*SRAMPAGESIZE; // This is the actual address //xprintf(PSTR("JA address=%04X\n"),n); SRAMAddress=n; //row=1; } // We should now fill the packet with some instructions on how to use it! // Set the SRAM page address 0..e. There are 14 pages // Coarse address setting // For the lulz, JZ gives random access down to byte level break; case 'Z': // Jay-Z, geddit?, JZ<hex addr 16 bit> Line[2]='0';Line[3]='x'; ptr=&Line[2]; xatoi(&ptr,&n); //xprintf(PSTR("JZ set SRAM address (byte level)\n")); //xprintf(PSTR("JZ page=%04X\n"),n); // Set the SRAM page address at byte level. Needs an actual 16 bit address // where only 15 bits are used. // For finer control than the JA command. // For the lulz and ability to plonk stuff using random access. SRAMAddress=n; break; case 'W': // JW,<row>,data - Write a packet to the SRAM page buffer //xprintf(PSTR("JW Write SRAM data\n")); ptr=&Line[3]; while (*ptr>=' ' && !isdigit(*ptr)) ptr++; // Seek the row value row=atoi(ptr); if (!row) // Row address must be greater than 0 { returncode=1; break; } while (isdigit(*ptr) || *ptr==',') ptr++; // Seek the comma after row // If the fifo is transmitting, we must wait here for (i=0;FIFOBusy;i++); // Can this break if the video source has stopped? We may want to timeout on this! // xprintf(PSTR("JW addr=%d\n"),row); // Write a single packet // Not sure how we are going to map control codes but probably the same as OL // Write the packet that we are going to decode into @SRAMAddress // TODO: Check the row number to see we don't have a buffer overrun // Load and decode the packet // Replace this with a section that reads a line of data from USB // For the first attempt, I'll just copy the rest of the command line // I think it is null terminated? Hmm or \r // JW,<rest of command line> PORTC.OUT&=~VBIT_SEL; // Set the mux to MPU so that we are in control for (i=0;i<45;i++)packet[i]=0; WritePrefix(packet, 5, row); // This prefix gets replaced later packet[3]=row; // The row gets encoded just before writing to FIFO //row++; // MRG line format is bit 8 set if it is a control code < ' ' for (int i=5;i<45 && *ptr && *ptr!='\r';i++) { packet[i]=*ptr++ & 0x7f; } // ** find the address of the row ** n=SRAMAddress+(row-1)*PACKETSIZE; SetSerialRamAddress(SPIRAM_WRITE, n); //xprintf(PSTR("JW write address=%04X\n"),n); //SRAMAddress+=PACKETSIZE; WriteSerialRam(packet,45); DeselectSerialRam(); break; case 'R': xprintf(PSTR("JR Read back SRAM data\n")); // Read back a single packet (translated back into OL format) break; case 'T': xprintf(PSTR("JT Transmit mpp\n")); // Set a flag to transmit the selected page ASAP. break; default: returncode=1; } break; case 'L': // L<nn>,<line data> // We don't use L in vbit. Because it would require RAM buffering or more file writing, // instead we use the e command which writes the file directly. xprintf(PSTR("L command not implemented. Use 'e'\n")); str[0]=0; returncode=1; break; case 'M': // MD - Delete all the pages selected by the last P command. xprintf(PSTR("Delete...\n")); // Iterate down all the pages // Traverse down subpages and release nodes // Go into the pages index and null out the entries in pages.idx break; case 'O': /* O - Opt out. Example: O1c*/ /* Two digit hex number. Only 6 bits are used so the valid range is 0..3f */ ptr=&Line[0]; Line[0]='0';Line[1]='x'; xatoi(&ptr,&n); OptRelays=n & 0x3f; break; case 'P': // P<mppss>. An invalid character will set null. P without parameters will return the current value ptr=&Line[2]; if (!*ptr) { sprintf_P(str,PSTR("%s\n\r"),pageFilter); break; } dest=pageFilter; for (i=0;i<5;i++) { ch=*ptr++; if (ch=='*') valid=1; else { switch (i) { case 0 : // M valid=(ch>'0' && ch<'9' );break; case 1 :; // PP case 2 : valid=((ch>='0' && ch<='9') || (ch>='A' && ch<='F'));break; case 3 :; // SS case 4 : valid=(ch>='0' && ch<='9');break; } } if (valid) *dest++ = ch; else { dest[0]=0; break; } } *dest=0; // terminate the string // TODO: Find out how many pages are in this page range pagecount=FindPageCount(); if (pagecount<0) { pagecount=1; returncode=8; // TODO: At this point we must create the page, as we are about to receive the contents. xprintf(PSTR("Page has been created. Please send some data to fill the page\n\r")); } sprintf_P(str,PSTR("%04d"),pagecount); // Where nnn is the number of pages in this filter. 099 is a filler ack and checksum // str[0]=0; break; case 'Q' : // QO, QM if (Line[2]=='M') // QMnn { ptr=&Line[3]; xatoi(&ptr,&n); xprintf(PSTR("QM command, n=%d\n"),n); n = ini_putl("service", "serialmode", n, inifile); // And at this point put it into the vbi configuration // vbi_mode_serial=0 or CTRL_C11_MAGAZINESERIAL_bm /** TBA. This setting needs to be in the VBI section if (n) vbi_mode_serial=0; else vbi_mode_serial=CTRL_C11_MAGAZINESERIAL_bm; */ break; } // QO sets both odd and even lines // QD only sets the odd. if (Line[2]=='O' || Line[2]=='D') // QO[18 characters <P|Q|1..8|F>]. QD is the odd line and has 18 lines { int i; char ch; ptr=&Line[3]; xputc('0'); // Validate it. for (i=0;i<18;i++) { ch=*ptr++; switch (ch) { case '1':;case'2':;case'3':;case'4':;case'5':;case'6':;case'7':;case'8':;case'I':; case'F':; case'P':; case'Q':; case'Z':; break; default: returncode=1; } g_OutputActions[0][i]=ch; // odd field if (Line[2]=='O') g_OutputActions[1][i]=ch; // even field (QO only) } *ptr=0; if (returncode) break; n = ini_puts("service", "outputodd", &Line[3], inifile); if (Line[2]=='O') n = ini_puts("service", "outputeven", &Line[3], inifile); // QO only break; } returncode=1; break; // We could probably use the S command to encapsulate Newfor. We aren't going to be setting the page status much. case 'S' : ; // Newfor. This should be a Newfor command. Hmm, but how to escape SO and SI? // Work out how to escape data. The parity and reserved characters will break the CI break; case 'T': // T <hhmmss> (this syntax was superceded by GUT and GUt) // testIni(); // test3(); // test2(); // UTC is the time of day in seconds Line[8]=0; ptr=&(Line[2]); UTC=0; // Maybe save this. We need to revert if it fails. for (i=2;i<8;i++) { // First multiply according to which digit switch (i) { case 3:; case 5:; case 7: UTC*=10;break; case 4:; case 6: UTC*=6;break; // (already *10!) } ch=*(ptr++)-'0'; UTC+=ch; } // xprintf(PSTR("UTC=%d\n\r"),UTC); // This upsets the protocol! /** UTC=Line[7]-'0'; // s units UTC=UTC+(Line[6]-'0')*10; // s tens UTC=UTC+(Line[5]-'0')*60; // m units UTC=UTC+(Line[4]-'0')*60*10; // m tens UTC=UTC+(Line[3]-'0')*60*60; // h units UTC=UTC+(Line[2]-'0')*60*60*10; // h tens */ // strcpy_P(str,PSTR("OK\n")); str[0]=0; break; case 'U': // TEST Init830F1(); break; case 'V': // Communication settings. 2 hex chars (bit=(on/off) 7=Viewdata/Text 1=CRLF/CR 0=Echo/Silent // VBIT seems a bit fussy. When using TED Scheduler it is best to sat V00 pagecount=sscanf(&(Line[2]),"%2X",&i); // xprintf(PSTR("sscanf returns %d. Parameter is %X0\n\r"),pagecount,i); if (pagecount>0) { echoMode=i; // Yes, it was OK // TODO: Save the result in the INI } else returncode=1; // No, it failed break; case 'W': // TEST Ad-tec opt outs // W14 - Send a mode 14 opt out // We want to be able to test various ATP950 modes. // read the parameter ptr=&Line[2]; xatoi(&ptr,&n); OptOutMode=n; xprintf(PSTR("W=%04X\n"),OptOutMode); // Which command? Set the appropriate opt out mode switch (OptOutMode) { case 14: xprintf(PSTR("Mode 14 shenanigans\n"),n); // Or just flag that we want an opt-out packet OptOutMode=14; OptOutType=OPTOUT_START; // Assemble a mode 14 packet break; default: OptOutMode=0; returncode=1; } // Assemble the packet and break; case 'X': /* X - Exit */ return 2; case 'Y': /* Y - Version. Y2 should return a date string */ strcpy_P(str,PSTR("VBIT620 Version 0.04")); break; case '?' :; // Status TODO xprintf(PSTR("STATUS %02X\n\r"),statusI2C); // Want to know if the chips check out and the file system is OK // Video Input: xprintf(PSTR("Video input: "));report(statusI2C & 0x01); // chip responds, generating field interrupts // Digital Encoder xprintf(PSTR("Digital encoder: "));report(statusI2C & 0x02); // chip responds // FIFO statusFIFO=test2(); xprintf(PSTR("FIFO R/W verified: "));report(statusFIFO); // we can read and write to it // File system xprintf(PSTR("File system: "));report(statusDisk); // There is a card, it is formatted, it has onair/pages.all break; default: xputs(PSTR("Unknown command\n")); returncode=1; }