KS0713
KS0713 Driver Module and modified GLCD.bas by Mark Rodgers
Modification Details
The two pieces of code below are modifications to existing code supplied with the current Swordfish Compiler(Ver 2.0.0.2).
The first piece is named KS0713.bas and is a modified version of S1D10605.bas
The Samsung KS0713 and Epson S1D10605 appear to be very similar and share the same command codes when addressing the internal processor, there are some minor differences in the particular displays chosen for these tests, but it seems the core code(written by David) is transferable.
The second piece of code is named GLCD_KS0173.bas and is a modified version of the compilers supplied GLCD.bas, the only changes are to allow the KS0713 to be brought into the code one writes using the compilers syntax, namely #option GLCD_MODEL = KS0713
No other changes affecting the normal use of this module are made and it can be used without problem on any existing code.
Display Type
The display used to confirm operation was a Displaytech 64128COG series obtained from RS Components(in the UK), part number 532-7114, it was chosen primarily due to a very low cost of £7.40 for one off.
The display was hardwired to operate in the parallel mode(take PS pin high) and to use 6800 mode(take MI pin high) and the pins DB0 to DB7, RST, E, R/W, RS, RST and CS1B were connected to the 18F452.
Details Of Use
The use of the driver is similar to the existing drivers with the exception of one addition in the KS0713.bas and that is a function called GLCD_FLIP_DISPLAY. This function allows the KS0713 display to be flipped over allowing the display to be mounted with its pins at the top or the bottom, at the moment this is not able to be achieved at run time, only at compile time. The function is Boolean and defaults, if not declared, as GLCD_FLIP_DISPLAY=False, error trapping and reporting is employed.
All other pins are as the exiting defaults and are changeable in the same way as any other driver supplied with the compliler.
How To Integrate With Swordfish
The Graphic LCD components of Swordfish are in Mecanique\Swordfish\Library\GLCD, the existing file GLCD.bas should be renamed GLCD_original.bas(or something you like) and the GLCD_KS0713.bas here should be copied in to the directory and renamed GLCD.bas, the KS0713 is now supported.
To recap the usage:-
Declare that you wish to bring the KS0713 into your program:-
- #option GLCD_MODEL = KS0713
Decide which way up the display should be:-
- GLCD_FLIP_DISPLAY=False, system default if not declared
- GLCD_FLIP_DISPLAY=True, inverts the display
I take no credit for the core of the code presented here, that lies with David and Steven.
The KS0713.bas Module code:-
{ **************************************************************** * Name : KS0713.BAS * * Author : David John Barker * * Modified: Mark Rodgers, 18,04,07 * * Notice : Copyright (c) 2006 Mecanique * * : All Rights Reserved * * Date : 02/05/2006 * * Version : 1.0 * * Notes : This is "S1D10605.bas" Modified to work with * * the SAMSUNG KS0713 COG-128X64 chipset and was * * tested using Displaytech 64128COG series from * * RS, part number 532-7114. * * The module is hardwired For parallel use(PS High) * * and 6800 mode(MI High). * * A new command has been added to allow the display * * to be mounted either way up and still print the * * characters correctly. * * This new command is GLCD_FLIP_DISPLAY. * * It is Boolean and defaults(if not declared) False.* **************************************************************** } Module KS0713 // import the graphics module... #DEFINE GLCD_PIXEL_01 #DEFINE GLCD_COLOR_01 #DEFINE GLCD_XY_08 Include "Graphics.bas" Include "system.bas" // default module options - user options can override these values... #option GLCD_DATA = PORTD // Data port #option GLCD_RS = PORTE.2 'modified for KS0713, Data Or command #option GLCD_EN = PORTE.0 // EN pin #option GLCD_RW = PORTC.0 // RW pin #option GLCD_CS1 = PORTE.1 // chip Select #option GLCD_RST = PORTC.1 // reset #option GLCD_ASPECT_RATIO = 100 'modified For KS0713, aspect ratio, smaller number will squeeze y For GLCD circles And Box #option GLCD_INIT_DELAY = 100 // initialisation delay (ms) #option GLCD_FLIP_DISPLAY=False 'normal display mode(not upsidedown) // validate Data port... #IF IsOption(GLCD_DATA) #IF Not IsValidPort(GLCD_DATA) #ERROR GLCD_DATA, "Invalid option. DATA must be a valid port name." #ENDIF #IFDEF GLCD_DATA@ Then #ERROR GLCD_DATA@, "Invalid option. DATA port cannot be a single bit value." #ENDIF #ENDIF 'validate RS pin, modified for KS0713 #IF IsOption(GLCD_RS) And Not IsValidPortPin(GLCD_RS) #ERROR GLCD_RS, "Invalid option. RS must be a valid port pin." #ENDIF // validate EN pin... #IF IsOption(GLCD_EN) And Not IsValidPortPin(GLCD_EN) #ERROR GLCD_EN, "Invalid option. EN must be a valid port pin." #ENDIF // validate RW pin... #IF IsOption(GLCD_RW) And Not IsValidPortPin(GLCD_RW) #ERROR GLCD_RW, "Invalid option. RW must be a valid port pin." #ENDIF // validate CS1 pin... #IF IsOption(GLCD_CS1) And Not IsValidPortPin(GLCD_CS1) #ERROR GLCD_CS1, "Invalid option. CS1 must be a valid port pin." #ENDIF // validate CS2 pin... #IF IsOption(GLCD_RST) And Not IsValidPortPin(GLCD_RST) #ERROR GLCD_RST, "Invalid option. RST must be a valid port pin." #ENDIF // validate initialisation delay... #IF IsOption(GLCD_INIT_DELAY) #IF Not (GLCD_INIT_DELAY in (0 To 1000)) #ERROR GLCD_INIT_DELAY, "Invalid option. GLCD initialize delay must be between 0 and 1000 (ms)." #ENDIF #ENDIF 'test for boolean value when FLIP_DISPLAY is specified #IF IsOption(GLCD_FLIP_DISPLAY) And Not False #IF IsOption(GLCD_FLIP_DISPLAY) And Not True #ERROR GLCD_FLIP_DISPLAY, "Invalid option. Value must be True or False (Boolean)" #ENDIF #ENDIF // now create Data TRIS... #option _GLCD_DATA_TRIS = GetTRIS(GLCD_DATA) // GLCD width And height... Public Const GLCDWidth = 128, GLCDHeight = 64, Flip=GLCD_FLIP_DISPLAY // x, y position... Public Dim Pos As TPosition 'KS0713 control commands, modified for KS0713 Const cmdOn = $AF, cmdOff = $AE, cmdStartLine = $40, cmdPage = $B0, cmdColumnMS = $10, cmdColumnLS = $0F, cmdADCNormal = $A0, cmdADCReverse = $A1, cmdDisplayNormal = $A6, cmdDisplayReverse = $A7, cmdDisplayAllOff = $A4, cmdDisplayAllOn = $A5, cmdBias19 = $A2, cmdBias17 = $A3, cmdModify = $E0, cmdEnd = $EE, cmdReset = $E2, cmdScanTopBottom = $C0, cmdScanBottomTop = $C8, cmdPowerControl = $28, cmdV5Voltage = $20, cmdContrast = $81, cmdStaticOn = $AD, cmdStaticOff = $AC, GLCDDelay = GLCD_INIT_DELAY, FLIP_DISPLAY=GLCD_FLIP_DISPLAY // port And pin settings, these are brought into // the program by using the above options... Dim Data As GLCD_DATA, // Data in (PORT) TRISData As _GLCD_DATA_TRIS, // Data TRIS RS As GLCD_RS.GLCD_RS@, 'modified for KS0713, RC pin (Data Or command) EN As GLCD_EN.GLCD_EN@, // EN pin RW As GLCD_RW.GLCD_RW@, // RW pin (Read Or write) CS1 As GLCD_CS1.GLCD_CS1@, // chip Select RST As GLCD_RST.GLCD_RST@ // reset { **************************************************************************** * Name : StrobeEN (Private) * * Purpose : Strobe the GLCD EN pin * **************************************************************************** } Inline Sub StrobeEN() CS1 = 0 EN = 1 DelayUS(1) EN = 0 CS1 = 1 End Sub { **************************************************************************** * Name : GLCDData (PRIVATE) * * Purpose : Switch To GLCD Data mode * * Modified For KS0713 * **************************************************************************** } Inline Sub GLCDData() RS = 1 End Sub { **************************************************************************** * Name : GLCDInst (PRIVATE) * * Purpose : Switch To GLCD instruction mode * * Modified For KS0713 * **************************************************************************** } Inline Sub GLCDInst() RS = 0 End Sub { **************************************************************************** * Name : GLCDRead (PRIVATE) * * Purpose : Set GLCD To Read mode * **************************************************************************** } Inline Sub GLCDRead() RW = 1 End Sub { **************************************************************************** * Name : GLCDWrite (PRIVATE) * * Purpose : Set GLCD To write mode * **************************************************************************** } Inline Sub GLCDWrite() RW = 0 End Sub { **************************************************************************** * Name : WaitForIdle (PRIVATE) * * Purpose : Block further GLCD access Until signalled ready. * **************************************************************************** } Sub WaitForIdle() Dim Timeout As Byte Timeout = $FF TRISData = $FF // Set Data bus To Input GLCDInst // instruction Data GLCDRead // Read mode Repeat ClrWDT Dec(Timeout) StrobeEN Until (Data.7 = 0) Or (Timeout = 0) End Sub { **************************************************************************** * Name : SetData (PRIVATE) * * Purpose : Write a Data Byte To GLCD * **************************************************************************** } Sub SetData(pData As Byte) WaitForIdle // block Until Not busy TRISData = $00 // Set Data bus To Output GLCDData // access display RAM Data GLCDWrite // write mode Data = pData // write To the bus StrobeEN // write To GLCD End Sub { **************************************************************************** * Name : GetData (PRIVATE) * * Purpose : Read Byte from GLCD * **************************************************************************** } Function GetData() As Byte WaitForIdle // block Until Not busy TRISData = $FF // Set Data bus To Input GLCDData // access display RAM Data GLCDRead // Read mode StrobeEN // latch Data Result = Data // get the Data End Function { **************************************************************************** * Name : Command (PRIVATE) * * Purpose : Write a command Byte To GLCD * **************************************************************************** } Sub Command(pCommand As Byte) WaitForIdle // block Until Not busy TRISData = $00 // Set Data bus To Output GLCDInst // instruction mode GLCDWrite // write mode Data = pCommand // write To the bus StrobeEN // write To GLCD End Sub { **************************************************************************** * Name : CommandWithData (PRIVATE) * * Purpose : Write a command plus extra Data Byte To GLCD * **************************************************************************** } Sub CommandWithData(pCommand,pData As Byte) WaitForIdle // block Until Not busy TRISData = $00 // Set Data bus To Output GLCDInst // instruction mode GLCDWrite // write mode Data = pCommand // write To the bus StrobeEN // write To GLCD Data = pData StrobeEN End Sub { **************************************************************************** * Name : SetPosition (PRIVATE) * * Purpose : Set GLCD x And y positions * * : Modified for use with "GLCD_FLIP_DISPLAY" command * **************************************************************************** } Sub SetPosition() Command(cmdPage Or Pos.y) // Set y position If Flip=False Then Command($10 Or (Pos.x + 4 >> 4)) // Set x, upper nibble Command($0F And Pos.x + 4) // Set x, lower nibble EndIf If Flip=True Then Command($10 Or (Pos.x >> 4)) 'setting For the KS0713, Set x, upper nibble Command($0F And Pos.x ) 'setting For the KS0713, Set x, lower nibble EndIf End Sub { **************************************************************************** * Name : WriteByte * * Purpose : Write a Byte At x, PAGE * **************************************************************************** } Public Sub WriteByte(pValue As Byte) SetPosition SetData(pValue) End Sub { **************************************************************************** * Name : ReadByte * * Purpose : Read a Byte At x, PAGE * **************************************************************************** } Public Function ReadByte() As Byte SetPosition GetData Result = GetData End Function { **************************************************************************** * Name : SetPixel * * Purpose : Set Pixel At Pixel location x,y * **************************************************************************** } Public Sub SetPixel(pX, pY As Byte) Dim YBit As Byte Dim Pixel As Byte If (pX < GLCDWidth) And (pY < GLCDHeight) Then YBit = 1 << (pY Mod 8) Pos.y = pY / 8 Pos.x = pX SetPosition GetData Pixel = GetData // pen is white... If Pen.Color = 0 Then If Pen.Mode = pmCopy Then YBit = Not YBit Pixel = Pixel And YBit EndIf // pen is black... Else // pen copy Or merge... If Pen.Mode <> pmXOR Then Pixel = Pixel Or YBit // pen XOR Else If (Pixel And YBit) = 0 Then Pixel = Pixel Or YBit Else YBit = Not YBit Pixel = Pixel And YBit EndIf EndIf EndIf SetPosition SetData(Pixel) EndIf End Sub { **************************************************************************** * Name : GetPixel * * Purpose : Return Pixel colour At Pixel position x, y * **************************************************************************** } Public Function GetPixel(pX, pY As Byte) As TColor Dim Pixel As Byte Pos.y = pY / 8 Pos.x = pX SetPosition GetData Pixel = GetData >> (pY Mod 8) Result = Pixel.0 End Function { **************************************************************************** * Name : Cls * * Purpose : Clear the GLCD screen * * : Modified For use with "GLCD_FLIP_DISPLAY" Command * **************************************************************************** } Public Sub Cls() Dim x, y As Byte y = 0 If Flip=False Then x = 4 EndIf If Flip=True Then x=0 'use when flipped EndIf Repeat Command(cmdPage Or y) Repeat Command(cmdColumnMS Or (x >> 4)) Command(cmdColumnLS And x) SetData($00) Inc(x) Until x > 131 Inc(y) Until y > 7 End Sub { **************************************************************************** * Name : SetContrast * * Purpose : Set the GLCD contrast * **************************************************************************** } Public Sub SetContrast(pValue As Byte) CommandWithData(cmdContrast,pValue) End Sub { **************************************************************************** * Name : Sleep * * Purpose : Put the GLCD To Sleep Or wake it up * **************************************************************************** } Public Sub Sleep(pOn As Boolean = true) If pOn Then Command(cmdOff) Command(cmdDisplayAllOn) Command(cmdStaticOff) Else Command(cmdDisplayAllOff) Command(cmdOn) EndIf End Sub { **************************************************************************** * Name : StandBy * * Purpose : Put the GLCD into standby mode Or wake it up * **************************************************************************** } Public Sub StandBy(pOn As Boolean = true) If pOn Then Command(cmdOff) Command(cmdDisplayAllOn) CommandWithData(cmdStaticOn, 3) Else Command(cmdStaticOff) Command(cmdDisplayAllOff) Command(cmdOn) EndIf End Sub { **************************************************************************** * Name : Initialize * * Purpose : Configure the GLCD before use * * : This section is Modified To work with the KS0713 * **************************************************************************** } Sub Initialize() Pos.x = 0 Pos.y = 0 DelayMS(GLCDDelay) // start up delay, allow GLCD To settle Output(RW) // Read/write is Low Low(EN) // Enable is Low Output(RS) 'setting for the KS0713' Data Or instruction is Low (command mode) Output(CS1) // screen High(RST) // reset Command(cmdReset) // software reset Command(cmdBias19) 'setting for the KS0713 If Flip=False Then Command(cmdADCReverse) 'setting For the KS0713, ADC Output = reversed EndIf If Flip=True Then Command(cmdADCNormal) 'setting For the KS0713, ADC Output = normal EndIf Command(cmdDisplayAllOff) // display all point normal Command(cmdV5Voltage Or 5) 'setting for the KS0713, internal resistor ratio (0..7) Command(cmdPowerControl Or $07) // internal power supply mode SetContrast(25) 'setting for the KS0713, LCD contrast Command(cmdStaticOff) // static indicator is off Command(cmdOn) // display is On If Flip=False Then Command(cmdScanBottomTop) 'setting For the KS0713, scan bottom to top EndIf If Flip=True Then Command(cmdScanTopBottom) 'setting For the KS0713, scan top to bottom EndIf Command(cmdDisplayNormal) // display normal polarity(not negative!) Command(cmdStartLine) // display start Line (Or value For Line number) End Sub Initialize
The GLCD_KS0713.bas Module code:-
{ **************************************************************** * Name : GLCD_KS0713.BAS * * Author : David John Barker * * : Steven Wright * * Modified: Mark Rodgers 19,04,07 * * Notice : Copyright (c) 2006 Mecanique * * : All Rights Reserved * * Date : 02/05/2006 * * Version : 1.2 * * Notes : 1.2 Added CreateMask() For 1 Bit y fonts * * : 1.3 Added support For S1D13700 * * : Modified To support SAMSUNG KS0713 * **************************************************************** } Module GLCD // validate model... #option GLCD_MODEL = KS0108 #IF Not (GLCD_MODEL in (KS0108, S1D10605, S1D15G00, SED1520, S1D13700, KS0713)) #ERROR GLCD_MODEL, "Invalid option. GLCD model not recognized." #ENDIF // import KS0108 driver... #IF GLCD_MODEL = KS0108 Include "KS0108.bas" Public Dim Pos As KS0108.Pos, Cls As KS0108.Cls, SetPixel As KS0108.SetPixel, WriteByte As KS0108.WriteByte, ReadByte As KS0108.ReadByte, GetPixel As KS0108.GetPixel #ENDIF // import S1D10605 driver... #IF GLCD_MODEL = S1D10605 Include "S1D10605.bas" Public Dim Pos As S1D10605.Pos, Cls As S1D10605.Cls, SetPixel As S1D10605.SetPixel, SetContrast As S1D10605.SetContrast, WriteByte As S1D10605.WriteByte, ReadByte As S1D10605.ReadByte, GetPixel As S1D10605.GetPixel, Sleep As S1D10605.Sleep, StandBy As S1D10605.StandBy #ENDIF // import S1D15G00 driver... #IF GLCD_MODEL = S1D15G00 Include "S1D15G00.bas" Public Dim Pos As S1D15G00.Pos, Cls As S1D15G00.Cls, SetPixel As S1D15G00.SetPixel, SetContrast As S1D15G00.SetContrast, Fill As S1D15G00.Fill, Contrast As S1D15G00.Contrast, MakeColor As S1D15G00.MakeColor, SetImage As S1D15G00.SetImage, CopyImage As S1D15G00.CopyImage #ENDIF // import SED1520 driver... #IF GLCD_MODEL = SED1520 Include "SED1520.bas" Public Dim Pos As SED1520.Pos, Cls As SED1520.Cls, SetPixel As SED1520.SetPixel, WriteByte As SED1520.WriteByte, ReadByte As SED1520.ReadByte, GetPixel As SED1520.GetPixel #ENDIF // import S1D13700 driver... #IF GLCD_MODEL = S1D13700 Include "S1D13700.bas" Public Dim Pos As S1D13700.Pos, Cls As S1D13700.Cls, SetPixel As S1D13700.SetPixel, WriteByte As S1D13700.WriteByte, ReadByte As S1D13700.ReadByte, GetPixel As S1D13700.GetPixel, ShowLayer As S1D13700.ShowLayer, SwitchLayer As S1D13700.SwitchLayer, Fill As S1D13700.Fill, SetImage As S1D13700.SetImage #ENDIF 'load the KS0713 driver file #IF GLCD_MODEL = KS0713 Include "KS0713.bas" Public Dim Pos As KS0713.Pos, Cls As KS0713.Cls, SetPixel As KS0713.SetPixel, SetContrast As KS0713.SetContrast, WriteByte As KS0713.WriteByte, ReadByte As KS0713.ReadByte, GetPixel As KS0713.GetPixel, Sleep As KS0713.Sleep, StandBy As KS0713.StandBy #ENDIF // import graphics And math... Include "Graphics.bas" Include "math.bas" // import constants... Public Const Width = GLCDWidth, Height = GLCDHeight // text out alignment constants Public Const taLeft = $01, taCenter = $02, taRight = $04 // make graphics vriables available For this // module interface Public Dim SetFont As Graphics.SetFont, TextWidth As Graphics.TextWidth, Pen As Graphics.Pen, Brush As Graphics.Brush, Font As Graphics.Font, TextAlign As Byte // default is equal apect ratio, change in GLCD model CORE... #option GLCD_ASPECT_RATIO = 100 Const AspectRatio = GLCD_ASPECT_RATIO { **************************************************************************** * Name : WriteImageByte (PRIVATE) * * Purpose : Write an image Byte To GLCD At Pixel position x,y * **************************************************************************** } #IFNDEF GLCD_SETIMAGE #IFDEF GLCD_PIXEL_01 Sub WriteImageByte(pX, pY As TXY, pValue As Byte) Dim Line, ShiftValue, YBit, YBitReverse As Byte Dim LastPosY As Byte LastPosY = Pos.y // SAVE y position YBit = pY Mod 8 // Offset YBitReverse = 8 - YBit // reverse Offset Pos.y = pY / 8 // align To PAGE Pos.x = pX // SAVE x // get first Byte... Line = ReadByte // Mask, If needed... If Pen.Mode = pmCopy Then Line = Line << YBitReverse Line = Line >> YBitReverse EndIf // merge Then write Data... ShiftValue = pValue << YBit If Pen.Mode = pmXOR Then Line = Line Xor ShiftValue Else Line = Line Or ShiftValue EndIf WriteByte(Line) // get Next Byte... If YBit <> 0 Then Inc(Pos.y) Line = ReadByte // Mask, If needed... If Pen.Mode = pmCopy Then Line = Line >> YBit Line = Line << YBit EndIf // merge Then write Data... ShiftValue = pValue >> YBitReverse If Pen.Mode = pmXOR Then Line = Line Xor ShiftValue Else Line = Line Or ShiftValue EndIf WriteByte(Line) EndIf // Restore y position... Pos.y = LastPosY End Sub { **************************************************************************** * Name : SetImage * * Purpose : BitBlit image To GLCD At Pixel location x,y * * : NOTE - This subroutine only supports $01 (monochrome) bitmaps * * : For drivers with ReadByte And WriteByte implemented * **************************************************************************** } Public Sub SetImage(pX, pY As TXY, ByRefConst pImage() As Byte, pMode As Byte = cmCopy) Dim Image As TImage Dim x,y,Width,Height As Byte Dim Line As Byte Dim LastPen As TPen Dim Index As Word LastPen = Pen Pen.Mode = pMode // get bitmap Width And Height... Image.Width = pImage(1) Image.Height = pImage(2) // Byte aligned Bit blit... Index = 4 y = pY Height = Image.Height / 8 While Height > 0 x = pX Width = Image.Width While Width > 0 WriteImageByte(x,y,pImage(Index)) Inc(Index) Inc(x) Dec(Width) Wend Inc(y,8) Dec(Height) Wend // non Byte aligned Bit blit... pY = y Image.Height = Image.Height Mod 8 If Image.Height > 0 Then x = pX Width = Image.Width While Width > 0 Line = pImage(Index) Height = Image.Height y = pY While Height > 0 Pen.Color = Line.0 SetPixel(x,y) Line = Line >> 1 Dec(Height) Inc(y) Wend Inc(Index) Dec(Width) Inc(x) Wend EndIf Pen = LastPen End Sub #ENDIF // GLCD_PIXEL_01 #ENDIF // GLCD_SETIMAGE { **************************************************************************** * Name : Line * * Purpose : Draws a Line using a Bresenham Line drawing algorithm * **************************************************************************** } #IFNDEF GLCD_LINE Public Sub Line(x1, y1, x2, y2 As TXY) Dim P, diff As LongInt Dim incx, incy As Integer Dim dx_ge_dy As Boolean Dim dy, dx, delta As Word Dim PenPos As Byte Dim Length As Byte // x direction... incx = 1 If x1 > x2 Then incx = -1 EndIf // y direction incy = 1 If y1 > y2 Then incy = -1 EndIf dx = abs(x2 - x1) dy = abs(y2 - y1) If dx >= dy Then dx_ge_dy = true dy = dy * 2 P = dy - dx delta = dx Else dx_ge_dy = false dx = dx * 2 P = dx - dy delta = dy EndIf diff = P - delta Inc(delta) PenPos = 0 Length = Pen.Style Repeat If Pen.Style > 0 Then If PenPos < Length Then SetPixel(x1, y1) EndIf Inc(PenPos) If PenPos > Length Then PenPos = 0 EndIf Else SetPixel(x1, y1) EndIf If P < 0 Then If dx_ge_dy Then Inc(P, dy) Inc(x1, incx) Else Inc(P, dx) Inc(y1, incy) EndIf Else Inc(P, diff) Inc(x1, incx) Inc(y1, incy) EndIf Dec(delta) Until delta = 0 End Sub #ENDIF // GLCD_LINE { **************************************************************************** * Name : Plot (PRIVATE) * * Purpose : Plots a Set of ellipse quadrant points * **************************************************************************** } #IFNDEF GLCD_ELLIPSE Sub Plot(pCX, pCY, pX, pY As TXY) SetPixel(pCX + pX, pCY + pY) SetPixel(pCX - pX, pCY + pY) SetPixel(pCX - pX, pCY - pY) SetPixel(pCX + pX, pCY - pY) End Sub { **************************************************************************** * Name : Ellipse * * Purpose : Draws an ellipse * * : A Fast Bresenham Type Algorithm For Drawing Ellipses * * : John Kennedy * * : Mathematics Department, Santa Monica College * * : Santa Monica, CA 90405 - http://homepage.smc.edu/kennedy_john * **************************************************************************** } Public Sub Ellipse(pCX, pCY, pXRadius, pYRadius As TXY) Dim x, y As TXY Dim XChange, YChange As LongInt Dim EllipseError As LongInt Dim TwoASquare, TwoBSquare As LongInt Dim StoppingX, StoppingY As LongInt Dim PenPos As Byte Dim Length As Byte Length = Pen.Style TwoASquare = 2 * pXRadius * pXRadius TwoBSquare = 2 * pYRadius * pYRadius x = pXRadius y = 0 XChange = pYRadius * pYRadius * (1 - 2 * pXRadius) YChange = pXRadius * pXRadius EllipseError = 0 StoppingX = TwoBSquare * pXRadius StoppingY = 0 PenPos = 0 While StoppingX >= StoppingY If Pen.Style > 0 Then If PenPos < Length Then Plot(pCX, pCY, x, y) EndIf Inc(PenPos) If PenPos > Length Then PenPos = 0 EndIf Else Plot(pCX, pCY, x, y) EndIf Inc(y) Inc(StoppingY, TwoASquare) Inc(EllipseError, YChange) Inc(YChange,TwoASquare) If (2 * EllipseError + XChange) > 0 Then Dec(x) Dec(StoppingX, TwoBSquare) Inc(EllipseError, XChange) Inc(XChange,TwoBSquare) EndIf Wend x = 0 y = pYRadius XChange = pYRadius * pYRadius YChange = pXRadius * pXRadius * (1 - 2 * pYRadius) EllipseError = 0 StoppingX = 0 StoppingY = TwoASquare * pYRadius PenPos = 0 While StoppingX <= StoppingY If Pen.Style > 0 Then If PenPos < Length Then Plot(pCX, pCY, x, y) EndIf Inc(PenPos) If PenPos > Length Then PenPos = 0 EndIf Else Plot(pCX, pCY, x, y) EndIf Inc(x) Inc(StoppingX, TwoBSquare) Inc(EllipseError, XChange) Inc(XChange,TwoBSquare) If (2 * EllipseError + YChange) > 0 Then Dec(y) Dec(StoppingY, TwoASquare) Inc(EllipseError, YChange) Inc(YChange,TwoASquare) EndIf Wend End Sub #ENDIF // GLCD_ELLIPSE { **************************************************************************** * Name : Circle * * Purpose : Draws a Circle, y is scaled To compensate For aspect ratio * **************************************************************************** } #IFNDEF GLCD_CIRCLE Public Sub Circle(pCX, pCY, pRadius As TXY) #IF GLCD_ASPECT_RATIO <> 100 Ellipse(pCX, pCY, pRadius, pRadius * AspectRatio / 100) #ELSE Ellipse(pCX, pCY, pRadius, pRadius) #ENDIF End Sub #ENDIF // GLCD_CIRCLE { **************************************************************************** * Name : HLine (PRIVATE) * * Purpose : Draws a horizontal Line * **************************************************************************** } #IFNDEF GLCD_RECTANGLE Sub HLine(pX1, pX2, pY As TXY) Dim PenPos As Byte Dim Length As Byte PenPos = 0 Length = Pen.Style While pX1 <= pX2 If Pen.Style > 0 Then If PenPos < Length Then SetPixel(pX1,pY) EndIf Inc(PenPos) If PenPos > Length Then PenPos = 0 EndIf Else SetPixel(pX1,pY) EndIf Inc(pX1) Wend End Sub { **************************************************************************** * Name : VLine (PRIVATE) * * Purpose : Draw a vertical Line * **************************************************************************** } Sub VLine(pX, pY1, pY2 As TXY) Dim PenPos As Byte Dim Length As Byte PenPos = 0 Length = Pen.Style While pY1 <= pY2 If Pen.Style > 0 Then If PenPos < Length Then SetPixel(pX,pY1) EndIf Inc(PenPos) If PenPos > Length Then PenPos = 0 EndIf Else SetPixel(pX,pY1) EndIf Inc(pY1) Wend End Sub { **************************************************************************** * Name : Rectangle * * Purpose : Draws a rectangle * **************************************************************************** } Public Sub Rectangle(px1, py1, px2, py2 As TXY) Dim Swap As TXY If px2 < px1 Then Swap = px1 px1 = px2 px2 = Swap EndIf If py2 < py1 Then Swap = py1 py1 = py2 py2 = Swap EndIf HLine(px1, px2, py1) VLine(px2, py1, py2) HLine(px1, px2, py2) VLine(px1, py1, py2) End Sub #ENDIF // GLCD_RECTANGLE { **************************************************************************** * Name : Square * * Purpose : Draws a square, y is scaled To compensate For aspect ratio * **************************************************************************** } #IFNDEF GLCD_SQUARE Public Sub Square(pX, pY, pSize As TXY) #IF GLCD_ASPECT_RATIO <> 100 Rectangle(pX, pY, pX + pSize, pY + pSize * AspectRatio / 100) #ELSE Rectangle(pX, pY, pX + pSize, pY + pSize) #ENDIF End Sub #ENDIF // GLCD_SQUARE { **************************************************************************** * Name : MoveTo * * Purpose : Moves graphics Cursor To given point before calling LineTo() * **************************************************************************** } Public Sub MoveTo(pX, pY As TXY) Pos.x = pX Pos.y = pY End Sub { **************************************************************************** * Name : LineTo * * Purpose : Draws a Line from the current graphics Cursor position * **************************************************************************** } Public Sub LineTo(pX, pY As TXY) Line(Pos.x, Pos.y, pX, pY) Pos.x = pX Pos.y = pY End Sub // monchrome Font rendering, WriteChar has Not be implemented // in main GLCD driver module... #IFNDEF GLCD_WRITECHAR #IFDEF GLCD_PIXEL_01 Dim FCharLocation, // unmodified y (Pixel) character location (Set in WriteChar) FMaskYPosition, // current Mask y position FMaskYMax As TXY // Max y position { **************************************************************************** * Name : ApplyFontStyle (PRIVATE) * * Purpose : Apply Font rendering style * **************************************************************************** } Function ApplyFontStyle(pTarget, pSource As Byte) As Byte If Font.Style = fsXOR Then Result = pTarget Xor pSource Else Result = pTarget Or pSource EndIf End Function { **************************************************************************** * Name : CreateMask (PRIVATE) * * Purpose : Create a Font Mask - a 1 will preserve the background, 0 will * * : Clear * **************************************************************************** } Function CreateMask() As Byte Dim FontHeight As Byte FontHeight = FCharLocation + Font.Height result = $FF Repeat result = result >> 1 result.7 = 1 If (FMaskYPosition >= FCharLocation) And (FMaskYPosition < FontHeight) Then result.7 = 0 EndIf Inc(FMaskYPosition) Until FMaskYPosition >= FMaskYMax Inc(FMaskYMax,8) End Function { **************************************************************************** * Name : WriteCharacterByte (PRIVATE) * * Purpose : Write a Font character Byte To GLCD * **************************************************************************** } Sub WriteCharacterByte(pValue As Byte) Dim Line, YBit, YBitReverse As Byte Dim LastPosY As Byte LastPosY = Pos.y // SAVE y position YBit = Pos.y Mod 8 // Offset YBitReverse = 8 - YBit // reverse Offset Pos.y = Pos.y / 8 // align To PAGE // get Data... Line = ReadByte // Mask, If required... If Font.Style = fsNormal Then FMaskYPosition = LastPosY // current y position FMaskYMax = FMaskYPosition + YBitReverse Line = Line And CreateMask EndIf // apply Font style, Then write To GLCD... Line = ApplyFontStyle(Line,pValue << YBit) WriteByte(Line) // get Next Byte... If YBit <> 0 Then Inc(Pos.y) Line = ReadByte // Mask, If required... If Font.Style = fsNormal Then Line = Line And CreateMask EndIf // apply Font style, Then write To GLCD Line = ApplyFontStyle(Line, pValue >> YBitReverse) WriteByte(Line) EndIf // Restore y position... Pos.y = LastPosY End Sub { **************************************************************************** * Name : WriteChar (PRIVATE) * * Purpose : Write a single character To GLCD * * : This routine only supports fonts with a y scan Line ($8x xx) * **************************************************************************** } Sub WriteChar() Dim FontByte, FontWidth, FontHeight As Byte Dim Mask, LastStyle As Byte FCharLocation = Pos.y FontWidth = 0 While FontWidth < Font.Width Pos.y = FCharLocation FontHeight = 0 While FontHeight < Font.Height FontByte = ReadFontByte Inc(FontHeight, 8) LastStyle = Font.Style If Font.Style = fsInvert Then Font.Style = fsNormal If FontHeight > Font.Height Then Mask = $FF << 8 - (FontHeight - Font.Height) FontByte = FontByte Or Mask EndIf FontByte = Not FontByte EndIf WriteCharacterByte(FontByte) Font.Style = LastStyle Inc(Pos.y, 8) Wend Inc(Pos.x) If Pos.x >= Width Then Pos.x = 0 EndIf Inc(FontWidth) Wend Pos.y = FCharLocation End Sub #ENDIF // GLCD_PIXEL_01 { **************************************************************************** * Name : WriteCharPixel (PRIVATE) * * Purpose : Write a character Pixel To the GLCD * **************************************************************************** } #IFDEF GLCD_PIXEL_08 Sub WriteCharPixel(pChar As Byte, pPenColor As TColor) Pen.Color = pPenColor If Brush.Style = bsClear Then If pChar.0 = 1 Then SetPixel(Pos.x,Pos.y) EndIf Else If pChar.0 = 0 Then Pen.Color = Brush.Color EndIf SetPixel(Pos.x,Pos.y) EndIf End Sub { **************************************************************************** * Name : WriteChar(PRIVATE) * * Purpose : Write a single character To GLCD * * : This routine only supports fonts with a y scan Line ($8x xx) * * : It's device independent, which makes it pretty slow - look at * * : implementing a Device specific routine in the GLCD driver * **************************************************************************** } Sub WriteChar() Dim x, y As TXY Dim FontByte, LastPosY As Byte Dim PenColor As TColor LastPosY = Pos.y PenColor = Pen.Color If Font.IsScanY Then x = 0 Repeat Pos.y = LastPosY y = 0 Repeat If y Mod 8 = 0 Then FontByte = ReadFontByte EndIf WriteCharPixel(FontByte, PenColor) FontByte = FontByte >> 1 Inc(Pos.y) Inc(y) Until y = Font.Height Inc(Pos.x) Inc(x) Until x = Font.Width EndIf Pen.Color = PenColor Pos.y = LastPosY End Sub #ENDIF // GLCD_PIXEL_08 #ENDIF // GLCD_WRITECHAR { **************************************************************************** * Name : WriteFontChar * * Purpose : Write a Font character To the GLCD * **************************************************************************** } Sub WriteFontChar(pChar As Char) LoadCharAddress(pChar) If Font.IsVariable Then Font.Width = ReadFontByte EndIf WriteChar End Sub { **************************************************************************** * Name : WriteLetterSpacing * * Purpose : * **************************************************************************** } Sub WriteFontSpace() Dim Index As Byte Index = Font.LetterSpacing While Index > 0 LoadLetterSpacing WriteChar Dec(Index) Wend End Sub { **************************************************************************** * Name : WriteItem (OVERLOAD) * * Purpose : Writes a character To GLCD * **************************************************************************** } Sub WriteItem(pChar As Char) WriteFontChar(pChar) End Sub { **************************************************************************** * Name : WriteItem (OVERLOAD) * * Purpose : Writes a string To GLCD * **************************************************************************** } Sub WriteItem(pStr As String) FSR0 = @pStr While INDF0 <> 0 WriteFontChar(POSTINC0) If Font.IsVariable And INDF0 <> 0 Then WriteFontSpace EndIf Wend End Sub { **************************************************************************** * Name : SetLocationX (PRIVATE) * * Purpose : Set Cursor x * **************************************************************************** } Sub SetLocationX(pX As TXY) Pos.x = pX End Sub { **************************************************************************** * Name : SetLocationY (PRIVATE) * * Purpose : Set Cursor y * **************************************************************************** } Sub SetLocationY(pY As TXY) Pos.y = pY End Sub { **************************************************************************** * Name : Write (COMPOUND) * * Purpose : Write one Or more items To GLCD * **************************************************************************** } Public Compound Sub Write(WriteItem) { **************************************************************************** * Name : WriteAt (COMPOUND) * * Purpose : Write one Or more items At position x, y * **************************************************************************** } Public Compound Sub WriteAt(SetLocationX, SetLocationY, WriteItem) { **************************************************************************** * Name : WriteStr * * Purpose : Write one item centred in x At position x, y * **************************************************************************** } Public Sub WriteStr(pX, pY As TXY, pStr As String) Pos.x = pX Pos.y = pY If TextAlign = taCenter Then Dec(Pos.x,TextWidth(pStr) / 2) ElseIf TextAlign = taRight Then Dec(Pos.x,TextWidth(pStr)) EndIf WriteItem(pStr) End Sub // initialize the module TextAlign = taLeft
End of post