Um mich etwas in ein KS0108-GLCD einzuarbeiten entstand aus einer "Drauf-los-Programmiererei" ein kleines Pong-Spiel.

Der Hintergrund dazu: Eigentlich wird aus der ganzen Sache mal ein Datenlogger mit USB-Stick, da ich aber bisher nur T6963C-Displays verwendet habe und dieses Projekt erstmal ein KS0108-GLCD verwendet habe ich mich mal in der Ansteuerung versucht. Grundsätzlich besitzt dieses Display einige Tücken. So muss zum Beispiel ein Grafik-Befehl in einem Rutsch ausgeführt werden und darf keinesfalls unterbrochen werden (z. B. durch einen Interrupt). Während das T6963C-Display bei Unterbrechung gemütlich gewartet hat, bis der Befehl vollständig übertragen wurde, führt das KS0108 den angebrochenen Befehl sofort aus - mit interessanten Folgen. Anschließend stimmt nichts mehr und jeder darauffolgende Befehl wird völlig falsch ausgeführt. Ebenfalls tödlich ist das Beschreiben außerhalb der Display-Position: Das T6963C-Display hat den Befehl dann einfach ignoriert während das KS0108-Display quasi überläuft und eine exestierende Position nimmt, ähnlich wie wenn man einer Bytevariable mit dem Wert null den Wert eins abzieht, was den Wert 255 als Ergebnis liefert.

Zum Programm: Es ist eine Quick'n'Dirty-Lösung, die rein aus dem Bauch heraus entstand. Wenn ich mich dazu motivieren kann werde ich den Code vielleicht noch umschreiben und erweitern, damit was schönes dabei rauskommt. Trotzdem funktioniert die Sache bereits tadellos.
Wird der Ball mit dem Schläger getroffen gibt es einen Punkt, verfehlt man den Ball wird ein Punkt abgezogen. Weniger wie null Punkte gibts nicht.

Vielleicht hat ja jemand Spaß daran und entwickelt es weiter oder spielt einfach nur ein paar Runden.

Code:
'#########
'## EDT ##
'#########
'---------
'KS0108-Ansteuerung
'V1.0
'07.10.2012
'BASCOM 2.0.7.5
'---------
'schaltplan_ks0108ans_v1_0.dsn
'---------
'DEMO- und Testprogramm zur Ansteuerung eines GLCDs mit KS0108-Controller.
'Mit optional angeschlossenen Tastern an Pind.0 und Pind.1 kann das Spiel gespielt werden.
'---------


$regfile = "m32def.dat"                                     'AtMega32
$crystal = 1000000                                          '1Mhz
$hwstack = 32                                               'nicht optimiert
$swstack = 8                                                'nicht optimiert
$framesize = 32                                             'nicht optimiert


Config Pind.0 = Input
Config Pind.1 = Input
Config Pind.2 = Input
Config Pind.3 = Input
Portd.0 = 1
Portd.1 = 1
Portd.2 = 1
Portd.3 = 1

'KONFIGURATION TIMER0
Config Timer0 = Timer , Prescale = 256                      '65,5ms
On Timer0 Isr_timer0
Enable Timer0
Start Timer0

'VARIABLEN
Dim X As Byte                                               'X-Pos. des Balls
Dim Y As Byte                                               'Y-Pos. des Balls
Dim X_dir As Bit                                            'Horizontale Laufrichtung 1=rechts, 0=links
Dim Y_dir As Bit                                            'Vertikale Laufrichtung 1=unten, 0=oben
Dim X_bar As Byte                                           'X-Position des Schlägers (linkes Ende)
Dim X_bar_offset As Byte                                    'X-Position des Schlägers (rechtes Ende)
Dim X_bar_temp As Byte                                      'Schlägerposition zum Rechnen
Dim Y_bar As Byte                                           'Y-Postion des Schlägers
Dim Point As Byte                                           'Punktestand
Dim Timer_flag As Bit                                       'Timer Flag
Dim I As Byte                                               'Indexvariable für For-Schleife

'INITIALISIEREN DER VARIABLEN
X = 20                                                      'X-Pos. des Balls am Start
Y = 20                                                      'Y-Pos. des Balls am Start
Y_bar = 60                                                  'X-Pos. des Schlägers am Start
X_bar = 20                                                  'Y_Pos. des Schlägers


$lib "glcdKS108.lbx"                                        'Lib für das Display

Config Graphlcd = 128 * 64sed , Dataport = Portc , Controlport = Porta , Ce = 4 , Ce2 = 3 , Cd = 0 , Rd = 1 , Reset = 5 , Enable = 2
Cls                                                         'LCD-löschen

Setfont My6_8

Lcdat 1 , 1 , "GLCD-DEMO" , 0
Lcdat 2 , 1 , "----------" , 0
Lcdat 4 , 1 , "KS0108-GLCD 128x64" , 0
Lcdat 5 , 1 , "AtMega32 @1Mhz" , 0
Lcdat 6 , 1 , "EDT 2012" , 0
Wait 1
Cls

Enable Interrupts

'### HAUPTSCHLEIFE ###
Do

   If Timer_flag = 1 Then
      Pset X , Y , 0                                        'Ball löschen
      If X_dir = 1 Then Incr X Else Decr X                  'Ballbewegung X-Ache
      If Y_dir = 1 Then Incr Y Else Decr Y                  'Ballbewegung Y-Achse
      If X = 127 Then X_dir = 0                             'Richtungswechsel X-Achse
      If Y = 63 Then                                        'Verzweigung wenn Ball am unteren Spielrand
         Y_dir = 0                                          'Richtungswechsel Y-Achse
         If Point > 0 Then Decr Point                       'Punktestand dekrementieren
      End If
      If X = 1 Then X_dir = 1                               'Richtungswechsel X-Achse
      If Y = 1 Then Y_dir = 1                               'Richtungswechsel Y-Achse
      X_bar_temp = X_bar                                    'Temporäre Variable zum Rechnen mit der aktuellen Schlägerpos. füllen
      For I = 1 To 10                                       'For-Schleife mit 10 Durchläufen
         If Y = 60 And X = X_bar_temp And Y_dir = 1 Then    'Abfrage ob Ball die Schlägerposition erreicht hat
            Incr Point                                      'wenn ja, Punktestand inkrementieren
            Toggle Y_dir                                    'und Richtungswechsel Y-Achse
         End If
         Incr X_bar_temp                                    'Temporäre Variable mit Schlägerposition um eins erhöhen
      Next
      Pset X , Y , 1                                        'Ball zeichnen

      If Pind.0 = 0 Then
         X_bar_offset = X_bar + 10
         Line(x_bar , Y_bar) -(x_bar_offset , Y_bar) , 0    'Schläger löschen
         If X_bar > 10 Then Decr X_bar                      'Schlägerposition dekrementieren
         X_bar_offset = X_bar + 10                          'Rechtes Schlägerende neu berechnen
         Line(x_bar , Y_bar) -(x_bar_offset , Y_bar) , 1    'Schläger zeichnen
      End If

      If Pind.1 = 0 Then
         X_bar_offset = X_bar + 10
         Line(x_bar , Y_bar) -(x_bar_offset , Y_bar) , 0
         If X_bar < 100 Then Incr X_bar
         X_bar_offset = X_bar + 10
         Line(x_bar , Y_bar) -(x_bar_offset , Y_bar) , 1
      End If

      Lcdat 1 , 1 , Point , 0                               'Punktestand zeichnen

      Reset Timer_flag
   End If

Loop

'### ISR ###
Isr_timer0:

   Set Timer_flag

Return


End

$include "my6_8.font"