home *** CD-ROM | disk | FTP | other *** search
/ Commodore 64 Scene Diskmags Assortment / Playback_07_1992_-_de.d64 / sysc64.txt < prev    next >
Text File  |  2023-02-26  |  25KB  |  167 lines

  1.    Peeks, Pokes und SYS-Routinen
  2.  
  3. Auf vieles, was beim C128 zum BASIC-Standard geh{CBM-C}rt, braucht der C64-Programmierer ebenfalls nicht zu verzichten. Systemadressen er{CBM-C}ffnen neue M{CBM-C}glichkeiten. Von uns verfertigte Maschinenroutinen sorgen f{CBM-X}r professionelle Eingabefelder und Eingabemasken.
  4.  
  5. Hilfe, wie kann ich den C64 programmieren? Diese Frage stellte nicht, wie man vielleicht zu glauben geneigt ist, ein im Programmieren unerfahrener C64-Besitzer, sondern ein C128-Anwender, der wohl schon so manches Programm f{CBM-X}r den C128 geschrieben hatte. Ob wohl das BASIC des C64 einen geringeren Wortschatz besitzt, folgt daraus nicht, da{CBM-V} zum Programmieren des C64 geringere Kenntnisse vonn{CBM-C}ten w{CBM-F}ren, sondern vielmehr das Gegenteil. Wo beim C128 ein einfacher BASIC-Befehl das Problem l{CBM-C}st, wird beim C64 das Wissen {CBM-X}ber diverse Tricks, {CBM-X}ber Systemadressen, wenn nicht gar fortgeschrittene Maschinensprachkenntnisse n{CBM-C}tig.
  6. Zwar existieren verschiedene BASIC-Erweiterungen f{CBM-X}r den C64, die einen mit dem C128 vergleichbaren Sprachwortschatz zur Verf{CBM-X}gung stellen, doch wenn ein Programm nicht nur f{CBM-X}r den Eigenbedarf entwickelt wird, sondern auch anderen Anwendern zugute kommen soll, gibt es gewisse Probleme. Wenn die BASIC-Erweiterung als Modul existiert, ben{CBM-C}tigen auch die anderen Anwender dieses Modul. Wenn die BASIC-Erweiterung als Programmfile auf einer Diskette existiert, darf sie aus urheberrechtlichen Gr{CBM-X}nden nicht weiterkopiert werden.
  7. Wie sich das Programmierproblem beim C64 l{CBM-C}sen l{CBM-F}{CBM-V}t, d{CBM-X}rfte auf der Hand liegen. Einige Tips und Tricks werden wir Ihnen gerne vermitteln. Au{CBM-V}erdem haben wir f{CBM-X}r Sie eine kleine Sammlung n{CBM-X}tzlicher Maschinenspracheroutinen bereitgestellt.
  8. Wer die ersten BASIC-Lernschritte mit seinem Computer bereits gemacht hat, wird als ernster Anwender versuchen, sein erworbenes Wissen f{CBM-X}r die Programmierung ma{CBM-V}geschneiderter Anwendungen einzusetzen. Doch er braucht nur seinen Bildschirm anzuschauen und wird feststellen, da{CBM-V} die hellblaue Schrift auf dem dunkelblauen Hintergrund so ziemlich das d{CBM-X}mmste ist, was man sich einfallen lassen konnte. Mit der Control- oder Commodore-Taste in Verbindung mit den Zifferntasten von eins bis acht ist die Zeichenfarbe rasch ge{CBM-F}ndert. Im Programm kann die Zeichenfarbe mit den im Rechnerhandbuch aufgef{CBM-X}hrten Steuercodes angew{CBM-F}hlt werden. Auf das Nachsehen in der Zeichentabelle kann verzichtet werden, da die Steuercodes auch direkt vom Rechner mit der ASC-Anweisung zu erfragen sind. Wenn wir etwa nach ?ASC(" die Control-Taste und die Zifferntaste 2 zur Wahl der Farbe Wei{CBM-V} dr{CBM-X}cken und danach die ganze Sache mit ") und Return abschlie{CBM-V}en, liefert der Rechner den Wert F{CBM-X}nf als Ergebnis. Das Umschalten im Programm auf Wei{CBM-V} geschieht also dann mit:
  9.  
  10. PRINT CHR$(5);
  11.  
  12. Dies d{CBM-X}rfte uns wohl schon l{CBM-F}ngst bekannt sein, beim C128 ist genau dasselbe der Fall. Doch wenn wir Rahmen- und Hintergrundfarbe w{CBM-F}hlen wollen, steht beim C64 keine COLOR-Anweisung zur Verf{CBM-X}gung. Gl{CBM-X}cklicherweise gibt es in BASIC Befehle, die das direkte Ansprechen von Speicher- und Registeradressen gestatten. Mit dem PEEK-Befehl k{CBM-C}nnen wir Daten lesen, mit dem POKE-Befehl Daten schreiben. Es erhebt sich nur noch die Frage nach dem Wohin.
  13.  
  14. Adressen f{CBM-X}r Farbgebung
  15. -----------------------
  16. Zeichenfarbe:       646
  17. Rahmenfarbe:      53280
  18. Hintergrundfarbe: 53281
  19.  
  20. Die Poke-Codes sind um eins kleiner als die Zahlen auf den Tasten, mit denen wir direkt die Zeichenfarbe anw{CBM-F}hlen k{CBM-C}n nen. POKE 53280,0 sorgt so f{CBM-X}r einen schwarzen Rahmen, mit POKE 646,1 wird die Zeichenfarbe wei{CBM-V}. Die Farben, die in Verbindung mit der Commodore-Taste anw{CBM-F}hlbar sind, erreichen wir durch Poke-Codes von acht bis f{CBM-X}nfzehn.
  21. Wenn die Farbgebung stimmt, kann im Programm die Beschriftung des Bildschirms vorgenommen werden. Doch bereits bei der Textpositionierung taucht das zweite Problem auf. Die CHAR-Anweisung, mit der dies spielend einfach beim C128 m{CBM-C}glich ist, existiert beim C64 nicht. Wir m{CBM-X}ssen daher nach anderen L{CBM-C}sungsm{CBM-C}glichkeiten suchen. Die BASIC-L{CBM-C}sung ist, in einem String, etwa CX$, 24 Cursor-down-Zeichen unterzubringen und in einem weiteren String CY$ 39 Cursor-right-Zeichen. CHAR,X,Y k{CBM-C}nnen wir somit ersetzen etwa durch:
  22.  
  23. PRINTCHR$(19)LEFT$(CX$,X)LEFT$(CY$,Y);
  24.  
  25. Es d{CBM-X}rfte sich verstehen, da{CBM-V} diese Positionierung nicht besonders schnell ist, wenn vielleicht hierzu vierzig Cursorzeichen auf den Bildschirm ausgegeben werden m{CBM-X}ssen.
  26. Eine andere M{CBM-C}glichkeit besteht im Benutzen einer f{CBM-X}r die Cursorpositionierung zust{CBM-F}ndigen Systemroutine:
  27.  
  28. POKE 783,0
  29. POKE782,X:POKE781,Y:SYS65520
  30.  
  31. In den meisten F{CBM-F}llen d{CBM-X}rfte sich der erste POKE-Befehl in die Speicherstelle 783 er{CBM-X}brigen. N{CBM-C}tig ist er nur, wenn Sie zuvor eine SYS-Routine aufgerufen haben, die ein gesetztes Carry-Flag zu r{CBM-X}ckliefert, da daraufhin SYS65520 nicht die Cursorposition neu festlegen, sondern nur abfragen w{CBM-X}rde.
  32.  
  33. Der Nachteil bei diesem POKEn ist freilich, da{CBM-V} man stets eine Menge Zahlen im Kopf oder anderswo parat haben mu{CBM-V}. Mit dem SYS-Befehl werden keine Werte an Speicherstellen {CBM-X}bergeben, sondern Maschinenroutinen, die sich an bestimmten Adressen vorfinden, aufgerufen. Da{CBM-V} drei Befehle langsamer als ein einziger abgearbeitet werden und da{CBM-V} Adressen in Form nichtssagender Zahlen der Lesbarkeit eines Programmes nicht zugute kommen, bedarf keiner weiteren Erl{CBM-F}uterung. Im Streben nach Einfachheit beschlo{CBM-V} ich, dieses Manko durch eine selbstgeschriebene Maschinenroutine zu beheben, deren Aufruf sich kaum vom CHAR-Befehl des C128 unterscheidet, wobei ich aber nur Wert auf die Cursorpositionierung legte und auf die M{CBM-C}glichkeit der Text{CBM-X}bergabe verzichtete. Text l{CBM-F}{CBM-V}t sich schlie{CBM-V}lich leicht hinterher mit dem PRINT-Befehl ausgeben. Sicherlich nicht schlecht sieht die Cursorpositionierung aus mit:
  34.  
  35. SYSAT,X,Y
  36.  
  37. Die Voraussetzung zur Verwendung dieses Befehls ist das Programm SYSMC, auf das wir sp{CBM-F}ter noch genauer zu sprechen kommen.
  38.  
  39. Auch bei der Programmlogik sind gewisse Einschr{CBM-F}nkungen in Kauf zu nehmen. Zwar gibt es die ON...GOTO- und die ON...GOSUB-Anweisungen, die ich beim C128 gerne zur Verzweigung nach Tastaturabfragungen ben{CBM-X}tze, besonders wenn mehr als zwei verschiedene Tasten auszuwerten sind. Wenn bei einer Men{CBM-X}auswahl nicht gerade die Zifferntasten von null bis neun Verwendung finden, bleibt kaum etwas anderes {CBM-X}brig, als die Verzweigungen mit einer Liste von IF...THEN-Anweisungen vorzunehmen. Mit der INSTR-Funktion und einer nachfolgenden ON-GOTO-Sprungliste vollzieht sich die Verzweigung schneller, k{CBM-X}rzer und {CBM-X}bersichtlicher. Zwar k{CBM-C}nnte beim C64 f{CBM-X}r mehr {SHIFT--}bersichtlichkeit und K{CBM-X}rze dadurch gesorgt werden, da{CBM-V} mittels einer Laufschleife die Position des Vergleichsbuchstabens in einem Vergleichsstring festgestellt wird, doch w{CBM-X}rde dies nur durch einen weiteren Geschwindigkeitsverlust des Programmes erkauft werden. Auf die INSTR-Anweisung m{CBM-C}chte ich allerdings auch beim C64 nicht verzichten, da diese Anweisung so manches erleichtert, und da ich andererseits C128-Programme auf den C64 umschreiben m{CBM-C}chte, ohne darin allzuviel zu {CBM-F}ndern. Daher verfa{CBM-V}te ich die Maschinenroutine SYSWO.
  40.  
  41. C128:  N=INSTR(T$,C$)
  42. C64:   SYSWO,C$,T$,N
  43.  
  44. In diesen F{CBM-F}llen wird die Position des Zeichens C$ im Vergleichsstring T$ festgestellt und an die Variable N {CBM-X}bergeben. Ist das Zeichen im Vergleichsstring nicht vorhanden, erh{CBM-F}lt die Variable N den Wert null. Ein kleiner Unterschied zwischen beiden Routinen besteht darin, da{CBM-V} die INSTR-Anweisung nicht nur einen einzigen Buchstaben vergleichen kann, sondern eine ganze Zeichen kette. SYSWO interessiert sich nur f{CBM-X}r den ersten Buchstaben aus C$.
  45.  
  46. Ein Manko des BASIC-Befehles INPUT, das den Commodore-Rechnern VC20, C64, C116, C16, Plus/4 und C128 zu eigen ist, besteht darin, da{CBM-V} gewisse Zeichen wie Kommas, Doppelpunkte und Hochkommas nicht angenommen werden. Au{CBM-V}erdem f{CBM-X}hren leere Datenfelder in gespeicherten Dateien beim Einlesen mit INPUT zu unerw{CBM-X}nschten Resultaten, da sie einfach als nicht vorhanden angesehen werden. F{CBM-X}r den C128 hatte ich bereits einen verbesserten INPUT-Befehl entwickelt, f{CBM-X}r den C64 existiert er inzwischen auch.
  47.  
  48. SYSIN:F$
  49.  
  50. Auf dem Bildschirm wird dabei kein Fragezeichen und auch kein zus{CBM-F}tzliches Leerzeichen ausgegeben. Alle eingetippten und auf dem Bildschirm sichtbaren Zeichen werden angenommen und der Variablen F$ {CBM-X}bergeben. Wurde nur die Return-Taste gedr{CBM-X}ckt, bleibt auch der alte Wert von F$ nicht erhalten, sondern wird durch den Leerstring ersetzt. Der Doppelpunkt zwischen SYSIN und der Variablen mag ziemlich un{CBM-X}blich er scheinen. Beim C128 war er aber unbedingt n{CBM-C}tig, da dort die Kommas beim SYS-Aufruf eine spezielle Bedeutung f{CBM-X}r die {SHIFT--}bergabe von Werten an CPU-Register besitzen.
  51.  
  52. Beim C64 wurde der Doppelpunkt beibehalten, damit beim Umschreiben von Programmen f{CBM-X}r den jeweils anderen Rechner keine {SHIFT-+}nderungen dieses Befehls n{CBM-C}tig werden. Statt einer String-Variablen kann auch eine Zahlenvariable {CBM-X}bergeben werden. Im Unterschied zum INPUT-Befehl ist ein Abfragekommentar nicht zul{CBM-F}ssig. Eine Variablenliste, durch Kommas getrennt, f{CBM-X}hrt zu unerw{CBM-X}nschten Ergebnissen. Daher darf dem SYSIN-Aufruf nur jeweils eine einzige Variable folgen. Auch ein Raute-Zeichen zum Lesen von anderen Ger{CBM-F}ten als dem Bildschirm kann nicht verwendet werden.
  53. Es gibt allerdings einen Trick, wonach sowohl ein ganz normaler INPUT-Befehl als auch der SYSIN-Aufruf in der Lage sind, von einem externen Ger{CBM-F}t Daten zu lesen. Hierf{CBM-X}r mu{CBM-V} nur vorher das entsprechende logische Ger{CBM-F}t als Eingabekanal deklariert werden. Au{CBM-V}erdem ist dem INPUT- oder dem SYSIN-Aufruf noch mitzuteilen, da{CBM-V} nicht die Tastatur das Eingabeger{CBM-F}t ist.
  54.  
  55. Beispiel:
  56. ---------
  57. 1 OPEN8,8,8,"DATENFILE,S,R"
  58. 2 POKE 19,8
  59. 3 POKE 781,8:SYS 65478
  60. 4 SYSIN:A$
  61. 5 SYSIN:B$
  62. 6 SYS65484
  63. 7 POKE 19,0
  64. 8 CLOSE8
  65.  
  66. Wird in die Speicherstelle 19 ein Wert ungleich null geschrieben, so wird die INPUT-Routine dar{CBM-X}ber informiert, da{CBM-V} nicht die Tastatur das Eingabeger{CBM-F}t ist, wodurch die Ausgabe eines Fragezeichens auf den Monitor unterlassen wird. F{CBM-X}r den SYSIN-Befehl w{CBM-F}re das zwar unn{CBM-C}tig gewesen, aber vielleicht m{CBM-C}chten Sie zum Einlesen von Zahlen den INPUT-Befehl verwenden, da dabei gleich eine ganze Variablenliste erlaubt ist. In Zeile drei geschieht {CBM-F}hnliches wie mit CMD8, nur da{CBM-V} ein Eingabekanal statt eines Ausgabekanals er{CBM-C}ffnet wird. Danach kann das Einlesen vorgenommen werden.
  67.  
  68. Wenn Sie den INPUT-Befehl ben{CBM-X}tzen, so verzichten Sie bitte auf das Rautezeichen, die Kanalnummer und das Komma, denn der Eingabekanal ist ja bereits offen. INPUT# w{CBM-X}rde ihn wieder schlie{CBM-V}en. Mit INPUT# als letzter Leseanweisung w{CBM-F}ren die Programmzeilen sechs und sieben {CBM-X}berfl{CBM-X}ssig. In Zeile sechs werden Ein- und Ausgabekan{CBM-F}le geschlossen, das hei{CBM-V}t, auf die Standardkan{CBM-F}le Tastatur und Bildschirm umgestellt. In Zeile sieben stellen wir den normalen INPUT-Befehl wieder auf Tastastur um, wenn wir ihn anschlie{CBM-V}end mit dem gewohnten Fragezeichen und nach der Eingabe den Sprung des Cursors in die n{CBM-F}chste Bildschirmzeile w{CBM-X}nschen.
  69.  
  70. Auch bei Ausgaben k{CBM-C}nnen Fehler auftreten. So gibt es einen Programmabbruch mit Fehlermeldung, wenn bei der Druckerausgabe der Drucker nicht angeschlossen oder nicht eingeschaltet ist. W{CBM-F}hrend beim C128 so etwas mit der TRAP-Funktion abgefangen werden kann, fehlt dem C64 eine solche Fehler behandlung. Ein Programmausstieg bei nichtbereitem Ausgabeger{CBM-F}t ist aber sicherlich nicht w{CBM-X}nschenswert. Eine TRAP-Funktion ist jedoch auch nicht vonn{CBM-C}ten. Programmfehler sollten nicht damit abgefangen werden, denn ein Programm darf schlie{CBM-V}lich nicht fehlerhaft programmiert sein.
  71.  
  72. Wenn ein externes Ger{CBM-F}t nicht ansprechbar ist, kann dies festgestellt werden, ohne da{CBM-V} die erw{CBM-F}hnte unerw{CBM-X}nschte Fehlerbehandlung des Computers zum Tragen kommt. Beim Lesen von Diskette erfolgt auch bei Nicht-Vorfinden eines Datenfiles keine Fehlermeldung. Mit der Statusvariablen ST kann nach dem ersten Leseversuch das Mi{CBM-V}lingen im Programm festgestellt und daraufhin die entsprechende Behandlung eingeleitet werden. Bei Ausgaben, etwa auf einen Drucker, existiert ein anderes Verfahren, um die Bereitschaft festzustellen: Wir haben vorher die M{CBM-C}glichkeit, einen Eingabekanal zu {CBM-C}ffnen, behandelt. Dasselbe kann auch mit einem Ausgabekanal geschehen. Nur darf, um die Bereitschaft zu testen, nicht der CMD-Befehl ben{CBM-X}tzt werden, da dieser bereits den unerw{CBM-X}nschten Programmabbruch verursacht. Anstelle des CMD-Befehles gibt es einen SYS-Aufruf, der dasselbe ohne Fehlermeldung vollbringt.
  73.  
  74. 1 OPEN4,4,7
  75. 2 POKE 781,4:SYS 65481
  76. 3 IF (PEEK(783)AND1)=1 THEN 6
  77. 4 PRINT A$
  78. 5 PRINT B$
  79. 7 SYS 65484
  80. 8 CLOSE 4
  81.  
  82. In Zeile zwei erfolgt die {SHIFT--}bergabe der Kanalnummer und im Anschlu{CBM-V} daran der SYS-Aufruf zum {CBM--}ffnen des entsprechenden Ausgabekanals. Die Bereitschaft des Ausgabeger{CBM-F}tes wird von dieser Systemroutine im Carry-Flag des CPU-Statusregisters vermerkt. Ist das Carry-Flag gesetzt, so zeigt dies die Nichtbereitschaft an. Jeder SYS-Aufruf {CBM-X}bergibt die Inhalte der Speicherstellen 780 bis 783 an Akku, X-, Y- und Statusregister und schickt nach der Ausf{CBM-X}hrung der gew{CBM-F}hlten Maschinenroutine die Registerinhalte wiederum in die eben genannten Speicherstellen zur{CBM-X}ck. Da Bit null des Statusregisters das Carryflag repr{CBM-F}sentiert, k{CBM-C}nnen wir es durch Undieren der Speicherstelle 783 mit dem Wert Eins abfragen und dementsprechend die Fehlerbehandlung einleiten, die in unserem Beispiel aus dem {SHIFT--}berspringen der Druckausgabe besteht.
  83.  
  84. Erw{CBM-F}hnenswert ist bei der Ausgabe auch die Rolle der Speicherstelle 19. Bei normal ge{CBM-C}ffnetem Ausgabekanal mit PRINT# oder CMD gibt es folgende Besonderheit: Bei logischen Kanalnummern, die gr{CBM-C}{CBM-V}er oder gleich dem Wert 128 sind, wird nach einem PRINT-Befehl, der nicht mit Komma oder Strichpunkt abgeschlossen ist, neben dem Return noch ein zus{CBM-F}tzliches Zeilenvorschubzeichen gesendet. Wer auf diese M{CBM-C}glichkeit auch bei unserem vorgestellten Verfahren nicht verzichten m{CBM-C}chte, mu{CBM-V} vor der ersten PRINT-Anweisung einen Wert ungleich Null in die Speicherstelle 19 poken. Zum Schlu{CBM-V} sollte dann aber, wie wir es bereits beim INPUT-Befehl besprachen, die Speicherstelle 19 auch wiederum mit einem Nullbyte versehen werden.
  85. Mit SYSIN statt INPUT gibt es keine urpl{CBM-C}tzlich auftretenden Dateifehler nach versehentlich leergelassenem Datenfeld mehr, keine Fehlermeldungen bringen bei Texteingaben, sofern sie nicht zu lang sind, den Bildschirm mehr durcheinander, alle Zeichen d{CBM-X}rfen verwendet werden. Das aber sch{CBM-X}tzt uns noch nicht vor versehentlichem Bildschirml{CBM-C}schen. Auch wenn SYSIN bereits wesentliche Verbesserungen bringt, reicht dies f{CBM-X}r eine wirklich gut gemachte Anwendung nicht aus. Noch kann wild auf dem Bildschirm umhergewandert und sein Inhalt zerschrieben werden.
  86. Beim C128 existiert die M{CBM-C}glichkeit, einen beliebigen rechteckigen Bildschirmteil als Window zu definieren und somit den verbleibenden Rest vor drohenden {SHIFT--}berschreibungen zu sch{CBM-X}tzen. Beim C64 m{CBM-X}ssen wir uns f{CBM-X}r ein solch {CBM-C}rtlich definiertes Eingabefeld schon anderes {CBM-X}berlegen. Jeder Tastendruck mu{CBM-V} {CBM-X}berpr{CBM-X}ft und daraufhin abgefragt werden, ob damit das vorgesehene Eingabefeld verlassen werden w{CBM-X}rde. Gegebenenfalls ist das Verlassen zu unterbinden.
  87.  
  88. Einige Tastendr{CBM-X}cke d{CBM-X}rfen auch nicht ausgef{CBM-X}hrt werden. Die Del/Inst-Taste k{CBM-C}nnte zu Bildverschiebungen au{CBM-V}erhalb unseres Eingabefeldes f{CBM-X}hren. Wenn wir auf das Einf{CBM-X}gen und auf Cursorsteuerung verzichten sowie das Zeichenl{CBM-C}schen durch Cursor-links, Leerzeichen und Cursor-links ersetzen, sollte ein einfaches Eingabefeld schon mit ein wenig BASIC-Programmierung gelingen. Dennoch d{CBM-X}rfte es sich als schwieriger erweisen, als es zun{CBM-F}chst scheint. Nicht selten sind vor allem die unscheinbarsten Dinge gerade diejenigen, die uns am meisten zu schaffen machen.
  89. Da der Cursor bei diesem einfachen Eingabefeld nicht {CBM-X}ber die Buchstaben wandert, sondern stets am Ende sitzt, kann er als inverses Leerzeichen mitgef{CBM-X}hrt werden. Sie k{CBM-C}nnen sich entweder an der Programmierung versuchen oder sich auch diese M{CBM-X}he sparen, denn ich habe f{CBM-X}r Sie bereits ein komfortableres Eingabefeld geschaffen. Dabei wird mit einem echten Cursor gearbeitet, der auch {CBM-X}ber bereits existierende Zeichen hinwegfahren kann, ohne diese zu ver{CBM-F}ndern.
  90.  
  91. {SHIFT--}ber einige Grundlagen m{CBM-C}chte ich Sie nicht in Unkenntnis lassen. Die Tastenabfrage in BASIC V2.0 mu{CBM-V} notgedrungen mit der GET-Anweisung erfolgen, da GETKEY nicht verf{CBM-X}gbar ist. Darauf k{CBM-C}nnen wir aber leichten Herzens verzichten.
  92.  
  93. 10 GET X$:IF X$="" THEN 10
  94.  
  95. Was uns aber zu schaffen macht, ist, da{CBM-V} bei GET, wie auch bei GETKEY, kein sichtbarer Cursor erscheint. In dem Buch PEEKS & POKES vom Data-Becker-Verlag ist das Ein- und Ausschalten des Cursors beschrieben.
  96.  
  97. Cursor ein: POKE 204,0
  98. Cursor aus: POKE 204,1
  99.  
  100. Da der C64 keinen Hardwarecursor besitzt, sondern das Blinken durch st{CBM-F}ndiges Auswechseln von Zeichenfarbe und Cursorfarbe im Farb-RAM sowie normaler und reverser Darstellung im Video-RAM erzeugt wird, darf der Cursor nur dann ausgeschaltet werden, wenn er sich momentan nicht in der Blinkphase befindet. Das ist dann der Fall, wenn die Speicherstelle 207 gerade den Wert null aufweist. Ein GETKEY mit Cursor k{CBM-C}nnte somit folgenderma{CBM-V}en aussehen:
  101.  
  102.  80 POKE204,0
  103.  90 GET X$:IF X$=""THEN 90
  104. 100 IF PEEK(207)=1 THEN 100k110 POKE 204,1
  105.  
  106. Das Warten auf das Ende der Blinkphase f{CBM-X}hrt zu l{CBM-F}stigen Verz{CBM-C}gerungen. Auch ist diese Methode zu unsicher, denn zwischen der Abfrage der Blinkphase und dem Abschalten des Cursors vergeht Zeit, die nicht einfach verschenkt werden darf. W{CBM-F}hrend in Zeile 100 der Cursor nicht in der Blinkphase gewesen sein mag, k{CBM-C}nnte sich dies bei der Ausf{CBM-X}hrung des POKE-Befehls in Zeile 110 bereits wieder ge{CBM-F}ndert haben. Als Resultat bliebe das Zeichen an der Cursorposition in reverser Darstellung auf dem Bildschirm stehen, was so eigentlich nicht sein sollte.
  107. Sowohl Wartezeit als auch Unsicherheit lassen sich beseitigen, wenn vorher das Zeichen unter dem Cursor aus dem Bildschirmspeicher in eine Variable oder sonstwohin gerettet wird. Nachher kann es einfach wieder in der urspr{CBM-X}nglichen Form zur{CBM-X}ckgeschrieben werden. Die Sache mit dem Cursor ist anscheinend nicht ganz einfach. Als Unterroutine meines Eingabefeldes existiert etwas {SHIFT-+}hnliches wie ein GETKEY mit Cursor. Allerdings wird das Ergebnis nicht gleich einer Variablen {CBM-X}bergeben, sondern mu{CBM-V} erst noch aus der Speicherstelle 780 geholt werden:
  108.  
  109. SYS49223:X$=CHR$(PEEK(780))
  110.  
  111. Die Begrenzung des Eingabefeldes, der Einf{CBM-X}gemodus, das L{CBM-C}schen ohne Ver schiebungen au{CBM-V}erhalb dieses Feldes, das Unterbinden verschiedener Tasten sowie das Umfunktionieren gewisser anderer Tasten erwies sich als ziemlich komplex.
  112.  
  113. Um Speicherplatz zu sparen und f{CBM-X}r den Benutzer die Handhabung zu vereinfachen, wurde auf die Programmierung in BASIC verzichtet und statt dessen eine Maschinenroutine bereitgestellt. Mit einem einzigen Befehl l{CBM-F}{CBM-V}t sich nun ein komfortables Eingabefeld f{CBM-X}r den C64 erzeugen:
  114.  
  115. SYSEF,L,N,F$
  116.  
  117. Das Eingabefeld beginnt ab der augenblicklichen Cursorposition. L gibt die L{CBM-F}nge des Eingabefeldes an. Die Variable N reicht einen Zahlenwert zur{CBM-X}ck, der Aufschlu{CBM-V} dar{CBM-X}ber gibt, mit welcher Taste die Eingabe beendet wurde. F$ steht f{CBM-X}r eine Stringvariable, an die die Eingabe {CBM-X}bergeben wird. Bei der Eingabe sind nat{CBM-X}rlich alle Zeichen erlaubt. Steuerzeichen f{CBM-X}r Farbe oder reverse Darstellung wurden durch eine modifizierte PRINT-Routine abgefangen. Au{CBM-V}er der Return-Taste beenden auch Cursor-up, Cursor-down und Control-C die Eingabe. Die Werte f{CBM-X}r N betragen:
  118.  
  119. 1 bei Control-C
  120. 2 bei Cursor-up
  121. 3 bei Cursor-down
  122. 4 bei Return
  123.  
  124. Wichtig ist diese Unterscheidung f{CBM-X}r das Programmieren von Eingabemasken, damit festgestellt werden kann, ob das folgende Eingabefeld zu bearbeiten ist oder das vorhergehende oder ob die Maskeneingabe vorzeitig beendet werden soll.
  125. Die Cursortasten f{CBM-X}r die horizontale Richtung funktionieren wie gewohnt, mit dem Unterschied, da{CBM-V} an den Feldbegrenzungen Schlu{CBM-V} ist. Die Home-Taste setzt den Cursor nicht in die linke obere Bildschirmecke, sondern nur an den Anfang des Eingabefeldes, die Control-Taste l{CBM-C}scht nur das Eingabefeld. Die Inst-Taste besitzt lediglich dieselbe Wirkung, wie wenn die Leertaste gedr{CBM-X}ckt w{CBM-X}rde. Steuerzeichen kommen so auf den Bild schirm, wie wenn man sich normalerweise im Anf{CBM-X}hrungszeichen-Modus bef{CBM-F}nde. Im Unterschied dazu werden sie freilich nicht revers dargestellt.
  126.  
  127. Was noch zur Programmierung ernstzunehmender Anwendungen fehlt, ist das Sperren und Entsperren der Stop-Taste.
  128.  
  129. Stoptaste aus:  SYSSF
  130. Stoptaste an:   SYSSO
  131.  
  132. Mit SYSSF (Stop-Off) wird die Stop-Funktion au{CBM-V}er Kraft gesetzt. Die Stop-Taste funktioniert daraufhin wie eine ganz normale Taste f{CBM-X}r Sonderfunktionen. Sie liefert den ASC-Wert Drei und kann somit statt Control-C die Feldeingabe beenden. Vor der Beendigung eines Programmes sollte mit SYSSO (Stop-On) die gewohnte Funktion der Stop-Taste wieder hergestellt werden.
  133.  
  134. Zu guter Letzt erhebt sich die Frage, wie sich die von mir entwickelten Maschinenroutinen einladen lassen. Da diese Routinen in Verbindung mit BASIC-Programmen Verwendung finden sollen, sollten sie nicht erst wie ein BASIC-Programm geladen und gestartet werden m{CBM-X}ssen. Im Normalfall w{CBM-X}rde f{CBM-X}r das Nachladen eines solchen Maschinenprogrammes der Befehl LOAD"MC-PRO GRAMM",8,1 Verwendung finden. Leider birgt dieses Verfahren Nachteile. So f{CBM-X}hrt etwa der LOAD-Befehl, aufgerufen in einem Programm, zu erneutem Programmstart.
  135. Ein anderes Verfahren arbeitet mit einem zus{CBM-F}tzlichen Ladeprogramm, das Maschinen- und BASIC-Programm im Direktmodus l{CBM-F}dt und dann das BASIC-Programm startet. Beides will mir nicht besonders gefallen. Zudem w{CBM-X}nschen wir uns ein Maschinenprogramm, das sich einfach mit LOAD und SAVE kopieren l{CBM-F}{CBM-V}t, ohne da{CBM-V} wir dazu ein spezielles File-Kopierprogramm ben{CBM-X}tzen m{CBM-X}ssen. Kopierbar wie ein BASIC-Programm wird ein Maschinenprogramm, wenn es zwei Nullbytes am Anfang besitzt. Leider stimmt aber nach dem Laden an den BASIC-Anfang und dem Speichern die gespeicherte Programmstartadresse nicht mehr, so da{CBM-V} sich daraufhin ein absolutes Laden mit ,8,1 verbietet.
  136. Der C128 kennt einen BLOAD-Befehl, mit dessen Hilfe Programmfiles an jede gew{CBM-X}nschte Speicheradresse kopiert werden k{CBM-C}nnen. Dies w{CBM-F}re genau das, was wir ben{CBM-C}tigen. Und in der Tat, es ist m{CBM-C}glich. Die LOAD-Routine ben{CBM-X}tzt unter anderem zwei Unterroutinen, die das Gew{CBM-X}nschte vollbringen, n{CBM-F}mlich Parameter holen und laden.
  137.  
  138. SYS 57812"SYSMC",8
  139. POKE 780,0
  140. POKE 781,254:POKE 782,191
  141. SYS65493
  142.  
  143. Dem Aufruf SYS 57812 folgen dieselben Parameter wie dem LOAD-Befehl. Als Sekund{CBM-F}radresse h{CBM-F}tten wir zus{CBM-F}tzlich eine Null angeben d{CBM-X}rfen. Eine Eins dagegen w{CBM-X}rde ein absolutes Laden zur Folge haben. Allerdings bewirkt der SYS-Aufruf nur die Bereitstellung der Parameter f{CBM-X}r eine folgende Laderoutine. W{CBM-F}hrend der LOAD-Befehl des BASIC der Laderoutine des Kernels den BASIC-Anfang als Startadresse nennt, k{CBM-C}nnen wir uns eine beliebige Adresse ausw{CBM-F}hlen. Das Low-Byte der Adresse ist hierzu dem X-Register (Adresse 781), das High-Byte dem Y-Register (Adresse 782) zu {CBM-X}bergeben.
  144.  
  145. Au{CBM-V}erdem ist durch eine Null im Akku (Adresse 780) der Laderoutine zu signalisieren, da{CBM-V} ein Ladevorgang stattfinden soll. Ein Wert ungleich Null w{CBM-X}rde n{CBM-F}mlich einen Verify ausl{CBM-C}sen. SYS 65493, die Laderoutine des Kernels, l{CBM-F}dt sodann das Programm SYSMC an die Adresse $BFFE. Da sich hier noch zwei ROM-Speicheradressen befinden, gelangen die ersten beiden nicht ben{CBM-C}tigten Nullbytes gar nicht erst in das RAM. Der ben{CBM-C}tigte Rest liegt dann im RAM-Bereich von $C000 bis $C165 und steht dem Benutzer zur Verf{CBM-X}gung.
  146.  
  147. Was an Information noch fehlt, sind die genauen Adressen der Routinen:
  148.  
  149. SYSAT,X,Y
  150. SYSWO,C$,T$,N
  151. SYSIN:F$
  152. SYSEF,L,N,F$
  153. SYSSF
  154. SYSSO
  155.  
  156. Damit wir uns die Adressen nicht zu merken brauchen, legen wir sie in Variablen ab. Sollten Sie in Ihrem BASIC-Programm den CLR-Befehl ben{CBM-X}tzen, so d{CBM-X}rfen Sie keinesfalls vergessen, den Variablen von neuem ihre Werte zuzuweisen, da sonst der Programmabsturz erfolgt.
  157.  
  158. AT = 49152
  159. WO = 49172
  160. IN = 49465
  161. EF = 49337
  162. SF = 49482
  163. SO = 49497
  164.  
  165. Ein kurzes Programm namens NEUSYS auf Ihrer Diskette enth{CBM-F}lt bereits die Ladeanweisung f{CBM-X}r das Maschinenprogramm und die Variableninitialisierung. Wenn Sie die vorgestellten Maschinenroutinen ben{CBM-X}tzen m{CBM-C}chten, brauchen Sie nur auf NEUSYS zur{CBM-X}ckzugreifen, woran Sie dann Ihre eigenen Programmzeilen anf{CBM-X}gen k{CBM-C}nnen. Wie sich mit den neuen Befehlen spielend einfach eine professionelle Maskeneingabe programmieren l{CBM-F}{CBM-V}t, k{CBM-C}nnen Sie am Programm MASKENDEMO sehen. Dort k{CBM-C}nnen Sie Adre{CBM-V}daten in eine Eingabemaske eingeben. Mit den Cursortasten k{CBM-C}nnen Sie sich beliebig von Feld zu Feld bewegen. Die Stop-Taste beendet fr{CBM-X}hzeitig die Eingabe f{CBM-X}r den Fall, da{CBM-V} Sie nicht alle Datenfelder ausf{CBM-X}llen m{CBM-C}chten.
  166.  
  167. Wenn Sie die hier vorgestellten Routinen ben{CBM-X}tzen, werden Ihre Programme gleich viel professioneller. Die Programme SYSMC, NEUSYS und MASKENDEMO sowie auch dieser Artikel sorgen f{CBM-X}r eine Zunahme der allgemeinen Programmqualit{CBM-F}t. Dinge wie das versehentliche Zerst{CBM-C}ren des Bildschirminhalts, unbeabsichtigter Programmabbruch, Nichtannahme bestimmter Zeichen und Ladefehler, verursacht durch leere Datenfelder, sollten n{CBM-F}mlich der Vergangenheit angeh{CBM-C}ren.