Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : PicoMite V5.07.08 betas
Page 11 of 11 | |||||
Author | Message | ||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9125 |
It was just a trivial bug when I introduced the ability to merge the layer when saving. Have a look at the PETSCII thread and the CSUB conversion thread. I could easily modify the blit memory command to take the encoded version which would reduce memory usage of the CSUB. My program that creates the CSUB from an old style sprite file could do the additional encoding Thoughts |
||||
disco4now Guru Joined: 18/12/2014 Location: AustraliaPosts: 897 |
Hi Peter, This is a Run Length Encoding method I played with at one time. Its from this thread. RLE image to SSD1963 * The image is stored using the following method. * The 3 bytes used to define each RGB888 pixel are reduced to 2 bytes encoded * as RGB565 ie. RRRRRGGG GGGBBBBB * This is then stored using Run Length Encoding (RLE). Each pixel is stored as * its two byte RGB565 code, unless a run of two or more identical pixel are detected. * In this case only the first two of these identical pixel are written, * a count is then made of the number of identical pixel beyond the first two. * This count is then recorded using 1,2 or 3 bytes a detailed below. * * If count <128 then a single Byte is used ie.0XXX XXXX B7=0 and B(6)-B(0) * contain the value. * If count < 16384 then two bytes are used. Byte 0 has B7=1 in to indicate * an addition Byte is required. i.e. * Byte 0 is 1XXX XXXX and Byte 1 has B7=0 is 0XXX XXXX .This leaves 14 bits * to store the counter. * For a counter of > 16383 then three bytes are used. B7=1 for Byte 1 indicating * another byte is required. ie. 1XXX XXXX 1XXX XXXX XXXX XXXX * All eight bits of Byte 2 are used to store the value, giving a total of 22 bits. * * This method of encoding is very effective when there are runs of the same pixel. * e.g. A full screen of the same colour is stored in 7 bytes. It can result in a bigger size if there are mostly runs of two pixels. In the CSUB header a bit could be used to indicate there is no RLE in these cases. This is the source of a CSUB I was working on the show icons from a CSUB. It is called with the address of the CSUB and the icon number to get. It extracts the RLE info and writes to screen. An enhancement I started on was to nominate 1 or 2 background colours which could be replaced when the icon is loaded. So the same icon could be loaded with say a red, yellow or Green backgound. If we could define a standard for these compressed icon,bitmaps sprites then the BLIT commands could be made to understand them on all the platforms and even use a CSUB to show them on the Micromites. I have progressed an editor in Purebasic that allows the editing/creation of the icons, even allows import of bmp files and generates the CSUB. I have not looked at it for sometime though. /******************************************************************************* * * MMBasic CSUB ShowIcon - Restores Run Length Encoded (RLE) image from * a CSUB in Program Memory onto SSD1963 LCD * acknowledgement to Peter Mather for various CFunctions for SSD1963 * and flash chips which have be used to provide many of the routines used. * When Generating the CSUB, use MERGE CSUB mode, and name the CSUB * RestoreImageRLE * * Entry point is function * void main(long long *x, long long *y, long long *width, long long *height, * long long *address,long long *cspin ) * * x,y,width and height defined the area of interest. 0,0,800,480 for the full screen * the width and height MUST match those used when storing the image, however x and y * can be different so its restored in a different position.The area must be with the * screen boundaries. * address is the page number to start reading from the flash chip. * cspin is the chip select pin allocated for the flash chip. (F_CS) 58 on an E100 * * Gerry Allardice 2020-2021 * V1.0 2020-12-30 Initial version for SSD1963 * V1.1 2021-01-25 Added OTM8009A 16bit mode ******************************************************************************/ //#define debugging // comment out on final version #define Version 100 //Version 1.0 #include <stdarg.h> #include <xc.h> // Required for SFR defs #include <sys/attribs.h> // Required to use __longramfunc__ #include "../CFunctions.h" /***** Uncomment the relevant line to compile for particular LCD******/ //#define SSD1963 //#define OTM8009A #define ILI9341P8 //#define ILI9341P16_64 '16bit on 64 pin port B9-B2 + E7-E0 //#define ILI9341P16_100 '16bit on 100 pin port A7-A0 + E7-E0 //#define ILI9341_SPI1_MX170 //#define ILI9341_SPI2_MX470 //#define ILI9488_SPI1_MX170 //#define ILI9488_SPI2_MX470 //#define ST7789_SPI1_MX170 //#define ST7789_SPI2_MX470 /*******************************************************************/ #ifdef SSD1963 //#define PINS64 //E64 driver Comment out for compilation for 100-pin part #define PINS100 //E100 driver Comment out for compilation for 64-pin part #define BITS8 //#define BITS16 #endif #ifdef ILI9341P8 void ShowIcon_for_ILI9341_8Bit_MX470(){ } #define ILI9341 #define MX470 #define PINS64 //E64 driver port E7-E0 #define BITS8 #endif #ifdef ILI9341P16_64 void ShowIcon_for_ILI9341_16Bit_64Pin(){ } #define ILI9341 #define MX470 #define PINS64 //E64 driver Comment out for compilation for 100-pin part //#define PINS100 //E100 driver Comment out for compilation for 64-pin part //#define BITS8 #define BITS16 #endif #ifdef OTM8009A #define PINS64 //E64 driver Comment out for compilation for 100-pin part //#define PINS100 //E100 driver Comment out for compilation for 64-pin part //#define BITS8 //8 bits on MCU and 74HC573 for bits 8-15 on LCD //clock bits 8-15 into a latch using RD pin #define BITS16 //16 bits on MCU bits 7-0 are E7-E0 on 100 and 64 pin // bit 15-8 are A7-A0 on 100 pin // bit 15-8 are B9-B2 on 64 pin #endif #ifdef ILI9341_SPI1_MX170 void ShowIcon_for_ILI9341_SPI1_MX170(){ } #define ILI9341SPI #define SPI2BYTE #define SPI #define MX170 #endif #ifdef ILI9341_SPI2_MX470 void ShowIcon_for_ILI9341_SPI2_MX470(){ } #define ILI9341SPI #define SPI2BYTE #define SPI #define MX470 #endif #ifdef ILI9488_SPI1_MX170 void ShowIcon_for_ILI9488_SPI1_MX170(){ } #define ILI9488SPI #define SPI3BYTE #define SPI #define MX170 #endif #ifdef ILI9488_SPI2_MX470 void ShowIcon_for_ILI9488_SPI2_MX470(){ } #define ILI9488SPI #define SPI3BYTE #define SPI #define MX470 #endif #ifdef ST7789_SPI1_MX170 void ShowIcon_for_ST7789_SPI1_MX170(){ } #define ST7789 #define SPI2BYTE #define SPI #define MX170 #endif #ifdef ST7789_SPI2_MX470 void ShowIcon_for_ST7789_SPI2_MX470(){ } #define ST7789 #define SPI2BYTE #define SPI #define MX470 #endif #define atrisinv *(volatile unsigned int *)(0xbf88601C) //latch registers #define aread *(volatile unsigned int *)(0xbf886020) //latch registers #define aport *(volatile unsigned int *)(0xbf886030) //latch register LATA #define aclrport *(volatile unsigned int *)(0xbf886034) //CLR for LATA #define asetport *(volatile unsigned int *)(0xbf886038) //SET for LATA #define btrisinv *(volatile unsigned int *)(0xbf88611C) //latch registers #define bread *(volatile unsigned int *)(0xbf886120) //latch registers #define bport *(volatile unsigned int *)(0xbf886130) //latch register LATB #define bclrport *(volatile unsigned int *)(0xbf886134) //CLR for LATB #define bsetport *(volatile unsigned int *)(0xbf886138) //SET for LATB #define ctrisinv *(volatile unsigned int *)(0xbf88621C) //latch registers #define cread *(volatile unsigned int *)(0xbf886220) //latch registers #define cport *(volatile unsigned int *)(0xbf886230) //latch register LATC #define cclrport *(volatile unsigned int *)(0xbf886234) //CLR for LATC #define csetport *(volatile unsigned int *)(0xbf886238) //SET for LATC #define etrisinv *(volatile unsigned int *)(0xbf88641C) //latch registers #define eread *(volatile unsigned int *)(0xbf886420) //latch registers #define eport *(volatile unsigned int *)(0xbf886430) //latch register LATE #define eclrport *(volatile unsigned int *)(0xbf886434) //CLR for LATE #define esetport *(volatile unsigned int *)(0xbf886438) //SET for LATE #define DEVID (*(volatile unsigned int *)0xBF80F220) #define TFT_CASET 0x2A #define TFT_RASET 0x2B #define TFT_RAMWR 0x2C #define TFT_RAMRD 0x2E #define TFT_MADCTL 0x36 #define TFT_MAD_MY 0x80 #define TFT_MAD_MX 0x40 #define TFT_MAD_MV 0x20 #define TFT_MAD_ML 0x10 #define TFT_MAD_RGB 0x00 #define TFT_MAD_BGR 0x08 #define TFT_MAD_MH 0x04 #define TFT_MAD_SS 0x02 #define TFT_MAD_GS 0x01 #define TFT_IDXRD 0x00 // ILI9341 only, indexed control register read #ifdef SPI #ifdef MX170 #define SPICON *(volatile unsigned int *)(0xbf805800) //SPI1 status register #define SPISTAT *(volatile unsigned int *)(0xbf805810) //SPI1 status register #define SPIBUF *(volatile unsigned int *)(0xbf805820) //SPI1 output buffer #define SPIBRG *(volatile unsigned int *)(0xbf805830) //SPI1 output buffer #define SPICON2 *(volatile unsigned int *)(0xbf805840) //SPI1 status register #define SPISTATCLR *(volatile unsigned int *)(0xbf805814) //SPI1 status clear register #endif #ifdef MX470 #define SPICON *(volatile unsigned int *)(0xbf805A00) //SPI2 control register #1 #define SPISTAT *(volatile unsigned int *)(0xbf805A10) //SPI2 status register #define SPIBUF *(volatile unsigned int *)(0xbf805A20) //SPI2 output buffer #define SPIBRG *(volatile unsigned int *)(0xbf805A30) //SPI2 speed register #define SPICON2 *(volatile unsigned int *)(0xbf805A40) //SPI2 control register #2 #define SPISTATCLR *(volatile unsigned int *)(0xbf805A14) //SPI1 status clear register #endif //#define ILImode 0x018520 //SPICON SPI MODE ? #define ILImode 0x018260 //SPICON Mode 0 CKE B(8)=0 CKP B(6)=1 //#define ILImode 0x008220 //SPICON Mode 1 CKE B(8)=0 CKP B(6)=0 //#define ILImode 0x018360 //SPICON Mode 2 CKE B(8)=1 CKP B(6)=1 //#define ILImode 0x018320 //SPICON Mode 3 CKE B(8)=1 CKP B(6)=0 //#define ILImode 0x8060 //SPICON #define SPIBRGValue 0x0 #define SPIsend(a) {int j;SPIBUF=a; while((SPISTAT & 0x80)==0); j=SPIBUF;} #define SPIqueue(a) {while(SPISTAT & 0x02){};SPIBUF=a;} #endif #ifdef SKIP void spi_write_command(unsigned char data){ PinSetBit(Option->LCD_CD, LATCLR); PinSetBit(Option->LCD_CS, LATCLR); SPIsend(data); PinSetBit(Option->LCD_CS, LATSET); } void spi_write_cd(unsigned char command, int data, ...){ int i; va_list ap; va_start(ap, data); spi_write_command(command); for(i = 0; i < data; i++) spi_write_data((char)va_arg(ap, int)); va_end(ap); } #endif #if defined ILI9341SPI || defined ILI9488SPI //ILI9341 and ILI9488 void defineregion(long x, long y, long width,long height){ long x1=x,x2=x+width-1,y1=y,y2=y+height-1; //PinSetBit(Option->LCD_CS, LATCLR); PinSetBit(Option->LCD_CD, LATCLR); SPIsend(TFT_CASET); PinSetBit(Option->LCD_CD, LATSET); SPIsend(x1 >> 8); SPIsend(x1); SPIsend(x2 >> 8); SPIsend(x2); PinSetBit(Option->LCD_CD, LATCLR); SPIsend(TFT_RASET); PinSetBit(Option->LCD_CD, LATSET); SPIsend(y1 >> 8); SPIsend(y1); SPIsend(y2 >> 8); SPIsend(y2); PinSetBit(Option->LCD_CD, LATCLR); SPIsend(TFT_RAMWR); PinSetBit(Option->LCD_CD, LATSET); //set CD high // PinSetBit(Option->LCD_CS, LATSET); } #endif #if defined ST7789 void defineregion(int xstart, int ystart, int width, int height) { int xend=xstart+width-1, yend=ystart+height-1; if(Option->DISPLAY_ORIENTATION==2){ ystart+=80; yend+=80; } if(Option->DISPLAY_ORIENTATION==1){ xstart+=80; xend+=80; } PinSetBit(Option->LCD_CD, LATCLR); //PinSetBit(Option->LCD_CS, LATCLR); //uSec(1000); SPIsend(TFT_CASET); PinSetBit(Option->LCD_CD, LATSET); uSec(1000); SPIsend(xstart >> 8); SPIsend(xstart); SPIsend(xend >> 8); SPIsend(xend); PinSetBit(Option->LCD_CD, LATCLR); //uSec(1000); SPIsend(TFT_RASET); PinSetBit(Option->LCD_CD, LATSET); uSec(1000); SPIsend(ystart >> 8); SPIsend(ystart); SPIsend(yend >> 8); SPIsend(yend); PinSetBit(Option->LCD_CD, LATCLR); // uSec(1000); SPIsend(TFT_RAMWR); //PinSetBit(Option->LCD_CS, LATSET); } #endif //Offsets into the persistent RAM of variables #ifdef PINS64 #define RS_Pin_No 27 #define WR_Pin_No 24 #define RS_Pin 0x1000 //bit 13 mask #define WR_Pin 0x0800 //bit 11 mask #define clrport bclrport #define setport bsetport #define port eport #define read eread #define trisinv etrisinv #ifdef ILI9341 #define RSLo {clrport=RS_Pin;} #define RSHi {setport=RS_Pin;} #define WRLo {clrport=WR_Pin;} #define WRHi {setport=WR_Pin;} #define RDLo (*(volatile unsigned int *)RDclrport)=RDpin #define RDHi (*(volatile unsigned int *)RDsetport)=RDpin #endif #ifdef SSD1963 void ShowIcon_for_SSD1963_8bit(){ } #define RSLo {clrport=RS_Pin;} #define RSHi {setport=RS_Pin;} #define WRLo {clrport=WR_Pin;} #define WRHi {setport=WR_Pin;} #define RDLo (*(volatile unsigned int *)RDclrport)=RDpin #define RDHi (*(volatile unsigned int *)RDsetport)=RDpin #endif #ifdef OTM8009A void ShowIcon_for_OTM8009A_16bit(){ } #define RD_Pin 0x8000 //b15 E64 #define RSLo bclrport=RS_Pin #define RSHi bsetport=RS_Pin #define WRLo bclrport=WR_Pin #define WRHi bsetport=WR_Pin #define RDLo bclrport=RD_Pin #define RDHi bsetport=RD_Pin #define CLKLo bclrport=RD_Pin; #define CLKHi bsetport=RD_Pin; #define WRTog WRLo; n=DEVID; WRHi; #endif #endif #ifdef PINS100 //E100 Board #define F_CS 58 // flashchip CS #define RS_Pin_No 18 //RE8 #define WR_Pin_No 19 //RE9 #define RD_Pin_No 6 // Pin 6/RC1 E100//if not used tie to 3.3v //RB15 pIN 30 #define RS_Pin 0x0100 //b8 portE #define WR_Pin 0x0200 //b9 portE #define RD_Pin 0x0002 //b1 portc #define clrport bclrport #define setport bsetport #define port eport #define read eread #define trisinv etrisinv #define RSLo eclrport=RS_Pin #define RSHi esetport=RS_Pin #define WRLo eclrport=WR_Pin #define WRHi esetport=WR_Pin #define RDLo cclrport=RD_Pin #define RDHi csetport=RD_Pin // #define RDTog RDLo;n=DEVID;n=DEVID;n=DEVID;n=DEVID;n=DEVID;n=DEVID;RDHi; #define RDTog RDLo;n=DEVID;n=DEVID;RDHi; #define WRTog WRLo;WRHi; #define WRTog3 WRLo;WRHi;WRLo;WRHi;WRLo;WRHi; // #define CLKLo bclrport=RD_Pin; // #define CLKHi bsetport=RD_Pin; // #define WRTog WRLo; n=DEVID; WRHi; // #define WRTog WRLo; n=DEVID;n=DEVID;WRHi; #endif #define Both WR_Pin | RS_Pin #define LANDSCAPE 1 #define PORTRAIT 2 #define RLANDSCAPE 3 #define RPORTRAIT 4 #ifdef debugging //Function that gets our address offset so we dont need to pass it in. __attribute__((noinline)) void getFPC(void *a, void *b, volatile unsigned int *c) { *c = (unsigned int) (__builtin_return_address (0) - (b -a)) ; } void pstring(const char *s){ volatile unsigned int libAddr ; getFPC(NULL,&&getFPCLab,&libAddr) ; // warning can be ignored, stupid editor getFPCLab: { } unsigned char * testData = (unsigned char *)((void *)s + libAddr ); MMPrintString(testData); } void p_int(int a,int base){ char b[64]; IntToStr(b,a,base); MMPrintString(b); } void p_float(float a,int m, int n, char c){ // m is the nbr of chars before the decimal point // n is the nbr chars after the point // ch is the leading pad char char b[14]; FloatToStr(b,a, m, n ,c); MMPrintString(b); } #endif void p_int(int a,int base){ char b[10]; IntToStr(b,a,base); MMPrintString(b); putConsole(32); } #ifdef OTM8009A /******************************************************************************* * * Write Data to a register on the OTM8009A Chip * ******************************************************************************/ void write_command_data16(unsigned int command, int data, ...){ long n; int i; int nextdata; #ifdef BITS8 CLKHi; //set CLK Hi to load latch RSLo; // i.e a command va_list ap; va_start(ap, data); //load bits 8-15 eclrport=(0xFF); // B0-B7 esetport=((command>>8) & 0xFF) ; //bits B15-B8 into B7-b0 CLKLo; //set CLK Lo to lock latch //B7-B0 in PORT E eclrport=(0xFF); // B0-B7 esetport=(command & 0xFF) ; //bits B7-B0 into B7-b0 WRTog; // RS low so send command CLKHi; //set CLK Hi to load latch RSHi; //ie data for(i = 0; i < data; i++) { nextdata=(char)va_arg(ap, int); //reads data in increments pointer CLKHi; //set CLK Hi to load latch eclrport=(0xFF); esetport=((nextdata>>8) & 0xFF) ; //bits B15-B8 into B7-b0 CLKLo; //set CLK Lo to lock latch eclrport=(0xFF); esetport=(nextdata & 0xFF) ; WRTog; // RS high so send data } va_end(ap); CLKHi; //set CLK Hi to load latch #endif #ifdef BITS16 RDHi; //set RD Hi if not tied to 3.3V RSLo; // i.e a command va_list ap; va_start(ap, data); //B7-B0 in PORT E eclrport=(0xFF); // B0-B7 esetport=(command & 0xFF) ; //bits B7-B0 into B7-b0 // B15-B8 in PORT C bclrport=(0x3FC); // B8-B15 bsetport=((command >> 6) & 0x3FC) ; //B15-8 moved to B9-B2 for B15-B8 WRTog;// WRLo; WRHi; // RS low RSHi; //ie data for(i = 0; i < data; i++) { nextdata=(char)va_arg(ap, int); //reads data in increments pointer eclrport=(0xFF); esetport=(nextdata & 0xFF) ; bclrport=(0x3FC); // B8-B15 bsetport=((nextdata >> 6) & 0x3FC) ; WRTog; } va_end(ap); #endif } /******************************************************************************* * * defines start/end coordinates for memory access from host to OTM8009A * also maps the start and end points to suit the orientation * * This function is a modified version of the function inside the MMBasic Interpreter * for MM+ on 'MX470 chips * *******************************************************************************/ void defineregion(long x, long y, long width,long height){ //ILI9325 long x1=x,x2=x+width-1,y1=y,y2=y+height-1; unsigned long xstart,xend,ystart,yend,Vertical,Horizontal; //xp,yp, if(HRes<VRes){ Vertical=VRes; Horizontal=HRes; } else { Vertical=HRes; Horizontal=VRes; } xstart = x1; xend = x2; ystart = y1; yend = y2; write_command_data16(0x2A00,1,xstart>>8); write_command_data16(0x2A01,1,xstart & 0xFF); write_command_data16(0x2A02,1,xend>>8); write_command_data16(0x2A03,1,xend & 0xFF); write_command_data16(0x2B00,1,ystart>>8); write_command_data16(0x2B01,1,ystart & 0xFF); write_command_data16(0x2B02,1,yend>>8); write_command_data16(0x2B03,1,yend & 0xFF); } #endif #ifdef ILI9341P8 /******************************************************************************* * * Write Data to a register on the Chip * ******************************************************************************/ void write_command_data(unsigned int command, int data, ...){ int i; #ifdef MX470 //RDHi; //set RD Hi if not tied to 3.3V RSLo; #endif va_list ap; va_start(ap, data); port=(command & 0x00FF) | WR_Pin; WRLo; WRHi; // RS low #ifdef MX470 RSHi; #endif for(i = 0; i < data; i++) { port= (char)va_arg(ap, int) | Both; WRLo; WRHi; //RS high } va_end(ap); } /******************************************************************************* * * defines start/end coordinates for memory access from host to ILI9341 * also maps the start and end points to suit the orientation *******************************************************************************/ void defineregion(long x, long y, long width,long height){ //ILI9341 long x1=x,x2=x+width-1,y1=y,y2=y+height-1; unsigned long xstart,xend,ystart,yend,Vertical,Horizontal; //xp,yp, if(HRes<VRes){ Vertical=VRes; Horizontal=HRes; } else { Vertical=HRes; Horizontal=VRes; } xstart = x1; xend = x2; ystart = y1; yend = y2; write_command_data(0x2A,4,xstart>>8,xstart,xend>>8,xend); write_command_data(0x2B,4,ystart>>8,ystart,yend>>8,yend); } #endif #ifdef SSD1963 /******************************************************************************* * * Write Data to a register on the Chip 8bit SSD1963 * ******************************************************************************/ void write_command_data(unsigned int command, int data, ...){ int i; RSLo; va_list ap; va_start(ap, data); port=(command & 0x00FF) | WR_Pin; WRLo; WRHi; // RS low RSHi; for(i = 0; i < data; i++) { port= (char)va_arg(ap, int) | Both; WRLo; WRHi; //RS high } va_end(ap); } /******************************************************************************* * * defines start/end coordinates for memory access from host to SSD1963 * also maps the start and end points to suit the orientation * *******************************************************************************/ void defineregion(long x, long y, long width,long height){ //SSD1963 long x1=x,x2=x+width-1,y1=y,y2=y+height-1; unsigned long xstart,xend,ystart,yend,Vertical,Horizontal; RSLo; if(HRes>VRes){ Vertical=VRes; Horizontal=HRes; } else { Vertical=HRes; Horizontal=VRes; } if(Option->DISPLAY_ORIENTATION!=LANDSCAPE)goto isP; xstart = x1; xend = x2; ystart = y1; yend = y2; if(Option->LCD_CD>6){ //reverse for 7" displays xstart = (Horizontal - 1) - x2; xend = (Horizontal - 1) - x1; } goto setreg; isP: if(Option->DISPLAY_ORIENTATION!=PORTRAIT)goto isRL; xstart = y1; xend = y2; ystart = (Vertical - 1) - x2; yend = (Vertical - 1) - x1; goto setreg; isRL: if(Option->DISPLAY_ORIENTATION!=RLANDSCAPE)goto isRP; xstart = (Horizontal - 1) - x2; xend = (Horizontal - 1) - x1; ystart = (Vertical - 1) - y2; yend = (Vertical - 1) - y1; if(Option->LCD_CD>6){//reverse for 7" displays xstart = x1; xend = x2; } goto setreg; isRP: xstart = (Horizontal - 1) - y2; xend = (Horizontal - 1) - y1; ystart = x1; yend = x2; setreg: port=0x22A ;WRLo; WRHi; // RS low RSHi; port=(xstart>>8 ) | Both; WRLo; WRHi; // RS HIGH port=(xstart) | Both; WRLo; WRHi; // RS HIGH port=(xend>>8 ) | Both; WRLo; WRHi; // RS HIGH port=(xend) | Both; WRLo; WRHi; // RS HIGH RSLo; port=0x22B ; WRLo; WRHi; // RS low RSHi; port=(ystart>>8 ) | Both; WRLo; WRHi; // RS HIGH port=(ystart) | Both; WRLo; WRHi; // RS HIGH port=(yend>>8 ) | Both; WRLo; WRHi; // RS HIGH port=(yend) | Both; WRLo; WRHi; // RS HIGH RSHi; } #endif /******************************************************************************* *CSUB ShowIcon - Restores RLE RGB565 image stored in program flash *as a CSUB and displays data on LCD screen SSD1963,OTM8009A * Usage: * ShowIcon x,y,iconno,addressofcsub,returncode * *****************************************************************************/ void main(long long *x, long long *y, long long *iconnumber, long long *iconaddr,long long *returncode){ long n; //used in WRTog DONT USE HERE for anything else // unsigned long bg1=*alt1,bg2=*alt2; // p_int(bg1,16); // p_int(bg2,16); // int t,m; // int add;//pin=*returncode; unsigned int iconno=*iconnumber,iconmax=0,iconstart=0; // add=*address<<8; //convert page number to byte number int x1=*x,y1=*y; // int width=*w,height=*h; int width=32,height=32; // unsigned int brgsave=0; unsigned long ch,cm,cl,i; unsigned long pixel1=0,pixel2=0,firstpixel=0;//,rle=0; unsigned long pcounter=0,pcounter1=0,pcounter2=0,pcounter3=0; int p; int pf=*iconaddr; //unsigned int iret; unsigned char iret; //char iret; *returncode=0; #ifdef SPI unsigned int consave=0,brgsave=0,con2save; //save any user SPI setup brgsave=SPIBRG; consave=SPICON; con2save=SPICON2; // switch to SPI enhanced mode for the bulk transfer SPICON=0x0; //Stops and resets the SPI //SPICON=ILImode; //SPICON=0x018260; SPICON = consave | (1 << 16); SPIBRG=0; //Set clock divider // SPIBRG=1; //Set clock divider 0x1 is /4 SPICON2=0xC00; PinSetBit(Option->LCD_CS, LATCLR); #endif /* Lets read in the CSUB RLE file and extract the pixels*/ i=0; p=0; // byte 0 is not used yet maybe a check byte in future. iret = *((char *)(pf+p)); p++; // byte 1 is the max number of icons. Over 255 will break it iret = *((char *)(pf+p)); p++; iconmax=iconmax | iret; if ((iconno+1)<=iconmax){ //Now find where the offset to where our icon starts is stored //The start address is high byte at 2+iconno*2 p=2+(iconno*2); iret = *((char *)(pf+p)); p++; iconstart=iret & 0xff ; iconstart=iconstart<<8; iret = *((char *)(pf+p)); p++; // p_int(iret,16); iconstart=iconstart | iret; //add the low byte // p_int(iconstart,16); //; putConsole(10); // putConsole(13); //The first two bytes are width and height for the icon p=iconstart; iret = *((char *)(pf+p)); p++; width=(iret & 0xFF); iret = *((char *)(pf+p)); p++; height=(iret & 0xFF); // p_int(width,16); // p_int(height,16); // p_int(width,10); // p_int(height,10); // putConsole(13); // if(x1 < 0) x1 = 0; if(x1 >= HRes) x1 = HRes - 1; // if(width < 0) width = 0; if(width > (HRes-x1)) width = HRes - x1; // if(y1 < 0) y1 = 0; if(y1 >= VRes) y1 = VRes - 1; // if(height < 0) height = 0; if(height > (VRes-y1)) height = VRes - y1; /* Move inside screen boundaries if it doesnt fit already*/ if(x1 < 0) x1 = 0; if(x1+width >= HRes) x1 = HRes -width; if(y1 < 0) y1 = 0; if(y1+height >= VRes) y1 = VRes -height; i=width*height; // p_int(i,10); // p_int(i,16); // putConsole(13); defineregion(x1,y1,width,height); #if defined SSD1963 || defined ILI9341 RSLo; port=0x22C ; WRLo; WRHi; // RS low RSHi; #endif #ifdef OTM8009A write_command_data16(0x2C00,0); //write to memory RSHi; //ie data RDHi; //set RD Hi if not tied to 3.3V #endif #ifdef SPI PinSetBit(Option->LCD_CD, LATSET); //PinSetBit(Option->LCD_CS, LATCLR); //SPIsend(data); //PinSetBit(Option->LCD_CS, LATSET); #endif while (i>0) { if (firstpixel==0){ //special case for first pixel //write to screen i--; firstpixel=1; ch = *((char *)(pf+p)); p++; ch = ch & 0xFF ; cl = *((char *)(pf+p)); p++; cl = cl & 0xFF ; pixel1=(ch<<8)|cl; #ifdef SSD1963 cm = ((ch << 5 ) & 0b11100000) | ((cl >> 3) & 0b00011100); ch= (ch & 0b11111000) ; cl= ((cl << 3) & 0b11111000); port=ch | Both; WRLo; WRHi; port=cm | Both; WRLo; WRHi; port=cl | Both; WRLo; WRHi; #endif #ifdef ILI9341P8 port=ch;WRLo;WRHi; port=cl;WRLo;WRHi; #endif #ifdef OTM8009A bclrport=(0x3FC); bsetport=(((ch<<2) & 0x3FC) ); eclrport=(0xFF); esetport=(cl & 0xFF); //B0-B7 is RE0-RE7 WRTog; #endif #ifdef SPI2BYTE SPIqueue(ch);SPIqueue(cl); #endif #ifdef SPI3BYTE cm = ((ch << 5 ) & 0b11100000) | ((cl >> 3) & 0b00011100); ch= (ch & 0b11111000) ; cl= ((cl << 3) & 0b11111000); SPIqueue(ch);SPIqueue(cm);SPIqueue(cl); #endif }else{ //subsequent pixels ch = *((char *)(pf+p)); p++; ch = ch & 0xFF ; cl = *((char *)(pf+p)); p++; cl = cl & 0xFF ; pixel2=(ch<<8)|cl; if (pixel1==pixel2) { //read the RLE count and write the second pixel //write repeated pixel to screen i--; #ifdef SSD1963 cm = ((ch << 5 ) & 0b11100000) | ((cl >> 3) & 0b00011100); ch= (ch & 0b11111000) ; cl= ((cl << 3) & 0b11111000); port=ch | Both; WRLo; WRHi; port=cm | Both; WRLo; WRHi; port=cl | Both; WRLo; WRHi; #endif #ifdef ILI9341P8 port=ch;WRLo;WRHi; port=cl;WRLo;WRHi; #endif #ifdef OTM8009A bclrport=(0x3FC); bsetport=(((ch<<2) & 0x3FC) ); eclrport=(0xFF); esetport=(cl & 0xFF); //B0-B7 is RE0-RE7 WRTog; #endif #ifdef SPI2BYTE SPIqueue(ch);SPIqueue(cl); #endif #ifdef SPI3BYTE cm = ((ch << 5 ) & 0b11100000) | ((cl >> 3) & 0b00011100); ch= (ch & 0b11111000) ; cl= ((cl << 3) & 0b11111000); SPIqueue(ch);SPIqueue(cm);SPIqueue(cl); #endif // now read the RLE counter pcounter1 = *((char *)(pf+p)); p++; if (pcounter1<128){ pcounter=pcounter1; }else{ pcounter1=(pcounter1 & 0b01111111); pcounter2 = *((char *)(pf+p)); p++; if (pcounter2<128){ pcounter=(pcounter1<<7) | pcounter2; }else{ pcounter2=(pcounter2 & 0b01111111); pcounter3 = *((char *)(pf+p)); p++; pcounter=(pcounter1<<15) | (pcounter2 <<8) | pcounter3; } } //p_int(i,10); // p_int(pcounter,10); // putConsole(13); while ( pcounter--) { //write repeated pixel to screen i--; #ifdef SSD1963 port=ch | Both; WRLo; WRHi; port=cm | Both; WRLo; WRHi; port=cl | Both; WRLo; WRHi; #endif #ifdef ILI9341P8 port=ch;WRLo;WRHi; port=cl;WRLo;WRHi; #endif #ifdef OTM8009A bclrport=(0x3FC); bsetport=(((ch<<2) & 0x3FC) ); eclrport=(0xFF); esetport=(cl & 0xFF); //B0-B7 is RE0-RE7 WRTog; #endif #ifdef SPI2BYTE SPIqueue(ch);SPIqueue(cl); #endif #ifdef SPI3BYTE SPIqueue(ch);SPIqueue(cm);SPIqueue(cl); #endif } //start new pixel firstpixel=0; }else{ //just a non matching pixel, no RLE in play //write to screen i--; #ifdef SSD1963 cm = ((ch << 5 ) & 0b11100000) | ((cl >> 3) & 0b00011100); ch= (ch & 0b11111000) ; cl= ((cl << 3) & 0b11111000); port=ch | Both; WRLo; WRHi; port=cm | Both; WRLo; WRHi; port=cl | Both; WRLo; WRHi; #endif #ifdef ILI9341P8 port=ch;WRLo;WRHi; port=cl;WRLo;WRHi; #endif #ifdef OTM8009A bclrport=(0x3FC); bsetport=(((ch<<2) & 0x3FC) ); eclrport=(0xFF); esetport=(cl & 0xFF); //B0-B7 is RE0-RE7 WRTog; #endif #ifdef SPI2BYTE SPIqueue(ch);SPIqueue(cl); #endif #ifdef SPI3BYTE cm = ((ch << 5 ) & 0b11100000) | ((cl >> 3) & 0b00011100); ch= (ch & 0b11111000) ; cl= ((cl << 3) & 0b11111000); SPIqueue(ch);SPIqueue(cm);SPIqueue(cl); #endif pixel1=pixel2; } } } #ifdef SPI while((SPISTAT & 0x80)==0); //wait for all writes to complete while(!(SPISTAT & 0x20)){i=SPIBUF;} // clean up rx fifo if not empty SPICON=0x0; //Stops and resets the SPI SPISTATCLR=0x40; // revert to previous SPI mode SPIBRG=brgsave; //restore user (or my) setup SPICON=consave; SPICON2=con2save; PinSetBit(Option->LCD_CS, LATSET); #endif } else{ *returncode=1; } } Latest F4 Latest H7 |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9125 |
Thanks for that but the images we are encoding are 4bit only so I'm going for something really simple each byte will be a nibble of count and then a nibble of colour. If the count is >15 then a second byte and possibly subsequent bytes for that colour will be needed. Seems to work well and is pretty efficient |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9125 |
NB: Re-upload at 9:34 UTC 17/09 to improve performance of compressed blits V5.07.08b17 https://geoffg.net/Downloads/picomite/PicoMite_Beta.zip Implements BLIT COMPRESSED address%, x%, y% [,col] This Blits a compressed csub to the current framebuffer (or VGA screen) see here for how to create a compressed CSUB from a Maximite style sprite file As before col is optional and specifies a colour that shouldn't be copied (-1 to 15) defaults to -1 if not specified indicating that all colours should be copied Edited 2023-09-17 20:35 by matherp |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4246 |
Some observations on b16 - when using layers, error messages are only shown on serial port, not screen - the inbuilt editor corrupt sprite files. Maybe something with eol termination Volhout PicomiteVGA PETSCII ROBOTS |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9125 |
Has always been the case but will consider switching to screen on error Files are tokenised when stored in memory and this may corrupt things which aren't Basic syntax. This is a limitation of the MMbasic editor and would need a big change to edit to and from disk |
||||
Mixtel90 Guru Joined: 05/10/2019 Location: United KingdomPosts: 6798 |
The PicoMite family never ceases to amaze me..... :) Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
vegipete Guru Joined: 29/01/2013 Location: CanadaPosts: 1109 |
Can these new versions of BLIT from flash include mirroring? (Left/Right and/or Up/Down.) Visit Vegipete's *Mite Library for cool programs. |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4246 |
Hi Peter, option base 1 dim a$(64) length 128 memory uses 9kbyte memory in 2 variables.... 2 ???? option base 1 dim a$(64,128) length 1 memory uses 16kbyte memory in 2 variables.... 16kbyte ? Any idea why 16 kbyte ? I am looking into a way to store bytes in a 64x128 array. Technically 8kbyte. The first option I can use MID$ to get the value. Another option is to use a long string, have not investigated yet. Volhout Edited 2023-09-18 06:20 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9125 |
No: they are designed for high speed. To mirror need massive amounts of nibble twiddling which is massively inefficient 64*129=8,256 rounds up to 9K 64*128*2=16284 = 16k Every string has a length byte so a string length of 1 takes 2 bytes Edited 2023-09-18 07:14 by matherp |
||||
carlschneider Senior Member Joined: 04/08/2023 Location: South AfricaPosts: 158 |
Hi Peter Would it be possible to allow an option to increase the cut, copy and paste buffer size in the EDITor? When doing development it would be nice to be able to cut and paste larger portions of code and then trim the buffer back to the smaller default when development is complete or memory space becomes challenging. Cheers Carl Retirement is tough on Hobbies without a day job |
||||
Mixtel90 Guru Joined: 05/10/2019 Location: United KingdomPosts: 6798 |
@ Volhout If you get the start address of the string +1 (to skip the length byte) then add an offset to it it's quicker to peek and poke than to use MID$ for individual bytes or words, I think. If you are after a numeric value, that is. Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9125 |
V5.07.08b18 https://geoffg.net/Downloads/picomite/PicoMite_Beta.zip Fixes a bug in multi-line comments When program errors occur and output is set to a framebuffer the firmware now automatically switches to the console so the error message is visible. Implements EDIT fname$ If a filename is specified the editor will load the file from the current disk (A: or B:) to allow editing and on exit with F1 or F2 save it to the disk. If the file does not exist it is created on exit. The current program stored in flash memory is not affected. If editing an existing file a backup with .bak appended to the filename is also created on exit. If fname$ includes an extension other than .bas then colour coding will be temporarily turned off during the edit. If no extension is specified the firmware will assume .bas Editing a file from disk allows non-Basic files such as html or sprite files to be edited without corruption during the tokenising process that happens when stored to flash. NB: edit without a filename works exactly as before. The program is loaded from flash memory and saved to flash memory. NB: On the PicoMiteVGA the edit command will automatically set to mode 1. The EDIT 1/2 version of the command is deprecated. SO: EDIT : from flash to flash EDIT fname$ : from disk to disk The edit buffer for cut and paste has been increased to 1024 characters but there is still a limitation that lines longer than the current display width cannot be cut and pasted. |
||||
carlschneider Senior Member Joined: 04/08/2023 Location: South AfricaPosts: 158 |
Thanks Peter Was the multi line comment bug related to /* something */ /* else /* Cheers Carl Retirement is tough on Hobbies without a day job |
||||
Amnesie Guru Joined: 30/06/2020 Location: GermanyPosts: 396 |
Nice implementation, but I guess with this amount of new things, it is a nightmare to keep the user manual up to date Greetings Daniel |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9125 |
It was related to any tokenisable code in the comment. Although the interpreter would skip everything in the comment, the tokeniser would get its knickers in a twist. For example a subroutine name in the comment would error if the same name occurred outside the comment. I hope now that anything in the comment is now ignored by the tokeniser and therefore won't cause problems The manual is only updated at each full release. In between you have to scan this sort of thread for anything new or changed Edited 2023-09-19 02:16 by matherp |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4246 |
Hi Peter, On 50708b17, just some observations: 1/ Now you have forced the editor in 80 column mode, is this something to do with "files" also ? 2/ When in mode2, and you type a command that is longer than the 40 characters screen width, the typing continues on the next line (wrap around) but the command typed is not accepted. Only the characters on the new line are seen as the new command. Thanks for your continued support. Volhout PicomiteVGA PETSCII ROBOTS |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9125 |
Has always and will always be the case No. Seemed to make sense as it is the mode that allows colour and a reasonable height and width. May look at this again - thoughts? |
||||
carlschneider Senior Member Joined: 04/08/2023 Location: South AfricaPosts: 158 |
Thanks Peter Yes that makes sense [in hindsight] and is what I experienced but didn't chase it down, because the sub routine I /*_*/ was required. All your effort and responsiveness is appreciated. Cheers Carl Retirement is tough on Hobbies without a day job |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4246 |
@Peter, Maybe some change for the user manual of the VGA version. The manual says sprites are numbered 1-64 The actual software allows only 32 sprites. Volhout. EDIT: it is actually 1-31. The error message is shown at the 32'th sprite loaded. Edited 2023-09-19 16:58 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
Page 11 of 11 |
Print this page |