'SSD1963_Driver 'Assembly parallel interface driver SSD1963 'Copyright (C) 2012 Raymond Allen. 'Ver1RevK: Initial Version (with pipeline fix to setpoint, fixed arbitary pins, fixed write hold time) 'Spin support for various geometrical shapes 'Assembly driver supports area, pixel and line drawing and also ROM font and bitmap support CON 'Pin Settings 'Be sure to change to the pins you are using before use! PinResetn=-1 'Leave negative if not used PinCs = 15 PinRd = 6 PinWr = 5 PinDC = 4 PinLowData=14 PinsDataBus=$FF<0 outa[PinResetn]~ dira[PinResetn]~~ waitcnt(cnt+clkfreq/2) outa[PinResetn]~~ waitcnt(cnt+clkfreq/2) InitLCD(bUsingVgaPlugin) 'Initialize the SSD1963 CreateTvClut 'Create color look-up table that mimics TV colors return PUB Stop '' Stop PPI Engine - frees a cog if cog cogstop(cog~ - 1) command~ PUB ConfigureText(x0,y0,nx,ny,sx,sy) 'Configure size and location of text area 'Note: This needs to be done BEFORE starting the assembly driver 'default is x0=y0=0, nx=40, ny=30, sx=sy=1 (scale = 1:1) nTextColumns:=nx nTextRows:=ny TextX0:=x0 TextY0:=y0 TextXScale:=sx TextYScale:=sy TextXWidth:=16*sx PRI DrawRomFont(color,x,y,CharAddress,CharRows,pLookup) color<<=2 color+=pTvColors SetCommand(Draw_RomFont,@color) PUB DrawRomFontChar(color,x,y,Char)|a a:=($200+(Char&$FE))<<6 color:=color<<1+Char&1 DrawRomFont(color,x,y,a,32,@Clut) PUB SetPixel(c,x,y) SetCommand(Set_Pixel,@c) PUB DrawLine(c,x1,y1,x2,y2)|t SetCommand(Draw_Line,@c) PUB DrawStraightLine(C,x1,y1,x2,y2)|n 'assumes x1=x2 or y1=y2 n:=x2-x1+y2-y1+1 SetWindow(x1,x2,y1,y1) WriteNRGB(c,n) PUB DrawCircle(c,x1,y1,r) Circle(x1,y1,r,false,c) PUB DrawSolidCircle(c,x1,y1,r) Circle(x1,y1,r,true,c) PUB DrawFilledCircle(c1,c2,x1,y1,r) Circle(x1,y1,r,true,c2) Circle(x1,y1,r,false,c1) PRI Circle(cX,cY,Rad,Fill,C) | Sum, XOff, YOff '' Draw a {RGB} circle of radius Rad at location X,Y '' ' "borrowed" from FemtoBasic XOff := 0 YOff := Rad Sum := (5 - Rad*4)/4 CirclePlot(cX, cY, XOff, YOff,Fill,C) repeat while (XOff < YOff) XOff++ if (Sum < 0) Sum += 2*XOff+1 else YOff-- Sum += 2*(XOff-YOff)+1 CirclePlot(cX, cY, XOff, YOff,Fill,C) CirclePlot(cX, cY, XOff, YOff,Fill, C) PRI CirclePlot(cx, cy, x1, y1,Fill,C) '' Put a circle on the screen! '' "borrowed" from FemtoBasic '' The Fill parameter is used to determine whether to use the LINE '' method (for a filled circle) or PutPixel '' if(Fill) if true DrawStraightLine(C,cx-x1,cy+y1,cx+x1,cy+y1) DrawStraightLine(C,cx-x1,cy-y1,cx+x1,cy-y1) DrawStraightLine(C,cx-y1,cy+x1,cx+y1,cy+x1) DrawStraightLine(C,cx-y1,cy-x1,cx+y1,cy-x1) else if (x1 == 0) SetPixel(C,cx, cy + y1) SetPixel(C,cx, cy - y1) SetPixel(C,cx + y1, cy) SetPixel(C,cx - y1, cy) else if (x1 == y1) SetPixel(C,cx + x1, cy + y1) SetPixel(C,cx - x1, cy + y1) SetPixel(C,cx + x1, cy - y1) SetPixel(C,cx - x1, cy - y1) else if (x1 < y1) SetPixel(C,cx + x1, cy + y1) SetPixel(C,cx - x1, cy + y1) SetPixel(C,cx + x1, cy - y1) SetPixel(C,cx - x1, cy - y1) SetPixel(C,cx + y1, cy + x1) SetPixel(C,cx - y1, cy + x1) SetPixel(C,cx + y1, cy - x1) SetPixel(C,cx - y1, cy - x1) PUB DrawTriangle(c,x1,y1,x2,y2,x3,y3) 'draw outline of triangle DrawLine(c,x1,y1,x2,y2) DrawLine(c,x2,y2,x3,y3) DrawLine(c,x3,y3,x1,y1) PUB DrawSolidTriangle(c,x1,y1,x2,y2,x3,y3)| xy[2] 'draw solid triangle in foreground color ' "borrowed" from graphics.spin '' Draw a solid triangle ' reorder vertices by descending y case (y1 => y2) & %100 | (y2 => y3) & %010 | (y1 => y3) & %001 %000: longmove(@xy, @x1, 2) longmove(@x1, @x3, 2) longmove(@x3, @xy, 2) %010: longmove(@xy, @x1, 2) longmove(@x1, @x2, 4) longmove(@x3, @xy, 2) %011: longmove(@xy, @x1, 2) longmove(@x1, @x2, 2) longmove(@x2, @xy, 2) %100: longmove(@xy, @x3, 2) longmove(@x2, @x1, 4) longmove(@x1, @xy, 2) %101: longmove(@xy, @x2, 2) longmove(@x2, @x3, 2) longmove(@x3, @xy, 2) ' draw triangle fillA(x1, y1, (x3 - x1) << 16 / (y1 - y3 + 1), (x2 - x1) << 16 / (y1 - y2 + 1), (x3 - x2) << 16 / (y2 - y3 + 1), y1 - y2, y1 - y3,c) PUB DrawFilledTriangle(c1,c2,x1,y1,x2,y2,x3,y3) 'draw triangle filled with background color DrawSolidTriangle(c2,x1,y1,x2,y2,x3,y3) DrawTriangle(c1,x1,y1,x2,y2,x3,y3) PRI fillA(x1, y1, da, db, db2, linechange, lines_minus_1,c)|i,j,k,x0,y0,xn, dxf,dyf,t1f,t2f,t3f,base0,base1 'fill a solid triangle 'converted from Graphics.spin assembly dyf:=y1 dxf:=(x1<<16)|$8000 t1f:=dxf 'added the -1 here for better look lines_minus_1++ repeat dxf+=da t1f+=db if dxf=16 base1~>=16 DrawStraightLine(c,base0,dyf,base1,dyf) linechange-- if linechange<0 db:=db2 dyf-- until (--lines_minus_1)==0 PUB DrawRectangle(c,x1,y1,x2,y2)|n 'Draw a rectangle outline given coordinates and color if x2>8) write_DATA(i) i:=hSyncWidth write_DATA(i) 'HPW=sync width write_DATA($00) 'LPS=Sync Pulse location write_DATA($00) write_DATA($00) 'LPSPP=zero write_CMD($B6) 'Set vertical timing: VBP=19, Sync=8 i:=yPixels+vBackPorch+vFrontPorch+vSyncWidth-1 write_DATA(i>>8) 'VT write_DATA(i) i:=vBackPorch+vSyncWidth 'VPS write_DATA(i>>8) ' write_DATA(i) i:=vSyncWidth write_DATA(i) 'VPW write_DATA($00) 'FPS=zero write_DATA($00) write_CMD($2A) 'Set column address 0..639 write_DATA($00) write_DATA($00) i:=xPixels-1 write_DATA(i>>8) write_DATA(i) write_CMD($2B) 'Set page address 0..479 i:=yPixels-1 write_DATA($00) write_DATA($00) write_DATA(i>>8) write_DATA(i) } write_CMD($13) 'Enter normal mode write_CMD($38) 'Exit idel mode write_CMD($29) 'Set Display ON PUB write_CMD(cmd_byte) setcommand(Write_command,@cmd_byte) PUB write_DATA(cmd_data) setcommand(Write_dat,@cmd_data) PUB read_DATA:cmd_data|i i:=@cmd_data setcommand(Read_dat,@i) return cmd_data PUB delayms(ms) waitcnt(cnt+(clkfreq/1000)*ms) PUB setcommand(cmd, argptr) command := cmd << 16 + argptr 'write command and pointer repeat while command 'wait for command to be cleared, signifying receipt PUB DummyOperation 'Used to make sure assembly done with last operation setcommand(DummyOp,0) '################################################################################################################ DAT 'Assembly SSD1963 Driver org 0 StartAssembly jmp #init 'Jump over mask definitions 'Inserting mask definitions here for clarity (instruction causes jump over this section) CS_mask long 1<