diff --git a/Code/PicoMite.patch b/Code/PicoMite.patch new file mode 100644 index 0000000..1430b84 --- /dev/null +++ b/Code/PicoMite.patch @@ -0,0 +1,1562 @@ +diff --git a/Custom.c b/Custom.c +index e89e1ca..8bd5df5 100644 +--- a/Custom.c ++++ b/Custom.c +@@ -118,8 +118,8 @@ static char *labelsfound, *labelsneeded; + int piointerrupt=0; + static inline uint32_t pio_sm_calc_wrap(uint wrap_target, uint wrap) { + uint32_t calc=0; +- valid_params_if(PIO, wrap < PIO_INSTRUCTION_COUNT); +- valid_params_if(PIO, wrap_target < PIO_INSTRUCTION_COUNT); ++ //valid_params_if(PIO, wrap < PIO_INSTRUCTION_COUNT); ++ //valid_params_if(PIO, wrap_target < PIO_INSTRUCTION_COUNT); + return (calc & ~(PIO_SM0_EXECCTRL_WRAP_TOP_BITS | PIO_SM0_EXECCTRL_WRAP_BOTTOM_BITS)) | + (wrap_target << PIO_SM0_EXECCTRL_WRAP_BOTTOM_LSB) | + (wrap << PIO_SM0_EXECCTRL_WRAP_TOP_LSB); +diff --git a/Draw.c b/Draw.c +index 6cd1d59..a7ca5c0 100644 +--- a/Draw.c ++++ b/Draw.c +@@ -109,8 +109,8 @@ int PrintPixelMode=0; + + short CurrentX=0, CurrentY=0; // the current default position for the next char to be written + short DisplayHRes, DisplayVRes; // the physical characteristics of the display +-struct spritebuffer spritebuff[MAXBLITBUF+1] = { 0 }; +-struct blitbuffer blitbuff[MAXBLITBUF+1] = { 0 }; ++struct spritebuffer spritebuff[MAXBLITBUF+1] = { 0 }; ++struct blitbuffer blitbuff[MAXBLITBUF+1] = { 0 }; + char CMM1=0; + // the MMBasic programming characteristics of the display + // note that HRes == 0 is an indication that a display is not configured +@@ -155,6 +155,11 @@ int transparenthigh=0,transparentlow=0; + uint32_t mergetimer=0; + #endif + #endif ++ ++#ifdef HARDWARE_SCROLL ++short offsetY = 0; ++#endif ++ + void cmd_ReadTriangle(unsigned char *p); + void (*DrawRectangle)(int x1, int y1, int x2, int y2, int c) = (void (*)(int , int , int , int , int ))DisplayNotSet; + void (*DrawBitmap)(int x1, int y1, int width, int height, int scale, int fc, int bc, unsigned char *bitmap) = (void (*)(int , int , int , int , int , int , int , unsigned char *))DisplayNotSet; +@@ -171,7 +176,7 @@ void DrawTriangle(int x0, int y0, int x1, int y1, int x2, int y2, int c, int fil + // in the case of the MX170 this function is called directly by MMBasic when the GUI command is used + // in the case of the MX470 it is called by MX470GUI in GUI.c + const int colours[16]={0x00,0xFF,0x4000,0x40ff,0x8000,0x80ff,0xff00,0xffff,0xff0000,0xff00FF,0xff4000,0xff40ff,0xff8000,0xff80ff,0xffff00,0xffffff}; +-void MIPS16 initFonts(void){ ++void MIPS16 initFonts(void){ + FontTable[0] = (unsigned char *)font1; + FontTable[1] = (unsigned char *)Misc_12x20_LE; + #ifdef PICOMITEVGA +@@ -449,7 +454,7 @@ void ClearScreen(int c) { + for(int y=0;y x2 - x1) w = x2 - x1; + if(w > y2 - y1) w = y2 - y1; +- + if(w > 0) { + w--; ++ + DrawRectangle(x1, y1, x2, y1 + w, c); // Draw the top horiz line + DrawRectangle(x1, y2 - w, x2, y2, c); // Draw the bottom horiz line + DrawRectangle(x1, y1, x1 + w, y2, c); // Draw the left vert line + DrawRectangle(x2 - w, y1, x2, y2, c); // Draw the right vert line ++ + w++; + } + +@@ -1299,10 +1304,13 @@ void GUIPrintChar(int fnt, int fc, int bc, char c, int orientation) { + } + } else np = p; + +- if(orientation < ORIENT_CCW90DEG) DrawBitmap(CurrentX + modx, CurrentY + mody, width, height, scale, fc, bc, np); ++ if(orientation < ORIENT_CCW90DEG) { ++ DrawBitmap(CurrentX + modx, CurrentY + mody, width, height, scale, fc, bc, np); ++ } + else DrawBitmap(CurrentX + modx, CurrentY + mody, height, width, scale, fc, bc, np); + } else { +- if(orientation < ORIENT_CCW90DEG) DrawRectangle(CurrentX + modx, CurrentY + mody, CurrentX + modx + (width * scale), CurrentY + mody + (height * scale), bc); ++ if(orientation < ORIENT_CCW90DEG) DrawRectangle(CurrentX + modx, CurrentY +mody , CurrentX + modx + (width * scale), ++ CurrentY + mody + (height * scale), bc); + else DrawRectangle(CurrentX + modx, CurrentY + mody, CurrentX + modx + (height * scale), CurrentY + mody + (width * scale), bc); + } + +@@ -1323,6 +1331,7 @@ void GUIPrintChar(int fnt, int fc, int bc, char c, int orientation) { + } else { + if(c == '.') DrawCircle(CurrentX + modx + (width * scale)/2, CurrentY + mody + (height * scale) - 7 * scale, 4 * scale, 0, fc, fc, 1.0); + if(c == 0x60) DrawCircle(CurrentX + modx + (width * scale)/2, CurrentY + mody + 9 * scale, 6 * scale, 2 * scale, fc, -1, 1.0); ++ + } + } + +@@ -1493,7 +1502,7 @@ void cmd_pixel(void) { + } else { + c = gui_fcolour; // setup the defaults + if(argc == 5){ +- getargaddress(argv[4], &cptr, &cfptr, &nc); ++ getargaddress(argv[4], &cptr, &cfptr, &nc); + if(nc == 1) c = getint(argv[4], 0, WHITE); + else if(nc>1) { + if(nc < n) n=nc; //adjust the dimensionality +@@ -1569,7 +1578,7 @@ void cmd_circle(void) { + } else { + w = 1; c = gui_fcolour; f = -1; a = 1; // setup the defaults + if(argc > 5 && *argv[6]) { +- getargaddress(argv[6], &wptr, &wfptr, &nw); ++ getargaddress(argv[6], &wptr, &wfptr, &nw); + if(nw == 1) w = getint(argv[6], 0, 100); + else if(nw>1) { + if(nw > 1 && nw < n) n=nw; //adjust the dimensionality +@@ -1580,12 +1589,12 @@ void cmd_circle(void) { + } + } + if(argc > 7 && *argv[8]){ +- getargaddress(argv[8], &aptr, &afptr, &na); ++ getargaddress(argv[8], &aptr, &afptr, &na); + if(na == 1) a = getnumber(argv[8]); + if(na > 1 && na < n) n=na; //adjust the dimensionality + } + if(argc > 9 && *argv[10]){ +- getargaddress(argv[10], &cptr, &cfptr, &nc); ++ getargaddress(argv[10], &cptr, &cfptr, &nc); + if(nc == 1) c = getint(argv[10], 0, WHITE); + else if(nc>1) { + if(nc > 1 && nc < n) n=nc; //adjust the dimensionality +@@ -1596,7 +1605,7 @@ void cmd_circle(void) { + } + } + if(argc > 11){ +- getargaddress(argv[12], &fptr, &ffptr, &nf); ++ getargaddress(argv[12], &fptr, &ffptr, &nf); + if(nf == 1) f = getint(argv[12], -1, WHITE); + else if(nf>1) { + if(nf > 1 && nf < n) n=nf; //adjust the dimensionality +@@ -1832,7 +1841,7 @@ void cmd_line(void) { + } else { + long long int *x1ptr, *y1ptr, *x2ptr, *y2ptr, *wptr, *cptr; + MMFLOAT *x1fptr, *y1fptr, *x2fptr, *y2fptr, *wfptr, *cfptr; +- ++ + getargs(&cmdline, 11,(unsigned char *)","); + if(!(argc & 1) || argc < 3) error("Argument count"); + getargaddress(argv[0], &x1ptr, &x1fptr, &n); +@@ -1858,11 +1867,11 @@ void cmd_line(void) { + w = getint(argv[8], 1, 100); + } + if(argc == 11) c = getint(argv[10], 0, WHITE); +- DrawLine(x1, y1, x2, y2, w, c); ++ DrawLine(x1, y1, x2, y2, w, c); + } else { + c = gui_fcolour; w = 1; // setup the defaults + if(argc > 7 && *argv[8]){ +- getargaddress(argv[8], &wptr, &wfptr, &nw); ++ getargaddress(argv[8], &wptr, &wfptr, &nw); + if(nw == 1) w = getint(argv[8], 0, 100); + else if(nw>1) { + if(nw > 1 && nw < n) n=nw; //adjust the dimensionality +@@ -1873,7 +1882,7 @@ void cmd_line(void) { + } + } + if(argc == 11){ +- getargaddress(argv[10], &cptr, &cfptr, &nc); ++ getargaddress(argv[10], &cptr, &cfptr, &nc); + if(nc == 1) c = getint(argv[10], 0, WHITE); + else if(nc>1) { + if(nc > 1 && nc < n) n=nc; //adjust the dimensionality +@@ -1943,7 +1952,7 @@ void cmd_box(void) { + } + c = gui_fcolour; w = 1; // setup the defaults + if(argc > 7 && *argv[8]){ +- getargaddress(argv[8], &wptr, &wfptr, &nw); ++ getargaddress(argv[8], &wptr, &wfptr, &nw); + if(nw == 1) w = getint(argv[8], 0, 100); + else if(nw>1) { + if(nw > 1 && nw < n) n=nw; //adjust the dimensionality +@@ -1954,7 +1963,7 @@ void cmd_box(void) { + } + } + if(argc > 9 && *argv[10]) { +- getargaddress(argv[10], &cptr, &cfptr, &nc); ++ getargaddress(argv[10], &cptr, &cfptr, &nc); + if(nc == 1) c = getint(argv[10], 0, WHITE); + else if(nc>1) { + if(nc > 1 && nc < n) n=nc; //adjust the dimensionality +@@ -1965,7 +1974,7 @@ void cmd_box(void) { + } + } + if(argc == 13){ +- getargaddress(argv[12], &fptr, &ffptr, &nf); ++ getargaddress(argv[12], &fptr, &ffptr, &nf); + if(nf == 1) f = getint(argv[12], 0, WHITE); + else if(nf>1) { + if(nf > 1 && nf < n) n=nf; //adjust the dimensionality +@@ -2510,7 +2519,7 @@ void MIPS16 cmd_rbox(void) { + } else { + c = gui_fcolour; w = 1; // setup the defaults + if(argc > 7 && *argv[8]){ +- getargaddress(argv[8], &wptr, &wfptr, &nw); ++ getargaddress(argv[8], &wptr, &wfptr, &nw); + if(nw == 1) w = getint(argv[8], 0, 100); + else if(nw>1) { + if(nw > 1 && nw < n) n=nw; //adjust the dimensionality +@@ -2521,7 +2530,7 @@ void MIPS16 cmd_rbox(void) { + } + } + if(argc > 9 && *argv[10]) { +- getargaddress(argv[10], &cptr, &cfptr, &nc); ++ getargaddress(argv[10], &cptr, &cfptr, &nc); + if(nc == 1) c = getint(argv[10], 0, WHITE); + else if(nc>1) { + if(nc > 1 && nc < n) n=nc; //adjust the dimensionality +@@ -2532,7 +2541,7 @@ void MIPS16 cmd_rbox(void) { + } + } + if(argc == 13){ +- getargaddress(argv[12], &fptr, &ffptr, &nf); ++ getargaddress(argv[12], &fptr, &ffptr, &nf); + if(nf == 1) f = getint(argv[12], 0, WHITE); + else if(nf>1) { + if(nf > 1 && nf < n) n=nf; //adjust the dimensionality +@@ -2649,7 +2658,7 @@ void cmd_triangle(void) { // thanks to + } else { + c = gui_fcolour; f = -1; + if(argc >= 13 && *argv[12]) { +- getargaddress(argv[12], &cptr, &cfptr, &nc); ++ getargaddress(argv[12], &cptr, &cfptr, &nc); + if(nc == 1) c = getint(argv[10], 0, WHITE); + else if(nc>1) { + if(nc > 1 && nc < n) n=nc; //adjust the dimensionality +@@ -2660,7 +2669,7 @@ void cmd_triangle(void) { // thanks to + } + } + if(argc == 15){ +- getargaddress(argv[14], &fptr, &ffptr, &nf); ++ getargaddress(argv[14], &fptr, &ffptr, &nf); + if(nf == 1) f = getint(argv[14], -1, WHITE); + else if(nf>1) { + if(nf > 1 && nf < n) n=nf; //adjust the dimensionality +@@ -2711,8 +2720,8 @@ static inline char getnextnibble(char **fc, int reset){ + if(available==0){ + available=**fc & 0xF; //number of identical pixels + out=(**fc)>>4; +- (*fc)++; +- } ++ (*fc)++; ++ } + if(!reset)available--; + return out; + } +@@ -2750,7 +2759,7 @@ void docompressed(char *fc,int x1, int y1, int w, int h, int8_t blank){ + } + } else getnextnibble(&fc,0); + } +- if(ww>0 && xx10 && xx10)copyframetoscreen((unsigned char *)t,0, ww-1, y, y, xx&1); + } + if(x>=x1+w)break; +- } ++ } + } + } +- } else ++ } else + #endif + if(x1 %2 == 0 && w % 2 == 0 && blank==-1){ + char c, *to; +@@ -2815,9 +2824,9 @@ void docompressed(char *fc,int x1, int y1, int w, int h, int8_t blank){ + if(y<0 || y>=VRes)continue; + if(x>=0 && x0 && xx10 && xx10)copyframetoscreen((unsigned char *)t,0, ww-1, y, y, xx&1); + } + if(x>=x1+w)break; +- } ++ } + } + } +- } else ++ } else + #endif + if(x1 %2 == 0 && w % 2 == 0 && blank==-1){ + char c, *to; +@@ -2970,9 +2979,9 @@ void cmd_blitmemory(void){ + if(y<0 || y>=VRes)continue; + if(x>=0 && x0 && xx10 && xx10)copyframetoscreen((unsigned char *)t,0, ww-1, y, y, xx&1); + } + if(x>=x1+w)break; +- } ++ } + } + } +- } else ++ } else + #endif + if(x1 %2 == 0 && w % 2 == 0 && blank==-1){ + char c, *to; +@@ -3128,9 +3137,9 @@ int blitother(void){ + if(y<0 || y>=VRes)continue; + if(x>=0 && x=x1+w)break; +- } ++ } + } + } + return 1; +@@ -3350,7 +3359,7 @@ int blitother(void){ + *pp &=0xF0; + *pp |= fcolour; + } +- } ++ } + to=d+toy*(HRes>>1)+(x2>>1); //get the byte that will start the output + itoggle=0; + pp=from; +@@ -3394,6 +3403,10 @@ int blitother(void){ + return 0; + } + void cmd_cls(void) { ++#ifdef HARDWARE_SCROLL ++ ResetHWScroll(); ++#endif ++ + if(Option.DISPLAY_TYPE == 0) error("Display not configured"); + #ifdef PICOMITE + HideAllControls(); +@@ -3939,7 +3952,7 @@ void MIPS16 loadsprite(unsigned char* p) { + MMgetline(fnbr, (char*)buff); // get the input line + while (buff[0] == 39)MMgetline(fnbr, (char*)buff); + z=buff; +- { ++ { + getargs(&z,5,(unsigned char *)", "); + width=getinteger(argv[0]); + number=getinteger(argv[2]); +@@ -4942,10 +4955,10 @@ void copyframetoscreen(uint8_t *s,int xstart, int xend, int ystart, int yend, in + WriteComand(CMD_WR_MEMSTART); + } + int i; +- int cnt=2; ++ int cnt=2; + if(Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE==ILI9481IPS || (Option.DISPLAY_TYPE>=SSDPANEL && Option.DISPLAY_TYPE<=SSD_PANEL_8)){ + cnt=3; +- } ++ } + if(map[15]==0){ + for(i=0;i<16;i++){ + if(Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE==ILI9481IPS){ +@@ -5223,20 +5236,20 @@ void cmd_framebuffer(void){ + #ifdef PICOMITE + if(mergerunning)error("Display in use for merged operation"); + #endif +- restorepanel(); +- return; ++ restorepanel(); ++ return; + } + else if(checkstring(p, (unsigned char *)"L")){ + if(!LayerBuf)error("Layer buffer not created"); + WriteBuf=LayerBuf; + setframebuffer(); +- return; ++ return; + } + else if(checkstring(p, (unsigned char *)"F")){ + if(!FrameBuf)error("Frame buffer not created"); + WriteBuf=FrameBuf; + setframebuffer(); +- return; ++ return; + } + { + getargs(&p,1,(unsigned char *)","); +@@ -5246,7 +5259,7 @@ void cmd_framebuffer(void){ + #ifdef PICOMITE + if(mergerunning)error("Display in use for merged operation"); + #endif +- restorepanel(); ++ restorepanel(); + } else if(strcasecmp(q,"L")==0){ + if(!LayerBuf)error("Layer buffer not created"); + WriteBuf=LayerBuf; +@@ -5302,7 +5315,7 @@ void cmd_framebuffer(void){ + SoftReset(); + } + } +- } else ++ } else + #endif + merge(colour); + #endif +@@ -5326,7 +5339,7 @@ void cmd_framebuffer(void){ + } + } + #endif +- if(WriteBuf!=LayerBuf)restorepanel(); ++ if(WriteBuf!=LayerBuf)restorepanel(); + if(FrameBuf)FreeMemory(FrameBuf); + FrameBuf=NULL; + } else if(checkstring(p, (unsigned char *)"L")){ +@@ -5340,7 +5353,7 @@ void cmd_framebuffer(void){ + } + } + #endif +- if(WriteBuf!=FrameBuf)restorepanel(); ++ if(WriteBuf!=FrameBuf)restorepanel(); + if(LayerBuf)FreeMemory(LayerBuf); + LayerBuf=NULL; + } else closeframebuffer(); +@@ -5354,7 +5367,7 @@ void cmd_framebuffer(void){ + if(checkstring(argv[4],(unsigned char *)"B"))background=1; + else error("Syntax"); + } +-#else ++#else + int complex=0; + unsigned char *buff = WriteBuf; + getargs(&p,3,(unsigned char *)","); +@@ -5374,7 +5387,7 @@ void cmd_framebuffer(void){ + else if(checkstring(argv[2],(unsigned char *)"L"))d=LayerBuf; + else if(checkstring(argv[2],(unsigned char *)"F"))d=FrameBuf; + else error("Syntax"); +- ++ + if(d!=s){ + if(!complex) memcpy(d,s,HRes*VRes/2); + else { +@@ -5384,13 +5397,13 @@ void cmd_framebuffer(void){ + if(DrawBufferSPI==DrawBuffer || DrawBufferSSD1963==DrawBuffer) DisplayMode=1; + WriteBuf=d; + for(int y=0;y= 0) { + for(int i=0;i>1),s=(i+lines)*(HRes>>1); ++ int d=i*(HRes>>1),s=(i+lines)*(HRes>>1); + for(int c=0;c<(HRes>>1);c++)WriteBuf[d+c]=WriteBuf[s+c]; + } + DrawRectangle(0, VRes-lines, HRes - 1, VRes - 1, PromptBC); // erase the lines to be scrolled off + } else { + lines=-lines; + for(int i=VRes-1;i>=lines;i--) { +- int d=i*(HRes>>1),s=(i-lines)*(HRes>>1); ++ int d=i*(HRes>>1),s=(i-lines)*(HRes>>1); + for(int c=0;c<(HRes>>1);c++)WriteBuf[d+c]=WriteBuf[s+c]; + } + DrawRectangle(0, 0, HRes - 1, lines - 1, PromptBC); // erase the lines introduced at the top +@@ -6660,7 +6673,7 @@ void ScrollLCDMono(int lines){ + } + #endif + for(int i=0;i>3),s=(i+lines)*(HRes>>3); ++ int d=i*(HRes>>3),s=(i+lines)*(HRes>>3); + for(int c=0;c<(HRes>>3);c++)WriteBuf[d+c]=WriteBuf[s+c]; + } + DrawRectangle(0, VRes-lines, HRes - 1, VRes - 1, 0); // erase the lines to be scrolled off +@@ -6682,7 +6695,7 @@ void ScrollLCDMono(int lines){ + } + #endif + for(int i=VRes-1;i>=lines;i--) { +- int d=i*(HRes>>3),s=(i-lines)*(HRes>>3); ++ int d=i*(HRes>>3),s=(i-lines)*(HRes>>3); + for(int c=0;c<(HRes>>3);c++)WriteBuf[d+c]=WriteBuf[s+c]; + } + DrawRectangle(0, 0, HRes - 1, lines - 1, 0); // erase the lines introduced at the top +@@ -6710,7 +6723,7 @@ void DrawBufferMono(int x1, int y1, int x2, int y2, unsigned char *p){ + if(y2 >= VRes) y2 = VRes - 1; + for(y=y1;y<=y2;y++){ + for(x=x1;x<=x2;x++){ +- c.rgbbytes[0]=*p++; ++ c.rgbbytes[0]=*p++; + if(c.rgbbytes[0]<0x40)c.rgbbytes[0]=0; + c.rgbbytes[1]=*p++; + if(c.rgbbytes[1]<0x40)c.rgbbytes[1]=0; +@@ -6779,7 +6792,7 @@ void ReadBufferMono(int x1, int y1, int x2, int y2, unsigned char *c){ + if(y2 >= VRes) yy2 = VRes - 1; + for(y=yy1;y<=yy2;y++){ + for(x=xx1;x<=xx2;x++){ +-#ifdef PICOMITEVGA ++#ifdef PICOMITEVGA + int tile= x/8 + (y/ytilecount)*X_TILE; + int back=RGB121map[tilebcols[tile] & 0xF]; + int front=RGB121map[tilefcols[tile] & 0xF]; +@@ -6935,25 +6948,34 @@ void MIPS16 DrawBitmapUser(int x1, int y1, int width, int height, int scale, int + error("MM.USER_BITMAP not defined"); + } + +- + void ScrollLCDSPI(int lines){ + if(lines==0)return; ++#ifdef HARDWARE_SCROLL ++ if (lines >= 0) { ++ HWScroll(offsetY); ++ } ++ ++ if(PinDef[Option.SYSTEM_CLK].mode & SPI0SCK)spi_finish(spi0); ++ else spi_finish(spi1); ++ ClearCS(Option.LCD_CS); ++#else + unsigned char *buff=GetMemory(3*HRes); + if(lines >= 0) { + for(int i=0;i=lines;i--) { + ReadBLITBuffer(0, i-lines, HRes -1, i-lines, buff); +- DrawBLITBuffer(0, i, HRes - 1, i, buff); ++ DrawBLITBuffer(0, i, HRes - 1, i, buff); + } + DrawRectangle(0, 0, HRes - 1, lines - 1, gui_bcolour); // erase the lines introduced at the top + } + FreeMemory(buff); ++#endif + } + #endif + +@@ -6982,7 +7004,11 @@ void SetFont(int fnt) { + gui_font_width = FontTable[fnt >> 4][0] * (fnt & 0b1111); + gui_font_height = FontTable[fnt >> 4][1] * (fnt & 0b1111); + if(Option.DISPLAY_CONSOLE) { ++#ifdef HARDWARE_SCROLL ++ Option.Height = LCD_HEIGHT/gui_font_height; ++#else + Option.Height = VRes/gui_font_height; ++#endif + Option.Width = HRes/gui_font_width; + } + gui_font = fnt; +@@ -7122,16 +7148,31 @@ void DisplayPutC(char c) { + CurrentY -= gui_font_height ; //Go up one line + if (CurrentY < 0) CurrentY = 0; + CurrentX = (Option.Width-1) * gui_font_width; //go to last character +- } ++ } + return; + case '\r': CurrentX = 0; + return; + case '\n': CurrentY += gui_font_height; +- if(CurrentY + gui_font_height >= VRes) { ++ if(CurrentY + gui_font_height >= LCD_HEIGHT) { + if(Option.NoScroll && Option.DISPLAY_CONSOLE){ClearScreen(gui_bcolour);CurrentX=0;CurrentY=0;} + else { ++#ifdef HARDWARE_SCROLL ++ int lines= 0; ++ lines = CurrentY + gui_font_height - LCD_HEIGHT; ++ DrawRectangleSPI(CurrentX,CurrentY,HRes-1,CurrentY+lines,BLACK); ++ offsetY += lines; ++ if(offsetY >= LCD_REAL_HEIGHT){ ++ offsetY -= LCD_REAL_HEIGHT; ++ } ++ ++ ScrollLCDSPI(lines); ++ ++ CurrentY -= lines; ++#else ++ + ScrollLCD(CurrentY + gui_font_height - VRes); + CurrentY -= (CurrentY + gui_font_height - VRes); ++#endif + } + } + return; +diff --git a/Editor.c b/Editor.c +index 02595ff..1f514d4 100644 +--- a/Editor.c ++++ b/Editor.c +@@ -43,7 +43,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + #define GUI_C_KEYWORD CYAN + #define GUI_C_QUOTE MAGENTA + #define GUI_C_NUMBER GREEN +-#define GUI_C_LINE MAGENTA ++#define GUI_C_LINE BLUE + #define GUI_C_STATUS WHITE + + //====================================================================================== +@@ -64,6 +64,11 @@ int StartEditChar = 0; + static bool markmode=false; + extern void routinechecks(void); + int optioncolourcodesave; ++#ifdef HARDWARE_SCROLL ++//replace all VRes to LCD_HEIGHT here ++extern short offsetY; ++#endif ++ + #if !defined(LITE) + #ifdef PICOMITEVGA + int editactive=0; +@@ -147,6 +152,7 @@ static char (*SSputchar)(char buff, int flush)=SerialConsolePutC; + void MX470Display(int fn) { + int t; + if(!Option.DISPLAY_CONSOLE) return; ++ int op_height; + switch(fn) { + case DISPLAY_CLS: ClearScreen(gui_bcolour); + break; +@@ -176,16 +182,27 @@ static char (*SSputchar)(char buff, int flush)=SerialConsolePutC; + break; + #endif + case CLEAR_TO_EOS: DrawBox(CurrentX, CurrentY, HRes-1, CurrentY + gui_font_height-1, 0, 0, gui_bcolour); +- DrawRectangle(0, CurrentY + gui_font_height, HRes-1, VRes-1, gui_bcolour); ++ DrawRectangle(0, CurrentY + gui_font_height, HRes-1, LCD_HEIGHT-1, gui_bcolour); ++ + break; + case SCROLL_DOWN: + break; ++#ifdef HARDWARE_SCROLL ++ case DRAW_LINE: ++ op_height = LCD_HEIGHT / gui_font_height; ++ DrawBox(0, gui_font_height * (op_height - 2), HRes - 1, LCD_HEIGHT - 1, 0, 0, ++ (DISPLAY_TYPE == MONOVGA ? 0 : gui_bcolour)); ++ DrawLine(0, LCD_HEIGHT - gui_font_height - 6, HRes - 1, LCD_HEIGHT - gui_font_height - 6, 1, ++ GUI_C_LINE); ++ ++#else + case DRAW_LINE: DrawBox(0, gui_font_height * (Option.Height - 2), HRes - 1, VRes - 1, 0, 0, (DISPLAY_TYPE==MONOVGA ? 0 :gui_bcolour)); + DrawLine(0, VRes - gui_font_height - 6, HRes - 1, VRes - gui_font_height - 6, 1, GUI_C_LINE); ++#endif + #ifdef PICOMITEVGA + if(DISPLAY_TYPE==MONOVGA && Option.ColourCode && ytilecount==12 && gui_font==1)for(int i=0; i<80; i++)tilefcols[38*X_TILE+i]=Option.VGAFC; + #endif +- CurrentX = 0; CurrentY = VRes - gui_font_height; ++ CurrentX = 0; CurrentY = LCD_HEIGHT - gui_font_height; + break; + } + } +@@ -260,8 +277,11 @@ void cmd_edit(void) { + #endif + EdBuff = GetTempMemory(EDIT_BUFFER_SIZE); + *EdBuff = 0; +- ++#ifdef HARDWARE_SCROLL ++ VHeight = LCD_HEIGHT/gui_font_height - 2; ++#else + VHeight = Option.Height - 2; ++#endif + VWidth = Option.Width; + edx = edy = curx = cury = y = x = tempx = 0; + txtp = EdBuff; +@@ -325,11 +345,21 @@ void cmd_edit(void) { + if(p > EdBuff) --p; + *p = 0; // erase the last line terminator + //Only setterminal if editor requires is bigger than 80*24 ++#ifdef HARDWARE_SCROLL ++ int op_height = LCD_HEIGHT/gui_font_height; ++ if (Option.Width > SCREENWIDTH || op_height > SCREENHEIGHT){ ++ setterminal((op_height> SCREENHEIGHT)?op_height:SCREENHEIGHT,(Option.Width > SCREENWIDTH)?Option.Width:SCREENWIDTH); // or height is > 24 ++ } ++#else + if (Option.Width > SCREENWIDTH || Option.Height > SCREENHEIGHT){ + setterminal((Option.Height > SCREENHEIGHT)?Option.Height:SCREENHEIGHT,(Option.Width > SCREENWIDTH)?Option.Width:SCREENWIDTH); // or height is > 24 + } ++#endif + PrintString("\033[?1000h"); // Tera Term turn on mouse click report in VT200 mode + PrintString("\0337\033[2J\033[H"); // vt100 clear screen and home cursor ++#ifdef HARDWARE_SCROLL ++ ResetHWScroll(); ++#endif + MX470Display(DISPLAY_CLS); // clear screen on the MX470 display only + SCursor(0, 0); + PrintFunctKeys(EDIT); +@@ -676,7 +706,11 @@ void FullScreenEditor(int xx, int yy, char *fname) { + // this must be an ordinary escape (not part of an escape code) + if(TextChanged) { + GetInputString((unsigned char *)"Exit and discard all changes (Y/N): "); +- if(toupper(*inpbuf) != 'Y') break; ++ if(toupper(*inpbuf) == 'Y'){ ++ goto exit_switch; ++ }else{ ++ break; ++ } + } + // fall through to the normal exit + +@@ -837,6 +871,9 @@ void FullScreenEditor(int xx, int yy, char *fname) { + for(i = 0; i < MAXCLIP + 1; i++) buf[i] = buf[i + 1]; // suffle down the buffer to get the next char + } while(*buf); + } ++exit_switch: ++ ResetHWScroll(); ++ ClearScreen(gui_bcolour); + } + + +@@ -1299,13 +1336,13 @@ void printLine(int ln) { + p = findLine(ln, &inmulti); + // i = VWidth - 1; // I think this is wrong. Does not show last character in line G.A. + i = VWidth ; ++ MX470Display(CLEAR_TO_EOL); + while(i && *p && *p != '\n') { + if(!inmulti)SetColour((unsigned char *)p, false); // set the colour for the LCD display only + else gui_fcolour = GUI_C_COMMENT; + MX470PutC(*p++); // print on the MX470 display + i--; + } +- MX470Display(CLEAR_TO_EOL); // clear to the end of line on the MX470 display only + } + SetColour(NULL, false); + +@@ -1445,7 +1482,7 @@ void PrintStatus(void) { + strcat(s, " "); + strcpy(s + 19, insert?"INS":"OVR"); + +- MX470Cursor((VWidth - strlen(s)) * gui_font_width, VRes - gui_font_height); ++ MX470Cursor((VWidth - strlen(s)) * gui_font_width, LCD_HEIGHT - gui_font_height); + MX470PutS(s, GUI_C_STATUS, gui_bcolour); // display the string on the display attached to the MX470 + + SCursor(VWidth - 25, VHeight + 1); +@@ -1463,7 +1500,7 @@ void editDisplayMsg(unsigned char *msg) { + SCursor(0, VHeight + 1); + if(Option.ColourCode) PrintString(VT100_C_ERROR); + PrintString("\033[7m"); +- MX470Cursor(0, VRes - gui_font_height); ++ MX470Cursor(0, LCD_HEIGHT - gui_font_height); + PrintString((char *)msg); + MX470PutS((char *)msg, BLACK, RED); + if(Option.ColourCode) PrintString(VT100_C_NORMAL); +@@ -1499,15 +1536,19 @@ void GetInputString(unsigned char *prompt) { + + SCursor(0, VHeight + 1); + PrintString((char *)prompt); +- MX470Cursor(0, VRes - gui_font_height); ++ MX470Cursor(0, LCD_HEIGHT - gui_font_height); + MX470PutS((char *)prompt, gui_fcolour, gui_bcolour); + for(i = 0; i < VWidth - strlen((char *)prompt); i++) { + SSputchar(' ',1); + MX470PutC(' '); + } + SCursor(strlen((char *)prompt), VHeight + 1); +- MX470Cursor(strlen((char *)prompt) * gui_font_width, VRes - gui_font_height); ++ MX470Cursor(strlen((char *)prompt) * gui_font_width, LCD_HEIGHT - gui_font_height); ++#ifdef PICOCALC ++ for(p = inpbuf; (*p = MMgetchar()) != '\n'; p++) { // get the input ++#else + for(p = inpbuf; (*p = MMgetchar()) != '\r'; p++) { // get the input ++#endif + if(*p == 0xb3 || *p == F3 || *p == ESC) { p++; break; } // return if it is SHIFT-F3, F3 or ESC + if(isprint(*p)) { + SSputchar(*p,1); // echo the char +diff --git a/External.c b/External.c +index 5c76cdc..3167eb7 100644 +--- a/External.c ++++ b/External.c +@@ -1527,34 +1527,11 @@ void PWMoff(int slice){ + pwm_set_enabled(slice, false); + } + #ifndef PICOMITEVGA +-void setBacklight(int level){ +- if(((Option.DISPLAY_TYPE>I2C_PANEL && Option.DISPLAY_TYPE=SSDPANEL && Option.DISPLAY_TYPE65535){ +- wrap>>=1; +- if(level>=0.0)high>>=1; +- div<<=1; +- } +- wrap--; +- if(div!=1)pwm_set_clkdiv(BacklightSlice,(float)div); +- pwm_set_wrap(BacklightSlice, wrap); +- pwm_set_chan_level(BacklightSlice, BacklightChannel, high); +- } else if(Option.DISPLAY_TYPE<=I2C_PANEL){ +- level*=255; +- level/=100; +- I2C_Send_Command(0x81);//SETCONTRAST +- I2C_Send_Command((uint8_t)level); +- } else if(Option.DISPLAY_TYPE>=SSDPANEL && Option.DISPLAY_TYPE>8; +- if(c==6)c=ESC; +- if(c==0x11)c=F1; +- if(c==5)c=F2; +- if(c==0x7)c=F4; ++ int realc=0; ++ switch(c) { ++ case 0xb1: ++ realc = ESC;break; ++ case 0x81: ++ realc = F1;break; ++ case 0x82: ++ realc=F2;break; ++ case 0x83: ++ realc=F3;break; ++ case 0x84: ++ realc=F4;break; ++ case 0x85: ++ realc=F5;break; ++ case 0x86: ++ realc=F6;break; ++ case 0x87: ++ realc=F7;break; ++ case 0x88: ++ realc=F8;break; ++ case 0x89: ++ realc=F9;break; ++ case 0x90: ++ realc=F10;break; ++ case 0xb5: ++ realc=UP;break; ++ case 0xb6: ++ realc=DOWN;break; ++ case 0xb7: ++ realc=RIGHT;break; ++ case 0xb4: ++ realc=LEFT;break; ++ case 0xd0: ++ realc=BreakKey;break; ++ case 0xd1: ++ realc=INSERT;break; ++ case 0xd2: ++ realc=HOME;break; ++ case 0xd5: ++ realc=END; break; ++ case 0xd6: ++ realc=PUP;break; ++ case 0xd7: ++ realc=PDOWN;break; ++ default: ++ realc = c; ++ break; ++ } ++ c = realc; ++ + if(c>='a' && c<='z' && ctrlheld)c=c-'a'+1; + if(c==BreakKey) + { // if the user wants to stop the progran +diff --git a/I2C.h b/I2C.h +index 8b048df..cb1d918 100644 +--- a/I2C.h ++++ b/I2C.h +@@ -81,6 +81,7 @@ extern char *I2C_Slave_Send_IntLine; // pointer t + extern char *I2C_Slave_Receive_IntLine; // pointer to the slave receive interrupt line number + extern char *I2C2_Slave_Send_IntLine; // pointer to the slave send interrupt line number + extern char *I2C2_Slave_Receive_IntLine; // pointer to the slave receive interrupt line number ++extern void I2C_Send_RegData(int i2caddr,int reg,char command); + extern void I2C_Send_Command(char command); + extern void CheckI2CKeyboard(int noerror, int read); + extern void cmd_camera(unsigned char *p); +diff --git a/MM_Misc.c b/MM_Misc.c +index 5f17ab7..76ddaf4 100644 +--- a/MM_Misc.c ++++ b/MM_Misc.c +@@ -2031,8 +2031,13 @@ void MIPS16 ConfigDisplayUser(unsigned char *tp){ + } + void MIPS16 clear320(void){ + if(SPI480){ ++#ifdef PICOCALC ++ HRes=320; ++ VRes=480; ++#else + HRes=480; + VRes=320; ++#endif + return; + } + screen320=0; +diff --git a/PicoMite.c b/PicoMite.c +index a6e2400..74ab630 100644 +--- a/PicoMite.c ++++ b/PicoMite.c +@@ -2564,11 +2564,12 @@ int MIPS16 main(){ + #endif + InitBasic(); + #ifndef PICOMITEVGA +- InitDisplaySSD(); ++ //InitDisplaySSD(); + InitDisplaySPI(0); +- InitDisplayI2C(0); +- InitDisplayVirtual(); ++ //InitDisplayI2C(0); ++ //InitDisplayVirtual(); + InitTouch(); ++ uSec(300000); + if(Option.BackLightLevel)setBacklight(Option.BackLightLevel); + #endif + ErrorInPrompt = false; +diff --git a/SPI-LCD.c b/SPI-LCD.c +index bc78290..e3f2c0b 100644 +--- a/SPI-LCD.c ++++ b/SPI-LCD.c +@@ -131,6 +131,7 @@ void DrawBufferMEM(int x1, int y1, int x2, int y2, unsigned char* p) ; + void ReadBufferMEM(int x1, int y1, int x2, int y2, unsigned char* buff); + void spi_write_CommandData(const uint8_t* pCommandData, uint8_t datalen); + void ST7920command(unsigned char data); ++extern short offsetY; + // utility function for routines that want to reserve a pin for special I/O + // this ignores any previous settings and forces the pin to its new state + // pin is the pin number +@@ -273,10 +274,105 @@ void MIPS16 InitDisplaySPI(int InitOnly) { + switch(Option.DISPLAY_TYPE) { + case ILI9488: + case ILI9488W: +- DisplayHRes = 480; +- DisplayVRes = 320; ++ DisplayHRes = 320; ++#ifdef HARDWARE_SCROLL ++ DisplayVRes = 480; ++#else ++ DisplayVRes = 320; ++#endif + ResetController(); + if(Option.DISPLAY_TYPE==ILI9488){ ++#ifdef PICOCALC ++ spi_write_command(0xF0); ++ spi_write_data(0xC3); ++ spi_write_command(0xF0); ++ spi_write_data(0x96); ++ spi_write_command(TFT_MADCTL); ++ spi_write_data(0x48); ++ spi_write_command(0x3A); ++ spi_write_data(0x06); ++ spi_write_command(0xB4); ++ spi_write_data(0x00); ++ //spi_write_command(0xB6); //RGB Control ++ //spi_write_data(0x8A); ++ //spi_write_data(0x07); ++ //spi_write_data(0x27); //320 Gates ++ spi_write_command(0xB7); ++ spi_write_data(0xC6); ++ spi_write_command(0xB9); ++ spi_write_data(0x02); ++ spi_write_data(0xE0); ++ spi_write_command(0xC0); ++ spi_write_data(0x80); ++ spi_write_data(0x06); ++ spi_write_command(0xC1); ++ spi_write_data(0x15); ++ spi_write_command(0xC2); ++ spi_write_data(0xA7); ++ spi_write_command(0xC5);//VCOM ++ spi_write_data(0x04); ++ spi_write_command(0xE8); ++ spi_write_data(0x40); ++ spi_write_data(0x8A); ++ spi_write_data(0x00); ++ spi_write_data(0x00); ++ spi_write_data(0x29); ++ spi_write_data(0x19); ++ spi_write_data(0xAA); ++ spi_write_data(0x33); ++ spi_write_command(0xE0); ++ spi_write_data(0xF0); ++ spi_write_data(0x06); ++ spi_write_data(0x0F); ++ spi_write_data(0x05); ++ spi_write_data(0x04); ++ spi_write_data(0x20); ++ spi_write_data(0x37); ++ spi_write_data(0x33); ++ spi_write_data(0x4C); ++ spi_write_data(0x37); ++ spi_write_data(0x13); ++ spi_write_data(0x14); ++ spi_write_data(0x2B); ++ spi_write_data(0x31); ++ spi_write_command(0xE1); ++ spi_write_data(0xF0); ++ spi_write_data(0x11); ++ spi_write_data(0x1B); ++ spi_write_data(0x11); ++ spi_write_data(0x0F); ++ spi_write_data(0x0A); ++ spi_write_data(0x37); ++ spi_write_data(0x43); ++ spi_write_data(0x4C); ++ spi_write_data(0x37); ++ spi_write_data(0x13); ++ spi_write_data(0x13); ++ spi_write_data(0x2C); ++ spi_write_data(0x32); ++ spi_write_command(0xF0); ++ spi_write_data(0x3C); ++ spi_write_command(0xF0); ++ spi_write_data(0x69); ++ spi_write_command(0x35); ++ spi_write_data(0x00); ++ spi_write_command(TFT_SLPOUT); ++ uSec(120); //ms ++ spi_write_command(TFT_DISPON); ++ uSec(20); ++ spi_write_command(TFT_INVON); ++ spi_write_command(TFT_CASET); ++ spi_write_data(0x00); ++ spi_write_data(0x00); ++ spi_write_data(0x01); ++ spi_write_data(0x3F); ++ spi_write_command(TFT_RASET); ++ spi_write_data(0x00); ++ spi_write_data(0x00); ++ spi_write_data(0x01); ++ spi_write_data(0x3F); ++ spi_write_command(TFT_RAMWR); ++#else + spi_write_command(0xE0); // Positive Gamma Control + spi_write_data(0x00); + spi_write_data(0x03); +@@ -357,6 +453,7 @@ void MIPS16 InitDisplaySPI(int InitOnly) { + + spi_write_command(TFT_DISPON); //Display on + uSec(25000); ++#endif + } else { + if(Option.BGR)spi_write_command(0x20); + else spi_write_command(0x21); +@@ -415,6 +512,9 @@ void MIPS16 InitDisplaySPI(int InitOnly) { + case RLANDSCAPE: spi_write_cd(ILI9341_MEMCONTROL,1,ILI9341_Landscape180); break; + case RPORTRAIT: spi_write_cd(ILI9341_MEMCONTROL,1,ILI9341_Portrait180); break; + } ++#ifdef HARDWARE_SCROLL ++ setScrollArea(0,0); ++#endif + break; + case ILI9481IPS: + DisplayHRes = 480; +@@ -831,9 +931,14 @@ void MIPS16 InitDisplaySPI(int InitOnly) { + VRes=DisplayVRes; + HRes=DisplayHRes; + } else { +- VRes=DisplayHRes; +- HRes=DisplayVRes; ++ VRes = DisplayHRes; ++ HRes = DisplayVRes; + } ++#ifdef PICOCALC ++ VRes=DisplayVRes; ++ HRes=DisplayHRes; ++#endif ++ + if(!InitOnly) { + ResetDisplay(); + ClearScreen(Option.DISPLAY_CONSOLE ? Option.DefaultBC : 0); +@@ -1069,20 +1174,136 @@ void spisendfast(unsigned char *n, int i){ + xmit_byte_multi(n,i);// HAL_SPI_Transmit(&hspi3,coord,4,500); + } + ++// Draw a filled rectangle ++// this is the basic drawing promitive used by most drawing routines ++// x1, y1, x2, y2 - the coordinates ++// c - the colour ++void DrawRectangleSPI(int x1, int y1, int x2, int y2, int c){ ++ // convert the colours to 565 format ++ unsigned char col[3]; ++ if(x1==x2 && y1==y2){ ++ if(x1 < 0) return; ++ if(x1 >= HRes) return; ++#ifdef HARDWARE_SCROLL ++ if(y1 < 0) {y1 = LCD_REAL_HEIGHT+y1;} ++ if(y1 >= VRes) {y1 = y1 % LCD_REAL_HEIGHT;} ++ y1 += offsetY; ++ y1 = y1 % LCD_REAL_HEIGHT; ++ y2 = y1; ++#else ++ if(y1 < 0) return; ++ if(y1 >= VRes) return; ++#endif ++ DefineRegionSPI(x1, y1, x2, y2, 1); ++ if(Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE==ILI9481IPS ){ ++ col[0]=(c>>16); ++ col[1]=(c>>8) & 0xFF; ++ col[2]=(c & 0xFF); ++ } else { ++ col[0]= ((c >> 16) & 0b11111000) | ((c >> 13) & 0b00000111); ++ col[1] = ((c >> 5) & 0b11100000) | ((c >> 3) & 0b00011111); ++ } ++ if(Option.DISPLAY_TYPE == GC9A01){ ++ col[0]=~col[0]; ++ col[1]=~col[1]; ++ } ++ SPIqueue(col); ++ } else { ++ int i,t,y; ++ unsigned char *p; ++ // make sure the coordinates are kept within the display area ++ if(x2 <= x1) { t = x1; x1 = x2; x2 = t; } ++ if(y2 <= y1) { t = y1; y1 = y2; y2 = t; } ++ if(x1 < 0) x1 = 0; ++ if(x1 >= HRes) x1 = HRes - 1; ++ if(x2 < 0) x2 = 0; ++ if(x2 >= HRes) x2 = HRes - 1; ++ ++#ifdef HARDWARE_SCROLL ++ y1 += offsetY; ++ y2 += offsetY; ++ ++ if (y2 >= VRes) { ++ if(y1 < VRes){ // 分割 ++ int ov_y = y2 - VRes; ++ DrawRectangleSPI(x1, 0, x2, ov_y, c); ++ y2 = VRes - 1; ++ }else{ ++ y1 = y1 % LCD_REAL_HEIGHT; ++ y2 = y2 % LCD_REAL_HEIGHT; ++ } ++ } ++ ++ if (y1 < 0) { y1 = VRes + y1; } ++ if (y1 >= VRes) { y1 = y1 % LCD_REAL_HEIGHT;} ++ if (y2 < 0) { y2 = VRes + y2;} ++ ++#else ++ if(y1 < 0) y1 = 0; ++ if(y1 >= VRes) y1 = VRes - 1; ++ if(y2 < 0) y2 = 0; ++ if(y2 >= VRes) y2 = VRes - 1; ++#endif ++ DefineRegionSPI(x1, y1, x2, y2, 1); ++ if(Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE==ILI9481IPS ){ ++ i = x2 - x1 + 1; ++ i*=3; ++ p=LCDBuffer; ++ col[0]=(c>>16); ++ col[1]=(c>>8) & 0xFF; ++ col[2]=(c & 0xFF); ++ for(t=0;t> 16) & 0b11111000) | ((c >> 13) & 0b00000111); ++ col[1] = ((c >> 5) & 0b11100000) | ((c >> 3) & 0b00011111); ++ if(Option.DISPLAY_TYPE == GC9A01){ ++ col[0]=~col[0]; ++ col[1]=~col[1]; ++ } ++ for(t=0;t= HRes) return; ++#ifdef HARDWARE_SCROLL ++ if(y1 < 0) {y1 = LCD_REAL_HEIGHT+y1;} ++ if(y1 >= VRes) {y1 = y1 % LCD_REAL_HEIGHT;} ++ y2 = y1; ++#else + if(y1 < 0) return; + if(y1 >= VRes) return; ++#endif + DefineRegionSPI(x1, y1, x2, y2, 1); + if(Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE==ILI9481IPS ){ + col[0]=(c>>16); +@@ -1107,10 +1328,17 @@ void DrawRectangleSPI(int x1, int y1, int x2, int y2, int c){ + if(x1 >= HRes) x1 = HRes - 1; + if(x2 < 0) x2 = 0; + if(x2 >= HRes) x2 = HRes - 1; ++#ifdef HARDWARE_SCROLL ++ if(y1 < 0) y1 = VRes+y1; ++ if(y1 >= VRes) y1 = y1 % VRes; ++ if(y2 < 0) y2 = VRes + y2; ++ if(y2 >= VRes) y2 = y2 % VRes; ++#else + if(y1 < 0) y1 = 0; + if(y1 >= VRes) y1 = VRes - 1; + if(y2 < 0) y2 = 0; + if(y2 >= VRes) y2 = VRes - 1; ++#endif + DefineRegionSPI(x1, y1, x2, y2, 1); + if(Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE==ILI9481IPS ){ + i = x2 - x1 + 1; +@@ -1166,8 +1394,12 @@ void DrawBitmapSPI(int x1, int y1, int width, int height, int scale, int fc, int + char rgbbytes[4]; + unsigned int rgb; + } c; ++#ifdef HARDWARE_SCROLL ++ y1 += offsetY; y1 = y1 %LCD_REAL_HEIGHT; ++#endif + if(bc == -1 && (void *)ReadBuffer == (void *)DisplayNotSet) bc = 0x0; + if(x1>=HRes || y1>=VRes || x1+width*scale<0 || y1+height*scale<0)return; ++ + // adjust when part of the bitmap is outside the displayable coordinates + vertCoord = y1; if(y1 < 0) y1 = 0; // the y coord is above the top of the screen + XStart = x1; if(XStart < 0) XStart = 0; // the x coord is to the left of the left marginn +@@ -1708,3 +1940,27 @@ int GetLineILI9341(void){ + return (int)(q); + } + #endif ++ ++#ifdef HARDWARE_SCROLL ++void setScrollArea(uint16_t topFixedArea, uint16_t bottomFixedArea) { ++ ++ spi_write_command(0x33); // Vertical HWScroll definition ++ spi_write_data(topFixedArea >> 8); ++ spi_write_data(topFixedArea); ++ spi_write_data(LCD_REAL_HEIGHT >> 8); ++ spi_write_data(LCD_REAL_HEIGHT & 0xff); ++ spi_write_data(bottomFixedArea >> 8); ++ spi_write_data(bottomFixedArea); ++ ++} ++ ++void HWScroll(uint16_t pixels) { ++ spi_write_command(0x37); // Vertical scrolling start address ++ spi_write_data(pixels >> 8); ++ spi_write_data(pixels & 0xFF); ++} ++void ResetHWScroll(){ ++ HWScroll(0); ++ offsetY= 0; ++} ++#endif +\ No newline at end of file +diff --git a/SPI-LCD.h b/SPI-LCD.h +index 2bed448..af0833c 100644 +--- a/SPI-LCD.h ++++ b/SPI-LCD.h +@@ -36,6 +36,7 @@ extern void SetAndReserve(int pin, int inp, int init, int type); + extern void OpenSpiChannel(void); + extern void DisplayNotSet(void); + extern void DrawRectangleSPI(int x1, int y1, int x2, int y2, int c); ++extern void DrawRectangleSPIHW(int x1, int y1, int x2, int y2, int c); + extern void DrawBufferSPI(int x1, int y1, int x2, int y2, unsigned char* p); + extern void SPISpeedSet(int speed); + extern void DefineRegionSPI(int xstart, int ystart, int xend, int yend, int rw); +@@ -420,6 +421,15 @@ extern void __not_in_flash_func(spi_finish)(spi_inst_t *spi); + #define P_OFF 0 + #define P_I2C_SCL 0 + #define P_I2C_SDA 1 ++ ++#define PICOCALC 1 ++#define HARDWARE_SCROLL 1 ++#ifdef ILI9488 ++#define LCD_WIDTH 320 ++#define LCD_HEIGHT 320 ++#define LCD_REAL_HEIGHT 480 // ILI9488 real height is 480 ++#endif ++ + extern void Display_Refresh(void); + extern void waitwhilebusy(void); + struct Displays { +@@ -459,5 +469,9 @@ extern void BitBangReadSPI(BYTE *buff, int cnt); + extern void ScrollLCDSPI(int lines); + extern void SetCS(void); + extern int GetLineILI9341(void); ++ ++void setScrollArea(uint16_t topFixedArea, uint16_t bottomFixedArea); ++void HWScroll(uint16_t pixels); ++extern void ResetHWScroll(); + #endif + +diff --git a/VS1053.c b/VS1053.c +index 8f4281a..30236b3 100644 +--- a/VS1053.c ++++ b/VS1053.c +@@ -32,7 +32,7 @@ + */ + #include "MMBasic_Includes.h" + #include "Hardware_Includes.h" +-#include "VS1053.h" ++#include "vs1053.h" + #include "vs1053b-patches.h" + #define LOG(...) + extern void __not_in_flash_func(spi_write_fast)(spi_inst_t *spi, const uint8_t *src, size_t len); +diff --git a/mmc_stm32.c b/mmc_stm32.c +index 64013ba..b80ae15 100644 +--- a/mmc_stm32.c ++++ b/mmc_stm32.c +@@ -1329,7 +1329,7 @@ void InitReservedIO(void) { + gpio_set_function(PinDef[Option.SYSTEM_I2C_SDA].GPno, GPIO_FUNC_I2C); + if(PinDef[Option.SYSTEM_I2C_SDA].mode & I2C0SDA){ + I2C0locked=1; +- i2c_init(i2c0,(Option.SYSTEM_I2C_SLOW ? 100000:400000)); ++ i2c_init(i2c0,(Option.SYSTEM_I2C_SLOW ? 10000:400000)); + gpio_pull_up(PinDef[Option.SYSTEM_I2C_SCL].GPno); + gpio_pull_up(PinDef[Option.SYSTEM_I2C_SDA].GPno); + I2C_enabled=1; +@@ -1338,7 +1338,7 @@ void InitReservedIO(void) { + I2C_Timeout=500; + } else { + I2C1locked=1; +- i2c_init(i2c1,(Option.SYSTEM_I2C_SLOW ? 100000:400000)); ++ i2c_init(i2c1,(Option.SYSTEM_I2C_SLOW ? 10000:400000)); + gpio_pull_up(PinDef[Option.SYSTEM_I2C_SCL].GPno); + gpio_pull_up(PinDef[Option.SYSTEM_I2C_SDA].GPno); + I2C2_enabled=1; diff --git a/Code/README.md b/Code/README.md index 394d3df..93e9074 100644 --- a/Code/README.md +++ b/Code/README.md @@ -31,6 +31,21 @@ make world now copy `build/fuzix.uf2` into picocalc like every pico device +## How to compile PicoMite(MMB) for picocalc + +```bash +git clone https://github.com/cuu/PicoMite.git +cd PicoMite + +git apply PicoMite.patch + +export PICO_SDK_PATH=/to/where/your/pico/sdk/is +mkdir build +cd build +cmake .. +make +``` +copy `build/PicoMite.uf2` into picocalc like every pico device