Eigene BASIC-Programmierung auf C=64
Oder wie programmiere ich bei begrenztem Speicherangebot?
Meine Computeranlage nebst umfangreicher Literatur plus Programme habe
ich 2009 dem Volkskundemuseum
geschenkt, das sie in einer Vitrine zur Schau stellt.
Zu Weihnachten 1983 kaufte ich mir knapp 900 DM meinen ersten Computer,
einen Commodore 64, der mit dem "Brotkasten-Design".
Mein erstes Spiel hieß "Rat-race" mit der Melodie von "Three
blind mice" und war ein Steckmodul.
Mein erstes nützliches Programm war "Textomat" von Data-Becker.
Ich begann bald selbst in Basic zu programmieren, was mir großen
Spaß brachte.
Eine große Hilfe dabei war das Steckmodul "Exbasic Level II".
Als ich - relativ spät - Ende der 80er Jahre beschloß, eine
Doktorarbeit zu schreiben, entwickelte ich zwei Programme, um die Daten
von 6565 Patienten einzugeben und auswerten.
Das Problem war, dies auf dem Commodore Homecomputer - 38911 Basic Bytes
free - mit sehr begrenztem Speicherangebot zu machen.
Mit intelligenter Ausnutzung von freien Bereichen im RAM kann man zwar
noch mal 4367 Bytes rauskitzeln, aber das war nur ein Tropfen auf den heißen
Stein.
Ich brauchte nämlich für jeden Patienten die Anwesenheitsjahre
von 1976 bis 1988, sein Geschlecht und sein Alter.
Das sind fast 100.000 Daten, zu viele, selbst für den Nachfolger Commodore
128 mit 122.365 Basic Bytes free.
Denn insbesondere die "FOR - NEXT" - Schleifen benötigen
sehr viel Speicherplatz .
Ich entschloß mich also, für jeden Patienten die Daten in einer
einzigen Zahl zu komprimieren:
Beschreibung:
Anwesenheitsjahr 1976: 2 hoch 0 = 1
......
Anwesenheitsjahr 1988: 2 hoch 12 = 4096
Geschlecht: weiblich: 2 hoch 13 = 8192, männlich = 0.
Das Alter wurde zerlegt in 64, 32, 16, 8, 4, 2 und 1 Jahrstücke.
64 = 2 hoch 14 = 16.384
......
1 = 2 hoch 20 = 1.048.576
Wenn man für jeden der Patienten die errechneten Zahlen aufaddiert,
kommt man auf Zahlengrößen zwischen 16.385 und 2.097.152.
Bei einem 8-Bit Computer erfordert das 6565 * 3 = 19.695 Speicherzellen.
Jetzt hatte ich Speicherplatz satt für das Programm und seine Schleifen.
Doch ergab sich bald ein neues Problem: der 128er war mit 1 Mhz. viel zu
langsam.
Um nur einen Auswertungsdurchgang für 6565 Personen zu erfüllen,
brauchte er 5 Stunden.
Das Abschalten der Bildschirmausgabe mit einem Poke erhöhte dann die
Taktfrequenz auf 2 Mhz., was damals schon viel komfortabler war.
Eine Programmierung in Maschinensprache hätte die Auswertungszeit
natürlich drastisch verkürzt, aber dann hätte ich mindestens
noch ein volles Jahr gebraucht, nur um diese Sprache zu lernen.
Als ich das alles meinem Doktorvater präsentierte, zog er seinen jungen
Oberarzt zu Rate, der mich dann fragte, warum ich das Rad noch einmal neu
erfunden hätte, denn für diese Aufgabenstellung gab es doch schon
Programme.
Heute hätte ich natürlich ein Tabellenkalulationsprogramm wie
z.B. Excel genommen, was es damals auch für den Commodore 64 gab (Calc
Result), was aber noch langsamer und auch viel zu speicherintensiv war.
Beim Kauf eines anderen Computers hätte ich mich erst neu einarbeiten
müssen.
Aber so hat das auch gut geklappt:
Weitere selbstgeschriebene Programme:
- Doppelkopf-Spiel-Auswertung mit detaillierter Statistik fuer jeden Mitspieler
- Transskription des MMPI (Minnesota Multiphasic Personality Inventory)
= Psycho-Test
- Transskription des FPI (Freiburger Persönlichkeits Inventar) = Psychotest
Die Nach-C=64-Zeit:
Seit 1993 benutze ich Macintosh, weil ich genug vom Programmieren habe.
Ich will den Computer nicht mehr verstehen, sondern nur noch benutzen.
Außerdem muß ich mich nicht so mit Viren rumschlagen wie die
Bill-Gates-Fan-Gemeinde.
Das liegt daran, daß die Hacker an größtmöglicher
Wirkung interessiert sind, die sie nur bei den zahlreicheren Microsoft-Usern
erzielen können.
Hier die BASIC-Befehlszeilen für das Eingabeprogramm
100 rem d2-eingabe
102 printchr$(14): poke 806,103: poke 807,243: poke 1344,0: poke 1351,128
104 list 4,1: list 1,3: list 0,1
105 print "S": poke 53272,23
106 for i = 1 to 8 : /i,"": nexti: i=0: rem Diese Zeile kommt
mir heute komisch vor.
110 rem beim 1.start zeile 270 aktivieren und zeile 370 inaktivieren
120 dim p(6000): dim a$(14)
125 :
130 rem i = laufende patienten-nummer
140 rem p(i) = beinhaltet jahre der anwesenheit, geschlecht und alter in
1988
150 rem J = maximale patientenzahl
160 rem gb = geburtsjahr des patienten
170 rem k= allgemeiner zaehler für a$(k)
180 rem a$(k) = anwesenheit in diesem jahr und geschlecht
190 print:print
200:
210 print"D2-Patienten-EingabeR": print
220 print"Wenn Floppy blinkt, ..."
222 print"1. Ist eine Diskette in der Floppy?"
224 print"2. Ist die Floppy verschlossen?"
230 print"Wenn ja, Duplikat-Diskette einlegen!"
240 print
250 print"Weiter = ´rWR´"
260 gete$.ife$<>"w"thenprint"Q":goto260
270 rem ifj=0then380:rem beim 1.start diese zeile aktivieren
280 :
290 :
300 rem holt bereits gespeicherte daten
302 open1,9,15:close1:ifst<0thenprint"Floppy ist aus/ab? CONT rRETURNR":stop
305 if st<0thengoto302
310 open 3,9,13,"daten,s,r"
320 input#3,j
330 fori=1toj
340 input#3,p(i)
350 nexti
355 i=i-1
360 close3
370 ifj=0then goto130: rem beim 1.start diese zeile inaktivieren
380 :
390 :
400 rem eingabe
410 print:i=i+1
420 print"S"
430 print"Pat-Nr."r"i"R"
440 print"war (nicht) da r+R(r-R) Zurueck = ´rZR´´"
450 :
460 fork=0to12
470 print1976+k
480 geta$(k):ifa$(k)<>"+"anda$(k)<>"-"anda$(k)<>"z"thenprint"Q":goto480
490 ifa$(k)="z"andk=0thengoto420
500 ifa$(k)="z"thenprint"QQ ":k=k-1:goto480
510 print"Q";a$(k)
520 nextk
530 :
540 :
550 :
560 print"Geschlecht rfR / rmR"
570 geta$(13):ifa$(13)<>"f"anda$(13)<>"m"thenprint"Q":goto570
580 print"QJJJJJJJJJJJJJJJJJJJJJJJJJJJ":a$(13)
590 :
600 :
610 input"Geburtsjahr -1900 rRETURNRJJJ0III";gb
620 ifgb>88orgb<-39thenprint"QQ":goto610
630 :
640 print
650 print"Speichern = ´S´`"
660 print"Weiter = ´W´"
670 print"zurueck = ´Z´"
680 gete$:ife$<>"z"ande$<>"s"ande$<>"w"thenprint"Q":goto680
690 ife$="z"thengoto420
700 :
710 :
720 rem zaehlt anwesenheitsjahre und geschlecht auf = p(i)
730 fork=0to13
740 ifa$(k)="+"thenp(i)=p(i)+2Îk
750 ifa$(k)="f"thenp(i)=p(i)+2Îk
760 nextk
770 :
780 gb=1988-1900-gb
790 rem errechnet das alter fuer 1988
800 rem und steckt diese zahl in p(i)
810 ifgb>=2Î6thenp(i)=p(i)+2Î14:gb=gb-2Î6
820 ifgb>=2Î5thenp(i)=p(i)+2Î15:gb=gb-2Î5
830 ifgb>=2Î4thenp(i)=p(i)+2Î16:gb=gb-2Î4
840 ifgb>=2Î3thenp(i)=p(i)+2Î17:gb=gb-2Î3
850 ifgb>=2Î2thenp(i)=p(i)+2Î18:gb=gb-2Î2
860 ifgb>=2Î1thenp(i)=p(i)+2Î19:gb=gb-2Î1
870 ifgb>=2Î0thenp(i)=p(i)+2Î20:gb=gb-2Î0
880 ife$="s"thenj=i:goto930
890 i=i+1
900 goto 420
910 :
920 :
930 :
940 rem speichert daten
942 open2,9,2:close2:ifst<0thenprint"SFloppy ist aus/ab?
rCONTR RETURN":stop
943 print" "
944 print" "
945 ifst<0thengoto942
950 open2,9,2,"@:daten,s,w"
960 print#2,j
970 fori=1toj
980 print#2,p(i)
990 nexti
995 :
1000 close2
1010 :
1020 print
1030 :
1040 print"Weiter = ´W´"
1050 print"Speichern = ´S´"
1060 print"S"
1062 print"Wenn nichts passiert,"
1064 "Floppy einschalten!"
1066 print
1068 print"Wenn Floppy blinkt, ..."
1070 print"1.Ist die Diskette im Laufwerk?"
1072 print"2.Ist die Floppy verschlossen?"
1074 print"Wenn ja, Kopie-Diskette rein!"
1076 print"Noch mal ´S´ druecken!"
1080 print
1082 print"Sicherheitskopie?"
1084 print"Neue Diskette rein und ´S´druecken!"
1086 print
1088 print"Weitere Eingaben machen?"
1090 print"´W´druecken!"
1100 gete$:ife$<>"w"ande$<>"s"thenprint"Q":goto1100
1110 ife$="s"thengoto940
1120 ife$="w"thenj=j+1:goto420
1130 end